From d2bc851cf721cd5e6ff8ab9b634376208ef55f27 Mon Sep 17 00:00:00 2001 From: Liphen Date: Mon, 27 May 2024 09:54:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=B0=94=E6=B3=A1=E6=B5=81?= =?UTF-8?q?=E6=B0=B4=E7=BA=BF=E5=A4=A7=E8=87=B4=E4=BB=A3=E7=A0=81=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chisel/playground/src/Core.scala | 3 - chisel/playground/src/ctrl/Ctrl.scala | 26 ++++++-- chisel/playground/src/defines/Bundles.scala | 17 ++--- .../src/defines/isa/Instructions.scala | 3 +- .../src/pipeline/decode/ARegfile.scala | 6 -- .../src/pipeline/decode/DecodeUnit.scala | 23 ++----- .../src/pipeline/decode/Decoder.scala | 1 - .../src/pipeline/decode/ForwardCtrl.scala | 62 ------------------- .../src/pipeline/execute/ExecuteUnit.scala | 33 +++------- .../src/pipeline/memory/MemoryUnit.scala | 5 +- .../pipeline/writeback/WriteBackUnit.scala | 2 + 11 files changed, 44 insertions(+), 137 deletions(-) delete mode 100644 chisel/playground/src/pipeline/decode/ForwardCtrl.scala diff --git a/chisel/playground/src/Core.scala b/chisel/playground/src/Core.scala index 6b0afbf..2431d85 100644 --- a/chisel/playground/src/Core.scala +++ b/chisel/playground/src/Core.scala @@ -46,9 +46,6 @@ class Core extends Module { decodeStage.decodeUnit <> decodeUnit.decodeStage // 译码单元 decodeUnit.regfile <> regfile.read - decodeUnit.forward.exe := executeUnit.decodeUnit.forward.exe - decodeUnit.forward.is_load := executeUnit.decodeUnit.forward.is_load // exe级是load指令 - decodeUnit.forward.mem := memoryUnit.decodeUnit decodeUnit.executeStage <> executeStage.decodeUnit // 执行级缓存 diff --git a/chisel/playground/src/ctrl/Ctrl.scala b/chisel/playground/src/ctrl/Ctrl.scala index 67b5e99..6ab8d38 100644 --- a/chisel/playground/src/ctrl/Ctrl.scala +++ b/chisel/playground/src/ctrl/Ctrl.scala @@ -15,12 +15,28 @@ class Ctrl extends Module { val writeBackUnit = Flipped(new WriteBackCtrl()) }) - val lw_stall = (io.executeUnit.data.is_load) && io.executeUnit.data.reg_waddr.orR && - (io.decodeUnit.src_info.src1.ren && io.decodeUnit.src_info.src1.raddr === io.executeUnit.data.reg_waddr || - io.decodeUnit.src_info.src2.ren && io.decodeUnit.src_info.src2.raddr === io.executeUnit.data.reg_waddr) + // 数据冲突的条件是: + // 1. 对应单元的指令有效 + // 2. 对应单元的指令写寄存器 + // 3. 对应单元的指令写寄存器地址与当前单元的指令读寄存器地址冲突 + val exe_conflict = io.executeUnit.info.valid && + io.executeUnit.info.reg_wen && + io.executeUnit.info.reg_waddr.orR && + (io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.executeUnit.info.reg_waddr || + io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.executeUnit.info.reg_waddr) + val mem_conflict = io.memoryUnit.info.valid && + io.memoryUnit.info.reg_wen && + io.memoryUnit.info.reg_waddr.orR && + (io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.memoryUnit.info.reg_waddr || + io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.memoryUnit.info.reg_waddr) + val wb_conflict = io.writeBackUnit.info.valid && + io.writeBackUnit.info.reg_wen && + io.writeBackUnit.info.reg_waddr.orR && + (io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.writeBackUnit.info.reg_waddr || + io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.writeBackUnit.info.reg_waddr) - io.fetchUnit.ctrlSignal.allow_to_go := !lw_stall - io.decodeUnit.ctrlSignal.allow_to_go := !lw_stall + io.fetchUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict) + io.decodeUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict) io.executeUnit.ctrlSignal.allow_to_go := true.B io.memoryUnit.ctrlSignal.allow_to_go := true.B io.writeBackUnit.ctrlSignal.allow_to_go := true.B diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index 6570c80..cb70f93 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -23,7 +23,6 @@ class RdInfo extends Bundle { class Info extends Bundle { val valid = Bool() - val inst_legal = Bool() val src1_ren = Bool() val src1_raddr = UInt(REG_ADDR_WID.W) val src2_ren = Bool() @@ -36,11 +35,6 @@ class Info extends Bundle { val inst = UInt(XLEN.W) } -class MemRead extends Bundle { - val is_load = Bool() - val reg_waddr = UInt(REG_ADDR_WID.W) -} - class SrcReadSignal extends Bundle { val ren = Bool() val raddr = UInt(REG_ADDR_WID.W) @@ -57,16 +51,13 @@ class FetchUnitCtrl extends Bundle { } class DecodeUnitCtrl extends Bundle { - val src_info = Output(new Bundle { - val src1 = new SrcReadSignal() - val src2 = new SrcReadSignal() - }) + val info = Output(new Info()) val ctrlSignal = Input(new CtrlSignal()) } class ExecuteCtrl extends Bundle { - val data = Output(new MemRead()) + val info = Output(new Info()) val flush = Output(Bool()) val target = Output(UInt(XLEN.W)) @@ -74,10 +65,14 @@ class ExecuteCtrl extends Bundle { } class MemoryCtrl extends Bundle { + val info = Output(new Info()) + val ctrlSignal = Input(new CtrlSignal()) } class WriteBackCtrl extends Bundle { + val info = Output(new Info()) + val ctrlSignal = Input(new CtrlSignal()) } diff --git a/chisel/playground/src/defines/isa/Instructions.scala b/chisel/playground/src/defines/isa/Instructions.scala index d5783be..e6a7d26 100644 --- a/chisel/playground/src/defines/isa/Instructions.scala +++ b/chisel/playground/src/defines/isa/Instructions.scala @@ -77,7 +77,7 @@ object BRUOpType { } // load store unit -object LSUOpType { //TODO: refactor LSU fuop +object LSUOpType { def lb = "b0000".U def lh = "b0001".U def lw = "b0010".U @@ -115,4 +115,3 @@ object MDUOpType { def isDivSign(op: UInt) = isDiv(op) && !op(0) def isWordOp(op: UInt) = op(3) } - diff --git a/chisel/playground/src/pipeline/decode/ARegfile.scala b/chisel/playground/src/pipeline/decode/ARegfile.scala index 3c12d76..59518d5 100644 --- a/chisel/playground/src/pipeline/decode/ARegfile.scala +++ b/chisel/playground/src/pipeline/decode/ARegfile.scala @@ -42,17 +42,11 @@ class ARegFile extends Module { io.read.src1.rdata := 0.U }.otherwise { io.read.src1.rdata := regs(io.read.src1.raddr) - when(io.write.wen && io.read.src1.raddr === io.write.waddr) { - io.read.src1.rdata := io.write.wdata - } } // src2 when(io.read.src2.raddr === 0.U) { io.read.src2.rdata := 0.U }.otherwise { io.read.src2.rdata := regs(io.read.src2.raddr) - when(io.write.wen && io.read.src2.raddr === io.write.waddr) { - io.read.src2.rdata := io.write.wdata - } } } diff --git a/chisel/playground/src/pipeline/decode/DecodeUnit.scala b/chisel/playground/src/pipeline/decode/DecodeUnit.scala index b6e9519..8966ff8 100644 --- a/chisel/playground/src/pipeline/decode/DecodeUnit.scala +++ b/chisel/playground/src/pipeline/decode/DecodeUnit.scala @@ -5,19 +5,12 @@ import chisel3.util._ import cpu.defines._ import cpu.defines.Const._ -class DataForwardToDecodeUnit extends Bundle { - val exe = new RegWrite() - val is_load = Bool() - val mem = new RegWrite() -} - class DecodeUnit extends Module { val io = IO(new Bundle { - val ctrl = new DecodeUnitCtrl() + val ctrl = new DecodeUnitCtrl() // 输入 val decodeStage = Flipped(new FetchUnitDecodeUnit()) val regfile = new Src12Read() - val forward = Input(new DataForwardToDecodeUnit()) // 输出 val executeStage = Output(new DecodeUnitExecuteUnit()) }) @@ -25,37 +18,29 @@ class DecodeUnit extends Module { val decoder = Module(new Decoder()).io decoder.in.inst := io.decodeStage.data.inst - val forwardCtrl = Module(new ForwardCtrl()).io - val pc = io.decodeStage.data.pc val info = Wire(new Info()) info := decoder.out.info info.valid := io.decodeStage.data.valid - forwardCtrl.in.forward := io.forward - forwardCtrl.in.regfile := io.regfile - io.regfile.src1.raddr := info.src1_raddr io.regfile.src2.raddr := info.src2_raddr - io.ctrl.src_info.src1.ren := info.src1_ren - io.ctrl.src_info.src1.raddr := info.src1_raddr - io.ctrl.src_info.src2.ren := info.src2_ren - io.ctrl.src_info.src2.raddr := info.src2_raddr + io.ctrl.info := info io.executeStage.data.pc := pc io.executeStage.data.info := info io.executeStage.data.src_info.src1_data := MuxCase( SignedExtend(pc, XLEN), Seq( - info.src1_ren -> forwardCtrl.out.data.src1.rdata, + info.src1_ren -> io.regfile.src1.rdata, (info.inst(6, 0) === "b0110111".U) -> 0.U ) ) io.executeStage.data.src_info.src2_data := Mux( info.src2_ren, - forwardCtrl.out.data.src2.rdata, + io.regfile.src2.rdata, info.imm ) } diff --git a/chisel/playground/src/pipeline/decode/Decoder.scala b/chisel/playground/src/pipeline/decode/Decoder.scala index f0ba433..be39ab3 100644 --- a/chisel/playground/src/pipeline/decode/Decoder.scala +++ b/chisel/playground/src/pipeline/decode/Decoder.scala @@ -38,7 +38,6 @@ class Decoder extends Module with HasInstrType { io.out.info.valid := false.B io.out.info.inst := inst - io.out.info.inst_legal := instrType =/= InstrN io.out.info.src1_ren := src1Type === SrcType.reg io.out.info.src1_raddr := Mux(io.out.info.src1_ren, rs, 0.U) io.out.info.src2_ren := src2Type === SrcType.reg diff --git a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala b/chisel/playground/src/pipeline/decode/ForwardCtrl.scala deleted file mode 100644 index b16283e..0000000 --- a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala +++ /dev/null @@ -1,62 +0,0 @@ -package cpu.pipeline - -import chisel3._ -import chisel3.util._ - -import cpu.defines._ -import cpu.defines.Const._ -import cpu.CpuConfig - -class ForwardCtrl extends Module { - val io = IO(new Bundle { - val in = Input(new Bundle { - val forward = new DataForwardToDecodeUnit() - val regfile = new Src12Read() - }) - val out = Output(new Bundle { - val data = new Src12Read() - }) - }) - - // wb优先度最低 - io.out.data.src1.raddr := DontCare - io.out.data.src2.raddr := DontCare - io.out.data.src1.rdata := io.in.regfile.src1.rdata - io.out.data.src2.rdata := io.in.regfile.src2.rdata - - // mem优先度中 - when( - io.in.forward.mem.wen && - io.in.forward.mem.waddr === io.in.regfile.src1.raddr - ) { - io.out.data.src1.rdata := io.in.forward.mem.wdata - } - when( - io.in.forward.mem.wen && - io.in.forward.mem.waddr === io.in.regfile.src2.raddr - ) { - io.out.data.src2.rdata := io.in.forward.mem.wdata - } - - // exe优先度高 - when( - io.in.forward.exe.wen && !io.in.forward.is_load && - io.in.forward.exe.waddr === io.in.regfile.src1.raddr - ) { - io.out.data.src1.rdata := io.in.forward.exe.wdata - } - when( - io.in.forward.exe.wen && !io.in.forward.is_load && - io.in.forward.exe.waddr === io.in.regfile.src2.raddr - ) { - io.out.data.src2.rdata := io.in.forward.exe.wdata - } - - // 读零寄存器时,数据为0 - when(io.in.regfile.src1.raddr === 0.U) { - io.out.data.src1.rdata := 0.U - } - when(io.in.regfile.src2.raddr === 0.U) { - io.out.data.src2.rdata := 0.U - } -} diff --git a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala index f8a7050..f8d51e5 100644 --- a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala +++ b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala @@ -11,16 +11,8 @@ class ExecuteUnit extends Module { val io = IO(new Bundle { val ctrl = new ExecuteCtrl() val executeStage = Input(new DecodeUnitExecuteUnit()) - val decodeUnit = new Bundle { - val forward = Output( - new Bundle { - val exe = new RegWrite() - val is_load = Bool() - } - ) - } - val memoryStage = Output(new ExecuteUnitMemoryUnit()) - val dataSram = new DataSram() + val memoryStage = Output(new ExecuteUnitMemoryUnit()) + val dataSram = new DataSram() }) val allow_to_go = io.ctrl.ctrlSignal.allow_to_go @@ -36,19 +28,12 @@ class ExecuteUnit extends Module { io.dataSram <> fu.dataSram - io.ctrl.data.is_load := fusel === FuType.lsu && LSUOpType.isLoad(io.executeStage.data.info.op) - io.ctrl.data.reg_waddr := io.executeStage.data.info.reg_waddr - io.ctrl.flush := valid && fu.ctrl.flush - io.ctrl.target := fu.ctrl.target + io.ctrl.flush := valid && fu.ctrl.flush + io.ctrl.target := fu.ctrl.target + io.ctrl.info := io.executeStage.data.info - io.memoryStage.data.pc := io.executeStage.data.pc - io.memoryStage.data.info := io.executeStage.data.info - io.memoryStage.data.src_info := io.executeStage.data.src_info - io.memoryStage.data.rd_info := fu.data.rd_info - - // 数据前递 - io.decodeUnit.forward.exe.wen := io.memoryStage.data.info.reg_wen - io.decodeUnit.forward.exe.waddr := io.memoryStage.data.info.reg_waddr - io.decodeUnit.forward.exe.wdata := io.memoryStage.data.rd_info.wdata(io.memoryStage.data.info.fusel) - io.decodeUnit.forward.is_load := io.ctrl.data.is_load + io.memoryStage.data.pc := io.executeStage.data.pc + io.memoryStage.data.info := io.executeStage.data.info + io.memoryStage.data.src_info := io.executeStage.data.src_info + io.memoryStage.data.rd_info := fu.data.rd_info } diff --git a/chisel/playground/src/pipeline/memory/MemoryUnit.scala b/chisel/playground/src/pipeline/memory/MemoryUnit.scala index 8d4ee17..89ae6d0 100644 --- a/chisel/playground/src/pipeline/memory/MemoryUnit.scala +++ b/chisel/playground/src/pipeline/memory/MemoryUnit.scala @@ -11,7 +11,6 @@ class MemoryUnit extends Module { val io = IO(new Bundle { val ctrl = new MemoryCtrl() val memoryStage = Input(new ExecuteUnitMemoryUnit()) - val decodeUnit = Output(new RegWrite()) val writeBackStage = Output(new MemoryUnitWriteBackUnit()) }) @@ -24,9 +23,7 @@ class MemoryUnit extends Module { BoringUtils.addSource(op, "mem_lsu_op") BoringUtils.addSource(addr, "mem_lsu_addr") - io.decodeUnit.wen := io.writeBackStage.data.info.reg_wen - io.decodeUnit.waddr := io.writeBackStage.data.info.reg_waddr - io.decodeUnit.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel) + io.ctrl.info := io.memoryStage.data.info io.writeBackStage.data.pc := io.memoryStage.data.pc io.writeBackStage.data.info := io.memoryStage.data.info diff --git a/chisel/playground/src/pipeline/writeback/WriteBackUnit.scala b/chisel/playground/src/pipeline/writeback/WriteBackUnit.scala index bc561c3..927feb4 100644 --- a/chisel/playground/src/pipeline/writeback/WriteBackUnit.scala +++ b/chisel/playground/src/pipeline/writeback/WriteBackUnit.scala @@ -22,6 +22,8 @@ class WriteBackUnit extends Module { io.regfile.waddr := io.writeBackStage.data.info.reg_waddr io.regfile.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel) + io.ctrl.info := io.writeBackStage.data.info + io.debug.pc := io.writeBackStage.data.pc io.debug.commit := io.writeBackStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go io.debug.rf_wnum := io.regfile.waddr