1//
2// Copyright 2016 Ettus Research, a National Instruments Company
3//
4// SPDX-License-Identifier: LGPL-3.0-or-later
5//
6`timescale 1ns/1ps
7
8module source_flow_control_legacy_tb();
9
10   reg clk    = 0;
11   reg reset  = 1;
12
13   always #10 clk = ~clk;
14
15   initial $dumpfile("source_flow_control_legacy_tb.vcd");
16   initial $dumpvars(0,source_flow_control_legacy_tb);
17
18   initial
19     begin
20	#1000 reset = 0;
21	#20000;
22	$finish;
23     end
24
25   reg [63:0]  tdata;
26   wire [63:0] tdata_int;
27   reg 	       tlast;
28   wire        tlast_int;
29   reg 	       tvalid = 1'b0;
30   wire        tvalid_int;
31   wire        tready, tready_int;
32
33   reg [63:0]  fc_tdata;
34   reg 	       fc_tlast, fc_tvalid;
35   wire        fc_tready;
36
37   wire [63:0] out_tdata;
38   wire        out_tlast, out_tready, out_tvalid;
39
40   wire [15:0] occ_in, occ_out;
41   reg 	       set_stb = 0;
42   reg [7:0]   set_addr;
43   reg [31:0]  set_data;
44
45
46   task send_fc_packet;
47      input [31:0] seqnum;
48      input [31:0] sid;
49      input always_go;
50
51      begin
52	 @(posedge clk);
53	 fc_tlast <= 1'b0;
54	 fc_tdata <= { 1'b1, 1'b0, 1'b0, 1'b0, 12'hABC, 16'd4, sid };
55	 fc_tvalid <= 1;
56	 @(posedge clk);
57	 fc_tlast <= 1'b1;
58	 //fc_tdata <= { 52'h0,seqnum };
59	 fc_tdata <= { 31'h0,always_go, seqnum };
60	 @(posedge clk);
61	 fc_tvalid <= 0;
62	 @(posedge clk);
63      end
64   endtask // send_packet
65
66   task send_packet;
67      input ec;
68      input timed;
69      input [11:0] seqnum;
70      input [31:0] sid;
71      input [63:0] vtime;
72      input [15:0] addr;
73      input [31:0] data;
74
75      begin
76	 // Send a packet
77	 @(posedge clk);
78	 tlast <= 1'b0;
79	 tdata <= { ec, 1'b0, timed, 1'b0, seqnum, timed ? 16'd6 : 16'd4, sid };
80	 tvalid <= 1;
81	 @(posedge clk);
82	 if(timed)
83	   begin
84	      tdata <= vtime;
85	      @(posedge clk);
86	   end
87	 tlast <= 1'b1;
88	 tdata <= { 16'h0, addr, data };
89	 @(posedge clk);
90	 tlast <= 1'b0;
91	 tvalid <= 0;
92	 @(posedge clk);
93      end
94   endtask // send_packet
95
96   initial
97     begin
98	tvalid <= 1'b0;
99	while(reset)
100	  @(posedge clk);
101	@(posedge clk);
102	// Set flow control window to be 2
103	set_stb <= 1;
104	set_addr <= 0;
105	set_data <= 2;
106	@(posedge clk);
107	set_stb <= 0;
108	// ExtContext. Time. Seq=0, SID=DEAD_6789, Time=10
109	send_packet(1'b1,1'b1,12'h0,32'hDEAD_6789,64'h10,16'hB,32'hF00D_1234);
110	send_packet(1'b1,1'b1,12'h1,32'hDEAD_6789,64'h20,16'hC,32'hABCD_4321);
111	send_packet(1'b1,1'b1,12'h2,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
112	send_packet(1'b1,1'b1,12'h3,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
113	send_packet(1'b1,1'b1,12'h4,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
114	send_packet(1'b1,1'b1,12'h5,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
115	send_packet(1'b1,1'b1,12'h6,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
116	send_packet(1'b1,1'b1,12'h7,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
117	send_packet(1'b1,1'b1,12'h8,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
118	#500;
119	// Consumed 2 packets
120	send_fc_packet(32'd1,32'h3,1'b0);
121	#300;
122	// Consumed 1 packet
123	send_fc_packet(32'd2,32'h3,1'b0);
124	#500;
125	// Consumed 2 packets
126	send_fc_packet(32'd4,32'h3,1'b0);
127	#400;
128	// Send same SEQ ID again to test it causes no changes.
129	send_fc_packet(32'd4,32'h3,1'b0);
130	#300;
131	// Consumed 1 packet
132	send_fc_packet(32'd5,32'h3,1'b0);
133	#500;
134	// Consumed 2 packets
135	send_fc_packet(32'd7,32'h3,1'b0);
136	#500;
137	send_packet(1'b1,1'b1,12'h9,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
138	send_packet(1'b1,1'b1,12'hA,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
139	#300;
140	// Consumed 1 packet
141	send_fc_packet(32'd8,32'h3,1'b0);
142	//
143	// Now force internal sequence count to close to wrap value to test corner case
144	//
145	#100;
146	source_flow_control_legacy.current_seqnum <= 32'hFFFF_FFFC;
147	#100;
148	send_fc_packet(32'hFFFF_FFFA,32'h3,1'b0);
149	#100;
150	send_packet(1'b1,1'b1,12'hFFC,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
151	#200;
152	send_packet(1'b1,1'b1,12'hFFD,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
153	send_packet(1'b1,1'b1,12'hFFE,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
154	send_packet(1'b1,1'b1,12'hFFF,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
155	send_packet(1'b1,1'b1,12'h000,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
156	send_packet(1'b1,1'b1,12'h001,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
157	send_packet(1'b1,1'b1,12'h002,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
158	#200;
159	// Consumed 2 packets
160	send_fc_packet(32'hFFFF_FFFC,32'h3,1'b0);
161	#200;
162	// Consumed 2 packets
163	send_fc_packet(32'hFFFF_FFFE,32'h3,1'b0);
164	send_packet(1'b1,1'b1,12'h003,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
165	send_packet(1'b1,1'b1,12'h004,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
166	#200;
167	// Consumed 2 packets
168	send_fc_packet(32'h0,32'h3,1'b0);
169	#200;
170	// Consumed 2 packets
171	send_fc_packet(32'h2,32'h3,1'b0);
172	#500;
173	//
174	// Again force internal sequence count to close to wrap value to test new corner case
175	//
176	#100;
177	source_flow_control_legacy.current_seqnum <= 32'hFFFF_FFFC;
178	#100;
179	send_fc_packet(32'hFFFF_FFFA,32'h3,1'b0);
180	#100;
181	send_packet(1'b1,1'b1,12'hFFC,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
182	#200;
183	send_packet(1'b1,1'b1,12'hFFD,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
184	send_packet(1'b1,1'b1,12'hFFE,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
185	send_packet(1'b1,1'b1,12'hFFF,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
186	send_packet(1'b1,1'b1,12'h000,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
187	send_packet(1'b1,1'b1,12'h001,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
188	send_packet(1'b1,1'b1,12'h002,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
189	#200;
190	// Consumed 1 packets
191	send_fc_packet(32'hFFFF_FFFB,32'h3,1'b0);
192	#200;
193	// Consumed 1 packets
194	send_fc_packet(32'hFFFF_FFFC,32'h3,1'b0);
195	send_packet(1'b1,1'b1,12'h003,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
196	send_packet(1'b1,1'b1,12'h004,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321);
197	#200;
198	// Consumed 1 packets
199	send_fc_packet(32'hFFFF_FFFD,32'h3,1'b0);
200	#200;
201	// Consumed 1 packets
202	send_fc_packet(32'hFFFF_FFFE,32'h3,1'b0);
203	#200;
204	// Consumed 1 packets
205	send_fc_packet(32'hFFFF_FFFF,32'h3,1'b0);
206	#200;
207	// Consumed 1 packets
208	send_fc_packet(32'h0,32'h3,1'b0);
209	#200;
210	// Consumed 1 packets
211	send_fc_packet(32'h1,32'h3,1'b0);
212	#200;
213	// Consumed 1 packets
214	send_fc_packet(32'h2,32'h3,1'b0);
215	#500;
216
217
218
219
220     end
221
222   axi_fifo #(.WIDTH(65), .SIZE(10)) fifo_in
223     (.clk(clk), .reset(reset), .clear(1'b0),
224      .i_tdata({tlast,tdata}), .i_tvalid(tvalid), .i_tready(tready),
225      .o_tdata({tlast_int,tdata_int}), .o_tvalid(tvalid_int), .o_tready(tready_int),
226      .occupied(occ_in));
227
228   source_flow_control_legacy source_flow_control_legacy
229     (.clk(clk), .reset(reset), .clear(1'b0),
230      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
231      .fc_tdata(fc_tdata), .fc_tlast(fc_tlast), .fc_tvalid(fc_tvalid), .fc_tready(fc_tready),
232      .in_tdata(tdata_int), .in_tlast(tlast_int), .in_tvalid(tvalid_int), .in_tready(tready_int),
233      .out_tdata(out_tdata), .out_tlast(out_tlast), .out_tvalid(out_tvalid), .out_tready(out_tready)
234      );
235
236   wire [63:0] dump_tdata;
237   wire        dump_tlast, dump_tvalid, dump_tready;
238
239   axi_fifo #(.WIDTH(65), .SIZE(10)) fifo_out
240     (.clk(clk), .reset(reset), .clear(1'b0),
241      .i_tdata({out_tlast,out_tdata}), .i_tvalid(out_tvalid), .i_tready(out_tready),
242      .o_tdata({dump_tlast,dump_tdata}), .o_tvalid(dump_tvalid), .o_tready(dump_tready),
243      .occupied(occ_out));
244
245   assign dump_tready = 0;
246
247   always @(posedge clk)
248     if(out_tvalid & out_tready)
249       begin
250	  $display("%x",out_tdata);
251	  if(out_tlast)
252	    $display("TLAST");
253       end
254endmodule // source_flow_control_legacy_tb
255