IBusFetcher now support proper iBusRsp.redo/flush
This commit is contained in:
parent
ebfa9e6577
commit
8be50b8e3d
|
@ -272,7 +272,7 @@ object LinuxGen {
|
|||
// wfiGenAsNop = true,
|
||||
// ucycleAccess = CsrAccess.NONE
|
||||
// )),
|
||||
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
catchAddressMisaligned = true,
|
||||
|
@ -310,7 +310,7 @@ object LinuxGen {
|
|||
// }
|
||||
// }
|
||||
|
||||
SpinalConfig(mergeAsyncProcess = true, anonymSignalPrefix = "_zz").generateVerilog {
|
||||
SpinalConfig(mergeAsyncProcess = false, anonymSignalPrefix = "_zz").generateVerilog {
|
||||
|
||||
|
||||
val toplevel = new VexRiscv(configFull(
|
||||
|
|
|
@ -21,7 +21,8 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
val prediction : BranchPrediction,
|
||||
val historyRamSizeLog2 : Int,
|
||||
val injectorStage : Boolean,
|
||||
val relaxPredictorAddress : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
|
||||
val relaxPredictorAddress : Boolean,
|
||||
val fetchRedoGen : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
|
||||
var prefetchExceptionPort : Flow[ExceptionCause] = null
|
||||
var decodePrediction : DecodePredictionBus = null
|
||||
var fetchPrediction : FetchPredictionBus = null
|
||||
|
@ -131,11 +132,16 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
val inc = RegInit(False) clearWhen(corrected || pcRegPropagate) setWhen(output.fire) clearWhen(!output.valid && output.ready)
|
||||
val pc = pcReg + (inc ## B"00").asUInt
|
||||
// val predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits)))
|
||||
val redo = fetchRedoGen generate Flow(UInt(32 bits))
|
||||
|
||||
if(compressedGen) when(inc) {
|
||||
pc(1) := False
|
||||
}
|
||||
|
||||
if(fetchRedoGen) when(redo.valid){
|
||||
corrected := True
|
||||
pc := redo.payload
|
||||
}
|
||||
// if(predictionPcLoad != null) {
|
||||
// when(predictionPcLoad.valid) {
|
||||
// corrected := True
|
||||
|
@ -147,7 +153,6 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
pc := jump.pcLoad.payload
|
||||
}
|
||||
|
||||
|
||||
when(booted && (output.ready || corrected || pcRegPropagate)){
|
||||
pcReg := pc
|
||||
}
|
||||
|
@ -231,6 +236,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
val decompressor = ifGen(decodePcGen)(new Area{
|
||||
def input = iBusRsp.output
|
||||
val output = Stream(FetchRsp())
|
||||
val flush = getFlushAt(DECOMPRESSOR)
|
||||
|
||||
val bufferValid = RegInit(False)
|
||||
val bufferData = Reg(Bits(16 bits))
|
||||
|
@ -248,7 +254,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
output.rsp.inst := isRvc ? decompressed | raw
|
||||
input.ready := !output.valid || !(!output.ready || (isRvc && !input.pc(1) && input.rsp.inst(16, 2 bits) =/= 3) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))
|
||||
addPrePopTask(() => {
|
||||
when(!input.ready && output.fire && !fetcherflushIt /* && ((isRvc && !bufferValid && !input.pc(1)) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))*/) {
|
||||
when(!input.ready && output.fire && !flush /* && ((isRvc && !bufferValid && !input.pc(1)) || (!isRvc && bufferValid && input.rsp.inst(16, 2 bits) =/= 3))*/) {
|
||||
input.pc.getDrivingReg(1) := True
|
||||
}
|
||||
})
|
||||
|
@ -264,7 +270,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
}
|
||||
bufferData := input.rsp.inst(31 downto 16)
|
||||
}
|
||||
bufferValid.clearWhen(fetcherflushIt)
|
||||
bufferValid.clearWhen(flush)
|
||||
iBusRsp.readyForError.clearWhen(bufferValid && isRvc) //Can't emit error, as there is a earlier instruction pending
|
||||
incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3)
|
||||
})
|
||||
|
|
|
@ -46,7 +46,8 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
prediction = prediction,
|
||||
historyRamSizeLog2 = historyRamSizeLog2,
|
||||
injectorStage = (!config.twoCycleCache && !withoutInjectorStage) || injectorStage,
|
||||
relaxPredictorAddress = relaxPredictorAddress){
|
||||
relaxPredictorAddress = relaxPredictorAddress,
|
||||
fetchRedoGen = true){
|
||||
import config._
|
||||
|
||||
assert(isPow2(cacheSize))
|
||||
|
@ -86,9 +87,6 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
FLUSH_ALL -> True
|
||||
))
|
||||
|
||||
|
||||
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor
|
||||
|
||||
if(catchSomething) {
|
||||
val exceptionService = pipeline.service(classOf[ExceptionService])
|
||||
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
|
||||
|
@ -238,9 +236,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
}
|
||||
|
||||
|
||||
redoBranch.valid := redoFetch
|
||||
redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc)
|
||||
iBusRsp.fetchFlush setWhen(redoBranch.valid)
|
||||
fetchPc.redo.valid := redoFetch
|
||||
fetchPc.redo.payload := iBusRsp.stages.last.input.payload
|
||||
iBusRsp.fetchFlush setWhen(redoFetch)
|
||||
|
||||
|
||||
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
|
||||
|
|
|
@ -245,13 +245,13 @@ class IBusSimplePlugin( resetVector : BigInt,
|
|||
prediction = prediction,
|
||||
historyRamSizeLog2 = historyRamSizeLog2,
|
||||
injectorStage = injectorStage,
|
||||
relaxPredictorAddress = relaxPredictorAddress){
|
||||
relaxPredictorAddress = relaxPredictorAddress,
|
||||
fetchRedoGen = memoryTranslatorPortConfig != null){
|
||||
|
||||
var iBus : IBusSimpleBus = null
|
||||
var decodeExceptionPort : Flow[ExceptionCause] = null
|
||||
val catchSomething = memoryTranslatorPortConfig != null || catchAccessFault
|
||||
var mmuBus : MemoryTranslatorBus = null
|
||||
var redoBranch : Flow[UInt] = null
|
||||
|
||||
if(rspHoldValue) assert(busLatencyMin <= 1)
|
||||
|
||||
|
@ -268,7 +268,6 @@ class IBusSimplePlugin( resetVector : BigInt,
|
|||
|
||||
if(memoryTranslatorPortConfig != null) {
|
||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig)
|
||||
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,12 +378,9 @@ class IBusSimplePlugin( resetVector : BigInt,
|
|||
|
||||
if(memoryTranslatorPortConfig != null){
|
||||
redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling)
|
||||
redoBranch.valid := redoRequired && iBusRsp.readyForError
|
||||
redoBranch.payload := decode.input(PC)
|
||||
|
||||
decode.arbitration.flushIt setWhen(redoBranch.valid)
|
||||
decode.arbitration.flushNext setWhen(redoBranch.valid)
|
||||
???
|
||||
fetchPc.redo.valid := redoRequired && iBusRsp.readyForError
|
||||
fetchPc.redo.payload := decode.input(PC)
|
||||
iBusRsp.fetchFlush setWhen(fetchPc.redo.valid)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -102,9 +102,9 @@ class DhrystoneBench extends FunSuite{
|
|||
getDmips(
|
||||
name = "GenLinuxBalenced",
|
||||
gen = LinuxGen.main(Array.fill[String](0)("")),
|
||||
testCmd = "make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=no CSR=yes CSR_SKIP_TEST=yes DEBUG_PLUGIN=no COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=no"
|
||||
testCmd = "make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=no CSR=yes CSR_SKIP_TEST=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=no"
|
||||
)
|
||||
|
||||
//make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yess SUPERVISOR=yes CSR=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=1 TRACE=no LINUX_REGRESSION=yes SEED=42
|
||||
|
||||
|
||||
test("final_report") {
|
||||
|
|
Loading…
Reference in New Issue