mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
lab2实验报告&lab3还有最后一个错误
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) && (
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) && (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user