Fix fetcher decompressor when driving decode stage

This commit is contained in:
Charles Papon 2020-02-21 02:03:29 +01:00
parent 59508d5b57
commit 32fade50e5
2 changed files with 11 additions and 12 deletions

View File

@ -88,8 +88,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
def isDrivingDecode(s : Any): Boolean = { def isDrivingDecode(s : Any): Boolean = {
if(injectorStage) return s == INJECTOR_M2S if(injectorStage) return s == INJECTOR_M2S
if(compressedGen) return s == DECOMPRESSOR s == IBUS_RSP || s == DECOMPRESSOR
s == IBUS_RSP
} }
def getFlushAt(s : Any, lastCond : Boolean = true): Bool = { def getFlushAt(s : Any, lastCond : Boolean = true): Bool = {
@ -240,9 +239,11 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
} }
val decompressor = ifGen(decodePcGen)(new Area{ val decompressor = ifGen(decodePcGen)(new Area{
val input = iBusRsp.output.clearValidWhen(iBusRsp.stages.last.flush) val input = iBusRsp.output.clearValidWhen(iBusRsp.redoFetch)
val output = Stream(FetchRsp()) val output = Stream(FetchRsp())
val flush = getFlushAt(DECOMPRESSOR) val flush = getFlushAt(DECOMPRESSOR)
val flushNext = if(isDrivingDecode(DECOMPRESSOR)) decode.arbitration.flushNext else False
val consumeCurrent = if(isDrivingDecode(DECOMPRESSOR)) flushNext && output.ready else False
val bufferValid = RegInit(False) val bufferValid = RegInit(False)
val bufferData = Reg(Bits(16 bits)) val bufferData = Reg(Bits(16 bits))
@ -250,7 +251,6 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
val isInputLowRvc = input.rsp.inst(1 downto 0) =/= 3 val isInputLowRvc = input.rsp.inst(1 downto 0) =/= 3
val isInputHighRvc = input.rsp.inst(17 downto 16) =/= 3 val isInputHighRvc = input.rsp.inst(17 downto 16) =/= 3
val doubleRvc = iBusRsp.stages.last.input.valid && !bufferValid && isInputLowRvc && isInputHighRvc && !input.pc(1)
val throw2BytesReg = RegInit(False) val throw2BytesReg = RegInit(False)
val throw2Bytes = throw2BytesReg || input.pc(1) val throw2Bytes = throw2BytesReg || input.pc(1)
val unaligned = throw2Bytes || bufferValid val unaligned = throw2Bytes || bufferValid
@ -266,7 +266,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
output.pc := input.pc output.pc := input.pc
output.isRvc := isRvc output.isRvc := isRvc
output.rsp.inst := isRvc ? decompressed | raw output.rsp.inst := isRvc ? decompressed | raw
input.ready := output.ready && (!iBusRsp.stages.last.input.valid || (!(bufferValid && isInputHighRvc) && !(aligned && isInputLowRvc && isInputHighRvc))) input.ready := output.ready && (!iBusRsp.stages.last.input.valid || flushNext || (!(bufferValid && isInputHighRvc) && !(aligned && isInputLowRvc && isInputHighRvc)))
when(output.fire){ when(output.fire){
throw2BytesReg := (aligned && isInputLowRvc && isInputHighRvc) || (bufferValid && isInputHighRvc) throw2BytesReg := (aligned && isInputLowRvc && isInputHighRvc) || (bufferValid && isInputHighRvc)
@ -280,7 +280,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
bufferValid setWhen(bufferFill) bufferValid setWhen(bufferFill)
} }
when(flush){ when(flush || consumeCurrent){
throw2BytesReg := False throw2BytesReg := False
bufferValid := False bufferValid := False
} }
@ -495,13 +495,11 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
} }
//TODO no more fireing depedancies //TODO no more fireing depedancies
predictionJumpInterface.valid := decode.arbitration.isValid && decodePrediction.cmd.hadBranch //TODO OH Doublon de priorité predictionJumpInterface.valid := decode.arbitration.isValid && decodePrediction.cmd.hadBranch
predictionJumpInterface.payload := decode.input(PC) + ((decode.input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt predictionJumpInterface.payload := decode.input(PC) + ((decode.input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt
if(relaxPredictorAddress) KeepAttribute(predictionJumpInterface.payload) decode.arbitration.flushNext setWhen(predictionJumpInterface.valid)
when(predictionJumpInterface.valid && decode.arbitration.isFiring){ if(relaxPredictorAddress) KeepAttribute(predictionJumpInterface.payload)
flushIt()
}
} }
case DYNAMIC_TARGET => new Area{ case DYNAMIC_TARGET => new Area{
// assert(!compressedGen || cmdToRspStageCount == 1, "Can't combine DYNAMIC_TARGET and RVC as it could stop the instruction fetch mid-air") // assert(!compressedGen || cmdToRspStageCount == 1, "Can't combine DYNAMIC_TARGET and RVC as it could stop the instruction fetch mid-air")

View File

@ -352,7 +352,8 @@ class IBusSimplePlugin( resetVector : BigInt,
val rspBuffer = if(!rspHoldValue) new Area{ val rspBuffer = if(!rspHoldValue) new Area{
val c = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin + (if(cmdForkOnSecondStage && cmdForkPersistence) 1 else 0)) val c = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin + (if(cmdForkOnSecondStage && cmdForkPersistence) 1 else 0))
c.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream c.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
c.io.flush := fetcherflushIt c.io.flush := iBusRsp.stages.last.flush
if(compressedGen) c.io.flush setWhen(decompressor.consumeCurrent)
rspBufferOutput << c.io.pop rspBufferOutput << c.io.pop
} else new Area{ } else new Area{
val rspStream = iBus.rsp.throwWhen(discardCounter =/= 0).toStream val rspStream = iBus.rsp.throwWhen(discardCounter =/= 0).toStream