An attempt was made to fix errors with this. There is an issue with either branching and/or register dependencies
This commit is contained in:
5 files changed
+59
-90
No files matched your search
+18
-22
@@ -20,7 +20,6 @@ module assignment3 #(parameter progsrc = "", parameter width=5, parameter romsz=
|
|||||||
// Inputs
|
// Inputs
|
||||||
logic [0:0] hazard_m2r_1, hazard_m2r_2;
|
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_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_rt_0, hazard_rt_1;
|
||||||
logic [4:0] hazard_rs_0, hazard_rs_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;
|
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;
|
logic [0:0] hazard_flushE, hazard_flushD;
|
||||||
// TODO: too many variables - find what should't be here
|
// TODO: too many variables - find what should't be here
|
||||||
hazard_unit hazard_unit(
|
hazard_unit hazard_unit(
|
||||||
hazard_m2r_1, hazard_rt_1, hazard_rs_1,
|
B,
|
||||||
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,
|
|
||||||
hazard_rs_0, hazard_rt_0,
|
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_rs_1, hazard_rt_1,
|
||||||
hazard_forwardAE, hazard_forwardBE,
|
hazard_write_reg_0, hazard_reg_we_1, hazard_m2r_1,
|
||||||
hazard_forwardAD, hazard_forwardBD, // MISSING
|
hazard_write_reg_1, hazard_reg_we_2, hazard_m2r_2,
|
||||||
|
hazard_write_reg_2, hazard_reg_we_3,
|
||||||
|
|
||||||
hazard_stallF, hazard_stallD,
|
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, pc_addr_1, pc_addr_2;
|
||||||
logic [2**width-1:0] pc_addr_write;
|
logic [2**width-1:0] pc_addr_write;
|
||||||
logic [0:0] pc_we;
|
logic [0:0] pc_we;
|
||||||
instruction_counter #(width) PC (clk, rst, ~hazard_stallF, pc_we, pc_addr_write, pc_addr);
|
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(clk, rst | hazard_flushD, ~hazard_stallF, pc_addr, pc_addr_1);
|
||||||
gatereg #(width, 1) gate_pc_addr_1(clk, rst | (hazard_branch_taken | hazard_jump_taken), ~hazard_stallD, pc_addr_1, pc_addr_2);
|
|
||||||
|
|
||||||
|
|
||||||
logic [2**width-1:0] rom_rd;
|
logic [2**width-1:0] rom_rd;
|
||||||
logic [2**width-1:0] instruction, instruction_1;
|
logic [2**width-1:0] instruction, instruction_1;
|
||||||
rom #(progsrc, romsz, width) ROM (pc_addr_1[romsz-1:0], rom_rd);
|
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);
|
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(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_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_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_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);
|
gatereg #(0, 1) gate_cu_rw_2 (clk, rst, 1'b1, cu_rw_2, REG_WE);
|
||||||
|
|
||||||
assign hazard_m2r_1 = cu_m2r_2;
|
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;
|
logic [2**width-1:0] sign_ext_imm, rt_imm;
|
||||||
sign_extender #(4, width) SIGNEXT(1'b1, instruction[15:0], sign_ext_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
|
// Inputs
|
||||||
logic [2**width-1:0] alu_in_a, alu_in_b;
|
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);
|
gatereg #(2, 1) gate_alu_flags (clk, rst, 1'b1, alu_flags, alu_flags_1);
|
||||||
assign rd_alu = alu_out_2;
|
assign rd_alu = alu_out_2;
|
||||||
|
|
||||||
logic [2**width-1:0] 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_2;
|
assign new_pc_addr = (sign_ext_imm << 2) + pc_addr_1;
|
||||||
gatereg #(width, 1) gate_new_pc_addr (clk, rst, 1'b1, new_pc_addr, new_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 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_flushD = pc_we;
|
||||||
assign hazard_jump_taken = pc_we;
|
|
||||||
logic [2**width-1:0] mem_out, mem_out_1;
|
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);
|
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);
|
gatereg #(width, 1) gate_mem_out (clk, rst, 1'b1, mem_out, mem_out_1);
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ module gatereg #(width, ndelay=1)(
|
|||||||
logic [2**width-1:0] hold_value[ndelay];
|
logic [2**width-1:0] hold_value[ndelay];
|
||||||
|
|
||||||
assign out = hold_value[ndelay-1];
|
assign out = hold_value[ndelay-1];
|
||||||
always_ff @( posedge clk ) begin
|
always_ff @( posedge clk or posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
for (integer i = 0; i < ndelay; ++i) begin
|
for (integer i = 0; i < ndelay; ++i) begin
|
||||||
hold_value[i] <= {(2**width){1'b0}};
|
hold_value[i] <= {(2**width){1'b0}};
|
||||||
|
|||||||
+36
-63
@@ -2,78 +2,51 @@
|
|||||||
`define HAZARD_SV
|
`define HAZARD_SV
|
||||||
|
|
||||||
module hazard_unit (
|
module hazard_unit (
|
||||||
// (I)Decode/EXecute stage
|
input logic [0:0] branch_decode,
|
||||||
input logic idex_MemRead,
|
input logic [4:0] rs_decode, rt_decode,
|
||||||
input logic [4:0] idex_Rt,
|
|
||||||
input logic [4:0] idex_Rs,
|
|
||||||
|
|
||||||
// EXecute/MEMory stage
|
input logic [4:0] rs_execute, rt_execute,
|
||||||
input logic exmem_RegWrite,
|
input logic [4:0] rd_execute,
|
||||||
input logic [4:0] exmem_Rd,
|
input logic [0:0] reg_write_execute, m2r_execute,
|
||||||
|
|
||||||
// MEMory/WriteBack stage
|
input logic [4:0] rd_memory,
|
||||||
input logic memwb_RegWrite,
|
input logic [0:0] reg_write_memory, m2r_memory,
|
||||||
input logic [4:0] memwb_Rd,
|
|
||||||
|
|
||||||
// (I)Fetch/(I)Decode stage
|
input logic [4:0] rd_writeback,
|
||||||
input logic [4:0] ifid_Rs,
|
input logic [0:0] reg_write_writeback,
|
||||||
input logic [4:0] ifid_Rt,
|
|
||||||
|
|
||||||
// branch / jump control
|
output logic [0:0] stall_fetch, stall_decode,
|
||||||
input logic branch_taken,
|
output logic [0:0] forward_a_decode, forward_b_decode,
|
||||||
input logic jump_taken,
|
output logic [0:0] flush_execute,
|
||||||
|
output logic [1:0] forward_a_execute, forward_b_execute
|
||||||
// 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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Forwarding for A/B ALU inputs
|
|
||||||
// 00 = no forwarding
|
|
||||||
// 01 = forward from MEM/WB
|
|
||||||
// 10 = forward from EX/MEM
|
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
// defaults
|
forward_a_execute = 2'b00;
|
||||||
forwardA = 2'b00;
|
forward_b_execute = 2'b00;
|
||||||
forwardB = 2'b00;
|
|
||||||
stallF = 1'b0;
|
|
||||||
stallD = 1'b0;
|
|
||||||
flushE = 1'b0;
|
|
||||||
flushD = 1'b0;
|
|
||||||
|
|
||||||
// Forwarding for ALU src A
|
if ( (rs_execute != 5'd0) && (rs_execute == rd_memory) && reg_write_memory)
|
||||||
if (exmem_RegWrite && (exmem_Rd != 5'd0) && (exmem_Rd == idex_Rs))
|
forward_a_execute = 2'b10;
|
||||||
forwardA = 2'b10;
|
else if ( (rs_execute != 5'd0) && (rs_execute == rd_memory) && reg_write_writeback)
|
||||||
else if (memwb_RegWrite && (memwb_Rd != 5'd0) && (memwb_Rd == idex_Rs))
|
forward_a_execute = 2'b01;
|
||||||
forwardA = 2'b01;
|
|
||||||
|
|
||||||
// Forwarding for ALU src B
|
if ( (rt_execute != 5'd0) && (rt_execute == rd_memory) && reg_write_memory)
|
||||||
if (exmem_RegWrite && (exmem_Rd != 5'd0) && (exmem_Rd == idex_Rt))
|
forward_b_execute = 2'b10;
|
||||||
forwardB = 2'b10;
|
else if ( (rt_execute != 5'd0) && (rt_execute == rd_memory) && reg_write_writeback)
|
||||||
else if (memwb_RegWrite && (memwb_Rd != 5'd0) && (memwb_Rd == idex_Rt))
|
forward_b_execute = 2'b01;
|
||||||
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
|
|
||||||
end
|
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
|
endmodule
|
||||||
`endif
|
`endif
|
||||||
@@ -10,10 +10,10 @@ module instruction_counter #(parameter width=5)(
|
|||||||
logic [2**width-1:0] pc;
|
logic [2**width-1:0] pc;
|
||||||
|
|
||||||
always_ff @(posedge clk or posedge rst) begin
|
always_ff @(posedge clk or posedge rst) begin
|
||||||
if (~en) begin
|
if (rst) begin
|
||||||
// Skip any cycles where we are disabled
|
|
||||||
end else if (rst) begin
|
|
||||||
pc <= {(2**width){1'b0}};
|
pc <= {(2**width){1'b0}};
|
||||||
|
end else if (~en) begin
|
||||||
|
// Skip any cycles where we are disabled
|
||||||
end else if (we) begin
|
end else if (we) begin
|
||||||
pc <= W;
|
pc <= W;
|
||||||
end else begin
|
end else begin
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
module mips_pipelined_tb();
|
module mips_pipelined_tb();
|
||||||
logic [0:0] clk;
|
logic [0:0] clk;
|
||||||
logic [0:0] rst;
|
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 clk = 0;
|
||||||
initial rst = 0;
|
initial rst = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user