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._
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
}

View File

@ -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,18 +28,35 @@ class SrcPlugin extends Plugin[VexRiscv]{
)
}
execute plug new Area{
import execute._
if(separatedAddSub) {
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
// 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, addSub.msb,
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb))
// 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) := addSub.resized
insert(SRC_LESS) := less
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
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
insert(SRC_LESS) := less
}
}
}
}

View File

@ -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,26 @@ 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),
@ -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(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")

View File

@ -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 <<