diff --git a/build.sbt b/build.sbt index 9db3789..6146488 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -val spinalVersion = "1.6.4" +val spinalVersion = "1.7.0" lazy val root = (project in file(".")). settings( diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index 64ce5ae..8a291d6 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -24,6 +24,7 @@ trait DecoderService{ def add(key : MaskedLiteral,values : Seq[(Stageable[_ <: BaseType],Any)]) def add(encoding :Seq[(MaskedLiteral,Seq[(Stageable[_ <: BaseType],Any)])]) def addDefault(key : Stageable[_ <: BaseType], value : Any) + def forceIllegal() : Unit } case class ExceptionCause(codeWidth : Int) extends Bundle{ diff --git a/src/main/scala/vexriscv/VexRiscv.scala b/src/main/scala/vexriscv/VexRiscv.scala index d3feda3..ed7e37e 100644 --- a/src/main/scala/vexriscv/VexRiscv.scala +++ b/src/main/scala/vexriscv/VexRiscv.scala @@ -136,10 +136,10 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{ plugins ++= config.plugins //regression usage - val lastStageInstruction = CombInit(stages.last.input(config.INSTRUCTION)).keep().addAttribute (Verilator.public) - val lastStagePc = CombInit(stages.last.input(config.PC)).keep().addAttribute(Verilator.public) - val lastStageIsValid = CombInit(stages.last.arbitration.isValid).keep().addAttribute(Verilator.public) - val lastStageIsFiring = CombInit(stages.last.arbitration.isFiring).keep().addAttribute(Verilator.public) + val lastStageInstruction = CombInit(stages.last.input(config.INSTRUCTION)).dontSimplifyIt().addAttribute (Verilator.public) + val lastStagePc = CombInit(stages.last.input(config.PC)).dontSimplifyIt().addAttribute(Verilator.public) + val lastStageIsValid = CombInit(stages.last.arbitration.isValid).dontSimplifyIt().addAttribute(Verilator.public) + val lastStageIsFiring = CombInit(stages.last.arbitration.isFiring).dontSimplifyIt().addAttribute(Verilator.public) //Verilator perf decode.arbitration.removeIt.noBackendCombMerge diff --git a/src/main/scala/vexriscv/demo/GenCustomSimdAdd.scala b/src/main/scala/vexriscv/demo/GenCustomSimdAdd.scala index 8b137f5..8d9d6be 100644 --- a/src/main/scala/vexriscv/demo/GenCustomSimdAdd.scala +++ b/src/main/scala/vexriscv/demo/GenCustomSimdAdd.scala @@ -13,7 +13,7 @@ object GenCustomSimdAdd extends App{ plugins = List( new SimdAddPlugin, new IBusSimplePlugin( - resetVector = 0x00000000l, + resetVector = 0x80000000l, cmdForkOnSecondStage = false, cmdForkPersistence = false, prediction = NONE, diff --git a/src/main/scala/vexriscv/demo/GenSmallAndProductiveCfu.scala b/src/main/scala/vexriscv/demo/GenSmallAndProductiveCfu.scala index a571bcc..d28e318 100644 --- a/src/main/scala/vexriscv/demo/GenSmallAndProductiveCfu.scala +++ b/src/main/scala/vexriscv/demo/GenSmallAndProductiveCfu.scala @@ -53,7 +53,6 @@ object GenSmallAndProductiveCfu extends App{ new CfuPlugin( stageCount = 1, allowZeroLatency = true, - cfuIndexWidth = 4, encodings = List( CfuPluginEncoding ( instruction = M"-------------------------0001011", @@ -64,16 +63,19 @@ object GenSmallAndProductiveCfu extends App{ busParameter = CfuBusParameter( CFU_VERSION = 0, CFU_INTERFACE_ID_W = 0, - CFU_FUNCTION_ID_W = 7, + CFU_FUNCTION_ID_W = 3, CFU_REORDER_ID_W = 0, CFU_REQ_RESP_ID_W = 0, CFU_INPUTS = 2, CFU_INPUT_DATA_W = 32, CFU_OUTPUTS = 1, CFU_OUTPUT_DATA_W = 32, - CFU_STATE_INDEX_NUM = 5, CFU_FLOW_REQ_READY_ALWAYS = false, - CFU_FLOW_RESP_READY_ALWAYS = false + CFU_FLOW_RESP_READY_ALWAYS = false, + CFU_WITH_STATUS = true, + CFU_RAW_INSN_W = 32, + CFU_CFU_ID_W = 4, + CFU_STATE_INDEX_NUM = 5 ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/demo/Murax.scala b/src/main/scala/vexriscv/demo/Murax.scala index 7c679a1..95a35b5 100644 --- a/src/main/scala/vexriscv/demo/Murax.scala +++ b/src/main/scala/vexriscv/demo/Murax.scala @@ -335,6 +335,54 @@ object Murax{ } } +object MuraxCfu{ + def main(args: Array[String]) { + SpinalVerilog{ + val config = MuraxConfig.default + config.cpuPlugins += new CfuPlugin( + stageCount = 1, + allowZeroLatency = true, + encodings = List( + CfuPluginEncoding ( + instruction = M"-------------------------0001011", + functionId = List(14 downto 12), + input2Kind = CfuPlugin.Input2Kind.RS + ) + ), + busParameter = CfuBusParameter( + CFU_VERSION = 0, + CFU_INTERFACE_ID_W = 0, + CFU_FUNCTION_ID_W = 3, + CFU_REORDER_ID_W = 0, + CFU_REQ_RESP_ID_W = 0, + CFU_INPUTS = 2, + CFU_INPUT_DATA_W = 32, + CFU_OUTPUTS = 1, + CFU_OUTPUT_DATA_W = 32, + CFU_FLOW_REQ_READY_ALWAYS = false, + CFU_FLOW_RESP_READY_ALWAYS = false, + CFU_WITH_STATUS = true, + CFU_RAW_INSN_W = 32, + CFU_CFU_ID_W = 4, + CFU_STATE_INDEX_NUM = 5 + ) + ) + + val toplevel = Murax(config) + + toplevel.rework { + for (plugin <- toplevel.system.cpu.plugins) plugin match { + case plugin: CfuPlugin => plugin.bus.toIo().setName("miaou") + case _ => + } + } + + toplevel + } + } +} + + object Murax_iCE40_hx8k_breakout_board_xip{ case class SB_GB() extends BlackBox{ diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 743d2c2..a0ad2c7 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -206,7 +206,7 @@ object VexRiscvSmpClusterGen { mvendorid = null, marchid = null, mimpid = null, - mhartid = 0, + mhartid = hartId, misaExtensionsInit = 0, misaAccess = CsrAccess.NONE, mtvecAccess = CsrAccess.READ_WRITE, diff --git a/src/main/scala/vexriscv/plugin/CfuPlugin.scala b/src/main/scala/vexriscv/plugin/CfuPlugin.scala index b8e98cb..de6daa1 100644 --- a/src/main/scala/vexriscv/plugin/CfuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CfuPlugin.scala @@ -23,6 +23,7 @@ case class CfuPluginParameter( case class CfuBusParameter(CFU_VERSION : Int = 0, CFU_INTERFACE_ID_W : Int = 0, CFU_FUNCTION_ID_W : Int, + CFU_CFU_ID_W : Int = 0, CFU_REORDER_ID_W : Int = 0, CFU_REQ_RESP_ID_W : Int = 0, CFU_STATE_INDEX_NUM : Int = 0, @@ -31,7 +32,9 @@ case class CfuBusParameter(CFU_VERSION : Int = 0, CFU_OUTPUTS : Int, CFU_OUTPUT_DATA_W : Int, CFU_FLOW_REQ_READY_ALWAYS : Boolean, - CFU_FLOW_RESP_READY_ALWAYS : Boolean) + CFU_FLOW_RESP_READY_ALWAYS : Boolean, + CFU_WITH_STATUS : Boolean = false, + CFU_RAW_INSN_W : Int = 0) case class CfuCmd( p : CfuBusParameter ) extends Bundle{ val function_id = UInt(p.CFU_FUNCTION_ID_W bits) @@ -39,6 +42,8 @@ case class CfuCmd( p : CfuBusParameter ) extends Bundle{ val request_id = UInt(p.CFU_REQ_RESP_ID_W bits) val inputs = Vec(Bits(p.CFU_INPUT_DATA_W bits), p.CFU_INPUTS) val state_index = UInt(log2Up(p.CFU_STATE_INDEX_NUM) bits) + val cfu_index = UInt(p.CFU_CFU_ID_W bits) + val raw_insn = Bits(p.CFU_RAW_INSN_W bits) def weakAssignFrom(m : CfuCmd): Unit ={ def s = this WeakConnector(m, s, m.function_id, s.function_id, defaultValue = null, allowUpSize = false, allowDownSize = true , allowDrop = true) @@ -51,6 +56,7 @@ case class CfuCmd( p : CfuBusParameter ) extends Bundle{ case class CfuRsp(p : CfuBusParameter) extends Bundle{ val response_id = UInt(p.CFU_REQ_RESP_ID_W bits) val outputs = Vec(Bits(p.CFU_OUTPUT_DATA_W bits), p.CFU_OUTPUTS) + val status = p.CFU_WITH_STATUS generate Bits(3 bits) def weakAssignFrom(m : CfuRsp): Unit ={ def s = this @@ -95,7 +101,7 @@ class CfuPlugin(val stageCount : Int, val busParameter : CfuBusParameter, val encodings : List[CfuPluginEncoding] = null, val stateAndIndexCsrOffset : Int = 0xBC0, - val cfuIndexWidth : Int = 0) extends Plugin[VexRiscv]{ + val statusCsrOffset : Int = 0x801) extends Plugin[VexRiscv]{ def p = busParameter assert(p.CFU_INPUTS <= 2) @@ -151,18 +157,33 @@ class CfuPlugin(val stageCount : Int, import pipeline.config._ val csr = pipeline plug new Area{ + val factory = pipeline.service(classOf[CsrInterface]) + val en = Reg(Bool()) init(False) + factory.rw(stateAndIndexCsrOffset, 31, en) + val stateId = Reg(UInt(log2Up(p.CFU_STATE_INDEX_NUM) bits)) init(0) if(p.CFU_STATE_INDEX_NUM > 1) { assert(stateAndIndexCsrOffset != -1, "CfuPlugin stateCsrIndex need to be set in the parameters") - pipeline.service(classOf[CsrInterface]).rw(stateAndIndexCsrOffset, 16, stateId) + factory.rw(stateAndIndexCsrOffset, 16, stateId) } - bus.cmd.state_index := stateId - val cfuIndex = Reg(UInt(cfuIndexWidth bits)) init(0) - if(cfuIndexWidth != 0){ - pipeline.service(classOf[CsrInterface]).rw(stateAndIndexCsrOffset, 0, cfuIndex) + + val cfuIndex = Reg(UInt(p.CFU_CFU_ID_W bits)) init(0) + if(p.CFU_CFU_ID_W != 0){ + factory.rw(stateAndIndexCsrOffset, 0, cfuIndex) + } + val status = p.CFU_WITH_STATUS generate new Area{ + val CU, OP, FI, OF, SI, CI = RegInit(False) + val flags = List(CU, OP, FI, OF, SI, CI).reverse + factory.rw(statusCsrOffset, flags.zipWithIndex.map(_.swap) :_*) + factory.duringWrite(statusCsrOffset){ + decode.arbitration.haltByOther := True //Handle CSRW to decode + } } } + when(decode.input(CFU_ENABLE) && !csr.en){ + pipeline.service(classOf[DecoderService]).forceIllegal() + } forkStage plug new Area{ import forkStage._ @@ -181,9 +202,12 @@ class CfuPlugin(val stageCount : Int, // bus.cmd.function_id := U(input(INSTRUCTION)(14 downto 12)).resized val functionIdFromInstructinoWidth = encodings.map(_.functionIdWidth).max val functionsIds = encodings.map(e => U(Cat(e.functionId.map(r => input(INSTRUCTION)(r))), functionIdFromInstructinoWidth bits)) - bus.cmd.function_id := csr.cfuIndex @@ functionsIds.read(input(CFU_ENCODING)) + bus.cmd.cfu_index := csr.cfuIndex + bus.cmd.state_index := csr.stateId + bus.cmd.function_id := functionsIds.read(input(CFU_ENCODING)) bus.cmd.reorder_id := 0 bus.cmd.request_id := 0 + bus.cmd.raw_insn := input(INSTRUCTION).resized if(p.CFU_INPUTS >= 1) bus.cmd.inputs(0) := input(RS1) if(p.CFU_INPUTS >= 2) bus.cmd.inputs(1) := input(CFU_INPUT_2_KIND).mux( CfuPlugin.Input2Kind.RS -> input(RS2), @@ -212,6 +236,13 @@ class CfuPlugin(val stageCount : Int, arbitration.haltItself setWhen(!rsp.valid) rsp.ready := !arbitration.isStuckByOthers output(REGFILE_WRITE_DATA) := rsp.outputs(0) + if(p.CFU_WITH_STATUS) when(arbitration.isFiring){ + switch(rsp.status) { + for (i <- 1 to 6) is(i) { + csr.status.flags(i-1) := True + } + } + } } } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 3fb6498..381f2e0 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -295,7 +295,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, pipeline plug new Area{ //Memory bandwidth counter - val rspCounter = RegInit(UInt(32 bits)) init(0) + val rspCounter = Reg(UInt(32 bits)) init(0) when(dBus.rsp.valid){ rspCounter := rspCounter + 1 } diff --git a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala index 8a458ff..a525b77 100644 --- a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala @@ -71,6 +71,8 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, } } + def forceIllegal() : Unit = if(catchIllegalInstruction) pipeline.decode.input(pipeline.config.LEGAL_INSTRUCTION) := False + val defaults = mutable.LinkedHashMap[Stageable[_ <: BaseType], BaseType]() val encodings = mutable.LinkedHashMap[MaskedLiteral,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]]() var decodeExceptionPort : Flow[ExceptionCause] = null diff --git a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala index 9de1382..035c5dc 100644 --- a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala @@ -141,7 +141,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l, iBus.cmd.address.allowOverride := cache.io.mem.cmd.address //Memory bandwidth counter - val rspCounter = RegInit(UInt(32 bits)) init(0) + val rspCounter = Reg(UInt(32 bits)) init(0) when(iBus.rsp.valid){ rspCounter := rspCounter + 1 } diff --git a/src/test/cpp/custom/simd_add/src/ld b/src/test/cpp/custom/simd_add/src/ld index 8d95523..3a4f112 100644 --- a/src/test/cpp/custom/simd_add/src/ld +++ b/src/test/cpp/custom/simd_add/src/ld @@ -1,13 +1,11 @@ OUTPUT_ARCH( "riscv" ) MEMORY { - onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x00000000, LENGTH = 8K + onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x80000000, LENGTH = 8K } SECTIONS { - . = 0x000; - .crt_section : { . = ALIGN(4);