-
Notifications
You must be signed in to change notification settings - Fork 185
/
regm.v
86 lines (75 loc) · 1.96 KB
/
regm.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
84
85
86
/*
* regm - register memory
*
* A 32-bit register memory. Two registers can be read at once. The
* variables `read1` and `read2` specify which registers to read. The
* output is placed in `data1` and `data2`.
*
* If `regwrite` is high, the value in `wrdata` will be written to the
* register in `wrreg`.
*
* The register at address $zero is treated special, it ignores
* assignment and the value read is always zero.
*
* If the register being read is the same as that being written, the
* value being written will be available immediately without a one
* cycle delay.
*
*/
`ifndef _regm
`define _regm
`ifndef DEBUG_CPU_REG
`define DEBUG_CPU_REG 0
`endif
module regm(
input wire clk,
input wire [4:0] read1, read2,
output wire [31:0] data1, data2,
input wire regwrite,
input wire [4:0] wrreg,
input wire [31:0] wrdata);
reg [31:0] mem [0:31]; // 32-bit memory with 32 entries
reg [31:0] _data1, _data2;
initial begin
if (`DEBUG_CPU_REG) begin
$display(" $v0, $v1, $t0, $t1, $t2, $t3, $t4, $t5, $t6, $t7");
$monitor("%x, %x, %x, %x, %x, %x, %x, %x, %x, %x",
mem[2][31:0], /* $v0 */
mem[3][31:0], /* $v1 */
mem[8][31:0], /* $t0 */
mem[9][31:0], /* $t1 */
mem[10][31:0], /* $t2 */
mem[11][31:0], /* $t3 */
mem[12][31:0], /* $t4 */
mem[13][31:0], /* $t5 */
mem[14][31:0], /* $t6 */
mem[15][31:0], /* $t7 */
);
end
end
always @(*) begin
if (read1 == 5'd0)
_data1 = 32'd0;
else if ((read1 == wrreg) && regwrite)
_data1 = wrdata;
else
_data1 = mem[read1][31:0];
end
always @(*) begin
if (read2 == 5'd0)
_data2 = 32'd0;
else if ((read2 == wrreg) && regwrite)
_data2 = wrdata;
else
_data2 = mem[read2][31:0];
end
assign data1 = _data1;
assign data2 = _data2;
always @(posedge clk) begin
if (regwrite && wrreg != 5'd0) begin
// write a non $zero register
mem[wrreg] <= wrdata;
end
end
endmodule
`endif