lab2实验报告&lab3还有最后一个错误

This commit is contained in:
2025-10-13 16:03:58 +08:00
parent 2f8cb461d5
commit 37ced72a9d
19 changed files with 1280 additions and 41 deletions

View File

@@ -25,6 +25,15 @@ class PipelineRegister(width: Int = Parameters.DataBits, defaultValue: UInt = 0.
val out = Output(UInt(width.W))
})
// Lab3(PipelineRegister)
io.out := 0.U
val register = RegInit(defaultValue)
when(io.flush) {
register := defaultValue
}.elsewhen(io.stall) {
}.otherwise {
register := io.in
}
io.out := register
// Lab3(PipelineRegister) End
}

View File

@@ -34,10 +34,27 @@ class Control extends Module {
val if2id_stall = Output(Bool())
})
// Lab3(Final)
io.if2id_flush := false.B
io.id2ex_flush := false.B
io.pc_stall := false.B
io.if2id_stall := false.B
val stall = Wire(Bool())
val load_use_hazard = io.memory_read_enable_ex && io.rd_ex =/= 0.U &&
(io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id)
val id_jump_needs_ex_alu = io.jump_instruction_id && io.rd_ex =/= 0.U &&
!io.memory_read_enable_ex && // 确保不是load-use hazard
(io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id)
// 最终的阻塞条件
stall := load_use_hazard || id_jump_needs_ex_alu
// 只有在流水线不被阻塞时跳转信号flush才应该生效。
val flush = io.jump_flag && !stall
// 最终输出
io.pc_stall := stall
io.if2id_stall := stall
io.if2id_flush := flush
// 只有在阻塞时才需要清空ID/EX来插入气泡。
// 跳转引起的清空只作用于IF/ID。
io.id2ex_flush := stall
// Lab3(Final) End
}

View File

@@ -41,9 +41,24 @@ class Forwarding extends Module {
})
// Lab3(Final)
io.reg1_forward_id := 0.U
io.reg2_forward_id := 0.U
io.reg1_forward_ex := 0.U
io.reg2_forward_ex := 0.U
val ex_mem_hazard_rs1 = io.reg_write_enable_mem && io.rd_mem =/= 0.U && (io.rd_mem === io.rs1_ex)
val ex_mem_hazard_rs2 = io.reg_write_enable_mem && io.rd_mem =/= 0.U && (io.rd_mem === io.rs2_ex)
val ex_wb_hazard_rs1 = io.reg_write_enable_wb && io.rd_wb =/= 0.U && (io.rd_wb === io.rs1_ex)
val ex_wb_hazard_rs2 = io.reg_write_enable_wb && io.rd_wb =/= 0.U && (io.rd_wb === io.rs2_ex)
io.reg1_forward_ex := Mux(ex_mem_hazard_rs1, ForwardingType.ForwardFromMEM,
Mux(ex_wb_hazard_rs1, ForwardingType.ForwardFromWB, ForwardingType.NoForward))
io.reg2_forward_ex := Mux(ex_mem_hazard_rs2, ForwardingType.ForwardFromMEM,
Mux(ex_wb_hazard_rs2, ForwardingType.ForwardFromWB, ForwardingType.NoForward))
// --- 旁路到 ID 阶段 ---
val id_mem_hazard_rs1 = io.reg_write_enable_mem && io.rd_mem =/= 0.U && (io.rd_mem === io.rs1_id)
val id_mem_hazard_rs2 = io.reg_write_enable_mem && io.rd_mem =/= 0.U && (io.rd_mem === io.rs2_id)
// 当MEM阶段转发时就不需要再看WB阶段了
val id_wb_hazard_rs1 = io.reg_write_enable_wb && io.rd_wb =/= 0.U && !id_mem_hazard_rs1 && (io.rd_wb === io.rs1_id)
val id_wb_hazard_rs2 = io.reg_write_enable_wb && io.rd_wb =/= 0.U && !id_mem_hazard_rs2 && (io.rd_wb === io.rs2_id)
io.reg1_forward_id := Mux(id_mem_hazard_rs1, ForwardingType.ForwardFromMEM,
Mux(id_wb_hazard_rs1, ForwardingType.ForwardFromWB, ForwardingType.NoForward))
io.reg2_forward_id := Mux(id_mem_hazard_rs2, ForwardingType.ForwardFromMEM,
Mux(id_wb_hazard_rs2, ForwardingType.ForwardFromWB, ForwardingType.NoForward))
// Lab3(Final) End
}

View File

@@ -171,8 +171,10 @@ class InstructionDecode extends Module {
val rs2 = io.instruction(24, 20)
// Lab3(Final) ID rs
io.regs_reg1_read_address := rs1
io.regs_reg2_read_address := rs2
val rs1_used = opcode =/= Instructions.lui && opcode =/= Instructions.auipc && opcode =/= Instructions.jal
val rs2_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.S || opcode === InstructionTypes.B
io.regs_reg1_read_address := Mux(rs1_used, rs1, 0.U)
io.regs_reg2_read_address := Mux(rs2_used, rs2, 0.U)
// Lab3(Final) ID rs End
io.ex_immediate := MuxLookup(
opcode,
@@ -211,8 +213,11 @@ class InstructionDecode extends Module {
)
)
// Lab3(Final) ID rd
io.ex_reg_write_enable := false.B
io.ex_reg_write_address := rd
val rd_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.I || opcode === InstructionTypes.L ||
opcode === Instructions.lui || opcode === Instructions.auipc || opcode === Instructions.jal ||
opcode === Instructions.jalr || opcode === Instructions.csr
io.ex_reg_write_enable := rd_used
io.ex_reg_write_address := Mux(rd_used, rd, 0.U)
// Lab3(Final) ID rd End
io.ex_csr_address := io.instruction(31, 20)
io.ex_csr_write_enable := (opcode === Instructions.csr) && (
@@ -222,10 +227,52 @@ class InstructionDecode extends Module {
)
// Lab3(Final)
io.ctrl_jump_instruction := false.B
io.clint_jump_flag := false.B
io.clint_jump_address := 0.U
io.if_jump_flag := false.B
io.if_jump_address := 0.U
// io.ctrl_jump_instruction := false.B
// io.clint_jump_flag := false.B
// io.clint_jump_address := 0.U
// io.if_jump_flag := false.B
// io.if_jump_address := 0.U
val reg1_data = MuxLookup(io.reg1_forward, io.reg1_data)(
Seq(
ForwardingType.ForwardFromMEM -> io.forward_from_mem,
ForwardingType.ForwardFromWB -> io.forward_from_wb
)
)
val reg2_data = MuxLookup(io.reg2_forward, io.reg2_data)(
Seq(
ForwardingType.ForwardFromMEM -> io.forward_from_mem,
ForwardingType.ForwardFromWB -> io.forward_from_wb
)
)
val is_jump_instruction = opcode === Instructions.jal || opcode === Instructions.jalr || opcode === InstructionTypes.B
io.ctrl_jump_instruction := is_jump_instruction
val jump_condition_met =
(opcode === Instructions.jal) ||
(opcode === Instructions.jalr) ||
(opcode === InstructionTypes.B) && MuxLookup(
funct3,
false.B,
IndexedSeq(
InstructionsTypeB.beq -> (reg1_data === reg2_data),
InstructionsTypeB.bne -> (reg1_data =/= reg2_data),
InstructionsTypeB.blt -> (reg1_data.asSInt < reg2_data.asSInt),
InstructionsTypeB.bge -> (reg1_data.asSInt >= reg2_data.asSInt),
InstructionsTypeB.bltu -> (reg1_data < reg2_data),
InstructionsTypeB.bgeu -> (reg1_data >= reg2_data)
)
)
val jump_address = Mux(
opcode === Instructions.jalr,
(reg1_data.asSInt + io.ex_immediate.asSInt).asUInt,
(io.instruction_address.asSInt + io.ex_immediate.asSInt).asUInt
) & (~1.U(Parameters.DataWidth)).asUInt // Ensure address is even
io.clint_jump_flag := jump_condition_met
io.clint_jump_address := jump_address
io.if_jump_flag := jump_condition_met || io.interrupt_assert
io.if_jump_address := Mux(
io.interrupt_assert,
io.interrupt_handler_address,
jump_address
)
// Lab3(Final) End
}

View File

@@ -32,9 +32,17 @@ class Control extends Module {
})
// Lab3(Forward)
io.if2id_flush := false.B
io.id2ex_flush := false.B
io.pc_stall := false.B
io.if2id_stall := false.B
// io.if2id_flush := false.B
// io.id2ex_flush := false.B
// io.pc_stall := false.B
// io.if2id_stall := false.B
val load_use_hazard = io.memory_read_enable_ex &&
(io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id) &&
io.rd_ex =/= 0.U
val flush = io.jump_flag
io.pc_stall := load_use_hazard && !flush
io.if2id_stall := load_use_hazard && !flush
io.if2id_flush := flush
io.id2ex_flush := flush || load_use_hazard
// Lab3(Forward) End
}

View File

@@ -61,8 +61,18 @@ class Execute extends Module {
alu.io.func := alu_ctrl.io.alu_funct
// Lab3(Forward)
val reg1_data = 0.U
val reg2_data = 0.U
val reg1_data = MuxLookup(io.reg1_forward, io.reg1_data)(
Seq(
ForwardingType.ForwardFromMEM -> io.forward_from_mem,
ForwardingType.ForwardFromWB -> io.forward_from_wb
)
)
val reg2_data = MuxLookup(io.reg2_forward, io.reg2_data)(
Seq(
ForwardingType.ForwardFromMEM -> io.forward_from_mem,
ForwardingType.ForwardFromWB -> io.forward_from_wb
)
)
// Lab3(Forward) End
alu.io.op1 := Mux(

View File

@@ -38,7 +38,19 @@ class Forwarding extends Module {
})
// Lab3(Forward)
io.reg1_forward_ex := 0.U
io.reg2_forward_ex := 0.U
// io.reg1_forward_ex := 0.U
// io.reg2_forward_ex := 0.U
io.reg1_forward_ex := ForwardingType.NoForward
io.reg2_forward_ex := ForwardingType.NoForward
when(io.reg_write_enable_mem && io.rd_mem =/= 0.U && io.rd_mem === io.rs1_ex) {
io.reg1_forward_ex := ForwardingType.ForwardFromMEM
}.elsewhen(io.reg_write_enable_wb && io.rd_wb =/= 0.U && io.rd_wb === io.rs1_ex) {
io.reg1_forward_ex := ForwardingType.ForwardFromWB
}
when(io.reg_write_enable_mem && io.rd_mem =/= 0.U && io.rd_mem === io.rs2_ex) {
io.reg2_forward_ex := ForwardingType.ForwardFromMEM
}.elsewhen(io.reg_write_enable_wb && io.rd_wb =/= 0.U && io.rd_wb === io.rs2_ex) {
io.reg2_forward_ex := ForwardingType.ForwardFromWB
}
// Lab3(Forward) End
}

View File

@@ -157,8 +157,12 @@ class InstructionDecode extends Module {
val rs2 = io.instruction(24, 20)
// Lab3(Forward) ID rs
io.regs_reg1_read_address := rs1
io.regs_reg2_read_address := rs2
// io.regs_reg1_read_address := rs1
// io.regs_reg2_read_address := rs2
val rs1_used = opcode =/= Instructions.lui && opcode =/= Instructions.auipc && opcode =/= Instructions.jal
val rs2_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.S || opcode === InstructionTypes.B
io.regs_reg1_read_address := Mux(rs1_used, rs1, 0.U)
io.regs_reg2_read_address := Mux(rs2_used, rs2, 0.U)
// Lab3(Forward) ID rs End
io.ex_immediate := MuxLookup(
opcode,
@@ -197,8 +201,13 @@ class InstructionDecode extends Module {
)
)
// Lab3(Forward) ID rd
io.ex_reg_write_enable := false.B
io.ex_reg_write_address := rd
// io.ex_reg_write_enable := false.B
// io.ex_reg_write_address := rd
val rd_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.I || opcode === InstructionTypes.L ||
opcode === Instructions.lui || opcode === Instructions.auipc || opcode === Instructions.jal ||
opcode === Instructions.jalr || opcode === Instructions.csr
io.ex_reg_write_enable := rd_used
io.ex_reg_write_address := Mux(rd_used, rd, 0.U)
// Lab3(Forward) ID rd End
io.ex_csr_address := io.instruction(31, 20)
io.ex_csr_write_enable := (opcode === Instructions.csr) && (

View File

@@ -34,10 +34,18 @@ class Control extends Module {
})
// Lab3(Stall)
io.if2id_flush := false.B
io.id2ex_flush := false.B
io.pc_stall := false.B
io.if2id_stall := false.B
// io.if2id_flush := false.B
// io.id2ex_flush := false.B
//
// io.pc_stall := false.B
// io.if2id_stall := false.B
val hazard_from_ex = io.reg_write_enable_ex && io.rd_ex =/= 0.U && (io.rd_ex === io.rs1_id || io.rd_ex === io.rs2_id)
val hazard_from_mem = io.reg_write_enable_mem && io.rd_mem =/= 0.U && (io.rd_mem === io.rs1_id || io.rd_mem === io.rs2_id)
val stall = hazard_from_ex || hazard_from_mem
val flush = io.jump_flag
io.pc_stall := stall && !flush
io.if2id_stall := stall && !flush
io.if2id_flush := flush
io.id2ex_flush := flush || stall
// Lab3(Stall) End
}

View File

@@ -157,8 +157,10 @@ class InstructionDecode extends Module {
val rs2 = io.instruction(24, 20)
// Lab3(Stall) ID rs
io.regs_reg1_read_address := rs1
io.regs_reg2_read_address := rs2
val rs1_used = opcode =/= Instructions.lui && opcode =/= Instructions.auipc && opcode =/= Instructions.jal
val rs2_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.S || opcode === InstructionTypes.B
io.regs_reg1_read_address := Mux(rs1_used, rs1, 0.U)
io.regs_reg2_read_address := Mux(rs2_used, rs2, 0.U)
// Lab3(Stall) ID rs End
io.ex_immediate := MuxLookup(
opcode,
@@ -197,8 +199,11 @@ class InstructionDecode extends Module {
)
)
// Lab3(Stall) ID rd
io.ex_reg_write_enable := false.B
io.ex_reg_write_address := rd
val rd_used = opcode === InstructionTypes.RM || opcode === InstructionTypes.I || opcode === InstructionTypes.L ||
opcode === Instructions.lui || opcode === Instructions.auipc || opcode === Instructions.jal ||
opcode === Instructions.jalr || opcode === Instructions.csr
io.ex_reg_write_enable := rd_used
io.ex_reg_write_address := Mux(rd_used, rd, 0.U)
// Lab3(Stall) ID rd End
io.ex_csr_address := io.instruction(31, 20)
io.ex_csr_write_enable := (opcode === Instructions.csr) && (

View File

@@ -32,8 +32,11 @@ class CPU extends Module {
val csr_regs = Module(new CSR)
// Lab3(ThreeStage)
if2id.io.flush := false.B
id2ex.io.flush := false.B
// if2id.io.flush := false.B
// id2ex.io.flush := false.B
ctrl.io.jump_flag_ex := ex.io.if_jump_flag
if2id.io.flush := ctrl.io.if2id_flush
id2ex.io.flush := ctrl.io.id2ex_flush
// Lab3(ThreeStage) End
regs.io.write_enable := id2ex.io.output_regs_write_enable

View File

@@ -18,5 +18,13 @@ import chisel3._
class Control extends Module {
// Lab3(ThreeStage)
val io = IO(new Bundle {
val jump_flag_ex = Input(Bool())
val if2id_flush = Output(Bool())
val id2ex_flush = Output(Bool())
})
val flush = io.jump_flag_ex
io.if2id_flush := flush
io.id2ex_flush := flush
// Lab3(ThreeStage) End
}