Skip to content

Commit a4294c9

Browse files
committed
ЛР6. Добавление тб
Closes #33.
1 parent 25804e7 commit a4294c9

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed

Labs/06. Main memory/tb_data_mem.sv

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/* -----------------------------------------------------------------------------
2+
* Project Name : Architectures of Processor Systems (APS) lab work
3+
* Organization : National Research University of Electronic Technology (MIET)
4+
* Department : Institute of Microdevices and Control Systems
5+
* Author(s) : Andrei Solodovnikov
6+
* Email(s) : [email protected]
7+
8+
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
9+
* ------------------------------------------------------------------------------
10+
*/
11+
module tb_data_mem;
12+
// Входы
13+
import memory_pkg::DATA_MEM_SIZE_WORDS;
14+
import memory_pkg::DATA_MEM_SIZE_BYTES;
15+
16+
logic clk_i;
17+
logic mem_req_i;
18+
logic write_enable_i;
19+
logic [3:0] byte_enable_i;
20+
logic [31:0] addr_i, addr;
21+
logic [31:0] write_data_i;
22+
assign addr = addr_i[2+:$clog2(DATA_MEM_SIZE_WORDS)];
23+
24+
logic [31:0] read_data_o;
25+
logic ready_o;
26+
27+
28+
logic [31:0] last_read_data;
29+
logic [31:0] last_write_data;
30+
31+
int err_cnt = 0;
32+
33+
static bit simulation_finished;
34+
35+
data_mem DUT (.*);
36+
37+
task read_request(input logic [31:0] address, output logic [31:0] data);
38+
addr_i <= address;
39+
mem_req_i <= 1'b1;
40+
write_enable_i <= 1'b0;
41+
@(posedge clk_i);
42+
data = read_data_o;
43+
mem_req_i <= 1'b0;
44+
endtask
45+
46+
task write_request( input logic [31:0] address, data, input [3:0] be);
47+
addr_i <= address;
48+
mem_req_i <= 1'b1;
49+
write_enable_i <= 1'b1;
50+
byte_enable_i <= be;
51+
write_data_i <= data;
52+
@(posedge clk_i);
53+
mem_req_i <= 1'b0;
54+
endtask
55+
56+
task direct_read_test();
57+
logic [31:0] data;
58+
for(int i = 0; i < 128; i++) begin
59+
read_request(i, data);
60+
end
61+
if(DATA_MEM_SIZE_BYTES > 128) begin
62+
for(int i = 1; i <= 128; i++) begin
63+
read_request(DATA_MEM_SIZE_BYTES / 128 * i + i%4, data);
64+
end
65+
end
66+
endtask
67+
68+
task direct_write_test();
69+
for(int i = 0; i < 128; i++) begin
70+
write_request(i, $urandom(), '1);
71+
end
72+
if(DATA_MEM_SIZE_BYTES > 128) begin
73+
for(int i = 1; i <= 128; i++) begin
74+
write_request(DATA_MEM_SIZE_BYTES / 128 * i + i%4, $urandom(), i%16);
75+
end
76+
end
77+
endtask
78+
79+
task random_write_test();
80+
repeat(1000) begin
81+
write_request($urandom_range(0, DATA_MEM_SIZE_BYTES-1), $urandom(), $urandom_range(0, 15));
82+
end
83+
repeat(1000) begin
84+
write_request($urandom(), $urandom(), $urandom_range(0, 15));
85+
end
86+
endtask
87+
88+
task random_read_test();
89+
logic [31:0] data;
90+
repeat(1000) begin
91+
read_request($urandom_range(0, DATA_MEM_SIZE_BYTES-1), data);
92+
end
93+
repeat(1000) begin
94+
read_request($urandom(), data);
95+
end
96+
endtask
97+
98+
task incorrect_read_test();
99+
mem_req_i <= '0;
100+
write_enable_i <= '1;
101+
addr_i <= '0;
102+
@(posedge clk_i);
103+
write_enable_i <= '0;
104+
@(posedge clk_i);
105+
mem_req_i <= '1;
106+
@(posedge clk_i);
107+
endtask
108+
109+
task incorrect_write_test();
110+
mem_req_i <= '0;
111+
write_enable_i <= '0;
112+
byte_enable_i <= '0;
113+
write_data_i <= '1;
114+
addr_i <= '0;
115+
@(posedge clk_i);
116+
mem_req_i <= '1;
117+
@(posedge clk_i);
118+
write_enable_i <= '1;
119+
@(posedge clk_i);
120+
byte_enable_i <= 4'b0010;
121+
@(posedge clk_i);
122+
endtask
123+
124+
task random_test();
125+
repeat(1000) begin
126+
mem_req_i <= $urandom_range(1);
127+
write_enable_i <= $urandom_range(1);
128+
byte_enable_i <= $urandom_range(15);
129+
addr_i <= $urandom();
130+
write_data_i <= $urandom();
131+
@(posedge clk_i);
132+
end
133+
endtask
134+
135+
initial begin
136+
$timeformat(-9, 3, "ns", 8);
137+
$display("Test has been started");
138+
139+
DUT.ram[0] = '0;
140+
DUT.ram[DATA_MEM_SIZE_WORDS-1] = '0;
141+
DUT.ram[DATA_MEM_SIZE_WORDS] = '0;
142+
assert( DUT.ram[0] == 0) else begin
143+
$display("RAM has no element with index 0");
144+
$fatal;
145+
end
146+
assert( DUT.ram[DATA_MEM_SIZE_WORDS-1] == 0) else begin
147+
$display("RAM has no element with index %d", DATA_MEM_SIZE_WORDS-1);
148+
$fatal;
149+
end
150+
assert( DUT.ram[DATA_MEM_SIZE_WORDS] === 'x) else begin
151+
$display("RAM has element with index %d", DATA_MEM_SIZE_WORDS);
152+
$fatal;
153+
end
154+
assert( DUT.ram[0][0] == 0) else begin
155+
$display("RAM bit indexes started not from 0");
156+
$fatal;
157+
end
158+
assert( DUT.ram[0][31] == 0) else begin
159+
$display("RAM bit indexes ended not at 31");
160+
$fatal;
161+
end
162+
assert( DUT.ram[0][32] === 'x) else begin
163+
$display("RAM bit indexes ended not at 31");
164+
$fatal;
165+
end
166+
167+
direct_write_test();
168+
direct_read_test();
169+
random_write_test();
170+
random_read_test();
171+
incorrect_read_test();
172+
incorrect_write_test();
173+
random_test();
174+
175+
$display("\nTest has been finished\nNumber of errors: %d\n", err_cnt);
176+
simulation_finished = 1;
177+
$finish;
178+
end
179+
180+
logic [31:0] ram_data;
181+
logic [31:0] addr_reg;
182+
always @(posedge clk_i) begin
183+
addr_reg <= addr;
184+
end
185+
assign ram_data = DUT.ram[addr_reg];
186+
187+
188+
initial begin
189+
clk_i = 0;
190+
forever #5 clk_i = ~clk_i;
191+
end
192+
193+
ready_check: assert property (@(posedge clk_i) ready_o) else begin
194+
err_cnt++;
195+
$display("Error at %t. Value of ready is not equal 1.", $time);
196+
end
197+
198+
correct_read_check: assert property (
199+
@(posedge clk_i)
200+
mem_req_i & !write_enable_i |=> read_data_o === ram_data
201+
) else begin
202+
err_cnt++;
203+
$display("Error at %t. Incorrect read_data_o: %08h instead of %08h", $time(), $sampled(read_data_o), $sampled(ram_data));
204+
end
205+
206+
logic [31:0] write_data;
207+
always @(posedge clk_i) begin
208+
write_data <= write_data_i;
209+
end
210+
211+
correct_write_check_0: assert property (
212+
@(posedge clk_i)
213+
mem_req_i & write_enable_i & byte_enable_i[0]|=> $past(write_data_i[7:0]) === ram_data[7:0]
214+
) else begin
215+
err_cnt++;
216+
$display("Error at %t. Incorrect value of ram[%01d][7:0]: %02h instead of %02h", $time(), $sampled(addr_reg), $sampled(ram_data[7:0]), $sampled(write_data_i[7:0]));
217+
end
218+
correct_write_check_1: assert property (
219+
@(posedge clk_i)
220+
mem_req_i & write_enable_i & byte_enable_i[1]|=> $past(write_data_i[15:8]) == ram_data[15:8]
221+
) else begin
222+
err_cnt++;
223+
$display("Error at %t. Incorrect value of ram[%01d][15:8]: %02h instead of %02h", $time(), $sampled(addr_reg), $sampled(ram_data[15:8]), $sampled(write_data_i[15:8]));
224+
end
225+
correct_write_check_2: assert property (
226+
@(posedge clk_i)
227+
mem_req_i & write_enable_i & byte_enable_i[2]|=> $past(write_data_i[23:16]) == ram_data[23:16]
228+
) else begin
229+
err_cnt++;
230+
$display("Error at %t. Incorrect value of ram[%d][23:16]: %02h instead of %02h", $time(), $sampled(addr_reg), $sampled(ram_data[23:16]), $sampled(write_data_i[23:16]));
231+
end
232+
correct_write_check_3: assert property (
233+
@(posedge clk_i)
234+
mem_req_i & write_enable_i & byte_enable_i[3]|=> $past(write_data_i[31:24]) == ram_data[31:24]
235+
) else begin
236+
err_cnt++;
237+
$display("Error at %t. Incorrect value of ram[%d][31:24]: %02h instead of %02h", $time(), $sampled(addr), $sampled(ram_data[31:24]), $sampled(write_data_i[31:24]));
238+
end
239+
240+
incorrect_read_check: assert property (
241+
@(posedge clk_i)
242+
!mem_req_i | write_enable_i |=> $stable(read_data_o)
243+
) else begin
244+
err_cnt++;
245+
$display("Error at %t. read_data_o is unstable without read request", $time());
246+
end
247+
248+
incorrect_write_check_0: assert property (
249+
@(posedge clk_i)
250+
(!mem_req_i | !write_enable_i | !byte_enable_i[0]) & $stable(addr) |=> $stable(ram_data[7:0])
251+
) else begin
252+
err_cnt++;
253+
$display("Error at %t. ram[%d][7:0] is unstable without write request", $time(), $sampled(addr_reg));
254+
end
255+
icorrect_write_check_1: assert property (
256+
@(posedge clk_i)
257+
(!mem_req_i | !write_enable_i | !byte_enable_i[1]) & $stable(addr) |=> $stable(ram_data[15:8])
258+
) else begin
259+
err_cnt++;
260+
$display("Error at %t. ram[%d][15:8] is unstable without write request", $time(), $sampled(addr_reg));
261+
end
262+
incorrect_write_check_2: assert property (
263+
@(posedge clk_i)
264+
(!mem_req_i | !write_enable_i | !byte_enable_i[2]) & $stable(addr) |=> $stable(ram_data[23:16])
265+
) else begin
266+
err_cnt++;
267+
$display("Error at %t. ram[%d][23:16] is unstable without write request", $time(), $sampled(addr_reg));
268+
end
269+
270+
incorrect_write_check_3: assert property (
271+
@(posedge clk_i)
272+
(!mem_req_i | !write_enable_i | !byte_enable_i[3]) & $stable(addr) |=> $stable(ram_data[31:24])
273+
) else begin
274+
err_cnt++;
275+
$display("Error at %t. ram[%d][31:24] is unstable without write request", $time(), $sampled(addr_reg));
276+
end
277+
278+
279+
always @(posedge clk_i) begin
280+
if(simulation_finished) begin
281+
$finish;
282+
end
283+
end
284+
285+
always @(posedge clk_i) begin
286+
if (err_cnt >= 10) begin
287+
$display("\nTest has been stopped after 10 errors"); $stop();
288+
end
289+
end
290+
291+
endmodule

0 commit comments

Comments
 (0)