Skip to content

Commit 0d602a6

Browse files
committed
Wr Enable Implemented and Passed through Stages - Unwated Reg update after Branch error mitigated
1 parent fafe969 commit 0d602a6

7 files changed

Lines changed: 40 additions & 11 deletions

File tree

03_RV32I-pipeline/src/main/scala/EXbarrier.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,28 @@ class EXBarrier extends Module {
3838
val inAluResult = Input(UInt(32.W))
3939
val inRD = Input(UInt(5.W))
4040
val inXcptInvalid = Input(Bool())
41+
val inWrEn = Input(Bool())
4142

4243
val outAluResult = Output(UInt(32.W))
4344
val outRD = Output(UInt(5.W))
4445
val outXcptInvalid = Output(Bool())
46+
val outWrEn = Output(Bool())
4547
})
4648

4749
val aluResult = RegInit(0.U(32.W))
4850
val rd = RegInit(0.U(5.W))
4951
val xcptInvalid = RegInit(false.B)
52+
val wrEnReg = RegInit(false.B)
5053

5154
aluResult := io.inAluResult
5255
rd := io.inRD
5356
xcptInvalid := io.inXcptInvalid
57+
wrEnReg := io.inWrEn
5458

5559
io.outAluResult := aluResult
5660
io.outRD := rd
5761
io.outXcptInvalid := xcptInvalid
62+
io.outWrEn := wrEnReg
5863
}
5964
//ToDo: Add your implementation according to the specification above here
6065

03_RV32I-pipeline/src/main/scala/FUnit.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class ForwardingUnit extends Module{
1414
val idBarRegFileReq_A = Input(UInt(5.W)) // RegisterRs
1515
val idBarRegFileReq_B = Input(UInt(5.W)) // RegisterRt
1616

17-
val wbStageWrEn = Input(Bool())
18-
// val memBarWrEn = Input(Bool()) // Does not exist currently, write enable is only sent via wb stage to the regFile
17+
val exBarWrEn = Input(Bool()) // NEW: Is the instruction in MEM writing?
18+
val wbStageWrEn = Input(Bool()) // Is the instruction in WB writing? // val memBarWrEn = Input(Bool()) // Does not exist currently, write enable is only sent via wb stage to the regFile
1919
// no mem module in task 3, hence there were no load instr (or store), write enable was always "set"
2020
// Also no branche or jump as of now
2121

@@ -27,7 +27,7 @@ class ForwardingUnit extends Module{
2727
io.regSelect_Rt := 0.U
2828

2929
// EX Hazard
30-
when(io.idBarRegFileReq_A === io.exBarRd && io.idBarRegFileReq_A =/= 0.U) {
30+
when(io.idBarRegFileReq_A === io.exBarRd && io.idBarRegFileReq_A =/= 0.U && io.exBarWrEn) {
3131
io.regSelect_Rs := 1.U
3232
}
3333
// MEM Hazard
@@ -37,7 +37,7 @@ class ForwardingUnit extends Module{
3737
}
3838
}
3939

40-
when(io.idBarRegFileReq_B === io.exBarRd && io.idBarRegFileReq_B =/= 0.U) {
40+
when(io.idBarRegFileReq_B === io.exBarRd && io.idBarRegFileReq_B =/= 0.U && io.exBarWrEn) {
4141
io.regSelect_Rt := 1.U
4242
}
4343
.elsewhen(io.idBarRegFileReq_B === io.memBarRd && io.idBarRegFileReq_B =/= 0.U && io.wbStageWrEn) {

03_RV32I-pipeline/src/main/scala/IDbarrier.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class IDBarrier extends Module {
4848
val inOperandB = Input(UInt(32.W))
4949
val inXcptInvalid = Input(Bool())
5050
val inTargetPC = Input(UInt(32.W))
51+
val inWrEn = Input(Bool())
5152

5253
val outUOP = Output(UInt(7.W))
5354
val outRD = Output(UInt(5.W))
@@ -57,6 +58,7 @@ class IDBarrier extends Module {
5758
val outOperandB = Output(UInt(32.W))
5859
val outXcptInvalid = Output(Bool())
5960
val outTargetPC = Output(UInt(32.W))
61+
val outWrEn = Output(Bool())
6062
})
6163

6264
val uopReg = RegInit(0.U(7.W)) // Assuming 0 is NOP
@@ -67,7 +69,8 @@ class IDBarrier extends Module {
6769
val operandB = RegInit(0.U(32.W))
6870
val xcptInvalid = RegInit(false.B)
6971
val targetPC = RegInit(0.U(32.W))
70-
72+
val wrEnReg = RegInit(false.B)
73+
7174

7275
uopReg := io.inUOP
7376
operandA := io.inOperandA
@@ -77,6 +80,8 @@ class IDBarrier extends Module {
7780
rs2 := io.inrs2
7881
xcptInvalid := io.inXcptInvalid
7982
targetPC := io.inTargetPC // Pass target
83+
wrEnReg := io.inWrEn
84+
8085

8186
io.outUOP := uopReg
8287
io.outOperandA := operandA
@@ -86,7 +91,8 @@ class IDBarrier extends Module {
8691
io.outrs2 := rs2
8792
io.outXcptInvalid := xcptInvalid
8893
io.outTargetPC := targetPC
89-
94+
io.outWrEn := wrEnReg
95+
9096
//RegNext means: "Create a register, feed this input into it, initialize it to this default value, and connect it to this output"
9197
// io.outUOP := RegNext(io.inUOP, 0.U)
9298
// io.outRD := RegNext(io.inRD, 0.U)

03_RV32I-pipeline/src/main/scala/IDstage.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class ID extends Module {
6363

6464
val pcSel = Output(Bool()) // Input for PC selection signal from EX stage (for branch/jump)
6565
val targetPC = Output(UInt(32.W)) // Output for target PC to IF stage for branch/jump
66+
val wr_en = Output(Bool()) //
6667
})
6768

6869
val opcode = io.inst(6, 0) // Extract opcode from instruction
@@ -76,7 +77,6 @@ class ID extends Module {
7677
val immB = Cat(io.inst(31), io.inst(7), io.inst(30, 25), io.inst(11, 8), 0.U(1.W)).asSInt.pad(32).asUInt // Extract immediate for B-type instructions, Bit 0 as it is a multiples of 2 bytes
7778

7879
io.uop := NOP.asUInt // Default to NOP
79-
io.rd_idx := rd // Output destination register index
8080
io.XcptInvalid := true.B // Default to invalid instruction, will be cleared for valid instructions
8181

8282
io.regFileReq_A.addr := rs1 // Set read address for rs1
@@ -93,6 +93,13 @@ class ID extends Module {
9393
Mux(opcode === "b1100111".U, ((io.regFileResp_A.data + immI).asUInt & "hfffffffe".U(32.W)),
9494
Mux(opcode === "b1100011".U, (io.pc + immB), 0.U(32.W)))) // Calculate target PC for JALR and B-type instructions, will be used in IF stage for PC update
9595

96+
// Branches (B-type) and Stores (S-type) do NOT write to registers!
97+
val isBranch = (opcode === "b1100011".U)
98+
// val isStore = (opcode === "b0100011".U) // Not Implemented right now
99+
100+
io.wr_en := !(isBranch) // || isStore)
101+
io.rd_idx := rd // Output destination register index
102+
96103
when(opcode === "b0110011".U) { // R-type instructions
97104
switch(funct3) {
98105
is("b000".U) { // ADD/SUB

03_RV32I-pipeline/src/main/scala/MEMbarrier.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,27 @@ class MEMBarrier extends Module {
3838
val inAluResult = Input(UInt(32.W))
3939
val inRD = Input(UInt(5.W))
4040
val inXcptInvalid = Input(Bool())
41+
val inWrEn = Input(Bool())
4142

4243
val outAluResult = Output(UInt(32.W))
4344
val outRD = Output(UInt(5.W))
4445
val outXcptInvalid = Output(Bool())
46+
val outWrEn = Output(Bool())
4547
})
4648

4749
val aluResult = RegInit(0.U(32.W))
4850
val rd = RegInit(0.U(5.W))
4951
val xcptInvalid = RegInit(false.B)
50-
52+
val wrEnReg = RegInit(false.B)
53+
5154
aluResult := io.inAluResult
5255
rd := io.inRD
5356
xcptInvalid := io.inXcptInvalid
57+
wrEnReg := io.inWrEn
5458

5559
io.outAluResult := aluResult
5660
io.outRD := rd
5761
io.outXcptInvalid := xcptInvalid
62+
io.outWrEn := wrEnReg
5863
}
5964
//ToDo: Add your implementation according to the specification above here

03_RV32I-pipeline/src/main/scala/WBstage.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ class WB extends Module {
4343
val io = IO(new Bundle {
4444
val aluResult = Input(UInt(32.W))
4545
val rd = Input(UInt(5.W))
46+
val inWrEn = Input(Bool())
4647

4748
val regFileReq = Output(new RegFileWriteReq) // Write request to register file
4849
val check_res = Output(UInt(32.W)) // Output for verification and debugging
4950
})
5051

5152
io.regFileReq.addr := io.rd // Set write address to rd
5253
io.regFileReq.data := io.aluResult // Forward aluResult to register file write port
53-
io.regFileReq.wr_en := true.B // Enable write for all R-type and I-type instructions (to be refined with instruction decoding)
54+
io.regFileReq.wr_en := io.inWrEn // Enable write for all R-type and I-type instructions, set in the ID Stage (False only in Branches and Store {not implemented yet})
5455

5556
io.check_res := io.aluResult // Output result for verification and debugging
5657
}

03_RV32I-pipeline/src/main/scala/core.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ class PipelinedRV32Icore (BinaryFile: String) extends Module {
127127
idBarrier.io.inOperandB := idStage.io.operandB
128128
idBarrier.io.inXcptInvalid := idStage.io.XcptInvalid
129129
idBarrier.io.inTargetPC := idStage.io.targetPC
130-
130+
// CRITICAL: If a branch is taken, force wr_en to false so the flushed Ghost instruction doesn't write!
131+
idBarrier.io.inWrEn := Mux(exStage.io.isBranch, false.B, idStage.io.wr_en)
132+
131133
// Connect ID barrier to EX stage
132134
exStage.io.uop := idBarrier.io.outUOP
133135
exStage.io.rd := idBarrier.io.outRD
@@ -139,15 +141,18 @@ class PipelinedRV32Icore (BinaryFile: String) extends Module {
139141
exBarrier.io.inAluResult := exStage.io.aluResult
140142
exBarrier.io.inRD := exStage.io.outRD
141143
exBarrier.io.inXcptInvalid := exStage.io.xcptInvalid
144+
exBarrier.io.inWrEn := idBarrier.io.outWrEn // Pass write enable from ID barrier to EX barrier (critical for correct forwarding behavior and to prevent hazards from writing instructions)
142145

143146
// Connect EX barrier to MEM Barrier
144147
memBarrier.io.inAluResult := exBarrier.io.outAluResult
145148
memBarrier.io.inRD := exBarrier.io.outRD
146149
memBarrier.io.inXcptInvalid := exBarrier.io.outXcptInvalid
150+
memBarrier.io.inWrEn := exBarrier.io.outWrEn // Pass write enable from EX barrier to MEM barrier (critical for correct forwarding behavior and to prevent hazards from writing instructions)
147151

148152
// Connect MEM barrier to WB Stage
149153
wbStage.io.aluResult := memBarrier.io.outAluResult
150154
wbStage.io.rd := memBarrier.io.outRD
155+
wbStage.io.inWrEn := memBarrier.io.outWrEn // Pass write enable from MEM barrier to WB stage (critical for correct forwarding behavior and to prevent hazards from writing instructions)
151156

152157
// Connect WB stage & MEM barrier to WB barrier
153158
wbBarrier.io.inCheckRes := wbStage.io.check_res
@@ -163,5 +168,5 @@ class PipelinedRV32Icore (BinaryFile: String) extends Module {
163168
fUnit.io.idBarRegFileReq_A := idBarrier.io.outrs1
164169
fUnit.io.idBarRegFileReq_B := idBarrier.io.outrs2
165170
fUnit.io.wbStageWrEn := wbStage.io.regFileReq.wr_en
166-
171+
fUnit.io.exBarWrEn := exBarrier.io.outWrEn // Check if the instruction in EX stage is writing (coming out of EX Barrier)
167172
}

0 commit comments

Comments
 (0)