MulPlugin fix buffer interraction with partial regfile bypass

This commit is contained in:
Dolu1990 2021-02-17 11:35:17 +01:00
parent 8b2a2afb6f
commit 06b7a91de4
2 changed files with 61 additions and 59 deletions

View File

@ -31,29 +31,62 @@ class HazardSimplePlugin(bypassExecute : Boolean = false,
override def build(pipeline: VexRiscv): Unit = { override def build(pipeline: VexRiscv): Unit = {
import pipeline._ import pipeline._
import pipeline.config._ import pipeline.config._
val src0Hazard = False
val src1Hazard = False
val readStage = service(classOf[RegFileService]).readStage() pipeline plug new Area {
val src0Hazard = False
val src1Hazard = False
def trackHazardWithStage(stage : Stage,bypassable : Boolean, runtimeBypassable : Stageable[Bool]): Unit ={ val readStage = service(classOf[RegFileService]).readStage()
val runtimeBypassableValue = if(runtimeBypassable != null) stage.input(runtimeBypassable) else True
val addr0Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs1Range) def trackHazardWithStage(stage: Stage, bypassable: Boolean, runtimeBypassable: Stageable[Bool]): Unit = {
val addr1Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs2Range) val runtimeBypassableValue = if (runtimeBypassable != null) stage.input(runtimeBypassable) else True
when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) { val addr0Match = if (pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs1Range)
if (bypassable) { val addr1Match = if (pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === readStage.input(INSTRUCTION)(rs2Range)
when(runtimeBypassableValue) { when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) {
if (bypassable) {
when(runtimeBypassableValue) {
when(addr0Match) {
readStage.input(RS1) := stage.output(REGFILE_WRITE_DATA)
}
when(addr1Match) {
readStage.input(RS2) := stage.output(REGFILE_WRITE_DATA)
}
}
}
}
when(stage.arbitration.isValid && (if (pessimisticWriteRegFile) True else stage.input(REGFILE_WRITE_VALID))) {
when((Bool(!bypassable) || !runtimeBypassableValue)) {
when(addr0Match) { when(addr0Match) {
readStage.input(RS1) := stage.output(REGFILE_WRITE_DATA) src0Hazard := True
} }
when(addr1Match) { when(addr1Match) {
readStage.input(RS2) := stage.output(REGFILE_WRITE_DATA) src1Hazard := True
} }
} }
} }
} }
when(stage.arbitration.isValid && (if(pessimisticWriteRegFile) True else stage.input(REGFILE_WRITE_VALID))) {
when((Bool(!bypassable) || !runtimeBypassableValue)) {
val writeBackWrites = Flow(cloneable(new Bundle {
val address = Bits(5 bits)
val data = Bits(32 bits)
}))
writeBackWrites.valid := stages.last.output(REGFILE_WRITE_VALID) && stages.last.arbitration.isFiring
writeBackWrites.address := stages.last.output(INSTRUCTION)(rdRange)
writeBackWrites.data := stages.last.output(REGFILE_WRITE_DATA)
val writeBackBuffer = writeBackWrites.stage()
val addr0Match = if (pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs1Range)
val addr1Match = if (pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs2Range)
when(writeBackBuffer.valid) {
if (bypassWriteBackBuffer) {
when(addr0Match) {
readStage.input(RS1) := writeBackBuffer.data
}
when(addr1Match) {
readStage.input(RS2) := writeBackBuffer.data
}
} else {
when(addr0Match) { when(addr0Match) {
src0Hazard := True src0Hazard := True
} }
@ -62,54 +95,24 @@ class HazardSimplePlugin(bypassExecute : Boolean = false,
} }
} }
} }
}
if (withWriteBackStage) trackHazardWithStage(writeBack, bypassWriteBack, null)
if (withMemoryStage) trackHazardWithStage(memory, bypassMemory, if (stages.last == memory) null else BYPASSABLE_MEMORY_STAGE)
if (readStage != execute) trackHazardWithStage(execute, bypassExecute, if (stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE)
val writeBackWrites = Flow(cloneable(new Bundle{ if (!pessimisticUseSrc) {
val address = Bits(5 bits) when(!readStage.input(RS1_USE)) {
val data = Bits(32 bits) src0Hazard := False
}))
writeBackWrites.valid := stages.last.output(REGFILE_WRITE_VALID) && stages.last.arbitration.isFiring
writeBackWrites.address := stages.last.output(INSTRUCTION)(rdRange)
writeBackWrites.data := stages.last.output(REGFILE_WRITE_DATA)
val writeBackBuffer = writeBackWrites.stage()
val addr0Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs1Range)
val addr1Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === readStage.input(INSTRUCTION)(rs2Range)
when(writeBackBuffer.valid) {
if (bypassWriteBackBuffer) {
when(addr0Match) {
readStage.input(RS1) := writeBackBuffer.data
} }
when(addr1Match) { when(!readStage.input(RS2_USE)) {
readStage.input(RS2) := writeBackBuffer.data src1Hazard := False
}
} else {
when(addr0Match) {
src0Hazard := True
}
when(addr1Match) {
src1Hazard := True
} }
} }
}
if(withWriteBackStage) trackHazardWithStage(writeBack,bypassWriteBack,null) when(readStage.arbitration.isValid && (src0Hazard || src1Hazard)) {
if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory, if(stages.last == memory) null else BYPASSABLE_MEMORY_STAGE) readStage.arbitration.haltByOther := True
if(readStage != execute) trackHazardWithStage(execute ,bypassExecute , if(stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE)
if(!pessimisticUseSrc) {
when(!readStage.input(RS1_USE)) {
src0Hazard := False
} }
when(!readStage.input(RS2_USE)) {
src1Hazard := False
}
}
when(readStage.arbitration.isValid && (src0Hazard || src1Hazard)){
readStage.arbitration.haltByOther := True
} }
} }
} }

View File

@ -61,10 +61,9 @@ class MulPlugin(var inputBuffer : Boolean = false,
when(arbitration.isValid && input(IS_MUL) && counter =/= delay){ when(arbitration.isValid && input(IS_MUL) && counter =/= delay){
arbitration.haltItself := True arbitration.haltItself := True
} }
when(!arbitration.isStuckByOthers){
counter := counter + 1 counter := counter + 1
} when(!arbitration.isStuck || arbitration.isStuckByOthers){
when(!arbitration.isStuck){
counter := 0 counter := 0
} }
} }