parent
290f584dcc
commit
b3ba6c1c88
|
@ -6,7 +6,7 @@ import cpu.defines.Const._
|
|||
case class CpuConfig(
|
||||
// 指令集
|
||||
val isRV32: Boolean = false, // 是否为RV32
|
||||
val hasMExtension: Boolean = true, // 是否实现M扩展,即乘除法指令
|
||||
val hasMExtension: Boolean = false, // 是否实现M扩展,即乘除法指令
|
||||
val hasZicsrExtension: Boolean = false, // 是否实现Zicsr扩展,即CSR指令
|
||||
val hasZifenceiExtension: Boolean = false, // 是否实现Zifencei扩展,即FENCE.I指令
|
||||
val hasAExtension: Boolean = false, // 是否实现A扩展,即原子指令
|
||||
|
|
|
@ -18,7 +18,7 @@ class SrcInfo extends Bundle {
|
|||
}
|
||||
|
||||
class RdInfo extends Bundle {
|
||||
val wdata = Vec(FuType.num, UInt(XLEN.W))
|
||||
val wdata = UInt(XLEN.W)
|
||||
}
|
||||
|
||||
class Info extends Bundle {
|
||||
|
|
|
@ -38,6 +38,5 @@ object Const extends Constants with SRAMConst
|
|||
object Instructions extends HasInstrType with CoreParameter {
|
||||
def NOP = 0x00000013.U
|
||||
val DecodeDefault = List(InstrN, FuType.alu, ALUOpType.add)
|
||||
def DecodeTable = RVIInstr.table ++
|
||||
(if (cpuConfig.hasMExtension) RVMInstr.table else Array.empty)
|
||||
def DecodeTable = RVIInstr.table
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ import chisel3._
|
|||
import chisel3.util._
|
||||
|
||||
trait HasInstrType {
|
||||
def InstrN = "b000".U
|
||||
def InstrI = "b100".U
|
||||
def InstrR = "b101".U
|
||||
def InstrS = "b010".U
|
||||
def InstrB = "b001".U
|
||||
def InstrU = "b110".U
|
||||
def InstrJ = "b111".U
|
||||
def InstrN = "b000".U
|
||||
def InstrI = "b100".U
|
||||
def InstrR = "b101".U
|
||||
def InstrS = "b010".U
|
||||
def InstrB = "b001".U
|
||||
def InstrU = "b110".U
|
||||
def InstrJ = "b111".U
|
||||
|
||||
def isRegWen(instrType: UInt): Bool = instrType(2)
|
||||
}
|
||||
|
@ -23,9 +23,8 @@ object SrcType {
|
|||
}
|
||||
|
||||
object FuType {
|
||||
def num = 2
|
||||
def num = 1
|
||||
def alu = 0.U // arithmetic logic unit
|
||||
def mdu = 1.U // multiplication division unit
|
||||
def apply() = UInt(log2Up(num).W)
|
||||
}
|
||||
|
||||
|
@ -55,25 +54,3 @@ object ALUOpType {
|
|||
def isWordOp(func: UInt) = func(4)
|
||||
def isAdd(func: UInt) = func(5)
|
||||
}
|
||||
|
||||
// mul div unit
|
||||
object MDUOpType {
|
||||
def mul = "b0000".U
|
||||
def mulh = "b0001".U
|
||||
def mulhsu = "b0010".U
|
||||
def mulhu = "b0011".U
|
||||
def div = "b0100".U
|
||||
def divu = "b0101".U
|
||||
def rem = "b0110".U
|
||||
def remu = "b0111".U
|
||||
|
||||
def mulw = "b1000".U
|
||||
def divw = "b1100".U
|
||||
def divuw = "b1101".U
|
||||
def remw = "b1110".U
|
||||
def remuw = "b1111".U
|
||||
|
||||
def isDiv(op: UInt) = op(2)
|
||||
def isDivSign(op: UInt) = isDiv(op) && !op(0)
|
||||
def isWordOp(op: UInt) = op(3)
|
||||
}
|
||||
|
|
|
@ -67,10 +67,6 @@ object RV64IInstr extends HasInstrType {
|
|||
def ADDW = BitPat("b0000000_?????_?????_000_?????_0111011")
|
||||
def SUBW = BitPat("b0100000_?????_?????_000_?????_0111011")
|
||||
|
||||
def LWU = BitPat("b???????_?????_?????_110_?????_0000011")
|
||||
def LD = BitPat("b???????_?????_?????_011_?????_0000011")
|
||||
def SD = BitPat("b???????_?????_?????_011_?????_0100011")
|
||||
|
||||
val table = Array(
|
||||
ADDIW -> List(InstrI, FuType.alu, ALUOpType.addw),
|
||||
SLLIW -> List(InstrI, FuType.alu, ALUOpType.sllw),
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package cpu.defines
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
object RV32MInstr extends HasInstrType with CoreParameter {
|
||||
def MUL = BitPat("b0000001_?????_?????_000_?????_0110011")
|
||||
def MULH = BitPat("b0000001_?????_?????_001_?????_0110011")
|
||||
def MULHSU = BitPat("b0000001_?????_?????_010_?????_0110011")
|
||||
def MULHU = BitPat("b0000001_?????_?????_011_?????_0110011")
|
||||
def DIV = BitPat("b0000001_?????_?????_100_?????_0110011")
|
||||
def DIVU = BitPat("b0000001_?????_?????_101_?????_0110011")
|
||||
def REM = BitPat("b0000001_?????_?????_110_?????_0110011")
|
||||
def REMU = BitPat("b0000001_?????_?????_111_?????_0110011")
|
||||
def MULW = BitPat("b0000001_?????_?????_000_?????_0111011")
|
||||
def DIVW = BitPat("b0000001_?????_?????_100_?????_0111011")
|
||||
def DIVUW = BitPat("b0000001_?????_?????_101_?????_0111011")
|
||||
def REMW = BitPat("b0000001_?????_?????_110_?????_0111011")
|
||||
def REMUW = BitPat("b0000001_?????_?????_111_?????_0111011")
|
||||
|
||||
val mulTable = Array(
|
||||
MUL -> List(InstrR, FuType.mdu, MDUOpType.mul),
|
||||
MULH -> List(InstrR, FuType.mdu, MDUOpType.mulh),
|
||||
MULHSU -> List(InstrR, FuType.mdu, MDUOpType.mulhsu),
|
||||
MULHU -> List(InstrR, FuType.mdu, MDUOpType.mulhu)
|
||||
)
|
||||
val divTable = Array(
|
||||
DIV -> List(InstrR, FuType.mdu, MDUOpType.div),
|
||||
DIVU -> List(InstrR, FuType.mdu, MDUOpType.divu),
|
||||
REM -> List(InstrR, FuType.mdu, MDUOpType.rem),
|
||||
REMU -> List(InstrR, FuType.mdu, MDUOpType.remu)
|
||||
)
|
||||
val table = mulTable ++ divTable
|
||||
}
|
||||
|
||||
object RV64MInstr extends HasInstrType with CoreParameter {
|
||||
def MULW = BitPat("b0000001_?????_?????_000_?????_0111011")
|
||||
def DIVW = BitPat("b0000001_?????_?????_100_?????_0111011")
|
||||
def DIVUW = BitPat("b0000001_?????_?????_101_?????_0111011")
|
||||
def REMW = BitPat("b0000001_?????_?????_110_?????_0111011")
|
||||
def REMUW = BitPat("b0000001_?????_?????_111_?????_0111011")
|
||||
|
||||
val mulTable = Array(
|
||||
MULW -> List(InstrR, FuType.mdu, MDUOpType.mulw)
|
||||
)
|
||||
val divTable = Array(
|
||||
DIVW -> List(InstrR, FuType.mdu, MDUOpType.divw),
|
||||
DIVUW -> List(InstrR, FuType.mdu, MDUOpType.divuw),
|
||||
REMW -> List(InstrR, FuType.mdu, MDUOpType.remw),
|
||||
REMUW -> List(InstrR, FuType.mdu, MDUOpType.remuw)
|
||||
)
|
||||
val table = mulTable ++ divTable
|
||||
}
|
||||
|
||||
object RVMInstr extends CoreParameter {
|
||||
val table = RV32MInstr.table ++ (if (XLEN == 64) RV64MInstr.table else Array.empty)
|
||||
}
|
|
@ -19,7 +19,6 @@ class Fu extends Module {
|
|||
})
|
||||
|
||||
val alu = Module(new Alu()).io
|
||||
val mdu = Module(new Mdu()).io
|
||||
|
||||
io.dataSram.en := false.B
|
||||
io.dataSram.addr := DontCare
|
||||
|
@ -29,10 +28,5 @@ class Fu extends Module {
|
|||
alu.info := io.data.info
|
||||
alu.src_info := io.data.src_info
|
||||
|
||||
mdu.info := io.data.info
|
||||
mdu.src_info := io.data.src_info
|
||||
|
||||
io.data.rd_info.wdata := DontCare
|
||||
io.data.rd_info.wdata(FuType.alu) := alu.result
|
||||
io.data.rd_info.wdata(FuType.mdu) := mdu.result
|
||||
io.data.rd_info.wdata := alu.result
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Div extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val src1 = Input(UInt(XLEN.W))
|
||||
val src2 = Input(UInt(XLEN.W))
|
||||
val signed = Input(Bool())
|
||||
|
||||
val result = Output(UInt((2 * XLEN).W))
|
||||
})
|
||||
|
||||
val div_signed = io.signed
|
||||
|
||||
val dividend_signed = io.src1(XLEN - 1) & div_signed
|
||||
val divisor_signed = io.src2(XLEN - 1) & div_signed
|
||||
|
||||
val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt)
|
||||
val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt)
|
||||
|
||||
val quotient_signed = (io.src1(XLEN - 1) ^ io.src2(XLEN - 1)) & div_signed
|
||||
val remainder_signed = io.src1(XLEN - 1) & div_signed
|
||||
|
||||
val quotient_abs = dividend_abs / divisor_abs
|
||||
val remainder_abs = dividend_abs - quotient_abs * divisor_abs
|
||||
|
||||
val quotient = WireInit(0.S(XLEN.W))
|
||||
val remainder = WireInit(0.S(XLEN.W))
|
||||
|
||||
quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt)
|
||||
remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt)
|
||||
when(io.src2 === 0.U) {
|
||||
quotient := (~0.U).asSInt
|
||||
remainder := io.src1.asSInt
|
||||
}
|
||||
|
||||
io.result := Cat(remainder, quotient)
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Mdu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
|
||||
val result = Output(UInt(XLEN.W))
|
||||
})
|
||||
|
||||
val mul = Module(new Mul()).io
|
||||
val div = Module(new Div()).io
|
||||
|
||||
val valid = io.info.valid
|
||||
val op = io.info.op
|
||||
val is_div = MDUOpType.isDiv(op)
|
||||
val is_w = MDUOpType.isWordOp(op)
|
||||
|
||||
val src1 = io.src_info.src1_data
|
||||
val src2 = io.src_info.src2_data
|
||||
|
||||
val zeroExtend = ZeroExtend(_: UInt, XLEN + 1)
|
||||
val signedExtend = SignedExtend(_: UInt, XLEN + 1)
|
||||
val srcMulConvertTable = Seq(
|
||||
MDUOpType.mul -> (zeroExtend, zeroExtend),
|
||||
MDUOpType.mulh -> (signedExtend, signedExtend),
|
||||
MDUOpType.mulhsu -> (signedExtend, zeroExtend),
|
||||
MDUOpType.mulhu -> (zeroExtend, zeroExtend)
|
||||
)
|
||||
|
||||
mul.src1 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._1(src1))))
|
||||
mul.src2 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._2(src2))))
|
||||
|
||||
val srcDivConvertFunc = (x: UInt) =>
|
||||
Mux(is_w, Mux(MDUOpType.isDivSign(op), SignedExtend(x(31, 0), XLEN), ZeroExtend(x(31, 0), XLEN)), x)
|
||||
div.src1 := srcDivConvertFunc(src1)
|
||||
div.src2 := srcDivConvertFunc(src2)
|
||||
div.signed := MDUOpType.isDivSign(op)
|
||||
|
||||
val mul_result = Mux(op(1, 0) === MDUOpType.mul, mul.result(XLEN - 1, 0), mul.result(2 * XLEN - 1, XLEN))
|
||||
val div_result = Mux(op(1), div.result(2 * XLEN - 1, XLEN), div.result(XLEN - 1, 0))
|
||||
val result = Mux(is_div, div_result, mul_result)
|
||||
|
||||
io.result := Mux(is_w, SignedExtend(result(31, 0), XLEN), result)
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Mul extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val src1 = Input(UInt((XLEN + 1).W))
|
||||
val src2 = Input(UInt((XLEN + 1).W))
|
||||
|
||||
val result = Output(UInt((2 * XLEN).W))
|
||||
})
|
||||
|
||||
val signed = WireInit(0.U((2 * XLEN).W))
|
||||
signed := (io.src1.asSInt * io.src2.asSInt).asUInt
|
||||
io.result := signed
|
||||
}
|
|
@ -18,10 +18,10 @@ class WriteBackUnit extends Module {
|
|||
io.writeBackStage.data.info.reg_wen
|
||||
|
||||
io.regfile.waddr := io.writeBackStage.data.info.reg_waddr
|
||||
io.regfile.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel)
|
||||
io.regfile.wdata := io.writeBackStage.data.rd_info.wdata
|
||||
|
||||
io.debug.pc := io.writeBackStage.data.pc
|
||||
io.debug.commit := io.writeBackStage.data.info.valid
|
||||
io.debug.commit := io.writeBackStage.data.info.valid
|
||||
io.debug.rf_wnum := io.regfile.waddr
|
||||
io.debug.rf_wdata := io.regfile.wdata
|
||||
}
|
||||
|
|
2
difftest
2
difftest
|
@ -1 +1 @@
|
|||
Subproject commit 8fb9d90b00e02be2baa7536ffa43fe0a6d6dc7f6
|
||||
Subproject commit e2b04f50f1fa43f0153bac2a21f1bbcc98f050be
|
Loading…
Reference in New Issue