From 0f1ca72171f0a8cac66e79b2fba0d6e0b5f682d4 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 4 Feb 2021 12:41:31 +0100 Subject: [PATCH 01/10] fix synthesis bench --- src/main/scala/vexriscv/demo/SynthesisBench.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/vexriscv/demo/SynthesisBench.scala b/src/main/scala/vexriscv/demo/SynthesisBench.scala index d0a2118..e021e19 100644 --- a/src/main/scala/vexriscv/demo/SynthesisBench.scala +++ b/src/main/scala/vexriscv/demo/SynthesisBench.scala @@ -217,7 +217,7 @@ object VexRiscvSynthesisBench { frequencyTarget = 50 MHz, vivadoPath=sys.env.getOrElse("VIVADO_ARTIX_7_BIN", null), workspacePath=workspace + "_area", - toplevelPath=rtl.getRtlPath(), + rtl=rtl, family=getFamilyName(), device="xcku035-fbva900-3-e" ) @@ -230,7 +230,7 @@ object VexRiscvSynthesisBench { frequencyTarget = 800 MHz, vivadoPath=sys.env.getOrElse("VIVADO_ARTIX_7_BIN", null), workspacePath=workspace + "_fmax", - toplevelPath=rtl.getRtlPath(), + rtl=rtl, family=getFamilyName(), device="xcku035-fbva900-3-e" ) @@ -243,7 +243,7 @@ object VexRiscvSynthesisBench { frequencyTarget = 50 MHz, vivadoPath=sys.env.getOrElse("VIVADO_ARTIX_7_BIN", null), workspacePath=workspace + "_area", - toplevelPath=rtl.getRtlPath(), + rtl=rtl, family=getFamilyName(), device="xcku3p-ffvd900-3-e" ) @@ -256,7 +256,7 @@ object VexRiscvSynthesisBench { frequencyTarget = 800 MHz, vivadoPath=sys.env.getOrElse("VIVADO_ARTIX_7_BIN", null), workspacePath=workspace + "_fmax", - toplevelPath=rtl.getRtlPath(), + rtl=rtl, family=getFamilyName(), device="xcku3p-ffvd900-3-e" ) From f278900cbe6a9c4e21f8ab585b49b9b29fb05381 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 5 Feb 2021 11:09:04 +0100 Subject: [PATCH 02/10] VexRiscvSmpCluster can now set regfile read kind --- src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index e01bd87..7c6e33d 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -15,7 +15,7 @@ import spinal.lib.generator.Handle import spinal.lib.misc.plic.PlicMapping import spinal.lib.system.debugger.SystemDebuggerConfig import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCache, InstructionCacheConfig} -import vexriscv.plugin.{BranchPlugin, CsrAccess, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DYNAMIC_TARGET, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, STATIC, SrcPlugin, StaticMemoryTranslatorPlugin, YamlPlugin} +import vexriscv.plugin.{BranchPlugin, CsrAccess, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DYNAMIC_TARGET, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, RegFileReadKind, STATIC, SrcPlugin, StaticMemoryTranslatorPlugin, YamlPlugin} import vexriscv.{Riscv, VexRiscv, VexRiscvBmbGenerator, VexRiscvConfig, plugin} import scala.collection.mutable @@ -162,7 +162,8 @@ object VexRiscvSmpClusterGen { earlyBranch : Boolean = false, dBusCmdMasterPipe : Boolean = false, withMmu : Boolean = true, - withSupervisor : Boolean = true + withSupervisor : Boolean = true, + regfileRead : RegFileReadKind = plugin.ASYNC ) = { assert(iCacheSize/iCacheWays <= 4096, "Instruction cache ways can't be bigger than 4096 bytes") assert(dCacheSize/dCacheWays <= 4096, "Data cache ways can't be bigger than 4096 bytes") @@ -236,7 +237,7 @@ object VexRiscvSmpClusterGen { catchIllegalInstruction = true ), new RegFilePlugin( - regFileReadyKind = plugin.ASYNC, + regFileReadyKind = regfileRead, zeroBoot = false, x0Init = true ), From 3b99090879a0da8d8e7373b2bda8ca492628d43d Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 16 Feb 2021 14:15:20 +0100 Subject: [PATCH 03/10] VexRiscvConfig.get added --- src/main/scala/vexriscv/VexRiscv.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/scala/vexriscv/VexRiscv.scala b/src/main/scala/vexriscv/VexRiscv.scala index 5f7865c..5730898 100644 --- a/src/main/scala/vexriscv/VexRiscv.scala +++ b/src/main/scala/vexriscv/VexRiscv.scala @@ -29,6 +29,11 @@ case class VexRiscvConfig(){ case None => None } } + def get[T](clazz: Class[T]): T = { + plugins.find(_.getClass == clazz) match { + case Some(x) => x.asInstanceOf[T] + } + } //Default Stageables object IS_RVC extends Stageable(Bool) From fe690528f7c3b8b2002e5d97081690d7cddbeac9 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 16 Feb 2021 14:16:57 +0100 Subject: [PATCH 04/10] MulPlugin.outputBuffer feature added --- .../scala/vexriscv/plugin/MulPlugin.scala | 46 +++++++++++++++---- .../vexriscv/TestIndividualFeatures.scala | 33 +++++++------ 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/MulPlugin.scala b/src/main/scala/vexriscv/plugin/MulPlugin.scala index 31714e8..c1619d2 100644 --- a/src/main/scala/vexriscv/plugin/MulPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulPlugin.scala @@ -5,7 +5,8 @@ import spinal.core._ import spinal.lib.KeepAttribute //Input buffer generaly avoid the FPGA synthesis to duplicate reg inside the DSP cell, which could stress timings quite much. -class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{ +class MulPlugin(var inputBuffer : Boolean = false, + var outputBuffer : Boolean = false) extends Plugin[VexRiscv]{ object MUL_LL extends Stageable(UInt(32 bits)) object MUL_LH extends Stageable(SInt(34 bits)) object MUL_HL extends Stageable(SInt(34 bits)) @@ -53,16 +54,26 @@ class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{ // a := input(SRC1) // b := input(SRC2) + val delay = (if(inputBuffer) 1 else 0) + (if(outputBuffer) 1 else 0) + + val delayLogic = (delay != 0) generate new Area{ + val counter = Reg(UInt(log2Up(delay+1) bits)) + when(arbitration.isValid && input(IS_MUL) && counter =/= delay){ + arbitration.haltItself := True + } + when(!arbitration.isStuckByOthers){ + counter := counter + 1 + } + when(!arbitration.isStuck){ + counter := 0 + } + } + val withInputBuffer = inputBuffer generate new Area{ val rs1 = RegNext(input(RS1)) val rs2 = RegNext(input(RS2)) a := rs1 b := rs2 - - val delay = RegNext(arbitration.isStuck) - when(arbitration.isValid && input(IS_MUL) && !delay){ - arbitration.haltItself := True - } } val noInputBuffer = (!inputBuffer) generate new Area{ @@ -91,10 +102,25 @@ class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{ val bSLow = (False ## b(15 downto 0)).asSInt val aHigh = (((aSigned && a.msb) ## a(31 downto 16))).asSInt val bHigh = (((bSigned && b.msb) ## b(31 downto 16))).asSInt - insert(MUL_LL) := aULow * bULow - insert(MUL_LH) := aSLow * bHigh - insert(MUL_HL) := aHigh * bSLow - insert(MUL_HH) := aHigh * bHigh + + val withOuputBuffer = outputBuffer generate new Area{ + val mul_ll = RegNext(aULow * bULow) + val mul_lh = RegNext(aSLow * bHigh) + val mul_hl = RegNext(aHigh * bSLow) + val mul_hh = RegNext(aHigh * bHigh) + + insert(MUL_LL) := mul_ll + insert(MUL_LH) := mul_lh + insert(MUL_HL) := mul_hl + insert(MUL_HH) := mul_hh + } + + val noOutputBuffer = (!outputBuffer) generate new Area{ + insert(MUL_LL) := aULow * bULow + insert(MUL_LH) := aSLow * bHigh + insert(MUL_HL) := aHigh * bSLow + insert(MUL_HH) := aHigh * bHigh + } Component.current.afterElaboration{ //Avoid synthesis tools to retime RS1 RS2 from execute stage to decode stage leading to bad timings (ex : Vivado, even if retiming is disabled) diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 0cf5ce6..429ad3e 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -173,19 +173,26 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") { } :: l - if(!noMemory && !noWriteBack) l = - new VexRiscvPosition("MulDivFpga") { - override def testParam = "MUL=yes DIV=yes" - override def applyOn(config: VexRiscvConfig): Unit = { - config.plugins += new MulPlugin - config.plugins += new MulDivIterativePlugin( - genMul = false, - genDiv = true, - mulUnrollFactor = 32, - divUnrollFactor = 1 - ) - } - } :: l + if(!noMemory && !noWriteBack) { + val inputBuffer = r.nextBoolean() + val outputBuffer = r.nextBoolean() + l = new VexRiscvPosition(s"MulDivFpga$inputBuffer$outputBuffer") { + override def testParam = "MUL=yes DIV=yes" + + override def applyOn(config: VexRiscvConfig): Unit = { + config.plugins += new MulPlugin( + inputBuffer = inputBuffer, + outputBuffer = outputBuffer + ) + config.plugins += new MulDivIterativePlugin( + genMul = false, + genDiv = true, + mulUnrollFactor = 32, + divUnrollFactor = 1 + ) + } + } :: l + } random(r, l) } From 1752b9e6d629e89fa6cb8ebb88fe8222e44effd3 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 16 Feb 2021 14:17:21 +0100 Subject: [PATCH 05/10] DataCache.toBmb with aggregation sync path pipelined --- src/main/scala/vexriscv/ip/DataCache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 6a7cbb7..2dac851 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -489,7 +489,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave cmdCtx.payload := aggregationCounter halt setWhen(!cmdCtx.ready) - val syncCtx = cmdCtx.queue(syncPendingMax) + val syncCtx = cmdCtx.queue(syncPendingMax).s2mPipe().m2sPipe() //Assume latency of sync is at least 3 cycles syncCtx.ready := bus.sync.fire sync.arbitrationFrom(bus.sync) From 8b2a2afb6fbcc954d333e6085e8bab71542c504f Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 16 Feb 2021 14:42:31 +0100 Subject: [PATCH 06/10] VexRIscvSmpCluster add options --- src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 7c6e33d..3f61c0d 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -159,6 +159,7 @@ object VexRiscvSmpClusterGen { iCacheWays : Int = 2, dCacheWays : Int = 2, iBusRelax : Boolean = false, + injectorStage : Boolean = false, earlyBranch : Boolean = false, dBusCmdMasterPipe : Boolean = false, withMmu : Boolean = true, @@ -181,7 +182,7 @@ object VexRiscvSmpClusterGen { prediction = vexriscv.plugin.NONE, historyRamSizeLog2 = 9, relaxPredictorAddress = true, - injectorStage = false, + injectorStage = injectorStage, relaxedPcCalculation = iBusRelax, config = InstructionCacheConfig( cacheSize = iCacheSize, From 06b7a91de4b288345d9be82324975c19a6ea1136 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 17 Feb 2021 11:35:17 +0100 Subject: [PATCH 07/10] MulPlugin fix buffer interraction with partial regfile bypass --- .../vexriscv/plugin/HazardSimplePlugin.scala | 113 +++++++++--------- .../scala/vexriscv/plugin/MulPlugin.scala | 7 +- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala b/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala index 1ed1d83..1b650e3 100644 --- a/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/HazardSimplePlugin.scala @@ -31,29 +31,62 @@ class HazardSimplePlugin(bypassExecute : Boolean = false, override def build(pipeline: VexRiscv): Unit = { import pipeline._ import pipeline.config._ - val src0Hazard = False - val src1Hazard = False - val readStage = service(classOf[RegFileService]).readStage() + pipeline plug new Area { + val src0Hazard = False + val src1Hazard = False - def trackHazardWithStage(stage : Stage,bypassable : Boolean, runtimeBypassable : Stageable[Bool]): Unit ={ - val runtimeBypassableValue = if(runtimeBypassable != null) stage.input(runtimeBypassable) else True - val addr0Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs1Range) - val addr1Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs2Range) - when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) { - if (bypassable) { - when(runtimeBypassableValue) { + val readStage = service(classOf[RegFileService]).readStage() + + def trackHazardWithStage(stage: Stage, bypassable: Boolean, runtimeBypassable: Stageable[Bool]): Unit = { + val runtimeBypassableValue = if (runtimeBypassable != null) stage.input(runtimeBypassable) else True + val addr0Match = if (pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs1Range) + val addr1Match = if (pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs2Range) + when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) { + if (bypassable) { + when(runtimeBypassableValue) { + when(addr0Match) { + readStage.input(RS1) := stage.output(REGFILE_WRITE_DATA) + } + when(addr1Match) { + readStage.input(RS2) := stage.output(REGFILE_WRITE_DATA) + } + } + } + } + when(stage.arbitration.isValid && (if (pessimisticWriteRegFile) True else stage.input(REGFILE_WRITE_VALID))) { + when((Bool(!bypassable) || !runtimeBypassableValue)) { when(addr0Match) { - readStage.input(RS1) := stage.output(REGFILE_WRITE_DATA) + src0Hazard := True } when(addr1Match) { - readStage.input(RS2) := stage.output(REGFILE_WRITE_DATA) + src1Hazard := True } } } } - when(stage.arbitration.isValid && (if(pessimisticWriteRegFile) True else stage.input(REGFILE_WRITE_VALID))) { - when((Bool(!bypassable) || !runtimeBypassableValue)) { + + + val writeBackWrites = Flow(cloneable(new Bundle { + val address = Bits(5 bits) + val data = Bits(32 bits) + })) + writeBackWrites.valid := stages.last.output(REGFILE_WRITE_VALID) && stages.last.arbitration.isFiring + writeBackWrites.address := stages.last.output(INSTRUCTION)(rdRange) + writeBackWrites.data := stages.last.output(REGFILE_WRITE_DATA) + val writeBackBuffer = writeBackWrites.stage() + + val addr0Match = if (pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs1Range) + val addr1Match = if (pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs2Range) + when(writeBackBuffer.valid) { + if (bypassWriteBackBuffer) { + when(addr0Match) { + readStage.input(RS1) := writeBackBuffer.data + } + when(addr1Match) { + readStage.input(RS2) := writeBackBuffer.data + } + } else { when(addr0Match) { src0Hazard := True } @@ -62,54 +95,24 @@ class HazardSimplePlugin(bypassExecute : Boolean = false, } } } - } + + if (withWriteBackStage) trackHazardWithStage(writeBack, bypassWriteBack, null) + if (withMemoryStage) trackHazardWithStage(memory, bypassMemory, if (stages.last == memory) null else BYPASSABLE_MEMORY_STAGE) + if (readStage != execute) trackHazardWithStage(execute, bypassExecute, if (stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE) - val writeBackWrites = Flow(cloneable(new Bundle{ - val address = Bits(5 bits) - val data = Bits(32 bits) - })) - writeBackWrites.valid := stages.last.output(REGFILE_WRITE_VALID) && stages.last.arbitration.isFiring - writeBackWrites.address := stages.last.output(INSTRUCTION)(rdRange) - writeBackWrites.data := stages.last.output(REGFILE_WRITE_DATA) - val writeBackBuffer = writeBackWrites.stage() - - val addr0Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs1Range) - val addr1Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs2Range) - when(writeBackBuffer.valid) { - if (bypassWriteBackBuffer) { - when(addr0Match) { - readStage.input(RS1) := writeBackBuffer.data + if (!pessimisticUseSrc) { + when(!readStage.input(RS1_USE)) { + src0Hazard := False } - when(addr1Match) { - readStage.input(RS2) := writeBackBuffer.data - } - } else { - when(addr0Match) { - src0Hazard := True - } - when(addr1Match) { - src1Hazard := True + when(!readStage.input(RS2_USE)) { + src1Hazard := False } } - } - if(withWriteBackStage) trackHazardWithStage(writeBack,bypassWriteBack,null) - if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory, if(stages.last == memory) null else BYPASSABLE_MEMORY_STAGE) - if(readStage != execute) trackHazardWithStage(execute ,bypassExecute , if(stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE) - - - if(!pessimisticUseSrc) { - when(!readStage.input(RS1_USE)) { - src0Hazard := False + when(readStage.arbitration.isValid && (src0Hazard || src1Hazard)) { + readStage.arbitration.haltByOther := True } - when(!readStage.input(RS2_USE)) { - src1Hazard := False - } - } - - when(readStage.arbitration.isValid && (src0Hazard || src1Hazard)){ - readStage.arbitration.haltByOther := True } } } diff --git a/src/main/scala/vexriscv/plugin/MulPlugin.scala b/src/main/scala/vexriscv/plugin/MulPlugin.scala index c1619d2..997857b 100644 --- a/src/main/scala/vexriscv/plugin/MulPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MulPlugin.scala @@ -61,10 +61,9 @@ class MulPlugin(var inputBuffer : Boolean = false, when(arbitration.isValid && input(IS_MUL) && counter =/= delay){ arbitration.haltItself := True } - when(!arbitration.isStuckByOthers){ - counter := counter + 1 - } - when(!arbitration.isStuck){ + + counter := counter + 1 + when(!arbitration.isStuck || arbitration.isStuckByOthers){ counter := 0 } } From be81cc1e0e18ade1c1e1a73fb6c2847cbd6f8d46 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 23 Feb 2021 12:23:48 +0100 Subject: [PATCH 08/10] CfuPlugin.response_ok removed --- src/main/scala/vexriscv/plugin/CfuPlugin.scala | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CfuPlugin.scala b/src/main/scala/vexriscv/plugin/CfuPlugin.scala index 60dd95b..30428e5 100644 --- a/src/main/scala/vexriscv/plugin/CfuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CfuPlugin.scala @@ -49,13 +49,11 @@ case class CfuCmd( p : CfuBusParameter ) extends Bundle{ } case class CfuRsp(p : CfuBusParameter) extends Bundle{ - val response_ok = Bool() val response_id = UInt(p.CFU_REQ_RESP_ID_W bits) val outputs = Vec(Bits(p.CFU_OUTPUT_DATA_W bits), p.CFU_OUTPUTS) def weakAssignFrom(m : CfuRsp): Unit ={ def s = this - s.response_ok := m.response_ok s.response_id := m.response_id s.outputs := m.outputs } @@ -105,7 +103,6 @@ class CfuPlugin(val stageCount : Int, // assert(p.CFU_FUNCTION_ID_W == 3) var bus : CfuBus = null - var joinException : Flow[ExceptionCause] = null lazy val forkStage = pipeline.execute lazy val joinStage = pipeline.stages(Math.min(pipeline.stages.length - 1, pipeline.indexOf(forkStage) + stageCount)) @@ -121,7 +118,6 @@ class CfuPlugin(val stageCount : Int, import pipeline.config._ bus = master(CfuBus(p)) - joinException = pipeline.service(classOf[ExceptionService]).newExceptionPort(joinStage) val decoderService = pipeline.service(classOf[DecoderService]) decoderService.addDefault(CFU_ENABLE, False) @@ -207,19 +203,11 @@ class CfuPlugin(val stageCount : Int, bus.rsp.combStage() } - joinException.valid := False - joinException.code := 15 - joinException.badAddr := 0 - rsp.ready := False when(input(CFU_IN_FLIGHT)){ arbitration.haltItself setWhen(!rsp.valid) rsp.ready := !arbitration.isStuckByOthers output(REGFILE_WRITE_DATA) := rsp.outputs(0) - - when(arbitration.isValid){ - joinException.valid := !rsp.response_ok - } } } @@ -251,7 +239,6 @@ case class CfuTest() extends Component{ val bus = slave(CfuBus(CfuTest.getCfuParameter())) } io.bus.rsp.arbitrationFrom(io.bus.cmd) - io.bus.rsp.response_ok := True io.bus.rsp.response_id := io.bus.cmd.request_id io.bus.rsp.outputs(0) := ~(io.bus.cmd.inputs(0) & io.bus.cmd.inputs(1)) } @@ -320,7 +307,6 @@ case class CfuDecoder(p : CfuBusParameter, io.input.rsp.payload := io.outputs.map(_.rsp.payload).read(OHToUInt(rspHits)) if(!hasDefault) when(rspNoHit.doIt) { io.input.rsp.valid := True - io.input.rsp.response_ok := False io.input.rsp.response_id := rspNoHit.response_id } for(output <- io.outputs) output.rsp.ready := io.input.rsp.ready From aee8841438d0b368eab0c68782f43bb2555c9966 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 4 Mar 2021 20:15:01 +0100 Subject: [PATCH 09/10] CFU ensure that CFU_IN_FLIGHT do not produce false positive when the pipeline is stuck --- src/main/scala/vexriscv/plugin/CfuPlugin.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/vexriscv/plugin/CfuPlugin.scala b/src/main/scala/vexriscv/plugin/CfuPlugin.scala index 30428e5..2586e7f 100644 --- a/src/main/scala/vexriscv/plugin/CfuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CfuPlugin.scala @@ -211,6 +211,7 @@ class CfuPlugin(val stageCount : Int, } } + pipeline.stages.dropRight(1).foreach(s => s.output(CFU_IN_FLIGHT) clearWhen(s.arbitration.isStuck)) addPrePopTask(() => stages.dropWhile(_ != memory).reverse.dropWhile(_ != joinStage).foreach(s => s.input(CFU_IN_FLIGHT).init(False))) } } From fd234bbf9e3820bb9d6e999ba2e77560c5fa3065 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 4 Mar 2021 20:29:33 +0100 Subject: [PATCH 10/10] fix cfu gen error --- src/main/scala/vexriscv/plugin/CfuPlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/CfuPlugin.scala b/src/main/scala/vexriscv/plugin/CfuPlugin.scala index 2586e7f..bb2cb56 100644 --- a/src/main/scala/vexriscv/plugin/CfuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CfuPlugin.scala @@ -211,7 +211,7 @@ class CfuPlugin(val stageCount : Int, } } - pipeline.stages.dropRight(1).foreach(s => s.output(CFU_IN_FLIGHT) clearWhen(s.arbitration.isStuck)) + pipeline.stages.drop(1).foreach(s => s.output(CFU_IN_FLIGHT) clearWhen(s.arbitration.isStuck)) addPrePopTask(() => stages.dropWhile(_ != memory).reverse.dropWhile(_ != joinStage).foreach(s => s.input(CFU_IN_FLIGHT).init(False))) } }