1+ `timescale 1ns / 1ps
2+
3+ module Blur_tb ;
4+
5+ // Clock and reset
6+ logic clk;
7+ logic reset;
8+
9+ // Test parameters
10+ parameter D = 8 ; // Image dimension (must be >= 4)
11+ parameter N = 4 ; // Conv2D parameter (can be 1, 2, 4, 8, or 16)
12+
13+ // DUT signals
14+ logic valid_i;
15+ logic ready_i;
16+ logic [D - 1 : 0 ][D - 1 : 0 ][7 : 0 ] data_in;
17+ logic valid_o;
18+ logic ready_o;
19+ logic [D - 3 : 0 ][D - 3 : 0 ][7 : 0 ] data_out;
20+ logic [1 : 0 ] blur_state;
21+ int cycles, start_v, end_v;
22+
23+ // Verification variables
24+ logic pass;
25+ logic [7 : 0 ] expected;
26+
27+ // Instantiate DUT
28+ Blur # (.D0 (D ), .D1 (D ), .N (N )) dut (
29+ .clk (clk),
30+ .reset (reset),
31+ .state (blur_state),
32+ .valid_i (valid_i),
33+ .ready_i (ready_i),
34+ .in (data_in),
35+ .valid_o (valid_o),
36+ .ready_o (ready_o),
37+ .out (data_out)
38+ );
39+
40+ // Clock generation
41+ initial begin
42+ clk = 0 ;
43+ forever # 5 clk = ~ clk; // 100MHz clock
44+ end
45+
46+ // Dump waveforms
47+ initial begin
48+ $dumpfile (" blur_tb.vcd" );
49+ $dumpvars (0 , Blur_tb);
50+ end
51+
52+ always_ff @ (posedge clk) begin
53+ if (reset) cycles <= '0 ;
54+ else cycles <= cycles + 1 ;
55+
56+ if (cycles > 200 ) begin
57+ $display (" timeout at 200 cycles!" );
58+ $finish ;
59+ end
60+
61+ if (valid_i) start_v <= cycles;
62+ if (valid_o) end_v <= cycles;
63+ end
64+
65+ // Test stimulus
66+ initial begin
67+ // Initialize signals
68+ reset = 1 ;
69+ valid_i = 0 ;
70+ ready_o = 0 ;
71+ data_in = '0 ;
72+
73+ // Hold reset for 5 cycles
74+ repeat (5 ) @ (posedge clk);
75+ reset = 0 ;
76+ @ (posedge clk);
77+
78+ // Prepare input data [0..D*D-1] arranged as DxD image
79+ for (int i = 0 ; i < D ; i++ ) begin
80+ for (int j = 0 ; j < D ; j++ ) begin
81+ data_in[i][j] = 8 '(i* D + j);
82+ end
83+ end
84+
85+ $display (" Starting test with D=%0d , N=%0d " , D , N );
86+ $display (" Input data (%0d x%0d ):" , D , D );
87+ for (int i = 0 ; i < D ; i++ ) begin
88+ for (int j = 0 ; j < D ; j++ ) begin
89+ $write (" %3d " , data_in[i][j]);
90+ end
91+ $write (" \n " );
92+ end
93+
94+ // Wait for module to be ready
95+ @ (posedge clk);
96+ while (! ready_i) begin
97+ @ (posedge clk);
98+ end
99+
100+ // Send input data
101+ $display (" \n Sending data to Blur module..." );
102+ valid_i = 1 ;
103+ @ (posedge clk);
104+
105+ // Check if transaction occurred
106+ if (ready_i && valid_i) begin
107+ $display (" Transaction accepted by module" );
108+ end
109+
110+ valid_i = 0 ; // Clear valid after one cycle
111+
112+ // Wait for output to be valid
113+ $display (" Waiting for output..." );
114+ while (! valid_o) begin
115+ @ (posedge clk);
116+ $display (" Cycle %0d : State = %0d " , cycles, blur_state);
117+ end
118+
119+ // Assert ready to accept output
120+ ready_o = 1 ;
121+ @ (posedge clk);
122+
123+ // Print output
124+ $display (" \n Output data received (%0d x%0d ):" , D - 2 , D - 2 );
125+ for (int i = 0 ; i < D - 2 ; i++ ) begin
126+ for (int j = 0 ; j < D - 2 ; j++ ) begin
127+ $write (" %3d " , data_out[i][j]);
128+ end
129+ $write (" \n " );
130+ end
131+
132+ // Verify output (should be corresponding input + 2)
133+ // The center (D-2)x(D-2) portion of the input should have 2 added
134+ $display (" \n Verifying output (each element should be corresponding input + 2):" );
135+ pass = 1 ;
136+ for (int i = 0 ; i < D - 2 ; i++ ) begin
137+ for (int j = 0 ; j < D - 2 ; j++ ) begin
138+ // Output[i][j] corresponds to input[i+1][j+1] after blur convolution
139+ expected = 8 '((i+ 1 )* D + (j+ 1 )) + 2 ;
140+ if (data_out[i][j] !== expected) begin
141+ $display (" ERROR: data_out[%0d ][%0d ] = %3d , expected %3d " , i, j, data_out[i][j], expected);
142+ pass = 0 ;
143+ end
144+ end
145+ end
146+
147+ if (pass) begin
148+ $display (" PASS: All outputs are correct!" );
149+ end else begin
150+ $display (" FAIL: Output mismatch detected!" );
151+ end
152+
153+ ready_o = 0 ;
154+
155+ // Wait a few cycles then end
156+ repeat (10 ) @ (posedge clk);
157+
158+ $display (" \n Test completed! Latency: %0d , Cycles: %0d " , end_v- start_v, cycles);
159+ $finish ;
160+ end
161+
162+ endmodule
0 commit comments