CoreMini / KelvinMini with 128-bit memory config Change-Id: I813d37358e7c4094c0033db08fcfc1490572a6a0
diff --git a/hdl/chisel/src/kelvin/BUILD b/hdl/chisel/src/kelvin/BUILD index 9414e08..10ab8c8 100644 --- a/hdl/chisel/src/kelvin/BUILD +++ b/hdl/chisel/src/kelvin/BUILD
@@ -203,6 +203,9 @@ verilog_file_path = "CoreMini.sv", gen_flags = [ "--enableFetchL0=False", + "--fetchDataBits=128", + "--lsuDataBits=128", + "--enableVector=False", "--moduleName=CoreMini", ], extra_outs = [
diff --git a/hdl/chisel/src/kelvin/Core.scala b/hdl/chisel/src/kelvin/Core.scala index d1b803a..b93593e 100644 --- a/hdl/chisel/src/kelvin/Core.scala +++ b/hdl/chisel/src/kelvin/Core.scala
@@ -119,6 +119,8 @@ p.fetchDataBits = arg.split("=")(1).toInt } else if (arg.startsWith("--enableVector")) { p.enableVector = arg.split("=")(1).toBoolean + } else if (arg.startsWith("--lsuDataBits")) { + p.lsuDataBits = arg.split("=")(1).toInt } else if (arg.startsWith("--target-dir")) { nextIsTargetDir = true chiselArgs = chiselArgs :+ arg
diff --git a/hdl/chisel/src/kelvin/Interfaces.scala b/hdl/chisel/src/kelvin/Interfaces.scala index 7ba3945..302bb63 100644 --- a/hdl/chisel/src/kelvin/Interfaces.scala +++ b/hdl/chisel/src/kelvin/Interfaces.scala
@@ -111,7 +111,7 @@ val write = Output(Bool()) val addr = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W)) val adrx = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W)) - val size = Output(UInt((log2Ceil(p.lsuDataBits / 8) + 1).W)) + val size = Output(UInt(p.dbusSize.W)) val wdata = Output(UInt(p.lsuDataBits.W)) val wmask = Output(UInt((p.lsuDataBits / 8).W)) // Read Phase.
diff --git a/hdl/chisel/src/kelvin/L1DCache.scala b/hdl/chisel/src/kelvin/L1DCache.scala index fed6e11..6e78791 100644 --- a/hdl/chisel/src/kelvin/L1DCache.scala +++ b/hdl/chisel/src/kelvin/L1DCache.scala
@@ -42,7 +42,7 @@ }) assert(p.axi1IdBits == 4) - assert(p.axi1DataBits == 256) + assert(p.axi1DataBits == 256 || p.axi1DataBits == 128) val bank0 = Module(new L1DCacheBank(p)) val bank1 = Module(new L1DCacheBank(p)) @@ -282,8 +282,8 @@ val bytes = p.lsuDataBits / 8 def Mem8to9(d: UInt, m: UInt): UInt = { - assert(d.getWidth == p.lsuDataBits) - assert(m.getWidth == p.lsuDataBits / 8) + assert(d.getWidth == 256) + assert(m.getWidth == 256 / 8) val data = Wire(Vec(bytes, UInt(9.W))) for (i <- 0 until bytes) { data(i) := Cat(m(i), d(7 + i * 8, 0 + i * 8)) @@ -292,7 +292,7 @@ } def Mem9to8(d: UInt): UInt = { - assert(d.getWidth == p.lsuDataBits * 9 / 8) + assert(d.getWidth == 256 * 9 / 8) val data = Wire(Vec(bytes, UInt(8.W))) for (i <- 0 until bytes) { data(i) := d(7 + i * 9, 0 + i * 9) @@ -301,7 +301,7 @@ } def Mem9to1(d: UInt): UInt = { - assert(d.getWidth == p.lsuDataBits * 9 / 8) + assert(d.getWidth == 256 * 9 / 8) val data = Wire(Vec(bytes, UInt(1.W))) for (i <- 0 until bytes) { data(i) := Cat(d(8 + i * 9)) @@ -324,9 +324,9 @@ val valid = Input(Bool()) val write = Input(Bool()) val addr = Input(UInt(slotBits.W)) - val wdata = Input(UInt((p.axi1DataBits * 9 / 8).W)) - val wmask = Input(UInt((p.axi1DataBits * 1 / 8).W)) - val rdata = Output(UInt((p.axi1DataBits * 9 / 8).W)) + val wdata = Input(UInt((256 * 9 / 8).W)) + val wmask = Input(UInt((256 * 1 / 8).W)) + val rdata = Output(UInt((256 * 9 / 8).W)) val volt_sel = Input(Bool()) }) } @@ -682,8 +682,14 @@ mem.io.write := rsel && !axiwrite || io.dbus.valid && io.dbus.write && !ractive mem.io.addr := Mux(rsel || axiwrite, replaceIdReg, foundId) mem.io.wmask := Mux(rsel, ~0.U(wmbits.W), io.dbus.wmask) - mem.io.wdata := Mux(rsel, Mem8to9(io.axi.read.data.bits.data, 0.U(wmbits.W)), - Mem8to9(io.dbus.wdata, ~0.U(wmbits.W))) + mem.io.wdata := + Mux(rsel, + Mem8to9( + Cat(0.U((256 - io.axi.read.data.bits.data.getWidth).W), io.axi.read.data.bits.data), + Cat(0.U((32 - wmbits).W), 0.U(wmbits.W))), + Mem8to9( + Cat(0.U((256 - io.dbus.wdata.getWidth).W), io.dbus.wdata), + Cat(0.U((32 - wmbits).W), ~0.U(wmbits.W)))) mem.io.volt_sel := io.volt_sel
diff --git a/hdl/chisel/src/kelvin/L1ICache.scala b/hdl/chisel/src/kelvin/L1ICache.scala index 7f2dedc..ac98d41 100644 --- a/hdl/chisel/src/kelvin/L1ICache.scala +++ b/hdl/chisel/src/kelvin/L1ICache.scala
@@ -31,11 +31,11 @@ // A relatively simple cache block. Only one transaction may post at a time. // 2^8 * 256 / 8 = 8KiB 4-way Tag[31,11] + Index[10,5] + Data[4,0] assert(p.axi0IdBits == 4) - assert(p.axi0DataBits == 256) + assert(p.axi0DataBits == 256 || p.axi0DataBits == 128) val slots = p.l1islots val slotBits = log2Ceil(slots) - val assoc = 4 + val assoc = p.l1iassoc val sets = slots / assoc val setLsb = log2Ceil(p.fetchDataBits / 8) val setMsb = log2Ceil(sets) + setLsb - 1 @@ -52,10 +52,10 @@ }) assert(assoc == 2 || assoc == 4 || assoc == 8 || assoc == 16 || assoc == slots) - assert(assoc != 2 || setLsb == 5 && setMsb == 11 && tagLsb == 12) - assert(assoc != 4 || setLsb == 5 && setMsb == 10 && tagLsb == 11) - assert(assoc != 8 || setLsb == 5 && setMsb == 9 && tagLsb == 10) - assert(assoc != 16 || setLsb == 5 && setMsb == 8 && tagLsb == 9) + assert(assoc != 2 || (setLsb == 5 && setMsb == 11 && tagLsb == 12) || (setLsb == 4 && setMsb == 10 && tagLsb == 11)) + assert(assoc != 4 || (setLsb == 5 && setMsb == 10 && tagLsb == 11) || (setLsb == 4 && setMsb == 9 && tagLsb == 10)) + assert(assoc != 8 || (setLsb == 5 && setMsb == 9 && tagLsb == 10) || (setLsb == 4 && setMsb == 8 && tagLsb == 9)) + assert(assoc != 16 || (setLsb == 5 && setMsb == 8 && tagLsb == 9) || (setLsb == 4 && setMsb == 7 && tagLsb == 8)) assert(assoc != slots || tagLsb == 5) class Sram_1rw_256x256 extends BlackBox { @@ -64,8 +64,8 @@ val valid = Input(Bool()) val write = Input(Bool()) val addr = Input(UInt(slotBits.W)) - val wdata = Input(UInt(p.axi0DataBits.W)) - val rdata = Output(UInt(p.axi0DataBits.W)) + val wdata = Input(UInt(256.W)) + val rdata = Output(UInt(256.W)) val volt_sel = Input(Bool()) }) } @@ -265,7 +265,7 @@ mem.io.valid := memread || memwrite mem.io.write := axiready mem.io.addr := Mux(axiready, replaceIdReg, readId) - mem.io.wdata := io.axi.read.data.bits.data + mem.io.wdata := Cat(0.U((256 - p.axi0DataBits).W), io.axi.read.data.bits.data) mem.io.volt_sel := io.volt_sel }
diff --git a/hdl/chisel/src/kelvin/Parameters.scala b/hdl/chisel/src/kelvin/Parameters.scala index 1d9f8f8..a7f1cf7 100644 --- a/hdl/chisel/src/kelvin/Parameters.scala +++ b/hdl/chisel/src/kelvin/Parameters.scala
@@ -32,7 +32,16 @@ } -case class Parameters(m: Seq[MemoryRegion] = Seq(), hartId: UInt = 0.U(32.W)) { +object Parameters { + def apply(): Parameters = { + return new Parameters() + } + def apply(m: Seq[MemoryRegion]): Parameters = { + return new Parameters(m) + } +} + +class Parameters(val m: Seq[MemoryRegion] = Seq(), val hartId: Int = 0) { case object Core { val tiny = 0 val little = 1 @@ -75,32 +84,40 @@ // Scalar Core Fetch bus. val fetchAddrBits = 32 // do not change var fetchDataBits = 256 // do not change + def fetchInstrSlots: Int = { + assert(fetchDataBits % 32 == 0) + assert(instructionBits % 32 == 0) + assert(fetchDataBits % instructionBits == 0) + fetchDataBits / instructionBits + } // Scalar Core Load Store Unit bus. val lsuAddrBits = 32 // do not change - val lsuDataBits = vectorBits + var lsuDataBits = vectorBits + def dbusSize: Int = { log2Ceil(lsuDataBits / 8) + 1 } // [External] Core AXI interface. val axiSysIdBits = 7 val axiSysAddrBits = 32 - val axiSysDataBits = vectorBits + def axiSysDataBits: Int = { lsuDataBits } // [Internal] L1ICache interface. val l1islots = 256 + val l1iassoc = 4 val axi0IdBits = 4 // (1x banks, 4 bits unused) val axi0AddrBits = 32 - val axi0DataBits = fetchDataBits + def axi0DataBits: Int = { fetchDataBits } // [Internal] L1DCache interface. val l1dslots = 256 // (x2 banks) val axi1IdBits = 4 // (x2 banks, 3 bits unused) val axi1AddrBits = 32 - val axi1DataBits = vectorBits + def axi1DataBits: Int = { lsuDataBits } /* axiSysDataBits */ /* vectorBits */ // [Internal] TCM[Vector,Scalar] interface. val axi2IdBits = 6 val axi2AddrBits = 32 - val axi2DataBits = vectorBits + def axi2DataBits: Int = { lsuDataBits } // vectorBits } import scala.reflect.runtime.{universe => ru} @@ -134,6 +151,9 @@ builder = builder.append(s"#define KP_${x.name} ${value}\n") } } + // TODO(atv): See if we can improve the reflection above to execute + // the methods for our dynamic parameters. + builder = builder.append(s"#define KP_dbusSize ${p.dbusSize}\n") builder = builder.append("#endif\n") builder.result() }
diff --git a/hdl/chisel/src/kelvin/scalar/Csr.scala b/hdl/chisel/src/kelvin/scalar/Csr.scala index 21b7d960..d6e2edb 100644 --- a/hdl/chisel/src/kelvin/scalar/Csr.scala +++ b/hdl/chisel/src/kelvin/scalar/Csr.scala
@@ -131,7 +131,7 @@ val mscratch = RegInit(0.U(32.W)) val mepc = RegInit(0.U(32.W)) - val mhartid = RegInit(p.hartId) + val mhartid = RegInit(p.hartId.U(32.W)) val mcycle = RegInit(0.U(64.W)) val minstret = RegInit(0.U(64.W))
diff --git a/hdl/chisel/src/kelvin/scalar/UncachedFetch.scala b/hdl/chisel/src/kelvin/scalar/UncachedFetch.scala index 0424897..797aab5 100644 --- a/hdl/chisel/src/kelvin/scalar/UncachedFetch.scala +++ b/hdl/chisel/src/kelvin/scalar/UncachedFetch.scala
@@ -21,7 +21,7 @@ class PredecodeOutput(p: Parameters) extends Bundle { val addr = UInt(p.fetchAddrBits.W) - val inst = Vec(8, UInt(p.instructionBits.W)) + val inst = Vec(p.fetchInstrSlots, UInt(p.instructionBits.W)) val startIdx = UInt(3.W) val count = UInt(4.W) val nextPc = UInt(p.instructionBits.W) @@ -29,7 +29,7 @@ class FetchResponse(p: Parameters) extends Bundle { val addr = UInt(p.fetchAddrBits.W) - val inst = Vec(8, UInt(p.instructionBits.W)) + val inst = Vec(p.fetchInstrSlots, UInt(p.instructionBits.W)) } class Instruction(p: Parameters) extends Bundle { @@ -56,7 +56,7 @@ io.fetch.valid := ibusCmd.valid io.fetch.bits.addr := Mux(ibusCmd.valid, ibusCmd.bits, 0.U) val data = Mux(ibusCmd.valid, io.ibus.rdata, 0.U) - for (i <- 0 until 8) { + for (i <- 0 until p.fetchInstrSlots) { val offset = p.instructionBits * i io.fetch.bits.inst(i) := data(offset + p.instructionBits - 1, offset) } @@ -67,7 +67,8 @@ ctrlAddr := Mux(io.ctrl.valid || ctrlValid && !io.ibus.ready, ctrlAddr, io.ctrl.bits ) - val lsb = log2Ceil(p.fetchAddrBits) + val lsb = log2Ceil(p.fetchDataBits / 8) + assert((p.fetchDataBits == 128 && lsb == 4) || (p.fetchDataBits == 256 && lsb == 5)) io.ibus.valid := io.ctrl.valid io.ibus.addr := Cat(io.ctrl.bits(p.fetchAddrBits - 1, lsb), 0.U(lsb.W)) io.ctrl.ready := io.ibus.ready @@ -87,7 +88,7 @@ val ibusFired = Input(Bool()) val fetchAddr = Decoupled(UInt(p.fetchAddrBits.W)) - val bufferRequest = DecoupledVectorIO(new FetchInstruction(p), 8) + val bufferRequest = DecoupledVectorIO(new FetchInstruction(p), p.fetchInstrSlots) }) def PredictJump(addr: UInt, inst: UInt): ValidIO[UInt] = { @@ -106,12 +107,13 @@ } def Predecode(fetchResponse: FetchResponse): (PredecodeOutput, Vec[Bool]) = { - val insts = (0 until 8).map(i => fetchResponse.inst(i)) + val insts = (0 until p.fetchInstrSlots).map(i => fetchResponse.inst(i)) val addr = fetchResponse.addr - val lsb = log2Ceil(p.fetchAddrBits) + val lsb = log2Ceil(p.fetchDataBits / 8) + assert((p.fetchDataBits == 128 && lsb == 4) || (p.fetchDataBits == 256 && lsb == 5)) val baseAddr = addr(p.fetchAddrBits - 1, lsb) - val startElem = addr(lsb - 1, lsb - 3) - val addrs = (0 until 8).map(i => Cat(baseAddr, i.U(3.W), 0.U(2.W))) + val startElem = addr(lsb - 1, lsb - log2Ceil(p.fetchInstrSlots)) + val addrs = (0 until p.fetchInstrSlots).map(i => Cat(baseAddr, i.U((lsb - 2).W), 0.U(2.W))) val branchTargets = (addrs zip insts).map { case (addr, inst) => { @@ -120,23 +122,23 @@ } } - val jumped = Wire(Vec(8, Bool())) - for (i <- 0 until 8) { + val jumped = Wire(Vec(p.fetchInstrSlots, Bool())) + for (i <- 0 until p.fetchInstrSlots) { val validInst = i.U >= startElem jumped(i) := validInst && branchTargets(i).valid } - val lastInstIdx = MuxCase(8.U, (0 until 8).map(i => jumped(i) -> i.U)) + val lastInstIdx = MuxCase(p.fetchInstrSlots.U, (0 until p.fetchInstrSlots).map(i => jumped(i) -> i.U)) val nextFetchPc = MuxCase(Cat(baseAddr + 1.U, 0.U(lsb.W)), - (0 until 8).map(i => jumped(i) -> branchTargets(i).bits)) + (0 until p.fetchInstrSlots).map(i => jumped(i) -> branchTargets(i).bits)) - val startElemW = Wire(UInt(3.W)) + val startElemW = Wire(UInt(log2Ceil(p.fetchInstrSlots).W)) startElemW := startElem val result = Wire(new PredecodeOutput(p)) result.addr := Cat(baseAddr, 0.U(lsb.W)) result.inst := insts result.startIdx := startElemW - result.count := Mux(lastInstIdx === 8.U, + result.count := Mux(lastInstIdx === p.fetchInstrSlots.U, lastInstIdx - startElem, lastInstIdx + 1.U - startElem) result.nextPc := nextFetchPc @@ -147,29 +149,29 @@ val pc = Reg(Valid(UInt(p.fetchAddrBits.W))) val (predecode, jumped) = Predecode(io.fetchData.bits) - var predecodeValids = (0 until 8).map(i => + var predecodeValids = (0 until p.fetchInstrSlots).map(i => i.U >= predecode.startIdx && i.U < (predecode.startIdx +& predecode.count) ) - for (i <- 0 until 8) { + for (i <- 0 until p.fetchInstrSlots) { val selectHot = PrioritySelect(predecodeValids) io.bufferRequest.bits(i).addr := MuxCase(0.U(p.fetchAddrBits.W), - (0 until 8).map(x => selectHot(x) -> (predecode.addr + (4 * x).U))) + (0 until p.fetchInstrSlots).map(x => selectHot(x) -> (predecode.addr + (4 * x).U))) io.bufferRequest.bits(i).inst := MuxCase(0.U(p.instructionBits.W), - (0 until 8).map(x => selectHot(x) -> predecode.inst(x))) + (0 until p.fetchInstrSlots).map(x => selectHot(x) -> predecode.inst(x))) io.bufferRequest.bits(i).brchFwd := MuxCase(false.B, - (0 until 8).map(x => selectHot(x) -> jumped(x))) + (0 until p.fetchInstrSlots).map(x => selectHot(x) -> jumped(x))) predecodeValids = VecInit((predecodeValids zip selectHot).map({case (p, s) => p && !s})) } - // We can fill up to 8 elements in the instruction buffer from each ibus + // We can fill up to p.fetchInstrSlots elements in the instruction buffer from each ibus // request. Use number of elements ready as a back-pressure signal. val fetchValid = !io.branch.valid && !reset.asBool && pc.valid && - (io.bufferRequest.nReady >= 8.U) + (io.bufferRequest.nReady >= p.fetchInstrSlots.U) val fetch = Reg(Valid(UInt(p.fetchAddrBits.W))) fetch := Mux(io.ibusFired, MakeValid(false.B, 0.U(p.fetchAddrBits.W)), @@ -225,7 +227,7 @@ val window = 16 val instructionBuffer = Module(new InstructionBuffer( - new FetchInstruction(p), 8, window, true)) + new FetchInstruction(p), p.fetchInstrSlots, window, true)) instructionBuffer.io.feedIn <> ctrl.io.bufferRequest io.inst.lanes <> instructionBuffer.io.out.take(4) instructionBuffer.io.flush.get := io.iflush.valid || branch.valid
diff --git a/hdl/chisel/src/matcha/Axi2Sram.scala b/hdl/chisel/src/matcha/Axi2Sram.scala index 934d8a0..1840ae8 100644 --- a/hdl/chisel/src/matcha/Axi2Sram.scala +++ b/hdl/chisel/src/matcha/Axi2Sram.scala
@@ -38,12 +38,12 @@ None } // Scalar DBus - val in1 = Flipped(new AxiMasterIO(p.axiSysAddrBits, p.axiSysDataBits, p.axiSysIdBits)) + val in1 = Flipped(new AxiMasterIO(p.axiSysAddrBits, p.axi2DataBits, p.axiSysIdBits)) // L1DCache - val in2 = Flipped(new AxiMasterIO(p.axiSysAddrBits, p.axiSysDataBits, p.axiSysIdBits)) + val in2 = Flipped(new AxiMasterIO(p.axiSysAddrBits, p.axi1DataBits, p.axiSysIdBits)) // L1ICache val in3 = new Bundle { - val read = Flipped(new AxiMasterReadIO(p.axiSysAddrBits, p.axiSysDataBits, p.axiSysIdBits)) + val read = Flipped(new AxiMasterReadIO(p.axiSysAddrBits, p.axi0DataBits, p.axiSysIdBits)) } // SRAM port val out = new CrossbarIO(p.axiSysAddrBits, p.axiSysDataBits, p.axiSysIdBits) @@ -51,11 +51,11 @@ assert(p.axiSysIdBits == 7) assert(p.axiSysAddrBits == 32) - assert(p.axiSysDataBits == 256) + assert(p.axiSysDataBits == 256 || p.axiSysDataBits == 128) assert(p.vectorBits == 256) - assert(p.axi0DataBits == 256) - assert(p.axi1DataBits == 256) - assert(p.axi2DataBits == 256) + assert(p.axi0DataBits == 256 || p.axi0DataBits == 128) + assert(p.axi1DataBits == 256 || p.axi1DataBits == 128) + assert(p.axi2DataBits == 256 || p.axi2DataBits == 128) def Decode(i: Int, id: UInt): Bool = { assert(id.getWidth == 7) @@ -221,7 +221,7 @@ } for (x <- readInterfaces) { - assert(!(x.data.valid && !x.data.ready)) + assert(!x.data.valid || x.data.ready) } assert(!(cctrl.io.in.valid && cctrl.io.in.ready && cctrl.io.in.bits.cwrite && !wdata.io.in.valid))
diff --git a/hdl/chisel/src/matcha/BUILD b/hdl/chisel/src/matcha/BUILD index 0b79dda..30fe3ef 100644 --- a/hdl/chisel/src/matcha/BUILD +++ b/hdl/chisel/src/matcha/BUILD
@@ -42,6 +42,9 @@ "//hdl/verilog:sram_1rw_256x256", "//hdl/verilog:sram_1rw_256x288", ], + extra_outs = [ + "VKelvin_parameters.h", + ], ) chisel_cc_library( @@ -59,6 +62,9 @@ "--enableVector=False", "--moduleName=KelvinScalar", ], + extra_outs = [ + "VKelvinScalar_parameters.h", + ], ) chisel_cc_library( @@ -74,8 +80,14 @@ verilog_file_path = "KelvinMini.sv", gen_flags = [ "--enableFetchL0=False", + "--fetchDataBits=128", + "--lsuDataBits=128", + "--enableVector=False", "--moduleName=KelvinMini", ], + extra_outs = [ + "VKelvinMini_parameters.h", + ], ) chisel_cc_library(
diff --git a/hdl/chisel/src/matcha/Kelvin.scala b/hdl/chisel/src/matcha/Kelvin.scala index fcb9e81..23745ae 100644 --- a/hdl/chisel/src/matcha/Kelvin.scala +++ b/hdl/chisel/src/matcha/Kelvin.scala
@@ -19,6 +19,8 @@ import bus.KelvinMemIO import common._ +import java.nio.file.{Paths, Files, StandardOpenOption} +import java.nio.charset.{StandardCharsets} import _root_.circt.stage.ChiselStage object Kelvin { @@ -142,19 +144,50 @@ object EmitKelvin extends App { val p = new kelvin.MatchaParameters + val core_p = new kelvin.Parameters var moduleName = "Kelvin" var chiselArgs = List[String]() + var targetDir: Option[String] = None + var nextIsTargetDir = false for (arg <- args) { + if (nextIsTargetDir) { + nextIsTargetDir = false + chiselArgs = chiselArgs :+ arg + targetDir = Some(arg) + } if (arg.startsWith("--enableFetchL0")) { - p.enableFetchL0 = arg.split("=")(1).toBoolean + val argval = arg.split("=")(1).toBoolean + p.enableFetchL0 = argval + core_p.enableFetchL0 = argval } else if (arg.startsWith("--moduleName")) { moduleName = arg.split("=")(1) } else if (arg.startsWith("--enableVector")) { - p.enableVector = arg.split("=")(1).toBoolean + val argval = arg.split("=")(1).toBoolean + p.enableVector = argval + core_p.enableVector = argval + } else if (arg.startsWith("--fetchDataBits")) { + val argval = arg.split("=")(1).toInt + p.fetchDataBits = argval + core_p.fetchDataBits = argval + } else if (arg.startsWith("--lsuDataBits")) { + val argval = arg.split("=")(1).toInt + p.lsuDataBits = argval + core_p.lsuDataBits = argval + } else if (arg.startsWith("--target-dir")) { + nextIsTargetDir = true + chiselArgs = chiselArgs :+ arg } else { chiselArgs = chiselArgs :+ arg } } ChiselStage.emitSystemVerilogFile( new Kelvin(p, moduleName), chiselArgs.toArray) + val header_str = kelvin.EmitParametersHeader(core_p) + targetDir match { + case Some(targetDir) => { + var ret = Files.write(Paths.get(targetDir + "/V" + moduleName + "_parameters.h"), header_str.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE) + () + } + case None => () + } }
diff --git a/hdl/chisel/src/matcha/MatchaParameters.scala b/hdl/chisel/src/matcha/MatchaParameters.scala index 7b5e6cf..55034b7 100644 --- a/hdl/chisel/src/matcha/MatchaParameters.scala +++ b/hdl/chisel/src/matcha/MatchaParameters.scala
@@ -18,7 +18,7 @@ import chisel3.util._ class MatchaParameters(m: Seq[MemoryRegion] = Seq(), - hartId: UInt = 2.U(32.W)) extends Parameters(m) { + hartId: Int = 2) extends Parameters(m, hartId) { // Debug // tl_main_pkg::ADDR_SPACE_DBG + dm::HaltAddress
diff --git a/tests/verilator_sim/BUILD b/tests/verilator_sim/BUILD index b67e15f..c2390c1 100644 --- a/tests/verilator_sim/BUILD +++ b/tests/verilator_sim/BUILD
@@ -110,6 +110,7 @@ srcs = [ "matcha/kelvin_if.h", "matcha/kelvin_tb.cc", + "@kelvin_hw//hdl/chisel/src/matcha:VKelvin_parameters.h", ], defines = [ "VERILATOR_MODEL=VKelvin", @@ -129,6 +130,7 @@ srcs = [ "matcha/kelvin_if.h", "matcha/kelvin_tb.cc", + "@kelvin_hw//hdl/chisel/src/matcha:VKelvinScalar_parameters.h", ], defines = [ "VERILATOR_MODEL=VKelvinScalar", @@ -148,6 +150,7 @@ srcs = [ "matcha/kelvin_if.h", "matcha/kelvin_tb.cc", + "@kelvin_hw//hdl/chisel/src/matcha:VKelvinMini_parameters.h", ], defines = [ "VERILATOR_MODEL=VKelvinMini",
diff --git a/tests/verilator_sim/kelvin/core_if.h b/tests/verilator_sim/kelvin/core_if.h index 1709f4b..ba7c5da 100644 --- a/tests/verilator_sim/kelvin/core_if.h +++ b/tests/verilator_sim/kelvin/core_if.h
@@ -62,17 +62,17 @@ sc_in<bool> io_ibus_valid; sc_out<bool> io_ibus_ready; sc_in<sc_bv<32> > io_ibus_addr; - sc_out<sc_bv<256> > io_ibus_rdata; + sc_out<sc_bv<KP_fetchDataBits> > io_ibus_rdata; sc_in<bool> io_dbus_valid; sc_out<bool> io_dbus_ready; sc_in<bool> io_dbus_write; sc_in<sc_bv<32> > io_dbus_addr; sc_in<sc_bv<32> > io_dbus_adrx; - sc_in<sc_bv<kDbusBits> > io_dbus_size; - sc_in<sc_bv<kVector> > io_dbus_wdata; - sc_in<sc_bv<kVector / 8> > io_dbus_wmask; - sc_out<sc_bv<kVector> > io_dbus_rdata; + sc_in<sc_bv<KP_dbusSize> > io_dbus_size; + sc_in<sc_bv<KP_lsuDataBits> > io_dbus_wdata; + sc_in<sc_bv<KP_lsuDataBits / 8> > io_dbus_wmask; + sc_out<sc_bv<KP_lsuDataBits> > io_dbus_rdata; #if KP_enableVector sc_out<bool> io_axi0_write_addr_ready; @@ -81,8 +81,8 @@ sc_in<sc_bv<kUncId> > io_axi0_write_addr_bits_id; sc_out<bool> io_axi0_write_data_ready; sc_in<bool> io_axi0_write_data_valid; - sc_in<sc_bv<kUncBits> > io_axi0_write_data_bits_data; - sc_in<sc_bv<kUncStrb> > io_axi0_write_data_bits_strb; + sc_in<sc_bv<KP_lsuDataBits> > io_axi0_write_data_bits_data; + sc_in<sc_bv<KP_lsuDataBits/8> > io_axi0_write_data_bits_strb; sc_in<bool> io_axi0_write_resp_ready; sc_out<bool> io_axi0_write_resp_valid; sc_out<sc_bv<kUncId> > io_axi0_write_resp_bits_id; @@ -95,7 +95,7 @@ sc_out<bool> io_axi0_read_data_valid; sc_out<sc_bv<2> > io_axi0_read_data_bits_resp; sc_out<sc_bv<kUncId> > io_axi0_read_data_bits_id; - sc_out<sc_bv<kUncBits> > io_axi0_read_data_bits_data; + sc_out<sc_bv<KP_lsuDataBits> > io_axi0_read_data_bits_data; #endif // KP_enableVector sc_out<bool> io_axi1_write_addr_ready; sc_in<bool> io_axi1_write_addr_valid; @@ -103,8 +103,8 @@ sc_in<sc_bv<kUncId> > io_axi1_write_addr_bits_id; sc_out<bool> io_axi1_write_data_ready; sc_in<bool> io_axi1_write_data_valid; - sc_in<sc_bv<kUncBits> > io_axi1_write_data_bits_data; - sc_in<sc_bv<kUncStrb> > io_axi1_write_data_bits_strb; + sc_in<sc_bv<KP_lsuDataBits> > io_axi1_write_data_bits_data; + sc_in<sc_bv<KP_lsuDataBits/8> > io_axi1_write_data_bits_strb; sc_in<bool> io_axi1_write_resp_ready; sc_out<bool> io_axi1_write_resp_valid; sc_out<sc_bv<kUncId> > io_axi1_write_resp_bits_id; @@ -117,10 +117,10 @@ sc_out<bool> io_axi1_read_data_valid; sc_out<sc_bv<2> > io_axi1_read_data_bits_resp; sc_out<sc_bv<kUncId> > io_axi1_read_data_bits_id; - sc_out<sc_bv<kUncBits> > io_axi1_read_data_bits_data; + sc_out<sc_bv<KP_lsuDataBits> > io_axi1_read_data_bits_data; Core_if(sc_module_name n, const char* bin) : Memory_if(n, bin) { - for (int i = 0; i < kUncBits / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { runused_.set_word(i, 0); } } @@ -177,14 +177,14 @@ // Data bus read. if (io_dbus_valid && io_dbus_ready && !io_dbus_write) { - sc_bv<kVector> rdata; + sc_bv<KP_lsuDataBits> rdata; uint32_t addr = io_dbus_addr.read().get_word(0); - uint32_t words[kVector / 32] = {0}; + uint32_t words[KP_lsuDataBits / 32] = {0}; memset(words, 0xcc, sizeof(words)); int bytes = io_dbus_size.read().get_word(0); Read(addr, bytes, reinterpret_cast<uint8_t*>(words)); - ReadSwizzle(addr, kVector / 8, reinterpret_cast<uint8_t*>(words)); - for (int i = 0; i < kVector / 32; ++i) { + ReadSwizzle(addr, KP_lsuDataBits / 8, reinterpret_cast<uint8_t*>(words)); + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { rdata.set_word(i, words[i]); } io_dbus_rdata = rdata; @@ -192,30 +192,30 @@ // Data bus write. if (io_dbus_valid && io_dbus_ready && io_dbus_write) { - sc_bv<kVector> wdata = io_dbus_wdata; + sc_bv<KP_lsuDataBits> wdata = io_dbus_wdata; uint32_t addr = io_dbus_addr.read().get_word(0); - uint32_t words[kVector / 32]; + uint32_t words[KP_lsuDataBits / 32]; int bytes = io_dbus_size.read().get_word(0); - for (int i = 0; i < kVector / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { words[i] = wdata.get_word(i); } - WriteSwizzle(addr, kVector / 8, reinterpret_cast<uint8_t*>(words)); + WriteSwizzle(addr, KP_lsuDataBits / 8, reinterpret_cast<uint8_t*>(words)); Write(addr, bytes, reinterpret_cast<uint8_t*>(words)); } rtcm_t tcm_read; - sc_bv<kUncBits> rdata; + sc_bv<KP_lsuDataBits> rdata; #if KP_enableVector // axi0 read. if (io_axi0_read_addr_valid && io_axi0_read_addr_ready) { uint32_t addr = io_axi0_read_addr_bits_addr.read().get_word(0); - uint32_t words[kUncBits / 32]; - Read(addr, kUncBits / 8, reinterpret_cast<uint8_t*>(words)); + uint32_t words[KP_lsuDataBits / 32]; + Read(addr, KP_lsuDataBits / 8, reinterpret_cast<uint8_t*>(words)); tcm_read.cycle = cycle_; tcm_read.id = io_axi0_read_addr_bits_id.read().get_word(0); - for (int i = 0; i < kUncBits / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { tcm_read.data.set_word(i, words[i]); } rtcm_[0].write(tcm_read); @@ -236,15 +236,15 @@ // axi0 write. if (io_axi0_write_addr_valid && io_axi0_write_addr_ready) { assert(io_axi0_write_data_valid && io_axi0_write_data_valid); - uint8_t wdata[kUncBits / 8]; + uint8_t wdata[KP_lsuDataBits / 8]; uint32_t addr = io_axi0_write_addr_bits_addr.read().get_word(0); uint32_t* p_wdata = reinterpret_cast<uint32_t*>(wdata); - for (int i = 0; i < kUncBits / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { p_wdata[i] = io_axi0_write_data_bits_data.read().get_word(i); } - for (int i = 0; i < kUncBits / 8; ++i) { + for (int i = 0; i < KP_lsuDataBits / 8; ++i) { if (io_axi0_write_data_bits_strb.read().get_bit(i) != 0) { Write(addr + i, 1, wdata + i); } @@ -260,12 +260,12 @@ // axi1 read. if (io_axi1_read_addr_valid && io_axi1_read_addr_ready) { uint32_t addr = io_axi1_read_addr_bits_addr.read().get_word(0); - uint32_t words[kUncBits / 32]; - Read(addr, kUncBits / 8, reinterpret_cast<uint8_t*>(words)); + uint32_t words[KP_lsuDataBits / 32]; + Read(addr, KP_lsuDataBits / 8, reinterpret_cast<uint8_t*>(words)); tcm_read.cycle = cycle_; tcm_read.id = io_axi1_read_addr_bits_id.read().get_word(0); - for (int i = 0; i < kUncBits / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { tcm_read.data.set_word(i, words[i]); } rtcm_[1].write(tcm_read); @@ -286,15 +286,15 @@ // axi1 write. if (io_axi1_write_addr_valid && io_axi1_write_addr_ready) { assert(io_axi1_write_data_valid && io_axi1_write_data_valid); - uint8_t wdata[kUncBits / 8]; + uint8_t wdata[KP_lsuDataBits / 8]; uint32_t addr = io_axi1_write_addr_bits_addr.read().get_word(0); uint32_t* p_wdata = reinterpret_cast<uint32_t*>(wdata); - for (int i = 0; i < kUncBits / 32; ++i) { + for (int i = 0; i < KP_lsuDataBits / 32; ++i) { p_wdata[i] = io_axi1_write_data_bits_data.read().get_word(i); } - for (int i = 0; i < kUncBits / 8; ++i) { + for (int i = 0; i < KP_lsuDataBits / 8; ++i) { if (io_axi1_write_data_bits_strb.read().get_bit(i) != 0) { Write(addr + i, 1, wdata + i); } @@ -314,11 +314,11 @@ struct rtcm_t { uint32_t cycle; uint32_t id : 7; - sc_bv<kUncBits> data; + sc_bv<KP_lsuDataBits> data; }; fifo_t<rtcm_t> rtcm_[2]; - sc_bv<kUncBits> runused_; + sc_bv<KP_lsuDataBits> runused_; }; #endif // TESTS_VERILATOR_SIM_KELVIN_CORE_IF_H_
diff --git a/tests/verilator_sim/kelvin/core_tb.cc b/tests/verilator_sim/kelvin/core_tb.cc index 8d5b982..ed45a8c 100644 --- a/tests/verilator_sim/kelvin/core_tb.cc +++ b/tests/verilator_sim/kelvin/core_tb.cc
@@ -90,13 +90,13 @@ sc_signal<sc_bv<32> > io_csr_out_value_6; sc_signal<sc_bv<32> > io_csr_out_value_7; sc_signal<sc_bv<32> > io_ibus_addr; - sc_signal<sc_bv<256> > io_ibus_rdata; + sc_signal<sc_bv<KP_fetchDataBits> > io_ibus_rdata; sc_signal<sc_bv<32> > io_dbus_addr; sc_signal<sc_bv<32> > io_dbus_adrx; - sc_signal<sc_bv<kDbusBits> > io_dbus_size; - sc_signal<sc_bv<kVector> > io_dbus_wdata; - sc_signal<sc_bv<kVector / 8> > io_dbus_wmask; - sc_signal<sc_bv<kVector> > io_dbus_rdata; + sc_signal<sc_bv<KP_dbusSize> > io_dbus_size; + sc_signal<sc_bv<KP_lsuDataBits> > io_dbus_wdata; + sc_signal<sc_bv<KP_lsuDataBits / 8> > io_dbus_wmask; + sc_signal<sc_bv<KP_lsuDataBits> > io_dbus_rdata; sc_signal<sc_bv<5> > io_slog_addr; sc_signal<sc_bv<32> > io_slog_data; sc_signal<sc_bv<4> > io_debug_en; @@ -108,8 +108,8 @@ sc_signal<sc_bv<kUncId> > io_axi0_write_addr_bits_id; sc_signal<bool> io_axi0_write_data_ready; sc_signal<bool> io_axi0_write_data_valid; - sc_signal<sc_bv<kUncBits> > io_axi0_write_data_bits_data; - sc_signal<sc_bv<kUncStrb> > io_axi0_write_data_bits_strb; + sc_signal<sc_bv<KP_lsuDataBits> > io_axi0_write_data_bits_data; + sc_signal<sc_bv<KP_lsuDataBits/8> > io_axi0_write_data_bits_strb; sc_signal<bool> io_axi0_write_resp_ready; sc_signal<bool> io_axi0_write_resp_valid; sc_signal<sc_bv<kUncId> > io_axi0_write_resp_bits_id; @@ -122,7 +122,7 @@ sc_signal<bool> io_axi0_read_data_valid; sc_signal<sc_bv<2> > io_axi0_read_data_bits_resp; sc_signal<sc_bv<kUncId> > io_axi0_read_data_bits_id; - sc_signal<sc_bv<kUncBits> > io_axi0_read_data_bits_data; + sc_signal<sc_bv<KP_lsuDataBits> > io_axi0_read_data_bits_data; #endif // KP_enableVector sc_signal<bool> io_axi1_write_addr_ready; sc_signal<bool> io_axi1_write_addr_valid; @@ -130,8 +130,8 @@ sc_signal<sc_bv<kUncId> > io_axi1_write_addr_bits_id; sc_signal<bool> io_axi1_write_data_ready; sc_signal<bool> io_axi1_write_data_valid; - sc_signal<sc_bv<kUncBits> > io_axi1_write_data_bits_data; - sc_signal<sc_bv<kUncStrb> > io_axi1_write_data_bits_strb; + sc_signal<sc_bv<KP_lsuDataBits> > io_axi1_write_data_bits_data; + sc_signal<sc_bv<KP_lsuDataBits/8> > io_axi1_write_data_bits_strb; sc_signal<bool> io_axi1_write_resp_ready; sc_signal<bool> io_axi1_write_resp_valid; sc_signal<sc_bv<kUncId> > io_axi1_write_resp_bits_id; @@ -144,7 +144,7 @@ sc_signal<bool> io_axi1_read_data_valid; sc_signal<sc_bv<2> > io_axi1_read_data_bits_resp; sc_signal<sc_bv<kUncId> > io_axi1_read_data_bits_id; - sc_signal<sc_bv<kUncBits> > io_axi1_read_data_bits_data; + sc_signal<sc_bv<KP_lsuDataBits> > io_axi1_read_data_bits_data; #define IO_DEBUG(x) \ sc_signal<sc_bv<32> > io_debug_addr##x; \
diff --git a/tests/verilator_sim/matcha/kelvin_if.h b/tests/verilator_sim/matcha/kelvin_if.h index f18ec48..0f435fb 100644 --- a/tests/verilator_sim/matcha/kelvin_if.h +++ b/tests/verilator_sim/matcha/kelvin_if.h
@@ -18,12 +18,17 @@ #include "tests/verilator_sim/kelvin/memory_if.h" #include "tests/verilator_sim/kelvin/kelvin_cfg.h" +#define PARAMS_HEADER_PREFIX hdl/chisel/src/matcha/ +#define PARAMS_HEADER_SUFFIX _parameters.h +#define PARAMS_HEADER STR(PARAMS_HEADER_PREFIX VERILATOR_MODEL PARAMS_HEADER_SUFFIX) +#include PARAMS_HEADER + // [Bus] addr // 1cc [SRAM] addr // 2cc [SRAM] rdata // [Bus] rdata constexpr int kWaitState = 2; -constexpr int kBusBits = 256; +constexpr int kBusBits = KP_lsuDataBits; struct Kelvin_if : Memory_if { sc_in<bool> io_bus_cvalid; @@ -32,7 +37,7 @@ sc_in<sc_bv<7> > io_bus_cid; sc_in<sc_bv<32> > io_bus_caddr; sc_in<sc_bv<kBusBits> > io_bus_wdata; - sc_in<sc_bv<32> > io_bus_wmask; + sc_in<sc_bv<kBusBits / 8> > io_bus_wmask; sc_out<bool> io_bus_rvalid; sc_out<sc_bv<7> > io_bus_rid;
diff --git a/tests/verilator_sim/matcha/kelvin_tb.cc b/tests/verilator_sim/matcha/kelvin_tb.cc index 38de989..cd17021 100644 --- a/tests/verilator_sim/matcha/kelvin_tb.cc +++ b/tests/verilator_sim/matcha/kelvin_tb.cc
@@ -21,6 +21,11 @@ #define MODEL_HEADER STR(VERILATOR_MODEL MODEL_HEADER_SUFFIX) #include MODEL_HEADER +#define PARAMS_HEADER_PREFIX hdl/chisel/src/matcha/ +#define PARAMS_HEADER_SUFFIX _parameters.h +#define PARAMS_HEADER STR(PARAMS_HEADER_PREFIX VERILATOR_MODEL PARAMS_HEADER_SUFFIX) +#include PARAMS_HEADER + #include "absl/flags/flag.h" #include "absl/flags/parse.h" #include "absl/flags/usage.h" @@ -65,11 +70,11 @@ sc_signal<bool> cwrite; sc_signal<sc_bv<32> > caddr; sc_signal<sc_bv<7> > cid; - sc_signal<sc_bv<256> > wdata; - sc_signal<sc_bv<32> > wmask; + sc_signal<sc_bv<KP_lsuDataBits> > wdata; + sc_signal<sc_bv<KP_lsuDataBits / 8> > wmask; sc_signal<bool> rvalid; sc_signal<sc_bv<7> > rid; - sc_signal<sc_bv<256> > rdata; + sc_signal<sc_bv<KP_lsuDataBits> > rdata; ml_reset = 0; clk_freeze = 0;