summaryrefslogtreecommitdiff
path: root/verilog/hazard.v
blob: 7ded32bf08b9d1009da9e1fd52595fb81bf476ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
`default_nettype none
`timescale 1ns/1ps

module hazard
(
	input wire [4:0] r1addr_e, r2addr_e,
	input wire [4:0] waddr_m, waddr_w, waddr_e,
	input wire wr_reg_m, wr_reg_w,
	output wire [1:0] r1forward_e, r2forward_e,

	input wire [4:0] r1addr_d, r2addr_d,
 	input wire wb_mem_e,
	output wire stall_f, stall_d, flush_e, flush_d,

	input wire branch_pc
);

// Forwarding Logic
assign r1forward_e = r1addr_e != 5'b0 ? (r1addr_e == waddr_m ? {1'b0, wr_reg_m} : (r1addr_e == waddr_w ? {wr_reg_w, 1'b0} : 2'b00)) : 2'b00;
assign r2forward_e = r2addr_e != 5'b0 ? (r2addr_e == waddr_m ? {1'b0, wr_reg_m} : (r2addr_e == waddr_w ? {wr_reg_w, 1'b0} : 2'b00)) : 2'b00;

// Load Hazard Logic
// TODO: Incoporate wb_pc_e into the calculations
// so that if pc is being written back pipeline not stalled
wire load_hazard = (waddr_e != 0) & ((r1addr_d == waddr_e) | (r2addr_d == waddr_e)) & wb_mem_e;

// Pipeline control outputs
assign stall_f = load_hazard;
assign stall_d = load_hazard;
assign flush_e = load_hazard | branch_pc;
assign flush_d = branch_pc;

endmodule