From c242744d02b052a7883aa618fe6ce9dca5f7fa68 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Jul 2021 14:45:54 +0200 Subject: [PATCH] CfuPlugin now only fork when the rest of the pipeline is hazard free --- src/main/scala/vexriscv/Stage.scala | 14 +++++++------- src/main/scala/vexriscv/plugin/CfuPlugin.scala | 6 +++++- .../vexriscv/plugin/DBusCachedPlugin.scala | 18 +++++++++++------- .../vexriscv/plugin/DBusSimplePlugin.scala | 8 +++++--- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/main/scala/vexriscv/Stage.scala b/src/main/scala/vexriscv/Stage.scala index 5f3365a..d4099d6 100644 --- a/src/main/scala/vexriscv/Stage.scala +++ b/src/main/scala/vexriscv/Stage.scala @@ -14,13 +14,13 @@ class Stageable[T <: Data](_dataType : => T) extends HardType[T](_dataType) with class Stage() extends Area{ def outsideCondScope[T](that : => T) : T = { - val body = Component.current.dslBody - body.push() - val swapContext = body.swap() - val ret = that - body.pop() - swapContext.appendBack() - ret + val body = Component.current.dslBody // Get the head of the current component symboles tree (AST in other words) + body.push() // Now all access to the SpinalHDL API will be append to it (instead of the current context) + val swapContext = body.swap() // Empty the symbole tree (but keep a reference to the old content) + val ret = that // Execute the block of code (will be added to the recently empty body) + body.pop() // Restore the original context in which this function was called + swapContext.appendBack() // append the original symboles tree to the modified body + ret // return the value returned by that } def input[T <: Data](key : Stageable[T]) : T = { diff --git a/src/main/scala/vexriscv/plugin/CfuPlugin.scala b/src/main/scala/vexriscv/plugin/CfuPlugin.scala index c96be09..6817e9d 100644 --- a/src/main/scala/vexriscv/plugin/CfuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CfuPlugin.scala @@ -166,7 +166,11 @@ class CfuPlugin(val stageCount : Int, forkStage plug new Area{ import forkStage._ - val schedule = arbitration.isValid && input(CFU_ENABLE) + val hazard = stages.dropWhile(_ != forkStage).tail.map(s => s.arbitration.isValid && s.input(HAS_SIDE_EFFECT)).orR + val scheduleWish = arbitration.isValid && input(CFU_ENABLE) + val schedule = scheduleWish && !hazard + arbitration.haltItself setWhen(scheduleWish && hazard) + val hold = RegInit(False) setWhen(schedule) clearWhen(bus.cmd.ready) val fired = RegInit(False) setWhen(bus.cmd.fire) clearWhen(!arbitration.isStuckByOthers) insert(CFU_IN_FLIGHT) := schedule || hold || fired diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 4309ea2..99786e7 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -81,8 +81,9 @@ class DBusCachedPlugin(val config : DataCacheConfig, // REGFILE_WRITE_VALID -> True, // BYPASSABLE_EXECUTE_STAGE -> False, // BYPASSABLE_MEMORY_STAGE -> False, - MEMORY_WR -> False - ) ++ (if(catchSomething) List(HAS_SIDE_EFFECT -> True) else Nil) + MEMORY_WR -> False, + HAS_SIDE_EFFECT -> True + ) ) if(withLrSc) decoderService.add(key, Seq(MEMORY_LRSC -> False)) @@ -103,8 +104,9 @@ class DBusCachedPlugin(val config : DataCacheConfig, IntAluPlugin.ALU_CTRL -> IntAluPlugin.AluCtrlEnum.ADD_SUB, SRC2_CTRL -> Src2CtrlEnum.IMS, // RS2_USE -> True, - MEMORY_WR -> True - ) ++ (if(catchSomething) List(HAS_SIDE_EFFECT -> True) else Nil) + MEMORY_WR -> True, + HAS_SIDE_EFFECT -> True + ) ) if(withLrSc) decoderService.add(key, Seq(MEMORY_LRSC -> False)) @@ -156,13 +158,15 @@ class DBusCachedPlugin(val config : DataCacheConfig, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_MEMORY_STAGE -> False, - MEMORY_WR -> False - ) ++ (if(catchSomething) List(HAS_SIDE_EFFECT -> True) else Nil) + MEMORY_WR -> False, + HAS_SIDE_EFFECT -> True + ) val storeActions = stdActions ++ List( SRC2_CTRL -> Src2CtrlEnum.IMS, RS2_USE -> True, - MEMORY_WR -> True + MEMORY_WR -> True, + HAS_SIDE_EFFECT -> True ) decoderService.addDefault(MEMORY_ENABLE, False) diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 1fe09ed..ac22dc4 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -327,13 +327,15 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_MEMORY_STAGE -> Bool(earlyInjection), - MEMORY_STORE -> False - ) ++ (if(catchAccessFault || catchAddressMisaligned) List(HAS_SIDE_EFFECT -> True) else Nil) + MEMORY_STORE -> False, + HAS_SIDE_EFFECT -> True + ) val storeActions = stdActions ++ List( SRC2_CTRL -> Src2CtrlEnum.IMS, RS2_USE -> True, - MEMORY_STORE -> True + MEMORY_STORE -> True, + HAS_SIDE_EFFECT -> True ) decoderService.addDefault(MEMORY_ENABLE, False)