forked from grahamedgecombe/icicle
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrv32_hazard.sv
93 lines (71 loc) · 3.22 KB
/
rv32_hazard.sv
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
`ifndef RV32_HAZARD
`define RV32_HAZARD
module rv32_hazard_unit #(
parameter BYPASSING = 0
) (
/* control in */
input [4:0] decode_rs1_unreg_in,
input decode_rs1_read_unreg_in,
input [4:0] decode_rs2_unreg_in,
input decode_rs2_read_unreg_in,
input decode_mem_fence_unreg_in,
input decode_mem_read_in,
input decode_mem_fence_in,
input decode_csr_read_in,
input [4:0] decode_rd_in,
input decode_rd_write_in,
input fetch_overwrite_pc_in,
input [4:0] execute_rd_in,
input execute_mem_fence_in,
input [4:0] mem_rd_in,
input mem_trap_in,
input mem_branch_mispredicted_in,
input instr_read_in,
input instr_ready_in,
input data_read_in,
input data_write_in,
input data_ready_in,
/* control out */
output logic pcgen_stall_out,
output logic fetch_stall_out,
output logic fetch_flush_out,
output logic decode_stall_out,
output logic decode_flush_out,
output logic execute_stall_out,
output logic execute_flush_out,
output logic mem_stall_out,
output logic mem_flush_out,
output logic writeback_flush_out
);
logic rs1_matches;
logic rs2_matches;
logic pcgen_wait_for_bus;
logic fetch_wait_for_rd_write;
logic fetch_wait_for_mem_fence;
logic execute_wait_for_bus;
generate
if (BYPASSING) begin
assign rs1_matches = decode_rs1_unreg_in == decode_rd_in && decode_rs1_read_unreg_in;
assign rs2_matches = decode_rs2_unreg_in == decode_rd_in && decode_rs2_read_unreg_in;
assign fetch_wait_for_rd_write = (rs1_matches || rs2_matches) && |decode_rd_in && (decode_mem_read_in || decode_csr_read_in) && decode_rd_write_in;
end else begin
assign rs1_matches = (decode_rs1_unreg_in == decode_rd_in || decode_rs1_unreg_in == execute_rd_in || decode_rs1_unreg_in == mem_rd_in) && decode_rs1_read_unreg_in;
assign rs2_matches = (decode_rs2_unreg_in == decode_rd_in || decode_rs2_unreg_in == execute_rd_in || decode_rs2_unreg_in == mem_rd_in) && decode_rs2_read_unreg_in;
assign fetch_wait_for_rd_write = (rs1_matches || rs2_matches) && |decode_rd_in && decode_rd_write_in;
end
endgenerate
assign pcgen_wait_for_bus = instr_read_in && !instr_ready_in;
assign fetch_wait_for_mem_fence = decode_mem_fence_unreg_in || decode_mem_fence_in || execute_mem_fence_in;
assign execute_wait_for_bus = (data_read_in || data_write_in) && !data_ready_in;
assign pcgen_stall_out = fetch_stall_out || pcgen_wait_for_bus;
assign fetch_stall_out = decode_stall_out || fetch_wait_for_rd_write || fetch_wait_for_mem_fence;
assign fetch_flush_out = pcgen_stall_out || mem_trap_in || mem_branch_mispredicted_in || fetch_overwrite_pc_in;
assign decode_stall_out = execute_stall_out;
assign decode_flush_out = fetch_stall_out || mem_trap_in || mem_branch_mispredicted_in || fetch_overwrite_pc_in;
assign execute_stall_out = mem_stall_out || execute_wait_for_bus;
assign execute_flush_out = decode_stall_out || mem_trap_in || mem_branch_mispredicted_in || fetch_overwrite_pc_in;
assign mem_stall_out = 0;
assign mem_flush_out = execute_stall_out;
assign writeback_flush_out = mem_stall_out;
endmodule
`endif