Add pessimistic harzard options

Add separated add/sum option in srcPlugin
This commit is contained in:
Charles Papon 2017-04-04 00:25:39 +02:00
parent acb85a1fb8
commit 2b24cbc8e1
4 changed files with 120 additions and 23 deletions

View File

@ -5,7 +5,13 @@ import spinal.core._
import spinal.lib._ 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._ import Riscv._
override def build(pipeline: VexRiscv): Unit = { override def build(pipeline: VexRiscv): Unit = {
import pipeline._ import pipeline._
@ -15,8 +21,8 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
def trackHazardWithStage(stage : Stage,bypassable : Boolean, runtimeBypassable : Stageable[Bool]): Unit ={ def trackHazardWithStage(stage : Stage,bypassable : Boolean, runtimeBypassable : Stageable[Bool]): Unit ={
val runtimeBypassableValue = if(runtimeBypassable != null) stage.input(runtimeBypassable) else True val runtimeBypassableValue = if(runtimeBypassable != null) stage.input(runtimeBypassable) else True
val addr0Match = stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs1Range) val addr0Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs1Range)
val addr1Match = stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs2Range) val addr1Match = if(pessimisticAddressMatch) True else stage.input(INSTRUCTION)(rdRange) === decode.input(INSTRUCTION)(rs2Range)
when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) { when(stage.arbitration.isValid && stage.input(REGFILE_WRITE_VALID)) {
if (bypassable) { if (bypassable) {
when(runtimeBypassableValue) { 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((Bool(!bypassable) || !runtimeBypassableValue)) {
when(addr0Match) { when(addr0Match) {
src0Hazard := True src0Hazard := True
@ -49,8 +57,8 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
writeBackWrites.data := writeBack.output(REGFILE_WRITE_DATA) writeBackWrites.data := writeBack.output(REGFILE_WRITE_DATA)
val writeBackBuffer = writeBackWrites.stage() val writeBackBuffer = writeBackWrites.stage()
val addr0Match = writeBackBuffer.address === decode.input(INSTRUCTION)(rs1Range) val addr0Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === decode.input(INSTRUCTION)(rs1Range)
val addr1Match = writeBackBuffer.address === decode.input(INSTRUCTION)(rs2Range) val addr1Match = if(pessimisticAddressMatch) True else writeBackBuffer.address === decode.input(INSTRUCTION)(rs2Range)
when(writeBackBuffer.valid) { when(writeBackBuffer.valid) {
if (bypassWriteBackBuffer) { if (bypassWriteBackBuffer) {
when(addr0Match) { when(addr0Match) {
@ -74,10 +82,10 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
trackHazardWithStage(execute ,bypassExecute ,BYPASSABLE_EXECUTE_STAGE) 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 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 src1Hazard := False
} }

View File

@ -4,7 +4,7 @@ import SpinalRiscv.{Riscv, VexRiscv}
import spinal.core._ import spinal.core._
class SrcPlugin extends Plugin[VexRiscv]{ class SrcPlugin(separatedAddSub : Boolean) extends Plugin[VexRiscv]{
override def build(pipeline: VexRiscv): Unit = { override def build(pipeline: VexRiscv): Unit = {
import pipeline._ import pipeline._
import pipeline.config._ import pipeline.config._
@ -28,18 +28,35 @@ class SrcPlugin extends Plugin[VexRiscv]{
) )
} }
execute plug new Area{ if(separatedAddSub) {
execute plug new Area {
import execute._ import execute._
// ADD, SUB // ADD, SUB
val addSub = (input(SRC1).asSInt + Mux(input(SRC_USE_SUB_LESS), ~input(SRC2), input(SRC2)).asSInt + Mux(input(SRC_USE_SUB_LESS),S(1),S(0))).asBits 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._
// ADD, SUB
val addSub = (input(SRC1).asSInt + Mux(input(SRC_USE_SUB_LESS), ~input(SRC2), input(SRC2)).asSInt + Mux(input(SRC_USE_SUB_LESS), S(1), S(0))).asBits
// SLT, SLTU // SLT, SLTU
val less = Mux(input(SRC1).msb === input(SRC2).msb, addSub.msb, val less = Mux(input(SRC1).msb === input(SRC2).msb, addSub.msb,
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).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 insert(SRC_LESS) := less
} }
} }
}
} }

View File

@ -118,10 +118,20 @@ object TopLevel {
zeroBoot = true zeroBoot = true
), ),
new IntAluPlugin, new IntAluPlugin,
new SrcPlugin, new SrcPlugin(
separatedAddSub = false
),
new FullBarrielShifterPlugin, new FullBarrielShifterPlugin,
// new LightShifterPlugin, // 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, true, false, true),
// new HazardSimplePlugin(false, false, false, false), // new HazardSimplePlugin(false, false, false, false),
new MulPlugin, new MulPlugin,
@ -153,16 +163,26 @@ object TopLevel {
catchIllegalInstruction = false catchIllegalInstruction = false
), ),
new RegFilePlugin( new RegFilePlugin(
regFileReadyKind = Plugin.SYNC, regFileReadyKind = Plugin.ASYNC,
zeroBoot = false zeroBoot = false
), ),
new IntAluPlugin, new IntAluPlugin,
new SrcPlugin, new SrcPlugin(
separatedAddSub = false
),
// new FullBarrielShifterPlugin, // new FullBarrielShifterPlugin,
new LightShifterPlugin, new LightShifterPlugin,
// new HazardSimplePlugin(true, true, true, true), // new HazardSimplePlugin(true, true, true, true),
// new HazardSimplePlugin(false, true, false, 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 MulPlugin,
// new DivPlugin, // new DivPlugin,
// new MachineCsr(csrConfig), // new MachineCsr(csrConfig),
@ -173,8 +193,59 @@ object TopLevel {
) )
) )
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),
new BranchPlugin(
earlyBranch = false,
catchAddressMisaligned = false,
prediction = NONE
)
)
val toplevel = new VexRiscv(configFull) val toplevel = new VexRiscv(configFull)
// val toplevel = new VexRiscv(configLight) // val toplevel = new VexRiscv(configLight)
// val toplevel = new VexRiscv(configTest)
toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute("verilator public") toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute("verilator public")
toplevel.decode.input(toplevel.config.PC).addAttribute("verilator public") toplevel.decode.input(toplevel.config.PC).addAttribute("verilator public")
toplevel.decode.arbitration.isValid.addAttribute("verilator public") toplevel.decode.arbitration.isValid.addAttribute("verilator public")

View File

@ -194,7 +194,7 @@ public:
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) { virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) {
assert(addr % 4 == 0); assertEq(addr % 4, 0);
*data = ( (mem[addr + 0] << 0) *data = ( (mem[addr + 0] << 0)
| (mem[addr + 1] << 8) | (mem[addr + 1] << 8)
| (mem[addr + 2] << 16) | (mem[addr + 2] << 16)
@ -202,6 +202,7 @@ public:
*error = addr == 0xF00FFF60u; *error = addr == 0xF00FFF60u;
} }
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { 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; *error = addr == 0xF00FFF60u;
if(wr){ if(wr){
memTraces << memTraces <<