mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-04-24 05:57:07 -04:00
Reduce area with reg[0] optimisation
This commit is contained in:
parent
fc1bb7249a
commit
88dee6d2bc
11 changed files with 3682 additions and 26 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
57
src/test/cpp/testA/dhrystoneO3.logRef
Normal file
57
src/test/cpp/testA/dhrystoneO3.logRef
Normal 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
|
|
@ -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);
|
||||
|
|
3584
src/test/resources/hex/dhrystoneO3.hex
Normal file
3584
src/test/resources/hex/dhrystoneO3.hex
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue