diff --git a/src/main/scala/vexiiriscv/Generate.scala b/src/main/scala/vexiiriscv/Generate.scala index e2f94692..142a917d 100644 --- a/src/main/scala/vexiiriscv/Generate.scala +++ b/src/main/scala/vexiiriscv/Generate.scala @@ -1,6 +1,7 @@ package vexiiriscv import spinal.core._ +import spinal.core.fiber.Fiber import spinal.lib.LatencyAnalysis import spinal.lib.bus.misc.SizeMapping import spinal.lib.bus.tilelink.{M2sTransfers, SizeRange} @@ -11,6 +12,7 @@ import vexiiriscv.decode.{Decode, DecodePipelinePlugin} import vexiiriscv.execute.{CsrRamPlugin, ExecuteLanePlugin, SrcPlugin} import vexiiriscv.execute.lsu._ import vexiiriscv.fetch._ +import vexiiriscv.misc.PrivilegedPlugin import vexiiriscv.prediction.BtbPlugin import vexiiriscv.regfile.RegFilePlugin import vexiiriscv.soc.TilelinkVexiiRiscvFiber @@ -87,6 +89,12 @@ object GenerateTilelink extends App { val sei = (cpu.priv.get.sei != null) generate InterruptNode.master() if(sei != null) cpu.priv.get.sei << sei; in(sei.flag) + + val patcher = Fiber build new AreaRoot { + val hartId = param.withHartIdInput generate plugins.collectFirst{ + case p : PrivilegedPlugin => p.api.harts(0).hartId.toIo + } + } } } } diff --git a/src/main/scala/vexiiriscv/Param.scala b/src/main/scala/vexiiriscv/Param.scala index 9945f851..5d108d5a 100644 --- a/src/main/scala/vexiiriscv/Param.scala +++ b/src/main/scala/vexiiriscv/Param.scala @@ -105,6 +105,7 @@ class ParamSimple(){ var privParam = PrivilegedParam.base var lsuForkAt = 0 var lsuPmaAt = 0 + var withHartIdInput = false var relaxedBranch = false var relaxedShift = false var relaxedSrc = true @@ -461,6 +462,7 @@ class ParamSimple(){ opt[Unit]("with-rvd") action { (v, c) => withRvd = true; withRvf = true } opt[Unit]("with-rvc") action { (v, c) => withRvc = true; withAlignerBuffer = true } opt[Unit]("with-rvZb") action { (v, c) => withRvZb = true } + opt[Unit]("with-hart-id-input") action { (v, c) => withHartIdInput = true } opt[Unit]("fma-reduced-accuracy") action { (v, c) => fpuFmaFullAccuracy = false } opt[Unit]("fpu-ignore-subnormal") action { (v, c) => fpuIgnoreSubnormal = true } opt[Unit]("with-aligner-buffer") unbounded() action { (v, c) => withAlignerBuffer = true } @@ -751,7 +753,7 @@ class ParamSimple(){ plugins += new CsrRamPlugin() if(withPerformanceCounters) plugins += new PerformanceCounterPlugin(additionalCounterCount = additionalPerformanceCounters) plugins += new CsrAccessPlugin(early0, writeBackKey = if(lanes == 1) "lane0" else "lane1") - plugins += new PrivilegedPlugin(privParam, hartId until hartId+hartCount) + plugins += new PrivilegedPlugin(privParam, withHartIdInput.mux(null, hartId until hartId+hartCount)) plugins += new TrapPlugin(trapAt = intWritebackAt) plugins += new EnvPlugin(early0, executeAt = 0) if(embeddedJtagTap || embeddedJtagInstruction) plugins += new EmbeddedRiscvJtag( diff --git a/src/main/scala/vexiiriscv/misc/PrivilegedPlugin.scala b/src/main/scala/vexiiriscv/misc/PrivilegedPlugin.scala index 797cf065..22a95222 100644 --- a/src/main/scala/vexiiriscv/misc/PrivilegedPlugin.scala +++ b/src/main/scala/vexiiriscv/misc/PrivilegedPlugin.scala @@ -95,11 +95,12 @@ class PrivilegedPlugin(val p : PrivilegedParam, val hartIds : Seq[Int]) extends val api = during build new Area{ val lsuTriggerBus = new LsuTriggerBus(p.debugTriggers) - val harts = for(hartId <- 0 until HART_COUNT) yield new Area{ + val harts = for(_ <- 0 until HART_COUNT) yield new Area{ val allowInterrupts = True val allowException = True val allowEbreakException = True val fpuEnable = False + val hartId = (hartIds == null) generate in(UInt(32 bits)) } } @@ -492,7 +493,14 @@ class PrivilegedPlugin(val p : PrivilegedParam, val hartIds : Seq[Int]) extends api.read(U(p.vendorId), CSR.MVENDORID) // MRO Vendor ID. api.read(U(p.archId), CSR.MARCHID) // MRO Architecture ID. api.read(U(p.impId), CSR.MIMPID) // MRO Implementation ID. - api.read(U(hartIds(hartId)), CSR.MHARTID) // MRO Hardware thread ID.Machine Trap Setup + hartIds match { + case null => { + assert(HART_COUNT.get == 1) + api.read(PrivilegedPlugin.this.api.harts(hartId).hartId, CSR.MHARTID) + } + case _ => api.read(U(hartIds(hartId)), CSR.MHARTID) // MRO Hardware thread ID.Machine Trap Setup + } + val misaExt = misaIds.map(1l << _).reduce(_ | _) val misaMxl = XLEN.get match { case 32 => BigInt(1) << XLEN.get - 2