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