diff --git a/chisel/playground/src/pipeline/decode/ARegfile.scala b/chisel/playground/src/pipeline/decode/ARegfile.scala index 27c24a5..e0535af 100644 --- a/chisel/playground/src/pipeline/decode/ARegfile.scala +++ b/chisel/playground/src/pipeline/decode/ARegfile.scala @@ -24,43 +24,35 @@ class RegWrite extends Bundle { class ARegFile(implicit val cpuConfig: CpuConfig) extends Module { val io = IO(new Bundle { - val read = Flipped(Vec(cpuConfig.decoderNum, new Src12Read())) - val write = Flipped(Vec(cpuConfig.commitNum, new RegWrite())) + val read = Flipped(new Src12Read()) + val write = Flipped(new RegWrite()) }) // 定义32个32位寄存器 val regs = RegInit(VecInit(Seq.fill(AREG_NUM)(0.U(XLEN.W)))) // 写寄存器堆 - for (i <- 0 until (cpuConfig.commitNum)) { - when(io.write(i).wen && io.write(i).waddr =/= 0.U) { - regs(io.write(i).waddr) := io.write(i).wdata - } + when(io.write.wen && io.write.waddr =/= 0.U) { + regs(io.write.waddr) := io.write.wdata } // 读寄存器堆 - for (i <- 0 until (cpuConfig.decoderNum)) { - // src1 - when(io.read(i).src1.raddr === 0.U) { - io.read(i).src1.rdata := 0.U - }.otherwise { - io.read(i).src1.rdata := regs(io.read(i).src1.raddr) - for (j <- 0 until (cpuConfig.commitNum)) { - when(io.write(j).wen && io.read(i).src1.raddr === io.write(j).waddr) { - io.read(i).src1.rdata := io.write(j).wdata - } - } + // src1 + when(io.read.src1.raddr === 0.U) { + 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(i).src2.raddr === 0.U) { - io.read(i).src2.rdata := 0.U - }.otherwise { - io.read(i).src2.rdata := regs(io.read(i).src2.raddr) - for (j <- 0 until (cpuConfig.commitNum)) { - when(io.write(j).wen && io.read(i).src2.raddr === io.write(j).waddr) { - io.read(i).src2.rdata := io.write(j).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/DecodeStage.scala b/chisel/playground/src/pipeline/decode/DecodeStage.scala new file mode 100644 index 0000000..e4aa9d2 --- /dev/null +++ b/chisel/playground/src/pipeline/decode/DecodeStage.scala @@ -0,0 +1,38 @@ +package cpu.pipeline.decode + +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ +import cpu.CpuConfig + +class IfIdData extends Bundle { + val inst = UInt(XLEN.W) + val valid = Bool() + val pc = UInt(XLEN.W) + val addr_misaligned = Bool() +} + +class FetchUnitDecodeUnit extends IfIdData { + val data = Output(new IfIdData()) +} + +class DecodeStage(implicit val cpuConfig: CpuConfig) extends Module { + val io = IO(new Bundle { + val ctrl = Input(new Bundle { + val allow_to_go = Bool() + val clear = Bool() + }) + val fetchUnit = Flipped(new FetchUnitDecodeUnit()) + val decodeUnit = new FetchUnitDecodeUnit() + }) + val data = RegInit(0.U.asTypeOf(new IfIdData())) + + when(io.ctrl.clear) { + data := 0.U.asTypeOf(new IfIdData()) + }.elsewhen(io.ctrl.allow_to_go) { + data := io.fetchUnit + } + + io.decodeUnit.data := data +} diff --git a/chisel/playground/src/pipeline/decode/DecodeUnit.scala b/chisel/playground/src/pipeline/decode/DecodeUnit.scala index daa08c7..bafaece 100644 --- a/chisel/playground/src/pipeline/decode/DecodeUnit.scala +++ b/chisel/playground/src/pipeline/decode/DecodeUnit.scala @@ -5,148 +5,60 @@ import chisel3.util._ import chisel3.util.experimental.BoringUtils import cpu.defines._ import cpu.defines.Const._ -import cpu.{BranchPredictorConfig, CpuConfig} import cpu.pipeline.execute.DecodeUnitExecuteUnit -import cpu.pipeline.fetch.IfIdData import cpu.pipeline.execute -class DecodeUnitInstFifo(implicit val cpuConfig: CpuConfig) extends Bundle { - val allow_to_go = Output(Vec(cpuConfig.decoderNum, Bool())) - val inst = Input(Vec(cpuConfig.decoderNum, new IfIdData())) - val info = Input(new Bundle { - val empty = Bool() - val almost_empty = Bool() - }) -} - class DataForwardToDecodeUnit extends Bundle { val exe = new RegWrite() val is_load = Bool() val mem = new RegWrite() } -class DecoderBranchPredictorUnit extends Bundle { - val bpuConfig = new BranchPredictorConfig() - val pc = Output(UInt(XLEN.W)) - val info = Output(new Info()) - val pht_index = Output(UInt(bpuConfig.phtDepth.W)) - - val branch_inst = Input(Bool()) - val branch = Input(Bool()) - val target = Input(UInt(XLEN.W)) - val update_pht_index = Input(UInt(bpuConfig.phtDepth.W)) -} - -class DecodeUnit(implicit val cpuConfig: CpuConfig) extends Module with HasExceptionNO with HasCSRConst { +class DecodeUnit extends Module with HasExceptionNO with HasCSRConst { val io = IO(new Bundle { // 输入 - val instFifo = new DecodeUnitInstFifo() - val regfile = Vec(cpuConfig.decoderNum, new Src12Read()) - val forward = Input(Vec(cpuConfig.commitNum, new DataForwardToDecodeUnit())) - val csr = Input(new execute.CsrDecodeUnit()) + val decodeStage = Flipped(new FetchUnitDecodeUnit()) + val regfile = new Src12Read() + val forward = Input(new DataForwardToDecodeUnit()) // 输出 val fetchUnit = new Bundle { val branch = Output(Bool()) val target = Output(UInt(XLEN.W)) } - val bpu = new DecoderBranchPredictorUnit() val executeStage = Output(new DecodeUnitExecuteUnit()) val ctrl = new DecodeUnitCtrl() }) - val decoder = Seq.fill(cpuConfig.decoderNum)(Module(new Decoder())) - val jumpCtrl = Module(new JumpCtrl()).io + val decoder = Module(new Decoder()) val forwardCtrl = Module(new ForwardCtrl()).io - val issue = Module(new Issue()).io - val pc = io.instFifo.inst.map(_.pc) - val inst = io.instFifo.inst.map(_.inst) - val info = Wire(Vec(cpuConfig.decoderNum, new Info())) - val mode = io.csr.mode + val pc = io.decodeStage.data.pc + val info = Wire(new Info()) - info := decoder.map(_.io.out.info) - info(0).valid := !io.instFifo.info.empty - info(1).valid := !io.instFifo.info.almost_empty && !io.instFifo.info.empty - - issue.allow_to_go := io.ctrl.allow_to_go - issue.instFifo := io.instFifo.info - io.instFifo.allow_to_go(1) := issue.inst1.allow_to_go - for (i <- 0 until (cpuConfig.decoderNum)) { - decoder(i).io.in.inst := inst(i) - issue.decodeInst(i) := info(i) - 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 - } + info := decoder.io.out.info + info.valid := io.decodeStage.data.valid forwardCtrl.in.forward := io.forward forwardCtrl.in.regfile := io.regfile - jumpCtrl.in.info := info(0) - jumpCtrl.in.forward := io.forward - jumpCtrl.in.pc := pc(0) - jumpCtrl.in.src_info := io.executeStage.inst(0).src_info - val inst0_branch = jumpCtrl.out.jump || io.bpu.branch + 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.branch := io.fetchUnit.branch - io.fetchUnit.branch := inst0_branch && io.ctrl.allow_to_go - io.fetchUnit.target := Mux(io.bpu.branch, io.bpu.target, jumpCtrl.out.jump_target) - - io.instFifo.allow_to_go(0) := io.ctrl.allow_to_go - io.bpu.pc := pc(0) - io.bpu.info := info(0) - io.bpu.pht_index := io.instFifo.inst(0).pht_index - - io.ctrl.inst0.src1.ren := info(0).src1_ren - io.ctrl.inst0.src1.raddr := info(0).src1_raddr - io.ctrl.inst0.src2.ren := info(0).src2_ren - io.ctrl.inst0.src2.raddr := info(0).src2_raddr - io.ctrl.branch := io.fetchUnit.branch - - io.executeStage.jump_branch_info.jump_regiser := jumpCtrl.out.jump_register - io.executeStage.jump_branch_info.branch_inst := io.bpu.branch_inst - io.executeStage.jump_branch_info.pred_branch := io.bpu.branch - io.executeStage.jump_branch_info.branch_target := io.bpu.target - io.executeStage.jump_branch_info.update_pht_index := io.bpu.update_pht_index - - for (i <- 0 until (cpuConfig.commitNum)) { - io.executeStage.inst(i).pc := pc(i) - io.executeStage.inst(i).info := info(i) - io.executeStage.inst(i).src_info.src1_data := MuxCase( - SignedExtend(pc(i), XLEN), - Seq( - info(i).src1_ren -> forwardCtrl.out.inst(i).src1.rdata, - (info(i).inst(6, 0) === "b0110111".U) -> 0.U - ) + 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.inst(6, 0) === "b0110111".U) -> 0.U ) - io.executeStage.inst(i).src_info.src2_data := Mux( - info(i).src2_ren, - forwardCtrl.out.inst(i).src2.rdata, - info(i).imm - ) - (0 until (INT_WID)).foreach(j => io.executeStage.inst(i).ex.interrupt(j) := io.csr.interrupt(j)) - io.executeStage.inst(i).ex.exception.map(_ := false.B) - io.executeStage.inst(i).ex.exception(illegalInst) := !info(i).inst_legal - io.executeStage.inst(i).ex.exception(instAccessFault) := io.instFifo.inst(i).access_fault - io.executeStage.inst(i).ex.exception(instPageFault) := io.instFifo.inst(i).page_fault - io.executeStage.inst(i).ex.exception(instAddrMisaligned) := io.instFifo.inst(i).addr_misaligned || - io.fetchUnit.target(log2Ceil(INST_WID / 8) - 1, 0).orR && io.fetchUnit.branch - io.executeStage.inst(i).ex.exception(breakPoint) := - info(i).op === CSROpType.ebreak && info(i).fusel === FuType.csr - io.executeStage.inst(i).ex.exception(ecallM) := - info(i).op === CSROpType.ecall && mode === ModeM && info(i).fusel === FuType.csr - io.executeStage.inst(i).ex.exception(ecallS) := - info(i).op === CSROpType.ecall && mode === ModeS && info(i).fusel === FuType.csr - io.executeStage.inst(i).ex.exception(ecallU) := - info(i).op === CSROpType.ecall && mode === ModeU && info(i).fusel === FuType.csr - io.executeStage.inst(i).ex.tval.map(_ := DontCare) - io.executeStage.inst(i).ex.tval(instPageFault) := pc(i) - io.executeStage.inst(i).ex.tval(instAccessFault) := pc(i) - io.executeStage.inst(i).ex.tval(illegalInst) := info(i).inst - io.executeStage.inst(i).ex.tval(instAddrMisaligned) := Mux( - io.fetchUnit.target(log2Ceil(INST_WID / 8) - 1, 0).orR && io.fetchUnit.branch, - io.fetchUnit.target, - pc(i) - ) - } + ) + io.executeStage.data.src_info.src2_data := Mux( + info.src2_ren, + forwardCtrl.out.data.src2.rdata, + info.imm + ) } diff --git a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala b/chisel/playground/src/pipeline/decode/ForwardCtrl.scala index c1c1ebf..f78232e 100644 --- a/chisel/playground/src/pipeline/decode/ForwardCtrl.scala +++ b/chisel/playground/src/pipeline/decode/ForwardCtrl.scala @@ -7,68 +7,56 @@ import cpu.defines._ import cpu.defines.Const._ import cpu.CpuConfig -class ForwardCtrl(implicit val cpuConfig: CpuConfig) extends Module { +class ForwardCtrl extends Module { val io = IO(new Bundle { val in = Input(new Bundle { - val forward = Vec(cpuConfig.commitNum, new DataForwardToDecodeUnit()) - val regfile = Vec(cpuConfig.decoderNum, new Src12Read()) + val forward = new DataForwardToDecodeUnit() + val regfile = new Src12Read() }) val out = Output(new Bundle { - val inst = Vec(cpuConfig.decoderNum, new Src12Read()) + val data = new Src12Read() }) }) // wb优先度最低 - for (i <- 0 until (cpuConfig.decoderNum)) { - io.out.inst(i).src1.raddr := DontCare - io.out.inst(i).src2.raddr := DontCare - io.out.inst(i).src1.rdata := io.in.regfile(i).src1.rdata - io.out.inst(i).src2.rdata := io.in.regfile(i).src2.rdata - } + 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优先度中 - for (i <- 0 until (cpuConfig.decoderNum)) { - for (j <- 0 until (cpuConfig.commitNum)) { - when( - io.in.forward(j).mem.wen && - io.in.forward(j).mem.waddr === io.in.regfile(i).src1.raddr - ) { - io.out.inst(i).src1.rdata := io.in.forward(j).mem.wdata - } - when( - io.in.forward(j).mem.wen && - io.in.forward(j).mem.waddr === io.in.regfile(i).src2.raddr - ) { - io.out.inst(i).src2.rdata := io.in.forward(j).mem.wdata - } - } + 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优先度高 - for (i <- 0 until (cpuConfig.decoderNum)) { - for (j <- 0 until (cpuConfig.commitNum)) { - when( - 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).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 - } - } + 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 - (0 until (cpuConfig.decoderNum)).foreach(i => { - when(io.in.regfile(i).src1.raddr === 0.U) { - io.out.inst(i).src1.rdata := 0.U - } - when(io.in.regfile(i).src2.raddr === 0.U) { - io.out.inst(i).src2.rdata := 0.U - } - }) + 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 + } }