diff --git a/chisel/playground/src/Core.scala b/chisel/playground/src/Core.scala index 5c28a4b..5940569 100644 --- a/chisel/playground/src/Core.scala +++ b/chisel/playground/src/Core.scala @@ -80,9 +80,9 @@ class Core(implicit val cpuConfig: CpuConfig) extends Module { decodeUnit.instFifo.info.almost_empty := instFifo.almost_empty decodeUnit.regfile <> regfile.read for (i <- 0 until (cpuConfig.commitNum)) { - decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe - decodeUnit.forward(i).mem_wreg := executeUnit.decodeUnit.forward(i).exe_mem_wreg - decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i) + decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe + decodeUnit.forward(i).is_load := executeUnit.decodeUnit.forward(i).is_load // exe级是load指令 + decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i) } decodeUnit.csr <> csr.decodeUnit decodeUnit.executeStage <> executeStage.decodeUnit diff --git a/chisel/playground/src/ctrl/Ctrl.scala b/chisel/playground/src/ctrl/Ctrl.scala index cbbf300..0089aad 100644 --- a/chisel/playground/src/ctrl/Ctrl.scala +++ b/chisel/playground/src/ctrl/Ctrl.scala @@ -16,16 +16,16 @@ class Ctrl(implicit val cpuConfig: CpuConfig) extends Module { val writeBackUnit = Flipped(new WriteBackCtrl()) }) - val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) && io.executeUnit.inst(0).reg_waddr.orR && + val inst0_lw_stall = (io.executeUnit.inst(0).is_load) && io.executeUnit.inst(0).reg_waddr.orR && (io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr || io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr) - val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) && io.executeUnit.inst(1).reg_waddr.orR && + val inst1_lw_stall = (io.executeUnit.inst(1).is_load) && io.executeUnit.inst(1).reg_waddr.orR && (io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr || io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr) val lw_stall = inst0_lw_stall || inst1_lw_stall // TODO: 这里的stall信号可以改进,尝试让前后端完全解耦 val longest_stall = - io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall + io.executeUnit.fu.stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall io.decodeUnit.allow_to_go := !(lw_stall || longest_stall) diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index f2225bb..4490504 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -46,7 +46,7 @@ class InstInfo extends Bundle { } class MemRead extends Bundle { - val mem_wreg = Bool() + val is_load = Bool() val reg_waddr = UInt(REG_ADDR_WID.W) } @@ -77,12 +77,12 @@ class DecodeUnitCtrl extends Bundle { class ExecuteFuCtrl extends Bundle { val allow_to_go = Input(Bool()) + val stall = Output(Bool()) } class ExecuteCtrl(implicit val cpuConfig: CpuConfig) extends Bundle { - val inst = Output(Vec(cpuConfig.commitNum, new MemRead())) - val fu_stall = Output(Bool()) - val flush = Output(Bool()) + val inst = Output(Vec(cpuConfig.commitNum, new MemRead())) + val flush = Output(Bool()) val allow_to_go = Input(Bool()) val do_flush = Input(Bool()) diff --git a/chisel/playground/src/pipeline/decode/DecodeUnit.scala b/chisel/playground/src/pipeline/decode/DecodeUnit.scala index fb08559..5ccfb8e 100644 --- a/chisel/playground/src/pipeline/decode/DecodeUnit.scala +++ b/chisel/playground/src/pipeline/decode/DecodeUnit.scala @@ -21,7 +21,7 @@ class DecodeUnitInstFifo(implicit val cpuConfig: CpuConfig) extends Bundle { class DataForwardToDecodeUnit extends Bundle { val exe = new RegWrite() - val mem_wreg = Bool() + val is_load = Bool() val mem = new RegWrite() } @@ -74,7 +74,7 @@ class DecodeUnit(implicit val cpuConfig: CpuConfig) extends Module with HasExcep for (i <- 0 until (cpuConfig.decoderNum)) { decoder(i).io.in.inst := inst(i) issue.decodeInst(i) := info(i) - issue.execute(i).mem_wreg := io.forward(i).mem_wreg + issue.execute(i).is_load := io.forward(i).is_load issue.execute(i).reg_waddr := io.forward(i).exe.waddr io.regfile(i).src1.raddr := info(i).src1_raddr io.regfile(i).src2.raddr := info(i).src2_raddr diff --git a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala b/chisel/playground/src/pipeline/decode/ForwardCtrl.scala index 9ef1a66..c1c1ebf 100644 --- a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala +++ b/chisel/playground/src/pipeline/decode/ForwardCtrl.scala @@ -48,13 +48,13 @@ class ForwardCtrl(implicit val cpuConfig: CpuConfig) extends Module { for (i <- 0 until (cpuConfig.decoderNum)) { for (j <- 0 until (cpuConfig.commitNum)) { when( - io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg && + io.in.forward(j).exe.wen && !io.in.forward(j).is_load && io.in.forward(j).exe.waddr === io.in.regfile(i).src1.raddr ) { io.out.inst(i).src1.rdata := io.in.forward(j).exe.wdata } when( - io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg && + io.in.forward(j).exe.wen && !io.in.forward(j).is_load && io.in.forward(j).exe.waddr === io.in.regfile(i).src2.raddr ) { io.out.inst(i).src2.rdata := io.in.forward(j).exe.wdata diff --git a/chisel/playground/src/pipeline/decode/Issue.scala b/chisel/playground/src/pipeline/decode/Issue.scala index 1addeb1..8878ec8 100644 --- a/chisel/playground/src/pipeline/decode/Issue.scala +++ b/chisel/playground/src/pipeline/decode/Issue.scala @@ -38,10 +38,10 @@ class Issue(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst { // 写后读冲突 val load_stall = - io.execute(0).mem_wreg && io.execute(0).reg_waddr.orR && + io.execute(0).is_load && io.execute(0).reg_waddr.orR && (inst1.src1_ren && inst1.src1_raddr === io.execute(0).reg_waddr || inst1.src2_ren && inst1.src2_raddr === io.execute(0).reg_waddr) || - io.execute(1).mem_wreg && io.execute(1).reg_waddr.orR && + io.execute(1).is_load && io.execute(1).reg_waddr.orR && (inst1.src1_ren && inst1.src1_raddr === io.execute(1).reg_waddr || inst1.src2_ren && inst1.src2_raddr === io.execute(1).reg_waddr) val raw_reg = // inst1的源操作数是inst0的目的操作数 diff --git a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala index ec3668d..ac04fab 100644 --- a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala +++ b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala @@ -24,8 +24,8 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module { Vec( cpuConfig.commitNum, new Bundle { - val exe = new RegWrite() - val exe_mem_wreg = Bool() + val exe = new RegWrite() + val is_load = Bool() } ) ) @@ -36,74 +36,35 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module { } }) - val fu = Module(new Fu()).io + val valid = io.executeStage.inst.map(_.info.valid && io.ctrl.allow_to_go) + val fusel = io.executeStage.inst.map(_.info.fusel) - val valid = VecInit( - io.executeStage.inst(0).info.valid && io.ctrl.allow_to_go, - io.executeStage.inst(1).info.valid && io.ctrl.allow_to_go - ) - - val fusel = VecInit( - io.executeStage.inst(0).info.fusel, - io.executeStage.inst(1).info.fusel - ) + io.ctrl.flush := io.fetchUnit.flush + for (i <- 0 until (cpuConfig.commitNum)) { + io.ctrl.inst(i).is_load := + io.executeStage.inst(i).info.fusel === FuType.lsu && io.executeStage.inst(i).info.reg_wen + io.ctrl.inst(i).reg_waddr := io.executeStage.inst(i).info.reg_waddr + } val is_csr = VecInit( - fusel(0) === FuType.csr && valid(0) && - !(HasExcInt(io.executeStage.inst(0).ex)), - fusel(1) === FuType.csr && valid(1) && - !(HasExcInt(io.executeStage.inst(1).ex)) + Seq.tabulate(cpuConfig.commitNum)(i => + fusel(i) === FuType.csr && valid(i) && !(HasExcInt(io.executeStage.inst(i).ex)) + ) ) - val mem_wreg = VecInit( - io.executeStage.inst(0).info.fusel === FuType.lsu && io.executeStage.inst(0).info.reg_wen, - io.executeStage.inst(1).info.fusel === FuType.lsu && io.executeStage.inst(1).info.reg_wen - ) - - io.ctrl.inst(0).mem_wreg := mem_wreg(0) - io.ctrl.inst(0).reg_waddr := io.executeStage.inst(0).info.reg_waddr - io.ctrl.inst(1).mem_wreg := mem_wreg(1) - io.ctrl.inst(1).reg_waddr := io.executeStage.inst(1).info.reg_waddr - io.ctrl.flush := io.fetchUnit.flush - io.csr.in.valid := is_csr.asUInt.orR - io.csr.in.pc := MuxCase( - 0.U, - Seq( - is_csr(0) -> io.executeStage.inst(0).pc, - is_csr(1) -> io.executeStage.inst(1).pc - ) - ) - io.csr.in.info := MuxCase( - 0.U.asTypeOf(new InstInfo()), - Seq( - is_csr(0) -> io.executeStage.inst(0).info, - is_csr(1) -> io.executeStage.inst(1).info - ) - ) - io.csr.in.src_info := MuxCase( - 0.U.asTypeOf(new SrcInfo()), - Seq( - is_csr(0) -> io.executeStage.inst(0).src_info, - is_csr(1) -> io.executeStage.inst(1).src_info - ) - ) - io.csr.in.ex := MuxCase( - 0.U.asTypeOf(new ExceptionInfo()), - Seq( - is_csr(0) -> io.executeStage.inst(0).ex, - is_csr(1) -> io.executeStage.inst(1).ex - ) - ) - val is_lsu = VecInit( - fusel(0) === FuType.lsu && valid(0) && - !(HasExcInt(io.executeStage.inst(0).ex)), - fusel(1) === FuType.lsu && valid(1) && - !(HasExcInt(io.executeStage.inst(1).ex)) - ) + def selectInstField[T <: Data](select: Vec[Bool], fields: Seq[T]): T = { + require(select.length == fields.length) + Mux1H(select.zip(fields)) + } - // input fu + io.csr.in.pc := selectInstField(is_csr, io.executeStage.inst.map(_.pc)) + io.csr.in.info := selectInstField(is_csr, io.executeStage.inst.map(_.info)) + io.csr.in.src_info := selectInstField(is_csr, io.executeStage.inst.map(_.src_info)) + io.csr.in.ex := selectInstField(is_csr, io.executeStage.inst.map(_.ex)) + + val fu = Module(new Fu()).io fu.ctrl <> io.ctrl.fu for (i <- 0 until (cpuConfig.commitNum)) { fu.inst(i).pc := io.executeStage.inst(i).pc @@ -121,12 +82,9 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module { io.bpu.branch := fu.branch.branch io.bpu.branch_inst := io.executeStage.jump_branch_info.branch_inst - io.fetchUnit.flush := valid(0) && io.ctrl.allow_to_go && - (fu.branch.flush || io.csr.out.flush) + io.fetchUnit.flush := valid(0) && io.ctrl.allow_to_go && (fu.branch.flush || io.csr.out.flush) io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.target, fu.branch.target) - io.ctrl.fu_stall := fu.stall_req - for (i <- 0 until (cpuConfig.commitNum)) { io.memoryStage.inst(i).pc := io.executeStage.inst(i).pc io.memoryStage.inst(i).info := io.executeStage.inst(i).info @@ -154,9 +112,9 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module { io.fetchUnit.target ) - io.decodeUnit.forward(i).exe.wen := io.memoryStage.inst(i).info.reg_wen - io.decodeUnit.forward(i).exe.waddr := io.memoryStage.inst(i).info.reg_waddr - io.decodeUnit.forward(i).exe.wdata := io.memoryStage.inst(i).rd_info.wdata(io.memoryStage.inst(i).info.fusel) - io.decodeUnit.forward(i).exe_mem_wreg := io.ctrl.inst(i).mem_wreg + io.decodeUnit.forward(i).exe.wen := io.memoryStage.inst(i).info.reg_wen + io.decodeUnit.forward(i).exe.waddr := io.memoryStage.inst(i).info.reg_waddr + io.decodeUnit.forward(i).exe.wdata := io.memoryStage.inst(i).rd_info.wdata(io.memoryStage.inst(i).info.fusel) + io.decodeUnit.forward(i).is_load := io.ctrl.inst(i).is_load } } diff --git a/chisel/playground/src/pipeline/execute/Fu.scala b/chisel/playground/src/pipeline/execute/Fu.scala index 1089656..cbf8267 100644 --- a/chisel/playground/src/pipeline/execute/Fu.scala +++ b/chisel/playground/src/pipeline/execute/Fu.scala @@ -21,7 +21,6 @@ class Fu(implicit val cpuConfig: CpuConfig) extends Module { }) } ) - val stall_req = Output(Bool()) val dataMemory = new Bundle { val addr = Output(UInt(XLEN.W)) } @@ -71,7 +70,7 @@ class Fu(implicit val cpuConfig: CpuConfig) extends Module { ) mdu.allow_to_go := io.ctrl.allow_to_go - io.stall_req := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready + io.ctrl.stall := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready io.inst(0).result.alu := alu(0).io.result io.inst(0).result.mdu := mdu.result