Add hazard tracking plugin
This commit is contained in:
parent
e58f28bc27
commit
23abdb7f95
|
@ -363,23 +363,87 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
}
|
||||
|
||||
|
||||
//class HazardSimplePlugin extends Plugin[VexRiscv] {
|
||||
// import Riscv._
|
||||
// override def build(pipeline: VexRiscv): Unit = {
|
||||
// import pipeline.config._
|
||||
// import pipeline._
|
||||
// val src0Hazard = False
|
||||
// val src1Hazard = False
|
||||
//
|
||||
//
|
||||
// when(decode.input(INSTRUCTION)(rs1Range) === 0 || !decode.input(SRC1_USE)){
|
||||
// src0Hazard := False
|
||||
// }
|
||||
// when(decode.input(INSTRUCTION)(rs2Range) === 0 || !decode.input(SRC2_USE)){
|
||||
// src1Hazard := False
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWriteBack: Boolean, bypassWriteBackBuffer : Boolean) extends Plugin[VexRiscv] {
|
||||
import Riscv._
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
import pipeline._
|
||||
val src0Hazard = False
|
||||
val src1Hazard = False
|
||||
|
||||
def trackHazardWithStage(stage : Stage,bypassable : Boolean, runtimeBypassable : Stageable[Bool]): Unit ={
|
||||
val runtimeBypassableValue = if(runtimeBypassable != null) stage.input(runtimeBypassable) else True
|
||||
val addr0Match = stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs1Range)
|
||||
val addr1Match = stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs2Range)
|
||||
when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) {
|
||||
if (bypassable) {
|
||||
when(runtimeBypassableValue) {
|
||||
when(addr0Match) {
|
||||
decode.input(REG1) := stage.output(REGFILE_WRITE_DATA)
|
||||
}
|
||||
when(addr1Match) {
|
||||
decode.input(REG2) := stage.output(REGFILE_WRITE_DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
when((Bool(!bypassable) || !runtimeBypassableValue)) {
|
||||
when(addr0Match) {
|
||||
src0Hazard := True
|
||||
}
|
||||
when(addr1Match) {
|
||||
src1Hazard := True
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val writeBackWrites = Flow(cloneable(new Bundle{
|
||||
val address = Bits(5 bits)
|
||||
val data = Bits(32 bits)
|
||||
}))
|
||||
writeBackWrites.valid := writeBack.output(REGFILE_WRITE_VALID) && writeBack.arbitration.isFiring
|
||||
writeBackWrites.address := writeBack.output(INSTRUCTION)(rdRange)
|
||||
writeBackWrites.data := writeBack.output(REGFILE_WRITE_DATA)
|
||||
val writeBackBuffer = writeBackWrites.stage()
|
||||
|
||||
val addr0Match = writeBackBuffer.address === decode.input(INSTRUCTION)(rs1Range)
|
||||
val addr1Match = writeBackBuffer.address === decode.input(INSTRUCTION)(rs2Range)
|
||||
when(writeBackBuffer.valid) {
|
||||
if (bypassWriteBackBuffer) {
|
||||
when(addr0Match) {
|
||||
decode.input(REG1) := writeBackWrites.data
|
||||
}
|
||||
when(addr1Match) {
|
||||
decode.input(REG2) := writeBackWrites.data
|
||||
}
|
||||
} else {
|
||||
when(addr0Match) {
|
||||
src0Hazard := True
|
||||
}
|
||||
when(addr1Match) {
|
||||
src1Hazard := True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trackHazardWithStage(writeBack,bypassWriteBack,null)
|
||||
trackHazardWithStage(memory,bypassMemory,BYPASSABLE_MEMORY_STAGE)
|
||||
trackHazardWithStage(execute,bypassExecute,BYPASSABLE_EXECUTE_STAGE)
|
||||
|
||||
|
||||
when(decode.input(INSTRUCTION)(rs1Range) === 0 || !decode.input(SRC1_USE)){
|
||||
src0Hazard := False
|
||||
}
|
||||
when(decode.input(INSTRUCTION)(rs2Range) === 0 || !decode.input(SRC2_USE)){
|
||||
src1Hazard := False
|
||||
}
|
||||
|
||||
when(src0Hazard || src1Hazard){
|
||||
decode.arbitration.haltIt := True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait RegFileReadKind
|
||||
object ASYNC extends RegFileReadKind
|
||||
|
@ -641,7 +705,7 @@ object TopLevel {
|
|||
new SrcPlugin,
|
||||
new FullBarrielShifterPlugin,
|
||||
new DBusSimplePlugin,
|
||||
new HazardSimplePlugin,
|
||||
new HazardSimplePlugin(true,true,true,true),
|
||||
new OutputAluResult
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue