Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_tx_test_class.vr | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | #include <vera_defines.vrh> | |
36 | #include "niu_gen_pio.vrh" | |
37 | #include "niu_tx_descp.vrh" | |
38 | #include "niu_tx_port.vrh" | |
39 | #include "niu_tx_test_control.vrh" | |
40 | #include "cMesg.vrh" | |
41 | #include "txc_util.vrh" | |
42 | #include "specweb_traffic_pattern.vrh" | |
43 | ||
44 | extern niu_gen_pio gen_pio_drv; | |
45 | extern Mesg be_msg; | |
46 | extern txc_util_class txc_util; | |
47 | extern event TX_rvcd_allpkts[4]; | |
48 | ||
49 | #include "dmc_memory_map.vri" | |
50 | ||
51 | #define TIME {get_time(HI), get_time(LO)} | |
52 | ||
53 | class niu_tx_test_class { | |
54 | ||
55 | integer id; | |
56 | integer cnt; | |
57 | integer mk_count[24]; | |
58 | ||
59 | // integer no_of_pkts; | |
60 | integer no_of_pkts_p0; | |
61 | integer no_of_pkts_p1; | |
62 | integer no_of_pkts_p2; | |
63 | integer no_of_pkts_p3; | |
64 | integer rand_num_pkts[24]; | |
65 | integer no_of_txdmas; | |
66 | integer pkts_done[4]; | |
67 | ||
68 | integer port0_enb = 0; | |
69 | integer port1_enb = 0; | |
70 | integer port2_enb = 0; | |
71 | integer port3_enb = 0; | |
72 | ||
73 | bit [23:0] dmas_ids_p0; | |
74 | bit [23:0] dmas_ids_p1; | |
75 | bit [23:0] dmas_ids_p2; | |
76 | bit [23:0] dmas_ids_p3; | |
77 | integer group_from_dma_channel[32]; // niu_dmc_virt.vr will populate this if required | |
78 | integer err_detected = 0; | |
79 | ||
80 | integer tx_kick_done[4]; | |
81 | ||
82 | integer tx_ports_sync_semaphore; | |
83 | integer rx_ports_sync_semaphore; | |
84 | integer total_tx_ports; | |
85 | ||
86 | CMacTxPort MacTxPort[4]; | |
87 | TxPacketGenConfig PktGenConfig[24]; | |
88 | flow_desc flow1[24]; | |
89 | niu_tx_test_control tx_control; | |
90 | ||
91 | Cspecweb_traffic_pattern specweb_traffic_pattern_tx; | |
92 | ||
93 | task get_dmaid(integer dma_id); | |
94 | task Rd_Pkt_Prt_Err_Set(); | |
95 | task Rd_Pkt_Prt_Err_Clr(); | |
96 | task Rd_TDMC_Intr_Dbg(); | |
97 | task Wr_1toC_TxCs(); | |
98 | task SetTDMCIntrDbg(bit [63:0] data); | |
99 | // task reset_dma(); | |
100 | task reset_dma((integer skip_chk = 0), (integer skip_rst = 1)); | |
101 | ||
102 | task get_txc_isr_count (integer count); | |
103 | ||
104 | task new((integer tx_ports_sync_semaphore_in = -1), | |
105 | (integer rx_ports_sync_semaphore_in = -1), | |
106 | (integer total_tx_ports_in = -1)); | |
107 | task kick_all_4ports(); | |
108 | task set_flow(integer pkt_type, integer dma_id, integer mac_id); | |
109 | task set_pktconfig(flow_desc flow1, integer dma_id, integer mac_id); | |
110 | // task tx_dma_init(integer mac_id, bit [23:0] dma_ids, integer ring_len[24]); | |
111 | task tx_dma_init(integer mac_id, integer ring_len, integer dma_id); | |
112 | task generate_pkts(integer no_of_pkts, integer mac_id, integer dma_id, (integer last_pkt | |
113 | =0)); | |
114 | task kick_dmas(integer no_of_pkts, integer mac_id, bit [23:0] dma_ids, integer port_enb); | |
115 | task set_pkt_len(integer pkt_len_param, integer mac_id, integer pkt_num); | |
116 | task set_pad_bytes(integer dma_id, integer pkt_num); | |
117 | ||
118 | task kick_all(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids); | |
119 | task kick_npkts(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids); | |
120 | task kick_rnum_pkts(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids); | |
121 | ||
122 | task setup_random_dmabinds(var bit [23:0] dmas_port0, var bit [23:0] dmas_port1, | |
123 | var bit [23:0] dmas_port2, var bit [23:0] dmas_port3); | |
124 | task call_gen_txgatherpkts(TxPacketGenConfig PktGenConfig, integer mac_id, integer pkt_num, integer dma_id); | |
125 | // task InitTxDMA(integer no_of_pkts,integer mac_id,bit[23:0] dma_ids); | |
126 | task InitTxDMA(integer no_of_pkts,integer mac_id, integer dma_id); | |
127 | task mailbox_update(integer mac_id, integer dma_id); | |
128 | task mailbox_read(integer mac_id, integer dma_id); | |
129 | task sync_on_pkts_done(integer mac_id); | |
130 | task check_tx_cs(integer mac_id, integer dma_id, string err_code,(integer chk_set=0),(integer chk_clr= 0)); | |
131 | task clear_mk(integer dma_id); | |
132 | task set_max_burst(integer mac_id, integer dma_id); | |
133 | task set_port_control(integer p0_enb, integer p1_enb, integer p2_enb, integer p3_enb); | |
134 | task BindDmaIntrDev(DMAChannel TxDma, integer i); | |
135 | ||
136 | task random_reset_reinit(integer mac_id, integer dma_id, integer no_of_pkts, var integer pkts_xmttd); | |
137 | task kick_all_wrreset(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids); | |
138 | function integer get_num_of_dmas_bport(bit [23:0] dma_ids); | |
139 | task get_numpkts_based_onconfig(); | |
140 | task random_stop_start_dma(integer mac_id, integer dma_id); | |
141 | ||
142 | } | |
143 | ||
144 | task niu_tx_test_class :: new((integer tx_ports_sync_semaphore_in = -1), | |
145 | (integer rx_ports_sync_semaphore_in = -1), | |
146 | (integer total_tx_ports_in = -1)) | |
147 | { | |
148 | ||
149 | integer i; | |
150 | ||
151 | integer mac_id0; | |
152 | integer mac_id1; | |
153 | integer mac_id2; | |
154 | integer mac_id3; | |
155 | ||
156 | mac_id0 = 0; | |
157 | mac_id1 = 1; | |
158 | mac_id2 = 2; | |
159 | mac_id3 = 3; | |
160 | ||
161 | MacTxPort[mac_id0] = new(mac_id0); | |
162 | MacTxPort[mac_id1] = new(mac_id1); | |
163 | ||
164 | tx_control = new(); | |
165 | ||
166 | for(i=0;i<24;i++) | |
167 | rand_num_pkts[i] = 0; | |
168 | ||
169 | // no_of_pkts = tx_control.no_of_pkts; | |
170 | no_of_txdmas = tx_control.no_of_dmas; | |
171 | printf("TX_TEST_CL : no_of_txdmas %0d\n",no_of_txdmas); | |
172 | ||
173 | if(tx_control.random_dmabinds == 0) { | |
174 | dmas_ids_p0 = tx_control.port0_dmas; | |
175 | dmas_ids_p1 = tx_control.port1_dmas; | |
176 | dmas_ids_p2 = tx_control.port2_dmas; | |
177 | dmas_ids_p3 = tx_control.port3_dmas; | |
178 | ||
179 | dmas_ids_p0 = {8'h0,dmas_ids_p0[15:0]}; | |
180 | dmas_ids_p1 = {8'h0,dmas_ids_p1[15:0]}; | |
181 | ||
182 | } else { | |
183 | // call the random dma bind function | |
184 | setup_random_dmabinds(dmas_ids_p0,dmas_ids_p1,dmas_ids_p2,dmas_ids_p3); | |
185 | ||
186 | dmas_ids_p0 = {8'h0,dmas_ids_p0[15:0]}; | |
187 | dmas_ids_p1 = {8'h0,dmas_ids_p1[15:0]}; | |
188 | } | |
189 | ||
190 | tx_ports_sync_semaphore = tx_ports_sync_semaphore_in; | |
191 | rx_ports_sync_semaphore = rx_ports_sync_semaphore_in; | |
192 | total_tx_ports = total_tx_ports_in; | |
193 | ||
194 | fork | |
195 | { | |
196 | sync_on_pkts_done(0); | |
197 | } | |
198 | { | |
199 | sync_on_pkts_done(1); | |
200 | } | |
201 | { | |
202 | sync_on_pkts_done(2); | |
203 | } | |
204 | { | |
205 | sync_on_pkts_done(3); | |
206 | } | |
207 | join none | |
208 | ||
209 | for(i=0;i<32;i++) | |
210 | group_from_dma_channel[i] = -1; | |
211 | ||
212 | if(tx_control.specweb_enabled) | |
213 | specweb_traffic_pattern_tx = new("TX" /*RX or TX*/); | |
214 | ||
215 | } | |
216 | ||
217 | ||
218 | task niu_tx_test_class :: get_dmaid(integer dma_id) | |
219 | { | |
220 | id = dma_id; | |
221 | } | |
222 | ||
223 | task niu_tx_test_class :: reset_dma((integer skip_chk = 0),(integer skip_rst = 1)) | |
224 | { | |
225 | ||
226 | // read the TX_CS reg and determin what to do | |
227 | ||
228 | bit [39:0] address; | |
229 | bit [63:0] r_data; | |
230 | ||
231 | bit [63:0] w_data = 64'h8000_0000; | |
232 | integer rst_done = 0; | |
233 | integer count = 0; | |
234 | ||
235 | // if fatal error detected reset the dma | |
236 | if(err_detected || !skip_rst ) { | |
237 | address = TX_CS + id*40'h200; | |
238 | printf(" DEBUG-- niu_tx_test_class id - %d addrsss - %x w_data - %x Time - %d \n",id,address,w_data,{get_time(HI), get_time(LO)}); | |
239 | ||
240 | gen_pio_drv.pio_wr(address,w_data); | |
241 | ||
242 | // perform a read from the register to make sure | |
243 | // tdmc is in the rst_done state before programming | |
244 | // the other config regs | |
245 | ||
246 | if(!skip_chk) { | |
247 | printf("TX_TEST_CL : check if rst_done\n"); | |
248 | while(!rst_done) { | |
249 | address = TX_CS + id*40'h200; | |
250 | gen_pio_drv.pio_rd(address,r_data); | |
251 | printf(" DEBUG-- niu_tx_test_class id - %d addrsss - %x r_data - %x Time - %d \n",id,address,r_data,{get_time(HI), get_time(LO)}); | |
252 | if(r_data[30]) { | |
253 | rst_done = 1; | |
254 | be_msg.print(e_mesg_info,"niu_tx_descp","SetTxCs","RST_STATE set for DMA %0d\n",id); | |
255 | } else { | |
256 | if(count > 100) { | |
257 | be_msg.print(e_mesg_error,"niu_tx_descp","SetTxCs","ERROR : RST_STATE not set for DMA %0d\n",id); | |
258 | rst_done = 1; | |
259 | } else { | |
260 | count++; | |
261 | rst_done = 0; | |
262 | repeat(50) @(posedge CLOCK); | |
263 | } | |
264 | } | |
265 | } | |
266 | } | |
267 | err_detected = 0; | |
268 | } | |
269 | } | |
270 | ||
271 | ||
272 | task niu_tx_test_class :: SetTDMCIntrDbg(bit [63:0] data) | |
273 | { | |
274 | bit [39:0] address; | |
275 | ||
276 | address = TDMC_INTR_DBG + id*40'h200; | |
277 | gen_pio_drv.pio_wr(address,data); | |
278 | } | |
279 | ||
280 | task niu_tx_test_class :: Rd_TDMC_Intr_Dbg() | |
281 | { | |
282 | bit [39:0] address; | |
283 | bit [63:0] rd_data; | |
284 | ||
285 | printf("VAL_OF_ID in TST_CLASS %d\n",id); | |
286 | address = TDMC_INTR_DBG + id*40'h200; | |
287 | gen_pio_drv.pio_rd(address,rd_data); | |
288 | if(rd_data[0]) | |
289 | be_msg.print(e_mesg_error,"intr_test","Rd_TDMC_Intr_Dbg","Src_Pkt_Prt_Err not cleared for DMA %0d\n",id); | |
290 | ||
291 | } | |
292 | ||
293 | ||
294 | task niu_tx_test_class :: Rd_Pkt_Prt_Err_Set() | |
295 | { | |
296 | bit [39:0] address; | |
297 | bit [63:0] rd_data; | |
298 | ||
299 | printf("VAL_OF_ID in TST_CLASS %d\n",id); | |
300 | address = TX_CS + id*40'h200; | |
301 | gen_pio_drv.pio_rd(address,rd_data); | |
302 | if(~rd_data[0]) | |
303 | be_msg.print(e_mesg_error,"intr_test","Rd_Pkt_Prt_Err_Set","Pkt_Prt_Err not set for DMA %0d\n",id); | |
304 | ||
305 | } | |
306 | ||
307 | task niu_tx_test_class :: Rd_Pkt_Prt_Err_Clr() | |
308 | { | |
309 | bit [39:0] address; | |
310 | bit [63:0] rd_data; | |
311 | ||
312 | address = TX_CS + id*40'h200; | |
313 | gen_pio_drv.pio_rd(address,rd_data); | |
314 | if(rd_data[0]) | |
315 | be_msg.print(e_mesg_error,"intr_test","Rd_Pkt_Prt_Err_Clr","Pkt_Prt_Err not cleared for DMA %0d\n",id); | |
316 | ||
317 | } | |
318 | ||
319 | task niu_tx_test_class :: Wr_1toC_TxCs() | |
320 | { | |
321 | bit [39:0] address; | |
322 | bit [63:0] rd_data; | |
323 | bit [63:0] mask; | |
324 | bit [63:0] wr_data; | |
325 | ||
326 | // first read to get the data | |
327 | ||
328 | address = TX_CS + id*40'h200; | |
329 | gen_pio_drv.pio_rd(address,rd_data); | |
330 | mask = 64'hffff_ffff_ffff_fffe; | |
331 | rd_data = rd_data & mask; | |
332 | ||
333 | // this is specific for pkt_prt_err | |
334 | // wr_data = rd_data | 64'h4000_0001; | |
335 | wr_data = 64'hc000_0001; | |
336 | ||
337 | gen_pio_drv.pio_wr(address,wr_data); | |
338 | ||
339 | } | |
340 | ||
341 | task niu_tx_test_class :: get_txc_isr_count (integer count) | |
342 | { | |
343 | cnt = count; | |
344 | } | |
345 | ||
346 | task niu_tx_test_class :: kick_all_4ports() | |
347 | { | |
348 | ||
349 | integer mac_id0; | |
350 | integer mac_id1; | |
351 | integer mac_id2; | |
352 | integer mac_id3; | |
353 | ||
354 | // integer rng_len; | |
355 | bit mb_enb; | |
356 | ||
357 | mac_id0 = 0; | |
358 | mac_id1 = 1; | |
359 | mac_id2 = 2; | |
360 | mac_id3 = 3; | |
361 | ||
362 | mb_enb = tx_control.enable_mb; | |
363 | ||
364 | port0_enb = tx_control.port0_enb; | |
365 | port1_enb = tx_control.port1_enb; | |
366 | port2_enb = tx_control.port2_enb; | |
367 | port3_enb = tx_control.port3_enb; | |
368 | ||
369 | // check if we need to sync all tx dmas | |
370 | // if so disable the txc-mac interface | |
371 | ||
372 | if(tx_control.sync_dmas) | |
373 | txc_util.txc_init(64'h0); | |
374 | else | |
375 | set_port_control(port0_enb,port1_enb,port2_enb,port3_enb); | |
376 | ||
377 | if(tx_control.tx_uniform_pkt_distribution) | |
378 | get_numpkts_based_onconfig(); | |
379 | ||
380 | ||
381 | //------ TXC init ---------------// | |
382 | ||
383 | repeat(10) @(posedge CLOCK); | |
384 | ||
385 | fork | |
386 | { | |
387 | if(tx_control.tx_uniform_pkt_distribution) | |
388 | kick_dmas(no_of_pkts_p0,0,dmas_ids_p0,port0_enb); | |
389 | else | |
390 | kick_dmas(tx_control.no_of_pkts,0,dmas_ids_p0,port0_enb); | |
391 | } | |
392 | { | |
393 | if(tx_control.tx_uniform_pkt_distribution) | |
394 | kick_dmas(no_of_pkts_p1,1,dmas_ids_p1,port1_enb); | |
395 | else | |
396 | kick_dmas(tx_control.no_of_pkts,1,dmas_ids_p1,port1_enb); | |
397 | } | |
398 | { | |
399 | repeat(5) @(posedge CLOCK); | |
400 | } | |
401 | { | |
402 | repeat(5) @(posedge CLOCK); | |
403 | } | |
404 | join all | |
405 | ||
406 | } | |
407 | ||
408 | // add task to bind the dmas to mac_port | |
409 | ||
410 | task niu_tx_test_class :: BindDmaIntrDev(DMAChannel TxDma, integer i) { | |
411 | ||
412 | integer j = 0; | |
413 | integer mac_id = 0; | |
414 | integer mac_ports; | |
415 | ||
416 | mac_ports = 2; | |
417 | ||
418 | for(j=0; j< mac_ports ;j++) { | |
419 | case(j) { | |
420 | 0 : { | |
421 | mac_id = 0; | |
422 | if(dmas_ids_p0[i]) { | |
423 | MacTxPort[mac_id].BindDmaIntrDev(TxDma,i); | |
424 | set_max_burst(mac_id,i); | |
425 | } | |
426 | } | |
427 | 1 : { | |
428 | mac_id = 1; | |
429 | if(dmas_ids_p1[i]) { | |
430 | MacTxPort[mac_id].BindDmaIntrDev(TxDma,i); | |
431 | set_max_burst(mac_id,i); | |
432 | } | |
433 | } | |
434 | 2 : { | |
435 | mac_id = 2; | |
436 | if(dmas_ids_p2[i]) { | |
437 | MacTxPort[mac_id].BindDmaIntrDev(TxDma,i); | |
438 | set_max_burst(mac_id,i); | |
439 | } | |
440 | } | |
441 | 3 : { | |
442 | mac_id = 3; | |
443 | if(dmas_ids_p3[i]) { | |
444 | MacTxPort[mac_id].BindDmaIntrDev(TxDma,i); | |
445 | set_max_burst(mac_id,i); | |
446 | } | |
447 | } | |
448 | } | |
449 | } | |
450 | } | |
451 | ||
452 | ||
453 | //--- task to set the flow and pkt type -----// | |
454 | ||
455 | ||
456 | task niu_tx_test_class :: set_flow(integer pkt_type, integer dma_id, integer mac_id) | |
457 | { | |
458 | flow1[dma_id] = new; | |
459 | ||
460 | //----- Packet flow description -------// | |
461 | ||
462 | flow1[dma_id].src_node.l2_addr = 48'haaaa_1111_0000; | |
463 | flow1[dma_id].src_node.tci = random(); | |
464 | flow1[dma_id].src_node.src_port = 20'h00001; | |
465 | // flow1[dma_id].dst_node.l2_addr = 48'hdddd_bbbb_0000; | |
466 | flow1[dma_id].dst_node.tci = random(); | |
467 | flow1[dma_id].dst_node.src_port = 20'h00001; | |
468 | flow1[dma_id].tup.src_tcp_udp_port = random(); | |
469 | flow1[dma_id].tup.dst_tcp_udp_port = random(); | |
470 | ||
471 | ||
472 | flow1[dma_id].frame.type = -1; | |
473 | flow1[dma_id].frame.class_mask = 0; | |
474 | flow1[dma_id].frame.class_funct = CLF_SRC; | |
475 | flow1[dma_id].frame.data_type = DAT_SEQ|DAT_LEN_EXACT ; | |
476 | flow1[dma_id].frame.data_seed = 0; | |
477 | flow1[dma_id].flow_no = 0; | |
478 | ||
479 | flow1[dma_id].rx_param.rcv_isn = 32'hA5A5_F5F5; | |
480 | flow1[dma_id].fl_state.tcp_flags = 6'b00_0010; | |
481 | ||
482 | flow1[dma_id].src_node.ip_addr = random(); | |
483 | flow1[dma_id].dst_node.ip_addr = random(); | |
484 | flow1[dma_id].src_node.ipv6_addr = random(); | |
485 | flow1[dma_id].dst_node.ipv6_addr = random(); | |
486 | ||
487 | // case statement for l2 DA | |
488 | ||
489 | case(mac_id) { | |
490 | 0 : flow1[dma_id].dst_node.l2_addr = 48'h0100_FFFF_0000; | |
491 | 1 : flow1[dma_id].dst_node.l2_addr = 48'h0100_FFFF_0001; | |
492 | 2 : flow1[dma_id].dst_node.l2_addr = 48'h0100_FFFF_0002; | |
493 | 3 : flow1[dma_id].dst_node.l2_addr = 48'h0100_FFFF_0003; | |
494 | } | |
495 | ||
496 | case(pkt_type) { | |
497 | 1 : { | |
498 | flow1[dma_id].frame.frame_type = 5'h0; | |
499 | flow1[dma_id].frame.frame_class = CL_ARP; | |
500 | } | |
501 | 2 : { | |
502 | flow1[dma_id].frame.frame_type = 5'h0; | |
503 | flow1[dma_id].frame.frame_class = CL_RARP; | |
504 | } | |
505 | 3 : { | |
506 | flow1[dma_id].frame.frame_type = 5'h2; | |
507 | flow1[dma_id].frame.frame_class = CL_IP; | |
508 | } | |
509 | 4 : { | |
510 | flow1[dma_id].frame.frame_type = 5'h2; | |
511 | flow1[dma_id].frame.frame_class = CL_IP; | |
512 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
513 | } | |
514 | 5 : { | |
515 | flow1[dma_id].frame.frame_type = 5'h2; | |
516 | flow1[dma_id].frame.frame_class = CL_TCP; | |
517 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
518 | } | |
519 | 6 : { | |
520 | flow1[dma_id].frame.frame_type = 5'h2; | |
521 | flow1[dma_id].frame.frame_class = CL_UDP; | |
522 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
523 | } | |
524 | 7 : { | |
525 | flow1[dma_id].frame.frame_type = 5'h6; | |
526 | flow1[dma_id].frame.frame_class = CL_IP; | |
527 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
528 | } | |
529 | 8 : { | |
530 | flow1[dma_id].frame.frame_type = 5'h6; | |
531 | flow1[dma_id].frame.frame_class = CL_TCP; | |
532 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
533 | } | |
534 | 9 : { | |
535 | flow1[dma_id].frame.frame_type = 5'h6; | |
536 | flow1[dma_id].frame.frame_class = CL_UDP; | |
537 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
538 | } | |
539 | 10 : { | |
540 | flow1[dma_id].frame.frame_type = 5'h3; | |
541 | flow1[dma_id].frame.frame_class = CL_IP; | |
542 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
543 | } | |
544 | 11 : { | |
545 | flow1[dma_id].frame.frame_type = 5'h3; | |
546 | flow1[dma_id].frame.frame_class = CL_TCP; | |
547 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
548 | } | |
549 | 12 : { | |
550 | flow1[dma_id].frame.frame_type = 5'h3; | |
551 | flow1[dma_id].frame.frame_class = CL_UDP; | |
552 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
553 | } | |
554 | 13 : { | |
555 | flow1[dma_id].frame.frame_type = 5'h7; | |
556 | flow1[dma_id].frame.frame_class = CL_IP; | |
557 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
558 | } | |
559 | 14 : { | |
560 | flow1[dma_id].frame.frame_type = 5'h7; | |
561 | flow1[dma_id].frame.frame_class = CL_TCP; | |
562 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
563 | } | |
564 | 15 : { | |
565 | flow1[dma_id].frame.frame_type = 5'h7; | |
566 | flow1[dma_id].frame.frame_class = CL_UDP; | |
567 | flow1[dma_id].frame.header_length = 5 + random()%11; | |
568 | } | |
569 | 16 : { | |
570 | flow1[dma_id].frame.frame_type = 5'ha; | |
571 | flow1[dma_id].frame.frame_class = CL_IP_V6; | |
572 | } | |
573 | 17 : { | |
574 | flow1[dma_id].frame.frame_type = 5'ha; | |
575 | flow1[dma_id].frame.frame_class = CL_TCP_IP_V6; | |
576 | } | |
577 | 18 : { | |
578 | flow1[dma_id].frame.frame_type = 5'ha; | |
579 | flow1[dma_id].frame.frame_class = CL_UDP_IP_V6; | |
580 | } | |
581 | 19 : { | |
582 | flow1[dma_id].frame.frame_type = 5'he; | |
583 | flow1[dma_id].frame.frame_class = CL_IP_V6; | |
584 | } | |
585 | 20 : { | |
586 | flow1[dma_id].frame.frame_type = 5'he; | |
587 | flow1[dma_id].frame.frame_class = CL_TCP_IP_V6; | |
588 | } | |
589 | 21 : { | |
590 | flow1[dma_id].frame.frame_type = 5'he; | |
591 | flow1[dma_id].frame.frame_class = CL_UDP_IP_V6; | |
592 | } | |
593 | 22 : { | |
594 | flow1[dma_id].frame.frame_type = 5'hb; | |
595 | flow1[dma_id].frame.frame_class = CL_IP_V6; | |
596 | } | |
597 | 23 : { | |
598 | flow1[dma_id].frame.frame_type = 5'hb; | |
599 | flow1[dma_id].frame.frame_class = CL_TCP_IP_V6; | |
600 | } | |
601 | 24 : { | |
602 | flow1[dma_id].frame.frame_type = 5'hb; | |
603 | flow1[dma_id].frame.frame_class = CL_UDP_IP_V6; | |
604 | } | |
605 | 25 : { | |
606 | flow1[dma_id].frame.frame_type = 5'hf; | |
607 | flow1[dma_id].frame.frame_class = CL_IP_V6; | |
608 | } | |
609 | 26 : { | |
610 | flow1[dma_id].frame.frame_type = 5'hf; | |
611 | flow1[dma_id].frame.frame_class = CL_TCP_IP_V6; | |
612 | } | |
613 | 27 : { | |
614 | flow1[dma_id].frame.frame_type = 5'hf; | |
615 | flow1[dma_id].frame.frame_class = CL_UDP_IP_V6; | |
616 | } | |
617 | } | |
618 | ||
619 | } | |
620 | ||
621 | task niu_tx_test_class :: set_pktconfig(flow_desc flow1, integer dma_id, integer mac_id) | |
622 | { | |
623 | PktGenConfig[dma_id] = new(); | |
624 | PktGenConfig[dma_id].mac_id = mac_id; | |
625 | PktGenConfig[dma_id].flow = flow1; | |
626 | } | |
627 | ||
628 | ||
629 | task niu_tx_test_class :: tx_dma_init(integer mac_id,integer ring_len, integer dma_id) | |
630 | { | |
631 | bit [39:0] rng_st_addr; | |
632 | integer tx_func_num; | |
633 | ||
634 | /*FOR VIRT PIO*/ | |
635 | ||
636 | if (group_from_dma_channel[dma_id] != -1) // niu_dmc_virt.vr will populate this table | |
637 | MacTxPort[mac_id].dma[dma_id].bind_to_group(group_from_dma_channel[dma_id]); | |
638 | else if(tx_control.tx_vir_pio) | |
639 | MacTxPort[mac_id].dma[dma_id].bind_to_group(dma_id); | |
640 | ||
641 | // get the func num from the run command | |
642 | ||
643 | tx_func_num = tx_control.tx_func_num; | |
644 | ||
645 | // initialize the dma | |
646 | MacTxPort[mac_id].dma[dma_id].xlate_on = 1; | |
647 | MacTxPort[mac_id].dma[dma_id].InitTXDMA(ring_len,rng_st_addr,0,tx_func_num); | |
648 | ||
649 | // based on command arg, enable or disable mask | |
650 | ||
651 | if(tx_control.enb_intr) | |
652 | MacTxPort[mac_id].dma[dma_id].SetTxEventMask(64'h0); | |
653 | ||
654 | } | |
655 | ||
656 | ||
657 | ||
658 | ||
659 | task niu_tx_test_class :: generate_pkts(integer no_of_pkts, integer mac_id, integer dma_id, | |
660 | (integer last_pkt = 0)) | |
661 | { | |
662 | integer j; | |
663 | integer k = 1; | |
664 | integer p_type; | |
665 | ||
666 | for(j=0;j<no_of_pkts;j++) { | |
667 | ||
668 | // set the mark bit count to zero | |
669 | ||
670 | if(j == 0) | |
671 | mk_count[dma_id] = 0; | |
672 | ||
673 | // set pkt_type | |
674 | if(tx_control.pkt_type == 0) { | |
675 | p_type = 1 + random()%27; | |
676 | printf("GEN_PKT : pkt_type %0d for pkt %0d\n",p_type,j); | |
677 | set_flow(p_type,dma_id,mac_id); | |
678 | } else set_flow(tx_control.pkt_type,dma_id,mac_id); | |
679 | ||
680 | set_pktconfig(flow1[dma_id],dma_id,mac_id); | |
681 | ||
682 | // set the pkt len for the pkt | |
683 | ||
684 | if(specweb_traffic_pattern_tx !== null) | |
685 | tx_control.pkt_len = specweb_traffic_pattern_tx.get_pkt_len(); | |
686 | ||
687 | set_pkt_len(tx_control.pkt_len,dma_id,j); | |
688 | ||
689 | // set mark bit | |
690 | if((j+1)%tx_control.mb_pkts == 0) { | |
691 | PktGenConfig[dma_id].mark_bit = 1; | |
692 | mk_count[dma_id]++; | |
693 | } else | |
694 | PktGenConfig[dma_id].mark_bit = 0; | |
695 | ||
696 | // set gather mode | |
697 | PktGenConfig[dma_id].g_mode = tx_control.gather_mode; | |
698 | ||
699 | // insert pad bytes between the control hdr and l2 header | |
700 | ||
701 | set_pad_bytes(dma_id,j); | |
702 | ||
703 | // this is only for loop_back_mode | |
704 | ||
705 | if(last_pkt) { | |
706 | PktGenConfig[dma_id].loop_back_rxdma_num = mac_id; | |
707 | PktGenConfig[dma_id].loop_back_rx_lastpacket = 1; | |
708 | } | |
709 | ||
710 | if((tx_control.random_gmode) || (tx_control.pkt_len == 0)) | |
711 | // call gen_txgather pkts function | |
712 | call_gen_txgatherpkts(PktGenConfig[dma_id],mac_id,j,dma_id); | |
713 | else | |
714 | MacTxPort[mac_id].dma[dma_id].gen_txpacket(j*(dma_id + 1),PktGenConfig[dma_id]); | |
715 | } | |
716 | } | |
717 | ||
718 | task niu_tx_test_class :: kick_dmas(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids,integer port_enb) | |
719 | { | |
720 | ||
721 | integer i,j,i1; | |
722 | bit [63:0] kick_limit[24] = 64'h0; | |
723 | bit [63:0] accum_kick[24] = 64'h0; | |
724 | bit [63:0] hd_ptr[24] = 64'h0; | |
725 | bit [23:0] kick_done = 24'h0; | |
726 | // integer kick_all = 1; | |
727 | ||
728 | // based on the kick mode from the control file kick appropriately | |
729 | ||
730 | ||
731 | if(port_enb) { | |
732 | ||
733 | if(tx_control.kick_mode == 1) { | |
734 | if(tx_control.random_rst) | |
735 | kick_all_wrreset(no_of_pkts,mac_id,dma_ids); | |
736 | else | |
737 | kick_all(no_of_pkts,mac_id,dma_ids); | |
738 | } else if(tx_control.kick_mode == 2) { | |
739 | kick_npkts(no_of_pkts,mac_id,dma_ids); | |
740 | } else if(tx_control.kick_mode == 3){ | |
741 | kick_rnum_pkts(no_of_pkts,mac_id,dma_ids); | |
742 | } | |
743 | } else repeat(2) @(posedge CLOCK); | |
744 | } | |
745 | ||
746 | //---- Task to Initial DMAS --------// | |
747 | ||
748 | task niu_tx_test_class :: InitTxDMA(integer no_of_pkts,integer mac_id,integer dma_id) | |
749 | { | |
750 | ||
751 | integer j; | |
752 | integer rng_len; | |
753 | ||
754 | j = dma_id; | |
755 | ||
756 | //------ TDMC init -------------// | |
757 | if(tx_control.kick_mode == 2) { | |
758 | if(tx_control.gather_mode || tx_control.random_gmode || (tx_control.pkt_len == 0)) | |
759 | rng_len = tx_control.kmode2_npkts*15%8 ? tx_control.kmode2_npkts*15/8 + 1 : tx_control.kmode2_npkts*15/8; | |
760 | else | |
761 | rng_len = tx_control.kmode2_npkts/8 + 2; | |
762 | } else if(tx_control.kick_mode == 3) { | |
763 | if(tx_control.gather_mode || tx_control.random_gmode || (tx_control.pkt_len == 0)) | |
764 | rng_len = 2 + random()%255; | |
765 | else | |
766 | rng_len = tx_control.ring_len; | |
767 | } else { | |
768 | if(tx_control.random_num_pkts) { | |
769 | rand_num_pkts[j] = 1 + no_of_pkts/2 + random()%no_of_pkts/2; | |
770 | printf("TX_TEST_CL : no_of_pkts for DMA %d is %d\n",dma_id,rand_num_pkts[j]); | |
771 | ||
772 | if(tx_control.gather_mode || tx_control.random_gmode || (tx_control.pkt_len == 0)) | |
773 | rng_len = (rand_num_pkts[j]*15)%8 ? (rand_num_pkts[j]*15)/8 + 1 : (rand_num_pkts[j]*15)/8; | |
774 | else | |
775 | rng_len = rand_num_pkts[j]%8 ? rand_num_pkts[j]/8 + 1 : rand_num_pkts[j]/8; | |
776 | } else { | |
777 | if(tx_control.gather_mode || tx_control.random_gmode || (tx_control.pkt_len == 0)) { | |
778 | if(tx_control.ring_len > 0) | |
779 | rng_len = tx_control.ring_len; | |
780 | else | |
781 | rng_len = (no_of_pkts*15)%8 ? (no_of_pkts*15)/8 + 1 : (no_of_pkts*15)/8; | |
782 | } else { | |
783 | if(tx_control.ring_len > 0) | |
784 | rng_len = tx_control.ring_len; | |
785 | else | |
786 | rng_len = no_of_pkts%8 ? no_of_pkts/8 + 1 : no_of_pkts/8; | |
787 | } | |
788 | } | |
789 | } | |
790 | ||
791 | ||
792 | be_msg.print(e_mesg_info,"tx_test_class","init_dmas","Ring_Length of DMA %d is %d\n",dma_id,rng_len); | |
793 | tx_dma_init(mac_id,rng_len,dma_id); | |
794 | ||
795 | } | |
796 | ||
797 | ||
798 | ||
799 | //---- Task to kick all pkts at one go ------------// | |
800 | ||
801 | task niu_tx_test_class :: kick_all(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids) | |
802 | { | |
803 | shadow integer i1; | |
804 | integer j; | |
805 | integer dma_id; | |
806 | bit [63:0] data; | |
807 | bit done = 1'b0; | |
808 | integer list; | |
809 | integer sync_pkt_chk = 0; | |
810 | integer num_dmas_bp = 0; | |
811 | ||
812 | //--- New the Macport and assign the dma list to the mac port | |
813 | ||
814 | list = dma_ids; | |
815 | ||
816 | // MacTxPort[mac_id] = new(mac_id); | |
817 | ||
818 | // add channels to the port for verif | |
819 | if(tx_control.enb_intr) { | |
820 | // this bind is taken care in the test | |
821 | } else { | |
822 | for(j=0;j<no_of_txdmas;j++) { | |
823 | if(dma_ids[j]) { | |
824 | MacTxPort[mac_id].add_channels(j); | |
825 | set_max_burst(mac_id,j); | |
826 | } | |
827 | } | |
828 | } | |
829 | ||
830 | // bind the dmas to the port | |
831 | MacTxPort[mac_id].SetActive(list); | |
832 | ||
833 | tx_kick_done[mac_id] = 0; | |
834 | ||
835 | //-- generate the pkts and kick all pkts ------// | |
836 | ||
837 | for(i1=0;i1<no_of_txdmas;i1++) { | |
838 | repeat(50) @(posedge CLOCK); | |
839 | fork { | |
840 | if(dma_ids[i1]) { | |
841 | ||
842 | dma_id = i1; | |
843 | ||
844 | InitTxDMA(no_of_pkts,mac_id,i1); | |
845 | ||
846 | if(tx_control.random_num_pkts) | |
847 | generate_pkts(rand_num_pkts[i1],mac_id,i1); | |
848 | else | |
849 | generate_pkts(no_of_pkts,mac_id,i1); | |
850 | // unstall the DMA | |
851 | MacTxPort[mac_id].dma[i1].SetTxCs(64'h2000_0000); | |
852 | ||
853 | // add the start stop task here | |
854 | ||
855 | if(tx_control.stop_unstall) { | |
856 | fork | |
857 | { | |
858 | MacTxPort[mac_id].dma[i1].stop_unstall_dma(pkts_done[mac_id]); | |
859 | } | |
860 | join none | |
861 | } | |
862 | ||
863 | ||
864 | if(tx_ports_sync_semaphore != -1) { | |
865 | semaphore_put(tx_ports_sync_semaphore, 1); | |
866 | semaphore_get(WAIT, tx_ports_sync_semaphore, total_tx_ports); | |
867 | semaphore_put(tx_ports_sync_semaphore, total_tx_ports); | |
868 | printf("niu_tx_test_class got tx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
869 | tx_ports_sync_semaphore, total_tx_ports); | |
870 | } | |
871 | ||
872 | if(rx_ports_sync_semaphore != -1) { | |
873 | semaphore_get(WAIT, rx_ports_sync_semaphore, total_tx_ports); | |
874 | semaphore_put(rx_ports_sync_semaphore, total_tx_ports); | |
875 | printf("niu_tx_test_class got rx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
876 | rx_ports_sync_semaphore, total_tx_ports); | |
877 | } | |
878 | ||
879 | MacTxPort[mac_id].dma[i1].setTxRingKick(MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr); | |
880 | printf("DMA_id %d kicked at time %d\n", i1, TIME); | |
881 | ||
882 | // add this to sync the pkt_cnt check | |
883 | sync_pkt_chk++; | |
884 | ||
885 | if(tx_control.sync_dmas) { | |
886 | if(dma_ids[23] == 1'b1) | |
887 | txc_util.txc_init(64'h1f); | |
888 | } | |
889 | ||
890 | ||
891 | repeat(2) @(posedge CLOCK); | |
892 | ||
893 | if(tx_control.enb_intr) { | |
894 | // do nothing taken care in ISR | |
895 | } else { | |
896 | fork { | |
897 | mailbox_update(mac_id,i1); | |
898 | } | |
899 | join none | |
900 | } | |
901 | ||
902 | } | |
903 | } join none | |
904 | } | |
905 | ||
906 | tx_kick_done[mac_id] = 1; | |
907 | ||
908 | num_dmas_bp = get_num_of_dmas_bport(dma_ids); | |
909 | ||
910 | // wait till sync_pkt_chk goes > 0 | |
911 | ||
912 | if(dma_ids == 24'h0) | |
913 | // sync_pkt_chk++; | |
914 | sync_pkt_chk = 0; | |
915 | ||
916 | while(sync_pkt_chk != num_dmas_bp) { | |
917 | repeat(100) @(posedge CLOCK); | |
918 | } | |
919 | ||
920 | ||
921 | if(tx_control.random_num_pkts) | |
922 | MacTxPort[mac_id].check_randompkt_cnt(rand_num_pkts,tx_control.pktcnt_rd_intv); | |
923 | else | |
924 | MacTxPort[mac_id].check_pkt_cnt(no_of_pkts,tx_control.pktcnt_rd_intv); | |
925 | ||
926 | if(get_plus_arg( CHECK, "MAC_LOOP_BACK=")) { | |
927 | for(j=0;j<no_of_txdmas;j++) { | |
928 | if(dma_ids[j] & ~done) { | |
929 | done = 1; | |
930 | dma_id = j; | |
931 | generate_pkts(1,mac_id,dma_id,1); | |
932 | MacTxPort[mac_id].dma[j].setTxRingKick(MacTxPort[mac_id].dma[j].desc_ring.ring_current_addr); | |
933 | printf("TX_TEST_CL : LOOP_BACK_MODE last_pkt gentd for dma %d\n",dma_ids[j]); | |
934 | } | |
935 | } | |
936 | } | |
937 | ||
938 | if(get_plus_arg(CHECK,"BYPASS_TXDRR")) { | |
939 | // do nothing | |
940 | } else { | |
941 | MacTxPort[mac_id].check_exit_status(); | |
942 | } | |
943 | } | |
944 | ||
945 | //---- Task to setup n pkts at a time and kick npkts ------------// | |
946 | ||
947 | task niu_tx_test_class :: kick_npkts(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids) | |
948 | { | |
949 | shadow integer i1; | |
950 | integer npkts = tx_control.kmode2_npkts; | |
951 | integer pkts_tobe_gentd[24]; | |
952 | bit [23:0] kick_done = 24'h0; | |
953 | integer total_pkts[24]; | |
954 | bit [63:0] hd_ptr[24] = 64'h0; | |
955 | bit [63:0] tail_ptr[24] = 64'h0; | |
956 | integer list,j; | |
957 | ||
958 | integer tot_pkts[24]; | |
959 | integer pkts_toreclaim[24]; | |
960 | integer loop_cnt[24]; | |
961 | integer wrap_cnt[24]; | |
962 | integer dect_pose[24]; | |
963 | integer dect_neg[24]; | |
964 | integer start[24]; | |
965 | integer count[24]; | |
966 | integer tail_wrap[24]; | |
967 | integer rd_tx_rng_hdl_delay = 50; | |
968 | ||
969 | list = dma_ids; | |
970 | ||
971 | // MacTxPort[mac_id] = new(mac_id); | |
972 | ||
973 | // add channels to the port for verif | |
974 | if(tx_control.enb_intr) { | |
975 | // this bind is taken care in the test | |
976 | } else { | |
977 | for(j=0;j<no_of_txdmas;j++) { | |
978 | if(dma_ids[j]) { | |
979 | MacTxPort[mac_id].add_channels(j); | |
980 | set_max_burst(mac_id,j); | |
981 | } | |
982 | } | |
983 | } | |
984 | ||
985 | // bind the dmas to the port | |
986 | MacTxPort[mac_id].SetActive(list); | |
987 | ||
988 | ||
989 | for(i1=0;i1<no_of_txdmas;i1++) { | |
990 | fork { | |
991 | ||
992 | tot_pkts[i1] = 0; | |
993 | pkts_toreclaim[i1] = 0; | |
994 | loop_cnt[i1] = 0; | |
995 | wrap_cnt[i1] = 0; | |
996 | dect_pose[i1] = 0; | |
997 | dect_neg[i1] = 1; | |
998 | start[i1] = 0; | |
999 | count[i1] = 0; | |
1000 | tail_wrap[i1] = 0; | |
1001 | // hd_wrap[i1] = 0; | |
1002 | ||
1003 | if(dma_ids[i1]) { | |
1004 | ||
1005 | InitTxDMA(no_of_pkts,mac_id,i1); | |
1006 | ||
1007 | // unstall the DMA | |
1008 | ||
1009 | MacTxPort[mac_id].dma[i1].SetTxCs(64'h0); | |
1010 | ||
1011 | total_pkts[i1] = 0; | |
1012 | ||
1013 | // add the start stop task here | |
1014 | ||
1015 | if(tx_control.stop_unstall) { | |
1016 | fork | |
1017 | { | |
1018 | MacTxPort[mac_id].dma[i1].stop_unstall_dma(pkts_done[mac_id]); | |
1019 | } | |
1020 | join none | |
1021 | } | |
1022 | ||
1023 | while(~kick_done[i1]) { | |
1024 | loop_cnt[i1]++; | |
1025 | count[i1] = 0; | |
1026 | printf("TX_TEST_CL : loop count %0d\n",loop_cnt[i1]); | |
1027 | ||
1028 | if(total_pkts[i1] < no_of_pkts) { | |
1029 | ||
1030 | if((no_of_pkts - total_pkts[i1]) > npkts) { | |
1031 | ||
1032 | if(tx_control.random_num_pkts) | |
1033 | pkts_tobe_gentd[i1] = 1 + random()%npkts; | |
1034 | else | |
1035 | pkts_tobe_gentd[i1] = npkts; | |
1036 | ||
1037 | generate_pkts(pkts_tobe_gentd[i1],mac_id,i1); | |
1038 | if(tx_control.kick_partial) | |
1039 | tail_ptr[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr - 64'h20; | |
1040 | else | |
1041 | tail_ptr[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr; | |
1042 | } else { | |
1043 | pkts_tobe_gentd[i1] = no_of_pkts - total_pkts[i1]; | |
1044 | generate_pkts(pkts_tobe_gentd[i1],mac_id,i1); | |
1045 | tail_ptr[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr; | |
1046 | } | |
1047 | ||
1048 | printf("Tx_test_cl : Kick_mode2, pkts_gen_in current kick %d for dma %d\n",pkts_tobe_gentd[i1],i1); | |
1049 | printf("Tail_PTR %0h\n",tail_ptr[i1]); | |
1050 | if(tx_ports_sync_semaphore != -1) { | |
1051 | semaphore_put(tx_ports_sync_semaphore, 1); | |
1052 | semaphore_get(WAIT, tx_ports_sync_semaphore, total_tx_ports); | |
1053 | semaphore_put(tx_ports_sync_semaphore, total_tx_ports); | |
1054 | printf("niu_tx_test_class got tx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
1055 | tx_ports_sync_semaphore, total_tx_ports); | |
1056 | } | |
1057 | ||
1058 | if(rx_ports_sync_semaphore != -1) { | |
1059 | semaphore_get(WAIT, rx_ports_sync_semaphore, total_tx_ports); | |
1060 | semaphore_put(rx_ports_sync_semaphore, total_tx_ports); | |
1061 | printf("niu_tx_test_class got rx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
1062 | rx_ports_sync_semaphore, total_tx_ports); | |
1063 | } | |
1064 | MacTxPort[mac_id].dma[i1].setTxRingKick(tail_ptr[i1]); | |
1065 | ||
1066 | tail_wrap[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_wrapped; | |
1067 | ||
1068 | total_pkts[i1] = total_pkts[i1] + pkts_tobe_gentd[i1]; | |
1069 | // printf("TX_TEST_CL : TOT_PKTS is %0d for dma %0d\n",total_pkts[i1],i1); | |
1070 | ||
1071 | MacTxPort[mac_id].dma[i1].RdTxRngHDL(hd_ptr[i1]); | |
1072 | // hd_wrap[i1] = hd_ptr[i1][19]; | |
1073 | // wait until certain diff between hd and tail ptr | |
1074 | // while((tail_ptr[i1][18:3] - hd_ptr[i1][18:3] != 0) && (count[i1] < 50)) | |
1075 | while(tail_ptr[i1][18:3] - hd_ptr[i1][18:3] != 0) { | |
1076 | MacTxPort[mac_id].dma[i1].RdTxRngHDL(hd_ptr[i1]); | |
1077 | if(get_plus_arg(CHECK,"RD_TX_RNG_HDL_DELAY")) | |
1078 | rd_tx_rng_hdl_delay = get_plus_arg(NUM,"RD_TX_RNG_HDL_DELAY"); | |
1079 | repeat(rd_tx_rng_hdl_delay) @(posedge CLOCK); | |
1080 | count[i1]++; | |
1081 | } | |
1082 | ||
1083 | printf("TX_TEST CL : head_ptr %d\n",hd_ptr[i1][18:3]); | |
1084 | printf("TX_TEST CL : head_ptr_wrap %d\n",hd_ptr[i1][19]); | |
1085 | ||
1086 | if(dect_pose[i1] == 0) { | |
1087 | if(hd_ptr[i1][19]) { | |
1088 | wrap_cnt[i1]++; | |
1089 | dect_pose[i1] = 1; | |
1090 | dect_neg[i1] = 0; | |
1091 | } | |
1092 | } | |
1093 | ||
1094 | if(dect_neg[i1] == 0) { | |
1095 | if(~hd_ptr[i1][19]) { | |
1096 | wrap_cnt[i1]++; | |
1097 | dect_pose[i1] = 0; | |
1098 | dect_neg[i1] = 1; | |
1099 | } | |
1100 | } | |
1101 | ||
1102 | // read the pkt_cnt | |
1103 | ||
1104 | // MacTxPort[mac_id].dma[i1].RdTxPktCnt(tot_pkts); | |
1105 | ||
1106 | tot_pkts[i1] = wrap_cnt[i1]*tx_control.ring_len*8 + hd_ptr[i1][18:3]; | |
1107 | pkts_toreclaim[i1] = tot_pkts[i1] - pkts_toreclaim[i1]; | |
1108 | ||
1109 | // call the task to reclaim the buffers | |
1110 | ||
1111 | if(start[i1] == 0) { | |
1112 | MacTxPort[mac_id].dma[i1].reclaim_buffers(1,pkts_toreclaim[i1]-1); | |
1113 | start[i1] = 1; | |
1114 | } else MacTxPort[mac_id].dma[i1].reclaim_buffers(1,pkts_toreclaim[i1]); | |
1115 | ||
1116 | pkts_toreclaim[i1] = tot_pkts[i1]; | |
1117 | ||
1118 | ||
1119 | } else { | |
1120 | kick_done[i1] = 1'b1; | |
1121 | } | |
1122 | } | |
1123 | ||
1124 | // MacTxPort[mac_id].dma[i1].reclaim_buffers(1,loop_cnt[i1]-1); | |
1125 | } else repeat(2) @(posedge CLOCK); | |
1126 | } join none | |
1127 | } | |
1128 | // wait_child(); | |
1129 | MacTxPort[mac_id].check_pkt_cnt(no_of_pkts,tx_control.pktcnt_rd_intv); | |
1130 | ||
1131 | if(get_plus_arg(CHECK,"BYPASS_TXDRR")) { | |
1132 | // do nothing | |
1133 | } else { | |
1134 | MacTxPort[mac_id].check_exit_status(); | |
1135 | } | |
1136 | ||
1137 | } | |
1138 | ||
1139 | //---- Task to setup and kick random number of pkts ------------// | |
1140 | //--- without waiting for head_ptr == tail_ptr -----------------// | |
1141 | ||
1142 | task niu_tx_test_class :: kick_rnum_pkts(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids) | |
1143 | { | |
1144 | shadow integer i1,k; | |
1145 | integer npkts; | |
1146 | integer pkts_tobe_gentd[24]; | |
1147 | bit [23:0] kick_done = 24'h0; | |
1148 | integer total_pkts[24]; | |
1149 | bit [63:0] hd_ptr[24]; | |
1150 | bit [63:0] tail_ptr[24]; | |
1151 | // bit [63:0] kick_ptr[24]; | |
1152 | integer kick_ptr[24]; | |
1153 | integer list,j; | |
1154 | integer hd_wrap[24]; | |
1155 | integer tail_wrap[24]; | |
1156 | ||
1157 | integer tot_pkts[24]; | |
1158 | integer pkts_toreclaim[24]; | |
1159 | integer loop_cnt[24]; | |
1160 | integer wrap_cnt[24]; | |
1161 | integer dect_pose[24]; | |
1162 | integer dect_neg[24]; | |
1163 | integer start[24]; | |
1164 | integer count[24]; | |
1165 | ||
1166 | list = dma_ids; | |
1167 | ||
1168 | // MacTxPort[mac_id] = new(mac_id); | |
1169 | ||
1170 | // add channels to the port for verif | |
1171 | if(tx_control.enb_intr) { | |
1172 | // this bind is taken care in the test | |
1173 | } else { | |
1174 | for(j=0;j<no_of_txdmas;j++) { | |
1175 | if(dma_ids[j]) { | |
1176 | MacTxPort[mac_id].add_channels(j); | |
1177 | set_max_burst(mac_id,j); | |
1178 | } | |
1179 | } | |
1180 | } | |
1181 | ||
1182 | // bind the dmas to the port | |
1183 | MacTxPort[mac_id].SetActive(list); | |
1184 | ||
1185 | ||
1186 | for(i1=0;i1<no_of_txdmas;i1++) { | |
1187 | fork { | |
1188 | ||
1189 | tot_pkts[i1] = 0; | |
1190 | pkts_toreclaim[i1] = 0; | |
1191 | loop_cnt[i1] = 0; | |
1192 | wrap_cnt[i1] = 0; | |
1193 | dect_pose[i1] = 0; | |
1194 | dect_neg[i1] = 1; | |
1195 | start[i1] = 0; | |
1196 | count[i1] = 0; | |
1197 | hd_ptr[i1] = 64'h0; | |
1198 | tail_ptr[i1] = 64'h0; | |
1199 | kick_ptr[i1] = 0; | |
1200 | hd_wrap[i1] = 0; | |
1201 | tail_wrap[i1] = 0; | |
1202 | ||
1203 | if(dma_ids[i1]) { | |
1204 | ||
1205 | InitTxDMA(no_of_pkts,mac_id,i1); | |
1206 | ||
1207 | // unstall the DMA | |
1208 | ||
1209 | MacTxPort[mac_id].dma[i1].SetTxCs(64'h0); | |
1210 | ||
1211 | printf("TX_TEST_CL : kick_done for dma %0d is %0b\n",i1,kick_done[i1]); | |
1212 | ||
1213 | total_pkts[i1] = 0; | |
1214 | printf("TX_TEST_CL : Total_pkts for dma %0d is %0d\n",i1,total_pkts[i1]); | |
1215 | ||
1216 | // add the start stop task here | |
1217 | ||
1218 | if(tx_control.stop_unstall) { | |
1219 | fork | |
1220 | { | |
1221 | for(k=0;k<no_of_pkts;k++) { | |
1222 | repeat(random()%100) @(posedge CLOCK); | |
1223 | random_stop_start_dma(mac_id,i1); | |
1224 | } | |
1225 | // MacTxPort[mac_id].dma[i1].stop_unstall_dma(100); | |
1226 | } | |
1227 | join none | |
1228 | } | |
1229 | ||
1230 | while(~kick_done[i1]) { | |
1231 | loop_cnt[i1]++; | |
1232 | count[i1] = 0; | |
1233 | printf("TX_TEST_CL : loop count %0d\n",loop_cnt[i1]); | |
1234 | ||
1235 | if(total_pkts[i1] < no_of_pkts) { | |
1236 | ||
1237 | MacTxPort[mac_id].dma[i1].RdTxRngHDL(hd_ptr[i1]); | |
1238 | hd_wrap[i1] = hd_ptr[i1][19]; | |
1239 | ||
1240 | if(tail_ptr[i1][18:3] > hd_ptr[i1][18:3]) | |
1241 | kick_ptr[i1] = MacTxPort[mac_id].dma[i1].ring_size*8 - tail_ptr[i1][18:3] + hd_ptr[i1][18:3]; | |
1242 | else if(tail_ptr[i1][18:3] < hd_ptr[i1][18:3]) | |
1243 | kick_ptr[i1] = hd_ptr[i1][18:3] - tail_ptr[i1][18:3]; | |
1244 | else if(tail_ptr[i1][18:3] == hd_ptr[i1][18:3]) { | |
1245 | if(tail_wrap[i1] == hd_wrap[i1]) | |
1246 | kick_ptr[i1] = MacTxPort[mac_id].dma[i1].ring_size*8; | |
1247 | else | |
1248 | kick_ptr[i1] = 0; | |
1249 | } | |
1250 | ||
1251 | ||
1252 | if(tx_control.gather_mode || tx_control.random_gmode || (tx_control.pkt_len == 0)) { | |
1253 | npkts = kick_ptr[i1]/15; | |
1254 | } else { | |
1255 | npkts = kick_ptr[i1]; | |
1256 | } | |
1257 | ||
1258 | if(npkts > (no_of_pkts - total_pkts[i1])) | |
1259 | npkts = no_of_pkts - total_pkts[i1]; | |
1260 | ||
1261 | printf("TX_TEST_CL : random_kicks , pkts kicked %d for DMA %d\n", npkts,i1); | |
1262 | ||
1263 | if(npkts > 0) | |
1264 | pkts_tobe_gentd[i1] = 1 + random()%npkts; | |
1265 | else | |
1266 | pkts_tobe_gentd[i1] = 0; | |
1267 | ||
1268 | if(pkts_tobe_gentd[i1] > 0) { | |
1269 | generate_pkts(pkts_tobe_gentd[i1],mac_id,i1); | |
1270 | ||
1271 | tail_ptr[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr; | |
1272 | printf("Tail_PTR %0h\n",tail_ptr[i1]); | |
1273 | ||
1274 | if(tx_ports_sync_semaphore != -1) { | |
1275 | semaphore_put(tx_ports_sync_semaphore, 1); | |
1276 | semaphore_get(WAIT, tx_ports_sync_semaphore, total_tx_ports); | |
1277 | semaphore_put(tx_ports_sync_semaphore, total_tx_ports); | |
1278 | printf("niu_tx_test_class got tx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
1279 | tx_ports_sync_semaphore, total_tx_ports); | |
1280 | } | |
1281 | ||
1282 | if(rx_ports_sync_semaphore != -1) { | |
1283 | semaphore_get(WAIT, rx_ports_sync_semaphore, total_tx_ports); | |
1284 | semaphore_put(rx_ports_sync_semaphore, total_tx_ports); | |
1285 | printf("niu_tx_test_class got rx_ports_sync_semaphore :%0d, total_tx_ports:%0d\n", | |
1286 | rx_ports_sync_semaphore, total_tx_ports); | |
1287 | } | |
1288 | MacTxPort[mac_id].dma[i1].setTxRingKick(tail_ptr[i1]); | |
1289 | } | |
1290 | ||
1291 | tail_wrap[i1] = MacTxPort[mac_id].dma[i1].desc_ring.ring_wrapped; | |
1292 | ||
1293 | total_pkts[i1] = total_pkts[i1] + pkts_tobe_gentd[i1]; | |
1294 | // printf("TX_TEST_CL : TOT_PKTS is %0d for dma %0d\n",total_pkts[i1],i1); | |
1295 | ||
1296 | if(dect_pose[i1] == 0) { | |
1297 | if(hd_ptr[i1][19]) { | |
1298 | wrap_cnt[i1]++; | |
1299 | dect_pose[i1] = 1; | |
1300 | dect_neg[i1] = 0; | |
1301 | } | |
1302 | } | |
1303 | ||
1304 | if(dect_neg[i1] == 0) { | |
1305 | if(~hd_ptr[i1][19]) { | |
1306 | wrap_cnt[i1]++; | |
1307 | dect_pose[i1] = 0; | |
1308 | dect_neg[i1] = 1; | |
1309 | } | |
1310 | } | |
1311 | ||
1312 | // MacTxPort[mac_id].dma[i1].RdTxPktCnt(tot_pkts[i1]); | |
1313 | ||
1314 | tot_pkts[i1] = wrap_cnt[i1]*MacTxPort[mac_id].dma[i1].ring_size*8 + hd_ptr[i1][18:3]; | |
1315 | pkts_toreclaim[i1] = tot_pkts[i1] - pkts_toreclaim[i1]; | |
1316 | ||
1317 | // call the task to reclaim the buffers | |
1318 | ||
1319 | if(pkts_toreclaim[i1] > 0) { | |
1320 | if(start[i1] == 0) { | |
1321 | MacTxPort[mac_id].dma[i1].reclaim_buffers(1,pkts_toreclaim[i1]-1); | |
1322 | start[i1] = 1; | |
1323 | } else MacTxPort[mac_id].dma[i1].reclaim_buffers(1,pkts_toreclaim[i1]); | |
1324 | } | |
1325 | ||
1326 | pkts_toreclaim[i1] = tot_pkts[i1]; | |
1327 | ||
1328 | ||
1329 | } else { | |
1330 | kick_done[i1] = 1'b1; | |
1331 | } | |
1332 | repeat(random()%200) @(posedge CLOCK); | |
1333 | } | |
1334 | ||
1335 | // MacTxPort[mac_id].dma[i1].reclaim_buffers(1,loop_cnt[i1]-1); | |
1336 | } else repeat(2) @(posedge CLOCK); | |
1337 | } join none | |
1338 | } | |
1339 | // wait_child(); | |
1340 | MacTxPort[mac_id].check_pkt_cnt(no_of_pkts,tx_control.pktcnt_rd_intv); | |
1341 | ||
1342 | if(get_plus_arg(CHECK,"BYPASS_TXDRR")) { | |
1343 | // do nothing | |
1344 | } else { | |
1345 | MacTxPort[mac_id].check_exit_status(); | |
1346 | } | |
1347 | ||
1348 | } | |
1349 | ||
1350 | ||
1351 | //---- Task to setup pkt_len----------------// | |
1352 | ||
1353 | task niu_tx_test_class :: set_pkt_len(integer pkt_len_param, integer dma_id, integer pkt_num) { | |
1354 | ||
1355 | // set the pkt len for the pkt | |
1356 | case(pkt_len_param) { | |
1357 | 0 : { | |
1358 | // PktGenConfig[dma_id].data_length = 128 + random()%9189; | |
1359 | randcase { | |
1360 | 27: PktGenConfig[dma_id].data_length = urandom_range(500, 128); | |
1361 | 13: PktGenConfig[dma_id].data_length = urandom_range(1000, 500); | |
1362 | 40: PktGenConfig[dma_id].data_length = urandom_range(1600, 1000); | |
1363 | 10: PktGenConfig[dma_id].data_length = urandom_range(4000, 1600); | |
1364 | 10: PktGenConfig[dma_id].data_length = urandom_range(9200, 4000); | |
1365 | } | |
1366 | } | |
1367 | 1 : PktGenConfig[dma_id].data_length = 64 + pkt_num; | |
1368 | 2 : PktGenConfig[dma_id].data_length = 500 + pkt_num; | |
1369 | 3 : PktGenConfig[dma_id].data_length = 1000+ pkt_num; | |
1370 | 4 : PktGenConfig[dma_id].data_length = 1500 + pkt_num; | |
1371 | 5 : PktGenConfig[dma_id].data_length = 2000 + pkt_num; | |
1372 | 6 : PktGenConfig[dma_id].data_length = 2500 + pkt_num; | |
1373 | 7 : PktGenConfig[dma_id].data_length = 3000 + pkt_num; | |
1374 | 8 : PktGenConfig[dma_id].data_length = 3500 + pkt_num; | |
1375 | 9 : PktGenConfig[dma_id].data_length = 4000 + pkt_num; | |
1376 | 10 : PktGenConfig[dma_id].data_length = 4500 + pkt_num; | |
1377 | 11 : PktGenConfig[dma_id].data_length = 5000 + pkt_num; | |
1378 | 12 : PktGenConfig[dma_id].data_length = 5500 + pkt_num; | |
1379 | 13 : PktGenConfig[dma_id].data_length = 6000 + pkt_num; | |
1380 | 14 : PktGenConfig[dma_id].data_length = 6500 + pkt_num; | |
1381 | 15 : PktGenConfig[dma_id].data_length = 7000 + pkt_num; | |
1382 | 16 : PktGenConfig[dma_id].data_length = 7500 + pkt_num; | |
1383 | 17 : PktGenConfig[dma_id].data_length = 8000 + pkt_num; | |
1384 | 18 : PktGenConfig[dma_id].data_length = 8500 + pkt_num; | |
1385 | 19 : PktGenConfig[dma_id].data_length = 9000 + pkt_num; | |
1386 | default : { | |
1387 | // added this piece of code to protect pkt_lens > 9588 | |
1388 | if(pkt_len_param > 9588) | |
1389 | PktGenConfig[dma_id].data_length = 9588; | |
1390 | else | |
1391 | PktGenConfig[dma_id].data_length = pkt_len_param; | |
1392 | } | |
1393 | } | |
1394 | } | |
1395 | ||
1396 | task niu_tx_test_class :: set_pad_bytes(integer dma_id, integer pkt_num) { | |
1397 | ||
1398 | // set pad bytes | |
1399 | case(tx_control.insert_pad) { | |
1400 | 0 : PktGenConfig[dma_id].pad = 0; | |
1401 | 1 : PktGenConfig[dma_id].pad = pkt_num%8; // sweep the pad bytes | |
1402 | 2 : PktGenConfig[dma_id].pad = random()%8; | |
1403 | 3 : PktGenConfig[dma_id].pad = tx_control.pad_bytes; | |
1404 | } | |
1405 | ||
1406 | // printf("TX_TEST_CL : Pad offset is %0d for pkt %0d\n",PktGenConfig[dma_id].pad,pkt_num); | |
1407 | } | |
1408 | ||
1409 | task niu_tx_test_class :: setup_random_dmabinds(var bit [23:0] dmas_port0, var bit [23:0] dmas_port1, | |
1410 | var bit [23:0] dmas_port2, var bit [23:0] dmas_port3) | |
1411 | { | |
1412 | ||
1413 | integer i,dma_num; | |
1414 | integer no_of_port0_dmas; | |
1415 | integer no_of_port1_dmas; | |
1416 | integer no_of_port2_dmas; | |
1417 | integer no_of_port3_dmas; | |
1418 | integer no_of_dmas_unused; | |
1419 | bit [23:0] mask = 24'h0; | |
1420 | bit [23:0] in_dmas_port0 = 24'h0; | |
1421 | bit [23:0] in_dmas_port1 = 24'h0; | |
1422 | bit [23:0] in_dmas_port2 = 24'h0; | |
1423 | bit [23:0] in_dmas_port3 = 24'h0; | |
1424 | ||
1425 | no_of_port0_dmas = 1 + random()%no_of_txdmas; | |
1426 | printf("RAND_DMA_BIND : No_of Dmas bound to Port0 is %0d\n",no_of_port0_dmas); | |
1427 | for(i=0;i<no_of_port0_dmas;i++) { | |
1428 | dma_num = random()%no_of_txdmas; | |
1429 | while(mask[dma_num] == 1'b1) { | |
1430 | dma_num = random()%no_of_txdmas; | |
1431 | } | |
1432 | ||
1433 | printf("RAND_DMA_BIND : Dma_Num %0d bound to Port0\n",dma_num); | |
1434 | in_dmas_port0[dma_num] = 1'b1; | |
1435 | mask = mask | in_dmas_port0; | |
1436 | } | |
1437 | ||
1438 | printf("RAND_DMA_BIND : MASK after port0 assign %0h\n",mask); | |
1439 | ||
1440 | no_of_dmas_unused = no_of_txdmas - no_of_port0_dmas; | |
1441 | ||
1442 | ||
1443 | if(no_of_txdmas == 16) { | |
1444 | if(no_of_dmas_unused == 0) | |
1445 | no_of_port1_dmas = 0; | |
1446 | else | |
1447 | // no_of_port1_dmas = 1 + random()%no_of_dmas_unused; | |
1448 | // assign the remaining DMAs to port1 | |
1449 | no_of_port1_dmas = no_of_dmas_unused; | |
1450 | ||
1451 | printf("RAND_DMA_BIND : No_of Dmas bound to Port1 is %0d\n",no_of_port1_dmas); | |
1452 | ||
1453 | for(i=0;i<no_of_port1_dmas;i++) { | |
1454 | dma_num = random()%no_of_txdmas; | |
1455 | ||
1456 | while(mask[dma_num] == 1'b1) { | |
1457 | dma_num = random()%no_of_txdmas; | |
1458 | } | |
1459 | ||
1460 | printf("RAND_DMA_BIND : Dma_Num %0d bound to Port1\n",dma_num); | |
1461 | in_dmas_port1[dma_num] = 1'b1; | |
1462 | mask = mask | in_dmas_port1; | |
1463 | } | |
1464 | ||
1465 | printf("RAND_DMA_BIND : MASK after port1 assign %0h\n",mask); | |
1466 | ||
1467 | dmas_port0 = in_dmas_port0; | |
1468 | dmas_port1 = in_dmas_port1; | |
1469 | ||
1470 | printf("RAND_DMA_BIND : port 0 DMA_BIND %0h\n",dmas_port0); | |
1471 | printf("RAND_DMA_BIND : port 1 DMA_BIND %0h\n",dmas_port1); | |
1472 | ||
1473 | } else if(no_of_txdmas == 24) { | |
1474 | ||
1475 | if(no_of_dmas_unused == 0) { | |
1476 | no_of_port1_dmas = 0; | |
1477 | no_of_port2_dmas = 0; | |
1478 | no_of_port3_dmas = 0; | |
1479 | in_dmas_port1 = 24'h0; | |
1480 | in_dmas_port2 = 24'h0; | |
1481 | in_dmas_port3 = 24'h0; | |
1482 | } else { | |
1483 | no_of_port1_dmas = 1 + random()%no_of_dmas_unused; | |
1484 | printf("RAND_DMA_BIND : No_of Dmas bound to Port1 is %0d\n",no_of_port1_dmas); | |
1485 | ||
1486 | for(i=0;i<no_of_port1_dmas;i++) { | |
1487 | dma_num = random()%no_of_txdmas; | |
1488 | ||
1489 | while(mask[dma_num] == 1'b1) { | |
1490 | dma_num = random()%no_of_txdmas; | |
1491 | } | |
1492 | ||
1493 | printf("RAND_DMA_BIND : Dma_Num %0d bound to Port1\n",dma_num); | |
1494 | in_dmas_port1[dma_num] = 1'b1; | |
1495 | mask = mask | in_dmas_port1; | |
1496 | ||
1497 | } | |
1498 | ||
1499 | printf("RAND_DMA_BIND : MASK after port1 assign %0h\n",mask); | |
1500 | ||
1501 | no_of_dmas_unused = no_of_dmas_unused - no_of_port1_dmas; | |
1502 | ||
1503 | if(no_of_dmas_unused == 0) { | |
1504 | no_of_port2_dmas = 0; | |
1505 | no_of_port3_dmas = 0; | |
1506 | in_dmas_port2 = 24'h0; | |
1507 | in_dmas_port3 = 24'h0; | |
1508 | } else { | |
1509 | no_of_port2_dmas = 1 + random()%no_of_dmas_unused; | |
1510 | printf("RAND_DMA_BIND : No_of Dmas bound to Port2 is %0d\n",no_of_port2_dmas); | |
1511 | ||
1512 | for(i=0;i<no_of_port2_dmas;i++) { | |
1513 | dma_num = random()%no_of_txdmas; | |
1514 | ||
1515 | while(mask[dma_num] == 1'b1) { | |
1516 | dma_num = random()%no_of_txdmas; | |
1517 | } | |
1518 | ||
1519 | printf("RAND_DMA_BIND : Dma_Num %0d bound to Port2\n",dma_num); | |
1520 | in_dmas_port2[dma_num] = 1'b1; | |
1521 | mask = mask | in_dmas_port2; | |
1522 | ||
1523 | } | |
1524 | printf("RAND_DMA_BIND : MASK after port2 assign %0h\n",mask); | |
1525 | ||
1526 | no_of_dmas_unused = no_of_dmas_unused - no_of_port2_dmas; | |
1527 | ||
1528 | if(no_of_dmas_unused == 0) { | |
1529 | no_of_port3_dmas = 0; | |
1530 | in_dmas_port3 = 24'h0; | |
1531 | } else { | |
1532 | no_of_port3_dmas = no_of_dmas_unused; | |
1533 | ||
1534 | printf("RAND_DMA_BIND : No_of Dmas bound to Port3 is %0d\n",no_of_port3_dmas); | |
1535 | ||
1536 | for(i=0;i<no_of_port3_dmas;i++) { | |
1537 | dma_num = random()%no_of_txdmas; | |
1538 | ||
1539 | while(mask[dma_num] == 1'b1) { | |
1540 | dma_num = random()%no_of_txdmas; | |
1541 | } | |
1542 | ||
1543 | printf("RAND_DMA_BIND : Dma_Num %0d bound to Port3\n",dma_num); | |
1544 | in_dmas_port3[dma_num] = 1'b1; | |
1545 | mask = mask | in_dmas_port3; | |
1546 | ||
1547 | } | |
1548 | printf("RAND_DMA_BIND : MASK after port3 assign %0h\n",mask); | |
1549 | } | |
1550 | } | |
1551 | } | |
1552 | ||
1553 | dmas_port0 = in_dmas_port0; | |
1554 | dmas_port1 = in_dmas_port1; | |
1555 | dmas_port2 = in_dmas_port2; | |
1556 | dmas_port3 = in_dmas_port3; | |
1557 | ||
1558 | printf("RAND_DMA_BIND : port 0 DMA_BIND %0h\n",dmas_port0); | |
1559 | printf("RAND_DMA_BIND : port 1 DMA_BIND %0h\n",dmas_port1); | |
1560 | printf("RAND_DMA_BIND : port 2 DMA_BIND %0h\n",dmas_port2); | |
1561 | printf("RAND_DMA_BIND : port 3 DMA_BIND %0h\n",dmas_port3); | |
1562 | } | |
1563 | } | |
1564 | ||
1565 | ||
1566 | task niu_tx_test_class :: call_gen_txgatherpkts(TxPacketGenConfig PktGenConfig, integer mac_id, integer pkt_num, integer dma_id) | |
1567 | { | |
1568 | integer i; | |
1569 | integer no_of_gathers; | |
1570 | integer avg_len_pbuff; | |
1571 | integer len_remaining; | |
1572 | integer pkt_page_id; | |
1573 | ||
1574 | @(posedge CLOCK); | |
1575 | // no_of_gathers = 1 + random()%15; | |
1576 | // printf("RAND_GTHR : no_of_gathers %0d\n",no_of_gathers); | |
1577 | // avg_len_pbuff = PktGenConfig.data_length%no_of_gathers + 1; | |
1578 | len_remaining = PktGenConfig.data_length - 4; // crc not included | |
1579 | ||
1580 | // check if len greater than 8100 bytes change the no_gathers | |
1581 | ||
1582 | if(len_remaining > 8100) | |
1583 | no_of_gathers = 3 + random()%13; | |
1584 | // no_of_gathers = 3; | |
1585 | else if(len_remaining > 4060) | |
1586 | no_of_gathers = 2 + random()%14; | |
1587 | // no_of_gathers = 2; | |
1588 | else no_of_gathers = 1 + random()%15; | |
1589 | ||
1590 | printf("RAND_GTHR : no_of_gathers %0d\n",no_of_gathers); | |
1591 | ||
1592 | avg_len_pbuff = PktGenConfig.data_length%no_of_gathers + 1; | |
1593 | ||
1594 | ||
1595 | // PktGenConfig.gConfig_noOfDesc = no_of_gathers; | |
1596 | PktGenConfig.gConfig_mode = 1; | |
1597 | ||
1598 | for(i=0;i<no_of_gathers;i++) { | |
1599 | ||
1600 | // randomize the addroffset except the first descriptor | |
1601 | ||
1602 | if(tx_control.random_addroffset) { | |
1603 | if(i==0) | |
1604 | PktGenConfig.gConfig_alignment[i] = 16; | |
1605 | else | |
1606 | PktGenConfig.gConfig_alignment[i] = 1; | |
1607 | } else { | |
1608 | // PktGenConfig.gConfig_alignment[i] = 16; | |
1609 | PktGenConfig.gConfig_alignment[i] = tx_control.byte_align; | |
1610 | } | |
1611 | ||
1612 | printf("RAND_GTHR : address_offset for gather %0d is %0d\n",i,PktGenConfig.gConfig_alignment[i]); | |
1613 | ||
1614 | if(no_of_gathers == 1) | |
1615 | PktGenConfig.gConfig_length[i] = PktGenConfig.data_length - 4; | |
1616 | else if(i == (no_of_gathers - 1)) | |
1617 | PktGenConfig.gConfig_length[i] = len_remaining; | |
1618 | else if(i == (no_of_gathers - 3)) { | |
1619 | if(len_remaining > 8160) | |
1620 | PktGenConfig.gConfig_length[i] = 4060; | |
1621 | else { | |
1622 | ||
1623 | if(i == 0) { | |
1624 | if(get_plus_arg(CHECK,"FDESC_SLINE_BYTE_ALIGN")) | |
1625 | PktGenConfig.gConfig_length[i] = 1 + random()%4060; | |
1626 | else | |
1627 | PktGenConfig.gConfig_length[i] = 16 + random()%4045; | |
1628 | } else { | |
1629 | PktGenConfig.gConfig_length[i] = 1 + random()%4080; | |
1630 | } | |
1631 | ||
1632 | if(PktGenConfig.gConfig_length[i] >= len_remaining) { | |
1633 | PktGenConfig.gConfig_length[i] = len_remaining; | |
1634 | no_of_gathers = i + 1; | |
1635 | } | |
1636 | } | |
1637 | } else if(i == (no_of_gathers - 2)) { | |
1638 | if(len_remaining > 4060) | |
1639 | PktGenConfig.gConfig_length[i] = 4060; | |
1640 | else { | |
1641 | ||
1642 | if(i == 0) { | |
1643 | if(get_plus_arg(CHECK,"FDESC_SLINE_BYTE_ALIGN")) | |
1644 | PktGenConfig.gConfig_length[i] = 1 + random()%4060; | |
1645 | else | |
1646 | PktGenConfig.gConfig_length[i] = 16 + random()%4065; | |
1647 | } else { | |
1648 | PktGenConfig.gConfig_length[i] = 1 + random()%4080; | |
1649 | } | |
1650 | ||
1651 | if(PktGenConfig.gConfig_length[i] >= len_remaining) { | |
1652 | PktGenConfig.gConfig_length[i] = len_remaining; | |
1653 | no_of_gathers = i + 1; | |
1654 | } | |
1655 | } | |
1656 | } else { | |
1657 | if(i == 0) { | |
1658 | if(get_plus_arg(CHECK,"FDESC_SLINE_BYTE_ALIGN")) | |
1659 | PktGenConfig.gConfig_length[i] = 1 + random()%4060; | |
1660 | else | |
1661 | PktGenConfig.gConfig_length[i] = 16 + random()%4045; | |
1662 | } else { | |
1663 | PktGenConfig.gConfig_length[i] = 1 + random()%4060; | |
1664 | } | |
1665 | ||
1666 | if(PktGenConfig.gConfig_length[i] >= len_remaining) { | |
1667 | PktGenConfig.gConfig_length[i] = len_remaining; | |
1668 | no_of_gathers = i + 1; | |
1669 | } | |
1670 | } | |
1671 | ||
1672 | printf("RAND_GTHR : length_of_gather %0d\n",PktGenConfig.gConfig_length[i]); | |
1673 | ||
1674 | len_remaining = len_remaining - PktGenConfig.gConfig_length[i]; | |
1675 | ||
1676 | printf("RAND_GTHR : remainder pkt_len %0d\n",len_remaining); | |
1677 | } | |
1678 | ||
1679 | PktGenConfig.gConfig_noOfDesc = no_of_gathers; | |
1680 | printf("RAND_GTHR : Actual no_of_gathers %0d\n",no_of_gathers); | |
1681 | ||
1682 | pkt_page_id = random()%2 ? MacTxPort[mac_id].dma[dma_id].page1_id : MacTxPort[mac_id].dma[dma_id].page0_id; | |
1683 | ||
1684 | MacTxPort[mac_id].dma[dma_id].gen_txGatherPackets(PktGenConfig,pkt_page_id); | |
1685 | ||
1686 | } | |
1687 | ||
1688 | task niu_tx_test_class :: mailbox_update(integer mac_id, integer dma_id) | |
1689 | { | |
1690 | bit [63:0] data; | |
1691 | bit [63:0] rd_data; | |
1692 | ||
1693 | while (!pkts_done[mac_id]) { | |
1694 | // enable the mailbox update | |
1695 | // do a read modify write | |
1696 | MacTxPort[mac_id].dma[dma_id].Read_TxCs(rd_data); | |
1697 | ||
1698 | if(rd_data[31]) | |
1699 | data = 64'h8000_0000; | |
1700 | else { | |
1701 | data = {rd_data[63:30],1'b1,rd_data[28:0]}; | |
1702 | MacTxPort[mac_id].dma[dma_id].SetTxCs(data); | |
1703 | mailbox_read(mac_id,dma_id); | |
1704 | } | |
1705 | } | |
1706 | } | |
1707 | ||
1708 | task niu_tx_test_class :: mailbox_read(integer mac_id, integer dma_id) | |
1709 | { | |
1710 | bit [39:0] address; | |
1711 | bit [63:0] rd_data; | |
1712 | integer mbox_to = 100; | |
1713 | integer done = 0; | |
1714 | ||
1715 | while(!done && !pkts_done[mac_id]) { | |
1716 | ||
1717 | if(get_plus_arg(CHECK,"TX_MB_READ_TO")) | |
1718 | mbox_to = get_plus_arg(NUM,"TX_MB_READ_TO"); | |
1719 | ||
1720 | repeat (mbox_to) @(posedge CLOCK); | |
1721 | // address = TX_CS + dma_id*40'h200; | |
1722 | // gen_pio_drv.pio_rd(address,rd_data); | |
1723 | MacTxPort[mac_id].dma[dma_id].Read_TxCs(rd_data); | |
1724 | ||
1725 | ||
1726 | if(~rd_data[29]) { | |
1727 | done = 1; | |
1728 | } else { | |
1729 | done = 0; | |
1730 | } | |
1731 | } | |
1732 | } | |
1733 | ||
1734 | task niu_tx_test_class :: clear_mk(integer dma_id) | |
1735 | { | |
1736 | bit [39:0] address; | |
1737 | bit [63:0] rd_data; | |
1738 | bit [63:0] wr_data; | |
1739 | ||
1740 | ||
1741 | address = TX_CS + dma_id*40'h200; | |
1742 | gen_pio_drv.pio_rd(address,rd_data); | |
1743 | ||
1744 | } | |
1745 | ||
1746 | task niu_tx_test_class :: sync_on_pkts_done(integer mac_id) | |
1747 | { | |
1748 | pkts_done[mac_id] = 0; | |
1749 | sync(ALL,TX_rvcd_allpkts[mac_id]); | |
1750 | pkts_done[mac_id] = 1; | |
1751 | } | |
1752 | ||
1753 | // add task to set the maxburst for | |
1754 | ||
1755 | task niu_tx_test_class :: set_max_burst(integer mac_id, integer dma_id) | |
1756 | { | |
1757 | ||
1758 | bit [63:0] max_burst; | |
1759 | ||
1760 | ||
1761 | if(tx_control.random_maxburst) { | |
1762 | max_burst = 64 + random()%16000; | |
1763 | printf("TX_TEST_CL : Max_burst for DMA %0d is %0h\n",dma_id,max_burst); | |
1764 | } else { | |
1765 | case(mac_id) { | |
1766 | 0 : max_burst = tx_control.port0_max_burst; | |
1767 | 1 : max_burst = tx_control.port1_max_burst; | |
1768 | 2 : max_burst = tx_control.port2_max_burst; | |
1769 | 3 : max_burst = tx_control.port3_max_burst; | |
1770 | } | |
1771 | } | |
1772 | ||
1773 | MacTxPort[mac_id].dma[dma_id].SetTxMaxBurst(max_burst); | |
1774 | ||
1775 | } | |
1776 | ||
1777 | // add task to read when expecting error cases | |
1778 | ||
1779 | task niu_tx_test_class :: check_tx_cs(integer mac_id, integer dma_id, string err_code, (integer | |
1780 | chk_set=0),(integer chk_clr = 0)) | |
1781 | { | |
1782 | bit [39:0] address; | |
1783 | bit [63:0] rd_data; | |
1784 | bit [63:0] wr_data; | |
1785 | ||
1786 | ||
1787 | case(err_code) { | |
1788 | ||
1789 | "Mbox_Error" : { | |
1790 | // call the read to the tx_cs register | |
1791 | ||
1792 | if(chk_set) { | |
1793 | address = TX_CS + dma_id*40'h200; | |
1794 | gen_pio_drv.pio_rd(address,rd_data); | |
1795 | ||
1796 | // check to see if the mbox_err bit set | |
1797 | if(~rd_data[7]) | |
1798 | printf("ERROR MBOX_ERR bit not set\n"); | |
1799 | else { | |
1800 | err_detected = 1; | |
1801 | printf("INFO MBOX_ERR bit SET\n"); | |
1802 | } | |
1803 | ||
1804 | } | |
1805 | ||
1806 | // do a read back to check if mbox err cleared | |
1807 | if(chk_clr) { | |
1808 | address = TX_CS + dma_id*40'h200; | |
1809 | gen_pio_drv.pio_rd(address,rd_data); | |
1810 | ||
1811 | if(rd_data[7]) | |
1812 | printf("ERROR MBOX_ERR bit not Cleared\n"); | |
1813 | else printf("INFO MBOX_ERR bit CLRD\n"); | |
1814 | } | |
1815 | ||
1816 | } | |
1817 | ||
1818 | "Nack_Pref_Error" : { | |
1819 | ||
1820 | // check to see if the mbox_err bit set | |
1821 | if(chk_set) { | |
1822 | ||
1823 | address = TX_CS + dma_id*40'h200; | |
1824 | gen_pio_drv.pio_rd(address,rd_data); | |
1825 | ||
1826 | if(~rd_data[3]) | |
1827 | printf("ERROR NACK_PREF_ERR bit not set\n"); | |
1828 | else { | |
1829 | err_detected = 1; | |
1830 | printf("INFO NACK_PREF_ERR bit SET\n"); | |
1831 | } | |
1832 | ||
1833 | } | |
1834 | ||
1835 | // do a read back to check if nack_pref err cleared | |
1836 | if(chk_clr) { | |
1837 | address = TX_CS + dma_id*40'h200; | |
1838 | gen_pio_drv.pio_rd(address,rd_data); | |
1839 | ||
1840 | if(rd_data[3]) | |
1841 | printf("ERROR NACK_PREF_ERR bit not Cleared\n"); | |
1842 | else printf("INFO NACK_PREF_ERR bit CLRD\n"); | |
1843 | } | |
1844 | ||
1845 | } | |
1846 | ||
1847 | "Conf_Part_Error" : { | |
1848 | // check to see if the mbox_err bit set | |
1849 | if(chk_set) { | |
1850 | ||
1851 | address = TX_CS + dma_id*40'h200; | |
1852 | gen_pio_drv.pio_rd(address,rd_data); | |
1853 | ||
1854 | if(~rd_data[1]) | |
1855 | printf("ERROR CONF_PART_ERR bit not set\n"); | |
1856 | else { | |
1857 | err_detected = 1; | |
1858 | printf("INFO CONF_PART_ERR bit SET\n"); | |
1859 | } | |
1860 | ||
1861 | } | |
1862 | ||
1863 | // do a read back to check if nack_pref err cleared | |
1864 | if(chk_clr) { | |
1865 | address = TX_CS + dma_id*40'h200; | |
1866 | gen_pio_drv.pio_rd(address,rd_data); | |
1867 | ||
1868 | if(rd_data[1]) | |
1869 | printf("ERROR CONF_PART_ERR bit not Cleared\n"); | |
1870 | else printf("INFO CONF_PART_ERR bit CLRD\n"); | |
1871 | } | |
1872 | ||
1873 | } | |
1874 | "PSize_Error" : { | |
1875 | // check to see if the pkt_sz_err bit set | |
1876 | if(chk_set) { | |
1877 | ||
1878 | address = TX_CS + dma_id*40'h200; | |
1879 | gen_pio_drv.pio_rd(address,rd_data); | |
1880 | ||
1881 | if(~rd_data[6]) | |
1882 | printf("ERROR PKT_SZ_ERR bit not set\n"); | |
1883 | else { | |
1884 | err_detected = 1; | |
1885 | printf("INFO PKT_SZ_ERR bit SET\n"); | |
1886 | } | |
1887 | ||
1888 | } | |
1889 | ||
1890 | ||
1891 | // do a read back to check if pkt_sz_err cleared | |
1892 | if(chk_clr) { | |
1893 | address = TX_CS + dma_id*40'h200; | |
1894 | gen_pio_drv.pio_rd(address,rd_data); | |
1895 | ||
1896 | if(rd_data[6]) | |
1897 | printf("ERROR PKT_SZ_ERR bit not Cleared\n"); | |
1898 | else printf("INFO PKT_SZ_ERR bit CLRD\n"); | |
1899 | } | |
1900 | ||
1901 | } | |
1902 | ||
1903 | } | |
1904 | ||
1905 | } | |
1906 | ||
1907 | task niu_tx_test_class :: set_port_control(integer p0_enb, integer p1_enb, integer p2_enb, integer p3_enb) | |
1908 | { | |
1909 | ||
1910 | bit [63:0] ctrl_data; | |
1911 | bit [3:0] port_enb; | |
1912 | ||
1913 | port_enb[0] = p0_enb; | |
1914 | port_enb[1] = p1_enb; | |
1915 | port_enb[2] = p2_enb; | |
1916 | port_enb[3] = p3_enb; | |
1917 | ||
1918 | ctrl_data = {59'h0,1'b1,port_enb}; | |
1919 | ||
1920 | txc_util.txc_init(ctrl_data); | |
1921 | ||
1922 | } | |
1923 | ||
1924 | task niu_tx_test_class :: random_reset_reinit(integer mac_id, integer dma_id, integer no_of_pkts, var integer pkts_xmttd) | |
1925 | { | |
1926 | integer i; | |
1927 | ||
1928 | MacTxPort[mac_id].dma[dma_id].reset_dma(); | |
1929 | pkts_xmttd = MacTxPort[mac_id].dma[dma_id].getPktCnt(); | |
1930 | printf("reset_reinit : pkts_xmttd %d\n",pkts_xmttd); | |
1931 | MacTxPort[mac_id].delete_channels(dma_id); | |
1932 | MacTxPort[mac_id].add_channels(dma_id); | |
1933 | InitTxDMA(no_of_pkts,mac_id,dma_id); | |
1934 | set_max_burst(mac_id,dma_id); | |
1935 | ||
1936 | generate_pkts(no_of_pkts,mac_id,dma_id); | |
1937 | ||
1938 | // unstall the DMA | |
1939 | MacTxPort[mac_id].dma[dma_id].SetTxCs(64'h2000_0000); | |
1940 | MacTxPort[mac_id].dma[dma_id].setTxRingKick(MacTxPort[mac_id].dma[dma_id].desc_ring.ring_current_addr); | |
1941 | ||
1942 | } | |
1943 | ||
1944 | task niu_tx_test_class :: random_stop_start_dma(integer mac_id, integer dma_id) { | |
1945 | ||
1946 | MacTxPort[mac_id].dma[dma_id].stop_dma(); | |
1947 | repeat (random()%500) @(posedge CLOCK); | |
1948 | MacTxPort[mac_id].dma[dma_id].SetTxCs(64'h0); | |
1949 | } | |
1950 | ||
1951 | ||
1952 | //---- Task to kick all pkts at one go ------------// | |
1953 | ||
1954 | task niu_tx_test_class :: kick_all_wrreset(integer no_of_pkts, integer mac_id, bit[23:0] dma_ids) | |
1955 | { | |
1956 | shadow integer i1,k; | |
1957 | integer j; | |
1958 | integer dma_id; | |
1959 | bit [63:0] data; | |
1960 | bit done = 1'b0; | |
1961 | integer list; | |
1962 | integer pkt_cnt[24]; | |
1963 | integer t_pkt_cnt[24]; | |
1964 | bit [23:0] sync_pkt_chk; | |
1965 | ||
1966 | //--- New the Macport and assign the dma list to the mac port | |
1967 | ||
1968 | list = dma_ids; | |
1969 | ||
1970 | // add channels to the port for verif | |
1971 | if(tx_control.enb_intr) { | |
1972 | // this bind is taken care in the test | |
1973 | } else { | |
1974 | for(j=0;j<no_of_txdmas;j++) { | |
1975 | if(dma_ids[j]) { | |
1976 | MacTxPort[mac_id].add_channels(j); | |
1977 | set_max_burst(mac_id,j); | |
1978 | } | |
1979 | } | |
1980 | } | |
1981 | ||
1982 | // initialize the t_pkt_cnt | |
1983 | for(j=0;j<24;j++) { | |
1984 | t_pkt_cnt[j] = 0; | |
1985 | sync_pkt_chk[j] = 0; | |
1986 | } | |
1987 | ||
1988 | // bind the dmas to the port | |
1989 | MacTxPort[mac_id].SetActive(list); | |
1990 | ||
1991 | tx_kick_done[mac_id] = 0; | |
1992 | ||
1993 | //-- generate the pkts and kick all pkts ------// | |
1994 | ||
1995 | for(i1=0;i1<no_of_txdmas;i1++) { | |
1996 | repeat(50) @(posedge CLOCK); | |
1997 | fork { | |
1998 | if(dma_ids[i1]) { | |
1999 | ||
2000 | dma_id = i1; | |
2001 | t_pkt_cnt[i1] = 0; | |
2002 | sync_pkt_chk[i1] = 0; | |
2003 | ||
2004 | InitTxDMA(no_of_pkts,mac_id,i1); | |
2005 | ||
2006 | if(tx_control.random_num_pkts) | |
2007 | generate_pkts(rand_num_pkts[i1],mac_id,i1); | |
2008 | else | |
2009 | generate_pkts(no_of_pkts,mac_id,i1); | |
2010 | // unstall the DMA | |
2011 | MacTxPort[mac_id].dma[i1].SetTxCs(64'h2000_0000); | |
2012 | ||
2013 | MacTxPort[mac_id].dma[i1].setTxRingKick(MacTxPort[mac_id].dma[i1].desc_ring.ring_current_addr); | |
2014 | printf("DMA_id %d kicked at time %d\n", i1, TIME); | |
2015 | ||
2016 | if(tx_control.sync_dmas) { | |
2017 | if(dma_ids[23] == 1'b1) | |
2018 | txc_util.txc_init(64'h1f); | |
2019 | } | |
2020 | ||
2021 | ||
2022 | // repeat(2) @(posedge CLOCK); | |
2023 | ||
2024 | /* fork | |
2025 | { | |
2026 | if(tx_control.enb_intr) { | |
2027 | // do nothing taken care in ISR | |
2028 | } else { | |
2029 | mailbox_update(mac_id,i1); | |
2030 | } | |
2031 | } join none */ | |
2032 | ||
2033 | fork | |
2034 | { | |
2035 | for(k=0;k<5;k++) { | |
2036 | repeat(1500) @(posedge CLOCK); | |
2037 | random_reset_reinit(mac_id,i1,no_of_pkts,pkt_cnt[i1]); | |
2038 | t_pkt_cnt[i1] = t_pkt_cnt[i1] + pkt_cnt[i1]; | |
2039 | // printf("Tx_test_cl : In random reset loop\n"); | |
2040 | // printf("Tx_test_cl reinit : total_pkt_cnt %d for DMA %d\n",t_pkt_cnt[i1],i1); | |
2041 | } | |
2042 | // add this to sync the pkt_cnt check | |
2043 | t_pkt_cnt[i1] = t_pkt_cnt[i1] + no_of_pkts; | |
2044 | printf("Tx_test_cl reinit : total_pkt_cnt %d for DMA %d\n",t_pkt_cnt[i1],i1); | |
2045 | sync_pkt_chk[i1] = 1; | |
2046 | } join none | |
2047 | ||
2048 | } | |
2049 | } join none | |
2050 | } | |
2051 | ||
2052 | tx_kick_done[mac_id] = 1; | |
2053 | ||
2054 | // wait till sync_pkt_chk goes > 0 | |
2055 | ||
2056 | if(dma_ids == 24'h0) | |
2057 | sync_pkt_chk = 24'h0; | |
2058 | ||
2059 | while((sync_pkt_chk & dma_ids) != dma_ids) { | |
2060 | repeat(100) @(posedge CLOCK); | |
2061 | } | |
2062 | ||
2063 | ||
2064 | if(tx_control.random_num_pkts) | |
2065 | MacTxPort[mac_id].check_randompkt_cnt(rand_num_pkts,tx_control.pktcnt_rd_intv); | |
2066 | else | |
2067 | // MacTxPort[mac_id].check_pkt_cnt(no_of_pkts,tx_control.pktcnt_rd_intv); | |
2068 | MacTxPort[mac_id].check_randompkt_cnt(t_pkt_cnt,tx_control.pktcnt_rd_intv); | |
2069 | ||
2070 | if(get_plus_arg( CHECK, "MAC_LOOP_BACK=")) { | |
2071 | for(j=0;j<no_of_txdmas;j++) { | |
2072 | if(dma_ids[j] & ~done) { | |
2073 | done = 1; | |
2074 | dma_id = j; | |
2075 | generate_pkts(1,mac_id,dma_id,1); | |
2076 | MacTxPort[mac_id].dma[j].setTxRingKick(MacTxPort[mac_id].dma[j].desc_ring.ring_current_addr); | |
2077 | printf("TX_TEST_CL : LOOP_BACK_MODE last_pkt gentd for dma %d\n",dma_ids[j]); | |
2078 | } | |
2079 | } | |
2080 | } | |
2081 | ||
2082 | if(get_plus_arg(CHECK,"BYPASS_TXDRR")) { | |
2083 | // do nothing | |
2084 | } else { | |
2085 | MacTxPort[mac_id].check_exit_status(); | |
2086 | } | |
2087 | } | |
2088 | ||
2089 | ||
2090 | function integer niu_tx_test_class :: get_num_of_dmas_bport(bit [23:0] dma_ids) | |
2091 | { | |
2092 | integer i = 0; | |
2093 | integer count = 0; | |
2094 | ||
2095 | for(i=0; i< no_of_txdmas; i++) { | |
2096 | if(dma_ids[i]) | |
2097 | count++; | |
2098 | } | |
2099 | ||
2100 | get_num_of_dmas_bport = count; | |
2101 | } | |
2102 | ||
2103 | //--- adding this task for generating num_pks | |
2104 | //--- based on the configuration | |
2105 | ||
2106 | task niu_tx_test_class :: get_numpkts_based_onconfig() | |
2107 | { | |
2108 | ||
2109 | integer dmas_p0; | |
2110 | integer dmas_p1; | |
2111 | integer dmas_p2; | |
2112 | integer dmas_p3; | |
2113 | integer ratio_p0p1_div_p2p3; | |
2114 | ||
2115 | if((tx_control.mac_speed0 == 10000) && (tx_control.mac_speed1 == 10000) | |
2116 | && (tx_control.mac_speed2 == 1000) && (tx_control.mac_speed3 == 1000)) { | |
2117 | dmas_p0 = get_num_of_dmas_bport(dmas_ids_p0); | |
2118 | dmas_p1 = get_num_of_dmas_bport(dmas_ids_p1); | |
2119 | dmas_p2 = get_num_of_dmas_bport(dmas_ids_p2); | |
2120 | dmas_p3 = get_num_of_dmas_bport(dmas_ids_p3); | |
2121 | ||
2122 | ratio_p0p1_div_p2p3 = 5; | |
2123 | ||
2124 | if(ratio_p0p1_div_p2p3 < 5) { | |
2125 | no_of_pkts_p0 = 10*tx_control.no_of_pkts; | |
2126 | no_of_pkts_p1 = 10*tx_control.no_of_pkts; | |
2127 | no_of_pkts_p2 = tx_control.no_of_pkts; | |
2128 | no_of_pkts_p3 = tx_control.no_of_pkts; | |
2129 | } else { | |
2130 | no_of_pkts_p0 = tx_control.no_of_pkts; | |
2131 | no_of_pkts_p1 = tx_control.no_of_pkts; | |
2132 | no_of_pkts_p2 = tx_control.no_of_pkts; | |
2133 | no_of_pkts_p3 = tx_control.no_of_pkts; | |
2134 | } | |
2135 | } else { | |
2136 | no_of_pkts_p0 = tx_control.no_of_pkts; | |
2137 | no_of_pkts_p1 = tx_control.no_of_pkts; | |
2138 | no_of_pkts_p2 = tx_control.no_of_pkts; | |
2139 | no_of_pkts_p3 = tx_control.no_of_pkts; | |
2140 | } | |
2141 | } | |
2142 | ||
2143 | ||
2144 | ||
2145 |