Sync CFU progress
This commit is contained in:
parent
7ae218704e
commit
744b040c70
|
@ -51,9 +51,10 @@ object GenSmallAndProductiveCfu extends App{
|
||||||
catchAddressMisaligned = false
|
catchAddressMisaligned = false
|
||||||
),
|
),
|
||||||
new CfuPlugin(
|
new CfuPlugin(
|
||||||
p = CfuParameter(
|
stageCount = 1,
|
||||||
stageCount = 1,
|
allowZeroLatency = true,
|
||||||
allowZeroLatency = true,
|
encoding = M"000000-------------------0001011",
|
||||||
|
busParameter = CfuBusParameter(
|
||||||
CFU_VERSION = 0,
|
CFU_VERSION = 0,
|
||||||
CFU_INTERFACE_ID_W = 0,
|
CFU_INTERFACE_ID_W = 0,
|
||||||
CFU_FUNCTION_ID_W = 2,
|
CFU_FUNCTION_ID_W = 2,
|
||||||
|
|
|
@ -6,8 +6,7 @@ import spinal.lib._
|
||||||
import spinal.lib.bus.bmb.WeakConnector
|
import spinal.lib.bus.bmb.WeakConnector
|
||||||
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping}
|
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping}
|
||||||
|
|
||||||
case class CfuParameter(stageCount : Int,
|
case class CfuPluginParameter(
|
||||||
allowZeroLatency : Boolean,
|
|
||||||
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,
|
||||||
|
@ -20,7 +19,19 @@ case class CfuParameter(stageCount : Int,
|
||||||
CFU_FLOW_REQ_READY_ALWAYS : Boolean,
|
CFU_FLOW_REQ_READY_ALWAYS : Boolean,
|
||||||
CFU_FLOW_RESP_READY_ALWAYS : Boolean)
|
CFU_FLOW_RESP_READY_ALWAYS : Boolean)
|
||||||
|
|
||||||
case class CfuCmd(p : CfuParameter) extends Bundle{
|
case class CfuBusParameter(CFU_VERSION : Int,
|
||||||
|
CFU_INTERFACE_ID_W : Int,
|
||||||
|
CFU_FUNCTION_ID_W : Int,
|
||||||
|
CFU_REORDER_ID_W : Int,
|
||||||
|
CFU_REQ_RESP_ID_W : Int,
|
||||||
|
CFU_INPUTS : Int,
|
||||||
|
CFU_INPUT_DATA_W : Int,
|
||||||
|
CFU_OUTPUTS : Int,
|
||||||
|
CFU_OUTPUT_DATA_W : Int,
|
||||||
|
CFU_FLOW_REQ_READY_ALWAYS : Boolean,
|
||||||
|
CFU_FLOW_RESP_READY_ALWAYS : Boolean)
|
||||||
|
|
||||||
|
case class CfuCmd( p : CfuBusParameter ) extends Bundle{
|
||||||
val function_id = UInt(p.CFU_FUNCTION_ID_W bits)
|
val function_id = UInt(p.CFU_FUNCTION_ID_W bits)
|
||||||
val reorder_id = UInt(p.CFU_REORDER_ID_W bits)
|
val reorder_id = UInt(p.CFU_REORDER_ID_W bits)
|
||||||
val request_id = UInt(p.CFU_REQ_RESP_ID_W bits)
|
val request_id = UInt(p.CFU_REQ_RESP_ID_W bits)
|
||||||
|
@ -35,7 +46,7 @@ case class CfuCmd(p : CfuParameter) extends Bundle{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case class CfuRsp(p : CfuParameter) extends Bundle{
|
case class CfuRsp(p : CfuBusParameter) extends Bundle{
|
||||||
val response_ok = Bool()
|
val response_ok = Bool()
|
||||||
val response_id = UInt(p.CFU_REQ_RESP_ID_W bits)
|
val response_id = UInt(p.CFU_REQ_RESP_ID_W bits)
|
||||||
val outputs = Vec(Bits(p.CFU_OUTPUT_DATA_W bits), p.CFU_OUTPUTS)
|
val outputs = Vec(Bits(p.CFU_OUTPUT_DATA_W bits), p.CFU_OUTPUTS)
|
||||||
|
@ -48,7 +59,7 @@ case class CfuRsp(p : CfuParameter) extends Bundle{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{
|
case class CfuBus(p : CfuBusParameter) extends Bundle with IMasterSlave{
|
||||||
val cmd = Stream(CfuCmd(p))
|
val cmd = Stream(CfuCmd(p))
|
||||||
val rsp = Stream(CfuRsp(p))
|
val rsp = Stream(CfuRsp(p))
|
||||||
|
|
||||||
|
@ -69,7 +80,12 @@ case class CfuBus(p : CfuParameter) extends Bundle with IMasterSlave{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
class CfuPlugin( val stageCount : Int,
|
||||||
|
val allowZeroLatency : Boolean,
|
||||||
|
val encoding : MaskedLiteral,
|
||||||
|
val busParameter : CfuBusParameter) extends Plugin[VexRiscv]{
|
||||||
|
def p = busParameter
|
||||||
|
|
||||||
assert(p.CFU_INPUTS <= 2)
|
assert(p.CFU_INPUTS <= 2)
|
||||||
assert(p.CFU_OUTPUTS == 1)
|
assert(p.CFU_OUTPUTS == 1)
|
||||||
assert(p.CFU_FUNCTION_ID_W == 3)
|
assert(p.CFU_FUNCTION_ID_W == 3)
|
||||||
|
@ -78,11 +94,12 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
var joinException : Flow[ExceptionCause] = null
|
var joinException : Flow[ExceptionCause] = null
|
||||||
|
|
||||||
lazy val forkStage = pipeline.execute
|
lazy val forkStage = pipeline.execute
|
||||||
lazy val joinStage = pipeline.stages(Math.min(pipeline.stages.length - 1, pipeline.indexOf(forkStage) + p.stageCount))
|
lazy val joinStage = pipeline.stages(Math.min(pipeline.stages.length - 1, pipeline.indexOf(forkStage) + stageCount))
|
||||||
|
|
||||||
|
|
||||||
object CFU_ENABLE extends Stageable(Bool())
|
val CFU_ENABLE = new Stageable(Bool()).setCompositeName(this, "CFU_ENABLE")
|
||||||
object CFU_IN_FLIGHT extends Stageable(Bool())
|
val CFU_IN_FLIGHT = new Stageable(Bool()).setCompositeName(this, "CFU_IN_FLIGHT")
|
||||||
|
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
import pipeline._
|
import pipeline._
|
||||||
|
@ -96,11 +113,11 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
|
|
||||||
//custom-0
|
//custom-0
|
||||||
decoderService.add(List(
|
decoderService.add(List(
|
||||||
M"000000-------------------0001011" -> List(
|
encoding -> List(
|
||||||
CFU_ENABLE -> True,
|
CFU_ENABLE -> True,
|
||||||
REGFILE_WRITE_VALID -> True,
|
REGFILE_WRITE_VALID -> True,
|
||||||
BYPASSABLE_EXECUTE_STAGE -> Bool(p.stageCount == 0),
|
BYPASSABLE_EXECUTE_STAGE -> Bool(stageCount == 0),
|
||||||
BYPASSABLE_MEMORY_STAGE -> Bool(p.stageCount <= 1),
|
BYPASSABLE_MEMORY_STAGE -> Bool(stageCount <= 1),
|
||||||
RS1_USE -> True,
|
RS1_USE -> True,
|
||||||
RS2_USE -> True
|
RS2_USE -> True
|
||||||
)
|
)
|
||||||
|
@ -111,6 +128,7 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
import pipeline._
|
import pipeline._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -121,7 +139,7 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
bus.cmd.valid := (schedule || hold) && !fired
|
bus.cmd.valid := (schedule || hold) && !fired
|
||||||
arbitration.haltItself setWhen(bus.cmd.valid && !bus.cmd.ready)
|
arbitration.haltItself setWhen(bus.cmd.valid && !bus.cmd.ready)
|
||||||
|
|
||||||
bus.cmd.function_id := U(input(INSTRUCTION)(14 downto 12))
|
bus.cmd.function_id := U(input(INSTRUCTION)(14 downto 12)).resized
|
||||||
bus.cmd.reorder_id := 0
|
bus.cmd.reorder_id := 0
|
||||||
bus.cmd.request_id := 0
|
bus.cmd.request_id := 0
|
||||||
if(p.CFU_INPUTS >= 1) bus.cmd.inputs(0) := input(RS1)
|
if(p.CFU_INPUTS >= 1) bus.cmd.inputs(0) := input(RS1)
|
||||||
|
@ -135,10 +153,10 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
//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(p.CFU_FLOW_RESP_READY_ALWAYS){
|
val rsp = if(p.CFU_FLOW_RESP_READY_ALWAYS){
|
||||||
bus.rsp.toFlow.toStream.queueLowLatency(
|
bus.rsp.toFlow.toStream.queueLowLatency(
|
||||||
size = p.stageCount + 1,
|
size = stageCount + 1,
|
||||||
latency = 0
|
latency = 0
|
||||||
)
|
)
|
||||||
} else if(forkStage != joinStage && p.allowZeroLatency) {
|
} else if(forkStage != joinStage && allowZeroLatency) {
|
||||||
bus.rsp.m2sPipe()
|
bus.rsp.m2sPipe()
|
||||||
} else {
|
} else {
|
||||||
bus.rsp.combStage()
|
bus.rsp.combStage()
|
||||||
|
@ -159,14 +177,17 @@ class CfuPlugin(val p: CfuParameter) extends Plugin[VexRiscv]{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPrePopTask(() => stages.dropWhile(_ != memory).reverse.dropWhile(_ != joinStage).foreach(s => s.input(CFU_IN_FLIGHT).init(False)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object CfuTest{
|
object CfuTest{
|
||||||
def getCfuParameter() = CfuParameter(
|
|
||||||
stageCount = 0,
|
// stageCount = 0,
|
||||||
allowZeroLatency = true,
|
// allowZeroLatency = true,
|
||||||
|
def getCfuParameter() = CfuBusParameter(
|
||||||
CFU_VERSION = 0,
|
CFU_VERSION = 0,
|
||||||
CFU_INTERFACE_ID_W = 0,
|
CFU_INTERFACE_ID_W = 0,
|
||||||
CFU_FUNCTION_ID_W = 3,
|
CFU_FUNCTION_ID_W = 3,
|
||||||
|
@ -190,7 +211,31 @@ case class CfuTest() extends Component{
|
||||||
io.bus.rsp.outputs(0) := ~(io.bus.cmd.inputs(0) & io.bus.cmd.inputs(1))
|
io.bus.rsp.outputs(0) := ~(io.bus.cmd.inputs(0) & io.bus.cmd.inputs(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class CfuDecoder(p : CfuParameter,
|
|
||||||
|
case class CfuBb(p : CfuBusParameter) extends BlackBox{
|
||||||
|
val io = new Bundle {
|
||||||
|
val clk, reset = in Bool()
|
||||||
|
val bus = slave(CfuBus(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
mapCurrentClockDomain(io.clk, io.reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
//case class CfuGray(p : CfuBusParameter) extends BlackBox{
|
||||||
|
// val req_function_id = in Bits(p.CFU_FUNCTION_ID_W)
|
||||||
|
// val req_data = in Bits(p.CFU_REQ_INPUTS)
|
||||||
|
// val resp_data = in Bits(p.CFU_FUNCTION_ID_W)
|
||||||
|
// input `CFU_FUNCTION_ID req_function_id,
|
||||||
|
// input [CFU_REQ_INPUTS-1:0]`CFU_REQ_DATA req_data,
|
||||||
|
// output [CFU_RESP_OUTPUTS-1:0]`CFU_RESP_DATA resp_data
|
||||||
|
// 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))
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
case class CfuDecoder(p : CfuBusParameter,
|
||||||
mappings : Seq[AddressMapping],
|
mappings : Seq[AddressMapping],
|
||||||
pendingMax : Int = 3) extends Component{
|
pendingMax : Int = 3) extends Component{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
|
|
Loading…
Reference in New Issue