Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / txc_sat / vera / niu_tx_test_class.vr
CommitLineData
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
44extern niu_gen_pio gen_pio_drv;
45extern Mesg be_msg;
46extern txc_util_class txc_util;
47extern event TX_rvcd_allpkts[4];
48
49#include "dmc_memory_map.vri"
50
51#define TIME {get_time(HI), get_time(LO)}
52
53class 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
144task 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
218task niu_tx_test_class :: get_dmaid(integer dma_id)
219{
220 id = dma_id;
221}
222
223task 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
272task 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
280task 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
294task 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
307task 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
319task 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
341task niu_tx_test_class :: get_txc_isr_count (integer count)
342{
343 cnt = count;
344}
345
346task niu_tx_test_class :: kick_all_4ports()
347{
348
349integer mac_id0;
350integer mac_id1;
351integer mac_id2;
352integer mac_id3;
353
354// integer rng_len;
355bit 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
364port0_enb = tx_control.port0_enb;
365port1_enb = tx_control.port1_enb;
366port2_enb = tx_control.port2_enb;
367port3_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
385fork
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 }
404join all
405
406}
407
408// add task to bind the dmas to mac_port
409
410task niu_tx_test_class :: BindDmaIntrDev(DMAChannel TxDma, integer i) {
411
412integer j = 0;
413integer mac_id = 0;
414integer 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
456task 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
621task 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
629task 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
659task 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
718task 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
748task 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
801task 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
947task 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
1142task 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
1353task 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
1396task 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
1409task 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
1566task 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
1688task 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
1708task 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
1734task 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
1746task 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
1755task 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
1779task niu_tx_test_class :: check_tx_cs(integer mac_id, integer dma_id, string err_code, (integer
1780chk_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
1907task 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
1924task 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
1944task 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
1954task 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
2090function 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
2106task niu_tx_test_class :: get_numpkts_based_onconfig()
2107{
2108
2109integer dmas_p0;
2110integer dmas_p1;
2111integer dmas_p2;
2112integer dmas_p3;
2113integer 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