1111
1212// Author: Florian Zaruba <[email protected] >1313
14- // / Testbench for the isochronous spill register.
14+ // / Testbench for the isochronous spill register and 4-phase handshake .
1515// / ## Compilation
1616// /
1717// / This module needs to be compile with `-timescale "1 ns / 1 ps"` as
1818// / it doesn't specify an internal timescale.
19- module isochronous_spill_register_tb # (
19+ module isochronous_crossing_tb # (
2020 parameter int unsigned NumReq = 32'd10000 ,
21- parameter time SrcCyclTime = 20ns ,
22- // / Make sure that the clocks are an integer multiple of each other.
23- parameter time DstCyclTime = SrcCyclTime * 2
21+ parameter string DUT = " spill_register " ,
22+ parameter int unsigned TCK_SRC_MULT = 2 ,
23+ parameter int unsigned TCK_DST_MULT = 6
2424);
2525
26+ localparam time CyclTime = 10ns ; // smallest possible cycle time
27+
2628 logic src_clk, dst_clk;
2729 logic src_rst_n, dst_rst_n;
2830 logic sim_done;
2931
3032 typedef logic [15 : 0 ] payload_t ;
3133 // check FIFO
3234 payload_t data_fifo[$];
35+ mailbox # (payload_t) data_mbx = new ();
3336
3437 STREAM_DV # (
3538 .payload_t (payload_t)
@@ -45,19 +48,22 @@ module isochronous_spill_register_tb #(
4548
4649 typedef stream_test :: stream_driver # (
4750 .payload_t (payload_t),
48- .TA (SrcCyclTime * 0 .2 ),
49- .TT (SrcCyclTime * 0 .8 )
51+ .TA (TCK_SRC_MULT * CyclTime * 0 .2 ),
52+ .TT (TCK_SRC_MULT * CyclTime * 0 .8 )
5053 ) stream_driver_in_t ;
5154
5255 typedef stream_test :: stream_driver # (
5356 .payload_t (payload_t),
54- .TA (DstCyclTime * 0 .2 ),
55- .TT (DstCyclTime * 0 .8 )
57+ .TA (TCK_DST_MULT * CyclTime * 0 .2 ),
58+ .TT (TCK_DST_MULT * CyclTime * 0 .8 )
5659 ) stream_driver_out_t ;
5760
5861 stream_driver_in_t in_driver = new (dut_in);
5962 stream_driver_out_t out_driver = new (dut_out);
6063
64+ int unsigned handshake_mst = 0 ;
65+ int unsigned handshake_slv = 0 ;
66+
6167 // Generate Stream data
6268 initial begin : proc_stream_master
6369 automatic payload_t test_data;
@@ -68,9 +74,10 @@ module isochronous_spill_register_tb #(
6874 for (int unsigned i = 0 ; i < NumReq; i++ ) begin
6975 test_data = payload_t ' ($urandom ());
7076 stall_cycles = $urandom_range (0 , 5 );
71- data_fifo. push_back (test_data) ;
77+ handshake_mst ++ ;
7278 repeat (stall_cycles) @ (posedge src_clk);
7379 in_driver.send (test_data);
80+ data_mbx.put (test_data);
7481 end
7582 end
7683
@@ -87,12 +94,14 @@ module isochronous_spill_register_tb #(
8794 stall_cycles = $urandom_range (0 , 5 );
8895 repeat (stall_cycles) @ (posedge dst_clk);
8996 out_driver.recv (actual);
90- expected = data_fifo.pop_front ();
97+ data_mbx.get (expected);
98+ handshake_slv++ ;
9199 assert (expected === actual) else $error (" expected: %h , actual: %0h " , expected, actual);
92100 num_tested++ ;
93101 end
94102 repeat (50 ) @ (posedge dst_clk);
95103 sim_done = 1'b1 ;
104+ assert (handshake_mst == handshake_slv) else $error (" Amount of handshakes differed." );
96105 end
97106
98107 // stop the simulation
@@ -104,18 +113,20 @@ module isochronous_spill_register_tb #(
104113
105114 // Clock Generation
106115 initial begin
116+ $display (" Simulating %d " , DUT );
107117 src_clk = 1'b0 ;
108- forever begin
109- src_clk = ~ src_clk;
110- # (SrcCyclTime / 2 );
111- end
112- end
113-
114- initial begin
115118 dst_clk = 1'b0 ;
116119 forever begin
117- dst_clk = ~ dst_clk;
118- # (DstCyclTime / 2 );
120+ fork
121+ forever begin
122+ src_clk = ~ src_clk;
123+ # ((CyclTime * TCK_SRC_MULT ) / 2 );
124+ end
125+ forever begin
126+ dst_clk = ~ dst_clk;
127+ # ((CyclTime * TCK_DST_MULT ) / 2 );
128+ end
129+ join
119130 end
120131 end
121132
@@ -140,19 +151,36 @@ module isochronous_spill_register_tb #(
140151 dst_rst_n = 1'b1 ;
141152 end
142153
143- isochronous_spill_register # (
144- .T (payload_t)
145- ) i_isochronous_spill_register (
146- .src_clk_i (dut_in.clk_i),
147- .src_rst_ni (src_rst_n),
148- .src_valid_i (dut_in.valid),
149- .src_ready_o (dut_in.ready),
150- .src_data_i (dut_in.data),
151- .dst_clk_i (dut_out.clk_i),
152- .dst_rst_ni (dst_rst_n),
153- .dst_valid_o (dut_out.valid),
154- .dst_ready_i (dut_out.ready),
155- .dst_data_o (dut_out.data)
156- );
157-
154+ if (DUT == " spill_register" ) begin
155+ isochronous_spill_register # (
156+ .T (payload_t)
157+ ) i_isochronous_spill_register (
158+ .src_clk_i (dut_in.clk_i),
159+ .src_rst_ni (src_rst_n),
160+ .src_valid_i (dut_in.valid),
161+ .src_ready_o (dut_in.ready),
162+ .src_data_i (dut_in.data),
163+ .dst_clk_i (dut_out.clk_i),
164+ .dst_rst_ni (dst_rst_n),
165+ .dst_valid_o (dut_out.valid),
166+ .dst_ready_i (dut_out.ready),
167+ .dst_data_o (dut_out.data)
168+ );
169+ end if (DUT == " 4phase_handshake" ) begin
170+ isochronous_4phase_handshake
171+ isochronous_4phase_handshake (
172+ .src_clk_i (dut_in.clk_i),
173+ .src_rst_ni (src_rst_n),
174+ .src_valid_i (dut_in.valid),
175+ .src_ready_o (dut_in.ready),
176+ .dst_clk_i (dut_out.clk_i),
177+ .dst_rst_ni (dst_rst_n),
178+ .dst_valid_o (dut_out.valid),
179+ .dst_ready_i (dut_out.ready)
180+ );
181+
182+ always_ff @ (posedge dut_in.clk_i)
183+ if (dut_in.valid & dut_in.ready)
184+ dut_out.data <= dut_in.data;
185+ end
158186endmodule
0 commit comments