rework fetcher
This commit is contained in:
parent
56fd73fbbc
commit
86efb75f6a
|
@ -18,7 +18,6 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
val compressedGen : Boolean,
|
||||
val cmdToRspStageCount : Int,
|
||||
val injectorReadyCutGen : Boolean,
|
||||
val relaxedPcCalculation : Boolean,
|
||||
val prediction : BranchPrediction,
|
||||
val historyRamSizeLog2 : Int,
|
||||
val injectorStage : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
|
||||
|
@ -111,39 +110,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
val predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits)))
|
||||
}
|
||||
|
||||
val fetchPc = if(relaxedPcCalculation) new PcFetch {
|
||||
//PC calculation without Jump
|
||||
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
|
||||
|
||||
val pcPlus4 = pcReg + 4
|
||||
if (keepPcPlus4) KeepAttribute(pcPlus4)
|
||||
when(preOutput.fire) {
|
||||
pcReg := pcPlus4
|
||||
}
|
||||
|
||||
//Realign
|
||||
if(compressedGen){
|
||||
when(preOutput.fire){
|
||||
pcReg(1 downto 0) := 0
|
||||
}
|
||||
}
|
||||
|
||||
preOutput.valid := RegNext(True) init (False) // && !jump.pcLoad.valid
|
||||
preOutput.payload := pcReg
|
||||
|
||||
//application of the selected jump request
|
||||
if(predictionPcLoad != null) {
|
||||
when(predictionPcLoad.valid) {
|
||||
pcReg := predictionPcLoad.payload
|
||||
preOutput.valid := False
|
||||
}
|
||||
}
|
||||
when(jump.pcLoad.valid) {
|
||||
pcReg := jump.pcLoad.payload
|
||||
}
|
||||
|
||||
|
||||
} else new PcFetch{
|
||||
val fetchPc = new PcFetch{
|
||||
//PC calculation without Jump
|
||||
val pcReg = Reg(UInt(32 bits)) init(if(resetVector != null) resetVector else externalResetVector) addAttribute(Verilator.public)
|
||||
val inc = RegInit(False)
|
||||
|
@ -216,14 +183,6 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
})
|
||||
|
||||
|
||||
// val iBusCmd = new Area {
|
||||
// def input = fetchPc.output
|
||||
//
|
||||
// // ...
|
||||
//
|
||||
// val output = Stream(UInt(32 bits))
|
||||
// }
|
||||
|
||||
case class FetchRsp() extends Bundle {
|
||||
val pc = UInt(32 bits)
|
||||
val rsp = IBusSimpleRsp()
|
||||
|
@ -232,22 +191,51 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
|
||||
|
||||
val iBusRsp = new Area {
|
||||
val input = Stream(UInt(32 bits))
|
||||
val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
|
||||
val inputPipelineHalt = Vec(False, cmdToRspStageCount-1)
|
||||
for(i <- 0 until cmdToRspStageCount) {
|
||||
// val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush
|
||||
inputPipeline(i) << {i match {
|
||||
case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation, collapsBubble = false)
|
||||
case _ => inputPipeline(i-1).haltWhen(inputPipelineHalt(i-1)).m2sPipeWithFlush(flush,collapsBubble = false)
|
||||
}}
|
||||
// val input = Stream(UInt(32 bits))
|
||||
// val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
|
||||
// val inputPipelineHalt = Vec(False, cmdToRspStageCount-1)
|
||||
// for(i <- 0 until cmdToRspStageCount) {
|
||||
// inputPipeline(i) << {i match {
|
||||
// case 0 => input.m2sPipeWithFlush(flush, false, collapsBubble = false)
|
||||
// case _ => inputPipeline(i-1).haltWhen(inputPipelineHalt(i-1)).m2sPipeWithFlush(flush,collapsBubble = false)
|
||||
// }}
|
||||
// }
|
||||
|
||||
// val stages = Array.fill(cmdToRspStageCount)(Stream(UInt(32 bits)))
|
||||
val stages = Array.fill(cmdToRspStageCount + 1)(new Bundle {
|
||||
val input = Stream(UInt(32 bits))
|
||||
val output = Stream(UInt(32 bits))
|
||||
val halt = Bool
|
||||
val inputSample = Bool
|
||||
})
|
||||
|
||||
stages(0).input << fetchPc.output
|
||||
stages(0).inputSample := True
|
||||
for(s <- stages) {
|
||||
s.halt := False
|
||||
s.output << s.input.haltWhen(s.halt)
|
||||
}
|
||||
|
||||
for((s,sNext) <- (stages, stages.tail).zipped) {
|
||||
sNext.input << s.output.m2sPipeWithFlush(flush, s != stages.head, collapsBubble = false)
|
||||
}
|
||||
|
||||
//
|
||||
// val pipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount + 1)
|
||||
// val halts = Vec(False, cmdToRspStageCount)
|
||||
// for(i <- 0 until cmdToRspStageCount + 1) {
|
||||
// pipeline(i) << {i match {
|
||||
// case 0 => pipeline(0) << fetchPc.output.haltWhen(halts(i))
|
||||
// case 1 => pipeline(1).m2sPipeWithFlush(flush, false, collapsBubble = false)
|
||||
// case _ => inputPipeline(i-1).haltWhen(inputPipelineHalt(i-1)).m2sPipeWithFlush(flush,collapsBubble = false)
|
||||
// }}
|
||||
// }
|
||||
|
||||
// ...
|
||||
|
||||
val readyForError = True
|
||||
val output = Stream(FetchRsp())
|
||||
incomingInstruction setWhen(inputPipeline.map(_.valid).orR)
|
||||
incomingInstruction setWhen(stages.tail.map(_.input.valid).reduce(_ || _))
|
||||
}
|
||||
|
||||
val decompressor = ifGen(decodePcGen)(new Area{
|
||||
|
@ -326,10 +314,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
val valids = pcUpdatedGen(True, False :: List(execute, memory, writeBack).map(_.arbitration.isStuck), true)
|
||||
pcValids := Vec(valids.takeRight(4))
|
||||
} else new Area{
|
||||
val valids = pcUpdatedGen(True, iBusRsp.inputPipeline.map(!_.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), relaxedPcCalculation)
|
||||
if(relaxedPcCalculation && fetchPrediction != null) when(fetchPc.predictionPcLoad.valid){
|
||||
valids(0).getDrivingReg := False
|
||||
}
|
||||
val valids = pcUpdatedGen(True, iBusRsp.stages.tail.map(!_.input.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), false)
|
||||
pcValids := Vec(valids.takeRight(4))
|
||||
}
|
||||
|
||||
|
@ -426,7 +411,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
}
|
||||
|
||||
def stage1ToInjectorPipe[T <: Data](input : T): (T,T) ={
|
||||
val iBusRspContext = iBusRsp.inputPipeline.tail.foldLeft(input)((data,stream) => RegNextWhen(data, stream.ready))
|
||||
val iBusRspContext = iBusRsp.stages.drop(1).dropRight(1).foldLeft(input)((data,stage) => RegNextWhen(data, stage.output.ready))
|
||||
// val decompressorContext = ifGen(compressedGen)(new Area{
|
||||
// val lastContext = RegNextWhen(iBusRspContext, decompressor.input.fire)
|
||||
// val output = decompressor.bufferValid ? lastContext | iBusRspContext
|
||||
|
@ -450,8 +435,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
|
||||
val historyCache = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
||||
val historyWrite = historyCache.writePort
|
||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.inputPipeline(0).ready)
|
||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.inputPipeline(0).payload >> 2).resized
|
||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.stages(0).output.ready)
|
||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.stages(0).input.payload >> 2).resized
|
||||
|
||||
case class DynamicContext() extends Bundle{
|
||||
val hazard = Bool
|
||||
|
@ -459,7 +444,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
}
|
||||
val fetchContext = DynamicContext()
|
||||
fetchContext.hazard := hazard
|
||||
fetchContext.line := historyCache.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.inputPipeline(0).ready || flush)
|
||||
fetchContext.line := historyCache.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.stages(0).output.ready || flush)
|
||||
|
||||
object PREDICTION_CONTEXT extends Stageable(DynamicContext())
|
||||
decode.insert(PREDICTION_CONTEXT) := stage1ToInjectorPipe(fetchContext)._2
|
||||
|
@ -509,8 +494,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
val history = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
||||
val historyWrite = history.writePort
|
||||
|
||||
val line = history.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.inputPipeline(0).ready || flush)
|
||||
val hit = line.source === (iBusRsp.inputPipeline(0).payload.asBits >> 2 + historyRamSizeLog2) && (if(compressedGen)(!(!line.unaligned && iBusRsp.inputPipeline(0).payload(1))) else True)
|
||||
val line = history.readSync((iBusRsp.stages(0).input.payload >> 2).resized, iBusRsp.stages(0).output.ready || flush)
|
||||
val hit = line.source === (iBusRsp.stages(1).input.payload.asBits >> 2 + historyRamSizeLog2) && (if(compressedGen)(!(!line.unaligned && iBusRsp.stages(1).input.payload(1))) else True)
|
||||
|
||||
//Avoid stoping instruction fetch in the middle patch
|
||||
if(compressedGen && cmdToRspStageCount == 1){
|
||||
|
@ -518,9 +503,10 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
}
|
||||
|
||||
//Avoid write to read hazard
|
||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.inputPipeline(0).ready)
|
||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.inputPipeline(0).payload >> 2).resized
|
||||
fetchPc.predictionPcLoad.valid := line.branchWish.msb && hit && !hazard && iBusRsp.inputPipeline(0).fire //XXX && !(!line.unaligned && iBusRsp.inputPipeline(0).payload(1))
|
||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.stages(0).output.ready)
|
||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.stages(1).input.payload >> 2).resized
|
||||
//TODO improve predictionPcLoad way of doing things
|
||||
fetchPc.predictionPcLoad.valid := line.branchWish.msb && hit && !hazard && iBusRsp.stages(1).output.fire //XXX && !(!line.unaligned && iBusRsp.inputPipeline(0).payload(1))
|
||||
fetchPc.predictionPcLoad.payload := line.target
|
||||
|
||||
case class PredictionResult() extends Bundle{
|
||||
|
|
|
@ -23,14 +23,14 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
keepPcPlus4 = keepPcPlus4,
|
||||
decodePcGen = compressedGen,
|
||||
compressedGen = compressedGen,
|
||||
cmdToRspStageCount = (if(config.twoCycleCache) 2 else 1),
|
||||
cmdToRspStageCount = (if(config.twoCycleCache) 2 else 1) + (if(relaxedPcCalculation) 1 else 0),
|
||||
injectorReadyCutGen = false,
|
||||
relaxedPcCalculation = relaxedPcCalculation,
|
||||
prediction = prediction,
|
||||
historyRamSizeLog2 = historyRamSizeLog2,
|
||||
injectorStage = !config.twoCycleCache || injectorStage){
|
||||
import config._
|
||||
|
||||
|
||||
var iBus : InstructionCacheMemBus = null
|
||||
var mmuBus : MemoryTranslatorBus = null
|
||||
var privilegeService : PrivilegeService = null
|
||||
|
@ -99,18 +99,20 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
iBus = master(new InstructionCacheMemBus(IBusCachedPlugin.this.config)).setName("iBus")
|
||||
iBus <> cache.io.mem
|
||||
iBus.cmd.address.allowOverride := cache.io.mem.cmd.address // - debugAddressOffset
|
||||
|
||||
|
||||
val stageOffset = if(relaxedPcCalculation) 1 else 0
|
||||
def stages = iBusRsp.stages.drop(stageOffset)
|
||||
//Connect prefetch cache side
|
||||
cache.io.cpu.prefetch.isValid := fetchPc.output.valid
|
||||
cache.io.cpu.prefetch.pc := fetchPc.output.payload
|
||||
iBusRsp.input << fetchPc.output.haltWhen(cache.io.cpu.prefetch.haltIt)
|
||||
cache.io.cpu.prefetch.isValid := stages(0).input.valid
|
||||
cache.io.cpu.prefetch.pc := stages(0).input.payload
|
||||
stages(0).halt setWhen(cache.io.cpu.prefetch.haltIt)
|
||||
|
||||
|
||||
cache.io.cpu.fetch.isRemoved := flush
|
||||
val iBusRspOutputHalt = False
|
||||
if (mmuBus != null) {
|
||||
cache.io.cpu.fetch.mmuBus <> mmuBus
|
||||
(if(twoCycleCache) iBusRsp.inputPipelineHalt(0) else iBusRspOutputHalt) setWhen(mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss)
|
||||
(if(twoCycleCache) stages(1).halt else iBusRspOutputHalt) setWhen(mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss)
|
||||
} else {
|
||||
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress
|
||||
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
||||
|
@ -123,15 +125,15 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
}
|
||||
|
||||
//Connect fetch cache side
|
||||
cache.io.cpu.fetch.isValid := iBusRsp.inputPipeline(0).valid
|
||||
cache.io.cpu.fetch.isStuck := !iBusRsp.inputPipeline(0).ready
|
||||
cache.io.cpu.fetch.pc := iBusRsp.inputPipeline(0).payload
|
||||
cache.io.cpu.fetch.isValid := stages(1).input.valid
|
||||
cache.io.cpu.fetch.isStuck := !stages(1).input.ready
|
||||
cache.io.cpu.fetch.pc := stages(1).input.payload
|
||||
|
||||
|
||||
if(twoCycleCache){
|
||||
cache.io.cpu.decode.isValid := iBusRsp.inputPipeline(1).valid
|
||||
cache.io.cpu.decode.isStuck := !iBusRsp.inputPipeline(1).ready
|
||||
cache.io.cpu.decode.pc := iBusRsp.inputPipeline(1).payload
|
||||
cache.io.cpu.decode.isValid := stages(2).input.valid
|
||||
cache.io.cpu.decode.isStuck := !stages(2).input.ready
|
||||
cache.io.cpu.decode.pc := stages(2).input.payload
|
||||
cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
|
||||
|
||||
if((!twoCycleRam || wayCount == 1) && !compressedGen && !injectorStage){
|
||||
|
@ -145,7 +147,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
|
||||
// val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
|
||||
val cacheRsp = if(twoCycleCache) cache.io.cpu.decode else cache.io.cpu.fetch
|
||||
val cacheRspArbitration = iBusRsp.inputPipeline(if(twoCycleCache) 1 else 0)
|
||||
val cacheRspArbitration = stages(if(twoCycleCache) 2 else 1)
|
||||
var issueDetected = False
|
||||
val redoFetch = False //RegNext(False) init(False)
|
||||
when(cacheRsp.isValid && cacheRsp.cacheMiss && !issueDetected){
|
||||
|
@ -174,49 +176,12 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
iBusRsp.output.arbitrationFrom(cacheRspArbitration.haltWhen(issueDetected || iBusRspOutputHalt))
|
||||
cacheRspArbitration.halt setWhen(issueDetected || iBusRspOutputHalt)
|
||||
iBusRsp.output.arbitrationFrom(cacheRspArbitration.output)
|
||||
iBusRsp.output.rsp.inst := cacheRsp.data
|
||||
iBusRsp.output.pc := cacheRspArbitration.payload
|
||||
iBusRsp.output.pc := cacheRspArbitration.output.payload
|
||||
|
||||
|
||||
// if (dataOnDecode) {
|
||||
// decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
|
||||
// } else {
|
||||
// iBusRsp.outputBeforeStage.arbitrationFrom(iBusRsp.inputPipeline(0))
|
||||
// iBusRsp.outputBeforeStage.rsp.inst := cache.io.cpu.fetch.data
|
||||
// iBusRsp.outputBeforeStage.pc := iBusRsp.inputPipeline(0).payload
|
||||
// }
|
||||
//
|
||||
// cache.io.cpu.decode.pc := injector.inputBeforeHalt.pc
|
||||
//
|
||||
// val ownDecode = pipeline.plugins.filter(_.isInstanceOf[InstructionInjector]).foldLeft(True)(_ && !_.asInstanceOf[InstructionInjector].isInjecting(decode))
|
||||
// cache.io.cpu.decode.isValid := decode.arbitration.isValid && ownDecode
|
||||
// cache.io.cpu.decode.isStuck := !injector.inputBeforeHalt.ready
|
||||
// cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
|
||||
// // cache.io.cpu.decode.pc := decode.input(PC)
|
||||
//
|
||||
// redoBranch.valid := decode.arbitration.isValid && ownDecode && cache.io.cpu.decode.cacheMiss && !cache.io.cpu.decode.mmuMiss && !cache.io.cpu.decode.illegalAccess
|
||||
// redoBranch.payload := decode.input(PC)
|
||||
// when(redoBranch.valid) {
|
||||
// decode.arbitration.redoIt := True
|
||||
// decode.arbitration.flushAll := True
|
||||
// }
|
||||
|
||||
// val redo = RegInit(False) clearWhen(decode.arbitration.isValid) setWhen(redoBranch.valid)
|
||||
// when(redoBranch.valid || redo){
|
||||
// service(classOf[InterruptionInhibitor]).inhibateInterrupts()
|
||||
// }
|
||||
|
||||
// if (catchSomething) {
|
||||
// val accessFault = if (catchAccessFault) cache.io.cpu.decode.error else False
|
||||
// val mmuMiss = if (catchMemoryTranslationMiss) cache.io.cpu.decode.mmuMiss else False
|
||||
// val illegalAccess = if (catchIllegalAccess) cache.io.cpu.decode.illegalAccess else False
|
||||
|
||||
// decodeExceptionPort.valid := decode.arbitration.isValid && ownDecode && (accessFault || mmuMiss || illegalAccess)
|
||||
// decodeExceptionPort.code := mmuMiss ? U(14) | 1
|
||||
// decodeExceptionPort.badAddr := decode.input(PC)
|
||||
// }
|
||||
|
||||
memory plug new Area {
|
||||
|
||||
|
|
|
@ -159,9 +159,8 @@ class IBusSimplePlugin(resetVector : BigInt,
|
|||
keepPcPlus4 = keepPcPlus4,
|
||||
decodePcGen = compressedGen,
|
||||
compressedGen = compressedGen,
|
||||
cmdToRspStageCount = busLatencyMin,
|
||||
cmdToRspStageCount = busLatencyMin + (if(relaxedPcCalculation) 1 else 0),
|
||||
injectorReadyCutGen = false,
|
||||
relaxedPcCalculation = relaxedPcCalculation,
|
||||
prediction = prediction,
|
||||
historyRamSizeLog2 = historyRamSizeLog2,
|
||||
injectorStage = injectorStage){
|
||||
|
@ -187,36 +186,49 @@ class IBusSimplePlugin(resetVector : BigInt,
|
|||
|
||||
pipeline plug new FetchArea(pipeline) {
|
||||
|
||||
|
||||
|
||||
//Avoid sending to many iBus cmd
|
||||
val pendingCmd = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
|
||||
val pendingCmdNext = pendingCmd + iBus.cmd.fire.asUInt - iBus.rsp.fire.asUInt
|
||||
pendingCmd := pendingCmdNext
|
||||
|
||||
val cmd = if(relaxedBusCmdValid) new Area {
|
||||
assert(relaxedPcCalculation, "relaxedBusCmdValid can only be used with relaxedPcCalculation")
|
||||
def input = fetchPc.output
|
||||
def output = iBusRsp.input
|
||||
???
|
||||
/* def inputStage = iBusRsp.stages(0)
|
||||
val busFork = Stream(UInt(32 bits))
|
||||
val busForkedReg = RegInit(False)
|
||||
if(!relaxedPcCalculation) busForkedReg clearWhen(flush)
|
||||
busForkedReg setWhen(iBus.cmd.fire)
|
||||
busForkedReg clearWhen(inputStage.output.ready)
|
||||
if(relaxedPcCalculation) busForkedReg clearWhen(flush)
|
||||
val busForked = Bool
|
||||
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 fork = StreamForkVex(input, 2, flush)
|
||||
val busFork = fork(0)
|
||||
val pipFork = fork(1)
|
||||
output << pipFork
|
||||
|
||||
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
|
||||
busFork.ready := iBus.cmd.ready && okBus*/
|
||||
} else new Area {
|
||||
def input = fetchPc.output
|
||||
def output = iBusRsp.input
|
||||
def stage = iBusRsp.stages(if(relaxedPcCalculation) 1 else 0)
|
||||
stage.halt setWhen(stage.input.valid && (!iBus.cmd.valid || !iBus.cmd.ready))
|
||||
|
||||
output << input.continueWhen(iBus.cmd.fire)
|
||||
|
||||
iBus.cmd.valid := input.valid && output.ready && pendingCmd =/= pendingMax
|
||||
iBus.cmd.pc := input.payload(31 downto 2) @@ "00"
|
||||
iBus.cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax
|
||||
iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00"
|
||||
}
|
||||
|
||||
|
||||
|
||||
val rsp = new Area {
|
||||
import iBusRsp._
|
||||
//Manage flush for iBus transactions in flight
|
||||
|
@ -226,20 +238,19 @@ class IBusSimplePlugin(resetVector : BigInt,
|
|||
discardCounter := (if(relaxedPcCalculation) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
|
||||
}
|
||||
|
||||
|
||||
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount + (if(relaxedBusCmdValid) 1 else 0))
|
||||
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount - (if(relaxedPcCalculation) 0 else 0))
|
||||
rspBuffer.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
||||
rspBuffer.io.flush := flush
|
||||
|
||||
val fetchRsp = FetchRsp()
|
||||
fetchRsp.pc := inputPipeline.last.payload
|
||||
fetchRsp.pc := stages.last.output.payload
|
||||
fetchRsp.rsp := rspBuffer.io.pop.payload
|
||||
fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin
|
||||
|
||||
|
||||
var issueDetected = False
|
||||
val join = StreamJoin(Seq(inputPipeline.last, rspBuffer.io.pop), fetchRsp)
|
||||
inputPipeline.last.ready setWhen(!inputPipeline.last.valid)
|
||||
val join = StreamJoin(Seq(stages.last.output, rspBuffer.io.pop), fetchRsp)
|
||||
stages.last.output.ready setWhen(!stages.last.output.valid)
|
||||
output << join.haltWhen(issueDetected)
|
||||
|
||||
if(catchAccessFault){
|
||||
|
|
|
@ -522,8 +522,8 @@ class TestIndividualFeatures extends FunSuite {
|
|||
// val seed = -2412372746600605141l
|
||||
|
||||
|
||||
// val testId = Some(mutable.HashSet[Int](15))
|
||||
// val seed = -8861778219266506530l
|
||||
// val testId = Some(mutable.HashSet[Int](1,6,11,17,23,24))
|
||||
// val seed = -7309275932954927463l
|
||||
|
||||
|
||||
val rand = new Random(seed)
|
||||
|
|
Loading…
Reference in New Issue