CfuPlugin encoding can now specify cmd/rsp less instruction
This commit is contained in:
parent
3cf8508db1
commit
f11c642cd6
|
@ -1,6 +1,6 @@
|
||||||
package vexriscv.plugin
|
package vexriscv.plugin
|
||||||
|
|
||||||
import vexriscv.{DecoderService, ExceptionCause, ExceptionService, Stage, Stageable, VexRiscv}
|
import vexriscv.{DecoderService, ExceptionCause, ExceptionService, JumpService, Stage, Stageable, VexRiscv}
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
import spinal.lib.bus.bmb.WeakConnector
|
import spinal.lib.bus.bmb.WeakConnector
|
||||||
|
@ -92,7 +92,9 @@ object CfuPlugin{
|
||||||
|
|
||||||
case class CfuPluginEncoding(instruction : MaskedLiteral,
|
case class CfuPluginEncoding(instruction : MaskedLiteral,
|
||||||
functionId : List[Range],
|
functionId : List[Range],
|
||||||
input2Kind : CfuPlugin.Input2Kind.E){
|
input2Kind : CfuPlugin.Input2Kind.E,
|
||||||
|
withCmd : Boolean = true,
|
||||||
|
withRsp : Boolean = true){
|
||||||
val functionIdWidth = functionId.map(_.size).sum
|
val functionIdWidth = functionId.map(_.size).sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +112,7 @@ class CfuPlugin(val stageCount : Int,
|
||||||
// assert(p.CFU_FUNCTION_ID_W == 3)
|
// assert(p.CFU_FUNCTION_ID_W == 3)
|
||||||
|
|
||||||
var bus : CfuBus = null
|
var bus : CfuBus = null
|
||||||
|
// var redoInterface : Flow[UInt] = 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) + stageCount))
|
lazy val joinStage = pipeline.stages(Math.min(pipeline.stages.length - 1, pipeline.indexOf(forkStage) + stageCount))
|
||||||
|
@ -119,31 +122,45 @@ class CfuPlugin(val stageCount : Int,
|
||||||
val CFU_IN_FLIGHT = new Stageable(Bool()).setCompositeName(this, "CFU_IN_FLIGHT")
|
val CFU_IN_FLIGHT = new Stageable(Bool()).setCompositeName(this, "CFU_IN_FLIGHT")
|
||||||
val CFU_ENCODING = new Stageable(UInt(log2Up(encodings.size) bits)).setCompositeName(this, "CFU_ENCODING")
|
val CFU_ENCODING = new Stageable(UInt(log2Up(encodings.size) bits)).setCompositeName(this, "CFU_ENCODING")
|
||||||
val CFU_INPUT_2_KIND = new Stageable(CfuPlugin.Input2Kind()).setCompositeName(this, "CFU_INPUT_2_KIND")
|
val CFU_INPUT_2_KIND = new Stageable(CfuPlugin.Input2Kind()).setCompositeName(this, "CFU_INPUT_2_KIND")
|
||||||
|
val CFU_WITH_CMD = new Stageable(Bool()).setCompositeName(this, "CFU_WITH_CMD")
|
||||||
|
val CFU_WITH_RSP = new Stageable(Bool()).setCompositeName(this, "CFU_WITH_RSP")
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
import pipeline._
|
import pipeline._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
|
// val pcManagerService = pipeline.service(classOf[JumpService])
|
||||||
|
// if(encodings.contains(_.cmd)redoInterface = pcManagerService.createJumpInterface(pipeline.writeBack)
|
||||||
|
|
||||||
bus = master(CfuBus(p))
|
bus = master(CfuBus(p))
|
||||||
|
|
||||||
val decoderService = pipeline.service(classOf[DecoderService])
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
decoderService.addDefault(CFU_ENABLE, False)
|
decoderService.addDefault(CFU_ENABLE, False)
|
||||||
|
decoderService.addDefault(CFU_WITH_CMD, False)
|
||||||
|
decoderService.addDefault(CFU_WITH_RSP, False)
|
||||||
|
|
||||||
for((encoding, id) <- encodings.zipWithIndex){
|
for((encoding, id) <- encodings.zipWithIndex){
|
||||||
var actions = List(
|
var actions : List[(Stageable[_ <: BaseType], Any)] = List(
|
||||||
CFU_ENABLE -> True,
|
CFU_ENABLE -> True,
|
||||||
REGFILE_WRITE_VALID -> True,
|
|
||||||
BYPASSABLE_EXECUTE_STAGE -> Bool(stageCount == 0),
|
|
||||||
BYPASSABLE_MEMORY_STAGE -> Bool(stageCount <= 1),
|
|
||||||
RS1_USE -> True,
|
|
||||||
CFU_ENCODING -> U(id),
|
CFU_ENCODING -> U(id),
|
||||||
CFU_INPUT_2_KIND -> encoding.input2Kind()
|
CFU_WITH_CMD -> Bool(encoding.withCmd),
|
||||||
|
CFU_WITH_RSP -> Bool(encoding.withRsp)
|
||||||
)
|
)
|
||||||
|
|
||||||
encoding.input2Kind match {
|
if(encoding.withCmd){
|
||||||
case CfuPlugin.Input2Kind.RS =>
|
actions :+= RS1_USE -> True
|
||||||
actions :+= RS2_USE -> True
|
actions :+= CFU_INPUT_2_KIND -> encoding.input2Kind()
|
||||||
case CfuPlugin.Input2Kind.IMM_I =>
|
encoding.input2Kind match {
|
||||||
|
case CfuPlugin.Input2Kind.RS =>
|
||||||
|
actions :+= RS2_USE -> True
|
||||||
|
case CfuPlugin.Input2Kind.IMM_I =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(encoding.withRsp){
|
||||||
|
actions :+= REGFILE_WRITE_VALID -> True
|
||||||
|
actions :+= BYPASSABLE_EXECUTE_STAGE -> Bool(stageCount == 0)
|
||||||
|
actions :+= BYPASSABLE_MEMORY_STAGE -> Bool(stageCount <= 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
decoderService.add(
|
decoderService.add(
|
||||||
|
@ -190,7 +207,7 @@ class CfuPlugin(val stageCount : Int,
|
||||||
import forkStage._
|
import forkStage._
|
||||||
input(CFU_ENABLE).clearWhen(!input(LEGAL_INSTRUCTION))
|
input(CFU_ENABLE).clearWhen(!input(LEGAL_INSTRUCTION))
|
||||||
val hazard = stages.dropWhile(_ != forkStage).tail.map(s => s.arbitration.isValid && s.input(HAS_SIDE_EFFECT)).orR
|
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 scheduleWish = arbitration.isValid && input(CFU_ENABLE) && input(CFU_WITH_CMD)
|
||||||
val schedule = scheduleWish && !hazard
|
val schedule = scheduleWish && !hazard
|
||||||
arbitration.haltItself setWhen(scheduleWish && hazard)
|
arbitration.haltItself setWhen(scheduleWish && hazard)
|
||||||
|
|
||||||
|
@ -233,12 +250,13 @@ class CfuPlugin(val stageCount : Int,
|
||||||
bus.rsp.combStage()
|
bus.rsp.combStage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val hazard = stages.dropWhile(_ != joinStage).tail.map(s => s.arbitration.isValid && s.input(HAS_SIDE_EFFECT)).orR
|
||||||
rsp.ready := False
|
rsp.ready := False
|
||||||
when(input(CFU_IN_FLIGHT)){
|
when((arbitration.isValid || input(CFU_IN_FLIGHT)) && input(CFU_WITH_RSP)){
|
||||||
arbitration.haltItself setWhen(!rsp.valid)
|
arbitration.haltItself setWhen(!rsp.valid || hazard)
|
||||||
rsp.ready := !arbitration.isStuckByOthers
|
rsp.ready := !arbitration.isStuckByOthers && !hazard
|
||||||
output(REGFILE_WRITE_DATA) := rsp.outputs(0)
|
output(REGFILE_WRITE_DATA) := rsp.outputs(0)
|
||||||
if(p.CFU_WITH_STATUS) when(arbitration.isFiring){
|
if(p.CFU_WITH_STATUS) when(rsp.fire){
|
||||||
switch(rsp.status) {
|
switch(rsp.status) {
|
||||||
for (i <- 1 to 6) is(i) {
|
for (i <- 1 to 6) is(i) {
|
||||||
csr.status.flags(i-1) := True
|
csr.status.flags(i-1) := True
|
||||||
|
|
Loading…
Reference in New Issue