Add pessimistic harzard options
Add separated add/sum option in srcPlugin
This commit is contained in:
parent
acb85a1fb8
commit
2b24cbc8e1
|
@ -5,7 +5,13 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
|
||||
|
||||
class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWriteBack: Boolean, bypassWriteBackBuffer : Boolean) extends Plugin[VexRiscv] {
|
||||
class HazardSimplePlugin(bypassExecute : Boolean,
|
||||
bypassMemory: Boolean,
|
||||
bypassWriteBack: Boolean,
|
||||
bypassWriteBackBuffer : Boolean,
|
||||
pessimisticUseSrc : Boolean = false,
|
||||
pessimisticWriteRegFile : Boolean = false,
|
||||
pessimisticAddressMatch : Boolean = false) extends Plugin[VexRiscv] {
|
||||
import Riscv._
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
|
@ -15,8 +21,8 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
|
|||
|
||||
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)
|
||||
val addr0Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs1Range)
|
||||
val addr1Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs2Range)
|
||||
when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) {
|
||||
if (bypassable) {
|
||||
when(runtimeBypassableValue) {
|
||||
|
@ -28,6 +34,8 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
when(stage.arbitration.isValid && (if(pessimisticWriteRegFile) True else stage.input(REGFILE_WRITE_VALID))) {
|
||||
when((Bool(!bypassable) || !runtimeBypassableValue)) {
|
||||
when(addr0Match) {
|
||||
src0Hazard := True
|
||||
|
@ -49,8 +57,8 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
|
|||
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)
|
||||
val addr0Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === decode.input(INSTRUCTION)(rs1Range)
|
||||
val addr1Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === decode.input(INSTRUCTION)(rs2Range)
|
||||
when(writeBackBuffer.valid) {
|
||||
if (bypassWriteBackBuffer) {
|
||||
when(addr0Match) {
|
||||
|
@ -74,10 +82,10 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
|
|||
trackHazardWithStage(execute ,bypassExecute ,BYPASSABLE_EXECUTE_STAGE)
|
||||
|
||||
|
||||
when(decode.input(INSTRUCTION)(rs1Range) === 0 || !decode.input(REG1_USE)){
|
||||
when(decode.input(INSTRUCTION)(rs1Range) === 0 || (if(pessimisticUseSrc) False else !decode.input(REG1_USE))){
|
||||
src0Hazard := False
|
||||
}
|
||||
when(decode.input(INSTRUCTION)(rs2Range) === 0 || !decode.input(REG2_USE)){
|
||||
when(decode.input(INSTRUCTION)(rs2Range) === 0 || (if(pessimisticUseSrc) False else !decode.input(REG2_USE))){
|
||||
src1Hazard := False
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import SpinalRiscv.{Riscv, VexRiscv}
|
|||
import spinal.core._
|
||||
|
||||
|
||||
class SrcPlugin extends Plugin[VexRiscv]{
|
||||
class SrcPlugin(separatedAddSub : Boolean) extends Plugin[VexRiscv]{
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
@ -28,6 +28,22 @@ class SrcPlugin extends Plugin[VexRiscv]{
|
|||
)
|
||||
}
|
||||
|
||||
if(separatedAddSub) {
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
// ADD, SUB
|
||||
val add = (input(SRC1).asUInt + input(SRC2).asUInt).asBits
|
||||
val sub = (input(SRC1).asUInt - input(SRC2).asUInt).asBits
|
||||
|
||||
// SLT, SLTU
|
||||
val less = Mux(input(SRC1).msb === input(SRC2).msb, sub.msb,
|
||||
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb))
|
||||
|
||||
insert(SRC_ADD_SUB) := input(SRC_USE_SUB_LESS) ? sub | add
|
||||
insert(SRC_LESS) := less
|
||||
}
|
||||
}else{
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
|
@ -38,8 +54,9 @@ class SrcPlugin extends Plugin[VexRiscv]{
|
|||
val less = Mux(input(SRC1).msb === input(SRC2).msb, addSub.msb,
|
||||
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb))
|
||||
|
||||
insert(SRC_ADD_SUB) := addSub.resized
|
||||
insert(SRC_ADD_SUB) := addSub
|
||||
insert(SRC_LESS) := less
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,10 +118,20 @@ object TopLevel {
|
|||
zeroBoot = true
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false
|
||||
),
|
||||
new FullBarrielShifterPlugin,
|
||||
// new LightShifterPlugin,
|
||||
new HazardSimplePlugin(true, true, true, true),
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
// new HazardSimplePlugin(false, false, false, false),
|
||||
new MulPlugin,
|
||||
|
@ -153,16 +163,76 @@ object TopLevel {
|
|||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.SYNC,
|
||||
regFileReadyKind = Plugin.ASYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false
|
||||
),
|
||||
// new FullBarrielShifterPlugin,
|
||||
new LightShifterPlugin,
|
||||
// new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
new HazardSimplePlugin(false, false, false, false),
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = false,
|
||||
bypassMemory = false,
|
||||
bypassWriteBack = false,
|
||||
bypassWriteBackBuffer = false,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
// new MulPlugin,
|
||||
// new DivPlugin,
|
||||
// new MachineCsr(csrConfig),
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
catchAddressMisaligned = false,
|
||||
prediction = NONE
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
val configTest = VexRiscvConfig(
|
||||
pcWidth = 32
|
||||
)
|
||||
|
||||
configTest.plugins ++= List(
|
||||
new PcManagerSimplePlugin(0x00000000l, false),
|
||||
new IBusSimplePlugin(
|
||||
interfaceKeepData = true,
|
||||
catchAccessFault = false
|
||||
),
|
||||
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = false,
|
||||
catchAccessFault = false
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.ASYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false
|
||||
),
|
||||
new FullBarrielShifterPlugin,
|
||||
// new LightShifterPlugin,
|
||||
// new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
// new MulPlugin,
|
||||
// new DivPlugin,
|
||||
// new MachineCsr(csrConfig),
|
||||
|
@ -175,6 +245,7 @@ object TopLevel {
|
|||
|
||||
val toplevel = new VexRiscv(configFull)
|
||||
// val toplevel = new VexRiscv(configLight)
|
||||
// val toplevel = new VexRiscv(configTest)
|
||||
toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute("verilator public")
|
||||
toplevel.decode.input(toplevel.config.PC).addAttribute("verilator public")
|
||||
toplevel.decode.arbitration.isValid.addAttribute("verilator public")
|
||||
|
|
|
@ -194,7 +194,7 @@ public:
|
|||
|
||||
|
||||
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) {
|
||||
assert(addr % 4 == 0);
|
||||
assertEq(addr % 4, 0);
|
||||
*data = ( (mem[addr + 0] << 0)
|
||||
| (mem[addr + 1] << 8)
|
||||
| (mem[addr + 2] << 16)
|
||||
|
@ -202,6 +202,7 @@ public:
|
|||
*error = addr == 0xF00FFF60u;
|
||||
}
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
assertEq(addr % (1 << size), 0);
|
||||
*error = addr == 0xF00FFF60u;
|
||||
if(wr){
|
||||
memTraces <<
|
||||
|
|
Loading…
Reference in New Issue