Add dummy decoding, exception code/tval

Add Cpu generation code
Add support for always ready rsp
This commit is contained in:
Charles Papon 2019-09-05 19:06:28 +02:00
parent 5ac443b745
commit d94cee13f0
2 changed files with 119 additions and 26 deletions

View File

@ -0,0 +1,76 @@
package vexriscv.demo
import spinal.core._
import vexriscv.plugin._
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
/**
* Created by spinalvm on 15.06.17.
*/
object GenSmallAndProductiveCfu extends App{
def cpu() = new VexRiscv(
config = VexRiscvConfig(
plugins = List(
new IBusSimplePlugin(
resetVector = 0x80000000l,
cmdForkOnSecondStage = false,
cmdForkPersistence = false,
prediction = NONE,
catchAccessFault = false,
compressedGen = false
),
new DBusSimplePlugin(
catchAddressMisaligned = false,
catchAccessFault = false
),
new CsrPlugin(CsrPluginConfig.smallest),
new DecoderSimplePlugin(
catchIllegalInstruction = false
),
new RegFilePlugin(
regFileReadyKind = plugin.SYNC,
zeroBoot = false
),
new IntAluPlugin,
new SrcPlugin(
separatedAddSub = false,
executeInsertion = true
),
new LightShifterPlugin,
new HazardSimplePlugin(
bypassExecute = true,
bypassMemory = true,
bypassWriteBack = true,
bypassWriteBackBuffer = true,
pessimisticUseSrc = false,
pessimisticWriteRegFile = false,
pessimisticAddressMatch = false
),
new BranchPlugin(
earlyBranch = false,
catchAddressMisaligned = false
),
new CfuPlugin(
p = CfuParameter(
stageCount = 1,
allowZeroLatency = true,
CFU_VERSION = 0,
CFU_INTERFACE_ID_W = 0,
CFU_FUNCTION_ID_W = 2,
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
)
),
new YamlPlugin("cpu0.yaml")
)
)
)
SpinalVerilog(cpu())
}

View File

@ -1,12 +1,11 @@
package vexriscv.plugin package vexriscv.plugin
import vexriscv.{DecoderService, Stageable, VexRiscv} import vexriscv.{DecoderService, ExceptionCause, ExceptionService, Stage, Stageable, VexRiscv}
import spinal.core._ import spinal.core._
import spinal.lib._ import spinal.lib._
case class CfuParameter(stageCount : Int, case class CfuParameter(stageCount : Int,
allowZeroLatency : Boolean, allowZeroLatency : Boolean,
dropWidth : Int,
CFU_VERSION : Int, CFU_VERSION : Int,
CFU_INTERFACE_ID_W : Int, CFU_INTERFACE_ID_W : Int,
CFU_FUNCTION_ID_W : Int, CFU_FUNCTION_ID_W : Int,
@ -16,8 +15,8 @@ case class CfuParameter(stageCount : Int,
CFU_INPUT_DATA_W : Int, CFU_INPUT_DATA_W : Int,
CFU_OUTPUTS : Int, CFU_OUTPUTS : Int,
CFU_OUTPUT_DATA_W : Int, CFU_OUTPUT_DATA_W : Int,
CFU_FLOW_REQ_READY_ALWAYS : Int, CFU_FLOW_REQ_READY_ALWAYS : Boolean,
CFU_FLOW_RESP_READY_ALWAYS : Int) CFU_FLOW_RESP_READY_ALWAYS : Boolean)
case class CfuCmd(p : CfuParameter) extends Bundle{ case class CfuCmd(p : CfuParameter) extends Bundle{
val function_id = UInt(p.CFU_FUNCTION_ID_W bits) val function_id = UInt(p.CFU_FUNCTION_ID_W bits)
@ -33,12 +32,10 @@ case class CfuRsp(p : CfuParameter) extends Bundle{
} }
case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{ case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{
val interface_id = UInt(p.CFU_INTERFACE_ID_W bits)
val cmd = Stream(CfuCmd(p)) val cmd = Stream(CfuCmd(p))
val rsp = Stream(CfuRsp(p)) val rsp = Stream(CfuRsp(p))
override def asMaster(): Unit = { override def asMaster(): Unit = {
out(interface_id)
master(cmd) master(cmd)
slave(rsp) slave(rsp)
} }
@ -47,39 +44,46 @@ case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{
class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
assert(p.CFU_INPUTS <= 2) assert(p.CFU_INPUTS <= 2)
assert(p.CFU_OUTPUTS == 1) assert(p.CFU_OUTPUTS == 1)
assert(p.CFU_FLOW_REQ_READY_ALWAYS == false)
assert(p.CFU_FLOW_RESP_READY_ALWAYS == false)
var bus : CfuBus = null 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) + p.stageCount - 1))
object CFU_ENABLE extends Stageable(Bool()) object CFU_ENABLE extends Stageable(Bool())
object CFU_FUNCTION extends Stageable(UInt(p.CFU_FUNCTION_ID_W bits)) object CFU_FUNCTION extends Stageable(UInt(p.CFU_FUNCTION_ID_W bits))
object CFU_IN_FLIGHT extends Stageable(Bool()) object CFU_IN_FLIGHT extends Stageable(Bool())
override def setup(pipeline: VexRiscv): Unit = { override def setup(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._ import pipeline.config._
bus = CfuBus(p) bus = master(CfuBus(p))
joinException = pipeline.service(classOf[ExceptionService]).newExceptionPort(joinStage)
val decoderService = pipeline.service(classOf[DecoderService]) val decoderService = pipeline.service(classOf[DecoderService])
//custom-0
decoderService.add(List( decoderService.add(List(
M"000000-----------000-----0010011" -> List( M"000000-----------000-----0001011" -> List(
CFU_ENABLE -> True, CFU_ENABLE -> True,
CFU_FUNCTION -> U"00", CFU_FUNCTION -> U"00",
REGFILE_WRITE_VALID -> ???, REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> ???, BYPASSABLE_EXECUTE_STAGE -> Bool(p.stageCount == 0),
BYPASSABLE_MEMORY_STAGE -> ???, BYPASSABLE_MEMORY_STAGE -> Bool(p.stageCount <= 1),
RS1_USE -> ???, RS1_USE -> True,
RS2_USE -> ??? RS2_USE -> True
), ),
M"000000-----------001-----0010011" -> List( M"000000-----------001-----0001011" -> List(
CFU_ENABLE -> True, CFU_ENABLE -> True,
CFU_FUNCTION -> U"01", CFU_FUNCTION -> U"01",
REGFILE_WRITE_VALID -> ???, REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> ???, BYPASSABLE_EXECUTE_STAGE -> Bool(p.stageCount == 0),
BYPASSABLE_MEMORY_STAGE -> ???, BYPASSABLE_MEMORY_STAGE -> Bool(p.stageCount <= 1),
RS1_USE -> ???, RS1_USE -> True,
RS2_USE -> ??? RS2_USE -> True
) )
)) ))
} }
@ -88,10 +92,6 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
import pipeline._ import pipeline._
import pipeline.config._ import pipeline.config._
val forkStage = execute
val joinStageId = Math.min(stages.length - 1, pipeline.indexOf(execute) + p.stageCount - 1)
val joinStage = stages(joinStageId)
forkStage plug new Area{ forkStage plug new Area{
import forkStage._ import forkStage._
val schedule = arbitration.isValid && input(CFU_ENABLE) val schedule = arbitration.isValid && input(CFU_ENABLE)
@ -114,13 +114,30 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
//If the CFU interface can produce a result combinatorialy and the fork stage isn't the same than the join stage //If the CFU interface can produce a result combinatorialy and the fork stage isn't the same than the join stage
//Then it is required to add a buffer on rsp to not propagate the fork stage ready := False in the CPU pipeline. //Then it is required to add a buffer on rsp to not propagate the fork stage ready := False in the CPU pipeline.
val rsp = if(forkStage != joinStage && p.allowZeroLatency) bus.rsp.m2sPipe() else bus.rsp val rsp = if(p.CFU_FLOW_RESP_READY_ALWAYS){
bus.rsp.toFlow.toStream.queueLowLatency(
size = p.stageCount + 1,
latency = 0
)
} else if(forkStage != joinStage && p.allowZeroLatency) {
bus.rsp.m2sPipe()
} else {
bus.rsp.combStage()
}
joinException.valid := False
joinException.code := 15
joinException.badAddr := 0
rsp.ready := False
when(input(CFU_IN_FLIGHT)){ when(input(CFU_IN_FLIGHT)){
arbitration.haltItself setWhen(!rsp.valid) arbitration.haltItself setWhen(!rsp.valid)
rsp.ready := arbitration.isStuckByOthers rsp.ready := arbitration.isStuckByOthers
output(REGFILE_WRITE_DATA) := rsp.outputs(0) output(REGFILE_WRITE_DATA) := rsp.outputs(0)
when(arbitration.isValid){
joinException.valid := !rsp.response_ok
}
} }
} }
} }