-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregfile.sv
More file actions
60 lines (53 loc) · 2.05 KB
/
regfile.sv
File metadata and controls
60 lines (53 loc) · 2.05 KB
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
`include "regfile_params.vh"
module regfile
#(
parameter int WORDS = REG_NUM_WORDS,
parameter int BITS = REG_NUM_BITS,
parameter int ADDR_LEFT = $clog2(WORDS)-1
)
(
output logic [BITS-1:0] r1_data,
output logic [BITS-1:0] r2_data,
input logic [BITS-1:0] wdata,
input logic [ADDR_LEFT:0] waddr, // (a) Changed to [ADDR_LEFT:0]
input logic [ADDR_LEFT:0] r1_addr, // (a) Changed to [ADDR_LEFT:0]
input logic [ADDR_LEFT:0] r2_addr, // (a) Changed to [ADDR_LEFT:0]
input logic [3:0] byte_en,
input logic rw_,
input logic clk,
input logic rst_, // (d) Added rst_ input
input logic [BITS-1:0] pc_addr,
input logic jal
);
logic [BITS-1:0] mem[0:WORDS-1];
// (c) BASE_ADDR eliminated - no address validation needed
// Combinational reads (immediate response)
always @* begin
r1_data = mem[r1_addr]; // Direct access, no range check needed
r2_data = mem[r2_addr]; // Direct access, no range check needed
end
// Asynchronous reset, synchronous write with dual write support for JAL
always_ff @(posedge clk or negedge rst_) begin
if (!rst_) begin
// (d) Reset all entries as shown in class - asynchronous reset
for (integer i = 0; i < WORDS; i = i + 1) begin
mem[i] <= {BITS{1'b0}};
end
end else begin
// JAL write (happens immediately in Stage 2)
if (jal) begin
mem[RA_REG] <= pc_addr + 1; // Write return address to $ra
end
// Normal write (happens in Stage 5)
// CRITICAL: Don't write to $ra if JAL is currently writing it (prevents dual write conflict)
if (rw_ == 1'b0 && waddr != '0 && !(jal && waddr == RA_REG)) begin
case (byte_en)
4'b1111: mem[waddr] <= wdata; // full word
4'b0011: mem[waddr][15:0] <= wdata[15:0]; // half word
4'b0001: mem[waddr][7:0] <= wdata[7:0]; // byte
default: mem[waddr] <= wdata; // fallback
endcase
end
end
end
endmodule