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 compressedGen : Boolean,
|
||||||
val cmdToRspStageCount : Int,
|
val cmdToRspStageCount : Int,
|
||||||
val injectorReadyCutGen : Boolean,
|
val injectorReadyCutGen : Boolean,
|
||||||
val relaxedPcCalculation : Boolean,
|
|
||||||
val prediction : BranchPrediction,
|
val prediction : BranchPrediction,
|
||||||
val historyRamSizeLog2 : Int,
|
val historyRamSizeLog2 : Int,
|
||||||
val injectorStage : Boolean) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
|
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 predictionPcLoad = ifGen(prediction == DYNAMIC_TARGET) (Flow(UInt(32 bits)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val fetchPc = if(relaxedPcCalculation) 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 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{
|
|
||||||
//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)
|
||||||
|
@ -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 {
|
case class FetchRsp() extends Bundle {
|
||||||
val pc = UInt(32 bits)
|
val pc = UInt(32 bits)
|
||||||
val rsp = IBusSimpleRsp()
|
val rsp = IBusSimpleRsp()
|
||||||
|
@ -232,22 +191,51 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
|
|
||||||
|
|
||||||
val iBusRsp = new Area {
|
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) {
|
||||||
|
// 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 input = Stream(UInt(32 bits))
|
||||||
val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
|
val output = Stream(UInt(32 bits))
|
||||||
val inputPipelineHalt = Vec(False, cmdToRspStageCount-1)
|
val halt = Bool
|
||||||
for(i <- 0 until cmdToRspStageCount) {
|
val inputSample = Bool
|
||||||
// val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush
|
})
|
||||||
inputPipeline(i) << {i match {
|
|
||||||
case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation, collapsBubble = false)
|
stages(0).input << fetchPc.output
|
||||||
case _ => inputPipeline(i-1).haltWhen(inputPipelineHalt(i-1)).m2sPipeWithFlush(flush,collapsBubble = false)
|
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 readyForError = True
|
||||||
val output = Stream(FetchRsp())
|
val output = Stream(FetchRsp())
|
||||||
incomingInstruction setWhen(inputPipeline.map(_.valid).orR)
|
incomingInstruction setWhen(stages.tail.map(_.input.valid).reduce(_ || _))
|
||||||
}
|
}
|
||||||
|
|
||||||
val decompressor = ifGen(decodePcGen)(new Area{
|
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)
|
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{
|
||||||
val valids = pcUpdatedGen(True, iBusRsp.inputPipeline.map(!_.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), relaxedPcCalculation)
|
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)
|
||||||
if(relaxedPcCalculation && fetchPrediction != null) when(fetchPc.predictionPcLoad.valid){
|
|
||||||
valids(0).getDrivingReg := False
|
|
||||||
}
|
|
||||||
pcValids := Vec(valids.takeRight(4))
|
pcValids := Vec(valids.takeRight(4))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +411,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
def stage1ToInjectorPipe[T <: Data](input : T): (T,T) ={
|
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 decompressorContext = ifGen(compressedGen)(new Area{
|
||||||
// val lastContext = RegNextWhen(iBusRspContext, decompressor.input.fire)
|
// val lastContext = RegNextWhen(iBusRspContext, decompressor.input.fire)
|
||||||
// val output = decompressor.bufferValid ? lastContext | iBusRspContext
|
// val output = decompressor.bufferValid ? lastContext | iBusRspContext
|
||||||
|
@ -450,8 +435,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
|
|
||||||
val historyCache = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
val historyCache = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
||||||
val historyWrite = historyCache.writePort
|
val historyWrite = historyCache.writePort
|
||||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.inputPipeline(0).ready)
|
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.stages(0).output.ready)
|
||||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.inputPipeline(0).payload >> 2).resized
|
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.stages(0).input.payload >> 2).resized
|
||||||
|
|
||||||
case class DynamicContext() extends Bundle{
|
case class DynamicContext() extends Bundle{
|
||||||
val hazard = Bool
|
val hazard = Bool
|
||||||
|
@ -459,7 +444,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
}
|
}
|
||||||
val fetchContext = DynamicContext()
|
val fetchContext = DynamicContext()
|
||||||
fetchContext.hazard := hazard
|
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())
|
object PREDICTION_CONTEXT extends Stageable(DynamicContext())
|
||||||
decode.insert(PREDICTION_CONTEXT) := stage1ToInjectorPipe(fetchContext)._2
|
decode.insert(PREDICTION_CONTEXT) := stage1ToInjectorPipe(fetchContext)._2
|
||||||
|
@ -509,8 +494,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
val history = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
val history = Mem(BranchPredictorLine(), 1 << historyRamSizeLog2)
|
||||||
val historyWrite = history.writePort
|
val historyWrite = history.writePort
|
||||||
|
|
||||||
val line = history.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.inputPipeline(0).ready || flush)
|
val line = history.readSync((iBusRsp.stages(0).input.payload >> 2).resized, iBusRsp.stages(0).output.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 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
|
//Avoid stoping instruction fetch in the middle patch
|
||||||
if(compressedGen && cmdToRspStageCount == 1){
|
if(compressedGen && cmdToRspStageCount == 1){
|
||||||
|
@ -518,9 +503,10 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Avoid write to read hazard
|
//Avoid write to read hazard
|
||||||
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.inputPipeline(0).ready)
|
val historyWriteLast = RegNextWhen(historyWrite, iBusRsp.stages(0).output.ready)
|
||||||
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.inputPipeline(0).payload >> 2).resized
|
val hazard = historyWriteLast.valid && historyWriteLast.address === (iBusRsp.stages(1).input.payload >> 2).resized
|
||||||
fetchPc.predictionPcLoad.valid := line.branchWish.msb && hit && !hazard && iBusRsp.inputPipeline(0).fire //XXX && !(!line.unaligned && iBusRsp.inputPipeline(0).payload(1))
|
//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
|
fetchPc.predictionPcLoad.payload := line.target
|
||||||
|
|
||||||
case class PredictionResult() extends Bundle{
|
case class PredictionResult() extends Bundle{
|
||||||
|
|
|
@ -23,14 +23,14 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
keepPcPlus4 = keepPcPlus4,
|
keepPcPlus4 = keepPcPlus4,
|
||||||
decodePcGen = compressedGen,
|
decodePcGen = compressedGen,
|
||||||
compressedGen = compressedGen,
|
compressedGen = compressedGen,
|
||||||
cmdToRspStageCount = (if(config.twoCycleCache) 2 else 1),
|
cmdToRspStageCount = (if(config.twoCycleCache) 2 else 1) + (if(relaxedPcCalculation) 1 else 0),
|
||||||
injectorReadyCutGen = false,
|
injectorReadyCutGen = false,
|
||||||
relaxedPcCalculation = relaxedPcCalculation,
|
|
||||||
prediction = prediction,
|
prediction = prediction,
|
||||||
historyRamSizeLog2 = historyRamSizeLog2,
|
historyRamSizeLog2 = historyRamSizeLog2,
|
||||||
injectorStage = !config.twoCycleCache || injectorStage){
|
injectorStage = !config.twoCycleCache || injectorStage){
|
||||||
import config._
|
import config._
|
||||||
|
|
||||||
|
|
||||||
var iBus : InstructionCacheMemBus = null
|
var iBus : InstructionCacheMemBus = null
|
||||||
var mmuBus : MemoryTranslatorBus = null
|
var mmuBus : MemoryTranslatorBus = null
|
||||||
var privilegeService : PrivilegeService = null
|
var privilegeService : PrivilegeService = null
|
||||||
|
@ -100,17 +100,19 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
iBus <> cache.io.mem
|
iBus <> cache.io.mem
|
||||||
iBus.cmd.address.allowOverride := cache.io.mem.cmd.address // - debugAddressOffset
|
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
|
//Connect prefetch cache side
|
||||||
cache.io.cpu.prefetch.isValid := fetchPc.output.valid
|
cache.io.cpu.prefetch.isValid := stages(0).input.valid
|
||||||
cache.io.cpu.prefetch.pc := fetchPc.output.payload
|
cache.io.cpu.prefetch.pc := stages(0).input.payload
|
||||||
iBusRsp.input << fetchPc.output.haltWhen(cache.io.cpu.prefetch.haltIt)
|
stages(0).halt setWhen(cache.io.cpu.prefetch.haltIt)
|
||||||
|
|
||||||
|
|
||||||
cache.io.cpu.fetch.isRemoved := flush
|
cache.io.cpu.fetch.isRemoved := flush
|
||||||
val iBusRspOutputHalt = False
|
val iBusRspOutputHalt = False
|
||||||
if (mmuBus != null) {
|
if (mmuBus != null) {
|
||||||
cache.io.cpu.fetch.mmuBus <> mmuBus
|
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 {
|
} else {
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress
|
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
||||||
|
@ -123,15 +125,15 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Connect fetch cache side
|
//Connect fetch cache side
|
||||||
cache.io.cpu.fetch.isValid := iBusRsp.inputPipeline(0).valid
|
cache.io.cpu.fetch.isValid := stages(1).input.valid
|
||||||
cache.io.cpu.fetch.isStuck := !iBusRsp.inputPipeline(0).ready
|
cache.io.cpu.fetch.isStuck := !stages(1).input.ready
|
||||||
cache.io.cpu.fetch.pc := iBusRsp.inputPipeline(0).payload
|
cache.io.cpu.fetch.pc := stages(1).input.payload
|
||||||
|
|
||||||
|
|
||||||
if(twoCycleCache){
|
if(twoCycleCache){
|
||||||
cache.io.cpu.decode.isValid := iBusRsp.inputPipeline(1).valid
|
cache.io.cpu.decode.isValid := stages(2).input.valid
|
||||||
cache.io.cpu.decode.isStuck := !iBusRsp.inputPipeline(1).ready
|
cache.io.cpu.decode.isStuck := !stages(2).input.ready
|
||||||
cache.io.cpu.decode.pc := iBusRsp.inputPipeline(1).payload
|
cache.io.cpu.decode.pc := stages(2).input.payload
|
||||||
cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
|
cache.io.cpu.decode.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
|
||||||
|
|
||||||
if((!twoCycleRam || wayCount == 1) && !compressedGen && !injectorStage){
|
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 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 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
|
var issueDetected = False
|
||||||
val redoFetch = False //RegNext(False) init(False)
|
val redoFetch = False //RegNext(False) init(False)
|
||||||
when(cacheRsp.isValid && cacheRsp.cacheMiss && !issueDetected){
|
when(cacheRsp.isValid && cacheRsp.cacheMiss && !issueDetected){
|
||||||
|
@ -174,49 +176,12 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheRspArbitration.halt setWhen(issueDetected || iBusRspOutputHalt)
|
||||||
iBusRsp.output.arbitrationFrom(cacheRspArbitration.haltWhen(issueDetected || iBusRspOutputHalt))
|
iBusRsp.output.arbitrationFrom(cacheRspArbitration.output)
|
||||||
iBusRsp.output.rsp.inst := cacheRsp.data
|
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 {
|
memory plug new Area {
|
||||||
|
|
||||||
|
|
|
@ -159,9 +159,8 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
keepPcPlus4 = keepPcPlus4,
|
keepPcPlus4 = keepPcPlus4,
|
||||||
decodePcGen = compressedGen,
|
decodePcGen = compressedGen,
|
||||||
compressedGen = compressedGen,
|
compressedGen = compressedGen,
|
||||||
cmdToRspStageCount = busLatencyMin,
|
cmdToRspStageCount = busLatencyMin + (if(relaxedPcCalculation) 1 else 0),
|
||||||
injectorReadyCutGen = false,
|
injectorReadyCutGen = false,
|
||||||
relaxedPcCalculation = relaxedPcCalculation,
|
|
||||||
prediction = prediction,
|
prediction = prediction,
|
||||||
historyRamSizeLog2 = historyRamSizeLog2,
|
historyRamSizeLog2 = historyRamSizeLog2,
|
||||||
injectorStage = injectorStage){
|
injectorStage = injectorStage){
|
||||||
|
@ -187,36 +186,49 @@ class IBusSimplePlugin(resetVector : BigInt,
|
||||||
|
|
||||||
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(relaxedBusCmdValid) new Area {
|
||||||
assert(relaxedPcCalculation, "relaxedBusCmdValid can only be used with relaxedPcCalculation")
|
???
|
||||||
def input = fetchPc.output
|
/* def inputStage = iBusRsp.stages(0)
|
||||||
def output = iBusRsp.input
|
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
|
val okBus = pendingCmd =/= pendingMax
|
||||||
iBus.cmd.valid := busFork.valid && okBus
|
iBus.cmd.valid := busFork.valid && okBus
|
||||||
iBus.cmd.pc := busFork.payload(31 downto 2) @@ "00"
|
iBus.cmd.pc := busFork.payload(31 downto 2) @@ "00"
|
||||||
busFork.ready := iBus.cmd.ready && okBus
|
busFork.ready := iBus.cmd.ready && okBus*/
|
||||||
} else new Area {
|
} else new Area {
|
||||||
def input = fetchPc.output
|
def stage = iBusRsp.stages(if(relaxedPcCalculation) 1 else 0)
|
||||||
def output = iBusRsp.input
|
stage.halt setWhen(stage.input.valid && (!iBus.cmd.valid || !iBus.cmd.ready))
|
||||||
|
|
||||||
output << input.continueWhen(iBus.cmd.fire)
|
iBus.cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax
|
||||||
|
iBus.cmd.pc := stage.input.payload(31 downto 2) @@ "00"
|
||||||
iBus.cmd.valid := input.valid && output.ready && pendingCmd =/= pendingMax
|
|
||||||
iBus.cmd.pc := input.payload(31 downto 2) @@ "00"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val rsp = new Area {
|
val rsp = new Area {
|
||||||
import iBusRsp._
|
import iBusRsp._
|
||||||
//Manage flush for iBus transactions in flight
|
//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)
|
discardCounter := (if(relaxedPcCalculation) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount - (if(relaxedPcCalculation) 0 else 0))
|
||||||
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), cmdToRspStageCount + (if(relaxedBusCmdValid) 1 else 0))
|
|
||||||
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
|
||||||
|
|
||||||
val fetchRsp = FetchRsp()
|
val fetchRsp = FetchRsp()
|
||||||
fetchRsp.pc := inputPipeline.last.payload
|
fetchRsp.pc := stages.last.output.payload
|
||||||
fetchRsp.rsp := rspBuffer.io.pop.payload
|
fetchRsp.rsp := rspBuffer.io.pop.payload
|
||||||
fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin
|
fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin
|
||||||
|
|
||||||
|
|
||||||
var issueDetected = False
|
var issueDetected = False
|
||||||
val join = StreamJoin(Seq(inputPipeline.last, rspBuffer.io.pop), fetchRsp)
|
val join = StreamJoin(Seq(stages.last.output, rspBuffer.io.pop), fetchRsp)
|
||||||
inputPipeline.last.ready setWhen(!inputPipeline.last.valid)
|
stages.last.output.ready setWhen(!stages.last.output.valid)
|
||||||
output << join.haltWhen(issueDetected)
|
output << join.haltWhen(issueDetected)
|
||||||
|
|
||||||
if(catchAccessFault){
|
if(catchAccessFault){
|
||||||
|
|
|
@ -522,8 +522,8 @@ class TestIndividualFeatures extends FunSuite {
|
||||||
// val seed = -2412372746600605141l
|
// val seed = -2412372746600605141l
|
||||||
|
|
||||||
|
|
||||||
// val testId = Some(mutable.HashSet[Int](15))
|
// val testId = Some(mutable.HashSet[Int](1,6,11,17,23,24))
|
||||||
// val seed = -8861778219266506530l
|
// val seed = -7309275932954927463l
|
||||||
|
|
||||||
|
|
||||||
val rand = new Random(seed)
|
val rand = new Random(seed)
|
||||||
|
|
Loading…
Reference in New Issue