From 106157f3719b357adc9995eb7b8b36359d9f00f4 Mon Sep 17 00:00:00 2001 From: HidetaroTanaka Date: Mon, 6 Nov 2023 15:14:35 +0900 Subject: [PATCH 1/5] changed InstBundle Immediate Generation --- .../hajime/common/HajimeCoreParams.scala | 3 +- src/main/scala/hajime/common/InstBundle.scala | 23 +- .../scala/hajime/common/RISCV_Consts.scala | 3 + src/main/scala/hajime/simple4Stage/Core.scala | 8 +- .../scala/hajime/superScalar/Dispatcher.scala | 28 -- .../scala/hajime/superScalar/FrontEnd.scala | 58 --- .../hajime/vectormodules/VectorCpu.scala | 12 +- .../scala/hajime/publicmodules/ALUTest.scala | 364 ------------------ 8 files changed, 30 insertions(+), 469 deletions(-) delete mode 100644 src/main/scala/hajime/superScalar/Dispatcher.scala delete mode 100644 src/main/scala/hajime/superScalar/FrontEnd.scala delete mode 100644 src/test/scala/hajime/publicmodules/ALUTest.scala diff --git a/src/main/scala/hajime/common/HajimeCoreParams.scala b/src/main/scala/hajime/common/HajimeCoreParams.scala index 4ea8ac0d..9a6a3c6f 100644 --- a/src/main/scala/hajime/common/HajimeCoreParams.scala +++ b/src/main/scala/hajime/common/HajimeCoreParams.scala @@ -6,11 +6,10 @@ import chisel3.util._ // TODO: add inst/data memory info // Do I even need multi issue? Vector and Multiply can overlap case class HajimeCoreParams( - issue_width: Int = 1, threads: Int = 1, xprlen: Int = 64, frequency: Int = 50*1000*1000, // x[MHz] = x * 1000 * 1000 - physicalRegFileEntries: Int = 48, + physicalRegFileEntriesFor1Thread: Int = 48, ras_depth: Int = 8, robEntries: Int = 8, useException: Boolean = true, diff --git a/src/main/scala/hajime/common/InstBundle.scala b/src/main/scala/hajime/common/InstBundle.scala index fdf3dfe0..b90ba484 100644 --- a/src/main/scala/hajime/common/InstBundle.scala +++ b/src/main/scala/hajime/common/InstBundle.scala @@ -4,7 +4,9 @@ import chisel3._ import chisel3.util._ import Functions._ -class InstBundle(implicit params: HajimeCoreParams) extends Bundle { +import scala.annotation.unused + +class InstBundle(implicit params: HajimeCoreParams) extends Bundle with ScalarOpConstants { import params._ val bits: UInt = UInt(32.W) @@ -14,12 +16,15 @@ class InstBundle(implicit params: HajimeCoreParams) extends Bundle { def funct3: UInt = bits(14,12) def rd: UInt = bits(11,7) def opcode: UInt = bits(6,0) - // TODO: refactor to better looking name - def i_imm: UInt = bits(31,20).ext(xprlen) - def s_imm: UInt = Cat(this.funct7, this.rd).ext(xprlen) - def b_imm: UInt = Cat(bits(31), bits(7), bits(30, 25), bits(11,8), 0.U(1.W)).ext(xprlen) - def u_imm: UInt = Cat(bits(31,12), 0.U(12.W)).ext(xprlen) - def j_imm: UInt = Cat(bits(31), bits(19,12), bits(20), bits(30,21), 0.U(1.W)).ext(xprlen) + def getImm(immType: ImmediateEnum.Type): UInt = { + MuxLookup(immType, 0.U)(Seq( + ImmediateEnum.I -> bits(31,20).ext(xprlen), + ImmediateEnum.S -> Cat(this.funct7, this.rd).ext(xprlen), + ImmediateEnum.B -> Cat(bits(31), bits(7), bits(30, 25), bits(11,8), 0.U(1.W)).ext(xprlen), + ImmediateEnum.U -> Cat(bits(31,12), 0.U(12.W)).ext(xprlen), + ImmediateEnum.J -> Cat(bits(31), bits(19,12), bits(20), bits(30,21), 0.U(1.W)).ext(xprlen) + )) + } def zimm: UInt = bits(31,20) def uimm19To15: UInt = Cat(false.B, this.rs1) def imm19To15: UInt = this.rs1.ext(xprlen) @@ -28,6 +33,10 @@ class InstBundle(implicit params: HajimeCoreParams) extends Bundle { class ProgramCounter(implicit params: HajimeCoreParams) extends Bundle { val addr = UInt(params.xprlen.W) def nextPC: UInt = addr + 4.U(params.xprlen.W) + + // C拡張用 + @unused + def nextCompressedPC: UInt = addr + 2.U(params.xprlen.W) def initialise(initial: UInt): ProgramCounter = { val initalisedWire = Wire(this) initalisedWire.addr := initial diff --git a/src/main/scala/hajime/common/RISCV_Consts.scala b/src/main/scala/hajime/common/RISCV_Consts.scala index b5ae80b7..96656dff 100644 --- a/src/main/scala/hajime/common/RISCV_Consts.scala +++ b/src/main/scala/hajime/common/RISCV_Consts.scala @@ -12,6 +12,9 @@ trait ScalarOpConstants { object ContentValid extends ChiselEnum { val N, Y = Value } + object ImmediateEnum extends ChiselEnum { + val I, S, B, U, J = Value + } object Branch extends ChiselEnum { val NONE, EQ, NE, LT, GE, LTU, GEU, JAL, JALR, ECALL, MRET = Value val condBranchList = EQ :: NE :: LT :: GE :: LTU :: GEU :: Nil diff --git a/src/main/scala/hajime/simple4Stage/Core.scala b/src/main/scala/hajime/simple4Stage/Core.scala index cf90cfbd..7c9f1761 100644 --- a/src/main/scala/hajime/simple4Stage/Core.scala +++ b/src/main/scala/hajime/simple4Stage/Core.scala @@ -203,7 +203,7 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons io.frontend.req := Mux(branch_evaluator.io.out.valid && ID_EX_REG.valid, branch_evaluator.io.out, branch_predictor.io.out) io.frontend.req.valid := WB_pc_redirect || (branch_evaluator.io.out.valid && ID_EX_REG.valid) || (branch_predictor.io.out.valid && io.frontend.resp.valid && io.frontend.resp.ready) branch_predictor.io.pc := io.frontend.resp.bits.pc - branch_predictor.io.imm := Mux(decoder.io.out.bits.isCondBranch, decoded_inst.b_imm, decoded_inst.j_imm) + branch_predictor.io.imm := Mux(decoder.io.out.bits.isCondBranch, decoded_inst.getImm(ImmediateEnum.B), decoded_inst.getImm(ImmediateEnum.J)) branch_predictor.io.BranchType := decoder.io.out.bits.branch decoder.io.inst := decoded_inst @@ -227,10 +227,10 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.pc ID_EX_REG.bits.dataSignals.bp_taken := branch_predictor.io.out.valid ID_EX_REG.bits.dataSignals.imm := MuxCase(0.U, Seq( - (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.u_imm, + (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.U), (decoder.io.out.bits.value1 === Value1.UIMM19_15.asUInt) -> decoded_inst.uimm19To15, - (decoder.io.out.bits.value2 === Value2.I_IMM.asUInt) -> decoded_inst.i_imm, - (decoder.io.out.bits.value2 === Value2.S_IMM.asUInt) -> decoded_inst.s_imm, + (decoder.io.out.bits.value2 === Value2.I_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.I), + (decoder.io.out.bits.value2 === Value2.S_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.S), )) val rs1ValueToEX = Mux(bypassingUnit.io.ID.out.rs1_value.valid, bypassingUnit.io.ID.out.rs1_value.bits, rf.io.rs1_out) diff --git a/src/main/scala/hajime/superScalar/Dispatcher.scala b/src/main/scala/hajime/superScalar/Dispatcher.scala deleted file mode 100644 index 79a728f8..00000000 --- a/src/main/scala/hajime/superScalar/Dispatcher.scala +++ /dev/null @@ -1,28 +0,0 @@ -package hajime.superScalar - -import chisel3._ -import chisel3.util._ -import hajime.common._ -import hajime.publicmodules._ - -class DispatcherResp(implicit params: HajimeCoreParams) extends Bundle { - import params._ - val pc = UInt(xprlen.W) - val pc_if_mispredict = UInt(xprlen.W) - val renamed_rs1 = Valid(UInt(log2Up(physicalRegFileEntries).W)) - val renamed_rs2 = Valid(UInt(log2Up(physicalRegFileEntries).W)) - val renamed_rd = Valid(UInt(log2Up(physicalRegFileEntries).W)) - val immediate = Valid(UInt(xprlen.W)) - val decoder_out = Valid(new ID_output) - val debug_inst = if(debug) Some(UInt(RISCV_Consts.INST_LEN.W)) else None -} - -class DispatcherIO(implicit params: HajimeCoreParams) extends Bundle { - val req = Flipped(new DecoupledIO(Vec(params.issue_width, new FrontEndResp()))) - val resp_toExecutor = new DecoupledIO(Vec(params.issue_width, new DispatcherResp())) - val resp_toFrontEnd = new ValidIO(new FrontEndReq()) -} - -class Dispatcher { - -} diff --git a/src/main/scala/hajime/superScalar/FrontEnd.scala b/src/main/scala/hajime/superScalar/FrontEnd.scala deleted file mode 100644 index 00c4315c..00000000 --- a/src/main/scala/hajime/superScalar/FrontEnd.scala +++ /dev/null @@ -1,58 +0,0 @@ -package hajime.superScalar - -import chisel3._ -import chisel3.util._ -import hajime.axiIO._ -import hajime.common._ - -class FrontEndReq(implicit params: HajimeCoreParams) extends Bundle { - val pc = UInt(params.xprlen.W) -} -class FrontEndResp(implicit params: HajimeCoreParams) extends Bundle { - val pc = UInt(params.xprlen.W) - val inst = UInt(RISCV_Consts.INST_LEN.W) -} - -class FrontEndCpuIO(implicit params: HajimeCoreParams) extends Bundle { - val req = Flipped(new ValidIO(new FrontEndReq())) - val resp = new DecoupledIO(Vec(params.issue_width, new FrontEndResp())) -} - -class FrontEndIO(implicit params: HajimeCoreParams) extends Bundle { - val cpu = new FrontEndCpuIO() - val icache_axi4lite = new AXI4liteIO(addr_width = params.xprlen, data_width = RISCV_Consts.INST_LEN * params.issue_width) - val reset_vector = Input(UInt(params.xprlen.W)) - val exception = Output(Bool()) -} - -class FrontEnd(implicit params: HajimeCoreParams) extends Module { - val io = IO(new FrontEndIO()) - io := DontCare - - val pc_reg = RegInit(io.reset_vector) - io.icache_axi4lite.ar.bits.addr := MuxCase(pc_reg+(params.issue_width.U << 2), Seq( - io.cpu.req.valid -> io.cpu.req.bits.pc, - (!io.icache_axi4lite.ar.ready || !io.icache_axi4lite.r.valid || !io.cpu.resp.ready) -> pc_reg, - )) - - when(io.cpu.resp.valid || io.cpu.resp.ready) { - pc_reg := io.icache_axi4lite.ar.bits.addr - } - - io.icache_axi4lite.ar.bits.prot := 0.U - io.icache_axi4lite.ar.valid := io.cpu.resp.ready || io.cpu.req.valid - - for((d,i) <- io.cpu.resp.bits.zipWithIndex) { - d.pc := pc_reg + (i.U << 2) - d.inst := io.icache_axi4lite.r.bits.data((i+1)*RISCV_Consts.INST_LEN-1,i*RISCV_Consts.INST_LEN) - } - io.cpu.resp.valid := io.icache_axi4lite.r.valid - io.icache_axi4lite.r.ready := io.cpu.resp.ready || io.cpu.req.valid - - io.exception := io.icache_axi4lite.r.bits.exception -} - -object FrontEnd extends App { - def apply(implicit params: HajimeCoreParams): FrontEnd = new FrontEnd() - (new chisel3.stage.ChiselStage).emitVerilog(apply(HajimeCoreParams()), args = COMPILE_CONSTANTS.CHISELSTAGE_ARGS) -} \ No newline at end of file diff --git a/src/main/scala/hajime/vectormodules/VectorCpu.scala b/src/main/scala/hajime/vectormodules/VectorCpu.scala index 5f5aa876..b48ac5ce 100644 --- a/src/main/scala/hajime/vectormodules/VectorCpu.scala +++ b/src/main/scala/hajime/vectormodules/VectorCpu.scala @@ -123,7 +123,7 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar io.frontend.req := Mux(branch_evaluator.io.out.valid && ID_EX_REG.valid, branch_evaluator.io.out, branch_predictor.io.out) io.frontend.req.valid := WB_pc_redirect || (branch_evaluator.io.out.valid && ID_EX_REG.valid) || (branch_predictor.io.out.valid && io.frontend.resp.valid && io.frontend.resp.ready) branch_predictor.io.pc := io.frontend.resp.bits.pc - branch_predictor.io.imm := Mux(decoder.io.out.bits.isCondBranch, decoded_inst.b_imm, decoded_inst.j_imm) + branch_predictor.io.imm := Mux(decoder.io.out.bits.isCondBranch, decoded_inst.getImm(ImmediateEnum.B), decoded_inst.getImm(ImmediateEnum.J)) branch_predictor.io.BranchType := decoder.io.out.bits.branch decoder.io.inst := decoded_inst @@ -147,10 +147,10 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.pc ID_EX_REG.bits.dataSignals.bp_taken := branch_predictor.io.out.valid ID_EX_REG.bits.dataSignals.imm := MuxCase(0.U, Seq( - (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.u_imm, + (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.U), (decoder.io.out.bits.value1 === Value1.UIMM19_15.asUInt) -> decoded_inst.uimm19To15, - (decoder.io.out.bits.value2 === Value2.I_IMM.asUInt) -> decoded_inst.i_imm, - (decoder.io.out.bits.value2 === Value2.S_IMM.asUInt) -> decoded_inst.s_imm, + (decoder.io.out.bits.value2 === Value2.I_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.I), + (decoder.io.out.bits.value2 === Value2.S_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.S), )) val rs1ValueToEX = Mux(bypassingUnit.io.ID.out.rs1_value.valid, bypassingUnit.io.ID.out.rs1_value.bits, rf.io.rs1_out) @@ -260,7 +260,7 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar } .elsewhen(io.frontend.resp.valid && decoder.io.out.valid && decoder.io.out.bits.vector.get && vectorDecoder.io.out.useVecLdstExec && vecLdstUnitReady) { vectorLdstUnit.io.signalIn.valid := true.B vectorLdstUnit.io.signalIn.bits.scalar.rs2Value := rs2ValueToEX - vectorLdstUnit.io.signalIn.bits.scalar.immediate := Mux(decoder.io.out.bits.memRead, decoded_inst.i_imm, decoded_inst.s_imm) + vectorLdstUnit.io.signalIn.bits.scalar.immediate := Mux(decoder.io.out.bits.memRead, decoded_inst.getImm(ImmediateEnum.I), decoded_inst.getImm(ImmediateEnum.S)) vectorLdstUnit.io.signalIn.bits.scalar.rdIndex := decoded_inst.rd val vecSigs = vectorLdstUnit.io.signalIn.bits.vector vecSigs.vs1 := decoded_inst.rs1 @@ -279,7 +279,7 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar } .elsewhen(io.frontend.resp.valid && decoder.io.out.valid && decoder.io.out.bits.memValid && vecLdstUnitReady) { vectorLdstUnit.io.signalIn.valid := true.B vectorLdstUnit.io.signalIn.bits.scalar.rs2Value := rs2ValueToEX - vectorLdstUnit.io.signalIn.bits.scalar.immediate := Mux(decoder.io.out.bits.memRead, decoded_inst.i_imm, decoded_inst.s_imm) + vectorLdstUnit.io.signalIn.bits.scalar.immediate := Mux(decoder.io.out.bits.memRead, decoded_inst.getImm(ImmediateEnum.I), decoded_inst.getImm(ImmediateEnum.S)) vectorLdstUnit.io.signalIn.bits.scalar.rdIndex := decoded_inst.rd vectorLdstUnit.io.signalIn.bits.vector := DontCare vectorLdstUnit.io.signalIn.bits.vector.scalarVal := rs1ValueToEX diff --git a/src/test/scala/hajime/publicmodules/ALUTest.scala b/src/test/scala/hajime/publicmodules/ALUTest.scala deleted file mode 100644 index 9ec3132b..00000000 --- a/src/test/scala/hajime/publicmodules/ALUTest.scala +++ /dev/null @@ -1,364 +0,0 @@ -package hajime.publicmodules - -import chisel3._ -import chiseltest._ -import hajime.common.Instructions._ -import hajime.common._ -import org.scalatest.flatspec._ - -/* -class ALUTest extends AnyFlatSpec with ChiselScalatestTester with ScalarOpConstants { - import ContentValid._ - it should "not act sussy" in { - // wtf? I have never curried ALU.apply - test(new ALU()(HajimeCoreParams())).withAnnotations(Seq(WriteVcdAnnotation)) { c => - def instDecode(inst: String): List[Int] = { - inst match { - case "add" => List(ARITHMETIC_FCN.ADDSUB.litValue.toInt, 0, 0) - case "sub" => List(ARITHMETIC_FCN.ADDSUB.litValue.toInt, 1, 0) - case "sll" => List(ARITHMETIC_FCN.SLL.litValue.toInt, 0, 0) - case "slt" => List(ARITHMETIC_FCN.SLT.litValue.toInt, 0, 0) - case "sltu" => List(ARITHMETIC_FCN.SLTU.litValue.toInt, 0, 0) - case "xor" => List(ARITHMETIC_FCN.XOR.litValue.toInt, 0, 0) - case "srl" => List(ARITHMETIC_FCN.SR.litValue.toInt, 0, 0) - case "sra" => List(ARITHMETIC_FCN.SR.litValue.toInt, 1, 0) - case "or" => List(ARITHMETIC_FCN.OR.litValue.toInt, 0, 0) - case "and" => List(ARITHMETIC_FCN.AND.litValue.toInt, 0, 0) - case "addw" => List(ARITHMETIC_FCN.ADDSUB.litValue.toInt, 0, 1) - case "subw" => List(ARITHMETIC_FCN.ADDSUB.litValue.toInt, 1, 1) - case "sllw" => List(ARITHMETIC_FCN.SLL.litValue.toInt, 0, 1) - case "srlw" => List(ARITHMETIC_FCN.SR.litValue.toInt, 0, 1) - case "sraw" => List(ARITHMETIC_FCN.SR.litValue.toInt, 1, 1) - case _ => List(ARITHMETIC_FCN.NONE.litValue.toInt, 0, 0) - } - } - - def DO_TEST(testNum: BigInt, inst: String, out: String, in1: String, in2: String): Unit = { - c.io.in1.poke(in1.U(RISCV_Consts.XLEN.W)) - c.io.in2.poke(in2.U(RISCV_Consts.XLEN.W)) - c.io.funct.arithmetic_funct.poke((instDecode(inst)).head) - c.io.funct.alu_flag.poke((instDecode(inst)(1))) - c.io.funct.op32.poke((instDecode(inst)(2))) - c.io.out.expect(out.U(RISCV_Consts.XLEN.W)) - if(c.io.out.peekInt() == out.U.litValue) println(s"test $testNum for $inst passed") - } - - def TEST_RR_OP(testNum: BigInt, inst: String, out: String, in1: String, in2: String): Unit = { - DO_TEST(testNum, inst, out, in1, in2) - c.clock.step() - } - - TEST_RR_OP(2, "add", "h00000000", "h00000000", "h00000000") - TEST_RR_OP(3, "add", "h00000002", "h00000001", "h00000001") - TEST_RR_OP(4, "add", "h0000000a", "h00000003", "h00000007") - - TEST_RR_OP(5, "add", "hffffffffffff8000", "h0000000000000000", "hffffffffffff8000") - TEST_RR_OP(6, "add", "hffffffff80000000", "hffffffff80000000", "h00000000") - TEST_RR_OP(7, "add", "hffffffff7fff8000", "hffffffff80000000", "hffffffffffff8000") - - TEST_RR_OP(8, "add", "h0000000000007fff", "h0000000000000000", "h0000000000007fff") - TEST_RR_OP(9, "add", "h000000007fffffff", "h000000007fffffff", "h0000000000000000") - TEST_RR_OP(10, "add", "h0000000080007ffe", "h000000007fffffff", "h0000000000007fff") - - TEST_RR_OP(11, "add", "hffffffff80007fff", "hffffffff80000000", "h0000000000007fff") - TEST_RR_OP(12, "add", "h000000007fff7fff", "h000000007fffffff", "hffffffffffff8000") - - TEST_RR_OP(13, "add", "hffffffffffffffff", "h0000000000000000", "hffffffffffffffff") - TEST_RR_OP(14, "add", "h0000000000000000", "hffffffffffffffff", "h0000000000000001") - TEST_RR_OP(15, "add", "hfffffffffffffffe", "hffffffffffffffff", "hffffffffffffffff") - - TEST_RR_OP(16, "add", "h0000000080000000", "h0000000000000001", "h000000007fffffff") - - - TEST_RR_OP(2, "addw", "h00000000", "h00000000", "h00000000") - TEST_RR_OP(3, "addw", "h00000002", "h00000001", "h00000001") - TEST_RR_OP(4, "addw", "h0000000a", "h00000003", "h00000007") - - TEST_RR_OP(5, "addw", "hffffffffffff8000", "h0000000000000000", "hffffffffffff8000") - TEST_RR_OP(6, "addw", "hffffffff80000000", "hffffffff80000000", "h00000000") - TEST_RR_OP(7, "addw", "h000000007fff8000", "hffffffff80000000", "hffffffffffff8000") - - TEST_RR_OP(8, "addw", "h0000000000007fff", "h0000000000000000", "h0000000000007fff") - TEST_RR_OP(9, "addw", "h000000007fffffff", "h000000007fffffff", "h0000000000000000") - TEST_RR_OP(10, "addw", "hffffffff80007ffe", "h000000007fffffff", "h0000000000007fff") - - TEST_RR_OP(11, "addw", "hffffffff80007fff", "hffffffff80000000", "h0000000000007fff") - TEST_RR_OP(12, "addw", "h000000007fff7fff", "h000000007fffffff", "hffffffffffff8000") - - TEST_RR_OP(13, "addw", "hffffffffffffffff", "h0000000000000000", "hffffffffffffffff") - TEST_RR_OP(14, "addw", "h0000000000000000", "hffffffffffffffff", "h0000000000000001") - TEST_RR_OP(15, "addw", "hfffffffffffffffe", "hffffffffffffffff", "hffffffffffffffff") - - TEST_RR_OP(16, "addw", "hffffffff80000000", "h0000000000000001", "h000000007fffffff") - - - TEST_RR_OP(2, "and", "h0f000f00", "hff00ff00", "h0f0f0f0f") - TEST_RR_OP(3, "and", "h00f000f0", "h0ff00ff0", "hf0f0f0f0") - TEST_RR_OP(4, "and", "h000f000f", "h00ff00ff", "h0f0f0f0f") - TEST_RR_OP(5, "and", "hf000f000", "hf00ff00f", "hf0f0f0f0") - - - TEST_RR_OP(2, "or", "hff0fff0f", "hff00ff00", "h0f0f0f0f") - TEST_RR_OP(3, "or", "hfff0fff0", "h0ff00ff0", "hf0f0f0f0") - TEST_RR_OP(4, "or", "h0fff0fff", "h00ff00ff", "h0f0f0f0f") - TEST_RR_OP(5, "or", "hf0fff0ff", "hf00ff00f", "hf0f0f0f0") - - - TEST_RR_OP(2, "sll", "h0000000000000001", "h0000000000000001", "d0") - TEST_RR_OP(3, "sll", "h0000000000000002", "h0000000000000001", "d1"); - TEST_RR_OP(4, "sll", "h0000000000000080", "h0000000000000001", "d7"); - TEST_RR_OP(5, "sll", "h0000000000004000", "h0000000000000001", "d14"); - TEST_RR_OP(6, "sll", "h0000000080000000", "h0000000000000001", "d31"); - - TEST_RR_OP(7, "sll", "hffffffffffffffff", "hffffffffffffffff", "d0"); - TEST_RR_OP(8, "sll", "hfffffffffffffffe", "hffffffffffffffff", "d1"); - TEST_RR_OP(9, "sll", "hffffffffffffff80", "hffffffffffffffff", "d7"); - TEST_RR_OP(10, "sll", "hffffffffffffc000", "hffffffffffffffff", "d14"); - TEST_RR_OP(11, "sll", "hffffffff80000000", "hffffffffffffffff", "d31"); - - TEST_RR_OP(12, "sll", "h0000000021212121", "h0000000021212121", "d0"); - TEST_RR_OP(13, "sll", "h0000000042424242", "h0000000021212121", "d1"); - TEST_RR_OP(14, "sll", "h0000001090909080", "h0000000021212121", "d7"); - TEST_RR_OP(15, "sll", "h0000084848484000", "h0000000021212121", "d14"); - TEST_RR_OP(16, "sll", "h1090909080000000", "h0000000021212121", "d31"); - - TEST_RR_OP(17, "sll", "h0000000021212121", "h0000000021212121", "hffffffffffffffc0"); - TEST_RR_OP(18, "sll", "h0000000042424242", "h0000000021212121", "hffffffffffffffc1"); - TEST_RR_OP(19, "sll", "h0000001090909080", "h0000000021212121", "hffffffffffffffc7"); - TEST_RR_OP(20, "sll", "h0000084848484000", "h0000000021212121", "hffffffffffffffce"); - - TEST_RR_OP(21, "sll", "h8000000000000000", "h0000000021212121", "hffffffffffffffff"); - TEST_RR_OP(50, "sll", "h8000000000000000", "h0000000000000001", "d63"); - TEST_RR_OP(51, "sll", "hffffff8000000000", "hffffffffffffffff", "d39"); - TEST_RR_OP(52, "sll", "h0909080000000000", "h0000000021212121", "d43"); - - - TEST_RR_OP(2, "sllw", "h0000000000000001", "h0000000000000001", "d0"); - TEST_RR_OP(3, "sllw", "h0000000000000002", "h0000000000000001", "d1"); - TEST_RR_OP(4, "sllw", "h0000000000000080", "h0000000000000001", "d7"); - TEST_RR_OP(5, "sllw", "h0000000000004000", "h0000000000000001", "d14"); - TEST_RR_OP(6, "sllw", "hffffffff80000000", "h0000000000000001", "d31"); - - TEST_RR_OP(7, "sllw", "hffffffffffffffff", "hffffffffffffffff", "d0"); - TEST_RR_OP(8, "sllw", "hfffffffffffffffe", "hffffffffffffffff", "d1"); - TEST_RR_OP(9, "sllw", "hffffffffffffff80", "hffffffffffffffff", "d7"); - TEST_RR_OP(10, "sllw", "hffffffffffffc000", "hffffffffffffffff", "d14"); - TEST_RR_OP(11, "sllw", "hffffffff80000000", "hffffffffffffffff", "d31"); - - TEST_RR_OP(12, "sllw", "h0000000021212121", "h0000000021212121", "d0"); - TEST_RR_OP(13, "sllw", "h0000000042424242", "h0000000021212121", "d1"); - TEST_RR_OP(14, "sllw", "hffffffff90909080", "h0000000021212121", "d7"); - TEST_RR_OP(15, "sllw", "h0000000048484000", "h0000000021212121", "d14"); - TEST_RR_OP(16, "sllw", "hffffffff80000000", "h0000000021212121", "d31"); - - TEST_RR_OP(17, "sllw", "h0000000021212121", "h0000000021212121", "hffffffffffffffe0"); - TEST_RR_OP(18, "sllw", "h0000000042424242", "h0000000021212121", "hffffffffffffffe1"); - TEST_RR_OP(19, "sllw", "hffffffff90909080", "h0000000021212121", "hffffffffffffffe7"); - TEST_RR_OP(20, "sllw", "h0000000048484000", "h0000000021212121", "hffffffffffffffee"); - TEST_RR_OP(21, "sllw", "hffffffff80000000", "h0000000021212121", "hffffffffffffffff"); - - TEST_RR_OP(44, "sllw", "h0000000012345678", "hffffffff12345678", "d0"); - TEST_RR_OP(45, "sllw", "h0000000023456780", "hffffffff12345678", "d4"); - TEST_RR_OP(46, "sllw", "hffffffff92345678", "h0000000092345678", "d0"); - TEST_RR_OP(47, "sllw", "hffffffff93456780", "h0000000099345678", "d4"); - - - TEST_RR_OP(2, "slt", "d0", "h0000000000000000", "h0000000000000000") - TEST_RR_OP(3, "slt", "d0", "h0000000000000001", "h0000000000000001") - TEST_RR_OP(4, "slt", "d1", "h0000000000000003", "h0000000000000007") - TEST_RR_OP(5, "slt", "d0", "h0000000000000007", "h0000000000000003") - - TEST_RR_OP(6, "slt", "d0", "h0000000000000000", "hffffffffffff8000") - TEST_RR_OP(7, "slt", "d1", "hffffffff80000000", "h0000000000000000") - TEST_RR_OP(8, "slt", "d1", "hffffffff80000000", "hffffffffffff8000") - - TEST_RR_OP(9, "slt", "d1", "h0000000000000000", "h0000000000007fff") - TEST_RR_OP(10, "slt", "d0", "h000000007fffffff", "h0000000000000000") - TEST_RR_OP(11, "slt", "d0", "h000000007fffffff", "h0000000000007fff") - - TEST_RR_OP(12, "slt", "d1", "hffffffff80000000", "h0000000000007fff") - TEST_RR_OP(13, "slt", "d0", "h000000007fffffff", "hffffffffffff8000") - - TEST_RR_OP(14, "slt", "d0", "h0000000000000000", "hffffffffffffffff") - TEST_RR_OP(15, "slt", "d1", "hffffffffffffffff", "h0000000000000001") - TEST_RR_OP(16, "slt", "d0", "hffffffffffffffff", "hffffffffffffffff") - - - TEST_RR_OP(2, "sltu", "d0", "h00000000", "h00000000") - TEST_RR_OP(3, "sltu", "d0", "h00000001", "h00000001") - TEST_RR_OP(4, "sltu", "d1", "h00000003", "h00000007") - TEST_RR_OP(5, "sltu", "d0", "h00000007", "h00000003") - - TEST_RR_OP(6, "sltu", "d1", "h00000000", "hffff8000") - TEST_RR_OP(7, "sltu", "d0", "h80000000", "h00000000") - TEST_RR_OP(8, "sltu", "d1", "h80000000", "hffff8000") - - TEST_RR_OP(9, "sltu", "d1", "h00000000", "h00007fff") - TEST_RR_OP(10, "sltu", "d0", "h7fffffff", "h00000000") - TEST_RR_OP(11, "sltu", "d0", "h7fffffff", "h00007fff") - - TEST_RR_OP(12, "sltu", "d0", "h80000000", "h00007fff") - TEST_RR_OP(13, "sltu", "d1", "h7fffffff", "hffff8000") - - TEST_RR_OP(14, "sltu", "d1", "h00000000", "hffffffff") - TEST_RR_OP(15, "sltu", "d0", "hffffffff", "h00000001") - TEST_RR_OP(16, "sltu", "d0", "hffffffff", "hffffffff") - - - TEST_RR_OP(2, "sra", "hffffffff80000000", "hffffffff80000000", "d0"); - TEST_RR_OP(3, "sra", "hffffffffc0000000", "hffffffff80000000", "d1"); - TEST_RR_OP(4, "sra", "hffffffffff000000", "hffffffff80000000", "d7"); - TEST_RR_OP(5, "sra", "hfffffffffffe0000", "hffffffff80000000", "d14"); - TEST_RR_OP(6, "sra", "hffffffffffffffff", "hffffffff80000001", "d31"); - - TEST_RR_OP(7, "sra", "h000000007fffffff", "h000000007fffffff", "d0"); - TEST_RR_OP(8, "sra", "h000000003fffffff", "h000000007fffffff", "d1"); - TEST_RR_OP(9, "sra", "h0000000000ffffff", "h000000007fffffff", "d7"); - TEST_RR_OP(10, "sra", "h000000000001ffff", "h000000007fffffff", "d14"); - TEST_RR_OP(11, "sra", "h0000000000000000", "h000000007fffffff", "d31"); - - TEST_RR_OP(12, "sra", "hffffffff81818181", "hffffffff81818181", "d0"); - TEST_RR_OP(13, "sra", "hffffffffc0c0c0c0", "hffffffff81818181", "d1"); - TEST_RR_OP(14, "sra", "hffffffffff030303", "hffffffff81818181", "d7"); - TEST_RR_OP(15, "sra", "hfffffffffffe0606", "hffffffff81818181", "d14"); - TEST_RR_OP(16, "sra", "hffffffffffffffff", "hffffffff81818181", "d31"); - - TEST_RR_OP(17, "sra", "hffffffff81818181", "hffffffff81818181", "hffffffffffffffc0"); - TEST_RR_OP(18, "sra", "hffffffffc0c0c0c0", "hffffffff81818181", "hffffffffffffffc1"); - TEST_RR_OP(19, "sra", "hffffffffff030303", "hffffffff81818181", "hffffffffffffffc7"); - TEST_RR_OP(20, "sra", "hfffffffffffe0606", "hffffffff81818181", "hffffffffffffffce"); - TEST_RR_OP(21, "sra", "hffffffffffffffff", "hffffffff81818181", "hffffffffffffffff"); - - - TEST_RR_OP(2, "sraw", "hffffffff80000000", "hffffffff80000000", "d0"); - TEST_RR_OP(3, "sraw", "hffffffffc0000000", "hffffffff80000000", "d1"); - TEST_RR_OP(4, "sraw", "hffffffffff000000", "hffffffff80000000", "d7"); - TEST_RR_OP(5, "sraw", "hfffffffffffe0000", "hffffffff80000000", "d14"); - TEST_RR_OP(6, "sraw", "hffffffffffffffff", "hffffffff80000001", "d31"); - - TEST_RR_OP(7, "sraw", "h000000007fffffff", "h000000007fffffff", "d0"); - TEST_RR_OP(8, "sraw", "h000000003fffffff", "h000000007fffffff", "d1"); - TEST_RR_OP(9, "sraw", "h0000000000ffffff", "h000000007fffffff", "d7"); - TEST_RR_OP(10, "sraw", "h000000000001ffff", "h000000007fffffff", "d14"); - TEST_RR_OP(11, "sraw", "h0000000000000000", "h000000007fffffff", "d31"); - - TEST_RR_OP(12, "sraw", "hffffffff81818181", "hffffffff81818181", "d0"); - TEST_RR_OP(13, "sraw", "hffffffffc0c0c0c0", "hffffffff81818181", "d1"); - TEST_RR_OP(14, "sraw", "hffffffffff030303", "hffffffff81818181", "d7"); - TEST_RR_OP(15, "sraw", "hfffffffffffe0606", "hffffffff81818181", "d14"); - TEST_RR_OP(16, "sraw", "hffffffffffffffff", "hffffffff81818181", "d31"); - - TEST_RR_OP(17, "sraw", "hffffffff81818181", "hffffffff81818181", "hffffffffffffffe0"); - TEST_RR_OP(18, "sraw", "hffffffffc0c0c0c0", "hffffffff81818181", "hffffffffffffffe1"); - TEST_RR_OP(19, "sraw", "hffffffffff030303", "hffffffff81818181", "hffffffffffffffe7"); - TEST_RR_OP(20, "sraw", "hfffffffffffe0606", "hffffffff81818181", "hffffffffffffffee"); - TEST_RR_OP(21, "sraw", "hffffffffffffffff", "hffffffff81818181", "hffffffffffffffff"); - - TEST_RR_OP(44, "sraw", "h0000000012345678", "hffffffff12345678", "d0"); - TEST_RR_OP(45, "sraw", "h0000000001234567", "hffffffff12345678", "d4"); - TEST_RR_OP(46, "sraw", "hffffffff92345678", "h0000000092345678", "d0"); - TEST_RR_OP(47, "sraw", "hfffffffff9234567", "h0000000092345678", "d4"); - - - TEST_RR_OP(2, "srl", "hffffffff80000000", "hffffffff80000000", "d0") - TEST_RR_OP(3, "srl", "h7fffffffc0000000", "hffffffff80000000", "d1") - TEST_RR_OP(4, "srl", "h01FFFFFFFF000000", "hffffffff80000000", "d7") - TEST_RR_OP(5, "srl", "h0003FFFFFFFE0000", "hffffffff80000000", "d14") - TEST_RR_OP(6, "srl", "h00000001FFFFFFFF", "hffffffff80000001", "d31") - - TEST_RR_OP(2, "srl", "hffffffffffffffff", "hffffffffffffffff", "d0") - TEST_RR_OP(3, "srl", "h7fffffffffffffff", "hffffffffffffffff", "d1") - TEST_RR_OP(4, "srl", "h01ffffffffffffff", "hffffffffffffffff", "d7") - TEST_RR_OP(5, "srl", "h0003ffffffffffff", "hffffffffffffffff", "d14") - TEST_RR_OP(6, "srl", "h00000001ffffffff", "hffffffffffffffff", "d31") - - TEST_RR_OP(2, "srl", "h0000000021212121", "h0000000021212121", "d0") - TEST_RR_OP(3, "srl", "h0000000010909090", "h0000000021212121", "d1") - TEST_RR_OP(4, "srl", "h0000000000424242", "h0000000021212121", "d7") - TEST_RR_OP(5, "srl", "h0000000000008484", "h0000000021212121", "d14") - TEST_RR_OP(6, "srl", "h0000000000000000", "h0000000021212121", "d31") - - TEST_RR_OP(17, "srl", "h0000000021212121", "h0000000021212121", "hffffffffffffffc0") - TEST_RR_OP(18, "srl", "h0000000010909090", "h0000000021212121", "hffffffffffffffc1") - TEST_RR_OP(19, "srl", "h0000000000424242", "h0000000021212121", "hffffffffffffffc7") - TEST_RR_OP(20, "srl", "h0000000000008484", "h0000000021212121", "hffffffffffffffce") - TEST_RR_OP(21, "srl", "h0000000000000000", "h0000000021212121", "hffffffffffffffff") - - - TEST_RR_OP(2, "srlw", "hffffffff80000000", "hffffffff80000000", "d0"); - TEST_RR_OP(3, "srlw", "h0000000040000000", "hffffffff80000000", "d1"); - TEST_RR_OP(4, "srlw", "h0000000001000000", "hffffffff80000000", "d7"); - TEST_RR_OP(5, "srlw", "h0000000000020000", "hffffffff80000000", "d14"); - TEST_RR_OP(6, "srlw", "h0000000000000001", "hffffffff80000001", "d31"); - - TEST_RR_OP(7, "srlw", "hffffffffffffffff", "hffffffffffffffff", "d0"); - TEST_RR_OP(8, "srlw", "h000000007fffffff", "hffffffffffffffff", "d1"); - TEST_RR_OP(9, "srlw", "h0000000001ffffff", "hffffffffffffffff", "d7"); - TEST_RR_OP(10, "srlw", "h000000000003ffff", "hffffffffffffffff", "d14"); - TEST_RR_OP(11, "srlw", "h0000000000000001", "hffffffffffffffff", "d31"); - - TEST_RR_OP(12, "srlw", "h0000000021212121", "h0000000021212121", "d0"); - TEST_RR_OP(13, "srlw", "h0000000010909090", "h0000000021212121", "d1"); - TEST_RR_OP(14, "srlw", "h0000000000424242", "h0000000021212121", "d7"); - TEST_RR_OP(15, "srlw", "h0000000000008484", "h0000000021212121", "d14"); - TEST_RR_OP(16, "srlw", "h0000000000000000", "h0000000021212121", "d31"); - - TEST_RR_OP(17, "srlw", "h0000000021212121", "h0000000021212121", "hffffffffffffffe0"); - TEST_RR_OP(18, "srlw", "h0000000010909090", "h0000000021212121", "hffffffffffffffe1"); - TEST_RR_OP(19, "srlw", "h0000000000424242", "h0000000021212121", "hffffffffffffffe7"); - TEST_RR_OP(20, "srlw", "h0000000000008484", "h0000000021212121", "hffffffffffffffee"); - TEST_RR_OP(21, "srlw", "h0000000000000000", "h0000000021212121", "hffffffffffffffff"); - - TEST_RR_OP(44, "srlw", "h0000000012345678", "hffffffff12345678", "d0"); - TEST_RR_OP(45, "srlw", "h0000000001234567", "hffffffff12345678", "d4"); - TEST_RR_OP(46, "srlw", "hffffffff92345678", "h0000000092345678", "d0"); - TEST_RR_OP(47, "srlw", "h0000000009234567", "h0000000092345678", "d4"); - - TEST_RR_OP(2, "sub", "h0000000000000000", "h0000000000000000", "h0000000000000000") - TEST_RR_OP(3, "sub", "h0000000000000000", "h0000000000000001", "h0000000000000001") - TEST_RR_OP(4, "sub", "hfffffffffffffffc", "h0000000000000003", "h0000000000000007") - - TEST_RR_OP(5, "sub", "h0000000000008000", "h0000000000000000", "hffffffffffff8000") - TEST_RR_OP(6, "sub", "hffffffff80000000", "hffffffff80000000", "h0000000000000000") - TEST_RR_OP(7, "sub", "hffffffff80008000", "hffffffff80000000", "hffffffffffff8000") - - TEST_RR_OP(8, "sub", "hffffffffffff8001", "h0000000000000000", "h0000000000007fff") - TEST_RR_OP(9, "sub", "h000000007fffffff", "h000000007fffffff", "h0000000000000000") - TEST_RR_OP(10, "sub", "h000000007fff8000", "h000000007fffffff", "h0000000000007fff") - - TEST_RR_OP(11, "sub", "hffffffff7fff8001", "hffffffff80000000", "h0000000000007fff") - TEST_RR_OP(12, "sub", "h0000000080007fff", "h000000007fffffff", "hffffffffffff8000") - - TEST_RR_OP(13, "sub", "h0000000000000001", "h0000000000000000", "hffffffffffffffff") - TEST_RR_OP(14, "sub", "hfffffffffffffffe", "hffffffffffffffff", "h0000000000000001") - TEST_RR_OP(15, "sub", "h0000000000000000", "hffffffffffffffff", "hffffffffffffffff") - - - TEST_RR_OP(2, "subw", "h0000000000000000", "h0000000000000000", "h0000000000000000") - TEST_RR_OP(3, "subw", "h0000000000000000", "h0000000000000001", "h0000000000000001") - TEST_RR_OP(4, "subw", "hfffffffffffffffc", "h0000000000000003", "h0000000000000007") - - TEST_RR_OP(5, "subw", "h0000000000008000", "h0000000000000000", "hffffffffffff8000") - TEST_RR_OP(6, "subw", "hffffffff80000000", "hffffffff80000000", "h0000000000000000") - TEST_RR_OP(7, "subw", "hffffffff80008000", "hffffffff80000000", "hffffffffffff8000") - - TEST_RR_OP(8, "subw", "hffffffffffff8001", "h0000000000000000", "h0000000000007fff") - TEST_RR_OP(9, "subw", "h000000007fffffff", "h000000007fffffff", "h0000000000000000") - TEST_RR_OP(10, "subw", "h000000007fff8000", "h000000007fffffff", "h0000000000007fff") - - TEST_RR_OP(11, "subw", "h000000007fff8001", "hffffffff80000000", "h0000000000007fff") - TEST_RR_OP(12, "subw", "hffffffff80007fff", "h000000007fffffff", "hffffffffffff8000") - - TEST_RR_OP(13, "subw", "h0000000000000001", "h0000000000000000", "hffffffffffffffff") - TEST_RR_OP(14, "subw", "hfffffffffffffffe", "hffffffffffffffff", "h0000000000000001") - TEST_RR_OP(15, "subw", "h0000000000000000", "hffffffffffffffff", "hffffffffffffffff") - - - TEST_RR_OP(2, "xor", "hf00ff00f", "hff00ff00", "h0f0f0f0f") - TEST_RR_OP(3, "xor", "hff00ff00", "h0ff00ff0", "hf0f0f0f0") - TEST_RR_OP(4, "xor", "h0ff00ff0", "h00ff00ff", "h0f0f0f0f") - TEST_RR_OP(5, "xor", "h00ff00ff", "hf00ff00f", "hf0f0f0f0") - } - } -} - */ From 910b3666776bf4163f693e33c5e1514f8685678a Mon Sep 17 00:00:00 2001 From: HidetaroTanaka Date: Mon, 6 Nov 2023 15:34:13 +0900 Subject: [PATCH 2/5] a --- src/main/scala/hajime/common/InstBundle.scala | 2 +- src/main/scala/hajime/common/RISCV_Consts.scala | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/scala/hajime/common/InstBundle.scala b/src/main/scala/hajime/common/InstBundle.scala index b90ba484..9a247c85 100644 --- a/src/main/scala/hajime/common/InstBundle.scala +++ b/src/main/scala/hajime/common/InstBundle.scala @@ -6,7 +6,7 @@ import Functions._ import scala.annotation.unused -class InstBundle(implicit params: HajimeCoreParams) extends Bundle with ScalarOpConstants { +class InstBundle(implicit params: HajimeCoreParams) extends Bundle { import params._ val bits: UInt = UInt(32.W) diff --git a/src/main/scala/hajime/common/RISCV_Consts.scala b/src/main/scala/hajime/common/RISCV_Consts.scala index 96656dff..b85bd819 100644 --- a/src/main/scala/hajime/common/RISCV_Consts.scala +++ b/src/main/scala/hajime/common/RISCV_Consts.scala @@ -12,9 +12,6 @@ trait ScalarOpConstants { object ContentValid extends ChiselEnum { val N, Y = Value } - object ImmediateEnum extends ChiselEnum { - val I, S, B, U, J = Value - } object Branch extends ChiselEnum { val NONE, EQ, NE, LT, GE, LTU, GEU, JAL, JALR, ECALL, MRET = Value val condBranchList = EQ :: NE :: LT :: GE :: LTU :: GEU :: Nil @@ -70,6 +67,10 @@ trait ScalarOpConstants { } } +object ImmediateEnum extends ChiselEnum { + val I, S, B, U, J = Value +} + object COMPILE_CONSTANTS { val CHISELSTAGE_ARGS = Array("--emission-options=disableMemRandomization,disableRegisterRandomization") val FIRTOOLOPS = Array("-disable-all-randomization", "-strip-debug-info") From 1b2c3155d74556ae6de148fc88bf267ce0af0c03 Mon Sep 17 00:00:00 2001 From: HidetaroTanaka Date: Mon, 6 Nov 2023 16:44:42 +0900 Subject: [PATCH 3/5] change FrontEnd Request to ProgramCounter --- .../hajime/common/BundleInitializer.scala | 15 +++++ .../hajime/simple4Stage/BranchEvaluator.scala | 4 +- .../hajime/simple4Stage/BranchPredictor.scala | 4 +- src/main/scala/hajime/simple4Stage/Core.scala | 4 +- .../scala/hajime/simple4Stage/Frontend.scala | 11 +--- .../hajime/vectorOoO/FrontEndForOoO.scala | 27 +++++++++ .../hajime/vectormodules/VectorCpu.scala | 4 +- src/test/scala/gcd/GCDSpec.scala | 55 ------------------- 8 files changed, 52 insertions(+), 72 deletions(-) create mode 100644 src/main/scala/hajime/common/BundleInitializer.scala create mode 100644 src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala delete mode 100644 src/test/scala/gcd/GCDSpec.scala diff --git a/src/main/scala/hajime/common/BundleInitializer.scala b/src/main/scala/hajime/common/BundleInitializer.scala new file mode 100644 index 00000000..d1f35e7f --- /dev/null +++ b/src/main/scala/hajime/common/BundleInitializer.scala @@ -0,0 +1,15 @@ +package hajime.common + +import chisel3._ +import chisel3.experimental._ +object BundleInitializer { + implicit class AddBundleInitializerConstructor[T <: Record](x: T) { + def Init(elems: (T => (Data, Data))*)(implicit sourceInfo: SourceInfo): T = { + val w = Wire(x) + for(e <- elems) { + e(w)._1 := e(w)._2 + } + w + } + } +} diff --git a/src/main/scala/hajime/simple4Stage/BranchEvaluator.scala b/src/main/scala/hajime/simple4Stage/BranchEvaluator.scala index 411b6bcf..ccf89d81 100644 --- a/src/main/scala/hajime/simple4Stage/BranchEvaluator.scala +++ b/src/main/scala/hajime/simple4Stage/BranchEvaluator.scala @@ -20,7 +20,7 @@ class BranchEvaluatorReq(implicit params: HajimeCoreParams) extends Bundle with class BranchEvaluatorIO(implicit params: HajimeCoreParams) extends Bundle { val req = Flipped(new ValidIO(new BranchEvaluatorReq())) - val out = new ValidIO(new FrontEndReq()) + val out = new ValidIO(new ProgramCounter()) } class BranchEvaluator(implicit params: HajimeCoreParams) extends Module with ScalarOpConstants { @@ -47,7 +47,7 @@ class BranchEvaluator(implicit params: HajimeCoreParams) extends Module with Sca x => x.asUInt -> (io.req.bits.bp_taken =/= branch_taken) ) ) - io.out.bits.pc := Mux(io.req.bits.BranchType === Branch.JALR.asUInt, Cat(io.req.bits.ALU_Result.head(params.xprlen-1), false.B), Mux( + io.out.bits.addr := Mux(io.req.bits.BranchType === Branch.JALR.asUInt, Cat(io.req.bits.ALU_Result.head(params.xprlen-1), false.B), Mux( branch_taken, io.req.bits.destPC, io.req.bits.pc.nextPC )) } diff --git a/src/main/scala/hajime/simple4Stage/BranchPredictor.scala b/src/main/scala/hajime/simple4Stage/BranchPredictor.scala index 852792b7..4594ddc7 100644 --- a/src/main/scala/hajime/simple4Stage/BranchPredictor.scala +++ b/src/main/scala/hajime/simple4Stage/BranchPredictor.scala @@ -10,7 +10,7 @@ class BranchPredictorIO(implicit params: HajimeCoreParams) extends Bundle with S // 分岐成立予測であれば,io.out.validはtrue // (分岐不成立予測なら単にPC+4を入れるだけ) // 分岐先予測はio.out.bits.pc - val out = new ValidIO(new FrontEndReq()) + val out = new ValidIO(new ProgramCounter()) val pc = Input(new ProgramCounter()) val imm = Input(UInt(params.xprlen.W)) val BranchType = Input(UInt(Branch.getWidth.W)) @@ -49,7 +49,7 @@ class BranchPredictor(implicit params: HajimeCoreParams) extends Module with Sca io.out.valid := branch_predict_taken // JALRならばRAS、それ以外はpc+imm (branch, jal) - io.out.bits.pc := Mux(io.BranchType === Branch.JALR.asUInt, RAS_pop(), io.pc.addr + io.imm) + io.out.bits.addr := Mux(io.BranchType === Branch.JALR.asUInt, RAS_pop(), io.pc.addr + io.imm) } object BranchPredictor extends App { diff --git a/src/main/scala/hajime/simple4Stage/Core.scala b/src/main/scala/hajime/simple4Stage/Core.scala index 7c9f1761..cc9a081c 100644 --- a/src/main/scala/hajime/simple4Stage/Core.scala +++ b/src/main/scala/hajime/simple4Stage/Core.scala @@ -224,7 +224,7 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons ID_ecall -> Causes.machine_ecall.U, )) ID_EX_REG.bits.dataSignals.pc := io.frontend.resp.bits.pc - ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.pc + ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.addr ID_EX_REG.bits.dataSignals.bp_taken := branch_predictor.io.out.valid ID_EX_REG.bits.dataSignals.imm := MuxCase(0.U, Seq( (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.U), @@ -469,7 +469,7 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons val dmemoryAccessException = (EX_WB_REG.bits.ctrlSignals.decode.memValid && ldstUnit.io.cpu.resp.valid && ldstUnit.io.cpu.resp.bits.exceptionSignals.valid) WB_pc_redirect := EX_WB_REG.valid && (EX_WB_REG.bits.ctrlSignals.decode.branch === Branch.MRET.asUInt || EX_WB_REG.bits.exceptionSignals.valid || dmemoryAccessException) when(WB_pc_redirect) { - io.frontend.req.bits.pc := csrUnit.io.resp.data + io.frontend.req.bits.addr := csrUnit.io.resp.data } // 割り込みまたは例外の場合は、PCのみ更新しリタイアしない(命令を破棄) val WB_inst_can_retire = EX_WB_REG.valid && !(EX_WB_REG.bits.exceptionSignals.valid || dmemoryAccessException) && !WB_stall diff --git a/src/main/scala/hajime/simple4Stage/Frontend.scala b/src/main/scala/hajime/simple4Stage/Frontend.scala index d5d13fb3..fb59dd91 100644 --- a/src/main/scala/hajime/simple4Stage/Frontend.scala +++ b/src/main/scala/hajime/simple4Stage/Frontend.scala @@ -6,13 +6,6 @@ import chisel3.util._ import hajime.axiIO.AXI4liteIO import hajime.common._ -/** - * PC Update request from CPU - */ -class FrontEndReq(implicit params: HajimeCoreParams) extends Bundle { - val pc = UInt(params.xprlen.W) -} - /** * send instruction from FrontEnd to CPU */ @@ -24,7 +17,7 @@ class FrontEndResp(implicit params: HajimeCoreParams) extends Bundle { } class FrontEndCpuIO(implicit params: HajimeCoreParams) extends Bundle { - val req = Flipped(new ValidIO(new FrontEndReq())) + val req = Flipped(new ValidIO(new ProgramCounter())) val resp = Irrevocable(new FrontEndResp()) } @@ -41,7 +34,7 @@ class Frontend(implicit params: HajimeCoreParams) extends Module { val pc_reg = RegInit(new ProgramCounter().initialise(io.reset_vector)) val addr_req_to_axi_ar = MuxCase(pc_reg.nextPC, Seq( - io.cpu.req.valid -> io.cpu.req.bits.pc, + io.cpu.req.valid -> io.cpu.req.bits.addr, // if AXI AR is not ready, or AXI R is not valid, or CPU is not ready, retain PC (!io.icache_axi4lite.ar.ready || !io.icache_axi4lite.r.valid || !io.cpu.resp.ready) -> pc_reg.addr, )) diff --git a/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala b/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala new file mode 100644 index 00000000..44367b48 --- /dev/null +++ b/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala @@ -0,0 +1,27 @@ +package hajime.vectorOoO + +import circt.stage.ChiselStage +import chisel3._ +import chisel3.util._ +import hajime.axiIO.AXI4liteIO +import hajime.common._ +import hajime.simple4Stage._ +import hajime.common.BundleInitializer._ + +class FrontEndForOoO(implicit params: HajimeCoreParams) extends Module { + val io = IO(new FrontEndIO()) + + val pc_reg = RegInit(Valid(new ProgramCounter()).Init( + _.valid -> true.B, + _.bits.addr -> io.reset_vector, + )) + val toAxiAR = MuxCase(pc_reg.bits.nextPC, Seq( + io.cpu.req.valid -> io.cpu.req.bits.addr, + // axiがreadyでなければPCを維持 + (!io.icache_axi4lite.ar.ready || !io.icache_axi4lite.r.valid || !io.cpu.resp.ready) -> pc_reg.bits.addr + )) + // cpuがFrontEndから命令を読み取ればaddr + when(io.cpu.resp.valid && io.cpu.resp.ready) { + pc_reg := io.cpu.req.bits + } +} diff --git a/src/main/scala/hajime/vectormodules/VectorCpu.scala b/src/main/scala/hajime/vectormodules/VectorCpu.scala index b48ac5ce..dd74bd12 100644 --- a/src/main/scala/hajime/vectormodules/VectorCpu.scala +++ b/src/main/scala/hajime/vectormodules/VectorCpu.scala @@ -144,7 +144,7 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar ID_ecall -> Causes.machine_ecall.U, )) ID_EX_REG.bits.dataSignals.pc := io.frontend.resp.bits.pc - ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.pc + ID_EX_REG.bits.dataSignals.bp_destPC := branch_predictor.io.out.bits.addr ID_EX_REG.bits.dataSignals.bp_taken := branch_predictor.io.out.valid ID_EX_REG.bits.dataSignals.imm := MuxCase(0.U, Seq( (decoder.io.out.bits.value1 === Value1.U_IMM.asUInt) -> decoded_inst.getImm(ImmediateEnum.U), @@ -473,7 +473,7 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar || (if(params.useException) EX_WB_REG.bits.exceptionSignals.valid || dmemoryAccessException else EX_WB_REG.bits.ctrlSignals.decode.branch === Branch.ECALL.asUInt)) when(WB_pc_redirect) { - io.frontend.req.bits.pc := csrUnit.io.resp.data + io.frontend.req.bits.addr := csrUnit.io.resp.data } // 割り込みまたは例外の場合は、PCのみ更新しリタイアしない(命令を破棄) val WB_inst_can_retire = EX_WB_REG.valid && !(EX_WB_REG.bits.exceptionSignals.valid || dmemoryAccessException) && !WB_stall diff --git a/src/test/scala/gcd/GCDSpec.scala b/src/test/scala/gcd/GCDSpec.scala deleted file mode 100644 index 7d79c44d..00000000 --- a/src/test/scala/gcd/GCDSpec.scala +++ /dev/null @@ -1,55 +0,0 @@ -// See README.md for license details. - -package gcd - -import chisel3._ -import chiseltest._ -import org.scalatest.freespec.AnyFreeSpec -import chisel3.experimental.BundleLiterals._ - -/** - * This is a trivial example of how to run this Specification - * From within sbt use: - * {{{ - * testOnly gcd.GcdDecoupledTester - * }}} - * From a terminal shell use: - * {{{ - * sbt 'testOnly gcd.GcdDecoupledTester' - * }}} - */ - -/* -class GCDSpec extends AnyFreeSpec with ChiselScalatestTester { - - "Gcd should calculate proper greatest common denominator" in { - test(new DecoupledGcd(16)) { dut => - dut.input.initSource() - dut.input.setSourceClock(dut.clock) - dut.output.initSink() - dut.output.setSinkClock(dut.clock) - - val testValues = for { x <- 0 to 10; y <- 0 to 10} yield (x, y) - val inputSeq = testValues.map { case (x, y) => (new GcdInputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U) } - val resultSeq = testValues.map { case (x, y) => - (new GcdOutputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U, _.gcd -> BigInt(x).gcd(BigInt(y)).U) - } - - fork { - // push inputs into the calculator, stall for 11 cycles one third of the way - val (seq1, seq2) = inputSeq.splitAt(resultSeq.length / 3) - dut.input.enqueueSeq(seq1) - dut.clock.step(11) - dut.input.enqueueSeq(seq2) - }.fork { - // retrieve computations from the calculator, stall for 10 cycles one half of the way - val (seq1, seq2) = resultSeq.splitAt(resultSeq.length / 2) - dut.output.expectDequeueSeq(seq1) - dut.clock.step(10) - dut.output.expectDequeueSeq(seq2) - }.join() - - } - } -} - */ From 0488c46d478f26f6da9fadc54c32d3649a4e05c6 Mon Sep 17 00:00:00 2001 From: HidetaroTanaka Date: Mon, 6 Nov 2023 18:25:14 +0900 Subject: [PATCH 4/5] a --- .../hajime/common/HajimeCoreParams.scala | 1 + src/main/scala/hajime/simple4Stage/Core.scala | 107 +----------------- .../scala/hajime/vectorOoO/Dispatcher.scala | 41 +++++++ .../hajime/vectorOoO/FrontEndForOoO.scala | 45 ++++++-- .../hajime/vectormodules/VectorCpu.scala | 4 - 5 files changed, 78 insertions(+), 120 deletions(-) create mode 100644 src/main/scala/hajime/vectorOoO/Dispatcher.scala diff --git a/src/main/scala/hajime/common/HajimeCoreParams.scala b/src/main/scala/hajime/common/HajimeCoreParams.scala index 9a6a3c6f..60c9b6b9 100644 --- a/src/main/scala/hajime/common/HajimeCoreParams.scala +++ b/src/main/scala/hajime/common/HajimeCoreParams.scala @@ -34,6 +34,7 @@ case class HajimeCoreParams( vlen: Int = 256, vecAluExecUnitNum: Int = 2, ) { + def physicalRegWidth: Int = log2Up(physicalRegFileEntriesFor1Thread) def robTagWidth: Int = log2Up(robEntries) def generateDefaultMISA: UInt = { Cat((xprlen match { diff --git a/src/main/scala/hajime/simple4Stage/Core.scala b/src/main/scala/hajime/simple4Stage/Core.scala index cc9a081c..88d226e4 100644 --- a/src/main/scala/hajime/simple4Stage/Core.scala +++ b/src/main/scala/hajime/simple4Stage/Core.scala @@ -164,9 +164,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons val csrUnit = Module(new CSRUnit()) csrUnit.io := DontCare val multiplier = if(params.useMulDiv) Some(Module(new NonPipelinedMultiplierWrap())) else None - val vectorDecoder = if(params.useVector) Some(Module(new VectorDecoder())) else None - val vecCtrlUnit = if(params.useVector) Some(Module(new VecCtrlUnit())) else None - val vecRegFile = if(params.useVector) Some(Module(new VecRegFile(vrfPortNum = 2))) else None if(params.useMulDiv) multiplier.get.io := DontCare ldstUnit.io.dcache_axi4lite <> io.dcache_axi4lite @@ -257,20 +254,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons bypassingUnit.io.ID.out.rs2_bypassMatchAtWB -> (!bypassingUnit.io.WB.in.bits.rd.valid), )) - if(params.useVector) { - vectorDecoder.get.io.inst := decoded_inst - when(decoder.io.out.valid && decoder.io.out.bits.vector.get) { - ID_EX_REG.bits.vectorCtrlSignals.get := vectorDecoder.get.io.out - } - // 0 -> v0.mask[i]が1ならば書き込み,0ならば書き込まない - // 1 -> マスクなし,全て書き込む - // (マスクを使わないベクタ命令は全てvm=1か?) - ID_EX_REG.bits.vectorDataSignals.get.mask := decoded_inst.bits(25) - ID_EX_REG.bits.vectorDataSignals.get.vs1 := decoded_inst.rs1 - ID_EX_REG.bits.vectorDataSignals.get.vs2 := decoded_inst.rs2 - ID_EX_REG.bits.vectorDataSignals.get.vd := decoded_inst.rd - } - if(params.debug) { ID_EX_REG.bits.debug.get.instruction := decoded_inst.bits ID_EX_REG.bits.debug.get.pc := io.frontend.resp.bits.pc @@ -287,44 +270,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons } // START OF EX STAGE - val idxReg = if(params.useVector) Some(RegInit(0.U(log2Up(params.vlen/8).W))) else None - val EX_WB_idxReg = if(params.useVector) Some(RegNext(idxReg.get)) else None - // TODO: ロードストアユニット内に入れる,他のベクタ実行ユニットも同様 - val vecValid = if(params.useVector) Some(RegInit(false.B)) else None - val vecDataReg = if(params.useVector) Some(RegNext(ID_EX_REG.bits.vectorDataSignals.get)) else None - if (params.useVector) { - // ベクタ命令がベクタレジスタに書き込み,かつinst.vmが1またはv0.mask[i]=1ならば書き込み - val vecWriteBack = ID_EX_REG.bits.vectorCtrlSignals.get.vrfWrite && (ID_EX_REG.bits.vectorDataSignals.get.mask || vecRegFile.get.io.readReq(0).resp.vm) - // vsetvli系でないベクタ命令が実行され,かつ最終要素でないならばインクリメント,それ以外ならばリセット - idxReg.get := MuxCase(0.U, Seq( - (ID_EX_REG.valid && ID_EX_REG.bits.ctrlSignals.decode.vector.get && !ID_EX_REG.bits.vectorCtrlSignals.get.isConfsetInst && - ((idxReg.get + 1.U) < EX_WB_REG.bits.vectorCsrPorts.get.vl)) -> (idxReg.get + 1.U) - )) - // Mux(!EX_stall && ID_inst_valid && decoder.io.out.bits.vector.get && !vectorDecoder.get.io.out.isConfsetInst, 0.U, idxReg.get + 1.U) - vecValid.get := ID_EX_REG.valid && ID_EX_REG.bits.ctrlSignals.decode.vector.get && vecWriteBack - - // vecRegFileへの入力 - vecRegFile.get.io.readReq(1) := DontCare - vecRegFile.get.io.writeReq(1) := DontCare - vecRegFile.get.io.readReq(0).req.sew := EX_WB_REG.bits.vectorCsrPorts.get.vtype.vsew - vecRegFile.get.io.readReq(0).req.idx := idxReg.get - vecRegFile.get.io.readReq(0).req.vs1 := ID_EX_REG.bits.vectorDataSignals.get.vs1 - vecRegFile.get.io.readReq(0).req.vs2 := ID_EX_REG.bits.vectorDataSignals.get.vs2 - vecRegFile.get.io.readReq(0).req.vd := ID_EX_REG.bits.vectorDataSignals.get.vd - - vecRegFile.get.io.writeReq(0).valid := vecValid.get - vecRegFile.get.io.writeReq(0).bits.vd := vecDataReg.get.vd - vecRegFile.get.io.writeReq(0).bits.vtype := EX_WB_REG.bits.vectorCsrPorts.get.vtype - vecRegFile.get.io.writeReq(0).bits.index := EX_WB_idxReg.get - vecRegFile.get.io.writeReq(0).bits.last := (EX_WB_idxReg.get-1.U) === EX_WB_REG.bits.vectorCsrPorts.get.vl - vecRegFile.get.io.writeReq(0).bits.data := ldstUnit.io.cpu.resp.bits.data - vecRegFile.get.io.writeReq(0).bits.vm := false.B - vecRegFile.get.io.writeReq(0).bits.writeReq := vecValid.get - - if(params.debug) { - io.debug_io.get.vrfMap.get := vecRegFile.get.io.debug.get - } - } alu.io.in1 := MuxLookup(ID_EX_REG.bits.ctrlSignals.decode.value1, 0.U)(Seq( Value1.RS1.asUInt -> ID_EX_REG.bits.dataSignals.rs1, @@ -337,18 +282,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons Value2.PC.asUInt -> ID_EX_REG.bits.dataSignals.pc.addr, )) - if (params.useVector) { - // ベクタメモリアクセス命令が有効ならaluへの入力を上書き - // UNIT_STRIDEならrs1+index*elen - when(ID_EX_REG.valid && ID_EX_REG.bits.ctrlSignals.decode.vector.get && ID_EX_REG.bits.vectorCtrlSignals.get.mop === MOP.UNIT_STRIDE.asUInt) { - alu.io.in2 := idxReg.get << MuxLookup(ID_EX_REG.bits.ctrlSignals.decode.memory_length, 0.U)(Seq( - MEM_LEN.B.asUInt -> 0.U, - MEM_LEN.H.asUInt -> 1.U, - MEM_LEN.W.asUInt -> 2.U, - MEM_LEN.D.asUInt -> 3.U, - )) - } - } alu.io.funct := ID_EX_REG.bits.ctrlSignals.decode branch_evaluator.io.req.bits.ALU_Result := alu.io.out @@ -370,36 +303,21 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons multiplier.get.io.resp.ready := !(EX_WB_REG.valid && WB_stall) } - if(params.useVector) { - vecCtrlUnit.get.io.req.valid := ID_EX_REG.valid && ID_EX_REG.bits.ctrlSignals.decode.vector.get && ID_EX_REG.bits.vectorCtrlSignals.get.isConfsetInst - vecCtrlUnit.get.io.req.bits.vDecode := ID_EX_REG.bits.vectorCtrlSignals.get - vecCtrlUnit.get.io.req.bits.rs1_value := ID_EX_REG.bits.dataSignals.rs1 - vecCtrlUnit.get.io.req.bits.rs2_value := ID_EX_REG.bits.dataSignals.rs2 - vecCtrlUnit.get.io.req.bits.zimm := ID_EX_REG.bits.dataSignals.zimm - vecCtrlUnit.get.io.req.bits.uimm := ID_EX_REG.bits.dataSignals.imm - } - val EX_arithmetic_result = if(params.useMulDiv) { Mux(ID_EX_REG.bits.ctrlSignals.decode.use_MUL, multiplier.get.io.resp.bits, alu.io.out) } else { alu.io.out } - val EX_vector_result = if(params.useVector) Some(vecCtrlUnit.get.io.resp.bits.vl) else None - - ldstUnit.io.cpu.req.valid := ID_EX_REG.valid && !EX_flush && (ID_EX_REG.bits.ctrlSignals.decode.memValid || (if(params.useVector) { - // マスク無しまたは要素が有効な場合にのみtrue - ID_EX_REG.bits.vectorDataSignals.get.mask || vecRegFile.get.io.readReq(0).resp.vm - } else true.B)) + ldstUnit.io.cpu.req.valid := ID_EX_REG.valid && !EX_flush && (ID_EX_REG.bits.ctrlSignals.decode.memValid) ldstUnit.io.cpu.req.bits.addr := alu.io.out - ldstUnit.io.cpu.req.bits.data := (if(params.useVector) Mux(ID_EX_REG.bits.vectorCtrlSignals.get.mop === MOP.UNIT_STRIDE.asUInt, vecRegFile.get.io.readReq(0).resp.vdOut, ID_EX_REG.bits.dataSignals.rs2) else ID_EX_REG.bits.dataSignals.rs2) + ldstUnit.io.cpu.req.bits.data := ID_EX_REG.bits.dataSignals.rs2 ldstUnit.io.cpu.req.bits.funct := ID_EX_REG.bits.ctrlSignals.decode bypassingUnit.io.EX.in.bits.rd.bits.index := ID_EX_REG.bits.ctrlSignals.rd_index bypassingUnit.io.EX.in.bits.rd.bits.value := MuxLookup(ID_EX_REG.bits.ctrlSignals.decode.writeback_selector, 0.U)(Seq( WB_SEL.PC4.asUInt -> ID_EX_REG.bits.dataSignals.pc.nextPC, WB_SEL.ARITH.asUInt -> EX_arithmetic_result, - WB_SEL.VECTOR.asUInt -> (if(params.useVector) EX_vector_result.get else 0.U) )) bypassingUnit.io.EX.in.bits.rd.valid := MuxLookup(ID_EX_REG.bits.ctrlSignals.decode.writeback_selector, false.B)(Seq( WB_SEL.PC4.asUInt -> true.B, @@ -407,7 +325,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons WB_SEL.CSR.asUInt -> false.B, WB_SEL.MEM.asUInt -> false.B, WB_SEL.NONE.asUInt -> false.B, - WB_SEL.VECTOR.asUInt -> (if(params.useVector) true.B else false.B) )) && ID_EX_REG.valid bypassingUnit.io.EX.in.valid := ID_EX_REG.bits.ctrlSignals.decode.write_to_rd && ID_EX_REG.valid @@ -415,12 +332,10 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons // 乗算命令であればmultiplier.respがvalidである必要がある // vsetvl系でないベクタ命令ならば最終要素の実行である必要がある(idxReg == vl) EX_WB_REG.valid := ID_EX_REG.valid && (!ID_EX_REG.bits.ctrlSignals.decode.memValid || ldstUnit.io.cpu.req.ready) && - (if(params.useMulDiv) !ID_EX_REG.bits.ctrlSignals.decode.use_MUL || multiplier.get.io.resp.valid else true.B) && - (if(params.useVector) !ID_EX_REG.bits.ctrlSignals.decode.vector.get || ID_EX_REG.bits.vectorCtrlSignals.get.isConfsetInst || ((idxReg.get + 1.U((idxReg.get.getWidth+1).W)) === EX_WB_REG.bits.vectorCsrPorts.get.vl) else true.B) + (if(params.useMulDiv) !ID_EX_REG.bits.ctrlSignals.decode.use_MUL || multiplier.get.io.resp.valid else true.B) EX_WB_REG.bits.dataSignals.pc := ID_EX_REG.bits.dataSignals.pc EX_WB_REG.bits.dataSignals.exResult := MuxLookup(ID_EX_REG.bits.ctrlSignals.decode.writeback_selector, 0.U)(Seq( WB_SEL.ARITH.asUInt -> EX_arithmetic_result, - WB_SEL.VECTOR.asUInt -> (if(params.useVector) EX_vector_result.get else 0.U), )) EX_WB_REG.bits.dataSignals.datatoCSR := Mux(ID_EX_REG.bits.ctrlSignals.decode.value1 === Value1.RS1.asUInt, ID_EX_REG.bits.dataSignals.rs1, ID_EX_REG.bits.dataSignals.imm) EX_WB_REG.bits.dataSignals.csr_addr := ID_EX_REG.bits.dataSignals.zimm @@ -436,21 +351,12 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons )) Mux(ID_EX_REG.bits.ctrlSignals.decode.branch === Branch.ECALL.asUInt, 0xb.U(params.xprlen.W), 0.U) - if(params.useVector) { - when(vecCtrlUnit.get.io.resp.valid) { - EX_WB_REG.bits.vectorCsrPorts.get := vecCtrlUnit.get.io.resp.bits - } - EX_WB_REG.bits.vectorExecNum.get := 0.U - } - if(params.debug) EX_WB_REG.bits.debug.get := ID_EX_REG.bits.debug.get // WBステージがvalidかつ破棄できないかつEXステージに有効な値がある場合,またはメモリアクセス命令かつldstUnit.reqがreadyでない,または乗算命令で乗算器がvalidでない // またはベクタ命令実行完了前にスカラ命令がID_EXレジスタにある,またはチェイニング不可能なベクタ命令(構造ハザード・0要素目の値が用意できていないなど) EX_stall := ID_EX_REG.valid && ((EX_WB_REG.valid && WB_stall) || (ID_EX_REG.bits.ctrlSignals.decode.memValid && !ldstUnit.io.cpu.req.ready) || (if(params.useMulDiv) { ID_EX_REG.bits.ctrlSignals.decode.use_MUL && !multiplier.get.io.resp.valid - } else false.B) || (if(params.useVector) { - ID_EX_REG.bits.ctrlSignals.decode.vector.get && !ID_EX_REG.bits.vectorCtrlSignals.get.isConfsetInst && (idxReg.get < EX_WB_REG.bits.vectorCsrPorts.get.vl-1.U) } else false.B)) when(WB_stall) { @@ -479,7 +385,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons WB_SEL.ARITH -> EX_WB_REG.bits.dataSignals.exResult, WB_SEL.CSR -> csrUnit.io.resp.data, WB_SEL.MEM -> ldstUnit.io.cpu.resp.bits.data, - WB_SEL.VECTOR -> (if(params.useVector) EX_WB_REG.bits.dataSignals.exResult else 0.U) ).map{ case (wb_sel, data) => (wb_sel.asUInt, data) }) @@ -498,16 +403,10 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons csrUnit.io.fromCPU.hartid := io.hartid csrUnit.io.fromCPU.cpu_operating := cpu_operating csrUnit.io.fromCPU.inst_retire := WB_inst_can_retire - if(params.useVector) { - csrUnit.io.fromCPU.vectorExecNum.get.valid := false.B - csrUnit.io.fromCPU.vectorExecNum.get.bits := DontCare - } csrUnit.io.exception.valid := (EX_WB_REG.bits.exceptionSignals.valid || dmemoryAccessException) && EX_WB_REG.valid csrUnit.io.exception.bits.mepc_write := EX_WB_REG.bits.dataSignals.pc.addr csrUnit.io.exception.bits.mcause_write := Mux(dmemoryAccessException, ldstUnit.io.cpu.resp.bits.exceptionSignals.bits, EX_WB_REG.bits.exceptionSignals.bits) - if(params.useVector) csrUnit.io.vectorCsrPorts.get := EX_WB_REG.bits.vectorCsrPorts.get - // EXまたはWBステージにfence, ecall, mretがある sysInst_in_pipeline := (ID_EX_REG.valid && ID_EX_REG.bits.ctrlSignals.decode.isSysInst) || (EX_WB_REG.valid && EX_WB_REG.bits.ctrlSignals.decode.isSysInst) diff --git a/src/main/scala/hajime/vectorOoO/Dispatcher.scala b/src/main/scala/hajime/vectorOoO/Dispatcher.scala new file mode 100644 index 00000000..c3372f21 --- /dev/null +++ b/src/main/scala/hajime/vectorOoO/Dispatcher.scala @@ -0,0 +1,41 @@ +package hajime.vectorOoO + +import chisel3._ +import circt.stage.ChiselStage +import chisel3.util._ +import hajime.common.BundleInitializer._ +import hajime.common._ +import hajime.simple4Stage._ +import hajime.vectormodules.VectorDecoderResp + +class DispatcherDataSignals(implicit params: HajimeCoreParams) extends Bundle { + import params._ + val pc = new ProgramCounter() + val renamedRs1 = Valid(UInt(physicalRegWidth.W)) + val renamedRs2 = Valid(UInt(physicalRegWidth.W)) + val renamedRd = Valid(UInt(physicalRegWidth.W)) + // jalr: immVal1 -> inst[31,20], immVal2 -> pc from RAS + // csr: immVal1 -> inst[31,20] (csr addr), immVal2 -> inst[4:0] + // vsetvli: immVal1 -> inst[30,20] + // vsetivli: immVal1 -> inst[29,20], immVal2 -> inst[4:0] + // vop.vi: immVal2 -> inst[4:0] + val immVal1 = UInt(xprlen.W) + val immVal2 = UInt(xprlen.W) +} +class DispatcherOutput(implicit params: HajimeCoreParams) extends Bundle { + val dataSignals = new DispatcherDataSignals() + val ctrlSignals = new BasicCtrlSignals() + val exceptionSignals = new Valid(UInt(params.xprlen.W)) + val vectorCtrlSignals = if(params.useVector) Some(new VectorDecoderResp()) else None + val debug = if(params.debug) Some(new Debug_Info()) else None +} + +class DispatcherIO(implicit params: HajimeCoreParams) extends Module { + val frontend = Flipped(new FrontEndCpuIO()) + val hartid = Input(UInt(params.xprlen.W)) + val toExecutor = new DecoupledIO(new DispatcherOutput()) +} + +class Dispatcher(implicit params: HajimeCoreParams) extends Module { + +} diff --git a/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala b/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala index 44367b48..230d7e2a 100644 --- a/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala +++ b/src/main/scala/hajime/vectorOoO/FrontEndForOoO.scala @@ -1,27 +1,48 @@ package hajime.vectorOoO -import circt.stage.ChiselStage import chisel3._ +import circt.stage.ChiselStage import chisel3.util._ -import hajime.axiIO.AXI4liteIO +import hajime.common.BundleInitializer._ import hajime.common._ import hajime.simple4Stage._ -import hajime.common.BundleInitializer._ class FrontEndForOoO(implicit params: HajimeCoreParams) extends Module { val io = IO(new FrontEndIO()) + io := DontCare val pc_reg = RegInit(Valid(new ProgramCounter()).Init( - _.valid -> true.B, + _.valid -> false.B, _.bits.addr -> io.reset_vector, )) - val toAxiAR = MuxCase(pc_reg.bits.nextPC, Seq( - io.cpu.req.valid -> io.cpu.req.bits.addr, - // axiがreadyでなければPCを維持 - (!io.icache_axi4lite.ar.ready || !io.icache_axi4lite.r.valid || !io.cpu.resp.ready) -> pc_reg.bits.addr - )) - // cpuがFrontEndから命令を読み取ればaddr - when(io.cpu.resp.valid && io.cpu.resp.ready) { - pc_reg := io.cpu.req.bits + // PCの更新はCPUが行う + when(io.cpu.req.valid) { + pc_reg := io.cpu.req + } + .otherwise { + pc_reg.valid := false.B } + + io.icache_axi4lite.ar.bits.addr := Mux(io.cpu.req.valid, io.cpu.req.bits.addr, pc_reg.bits.addr) + io.icache_axi4lite.ar.bits.prot := 0.U + io.icache_axi4lite.ar.valid := io.cpu.req.valid || pc_reg.valid + + io.cpu.resp.bits.pc := pc_reg.bits + io.cpu.resp.bits.inst.bits := io.icache_axi4lite.r.bits.data + io.cpu.resp.valid := io.icache_axi4lite.r.valid + io.icache_axi4lite.r.ready := io.cpu.resp.ready + + val instAccessFault = pc_reg.bits.addr > 0x1FFC.U + val instAddressMisaligned = pc_reg.bits.addr(1, 0) =/= 0.U + io.cpu.resp.bits.exceptionSignals.bits := MuxCase(0.U, Seq( + instAccessFault -> Causes.fetch_access.U, + instAddressMisaligned -> Causes.misaligned_fetch.U, + )) + io.cpu.resp.bits.exceptionSignals.valid := instAccessFault || instAddressMisaligned +} + +object FrontEndForOoO extends App { + implicit val params: HajimeCoreParams = HajimeCoreParams() + def apply(implicit params: HajimeCoreParams): FrontEndForOoO = new FrontEndForOoO() + ChiselStage.emitSystemVerilogFile(new FrontEndForOoO(), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS) } diff --git a/src/main/scala/hajime/vectormodules/VectorCpu.scala b/src/main/scala/hajime/vectormodules/VectorCpu.scala index dd74bd12..70516cba 100644 --- a/src/main/scala/hajime/vectormodules/VectorCpu.scala +++ b/src/main/scala/hajime/vectormodules/VectorCpu.scala @@ -293,10 +293,6 @@ class VectorCpu(implicit params: HajimeCoreParams) extends CpuModule with Scalar when(decoder.io.out.valid && decoder.io.out.bits.vector.get) { ID_EX_REG.bits.vectorCtrlSignals.get := vectorDecoder.io.out } - // 0 -> v0.mask[i]が1ならば書き込み,0ならば書き込まない - // 1 -> マスクなし,全て書き込む - // (マスクを使わないベクタ命令は全てvm=1か?) - ID_EX_REG.bits.vectorDataSignals.get.mask := vectorDecoder.io.out.vm ID_EX_REG.bits.vectorDataSignals.get.vs1 := decoded_inst.rs1 ID_EX_REG.bits.vectorDataSignals.get.vs2 := decoded_inst.rs2 ID_EX_REG.bits.vectorDataSignals.get.vd := decoded_inst.rd From 1a0431b2ef93d5f63338b795600664b72756b4e5 Mon Sep 17 00:00:00 2001 From: HidetaroTanaka Date: Tue, 7 Nov 2023 18:38:22 +0900 Subject: [PATCH 5/5] aaa --- ...V_Consts.scala => ScalarOpConstants.scala} | 11 +- src/main/scala/hajime/publicmodules/ALU.scala | 5 +- .../hajime/simple4Stage/BranchPredictor.scala | 5 +- .../scala/hajime/vectorOoO/Dispatcher.scala | 37 ++++- .../scala/hajime/vectorOoO/RenameUnit.scala | 151 ++++++++++++++++++ 5 files changed, 191 insertions(+), 18 deletions(-) rename src/main/scala/hajime/common/{RISCV_Consts.scala => ScalarOpConstants.scala} (95%) create mode 100644 src/main/scala/hajime/vectorOoO/RenameUnit.scala diff --git a/src/main/scala/hajime/common/RISCV_Consts.scala b/src/main/scala/hajime/common/ScalarOpConstants.scala similarity index 95% rename from src/main/scala/hajime/common/RISCV_Consts.scala rename to src/main/scala/hajime/common/ScalarOpConstants.scala index b85bd819..9b9589b3 100644 --- a/src/main/scala/hajime/common/RISCV_Consts.scala +++ b/src/main/scala/hajime/common/ScalarOpConstants.scala @@ -1,12 +1,7 @@ package hajime.common import chisel3._ -import chisel3.util._ -import Functions._ - -object RISCV_Consts { - val INST_LEN: Int = 32 -} +import hajime.common.Functions._ trait ScalarOpConstants { object ContentValid extends ChiselEnum { @@ -71,6 +66,10 @@ object ImmediateEnum extends ChiselEnum { val I, S, B, U, J = Value } +object UseRegisterAs extends ChiselEnum { + val NONE, SCALAR, VECTOR = Value +} + object COMPILE_CONSTANTS { val CHISELSTAGE_ARGS = Array("--emission-options=disableMemRandomization,disableRegisterRandomization") val FIRTOOLOPS = Array("-disable-all-randomization", "-strip-debug-info") diff --git a/src/main/scala/hajime/publicmodules/ALU.scala b/src/main/scala/hajime/publicmodules/ALU.scala index 4d85d39a..63e5de98 100644 --- a/src/main/scala/hajime/publicmodules/ALU.scala +++ b/src/main/scala/hajime/publicmodules/ALU.scala @@ -1,11 +1,10 @@ package hajime.publicmodules -import circt.stage.ChiselStage import chisel3._ +import circt.stage.ChiselStage import chisel3.util._ -import hajime.common.RISCV_Consts._ +import hajime.common.Functions._ import hajime.common._ -import Functions._ class ALUIO(implicit params: HajimeCoreParams) extends Bundle { import params._ diff --git a/src/main/scala/hajime/simple4Stage/BranchPredictor.scala b/src/main/scala/hajime/simple4Stage/BranchPredictor.scala index 4594ddc7..68c933e5 100644 --- a/src/main/scala/hajime/simple4Stage/BranchPredictor.scala +++ b/src/main/scala/hajime/simple4Stage/BranchPredictor.scala @@ -1,10 +1,9 @@ package hajime.simple4Stage -import circt.stage.ChiselStage import chisel3._ +import circt.stage.ChiselStage import chisel3.util._ -import hajime.common.{ScalarOpConstants, _} -import hajime.common.RISCV_Consts._ +import hajime.common._ class BranchPredictorIO(implicit params: HajimeCoreParams) extends Bundle with ScalarOpConstants { // 分岐成立予測であれば,io.out.validはtrue diff --git a/src/main/scala/hajime/vectorOoO/Dispatcher.scala b/src/main/scala/hajime/vectorOoO/Dispatcher.scala index c3372f21..789e4786 100644 --- a/src/main/scala/hajime/vectorOoO/Dispatcher.scala +++ b/src/main/scala/hajime/vectorOoO/Dispatcher.scala @@ -5,15 +5,23 @@ import circt.stage.ChiselStage import chisel3.util._ import hajime.common.BundleInitializer._ import hajime.common._ +import hajime.publicmodules._ import hajime.simple4Stage._ -import hajime.vectormodules.VectorDecoderResp +import hajime.vectormodules._ + +class RenamedReg(implicit params: HajimeCoreParams) extends Bundle { + val num = UInt(params.physicalRegWidth.W) + val useAs = UseRegisterAs() +} class DispatcherDataSignals(implicit params: HajimeCoreParams) extends Bundle { import params._ val pc = new ProgramCounter() - val renamedRs1 = Valid(UInt(physicalRegWidth.W)) - val renamedRs2 = Valid(UInt(physicalRegWidth.W)) - val renamedRd = Valid(UInt(physicalRegWidth.W)) + val renamedRs1 = new RenamedReg() + val renamedRs2 = new RenamedReg() + val renamedRs3 = new RenamedReg() + assert(renamedRs3.useAs =/= UseRegisterAs.SCALAR, "renamedRs3 must be used as Vector Register") + val renamedRd = new RenamedReg() // jalr: immVal1 -> inst[31,20], immVal2 -> pc from RAS // csr: immVal1 -> inst[31,20] (csr addr), immVal2 -> inst[4:0] // vsetvli: immVal1 -> inst[30,20] @@ -24,18 +32,35 @@ class DispatcherDataSignals(implicit params: HajimeCoreParams) extends Bundle { } class DispatcherOutput(implicit params: HajimeCoreParams) extends Bundle { val dataSignals = new DispatcherDataSignals() - val ctrlSignals = new BasicCtrlSignals() + val scalarCtrlSignals = new BasicCtrlSignals() val exceptionSignals = new Valid(UInt(params.xprlen.W)) val vectorCtrlSignals = if(params.useVector) Some(new VectorDecoderResp()) else None val debug = if(params.debug) Some(new Debug_Info()) else None } -class DispatcherIO(implicit params: HajimeCoreParams) extends Module { +class DispatcherIO(implicit params: HajimeCoreParams) extends Bundle { val frontend = Flipped(new FrontEndCpuIO()) val hartid = Input(UInt(params.xprlen.W)) val toExecutor = new DecoupledIO(new DispatcherOutput()) + // リタイア状態テーブルの同じ物理レジスタをフリーリストに入れる + val retiredRd = Input(Valid(new RetiredReg())) + val bpMiss = Input(Bool()) } class Dispatcher(implicit params: HajimeCoreParams) extends Module { + val io = IO(new DispatcherIO()) + + val decoder = Module(new Decoder()) + val branchPredictor = Module(new BranchPredictor()) + val vectorDecoder = if(params.useVector) Some(Module(new VectorDecoder())) else None + val renameUnit = Module(new RenameUnit()) + + val instBundle = Wire(new InstBundle()) + instBundle := io.frontend.resp.bits.inst + decoder.io.inst := instBundle + vectorDecoder.get.io.inst := instBundle + branchPredictor.io.pc := io.frontend.resp.bits.pc + branchPredictor.io.imm := Mux(decoder.io.out.bits.isCondBranch, instBundle.getImm(ImmediateEnum.B), instBundle.getImm(ImmediateEnum.J)) + branchPredictor.io.BranchType := decoder.io.out.bits.branch } diff --git a/src/main/scala/hajime/vectorOoO/RenameUnit.scala b/src/main/scala/hajime/vectorOoO/RenameUnit.scala new file mode 100644 index 00000000..4b0b68f7 --- /dev/null +++ b/src/main/scala/hajime/vectorOoO/RenameUnit.scala @@ -0,0 +1,151 @@ +package hajime.vectorOoO + +import chisel3._ +import circt.stage.ChiselStage +import chisel3.util._ +import hajime.common.BundleInitializer._ +import hajime.common._ +import hajime.publicmodules._ +import hajime.simple4Stage._ +import hajime.vectormodules._ + +class RenameReq extends Bundle { + val num = UInt(5.W) + val useAs = UseRegisterAs() +} + +class RetiredReg(implicit params: HajimeCoreParams) extends Bundle { + val num = UInt(5.W) + val renamedNum = UInt(params.physicalRegWidth.W) + val useAs = UseRegisterAs() +} + +class RenameReqIO(implicit params: HajimeCoreParams) extends Bundle { + val rs1 = Input(new RenameReq()) + val rs2 = Input(new RenameReq()) + val rs3 = Input(new RenameReq()) + val rd = Input(new RenameReq()) + // rdやvdへ書き込むならばフリーリストからの割当を行う + val writeToRd = Input(Bool()) + val stall = Output(Bool()) + + val renamedRs1 = Output(new RenamedReg()) + val renamedRs2 = Output(new RenamedReg()) + val renamedRs3 = Output(new RenamedReg()) + val renamedRd = Output(new RenamedReg()) + val retiredRd = Input(Valid(new RetiredReg())) + val bpMiss = Input(Bool()) +} + +class RenameUnit(implicit params: HajimeCoreParams) extends Module { + val io = IO(new RenameReqIO()) + + // 投機状態のマップテーブル + val speculativeScalarRegMapTable = RegInit(VecInit( + (0 until 32).map(_.U(params.physicalRegWidth.W)) + )) + val speculativeVectorRegMapTable = RegInit(VecInit( + (0 until 32).map(_.U(params.physicalRegWidth.W)) + )) + + // リタイア状態のマップテーブル + val retireScalarRegMapTable = RegInit(VecInit( + (0 until 32).map(_.U(params.physicalRegWidth.W)) + )) + val retireVectorRegMapTable = RegInit(VecInit( + (0 until 32).map(_.U(params.physicalRegWidth.W)) + )) + + // フリーリスト + // 初期値: 32, 33, ..., 47 + val scalarFreeList = RegInit(VecInit( + (0 until params.physicalRegFileEntriesFor1Thread).map( + i => (if(0 <= i && i < params.physicalRegFileEntriesFor1Thread-32) i+32 else 0).U(params.physicalRegWidth.W) + ) + )) + val scalarFreeListHead = RegInit(0.U(params.physicalRegWidth.W)) + val scalarFreeListTail = RegInit((params.physicalRegFileEntriesFor1Thread-32).U(params.physicalRegWidth.W)) + + val vectorFreeList = RegInit(VecInit( + (0 until params.physicalRegFileEntriesFor1Thread).map( + i => (if (0 <= i && i < params.physicalRegFileEntriesFor1Thread - 32) i + 32 else 0).U(params.physicalRegWidth.W) + ) + )) + val vectorFreeListHead = RegInit(0.U(params.physicalRegWidth.W)) + val vectorFreeListTail = RegInit((params.physicalRegFileEntriesFor1Thread - 32).U(params.physicalRegWidth.W)) + def freeListPtrNext(ptr: UInt): UInt = Mux(ptr +& 1.U === params.physicalRegFileEntriesFor1Thread.U, 0.U, ptr +& 1.U) + // headとtailが同じならばempty + val scalarFreeListEmpty = (scalarFreeListHead === scalarFreeListTail) + + io.stall := scalarFreeListEmpty + def appendToFreeList(freeList: Vec[UInt], tail: UInt, data: UInt): Unit = { + freeList(tail) := data + tail := freeListPtrNext(tail) + } + def readFromFreeList(freeList: Vec[UInt], head: UInt): UInt = { + val data = freeList(head) + head := freeListPtrNext(head) + data + } + + // 分岐予測ミスで最後のリタイアからやり直す場合,リタイア状態のマップテーブルを投機状態に入れる + // jalrの分岐予測ミスでrdが非零の場合,rdの更新を反映させる + when(io.bpMiss) { + for(((speculative, retire), i) <- (speculativeScalarRegMapTable zip retireScalarRegMapTable).zipWithIndex) { + speculative := Mux(io.retiredRd.valid && (i.U === io.retiredRd.bits.num), io.retiredRd.bits.renamedNum, retire) + } + for((speculative, retire) <- (speculativeVectorRegMapTable zip retireVectorRegMapTable)) { + speculative := retire + } + } + + // 読み出すレジスタのリネーミングは投機状態を見れば良い + io.renamedRs1.useAs := io.rs1.useAs + io.renamedRs1.num := MuxLookup(io.rs1.useAs, speculativeScalarRegMapTable(io.rs1.num))(Seq( + UseRegisterAs.SCALAR -> speculativeScalarRegMapTable(io.rs1.num), + UseRegisterAs.VECTOR -> speculativeVectorRegMapTable(io.rs1.num), + )) + io.renamedRs2.useAs := io.rs2.useAs + io.renamedRs2.num := MuxLookup(io.rs2.useAs, speculativeScalarRegMapTable(io.rs2.num))(Seq( + UseRegisterAs.SCALAR -> speculativeScalarRegMapTable(io.rs2.num), + UseRegisterAs.VECTOR -> speculativeVectorRegMapTable(io.rs2.num), + )) + io.renamedRs3.useAs := io.rs3.useAs + io.renamedRs3.num := speculativeVectorRegMapTable(io.rs3.num) + + // 書き込むレジスタのリネーミングはfreeListから取り出し,投機状態マップテーブルを更新 + when(io.writeToRd) { + assert(io.rd.useAs =/= UseRegisterAs.NONE, "specify rd usage when write to rd") + io.renamedRd.useAs := io.rd.useAs + io.renamedRd.num := 0.U + when(io.rd.useAs === UseRegisterAs.SCALAR) { + io.renamedRd.num := readFromFreeList(scalarFreeList, scalarFreeListHead) + speculativeScalarRegMapTable(io.rd.num) := io.renamedRd.num + } .elsewhen(io.rd.useAs === UseRegisterAs.VECTOR) { + io.renamedRd.num := readFromFreeList(vectorFreeList, vectorFreeListHead) + speculativeVectorRegMapTable(io.rd.num) := io.renamedRd.num + } + } .otherwise { + io.renamedRd.useAs := UseRegisterAs.NONE + io.renamedRd.num := 0.U + } + + // リタイアする場合はfreeListに使用済みのものを入れ,リタイア状態マップテーブルを更新 + when(io.retiredRd.valid) { + switch(io.retiredRd.bits.useAs) { + is(UseRegisterAs.SCALAR) { + appendToFreeList(scalarFreeList, scalarFreeListTail, retireScalarRegMapTable(io.retiredRd.bits.num)) + retireScalarRegMapTable(io.retiredRd.bits.num) := io.retiredRd.bits.renamedNum + } + is(UseRegisterAs.VECTOR) { + appendToFreeList(vectorFreeList, vectorFreeListTail, retireVectorRegMapTable(io.retiredRd.bits.num)) + retireVectorRegMapTable(io.retiredRd.bits.num) := io.retiredRd.bits.renamedNum + } + } + } +} + +object RenameUnit extends App { + implicit val params = HajimeCoreParams() + ChiselStage.emitSystemVerilogFile(new RenameUnit(), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS) +} \ No newline at end of file