From 23abdb7f954a5c6f4512c52b4bdcd897d99d894c Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Sat, 11 Mar 2017 16:45:04 +0100 Subject: [PATCH] Add hazard tracking plugin --- src/main/scala/SpinalRiscv/TopLevel.scala | 100 ++++++++++++++++++---- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index 4138b6d..ca35008 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -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 )