完成lab2实验大致框架

实现I型和U型运算类指令的理想流水线设计
This commit is contained in:
Liphen 2024-05-27 16:18:59 +08:00
parent 290f584dcc
commit b3ba6c1c88
12 changed files with 15 additions and 220 deletions

View File

@ -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扩展即原子指令

View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}

View File

@ -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),

View File

@ -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)
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

@ -1 +1 @@
Subproject commit 8fb9d90b00e02be2baa7536ffa43fe0a6d6dc7f6
Subproject commit e2b04f50f1fa43f0153bac2a21f1bbcc98f050be