-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregfile_tb.v
126 lines (111 loc) · 3.45 KB
/
regfile_tb.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
`timescale 1ns / 1ps
`default_nettype none
module regfile_tb(clk);
reg clk_tb, resetb_tb, we_rd_tb;
reg [4:0] a_rs1_tb, a_rs2_tb, a_rd_tb;
wire [31:0] d_rs1_tb, d_rs2_tb;
reg [31:0] d_rd_tb;
assign clk_tb = clk;
// always begin : CLK_GENERATOR
// #5 clk_tb = 1'b0;
// #5 clk_tb = 1'b1;
// end
// Test 1: writes 16, 15, 14, 13, 12,... to registers x0, x1, x2, x3, x4,...
// Rs1 and Rs2 reads with delay of 1 and 2 clocks, respectively
task run_test1;
integer i;
begin
$display("(TT) --------------------------------------------------");
$display("(TT) Test 1: Basic R/W ");
$display("(TT) 1. Writes 32, 31, ... to x0, x1, ... consecutively");
$display("(TT) 2. RS1 reads x31, x0, x1, ...");
$display("(TT) 3. RS2 reads x30, x31, x0, x1, ...");
$display("(TT) 4. RS1 should read X, 0, 31, 30, ...");
$display("(TT) 5. RS2 should read X, X, 0, 31, 30, ...");
$display("(TT) 6. No stray value should remain");
$display("(TT) --------------------------------------------------");
resetb_tb = 1'b0;
we_rd_tb = 1'b0;
@(posedge clk_tb) resetb_tb = 1'b1;
for (i = 0; i < 40; i = i + 1) begin
// Writeback addr
a_rd_tb = i;
// Writeback data
d_rd_tb = 32 - i%32;
we_rd_tb = 1'b1;
// RS1 addr
a_rs1_tb = i - 1;
// RS2 addr
a_rs2_tb = i - 2;
#0; // Wait for combinational to complete
// Then display results
$display("(TT) a_rd = x%d, d_rd = %d, we_rd = %d",
a_rd_tb, d_rd_tb, we_rd_tb);
$display("(TT) a_rs1 = x%d, d_rs1 = %d",
a_rs1_tb, d_rs1_tb);
$display("(TT) a_rs2 = x%d, d_rs2 = %d",
a_rs2_tb, d_rs2_tb);
$display("");
@(posedge clk_tb);
end
end
endtask //
// Test 2: Forwarding test
task run_test2;
integer i;
begin
$display("(TT) --------------------------------------------------");
$display("(TT) Test 2: Forwarding R/W ");
$display("(TT) 1. Writes 32, 31, ... to x0, x1, ... consecutively");
$display("(TT) 2. RS1 reads x0, x1, ...");
$display("(TT) 3. RS2 reads x31, x0, x1, ...");
$display("(TT) 4. RS1 should read 0, 31, 30, ...");
$display("(TT) 5. RS2 should read X, 0, 31, 30, ...");
$display("(TT) 6. No stray value should remain");
$display("(TT) --------------------------------------------------");
resetb_tb = 1'b0;
we_rd_tb = 1'b0;
@(posedge clk_tb) resetb_tb = 1'b1;
for (i = 0; i < 40; i = i + 1) begin
// Writeback addr
a_rd_tb = i;
// Writeback data
d_rd_tb = 32 - i%32;
we_rd_tb = 1'b1;
// RS1 addr
a_rs1_tb = i;
// RS2 addr
a_rs2_tb = i - 1;
#0; // Wait for combinational to complete
// Then display results
$display("(TT) a_rd = x%d, d_rd = %d, we_rd = %d",
a_rd_tb, d_rd_tb, we_rd_tb);
$display("(TT) a_rs1 = x%d, d_rs1 = %d",
a_rs1_tb, d_rs1_tb);
$display("(TT) a_rs2 = x%d, d_rs2 = %d",
a_rs2_tb, d_rs2_tb);
$display("");
@(posedge clk_tb);
end
end
endtask //
regfile UUT(
.clk(clk_tb), .resetb(resetb_tb),
.a_rs1(a_rs1_tb), .d_rs1(d_rs1_tb),
.a_rs2(a_rs2_tb), .d_rs2(d_rs2_tb),
.a_rd(a_rd_tb), .d_rd(d_rd_tb),
.we_rd(we_rd_tb)
);
// Run the tests
initial
begin : RUN_ALL_TESTS
$dumpfile("tb_log/regfile_tb.vcd");
$dumpvars(0,regfile_tb);
@(posedge clk_tb);
// Test 1
run_test1();
// Test 2
run_test2();
$finish;
end
endmodule // regfile_tb