Fetcher/IBusSimplePlugin wip

This commit is contained in:
Dolu1990 2018-10-03 01:02:22 +02:00
parent 0ada869b2d
commit c61f17aea3
3 changed files with 42 additions and 53 deletions

View File

@ -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{

View File

@ -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){

View File

@ -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