From 290f584dccd90e99b3a340c51b000d3d3ea3ccb6 Mon Sep 17 00:00:00 2001 From: Liphen Date: Mon, 27 May 2024 16:05:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=AE=9E=E9=AA=8C=E5=A4=A7?= =?UTF-8?q?=E8=87=B4=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现乘除法指令的理想流水线设计实验 --- .../src/defines/isa/Instructions.scala | 36 ++--- chisel/playground/src/defines/isa/RVI.scala | 29 +--- .../src/pipeline/decode/Decoder.scala | 2 - .../playground/src/pipeline/execute/Fu.scala | 18 +-- .../src/pipeline/execute/fu/Lsu.scala | 131 ------------------ .../src/pipeline/memory/MemoryUnit.scala | 10 -- 6 files changed, 19 insertions(+), 207 deletions(-) delete mode 100644 chisel/playground/src/pipeline/execute/fu/Lsu.scala diff --git a/chisel/playground/src/defines/isa/Instructions.scala b/chisel/playground/src/defines/isa/Instructions.scala index e11ba4d..7d4b1d8 100644 --- a/chisel/playground/src/defines/isa/Instructions.scala +++ b/chisel/playground/src/defines/isa/Instructions.scala @@ -4,14 +4,13 @@ import chisel3._ import chisel3.util._ trait HasInstrType { - def InstrN = "b0000".U - def InstrI = "b0100".U - def InstrR = "b0101".U - def InstrS = "b0010".U - def InstrB = "b0001".U - def InstrU = "b0110".U - def InstrJ = "b0111".U - def InstrSA = "b1111".U // Atom Inst: SC + 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) } @@ -24,10 +23,9 @@ object SrcType { } object FuType { - def num = 3 + def num = 2 def alu = 0.U // arithmetic logic unit def mdu = 1.U // multiplication division unit - def lsu = 2.U // load store unit def apply() = UInt(log2Up(num).W) } @@ -58,24 +56,6 @@ object ALUOpType { def isAdd(func: UInt) = func(5) } -// load store unit -object LSUOpType { - def lb = "b0000".U - def lh = "b0001".U - def lw = "b0010".U - def ld = "b0011".U - def lbu = "b0100".U - def lhu = "b0101".U - def lwu = "b0110".U - def sb = "b1000".U - def sh = "b1001".U - def sw = "b1010".U - def sd = "b1011".U - - def isStore(func: UInt): Bool = func(3) - def isLoad(func: UInt): Bool = !isStore(func) -} - // mul div unit object MDUOpType { def mul = "b0000".U diff --git a/chisel/playground/src/defines/isa/RVI.scala b/chisel/playground/src/defines/isa/RVI.scala index c1d1f43..2e010dd 100644 --- a/chisel/playground/src/defines/isa/RVI.scala +++ b/chisel/playground/src/defines/isa/RVI.scala @@ -56,28 +56,6 @@ object RV32I_ALUInstr extends HasInstrType with CoreParameter { ) } -object RV32I_LSUInstr extends HasInstrType { - def LB = BitPat("b????????????_?????_000_?????_0000011") - def LH = BitPat("b????????????_?????_001_?????_0000011") - def LW = BitPat("b????????????_?????_010_?????_0000011") - def LBU = BitPat("b????????????_?????_100_?????_0000011") - def LHU = BitPat("b????????????_?????_101_?????_0000011") - def SB = BitPat("b???????_?????_?????_000_?????_0100011") - def SH = BitPat("b???????_?????_?????_001_?????_0100011") - def SW = BitPat("b???????_?????_?????_010_?????_0100011") - - val table = Array( - LB -> List(InstrI, FuType.lsu, LSUOpType.lb), - LH -> List(InstrI, FuType.lsu, LSUOpType.lh), - LW -> List(InstrI, FuType.lsu, LSUOpType.lw), - LBU -> List(InstrI, FuType.lsu, LSUOpType.lbu), - LHU -> List(InstrI, FuType.lsu, LSUOpType.lhu), - SB -> List(InstrS, FuType.lsu, LSUOpType.sb), - SH -> List(InstrS, FuType.lsu, LSUOpType.sh), - SW -> List(InstrS, FuType.lsu, LSUOpType.sw) - ) -} - object RV64IInstr extends HasInstrType { def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011") def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011") @@ -102,14 +80,11 @@ object RV64IInstr extends HasInstrType { SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw), SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw), ADDW -> List(InstrR, FuType.alu, ALUOpType.addw), - SUBW -> List(InstrR, FuType.alu, ALUOpType.subw), - LWU -> List(InstrI, FuType.lsu, LSUOpType.lwu), - LD -> List(InstrI, FuType.lsu, LSUOpType.ld), - SD -> List(InstrS, FuType.lsu, LSUOpType.sd) + SUBW -> List(InstrR, FuType.alu, ALUOpType.subw) ) } object RVIInstr extends CoreParameter { - val table = RV32I_ALUInstr.table ++ RV32I_LSUInstr.table ++ + val table = RV32I_ALUInstr.table ++ (if (XLEN == 64) RV64IInstr.table else Array.empty) } diff --git a/chisel/playground/src/pipeline/decode/Decoder.scala b/chisel/playground/src/pipeline/decode/Decoder.scala index be39ab3..db295cc 100644 --- a/chisel/playground/src/pipeline/decode/Decoder.scala +++ b/chisel/playground/src/pipeline/decode/Decoder.scala @@ -25,7 +25,6 @@ class Decoder extends Module with HasInstrType { InstrI -> (SrcType.reg, SrcType.imm), InstrR -> (SrcType.reg, SrcType.reg), InstrS -> (SrcType.reg, SrcType.reg), - InstrSA -> (SrcType.reg, SrcType.reg), InstrB -> (SrcType.reg, SrcType.reg), InstrU -> (SrcType.pc, SrcType.imm), InstrJ -> (SrcType.pc, SrcType.imm), @@ -51,7 +50,6 @@ class Decoder extends Module with HasInstrType { Seq( InstrI -> SignedExtend(inst(31, 20), XLEN), InstrS -> SignedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN), - InstrSA -> SignedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN), InstrB -> SignedExtend(Cat(inst(31), inst(7), inst(30, 25), inst(11, 8), 0.U(1.W)), XLEN), InstrU -> SignedExtend(Cat(inst(31, 12), 0.U(12.W)), XLEN), InstrJ -> SignedExtend(Cat(inst(31), inst(19, 12), inst(20), inst(30, 21), 0.U(1.W)), XLEN) diff --git a/chisel/playground/src/pipeline/execute/Fu.scala b/chisel/playground/src/pipeline/execute/Fu.scala index 25bd445..53177d8 100644 --- a/chisel/playground/src/pipeline/execute/Fu.scala +++ b/chisel/playground/src/pipeline/execute/Fu.scala @@ -9,10 +9,10 @@ import cpu.CpuConfig class Fu extends Module { val io = IO(new Bundle { val data = new Bundle { - val pc = Input(UInt(XLEN.W)) - val info = Input(new Info()) - val src_info = Input(new SrcInfo()) - val rd_info = Output(new RdInfo()) + val pc = Input(UInt(XLEN.W)) + val info = Input(new Info()) + val src_info = Input(new SrcInfo()) + val rd_info = Output(new RdInfo()) } val dataSram = new DataSram() @@ -20,7 +20,11 @@ class Fu extends Module { val alu = Module(new Alu()).io val mdu = Module(new Mdu()).io - val lsu = Module(new Lsu()).io + + io.dataSram.en := false.B + io.dataSram.addr := DontCare + io.dataSram.wdata := DontCare + io.dataSram.wen := 0.U alu.info := io.data.info alu.src_info := io.data.src_info @@ -28,10 +32,6 @@ class Fu extends Module { mdu.info := io.data.info mdu.src_info := io.data.src_info - lsu.info := io.data.info - lsu.src_info := io.data.src_info - lsu.dataSram <> io.dataSram - io.data.rd_info.wdata := DontCare io.data.rd_info.wdata(FuType.alu) := alu.result io.data.rd_info.wdata(FuType.mdu) := mdu.result diff --git a/chisel/playground/src/pipeline/execute/fu/Lsu.scala b/chisel/playground/src/pipeline/execute/fu/Lsu.scala deleted file mode 100644 index 301c409..0000000 --- a/chisel/playground/src/pipeline/execute/fu/Lsu.scala +++ /dev/null @@ -1,131 +0,0 @@ -package cpu.pipeline - -import chisel3._ -import chisel3.util._ -import cpu.defines._ -import cpu.defines.Const._ -import cpu.CpuConfig -import chisel3.util.experimental.BoringUtils - -class Lsu extends Module { - val io = IO(new Bundle { - val info = Input(new Info()) - val src_info = Input(new SrcInfo()) - val dataSram = new DataSram() - }) - - def genWmask(addr: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> 0x1.U, //0001 << addr(2:0) - "b01".U -> 0x3.U, //0011 - "b10".U -> 0xf.U, //1111 - "b11".U -> 0xff.U //11111111 - ) - ) << addr(2, 0) - } - def genWdata(data: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> Fill(8, data(7, 0)), - "b01".U -> Fill(4, data(15, 0)), - "b10".U -> Fill(2, data(31, 0)), - "b11".U -> data - ) - ) - } - - def genWmask32(addr: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> 0x1.U, //0001 << addr(1:0) - "b01".U -> 0x3.U, //0011 - "b10".U -> 0xf.U //1111 - ) - ) << addr(1, 0) - } - def genWdata32(data: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> Fill(4, data(7, 0)), - "b01".U -> Fill(2, data(15, 0)), - "b10".U -> data - ) - ) - } - - val valid = io.info.valid && io.info.fusel === FuType.lsu - val op = io.info.op - val is_load = valid && LSUOpType.isLoad(op) - val is_store = valid && LSUOpType.isStore(op) - val addr = io.src_info.src1_data + io.info.imm - val wdata = io.src_info.src2_data - val size = op(1, 0) - val req_addr = if (XLEN == 32) SignedExtend(addr, XLEN) else addr - val req_wdata = if (XLEN == 32) genWdata32(wdata, size) else genWdata(wdata, size) - val req_wmask = if (XLEN == 32) genWmask32(addr, size) else genWmask(addr, size) - val rdata = io.dataSram.rdata - - val mem_op = Wire(FuOpType()) - val mem_addr = Wire(UInt(XLEN.W)) - val mem_partial_load = !LSUOpType.isStore(mem_op) && (mem_op =/= LSUOpType.ld) - - val rdata64 = LookupTree( - mem_addr(2, 0), - List( - "b000".U -> rdata(63, 0), - "b001".U -> rdata(63, 8), - "b010".U -> rdata(63, 16), - "b011".U -> rdata(63, 24), - "b100".U -> rdata(63, 32), - "b101".U -> rdata(63, 40), - "b110".U -> rdata(63, 48), - "b111".U -> rdata(63, 56) - ) - ) - val rdata32 = LookupTree( - mem_addr(1, 0), - List( - "b00".U -> rdata(31, 0), - "b01".U -> rdata(31, 8), - "b10".U -> rdata(31, 16), - "b11".U -> rdata(31, 24) - ) - ) - val rdata_result = if (XLEN == 32) rdata32 else rdata64 - val rdata_partial_result = LookupTree( - mem_op, - List( - LSUOpType.lb -> SignedExtend(rdata_result(7, 0), XLEN), - LSUOpType.lh -> SignedExtend(rdata_result(15, 0), XLEN), - LSUOpType.lw -> SignedExtend(rdata_result(31, 0), XLEN), - LSUOpType.lbu -> ZeroExtend(rdata_result(7, 0), XLEN), - LSUOpType.lhu -> ZeroExtend(rdata_result(15, 0), XLEN), - LSUOpType.lwu -> ZeroExtend(rdata_result(31, 0), XLEN) - ) - ) - val addr_aligned = LookupTree( - op(1, 0), - List( - "b00".U -> true.B, //b - "b01".U -> (addr(0) === 0.U), //h - "b10".U -> (addr(1, 0) === 0.U), //w - "b11".U -> (addr(2, 0) === 0.U) //d - ) - ) - - io.dataSram.en := valid && addr_aligned - io.dataSram.wen := req_wmask & Fill(8, is_store) - io.dataSram.addr := req_addr // 在mem被阻塞时,保持原先的读地址不变 - io.dataSram.wdata := req_wdata - - val result = Wire(UInt(XLEN.W)) - result := Mux(mem_partial_load, rdata_partial_result, rdata_result) - BoringUtils.addSource(result, "mem_lsu_rdata") - BoringUtils.addSink(mem_op, "mem_lsu_op") - BoringUtils.addSink(mem_addr, "mem_lsu_addr") -} diff --git a/chisel/playground/src/pipeline/memory/MemoryUnit.scala b/chisel/playground/src/pipeline/memory/MemoryUnit.scala index 82705ed..049b4d1 100644 --- a/chisel/playground/src/pipeline/memory/MemoryUnit.scala +++ b/chisel/playground/src/pipeline/memory/MemoryUnit.scala @@ -13,17 +13,7 @@ class MemoryUnit extends Module { val writeBackStage = Output(new MemoryUnitWriteBackUnit()) }) - val rdata = Wire(UInt(XLEN.W)) - val op = Wire(FuOpType()) - val addr = Wire(UInt(XLEN.W)) - op := io.memoryStage.data.info.op - addr := io.memoryStage.data.src_info.src1_data + io.memoryStage.data.info.imm - BoringUtils.addSink(rdata, "mem_lsu_rdata") - BoringUtils.addSource(op, "mem_lsu_op") - BoringUtils.addSource(addr, "mem_lsu_addr") - io.writeBackStage.data.pc := io.memoryStage.data.pc io.writeBackStage.data.info := io.memoryStage.data.info io.writeBackStage.data.rd_info.wdata := io.memoryStage.data.rd_info.wdata - io.writeBackStage.data.rd_info.wdata(FuType.lsu) := rdata }