Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified 3-pipeline/src/main/resources/hazard_extended.asmbin
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class CPU extends Module {
ctrl.io.rs2_id := id.io.regs_reg2_read_address
ctrl.io.memory_read_enable_ex := id2ex.io.output_memory_read_enable
ctrl.io.rd_ex := id2ex.io.output_regs_write_address
ctrl.io.uses_rs2_id := id.io.uses_rs2_id
ctrl.io.uses_rs1_id := id.io.uses_rs1_id

regs.io.write_enable := mem2wb.io.output_regs_write_enable
regs.io.write_address := mem2wb.io.output_regs_write_address
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class Control extends Module {
val rs2_id = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // id.io.regs_reg2_read_address
val memory_read_enable_ex = Input(Bool()) // id2ex.io.output_memory_read_enable
val rd_ex = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // id2ex.io.output_regs_write_address

val uses_rs1_id = Input(Bool()) // true only if current ID instruction really reads rs1
val uses_rs2_id = Input(Bool()) // true only if current ID instruction really reads rs2
val if_flush = Output(Bool())
val id_flush = Output(Bool())
val pc_stall = Output(Bool())
Expand Down Expand Up @@ -84,7 +85,7 @@ class Control extends Module {
// Detection conditions (ALL must be true):
io.memory_read_enable_ex && // 1. EX stage has load instruction
io.rd_ex =/= 0.U && // 2. Load destination is not x0
(io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id) // 3. ID stage uses load destination
((io.uses_rs1_id && (io.rd_ex === io.rs1_id)) || (io.uses_rs2_id && (io.rd_ex === io.rs2_id))) // 3. ID stage uses load destination
//
// Example triggering this hazard:
// LW x1, 0(x2) [EX stage: memory_read_enable_ex=1, rd_ex=x1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,33 @@ class InstructionDecode extends Module {
val ex_reg_write_address = Output(UInt(Parameters.PhysicalRegisterAddrWidth))
val ex_csr_address = Output(UInt(Parameters.CSRRegisterAddrWidth))
val ex_csr_write_enable = Output(Bool())
val uses_rs1_id = Output(Bool()) // tells Control/Forwarding whether rs1 is valid for this instruction
val uses_rs2_id = Output(Bool()) // tells Control/Forwarding whether rs2 is valid for this instruction
})
val opcode = io.instruction(6, 0)
val funct3 = io.instruction(14, 12)
val funct7 = io.instruction(31, 25)
val rd = io.instruction(11, 7)
val rs1 = io.instruction(19, 15)
val rs2 = io.instruction(24, 20)

io.regs_reg1_read_address := Mux(opcode === Instructions.lui, 0.U(Parameters.PhysicalRegisterAddrWidth), rs1)
io.regs_reg2_read_address := rs2
val uses_rs2 = (opcode === InstructionTypes.RM) ||
(opcode === InstructionTypes.S) ||
(opcode === InstructionTypes.B)

val uses_rs1 = !(opcode === Instructions.jal) &&
!(opcode === Instructions.lui) &&
!(opcode === Instructions.auipc) &&
!(opcode === Instructions.fence) &&
!(opcode === Instructions.csr &&
(funct3 === InstructionsTypeCSR.csrrwi ||
funct3 === InstructionsTypeCSR.csrrsi ||
funct3 === InstructionsTypeCSR.csrrci))

io.uses_rs2_id := uses_rs2
io.uses_rs1_id := uses_rs1

io.regs_reg1_read_address := Mux(uses_rs1, rs1, 0.U(Parameters.PhysicalRegisterAddrWidth))
io.regs_reg2_read_address := Mux(uses_rs2, rs2, 0.U(Parameters.PhysicalRegisterAddrWidth))
io.ex_immediate := MuxLookup(
opcode,
Cat(Fill(20, io.instruction(31)), io.instruction(31, 20))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class CPU extends Module {
ctrl.io.reg_write_enable_ex := id2ex.io.output_regs_write_enable
ctrl.io.rd_mem := ex2mem.io.output_regs_write_address
ctrl.io.reg_write_enable_mem := ex2mem.io.output_regs_write_enable
ctrl.io.uses_rs2_id := id.io.uses_rs2_id
ctrl.io.uses_rs1_id := id.io.uses_rs1_id

regs.io.write_enable := mem2wb.io.output_regs_write_enable
regs.io.write_address := mem2wb.io.output_regs_write_address
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ class Control extends Module {
val rd_ex = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // id2ex.io.output_regs_write_address
val reg_write_enable_ex = Input(Bool()) // id2ex.io.output_regs_write_enable
val rd_mem = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // ex2mem.io.output_regs_write_address
val reg_write_enable_mem = Input(Bool()) // ex2mem.io.output_regs_write_enable
val reg_write_enable_mem = Input(Bool())
val uses_rs1_id = Input(Bool()) // true only if current ID instruction really reads rs1
val uses_rs2_id = Input(Bool()) // true only if current ID instruction really reads rs2

val if_flush = Output(Bool())
val id_flush = Output(Bool())
Expand Down Expand Up @@ -83,12 +85,12 @@ class Control extends Module {

// Check EX stage dependency (1-cycle old instruction):
(io.reg_write_enable_ex && // EX stage will write a register
(io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id) && // Destination matches ID source
((io.uses_rs1_id && (io.rd_ex === io.rs1_id)) || (io.uses_rs2_id && (io.rd_ex === io.rs2_id))) && // Destination matches ID source
io.rd_ex =/= 0.U) // Not writing to x0 (always zero)
||
// Check MEM stage dependency (2-cycle old instruction):
(io.reg_write_enable_mem && // MEM stage will write a register
(io.rd_mem === io.rs1_id || io.rd_mem === io.rs2_id) && // Destination matches ID source
((io.uses_rs1_id && (io.rd_mem === io.rs1_id)) || (io.uses_rs2_id && (io.rd_mem === io.rs2_id))) && // Destination matches ID source
io.rd_mem =/= 0.U) // Not writing to x0
) {
// Stall action: Insert bubble (NOP) and freeze earlier stages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,34 @@ class InstructionDecode extends Module {
val ex_reg_write_address = Output(UInt(Parameters.PhysicalRegisterAddrWidth))
val ex_csr_address = Output(UInt(Parameters.CSRRegisterAddrWidth))
val ex_csr_write_enable = Output(Bool())
val uses_rs1_id = Output(Bool()) // tells Control/Forwarding whether rs1 is valid for this instruction
val uses_rs2_id = Output(Bool()) // tells Control/Forwarding whether rs2 is valid for this instruction

})
val opcode = io.instruction(6, 0)
val funct3 = io.instruction(14, 12)
val funct7 = io.instruction(31, 25)
val rd = io.instruction(11, 7)
val rs1 = io.instruction(19, 15)
val rs2 = io.instruction(24, 20)

io.regs_reg1_read_address := Mux(opcode === Instructions.lui, 0.U(Parameters.PhysicalRegisterAddrWidth), rs1)
io.regs_reg2_read_address := rs2
val uses_rs2 = (opcode === InstructionTypes.RM) ||
(opcode === InstructionTypes.S) ||
(opcode === InstructionTypes.B)

val uses_rs1 = !(opcode === Instructions.jal) &&
!(opcode === Instructions.lui) &&
!(opcode === Instructions.auipc) &&
!(opcode === Instructions.fence) &&
!(opcode === Instructions.csr &&
(funct3 === InstructionsTypeCSR.csrrwi ||
funct3 === InstructionsTypeCSR.csrrsi ||
funct3 === InstructionsTypeCSR.csrrci))

io.uses_rs2_id := uses_rs2
io.uses_rs1_id := uses_rs1

io.regs_reg1_read_address := Mux(uses_rs1, rs1, 0.U(Parameters.PhysicalRegisterAddrWidth))
io.regs_reg2_read_address := Mux(uses_rs2, rs2, 0.U(Parameters.PhysicalRegisterAddrWidth))
io.ex_immediate := MuxLookup(
opcode,
Cat(Fill(20, io.instruction(31)), io.instruction(31, 20))
Expand Down