-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmem.v
83 lines (75 loc) · 2.5 KB
/
mem.v
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
module MemoryAccess(
// from EX_MEM
input wire wr_enable_i,
input wire wr_i,
input wire[`AddrLen - 1: 0] next_pc_i,
input wire[`Funct3Len - 1: 0] funct3_i, // for LOAD/STORE in MEM
input wire[`RegAddrLen - 1: 0] rd_addr_i,
input wire rd_write_enable_i,
input wire[`RegLen - 1: 0] rd_data_i, // to rd
output reg stall_req_o,
// to MEMCTRL
output reg wr_enable_o,
output reg wr_o,
output reg[`AddrLen - 1: 0] next_pc_o,
// from MEMCTRL
input wire is_mem_output_i,
input wire load_store_ready_i,
input wire[`RegLen - 1: 0] load_data_i,
// to WB & MEM forwarding signals
output reg[`RegLen - 1: 0] rd_data_o,
output reg[`RegAddrLen - 1: 0] rd_addr_o,
output reg rd_write_enable_o
);
// rd addr/enable WB
always @(*) begin
rd_addr_o = rd_addr_i;
rd_write_enable_o = rd_write_enable_i;
end
always @(*) begin
if(wr_enable_i) begin
if(load_store_ready_i) begin // LOAD/STORE is ready now
if(wr_i == `Write) rd_data_o = `ZERO_WORD;
else begin // LOAD
case(funct3_i)
// MEMCTRL only fetches data. Data extending here(signed/unsigned)
`LB: rd_data_o = {{24{load_data_i[7]}}, load_data_i[7: 0]};
`LH: rd_data_o = {{16{load_data_i[15]}}, load_data_i[15: 0]};
`LW: rd_data_o = load_data_i;
`LBU: rd_data_o = {24'b0, load_data_i[7: 0]};
`LHU: rd_data_o = {16'b0, load_data_i[15: 0]};
default:rd_data_o = `ZERO_WORD;
endcase
end
end
else rd_data_o = `ZERO_WORD;
end
else rd_data_o = rd_data_i;
end
// wr_enable for MEMCTRL: when ready, disable FIXME: may cause bugs
always @(*) begin
if(wr_enable_i) begin
if(load_store_ready_i) begin
wr_enable_o = `Disable;
wr_o = `Read;
end
else begin
wr_enable_o = wr_enable_i;
wr_o = wr_i;
end
end
else begin
wr_enable_o = `Disable;
wr_o = `Read;
end
end
always @(*) begin
if(wr_enable_i && is_mem_output_i) begin
stall_req_o = ~load_store_ready_i;
end
else stall_req_o = `Disable;
end
always @(*) begin
next_pc_o = next_pc_i;
end
endmodule