Add dummy decoding, exception code/tval
Add Cpu generation code Add support for always ready rsp
This commit is contained in:
parent
5ac443b745
commit
d94cee13f0
|
@ -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())
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
package vexriscv.plugin
|
||||
|
||||
import vexriscv.{DecoderService, Stageable, VexRiscv}
|
||||
import vexriscv.{DecoderService, ExceptionCause, ExceptionService, Stage, Stageable, VexRiscv}
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
case class CfuParameter(stageCount : Int,
|
||||
allowZeroLatency : Boolean,
|
||||
dropWidth : Int,
|
||||
CFU_VERSION : Int,
|
||||
CFU_INTERFACE_ID_W : Int,
|
||||
CFU_FUNCTION_ID_W : Int,
|
||||
|
@ -16,8 +15,8 @@ case class CfuParameter(stageCount : Int,
|
|||
CFU_INPUT_DATA_W : Int,
|
||||
CFU_OUTPUTS : Int,
|
||||
CFU_OUTPUT_DATA_W : Int,
|
||||
CFU_FLOW_REQ_READY_ALWAYS : Int,
|
||||
CFU_FLOW_RESP_READY_ALWAYS : Int)
|
||||
CFU_FLOW_REQ_READY_ALWAYS : Boolean,
|
||||
CFU_FLOW_RESP_READY_ALWAYS : Boolean)
|
||||
|
||||
case class CfuCmd(p : CfuParameter) extends Bundle{
|
||||
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{
|
||||
val interface_id = UInt(p.CFU_INTERFACE_ID_W bits)
|
||||
val cmd = Stream(CfuCmd(p))
|
||||
val rsp = Stream(CfuRsp(p))
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(interface_id)
|
||||
master(cmd)
|
||||
slave(rsp)
|
||||
}
|
||||
|
@ -47,39 +44,46 @@ case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{
|
|||
class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||
assert(p.CFU_INPUTS <= 2)
|
||||
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 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_FUNCTION extends Stageable(UInt(p.CFU_FUNCTION_ID_W bits))
|
||||
object CFU_IN_FLIGHT extends Stageable(Bool())
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
bus = CfuBus(p)
|
||||
bus = master(CfuBus(p))
|
||||
joinException = pipeline.service(classOf[ExceptionService]).newExceptionPort(joinStage)
|
||||
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
|
||||
//custom-0
|
||||
decoderService.add(List(
|
||||
M"000000-----------000-----0010011" -> List(
|
||||
M"000000-----------000-----0001011" -> List(
|
||||
CFU_ENABLE -> True,
|
||||
CFU_FUNCTION -> U"00",
|
||||
REGFILE_WRITE_VALID -> ???,
|
||||
BYPASSABLE_EXECUTE_STAGE -> ???,
|
||||
BYPASSABLE_MEMORY_STAGE -> ???,
|
||||
RS1_USE -> ???,
|
||||
RS2_USE -> ???
|
||||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> Bool(p.stageCount == 0),
|
||||
BYPASSABLE_MEMORY_STAGE -> Bool(p.stageCount <= 1),
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
),
|
||||
M"000000-----------001-----0010011" -> List(
|
||||
M"000000-----------001-----0001011" -> List(
|
||||
CFU_ENABLE -> True,
|
||||
CFU_FUNCTION -> U"01",
|
||||
REGFILE_WRITE_VALID -> ???,
|
||||
BYPASSABLE_EXECUTE_STAGE -> ???,
|
||||
BYPASSABLE_MEMORY_STAGE -> ???,
|
||||
RS1_USE -> ???,
|
||||
RS2_USE -> ???
|
||||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> Bool(p.stageCount == 0),
|
||||
BYPASSABLE_MEMORY_STAGE -> Bool(p.stageCount <= 1),
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
)
|
||||
))
|
||||
}
|
||||
|
@ -88,10 +92,6 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
|||
import pipeline._
|
||||
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{
|
||||
import forkStage._
|
||||
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
|
||||
//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)){
|
||||
arbitration.haltItself setWhen(!rsp.valid)
|
||||
rsp.ready := arbitration.isStuckByOthers
|
||||
output(REGFILE_WRITE_DATA) := rsp.outputs(0)
|
||||
|
||||
when(arbitration.isValid){
|
||||
joinException.valid := !rsp.response_ok
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue