From aee68f46647ae009b200529a66ff9ee7edb14fcb Mon Sep 17 00:00:00 2001 From: Riley King-Saunders Date: Thu, 12 Nov 2026 16:06:49 +1100 Subject: [PATCH] An attempt was made to fix errors with this. There is an issue with either branching and/or register dependencies --- modules/assignment3.sv | 40 ++++++------- modules/gatereg.sv | 2 +- modules/hazard_unit.sv | 103 ++++++++++++--------------------- modules/instruction_counter.sv | 6 +- tests/mips_pipelined.sv | 2 +- 5 files changed, 61 insertions(+), 92 deletions(-) diff --git a/modules/assignment3.sv b/modules/assignment3.sv index cfd8c00..aae33d2 100644 --- a/modules/assignment3.sv +++ b/modules/assignment3.sv @@ -20,7 +20,6 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz= // Inputs logic [0:0] hazard_m2r_1, hazard_m2r_2; logic [0:0] hazard_reg_we_1, hazard_reg_we_2, hazard_reg_we_3; - logic [0:0] hazard_branch_taken, hazard_jump_taken; logic [4:0] hazard_rt_0, hazard_rt_1; logic [4:0] hazard_rs_0, hazard_rs_1; logic [4:0] hazard_write_reg_0, hazard_write_reg_1, hazard_write_reg_2; @@ -31,30 +30,30 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz= logic [0:0] hazard_flushE, hazard_flushD; // TODO: too many variables - find what should't be here hazard_unit hazard_unit( - hazard_m2r_1, hazard_rt_1, hazard_rs_1, - hazard_reg_we_1, hazard_write_reg_0, /*>Duplicate but Missing?*/ hazard_m2r_1, - hazard_reg_we_2, hazard_write_reg_1, /*>Missing*/ hazard_m2r_2, - hazard_reg_we_3, hazard_write_reg_2, // MISSING, + B, hazard_rs_0, hazard_rt_0, - hazard_branch_taken, hazard_jump_taken, // NOTE: We aren't doing branch prediction. Can just be control unit branch - hazard_forwardAE, hazard_forwardBE, - hazard_forwardAD, hazard_forwardBD, // MISSING + hazard_rs_1, hazard_rt_1, + hazard_write_reg_0, hazard_reg_we_1, hazard_m2r_1, + hazard_write_reg_1, hazard_reg_we_2, hazard_m2r_2, + hazard_write_reg_2, hazard_reg_we_3, + hazard_stallF, hazard_stallD, - hazard_flushE, hazard_flushD + hazard_forwardAD, hazard_forwardBD, + hazard_flushE, + hazard_forwardAE, hazard_forwardBE ); logic [2**width-1:0] pc_addr, pc_addr_1, pc_addr_2; logic [2**width-1:0] pc_addr_write; logic [0:0] pc_we; instruction_counter #(width) PC (clk, rst, ~hazard_stallF, pc_we, pc_addr_write, pc_addr); - gatereg #(width, 1) gate_pc_addr(clk, rst, ~hazard_stallF, pc_addr, pc_addr_1); // TODO: Verify if this needs to exist - gatereg #(width, 1) gate_pc_addr_1(clk, rst | (hazard_branch_taken | hazard_jump_taken), ~hazard_stallD, pc_addr_1, pc_addr_2); + gatereg #(width, 1) gate_pc_addr(clk, rst | hazard_flushD, ~hazard_stallF, pc_addr, pc_addr_1); logic [2**width-1:0] rom_rd; logic [2**width-1:0] instruction, instruction_1; rom #(progsrc, romsz, width) ROM (pc_addr_1[romsz-1:0], rom_rd); - gatereg #(width, 1) gate_instruction(clk, rst | (hazard_branch_taken | hazard_jump_taken), ~hazard_stallD, rom_rd, instruction); + gatereg #(width, 1) gate_instruction(clk, rst | hazard_flushD, ~hazard_stallD, rom_rd, instruction); gatereg #(width, 1) gate_instruction_1(clk, rst | hazard_flushE, 1'b1, instruction, instruction_1); @@ -74,11 +73,10 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz= gatereg #(0, 1) gate_cu_m2r(clk, rst | hazard_flushE, 1'b1, cu_m2r, cu_m2r_1); gatereg #(0, 1) gate_cu_m2r_1 (clk, rst, 1'b1, cu_m2r_1, cu_m2r_2); - gatereg #(0, 1) gate_cu_m2r_2 (clk, rst, 1'b1, cu_m2r_2, REGW_MEM_OR_RD); - gatereg #(0, 1) gate_cu_m2w_1 (clk, rst, 1'b1, cu_m2w_1, MEM_WE); - gatereg #(0, 1) gate_cu_rw_1 (clk, rst, 1'b1, cu_rw_1, cu_rw_2); + + gatereg #(0, 1) gate_cu_m2r_2 (clk, rst, 1'b1, cu_m2r_2, REGW_MEM_OR_RD); gatereg #(0, 1) gate_cu_rw_2 (clk, rst, 1'b1, cu_rw_2, REG_WE); assign hazard_m2r_1 = cu_m2r_2; @@ -116,7 +114,7 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz= logic [2**width-1:0] sign_ext_imm, rt_imm; sign_extender #(4, width) SIGNEXT(1'b1, instruction[15:0], sign_ext_imm); - gatereg #(width, 1) gate_sign_ext_imm(clk, rst, 1'b1, sign_ext_imm, rt_imm); + gatereg #(width, 1) gate_sign_ext_imm(clk, rst | hazard_flushE, 1'b1, sign_ext_imm, rt_imm); // Inputs logic [2**width-1:0] alu_in_a, alu_in_b; @@ -143,15 +141,13 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz= gatereg #(2, 1) gate_alu_flags (clk, rst, 1'b1, alu_flags, alu_flags_1); assign rd_alu = alu_out_2; - logic [2**width-1:0] new_pc_addr, new_pc_addr_1; - assign new_pc_addr = (sign_ext_imm << 2) + pc_addr_2; - gatereg #(width, 1) gate_new_pc_addr (clk, rst, 1'b1, new_pc_addr, new_pc_addr_1); + logic [2**width-1:0] new_pc_addr; + assign new_pc_addr = (sign_ext_imm << 2) + pc_addr_1; - assign pc_addr_write = new_pc_addr_1; + assign pc_addr_write = new_pc_addr; assign pc_we = B & ((hazard_forwardAD ? alu_out_1 : regf_rs) == (hazard_forwardBD ? alu_out_1 : regf_rt)); - assign hazard_branch_taken = pc_we; - assign hazard_jump_taken = pc_we; + assign hazard_flushD = pc_we; logic [2**width-1:0] mem_out, mem_out_1; ram #(ramsz, width) RAM (clk, rst, alu_out_1[ramsz-1:0], MEM_WE, alu_in_b, mem_out); gatereg #(width, 1) gate_mem_out (clk, rst, 1'b1, mem_out, mem_out_1); diff --git a/modules/gatereg.sv b/modules/gatereg.sv index 7c4d604..24a4028 100644 --- a/modules/gatereg.sv +++ b/modules/gatereg.sv @@ -5,7 +5,7 @@ module gatereg #(width, ndelay=1)( logic [2**width-1:0] hold_value[ndelay]; assign out = hold_value[ndelay-1]; - always_ff @( posedge clk ) begin + always_ff @( posedge clk or posedge rst) begin if (rst) begin for (integer i = 0; i < ndelay; ++i) begin hold_value[i] <= {(2**width){1'b0}}; diff --git a/modules/hazard_unit.sv b/modules/hazard_unit.sv index 42d3c90..bed4b04 100644 --- a/modules/hazard_unit.sv +++ b/modules/hazard_unit.sv @@ -2,78 +2,51 @@ `define HAZARD_SV module hazard_unit ( - // (I)Decode/EXecute stage - input logic idex_MemRead, - input logic [4:0] idex_Rt, - input logic [4:0] idex_Rs, + input logic [0:0] branch_decode, + input logic [4:0] rs_decode, rt_decode, + + input logic [4:0] rs_execute, rt_execute, + input logic [4:0] rd_execute, + input logic [0:0] reg_write_execute, m2r_execute, - // EXecute/MEMory stage - input logic exmem_RegWrite, - input logic [4:0] exmem_Rd, + input logic [4:0] rd_memory, + input logic [0:0] reg_write_memory, m2r_memory, - // MEMory/WriteBack stage - input logic memwb_RegWrite, - input logic [4:0] memwb_Rd, + input logic [4:0] rd_writeback, + input logic [0:0] reg_write_writeback, - // (I)Fetch/(I)Decode stage - input logic [4:0] ifid_Rs, - input logic [4:0] ifid_Rt, - - // branch / jump control - input logic branch_taken, - input logic jump_taken, - - // outputs - output logic [1:0] forwardA, - output logic [1:0] forwardB, - output logic stallF, // Stall OC register - output logic stallD, // Stall Instruction Memory - output logic flushE, // Flush ALU inputs - output logic flushD // Flush + output logic [0:0] stall_fetch, stall_decode, + output logic [0:0] forward_a_decode, forward_b_decode, + output logic [0:0] flush_execute, + output logic [1:0] forward_a_execute, forward_b_execute ); - - // Forwarding for A/B ALU inputs - // 00 = no forwarding - // 01 = forward from MEM/WB - // 10 = forward from EX/MEM - always_comb begin - // defaults - forwardA = 2'b00; - forwardB = 2'b00; - stallF = 1'b0; - stallD = 1'b0; - flushE = 1'b0; - flushD = 1'b0; + forward_a_execute = 2'b00; + forward_b_execute = 2'b00; - // Forwarding for ALU src A - if (exmem_RegWrite && (exmem_Rd != 5'd0) && (exmem_Rd == idex_Rs)) - forwardA = 2'b10; - else if (memwb_RegWrite && (memwb_Rd != 5'd0) && (memwb_Rd == idex_Rs)) - forwardA = 2'b01; - - // Forwarding for ALU src B - if (exmem_RegWrite && (exmem_Rd != 5'd0) && (exmem_Rd == idex_Rt)) - forwardB = 2'b10; - else if (memwb_RegWrite && (memwb_Rd != 5'd0) && (memwb_Rd == idex_Rt)) - forwardB = 2'b01; - - // Load-use hazard stall - // if instruction in EX is a load and next instruction uses its result - if (idex_MemRead && - ((idex_Rt == ifid_Rs) || (idex_Rt == ifid_Rt))) begin - stallF = 1'b1; - stallD = 1'b1; - flushE = 1'b1; // insert bubble into EX - end - - // Control hazard flush - // branch/jump resolved in EX - if (branch_taken || jump_taken) begin - flushD = 1'b1; // flush wrong instruction in decode - flushE = 1'b1; // flush wrong instruction in execute - end + if ( (rs_execute != 5'd0) && (rs_execute == rd_memory) && reg_write_memory) + forward_a_execute = 2'b10; + else if ( (rs_execute != 5'd0) && (rs_execute == rd_memory) && reg_write_writeback) + forward_a_execute = 2'b01; + + if ( (rt_execute != 5'd0) && (rt_execute == rd_memory) && reg_write_memory) + forward_b_execute = 2'b10; + else if ( (rt_execute != 5'd0) && (rt_execute == rd_memory) && reg_write_writeback) + forward_b_execute = 2'b01; end + logic [0:0] loaduse_stall; + assign loaduse_stall = ((rs_decode == rt_execute) | (rt_decode == rt_execute)) & m2r_execute; + + assign forward_a_decode = (rs_decode != 5'd0) & (rs_decode == rd_memory) & reg_write_memory; + assign forward_b_decode = (rt_decode != 5'd0) & (rt_decode == rd_memory) & reg_write_memory; + + logic [0:0] branch_stall; + assign branch_stall = (branch_decode & reg_write_execute & (rd_execute == rs_decode || rd_execute == rt_decode) ) || + (branch_decode & m2r_memory & (rd_memory == rs_decode || rd_memory == rt_decode) ); + + assign stall_fetch = loaduse_stall | branch_stall; + assign stall_decode = loaduse_stall | branch_stall; + assign flush_execute = loaduse_stall | branch_stall; endmodule `endif diff --git a/modules/instruction_counter.sv b/modules/instruction_counter.sv index 2927688..0a51749 100644 --- a/modules/instruction_counter.sv +++ b/modules/instruction_counter.sv @@ -10,10 +10,10 @@ module instruction_counter #(parameter width=5)( logic [2**width-1:0] pc; always_ff @(posedge clk or posedge rst) begin - if (~en) begin - // Skip any cycles where we are disabled - end else if (rst) begin + if (rst) begin pc <= {(2**width){1'b0}}; + end else if (~en) begin + // Skip any cycles where we are disabled end else if (we) begin pc <= W; end else begin diff --git a/tests/mips_pipelined.sv b/tests/mips_pipelined.sv index 8bb0abe..2ce17be 100644 --- a/tests/mips_pipelined.sv +++ b/tests/mips_pipelined.sv @@ -17,7 +17,7 @@ module mips_pipelined_tb(); logic [0:0] clk; logic [0:0] rst; - assignment3 #("./asm/bin/ELEC4720-2026s2-Ass-03-NoHazardsDemo.hex") CPU (clk, rst); + assignment3 #("./asm/bin/ELEC4720-2026s2-Ass-03-HazardsDemo.hex") CPU (clk, rst); initial clk = 0; initial rst = 0;