aboutsummaryrefslogtreecommitdiff
path: root/VexRiscv/src/main/scala/vexriscv/VexRiscv.scala
diff options
context:
space:
mode:
Diffstat (limited to 'VexRiscv/src/main/scala/vexriscv/VexRiscv.scala')
-rw-r--r--VexRiscv/src/main/scala/vexriscv/VexRiscv.scala152
1 files changed, 152 insertions, 0 deletions
diff --git a/VexRiscv/src/main/scala/vexriscv/VexRiscv.scala b/VexRiscv/src/main/scala/vexriscv/VexRiscv.scala
new file mode 100644
index 0000000..ed7e37e
--- /dev/null
+++ b/VexRiscv/src/main/scala/vexriscv/VexRiscv.scala
@@ -0,0 +1,152 @@
+package vexriscv
+
+import vexriscv.plugin._
+import spinal.core._
+
+import scala.collection.mutable.ArrayBuffer
+import scala.collection.Seq
+
+object VexRiscvConfig{
+ def apply(withMemoryStage : Boolean, withWriteBackStage : Boolean, plugins : Seq[Plugin[VexRiscv]]): VexRiscvConfig = {
+ val config = VexRiscvConfig()
+ config.plugins ++= plugins
+ config.withMemoryStage = withMemoryStage
+ config.withWriteBackStage = withWriteBackStage
+ config
+ }
+
+ def apply(plugins : Seq[Plugin[VexRiscv]] = ArrayBuffer()) : VexRiscvConfig = apply(true,true,plugins)
+}
+trait VexRiscvRegressionArg{
+ def getVexRiscvRegressionArgs() : Seq[String]
+}
+case class VexRiscvConfig(){
+ var withMemoryStage = true
+ var withWriteBackStage = true
+ val plugins = ArrayBuffer[Plugin[VexRiscv]]()
+
+ def add(that : Plugin[VexRiscv]) : this.type = {plugins += that;this}
+ def find[T](clazz: Class[T]): Option[T] = {
+ plugins.find(_.getClass == clazz) match {
+ case Some(x) => Some(x.asInstanceOf[T])
+ case None => None
+ }
+ }
+ def get[T](clazz: Class[T]): T = {
+ plugins.find(_.getClass == clazz) match {
+ case Some(x) => x.asInstanceOf[T]
+ }
+ }
+
+ def withRvc = plugins.find(_.isInstanceOf[IBusFetcher]) match {
+ case Some(x) => x.asInstanceOf[IBusFetcher].withRvc
+ case None => false
+ }
+
+ def withRvf = find(classOf[FpuPlugin]) match {
+ case Some(x) => true
+ case None => false
+ }
+
+ def withRvd = find(classOf[FpuPlugin]) match {
+ case Some(x) => x.p.withDouble
+ case None => false
+ }
+
+ //Default Stageables
+ object IS_RVC extends Stageable(Bool)
+ object BYPASSABLE_EXECUTE_STAGE extends Stageable(Bool)
+ object BYPASSABLE_MEMORY_STAGE extends Stageable(Bool)
+ object RS1 extends Stageable(Bits(32 bits))
+ object RS2 extends Stageable(Bits(32 bits))
+ object RS1_USE extends Stageable(Bool)
+ object RS2_USE extends Stageable(Bool)
+ object RESULT extends Stageable(UInt(32 bits))
+ object PC extends Stageable(UInt(32 bits))
+ object PC_CALC_WITHOUT_JUMP extends Stageable(UInt(32 bits))
+ object INSTRUCTION extends Stageable(Bits(32 bits))
+ object INSTRUCTION_ANTICIPATED extends Stageable(Bits(32 bits))
+ object LEGAL_INSTRUCTION extends Stageable(Bool)
+ object REGFILE_WRITE_VALID extends Stageable(Bool)
+ object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
+
+ object MPP extends PipelineThing[UInt]
+ object DEBUG_BYPASS_CACHE extends PipelineThing[Bool]
+
+ object SRC1 extends Stageable(Bits(32 bits))
+ object SRC2 extends Stageable(Bits(32 bits))
+ object SRC_ADD_SUB extends Stageable(Bits(32 bits))
+ object SRC_ADD extends Stageable(Bits(32 bits))
+ object SRC_SUB extends Stageable(Bits(32 bits))
+ object SRC_LESS extends Stageable(Bool)
+ object SRC_USE_SUB_LESS extends Stageable(Bool)
+ object SRC_LESS_UNSIGNED extends Stageable(Bool)
+ object SRC_ADD_ZERO extends Stageable(Bool)
+
+
+ object HAS_SIDE_EFFECT extends Stageable(Bool)
+
+ //Formal verification purposes
+ object FORMAL_HALT extends Stageable(Bool)
+ object FORMAL_PC_NEXT extends Stageable(UInt(32 bits))
+ object FORMAL_MEM_ADDR extends Stageable(UInt(32 bits))
+ object FORMAL_MEM_RMASK extends Stageable(Bits(4 bits))
+ object FORMAL_MEM_WMASK extends Stageable(Bits(4 bits))
+ object FORMAL_MEM_RDATA extends Stageable(Bits(32 bits))
+ object FORMAL_MEM_WDATA extends Stageable(Bits(32 bits))
+ object FORMAL_INSTRUCTION extends Stageable(Bits(32 bits))
+
+
+ object Src1CtrlEnum extends SpinalEnum(binarySequential){
+ val RS, IMU, PC_INCREMENT, URS1 = newElement() //IMU, IMZ IMJB
+ }
+
+ object Src2CtrlEnum extends SpinalEnum(binarySequential){
+ val RS, IMI, IMS, PC = newElement() //TODO remplacing ZERO could avoid 32 muxes if SRC_ADD can be disabled
+ }
+ object SRC1_CTRL extends Stageable(Src1CtrlEnum())
+ object SRC2_CTRL extends Stageable(Src2CtrlEnum())
+
+ def getRegressionArgs() : Seq[String] = {
+ val str = ArrayBuffer[String]()
+ plugins.foreach{
+ case e : VexRiscvRegressionArg => str ++= e.getVexRiscvRegressionArgs()
+ case _ =>
+ }
+ str
+ }
+}
+
+
+
+
+class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
+ type T = VexRiscv
+ import config._
+
+ //Define stages
+ def newStage(): Stage = { val s = new Stage; stages += s; s }
+ val decode = newStage()
+ val execute = newStage()
+ val memory = ifGen(config.withMemoryStage) (newStage())
+ val writeBack = ifGen(config.withWriteBackStage) (newStage())
+
+ def stagesFromExecute = stages.dropWhile(_ != execute)
+
+ plugins ++= config.plugins
+
+ //regression usage
+ 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
+ if(withMemoryStage){
+ memory.arbitration.removeIt.noBackendCombMerge
+ }
+ execute.arbitration.flushNext.noBackendCombMerge
+}
+
+