Reduce area with reg[0] optimisation

This commit is contained in:
Charles Papon 2017-03-18 19:32:54 +01:00
parent fc1bb7249a
commit 88dee6d2bc
11 changed files with 3682 additions and 26 deletions

View file

@ -121,7 +121,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
default -> rspShifted //W
)
when(input(MEMORY_ENABLE)) {
when(arbitration.isValid && input(MEMORY_ENABLE)) {
input(REGFILE_WRITE_DATA) := rspFormated
}

View file

@ -13,11 +13,6 @@ class HazardSimplePlugin(bypassExecute : Boolean,bypassMemory: Boolean,bypassWri
val src0Hazard = False
val src1Hazard = False
//Disable rd0 write in decoding stage
when(decode.input(INSTRUCTION)(rdRange) === 0) {
decode.input(REGFILE_WRITE_VALID) := 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)

View file

@ -89,7 +89,7 @@ class MulPlugin extends Plugin[VexRiscv]{
val result = input(MUL_LOW) + (input(MUL_HH) << 32)
when(input(IS_MUL)){
when(arbitration.isValid && input(IS_MUL)){
switch(input(INSTRUCTION)(13 downto 12)){
is(B"00"){
input(REGFILE_WRITE_DATA) := input(MUL_LOW)(31 downto 0).asBits

View file

@ -5,8 +5,12 @@ import SpinalRiscv._
import spinal.core._
import spinal.lib._
trait BranchPrediction
object DISABLE extends BranchPrediction
object STATIC extends BranchPrediction
object DYNAMIC extends BranchPrediction
class NoPredictionBranchPlugin(earlyBranch : Boolean) extends Plugin[VexRiscv]{
class NoPredictionBranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction) extends Plugin[VexRiscv]{
object BranchCtrlEnum extends SpinalEnum(binarySequential){
val INC,B,JAL,JALR = newElement()
}
@ -79,11 +83,13 @@ class NoPredictionBranchPlugin(earlyBranch : Boolean) extends Plugin[VexRiscv]{
)
val imm = IMM(input(INSTRUCTION))
insert(BRANCH_CALC) := input(BRANCH_SOLVED).mux(
BranchCtrlEnum.JAL -> (input(PC) + imm.j_sext.asUInt),
BranchCtrlEnum.JALR -> (input(REG1).asUInt + imm.i_sext.asUInt),
default -> (input(PC) + imm.b_sext.asUInt) //B
)
val branch_src1 = (input(BRANCH_CTRL) === BranchCtrlEnum.JALR) ? input(REG1).asUInt | input(PC)
val branch_src2 = input(BRANCH_CTRL).mux(
BranchCtrlEnum.JAL -> imm.j_sext,
BranchCtrlEnum.JALR -> imm.i_sext,
default -> imm.b_sext //B
).asUInt
insert(BRANCH_CALC) := branch_src1 + branch_src2
}
val branchStage = if(earlyBranch) execute else memory

View file

@ -1,6 +1,6 @@
package SpinalRiscv.Plugin
import SpinalRiscv.{DecoderService, Riscv, VexRiscv}
import SpinalRiscv.{Stageable, DecoderService, Riscv, VexRiscv}
import spinal.core._
import spinal.lib._
@ -30,6 +30,11 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
decode plug new Area{
import decode._
//Disable rd0 write in decoding stage
when(decode.input(INSTRUCTION)(rdRange) === 0) {
decode.input(REGFILE_WRITE_VALID) := False
}
val rs1 = input(INSTRUCTION)(Riscv.rs1Range).asUInt
val rs2 = input(INSTRUCTION)(Riscv.rs2Range).asUInt
@ -47,8 +52,8 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
case `SYNC` => (global.regFile.readSync(regFileReadAddress1),global.regFile.readSync(regFileReadAddress2))
}
insert(REG1) := Mux(rs1 =/= 0, rs1Data, B(0, 32 bit))
insert(REG2) := Mux(rs2 =/= 0, rs2Data, B(0, 32 bit))
insert(REG1) := rs1Data
insert(REG2) := rs2Data
}
writeBack plug new Area {
@ -58,6 +63,11 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
regFileWrite.valid := input(REGFILE_WRITE_VALID) && arbitration.isFiring
regFileWrite.address := input(INSTRUCTION)(rdRange).asUInt
regFileWrite.data := input(REGFILE_WRITE_DATA)
//CPU will write constant register zero in the first cycle
regFileWrite.valid setWhen(RegNext(False) init(True))
inputInit[Bits](REGFILE_WRITE_DATA, 0)
inputInit[Bits](INSTRUCTION, 0)
}
}
}

View file

@ -61,6 +61,9 @@ class Stage() extends Area{
val inputsDefault = mutable.HashMap[Stageable[Data],Data]()
val outputsDefault = mutable.HashMap[Stageable[Data],Data]()
def inputInit[T <: BaseType](stageable : Stageable[T],initValue : T) =
Component.current.addPrePopTask(() => inputsDefault(stageable.asInstanceOf[Stageable[Data]]).asInstanceOf[T].getDrivingReg.init(initValue))
}

View file

@ -37,15 +37,15 @@ object TopLevel {
new RegFilePlugin(Plugin.SYNC),
new IntAluPlugin,
new SrcPlugin,
new FullBarrielShifterPlugin,
// new LightShifterPlugin,
// new FullBarrielShifterPlugin,
new LightShifterPlugin,
new DBusSimplePlugin,
new HazardSimplePlugin(false, true, false, true),
// new HazardSimplePlugin(false, true, false, true),
// new HazardSimplePlugin(true, true, true, true),
// new HazardSimplePlugin(false, false, false, false),
new HazardSimplePlugin(false, false, false, false),
new MulPlugin,
new DivPlugin,
new NoPredictionBranchPlugin(false)
new NoPredictionBranchPlugin(false, DISABLE)
)
val toplevel = new VexRiscv(config)

View file

@ -0,0 +1,57 @@
Dhrystone Benchmark, Version 2.1 (Language: C)
Program compiled without 'register' attribute
Please give the number of runs through the benchmark:
Execution starts, 200 runs through Dhrystone
Execution ends
Final values of the variables used in the benchmark:
Int_Glob: 5
should be: 5
Bool_Glob: 1
should be: 1
Ch_1_Glob: A
should be: A
Ch_2_Glob: B
should be: B
Arr_1_Glob[8]: 7
should be: 7
Arr_2_Glob[8][7]: 210
should be: Number_Of_Runs + 10
Ptr_Glob->
Ptr_Comp: 1073809016
should be: (implementation-dependent)
Discr: 0
should be: 0
Enum_Comp: 2
should be: 2
Int_Comp: 17
should be: 17
Str_Comp: DHRYSTONE PROGRAM, SOME STRING
should be: DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
Ptr_Comp: 1073809016
should be: (implementation-dependent), same as above
Discr: 0
should be: 0
Enum_Comp: 1
should be: 1
Int_Comp: 18
should be: 18
Str_Comp: DHRYSTONE PROGRAM, SOME STRING
should be: DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc: 5
should be: 5
Int_2_Loc: 13
should be: 13
Int_3_Loc: 7
should be: 7
Enum_Loc: 1
should be: 1
Str_1_Loc: DHRYSTONE PROGRAM, 1'ST STRING
should be: DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING
should be: DHRYSTONE PROGRAM, 2'ND STRING

View file

@ -371,8 +371,8 @@ public:
class Dhrystone : public Workspace{
public:
Dhrystone() : Workspace("Dhrystone") {
loadHex("../../resources/hex/dhrystoneO3M.hex");
Dhrystone(string name) : Workspace(name) {
loadHex("../../resources/hex/" + name + ".hex");
}
virtual void checks(){
@ -380,7 +380,7 @@ public:
}
virtual void pass(){
FILE *refFile = fopen("Dhrystone.logRef", "r");
FILE *refFile = fopen((name + ".logRef").c_str(), "r");
fseek(refFile, 0, SEEK_END);
uint32_t refSize = ftell(refFile);
fseek(refFile, 0, SEEK_SET);
@ -389,7 +389,7 @@ public:
logTraces.flush();
FILE *logFile = fopen("Dhrystone.logTrace", "r");
FILE *logFile = fopen((name + ".logTrace").c_str(), "r");
fseek(logFile, 0, SEEK_END);
uint32_t logSize = ftell(logFile);
fseek(logFile, 0, SEEK_SET);
@ -500,7 +500,8 @@ int main(int argc, char **argv, char **env) {
RiscvTest(name).run();
}
#endif
Dhrystone().run(0.8e6);
Dhrystone("dhrystoneO3").run(1e6);
Dhrystone("dhrystoneO3M").run(0.8e6);
}
uint64_t duration = timer_end(startedAt);

File diff suppressed because it is too large Load diff