Fetcher/IBusSimplePlugin wip
This commit is contained in:
parent
0ada869b2d
commit
c61f17aea3
|
@ -114,10 +114,22 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
//PC calculation without Jump
|
//PC calculation without Jump
|
||||||
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
|
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
|
||||||
val inc = RegInit(False)
|
val inc = RegInit(False)
|
||||||
|
val propagatePc = False
|
||||||
|
|
||||||
val pc = pcReg + (inc ## B"00").asUInt
|
val pc = pcReg + (inc ## B"00").asUInt
|
||||||
val samplePcNext = False
|
val samplePcNext = False
|
||||||
|
|
||||||
|
if(compressedGen) {
|
||||||
|
when(inc) {
|
||||||
|
pc(1) := False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(propagatePc){
|
||||||
|
samplePcNext := True
|
||||||
|
inc := False
|
||||||
|
}
|
||||||
|
|
||||||
if(predictionPcLoad != null) {
|
if(predictionPcLoad != null) {
|
||||||
when(predictionPcLoad.valid) {
|
when(predictionPcLoad.valid) {
|
||||||
inc := False
|
inc := False
|
||||||
|
@ -142,14 +154,6 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
pcReg := pc
|
pcReg := pc
|
||||||
}
|
}
|
||||||
|
|
||||||
if(compressedGen) {
|
|
||||||
when(preOutput.fire) {
|
|
||||||
pcReg(1 downto 0) := 0
|
|
||||||
when(pc(1)){
|
|
||||||
inc := True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
preOutput.valid := RegNext(True) init (False)
|
preOutput.valid := RegNext(True) init (False)
|
||||||
preOutput.payload := pc
|
preOutput.payload := pc
|
||||||
|
@ -217,7 +221,13 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
for((s,sNext) <- (stages, stages.tail).zipped) {
|
for((s,sNext) <- (stages, stages.tail).zipped) {
|
||||||
sNext.input << s.output.m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false)
|
if(s == stages.head) {
|
||||||
|
sNext.input.arbitrationFrom(s.output.toEvent().m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false))
|
||||||
|
sNext.input.payload := fetchPc.pcReg
|
||||||
|
fetchPc.propagatePc setWhen(sNext.input.fire)
|
||||||
|
} else {
|
||||||
|
sNext.input << s.output.m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -310,7 +320,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
}).tail
|
}).tail
|
||||||
}
|
}
|
||||||
|
|
||||||
val nextPcCalc = if (decodePcGen) {
|
val nextPcCalc = if (decodePcGen) new Area{
|
||||||
val valids = pcUpdatedGen(True, False :: List(execute, memory, writeBack).map(_.arbitration.isStuck), true)
|
val valids = pcUpdatedGen(True, False :: List(execute, memory, writeBack).map(_.arbitration.isStuck), true)
|
||||||
pcValids := Vec(valids.takeRight(4))
|
pcValids := Vec(valids.takeRight(4))
|
||||||
} else new Area{
|
} else new Area{
|
||||||
|
|
|
@ -151,8 +151,7 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
compressedGen : Boolean = false,
|
compressedGen : Boolean = false,
|
||||||
busLatencyMin : Int = 1,
|
busLatencyMin : Int = 1,
|
||||||
pendingMax : Int = 7,
|
pendingMax : Int = 7,
|
||||||
injectorStage : Boolean = true,
|
injectorStage : Boolean = true
|
||||||
relaxedBusCmdValid : Boolean = false
|
|
||||||
) extends IBusFetcherImpl(
|
) extends IBusFetcherImpl(
|
||||||
catchAccessFault = catchAccessFault,
|
catchAccessFault = catchAccessFault,
|
||||||
resetVector = resetVector,
|
resetVector = resetVector,
|
||||||
|
@ -164,8 +163,6 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
prediction = prediction,
|
prediction = prediction,
|
||||||
historyRamSizeLog2 = historyRamSizeLog2,
|
historyRamSizeLog2 = historyRamSizeLog2,
|
||||||
injectorStage = injectorStage){
|
injectorStage = injectorStage){
|
||||||
assert(!(prediction == DYNAMIC_TARGET && relaxedBusCmdValid), "IBusSimplePlugin doesn't allow dynamic_target prediction and relaxedBusCmdValid together")
|
|
||||||
assert(!relaxedBusCmdValid)
|
|
||||||
|
|
||||||
var iBus : IBusSimpleBus = null
|
var iBus : IBusSimpleBus = null
|
||||||
var decodeExceptionPort : Flow[ExceptionCause] = null
|
var decodeExceptionPort : Flow[ExceptionCause] = null
|
||||||
|
@ -185,44 +182,23 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
pipeline plug new FetchArea(pipeline) {
|
pipeline plug new FetchArea(pipeline) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Avoid sending to many iBus cmd
|
//Avoid sending to many iBus cmd
|
||||||
val pendingCmd = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
|
val pendingCmd = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
|
||||||
val pendingCmdNext = pendingCmd + iBus.cmd.fire.asUInt - iBus.rsp.fire.asUInt
|
val pendingCmdNext = pendingCmd + iBus.cmd.fire.asUInt - iBus.rsp.fire.asUInt
|
||||||
pendingCmd := pendingCmdNext
|
pendingCmd := pendingCmdNext
|
||||||
|
|
||||||
val cmd = if(relaxedBusCmdValid) new Area {
|
val cmd = /*if(relaxedPcCalculation) new Area {
|
||||||
???
|
//This implementation keep the iBus.cmd on the bus until it's executed, even if the pipeline is flushed
|
||||||
/* def inputStage = iBusRsp.stages(0)
|
def stage = iBusRsp.stages(1)
|
||||||
val busFork = Stream(UInt(32 bits))
|
stage.halt setWhen(iBus.cmd.isStall)
|
||||||
val busForkedReg = RegInit(False)
|
val cmdKeep = RegInit(False) setWhen(iBus.cmd.valid) clearWhen(iBus.cmd.ready)
|
||||||
if(!relaxedPcCalculation) busForkedReg clearWhen(flush)
|
val cmdFired = RegInit(False) setWhen(iBus.cmd.fire) clearWhen(stage.input.ready)
|
||||||
busForkedReg setWhen(iBus.cmd.fire)
|
iBus.cmd.valid := (stage.input.valid || cmdKeep) && pendingCmd =/= pendingMax && !cmdFired
|
||||||
busForkedReg clearWhen(inputStage.output.ready)
|
iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00"
|
||||||
if(relaxedPcCalculation) busForkedReg clearWhen(flush)
|
} else */new Area {
|
||||||
val busForked = Bool
|
//This implementation keep the iBus.cmd on the bus until it's executed or the the pipeline is flushed (not "safe")
|
||||||
busForked := (if(!relaxedPcCalculation) (busForkedReg && !flush) else (busForkedReg))
|
|
||||||
|
|
||||||
|
|
||||||
busFork.valid := inputStage.input.valid && !busForkedReg
|
|
||||||
busFork.payload := inputStage.input.payload
|
|
||||||
|
|
||||||
inputStage.halt setWhen()
|
|
||||||
output.valid := (inputStage.input.valid && iBus.cmd.fire) || busForked
|
|
||||||
output.payload := input.payload
|
|
||||||
input.ready := output.fire
|
|
||||||
|
|
||||||
|
|
||||||
val okBus = pendingCmd =/= pendingMax
|
|
||||||
iBus.cmd.valid := busFork.valid && okBus
|
|
||||||
iBus.cmd.pc := busFork.payload(31 downto 2) @@ "00"
|
|
||||||
busFork.ready := iBus.cmd.ready && okBus*/
|
|
||||||
} else new Area {
|
|
||||||
def stage = iBusRsp.stages(if(relaxedPcCalculation) 1 else 0)
|
def stage = iBusRsp.stages(if(relaxedPcCalculation) 1 else 0)
|
||||||
stage.halt setWhen(stage.input.valid && (!iBus.cmd.valid || !iBus.cmd.ready))
|
stage.halt setWhen(stage.input.valid && (!iBus.cmd.valid || !iBus.cmd.ready))
|
||||||
|
|
||||||
iBus.cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax
|
iBus.cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax
|
||||||
iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00"
|
iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00"
|
||||||
}
|
}
|
||||||
|
@ -235,10 +211,11 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
val discardCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
|
val discardCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
|
||||||
discardCounter := discardCounter - (iBus.rsp.fire && discardCounter =/= 0).asUInt
|
discardCounter := discardCounter - (iBus.rsp.fire && discardCounter =/= 0).asUInt
|
||||||
when(flush) {
|
when(flush) {
|
||||||
|
// discardCounter := (if(relaxedPcCalculation) pendingCmd + iBus.cmd.valid.asUInt - iBus.rsp.fire.asUInt else pendingCmd - iBus.rsp.fire.asUInt)
|
||||||
discardCounter := (if(relaxedPcCalculation) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
|
discardCounter := (if(relaxedPcCalculation) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount - (if(relaxedPcCalculation) 0 else 0))
|
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin)
|
||||||
rspBuffer.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
rspBuffer.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
||||||
rspBuffer.io.flush := flush
|
rspBuffer.io.flush := flush
|
||||||
|
|
||||||
|
@ -249,8 +226,11 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
|
|
||||||
|
|
||||||
var issueDetected = False
|
var issueDetected = False
|
||||||
val join = StreamJoin(Seq(stages.last.output, rspBuffer.io.pop), fetchRsp)
|
val join = Stream(FetchRsp())
|
||||||
stages.last.output.ready setWhen(!stages.last.output.valid)
|
join.valid := stages.last.output.valid && rspBuffer.io.pop.valid
|
||||||
|
join.payload := fetchRsp
|
||||||
|
stages.last.output.ready := stages.last.output.valid ? join.fire | join.ready
|
||||||
|
rspBuffer.io.pop.ready := join.fire
|
||||||
output << join.haltWhen(issueDetected)
|
output << join.haltWhen(issueDetected)
|
||||||
|
|
||||||
if(catchAccessFault){
|
if(catchAccessFault){
|
||||||
|
|
|
@ -718,11 +718,6 @@ public:
|
||||||
logTraces.open (name + ".logTrace");
|
logTraces.open (name + ".logTrace");
|
||||||
fillSimELements();
|
fillSimELements();
|
||||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
|
||||||
|
|
||||||
//Sync register file initial content
|
|
||||||
for(int i = 1;i < 32;i++){
|
|
||||||
riscvRef.regs[i] = top->VexRiscv->RegFilePlugin_regFile[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Workspace(){
|
virtual ~Workspace(){
|
||||||
|
@ -921,6 +916,10 @@ public:
|
||||||
|
|
||||||
postReset();
|
postReset();
|
||||||
|
|
||||||
|
//Sync register file initial content
|
||||||
|
for(int i = 1;i < 32;i++){
|
||||||
|
riscvRef.regs[i] = top->VexRiscv->RegFilePlugin_regFile[i];
|
||||||
|
}
|
||||||
resetDone = true;
|
resetDone = true;
|
||||||
|
|
||||||
#ifdef REF
|
#ifdef REF
|
||||||
|
|
Loading…
Reference in New Issue