Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / txc_sat / vera / niu_tx_port.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_tx_port.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 "niu_tx_descp.vrh"
36#include "dmc_memory_map.vri"
37#include "txc_memory_map.vri"
38extern niu_gen_pio gen_pio_drv;
39// tmp only
40// #include "txc_drr_chk_if.vri"
41#include "tx_port_drr_if.vri"
42extern mbox_class mbox_id;
43#include "cMesg.vrh"
44extern Mesg be_msg;
45extern event TX_rvcd_allpkts[4];
46extern mac_pio_cl mac_pio_class;
47extern mac_util_class mac_util;
48
49// To Support MAC Loop back mode
50#include "niu_rxtoken.vrh"
51#include "niu_txport_cb.vrh"
52
53#define TIME {get_time(HI), get_time(LO)}
54
55class CMacTxPort {
56
57 integer id; // port id
58 DMAChannel dma[32]; // a max of 32 dma channels per port can be bound
59 integer port_speed;
60 integer USE_CALL_BACKS = 0;
61
62 bit[31:0] DMAActiveList;
63 bit[31:0] OrigDMAActiveList;
64 bit [11:0] port_offset;
65 bit [3:0] MAC_LOOP_BACK_MODE;
66 integer EXT_LOOPBACK_DST=-1;
67
68 CTxPortCbMgr TxPortCbMgr;
69
70 task new(integer i=0);
71 task add_channels( integer i);
72 task delete_channels( integer i);
73 task BindDmaIntrDev( DMAChannel TxDma, integer i );
74 task SetActive (integer list, (integer rebind = 0));
75 task DRR(/*TMPONLY*/txc_port_drr port_bind);
76 task pollLatchActive(txc_port_drr port_bind);
77 function integer check_active ( integer j, integer activeList);
78
79 task check_exit_status();
80 task check_pkt_cnt (integer no_of_pkts, (integer timeout_count= 100),(integer chk_type = 0));
81 task check_randompkt_cnt (integer no_of_pkts[24], (integer timeout_count = 100));
82 task check_pkt_cnt_perdma (integer no_of_pkts);
83 function integer get_allpkts_toport (integer no_of_pkts);
84 function integer get_allpkts_toport_random (integer no_of_pkts[24]);
85
86 task SetActive_NoOfDMAs (integer list) ;
87 task Inj_ReEcc_Error(bit [63:0] data, (integer fifo_sel = 0));
88 task Rd_ReEcc_St(var bit [63:0] r_data);
89 task Rd_ReEcc_UE();
90 task Rd_ReEcc_CE();
91 task Enb_Watermark_Reg(bit [63:0] data);
92 task Wr_TXC_RO_CTL(bit [63:0] data);
93 task Rd_TXC_RO_CTL(var bit [63:0] rd_data);
94 task SnapShotDMAs( bit[31:0] ActiveListSnapShot);
95 task LoadDMAStates( bit[31:0] ActiveListSnapShot);
96 task PullTokensBack( bit[31:0] list);
97 function integer wait_for_addcredit(txc_port_drr port_bind);
98
99 task Wr_Txc_max_reoder(bit[63:0] wr_data);
100 task Wr_Txc_Port_Ctl(bit[63:0] wr_data);
101 task Wr_Txc_Pkt_stuffed(bit[63:0] wr_data);
102 task Wr_Txc_Pkt_Xmitted(bit[63:0] wr_data);
103 task Rd_Txc_Pkt_stuffed(var bit[63:0] rd_data);
104 task Rd_Txc_Pkt_Xmitted(var bit[63:0] rd_data);
105
106 // add tasks to read & write RO ECC
107
108 task Wr_Txc_ROECC_ST(bit [63:0] wr_data);
109 task Rd_Txc_ROECC_ST(var bit [63:0] rd_data);
110
111 task Rd_Txc_RO_Data0(var bit [63:0] rd_data);
112 task Rd_Txc_RO_Data1(var bit [63:0] rd_data);
113 task Rd_Txc_RO_Data2(var bit [63:0] rd_data);
114 task Rd_Txc_RO_Data3(var bit [63:0] rd_data);
115 task Rd_Txc_RO_Data4(var bit [63:0] rd_data);
116
117 // add tasks to read & write SF ECC
118
119 task Wr_Txc_SFECC_ST(bit [63:0] wr_data);
120 task Rd_Txc_SFECC_ST(var bit [63:0] rd_data);
121
122 task Rd_Txc_SF_Data0(var bit [63:0] rd_data);
123 task Rd_Txc_SF_Data1(var bit [63:0] rd_data);
124 task Rd_Txc_SF_Data2(var bit [63:0] rd_data);
125 task Rd_Txc_SF_Data3(var bit [63:0] rd_data);
126 task Rd_Txc_SF_Data4(var bit [63:0] rd_data);
127
128 // add rds & wr to txc-tid regs
129
130 task Wr_Txc_RO_Tids(bit [63:0] wr_data);
131 task Wr_Txc_RO_State0(bit [63:0] wr_data);
132 task Wr_Txc_RO_State1(bit [63:0] wr_data);
133 task Wr_Txc_RO_State2(bit [63:0] wr_data);
134 task Wr_Txc_RO_State3(bit [63:0] wr_data);
135
136 task Rd_Txc_RO_Tids(var bit [63:0] rd_data);
137 task Rd_Txc_RO_State0(var bit [63:0] rd_data);
138 task Rd_Txc_RO_State1(var bit [63:0] rd_data);
139 task Rd_Txc_RO_State2(var bit [63:0] rd_data);
140 task Rd_Txc_RO_State3(var bit [63:0] rd_data);
141
142 task DeActivate_channel(integer i);
143
144 task check_bytes_txmitted();
145 task check_pkts_stuffed(integer no_of_pkts);
146 task Wr_Txc_Intr_Mask(bit[63:0] data);
147 task Rd_Txc_Intr_Stat(var bit[63:0] rd_data);
148 task Wr_Txc_Intr_Stat(bit [63:0] data);
149
150 task check_mac_txfrmcnt(integer no_of_pkts);
151
152}
153
154function integer CMacTxPort::check_active ( integer j, integer activeList) {
155 // returns 1 if jth bit in the ActiveList is set else returns 0
156 integer tmp;
157 tmp = 1 <<j;
158 if(activeList & tmp) check_active = (1);
159 else check_active = (0);
160
161}
162
163task CMacTxPort::new (integer i = 0) {
164
165 string init_loopback,temp_port;
166 bit [31:0] loopback;
167 integer j;
168
169printf("MacTxPort %0d newed\n", this.id);
170 id = i;
171 trigger(OFF,TX_rvcd_allpkts[id]);
172 DMAActiveList = 0; // none of the DMAs active
173 OrigDMAActiveList = DMAActiveList;
174 port_offset = 256*i;
175 MAC_LOOP_BACK_MODE = 0;
176 if(get_plus_arg(CHECK, "rx0_txloopback_src"))
177 if(get_plus_arg(NUM, "rx0_txloopback_src=") == this.id) {
178 EXT_LOOPBACK_DST = 0;
179 printf("MacTxPort %0d EXT_LOOPBACK_DST=%0d\n", this.id, EXT_LOOPBACK_DST);
180 }
181 if(get_plus_arg(CHECK, "rx1_txloopback_src"))
182 if(get_plus_arg(NUM, "rx1_txloopback_src=") == this.id) {
183 EXT_LOOPBACK_DST = 1;
184 printf("MacTxPort %0d EXT_LOOPBACK_DST=%0d\n", this.id, EXT_LOOPBACK_DST);
185 }
186 if(get_plus_arg(CHECK, "rx2_txloopback_src"))
187 if(get_plus_arg(NUM, "rx2_txloopback_src=") == this.id) {
188 EXT_LOOPBACK_DST = 2;
189 printf("MacTxPort %0d EXT_LOOPBACK_DST=%0d\n", this.id, EXT_LOOPBACK_DST);
190 }
191 if(get_plus_arg(CHECK, "rx3_txloopback_src"))
192 if(get_plus_arg(NUM, "rx3_txloopback_src=") == this.id) {
193 EXT_LOOPBACK_DST = 3;
194 printf("MacTxPort %0d EXT_LOOPBACK_DST=%0d\n", this.id, EXT_LOOPBACK_DST);
195 }
196
197 TxPortCbMgr = new(i);
198 for(j=0;j<4;j++) {
199 if(mbox_id.niu_tx_cb[j] == -1) {
200 // Alocate Mailbox
201 mbox_id.niu_tx_cb[j] = alloc(MAILBOX,0,1);
202 // Check if we were succesfull allocating the mailbox
203 if(mbox_id.niu_tx_cb[j] == 0) {
204 printf("ERROR Could not allocate the outgoing mailbox port %d \n",j);
205 mbox_id.niu_tx_cb[j] = -1;
206 return;
207 }
208 }
209 }
210
211 for(j=0;j<4;j++) {
212 if(mbox_id.niu_txdrr[j] == -1) {
213 // Alocate Mailbox
214 mbox_id.niu_txdrr[j] = alloc(MAILBOX,0,1);
215 // Check if we were succesfull allocating the mailbox
216 if(mbox_id.niu_txdrr[j] == 0) {
217 printf("ERROR Could not allocate the outgoing mailbox port %d \n",j);
218 mbox_id.niu_txdrr[j] = -1;
219 return;
220 }
221 }
222 }
223 if( get_plus_arg( CHECK, "NW_DRR_MODEL")) {
224 USE_CALL_BACKS = 1;
225 }
226
227 if( get_plus_arg( CHECK, "MAC_LOOP_BACK=")) {
228 loopback = get_plus_arg( STR, "MAC_LOOP_BACK=");
229 init_loopback.bittostr(loopback);
230 for (j=0; j<init_loopback.len();j++)
231 {
232 temp_port =init_loopback.substr(j,j);
233 MAC_LOOP_BACK_MODE = MAC_LOOP_BACK_MODE | ( 1<<temp_port.atoi());
234 }
235 printf(" MAC LOOP BACK ENABLED!! LoopBack Configuration - %b \n",MAC_LOOP_BACK_MODE);
236 } else MAC_LOOP_BACK_MODE = 0;
237
238
239 fork
240 case(id) {
241 0: DRR(txc_port0_drr_bind) ;
242 1: DRR(txc_port1_drr_bind) ;
243 default: printf("ERROR Incorrect port id set for CMacTxPort got id=%0d\n",id);
244 }
245 join none
246
247}
248
249task CMacTxPort::BindDmaIntrDev( DMAChannel TxDma, integer i ) {
250/* For binding interruptable dma devices */
251 dma[i] = TxDma;
252 dma[i].bind_to_txport(id/*port_id*/);
253 printf(" CMacTxPort::BindDmaIntrDevTRxDMA Channel - %d Bound as Logical DeviceId - %d \n",i,dma[i].dev_id);
254
255}
256task CMacTxPort::add_channels( integer i) {
257 dma[i] = null;
258 dma[i] = new(i,"TX");
259 dma[i].bind_to_txport(id/*port_id*/);
260}
261
262task CMacTxPort:: delete_channels( integer i) {
263 dma[i].unbind_from_txport(id);
264 dma[i] = null;
265}
266
267task CMacTxPort::SetActive( integer list, (integer rebind = 0)) {
268
269 bit [39:0] address;
270 bit [63:0] w_data;
271 bit [63:0] rd_data;
272
273 DMAActiveList = list;
274 OrigDMAActiveList = DMAActiveList;
275
276 if(!rebind) {
277
278 address = TXC_FZC_BASE+ (TXC_PORT0_DMA_ENBALE + port_offset);
279 w_data = {random(),DMAActiveList} ; //
280 gen_pio_drv.pio_wr(address,w_data);
281
282 } else {
283
284 // do a read modify write while trying to rebind
285
286 address = TXC_FZC_BASE+ (TXC_PORT0_DMA_ENBALE + port_offset);
287 // first read the data
288 gen_pio_drv.pio_rd(address,rd_data);
289
290 w_data = rd_data | {random(),DMAActiveList} ; //
291 gen_pio_drv.pio_wr(address,w_data);
292
293 DMAActiveList = w_data;
294 OrigDMAActiveList = w_data;
295 }
296
297}
298
299task CMacTxPort :: DeActivate_channel(integer list) {
300
301 integer i;
302 bit [31:0] delete_list;
303 bit [39:0] address;
304 bit [63:0] w_data = 64'h0;
305 bit [63:0] rd_data;
306
307 delete_list = list;
308
309 address = TXC_FZC_BASE+ (TXC_PORT0_DMA_ENBALE + port_offset);
310 gen_pio_drv.pio_rd(address,rd_data);
311
312 for(i=0;i<32;i++) {
313 if(delete_list[i] & rd_data[i])
314 w_data[i] = 0;
315 else
316 w_data[i] = rd_data[i];
317 }
318
319 gen_pio_drv.pio_wr(address,w_data);
320}
321
322
323//temp task for Set Active based on the number of DMAs tied to the ports
324
325task CMacTxPort :: SetActive_NoOfDMAs (integer list) {
326
327 bit [39:0] address;
328 bit [63:0] w_data;
329
330 DMAActiveList = (1 << list) - 1;
331 OrigDMAActiveList = DMAActiveList;
332
333 address = TXC_FZC_BASE+ (TXC_PORT0_DMA_ENBALE + port_offset);
334 w_data = {random(),DMAActiveList} ; //
335 gen_pio_drv.pio_wr(address,w_data);
336
337}
338
339//-- progranmme the watermark register -----//
340
341task CMacTxPort :: Enb_Watermark_Reg(bit [63:0] data) {
342
343 bit [39:0] address;
344
345 address = TXC_FZC_BASE + (TXC_RO_STATE3 + port_offset);
346 gen_pio_drv.pio_wr(address,data);
347}
348
349//-- write to TXC_RO_st_ctl
350
351task CMacTxPort :: Wr_TXC_RO_CTL(bit [63:0] data)
352{
353
354 bit [39:0] address;
355
356 address = TXC_FZC_BASE + (TXC_RO_CTL + port_offset);
357 gen_pio_drv.pio_wr(address,data);
358}
359
360//-- write to TXC_RO_st_ctl
361
362task CMacTxPort :: Rd_TXC_RO_CTL(var bit [63:0] rd_data)
363{
364
365 bit [39:0] address;
366
367 address = TXC_FZC_BASE + (TXC_RO_CTL + port_offset);
368 gen_pio_drv.pio_rd(address,rd_data);
369}
370
371
372// task to inject ECC errors
373
374task CMacTxPort :: Inj_ReEcc_Error(bit [63:0] data, (integer fifo_sel = 0))
375{
376 bit [39:0] address;
377
378 if(fifo_sel == 0) {
379 // ecc error RO fifo
380 address = TXC_FZC_BASE + (TXC_ROECC_CTL + port_offset);
381 gen_pio_drv.pio_wr(address,data);
382 } else if(fifo_sel == 1) {
383 // ecc error SO fifo
384 address = TXC_FZC_BASE + (TXC_SFECC_CTL + port_offset);
385 gen_pio_drv.pio_wr(address,data);
386 }
387}
388
389// task to read ecc status register
390
391task CMacTxPort :: Rd_ReEcc_St(var bit [63:0] r_data)
392{
393 bit [39:0] address;
394
395 address = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
396 gen_pio_drv.pio_rd(address,r_data);
397}
398
399// Task to read correct able err
400
401task CMacTxPort :: Rd_ReEcc_CE()
402{
403 bit [63:0] rd_data;
404
405 Rd_ReEcc_St(rd_data);
406
407 if(rd_data[17])
408 be_msg.print(e_mesg_info,"niu_tx_port","Rd_ReEcc_Ce","Detected CE at address %0h\n",rd_data[9:0]);
409 else
410 be_msg.print(e_mesg_error,"niu_tx_port","Rd_ReEcc_Ce","No CE detected at address %0h\n",rd_data[9:0]);
411 }
412
413// Task to read correct able err
414
415task CMacTxPort :: Rd_ReEcc_UE()
416{
417 bit [63:0] rd_data;
418
419 Rd_ReEcc_St(rd_data);
420
421 if(rd_data[16])
422 be_msg.print(e_mesg_info,"niu_tx_port","Rd_ReEcc_UE","Detected UE at address %0h\n",rd_data[9:0]);
423 else
424 be_msg.print(e_mesg_error,"niu_tx_port","Rd_ReEcc_UE","No UE detected at address %0h\n",rd_data[9:0]);
425}
426
427
428// task to read modify write to TXC_MAX_REORDER
429
430task CMacTxPort :: Wr_Txc_max_reoder(bit[63:0] wr_data) {
431
432 bit [39:0] address;
433 bit [63:0] rd_data;
434 bit [63:0] ac_wrdata;
435
436 address = TXC_FZC_BASE + (TXC_MAX_REORDER);
437 gen_pio_drv.pio_rd(address,rd_data);
438 ac_wrdata = rd_data | wr_data;
439
440 address = TXC_FZC_BASE + (TXC_MAX_REORDER);
441 gen_pio_drv.pio_wr(address,ac_wrdata);
442
443}
444
445
446
447// task to write to txc_port_ctl
448
449task CMacTxPort :: Wr_Txc_Port_Ctl(bit[63:0] wr_data) {
450
451 bit [39:0] address;
452
453 address = TXC_FZC_BASE + (TXC_PORT0_CONTROL + port_offset);
454 gen_pio_drv.pio_wr(address,wr_data);
455}
456
457
458// task to rd & wr pkts stuffed & pkts_xmitted
459
460task CMacTxPort :: Wr_Txc_Pkt_stuffed(bit[63:0] wr_data) {
461
462 bit [39:0] address;
463 address = TXC_FZC_BASE + (TXC_PKT_STUFFED + port_offset);
464 gen_pio_drv.pio_wr(address,wr_data);
465
466}
467
468task CMacTxPort :: Wr_Txc_Pkt_Xmitted(bit[63:0] wr_data) {
469
470 bit [39:0] address;
471 address = TXC_FZC_BASE + (TXC_PKT_XMIT + port_offset);
472 gen_pio_drv.pio_wr(address,wr_data);
473}
474
475task CMacTxPort :: Rd_Txc_Pkt_stuffed(var bit[63:0] rd_data) {
476
477 bit [39:0] address;
478 address = TXC_FZC_BASE + (TXC_PKT_STUFFED + port_offset);
479 gen_pio_drv.pio_rd(address, rd_data);
480}
481
482task CMacTxPort :: Rd_Txc_Pkt_Xmitted(var bit[63:0] rd_data) {
483
484 bit [39:0] address;
485 address = TXC_FZC_BASE + (TXC_PKT_XMIT + port_offset);
486 gen_pio_drv.pio_rd(address, rd_data);
487}
488
489// tasks to rd & write RO based regs
490
491task CMacTxPort :: Wr_Txc_ROECC_ST(bit [63:0] wr_data) {
492 bit [39:0] address;
493 address = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
494 gen_pio_drv.pio_wr(address,wr_data);
495}
496
497task CMacTxPort :: Rd_Txc_ROECC_ST(var bit [63:0] rd_data) {
498 bit [39:0] address;
499 address = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
500 gen_pio_drv.pio_rd(address, rd_data);
501}
502
503
504task CMacTxPort :: Rd_Txc_RO_Data0(var bit [63:0] rd_data) {
505 bit [39:0] address;
506 address = TXC_FZC_BASE + (TXC_RO_DATA0 + port_offset);
507 gen_pio_drv.pio_rd(address, rd_data);
508}
509
510task CMacTxPort :: Rd_Txc_RO_Data1(var bit [63:0] rd_data) {
511 bit [39:0] address;
512 address = TXC_FZC_BASE + (TXC_RO_DATA1 + port_offset);
513 gen_pio_drv.pio_rd(address, rd_data);
514}
515
516task CMacTxPort :: Rd_Txc_RO_Data2(var bit [63:0] rd_data) {
517 bit [39:0] address;
518 address = TXC_FZC_BASE + (TXC_RO_DATA2 + port_offset);
519 gen_pio_drv.pio_rd(address, rd_data);
520}
521
522task CMacTxPort :: Rd_Txc_RO_Data3(var bit [63:0] rd_data) {
523 bit [39:0] address;
524 address = TXC_FZC_BASE + (TXC_RO_DATA3 + port_offset);
525 gen_pio_drv.pio_rd(address, rd_data);
526}
527
528task CMacTxPort :: Rd_Txc_RO_Data4(var bit [63:0] rd_data) {
529 bit [39:0] address;
530 address = TXC_FZC_BASE + (TXC_RO_DATA4 + port_offset);
531 gen_pio_drv.pio_rd(address, rd_data);
532}
533
534
535// tasks to rd & write SF based regs
536
537task CMacTxPort :: Wr_Txc_SFECC_ST(bit [63:0] wr_data) {
538 bit [39:0] address;
539 address = TXC_FZC_BASE + (TXC_SFECC_ST + port_offset);
540 gen_pio_drv.pio_wr(address,wr_data);
541}
542
543task CMacTxPort :: Rd_Txc_SFECC_ST(var bit [63:0] rd_data) {
544 bit [39:0] address;
545 address = TXC_FZC_BASE + (TXC_SFECC_ST + port_offset);
546 gen_pio_drv.pio_rd(address, rd_data);
547}
548
549task CMacTxPort :: Rd_Txc_SF_Data0(var bit [63:0] rd_data) {
550 bit [39:0] address;
551 address = TXC_FZC_BASE + (TXC_SF_DATA0 + port_offset);
552 gen_pio_drv.pio_rd(address, rd_data);
553}
554
555task CMacTxPort :: Rd_Txc_SF_Data1(var bit [63:0] rd_data) {
556 bit [39:0] address;
557 address = TXC_FZC_BASE + (TXC_SF_DATA1 + port_offset);
558 gen_pio_drv.pio_rd(address, rd_data);
559}
560
561task CMacTxPort :: Rd_Txc_SF_Data2(var bit [63:0] rd_data) {
562 bit [39:0] address;
563 address = TXC_FZC_BASE + (TXC_SF_DATA2 + port_offset);
564 gen_pio_drv.pio_rd(address, rd_data);
565}
566
567task CMacTxPort :: Rd_Txc_SF_Data3(var bit [63:0] rd_data) {
568 bit [39:0] address;
569 address = TXC_FZC_BASE + (TXC_SF_DATA3 + port_offset);
570 gen_pio_drv.pio_rd(address, rd_data);
571}
572
573task CMacTxPort :: Rd_Txc_SF_Data4(var bit [63:0] rd_data) {
574 bit [39:0] address;
575 address = TXC_FZC_BASE + (TXC_SF_DATA4 + port_offset);
576 gen_pio_drv.pio_rd(address, rd_data);
577}
578
579//### txc tid register read & write
580
581task CMacTxPort :: Wr_Txc_RO_Tids(bit [63:0] wr_data) {
582 bit [39:0] address;
583 address = TXC_FZC_BASE + (TXC_RO_TIDS + port_offset);
584 gen_pio_drv.pio_wr(address,wr_data);
585}
586
587task CMacTxPort :: Wr_Txc_RO_State0(bit [63:0] wr_data){
588 bit [39:0] address;
589 address = TXC_FZC_BASE + (TXC_RO_STATE0 + port_offset);
590 gen_pio_drv.pio_wr(address,wr_data);
591}
592
593task CMacTxPort :: Wr_Txc_RO_State1(bit [63:0] wr_data){
594 bit [39:0] address;
595 address = TXC_FZC_BASE + (TXC_RO_STATE1 + port_offset);
596 gen_pio_drv.pio_wr(address,wr_data);
597}
598
599task CMacTxPort :: Wr_Txc_RO_State2(bit [63:0] wr_data){
600 bit [39:0] address;
601 address = TXC_FZC_BASE + (TXC_RO_STATE2 + port_offset);
602 gen_pio_drv.pio_wr(address,wr_data);
603}
604
605task CMacTxPort :: Wr_Txc_RO_State3(bit [63:0] wr_data){
606 bit [39:0] address;
607 address = TXC_FZC_BASE + (TXC_RO_STATE3 + port_offset);
608 gen_pio_drv.pio_wr(address,wr_data);
609}
610
611task CMacTxPort :: Rd_Txc_RO_Tids(var bit [63:0] rd_data) {
612 bit [39:0] address;
613 address = TXC_FZC_BASE + (TXC_RO_TIDS + port_offset);
614 gen_pio_drv.pio_rd(address, rd_data);
615}
616
617task CMacTxPort :: Rd_Txc_RO_State0(var bit [63:0] rd_data) {
618 bit [39:0] address;
619 address = TXC_FZC_BASE + (TXC_RO_STATE0 + port_offset);
620 gen_pio_drv.pio_rd(address, rd_data);
621}
622
623task CMacTxPort :: Rd_Txc_RO_State1(var bit [63:0] rd_data) {
624 bit [39:0] address;
625 address = TXC_FZC_BASE + (TXC_RO_STATE1 + port_offset);
626 gen_pio_drv.pio_rd(address, rd_data);
627}
628
629task CMacTxPort :: Rd_Txc_RO_State2(var bit [63:0] rd_data) {
630 bit [39:0] address;
631 address = TXC_FZC_BASE + (TXC_RO_STATE2 + port_offset);
632 gen_pio_drv.pio_rd(address, rd_data);
633}
634
635task CMacTxPort :: Rd_Txc_RO_State3(var bit [63:0] rd_data) {
636 bit [39:0] address;
637 address = TXC_FZC_BASE + (TXC_RO_STATE3 + port_offset);
638 gen_pio_drv.pio_rd(address, rd_data);
639}
640
641task CMacTxPort :: Wr_Txc_Intr_Mask(bit[63:0] data) {
642 bit [63:0] address;
643 address = TXC_FZC_BASE + TXC_INT_MASK;
644 gen_pio_drv.pio_wr(address, data);
645}
646
647task CMacTxPort :: Rd_Txc_Intr_Stat(var bit[63:0] rd_data) {
648
649 bit [63:0] address;
650
651 address = TXC_FZC_BASE + TXC_INT_STAT;
652 gen_pio_drv.pio_rd(address, rd_data);
653}
654
655task CMacTxPort :: Wr_Txc_Intr_Stat(bit [63:0] data) {
656
657 bit [63:0] address;
658
659 address = TXC_FZC_BASE + TXC_INT_STAT;
660 gen_pio_drv.pio_wr(address, data);
661}
662
663
664
665
666task CMacTxPort::pollLatchActive(txc_port_drr port_bind) {
667 CTxDrrTr drr_trigger;
668
669 #ifndef RXC_SAT
670 while(1) {
671 while(~port_bind.$latch_activedma){
672 @(posedge port_bind.$clk);
673 }
674 @(posedge port_bind.$clk);
675 drr_trigger = new();
676 drr_trigger.LatchActiveSeen = 1;
677 drr_trigger.activeList = port_bind.$activeListDMA;
678 mailbox_put(mbox_id.niu_txdrr[id] , drr_trigger);
679 @(posedge port_bind.$clk);
680
681 }
682 #endif
683}
684task CMacTxPort::SnapShotDMAs( bit[31:0] ActiveListSnapShot) {
685integer i;
686integer status;
687
688 for(i=0;i<32;i++) {
689 if(ActiveListSnapShot[i]) {
690 dma[i].SnapShotDRRState();
691
692 if (get_plus_arg(CHECK,"RAND_KMCD")) {
693 if(dma[i].list_empty) {
694 status = dma[i].enableTokens(dma[i].lkick_data);
695 dma[i].start = 0;
696 }
697 }
698 }
699 }
700}
701
702task CMacTxPort::LoadDMAStates( bit[31:0] ActiveListSnapShot) {
703integer i;
704 for(i=0;i<32;i++) {
705 if(ActiveListSnapShot[i])
706 dma[i].LoadDRRState();
707 }
708}
709task CMacTxPort::PullTokensBack( bit[31:0] list) {
710 integer i;
711 integer empty;
712 CTxToken TxToken;
713 integer dmas_updated[32];
714 bit[31:0] dmas_touched;
715
716
717 dmas_touched = 0;
718
719 printf("CMacTxPort::PullTokensBack Start - Time - %d \n",TIME);
720 empty = TxPortCbMgr.PullPortTokenList(TxToken);
721 while(empty==1) {
722 if ( ( list[TxToken.dma_num] ==1)) {
723 dmas_updated[TxToken.dma_num] = TxToken.current_deficit;
724 dmas_touched[TxToken.dma_num] = 1;
725 printf("DEBUG trans_id PullTokensBack DMA- %d Address - %x Deficit - %d \n",TxToken.dma_num,TxToken.xlate_gather_address[0],TxToken.current_deficit);
726 }
727 dma[TxToken.dma_num].push_back_token(TxToken);
728 empty = TxPortCbMgr.PullPortTokenList(TxToken);
729 //@(posedge CLOCK);
730 }
731 printf("CMacTxPort::PullTokensBack End - Time - %d \n",TIME);
732 for(i=0;i<32;i++) {
733 if(list[i] & dmas_touched[i]) {
734 printf("Setting DMA - %d defict to %d \n",i,dmas_updated[i]);
735 dma[i].current_deficit = dmas_updated[i];
736 }
737 }
738
739}
740task CMacTxPort::DRR(txc_port_drr port_bind) {
741
742
743// from a list of active DMAs sort through the TxTokenList - and generate appropriate
744// tokens for the packet checker
745
746integer arb_id,old_arb_id;
747integer dmas_active;
748integer total_dmas_active;
749integer i,match_found;
750integer iter;
751integer status;
752integer maintain_active_state;
753integer dma_id,length;
754CTxToken TxToken;
755CRxToken RxToken; // FOR MAC LOOP BACK MODE
756integer debug_count;
757bit [31:0] ActiveListFromHardware;
758bit [31:0] ActiveListFromHardware_old = 32'h0;
759bit [31:0] deficit_list = 32'h0;
760integer dma_deficit_list =0;
761integer all_dmas_deficit = 1;
762bit start_sim = 0;
763
764// For Random Kicks
765bit [31:0] ActiveListSnapShot;
766integer old_arb_idSnapShot;
767CTxDrrTr drr_trigger;
768integer no_of_entries;
769integer NewKickDMA;
770integer NewKickSeen;
771integer LatchActiveSeen;
772integer LatchActiveSeenFirstTime;
773integer no_of_dmas_eoflist;
774integer got_new_kick;
775LatchActiveSeenFirstTime = 0;
776
777// allocate memory for port0 mailbox
778 if(mbox_id.mac_opp[this.id] == -1) {
779 // Alocate Mailbox
780 mbox_id.mac_opp[this.id] = alloc(MAILBOX,0,1);
781 // Check if we were succesfull allocating the mailbox
782 if(mbox_id.mac_opp[this.id] == 0) {
783 printf("ERROR Could not allocate the outgoing mailbox port %d \n",this.id);
784 mbox_id.mac_opp[this.id] = -1;
785 return;
786 }
787 }
788
789
790 @(posedge port_bind.$clk);
791 @(posedge port_bind.$clk);
792 @(posedge port_bind.$clk);
793 @(posedge port_bind.$clk);
794 old_arb_id = 0;
795 debug_count = 0;
796
797 fork {
798 pollLatchActive(port_bind);
799 } join none
800
801while(1) {
802 debug_count ++;
803
804 // wait for some conditions - initial version look for latch enable
805 // for all active DMAs, add credits
806
807 /*
808 There are two ways to evaluate this
809 1. LatchActive is Seen
810 2. New Kick is Set
811 If both happens at the same time, LatchActive takes precedence for now
812 3. Any Kicks before the first LatchActive will also not trigger this
813
814 */
815
816 printf(" Before mailbox_get Time - %d \n",TIME);
817 no_of_entries = mailbox_get(WAIT,mbox_id.niu_txdrr[id],drr_trigger);
818 printf(" After mailbox_get Time - %d \n",TIME);
819 LatchActiveSeen = drr_trigger.LatchActiveSeen;
820 NewKickSeen = drr_trigger.NewKickSeen;
821 NewKickDMA = drr_trigger.NewKickDMA;
822 ActiveListFromHardware = drr_trigger.activeList;
823
824 if(NewKickSeen & LatchActiveSeenFirstTime & (LatchActiveSeen==0)) {
825 printf("LOCK Time - %d \n",TIME);
826 trigger(OFF,TxPortCbMgr.lock_port_queue);
827 }
828 if(LatchActiveSeen) {
829 // Take SnapShot of the current State and Store this
830 printf("DRR DEBUG ActiveList from Hardware - %x From Verif Model - %x \n",ActiveListFromHardware,OrigDMAActiveList);
831 ActiveListSnapShot = ActiveListFromHardware;
832 printf("DRR DEBUG ActiveListSnapShot - %x From Verif Model - %x \n",ActiveListSnapShot,OrigDMAActiveList);
833 // SnapShot All the Contexts
834 old_arb_idSnapShot = old_arb_id;
835 SnapShotDMAs(ActiveListSnapShot);
836 LatchActiveSeenFirstTime = 1;
837 TxPortCbMgr.FreezeCurrentTokenList();
838
839 ActiveListFromHardware_old = ActiveListFromHardware;
840 } else if(NewKickSeen & LatchActiveSeenFirstTime) {
841 ActiveListFromHardware = ActiveListSnapShot;
842 printf("New KICK Seen\n");
843 // StoreBack All the old Contexts
844 old_arb_id= old_arb_idSnapShot;
845 // LoadDMAStates(ActiveListSnapShot);
846 printf("DRR DEBUG ActiveListSnapShot - %x From Verif Model - %x \n",ActiveListSnapShot,OrigDMAActiveList);
847 PullTokensBack(ActiveListSnapShot);
848 printf("DRR DEBUG Restart DRR - Time - %d \n",TIME);
849
850
851 }
852
853 if(LatchActiveSeenFirstTime==0) {
854 ActiveListFromHardware = 0;
855 printf("First KICK Seen\n");
856 }
857 //@(posedge port_bind.$clk);
858
859
860 if(ActiveListFromHardware!==OrigDMAActiveList) {
861 printf(" DRR DEBUG - Warning - Changing Verif List to - %d !! \n",ActiveListFromHardware);
862 } else {
863 printf(" DRR DEBUG - Active Lists Match -!! \n");
864 }
865 DMAActiveList = ActiveListFromHardware;
866
867 dmas_active = 0;
868
869
870 for(i = 0; i < 32; i ++) {
871 if(DMAActiveList[i] ) {
872 // added code for using cache model
873 // checktoken_valid
874
875 if (get_plus_arg(CHECK,"WCACHE_MODEL")) {
876 if(dma[i].checkTokenHeadValid_from_Mcache()) {
877 dmas_active = ( dmas_active | ( 1<< i ));
878 if(NewKickSeen & LatchActiveSeenFirstTime) {
879 printf("SKIP CREDITS ADDITIONS at time %d\n",{get_time(HI), get_time(LO)});
880 } else {
881 if(all_dmas_deficit) {
882 dma[i].add_drr_credits();
883 printf("DRR_DEBUG ADDED CREDITS at time %d\n",{get_time(HI), get_time(LO)});
884 }
885 }
886 } else printf(" WCACHE_MODEL TokenList Empty\n");
887 } else {
888 if(dma[i].checkTokenHeadValid()) {
889 dmas_active = ( dmas_active | ( 1<< i ));
890 if(NewKickSeen & LatchActiveSeenFirstTime) {
891 printf("SKIP CREDITS ADDITIONS at time %d\n",{get_time(HI), get_time(LO)});
892 } else {
893 if(all_dmas_deficit) {
894 dma[i].add_drr_credits();
895 printf("DRR_DEBUG ADDED CREDITS at time %d\n",{get_time(HI), get_time(LO)});
896 }
897 }
898 } else printf("TokenList Empty\n");
899 }
900 }
901 }
902
903
904 printf("DRR DEBUG -Active list - %x Time - %d \n",dmas_active,{get_time(HI), get_time(LO)});
905 while(dmas_active) {
906
907 printf("DRR DEBUG Restart DRR - Time - %d \n",TIME);
908 arb_id = old_arb_id ;
909
910 dma_id = -1;
911 match_found =0;
912 iter =0;
913
914 while( (iter <32 /*MAX_NO_OF_DMAS*/) & ( !match_found)) {
915 // printf(" DRR DEBUG arb_id - %x dmas_active - %x \n",arb_id,dmas_active);
916 if(check_active(arb_id,dmas_active)) {
917 printf(" DRR DEBUG MATCHED arb_id - %x dmas_active - %x \n",arb_id,dmas_active);
918 dma_id = arb_id;
919 match_found = 1;
920 }
921 arb_id = (arb_id + 1)%32;
922 iter++;
923 } // At the end of this there should be at least one dma_id selected
924
925 if( (dma_id == -1) ) {
926 printf("DRR DEBUG Error in the code -- FIX IT \n");
927 return;
928 }
929
930
931 if (get_plus_arg(CHECK,"WCACHE_MODEL"))
932 status = dma[dma_id].get_current_token_from_Mcache(TxToken);
933 else
934 status = dma[dma_id].get_current_token(TxToken);
935
936 /* TODO
937 if the token is valid then only send it across, else do nothing
938
939 The status above indicates the following
940 - EOL reached or not
941 - any error associated with this packet
942 - if the dma hasnt been kicked
943
944 */
945
946 maintain_active_state = 1;
947 if(status == -1) {
948 printf(" DRR DEBUG descriptor either not initialised or packet in the descriptor not kicked DMA = %d \n",dma_id);
949 maintain_active_state = 0;
950 } else {
951 if(dma[dma_id].current_deficit > 0) {
952 length = TxToken.pkt_length + 16;
953 TxToken.current_deficit = dma[dma_id].current_deficit;
954
955 maintain_active_state = dma[dma_id].update_deficit(length); //
956 printf("DRR DEBUG Sending data for channel #%d length = %d New Deficit = %d \n",dma_id,length,dma[dma_id].current_deficit);
957 printf("DRR DEBUG Sending Token %d for channel #%d length = %d descriptor address - %x \n",TxToken.id,dma_id,length,TxToken.descriptor_address);
958 printf("DEBUG trans_id Sending Token %d for channel #%d length = %d packet_Addres - %x Deficit - %d \n",TxToken.id,dma_id,length,TxToken.xlate_gather_address[0],TxToken.current_deficit);
959
960 if (get_plus_arg(CHECK,"WCACHE_MODEL"))
961 dma[dma_id].M_TxTokenList.pop_front();
962 else
963 dma[dma_id].TxTokenList.pop_front();
964
965 if(dma[dma_id].conf_part_err_seen) {
966 printf(" Tx Token id - %d Error Set - Packet to be dropped !!!! \n",TxToken.id);
967 } else if((TxToken.error_info.hosterrors.packet_errors == PKT_PART_ERROR)|(dma[dma_id].pkt_part_err_seen )){
968 dma[dma_id].pkt_part_err_seen = 1;
969
970 printf(" Tx Token id - %d Error Set - Packet to be dropped !!!! \n",TxToken.id);
971 } else {
972 dma[dma_id].incPktCnt();
973 if(USE_CALL_BACKS) {
974 TxPortCbMgr.CheckReqCbs(TxToken);
975 TxPortCbMgr.pushToPortTokenList(TxToken);
976 } else {
977 TxPortCbMgr.CheckReqCbs(TxToken);
978 mailbox_put(mbox_id.mac_opp[this.id],TxToken.pgToken);
979 }
980 printf("DRR_DEBUG Token_id %0d sent to end_chkr at time %d\n",TxToken.id,{get_time(HI),get_time(LO)});
981
982 if(MAC_LOOP_BACK_MODE[this.id]) {
983 // Send the packet to Rx Token List
984 RxToken = new();
985 RxToken.id=TxToken.pgToken.gId;
986 RxToken.pkt_length = TxToken.pkt_length + 4 ;
987 RxToken.pgToken = TxToken.pgToken.object_copy();
988 RxToken.pgToken.pack_db.flow.partial_chksum = 0;
989 RxToken.dma_num=TxToken.loop_back_rxdma_num;
990 RxToken.last_packet=TxToken.loop_back_rx_lastpacket;
991 RxToken.port_num=this.id;
992 mailbox_put(mbox_id.niu_rxpath_mb[RxToken.port_num],RxToken);
993 printf("Tx DRR_DEBUG Token_id %0d sent to Rx DRR Loop Back Mode at time %d\n",TxToken.id,{get_time(HI),get_time(LO)});
994 } else if(EXT_LOOPBACK_DST != -1 ) {
995 // Send the packet to Rx Token List
996 RxToken = new();
997 RxToken.id=TxToken.pgToken.gId;
998 RxToken.pkt_length = TxToken.pkt_length + 4 ;
999 RxToken.pgToken = TxToken.pgToken.object_copy();
1000 RxToken.pgToken.pack_db.flow.partial_chksum = 0;
1001 RxToken.dma_num= EXT_LOOPBACK_DST;
1002 //RxToken.dma_num=TxToken.loop_back_rxdma_num;
1003 RxToken.last_packet=TxToken.loop_back_rx_lastpacket;
1004 RxToken.port_num= EXT_LOOPBACK_DST;
1005 mailbox_put(mbox_id.niu_rxpath_mb[RxToken.port_num], RxToken);
1006 printf("MaxTxPort%0d Token_id=%0d sent to Rx Ext loopback port=%0d dma=%0d time=%0d\n", this.id, TxToken.id, RxToken.port_num, RxToken.dma_num, TIME);
1007
1008 }
1009 } // end elseif error_set
1010
1011 } else {
1012 maintain_active_state = 0;
1013 printf("DRR DEBUG DMA# %d In deficit Need more credit \n",dma_id);
1014 }
1015 }
1016
1017 // int status = DMA[dma_id]->update_descriptor();
1018
1019
1020 if (get_plus_arg(CHECK,"WCACHE_MODEL"))
1021 status = dma[dma_id].get_current_token_from_Mcache(TxToken);
1022 else
1023 status = dma[dma_id].get_current_token(TxToken);
1024
1025 if(status == -1) {
1026 // EOL Reached
1027 // dma[dma_id].current_deficit_old = dma[dma_id].current_deficit;
1028 // dma[dma_id].current_deficit = 0;
1029 // deficit_list[dma_id] = 1'b1;
1030 }
1031
1032 status = 1;
1033 if(status==0) { // delete the DMA from the active list
1034 dmas_active = dmas_active ^ ( 1 << dma_id );
1035 maintain_active_state = 0;
1036 printf("DRR DEBUG Deleting Channel #%d from Active List due to descriptor errors \n",dma_id);
1037 }
1038
1039 if(maintain_active_state==0) {
1040 printf(" DRR DEBUG - Before deleting dmas_active = %x \n",dmas_active);
1041 dmas_active = dmas_active ^ ( 1 << dma_id );
1042 printf("DRR DEBUG Deleting Channel #%d from Active List: Channel Id %d has -ve Deficit= %d \n",dma_id,dma_id,dma[dma_id].current_deficit);
1043 // deficit_list[dma_id] = 1'b1;
1044 printf(" DRR DEBUG - After deleting dmas_active = %x \n",dmas_active);
1045 old_arb_id = (dma_id + 1) %32 ;
1046 }
1047 }
1048 // @(posedge CLOCK);
1049 // @(posedge port_bind.$clk);
1050
1051 printf(" DRR DEBUG Resetting old_arb_id to 0 Time - %d \n",{get_time(HI), get_time(LO)});
1052 old_arb_id = 0;
1053 printf(" DRR DEBUG done with DRR Time - %d list - %x \n", {get_time(HI), get_time(LO)},dmas_active);
1054
1055
1056 dma_deficit_list=0;
1057 total_dmas_active = 0;
1058 deficit_list = 0;
1059 for(i=0;i<32;i++) {
1060 if(ActiveListFromHardware[i] && (dma[i]!=null)) {
1061 total_dmas_active++;
1062 if(dma[i].current_deficit <=0) {
1063 dma_deficit_list++;
1064 deficit_list[i] = 1'b1;
1065 printf("DRR DEBUG Before Add Credit - dma - %d in defict, Total - %d \n",i,dma_deficit_list);
1066 }
1067 }
1068 }
1069
1070
1071
1072 no_of_dmas_eoflist=0;
1073
1074 if(NewKickSeen & LatchActiveSeenFirstTime & (LatchActiveSeen==0)) {
1075 // unlock the queue
1076 printf("UNLOCK Time - %d \n",TIME);
1077 trigger(ON,TxPortCbMgr.lock_port_queue);
1078 }
1079
1080 if(1){
1081 // All of these gets processed when clr_eoflist signal comes
1082 // if a new kick is seen then this need not be executed
1083 got_new_kick = wait_for_addcredit(port_bind);
1084 if(got_new_kick) {
1085 printf("Exiting wait_for_addcredit because of new kick Time - %d \n",TIME);
1086 } else {
1087 for(i=0;i<32;i++) {
1088 if(OrigDMAActiveList[i]) {
1089 if(( total_dmas_active==1)&& ( port_bind.$eoflist[i] )) {
1090 dma[i].current_deficit = 0;
1091 if(deficit_list[i]==1'b0) {
1092 no_of_dmas_eoflist++;
1093 }
1094 dma[i].add_drr_credits();
1095 printf("Resetting the deficit for DMA_ID %d total_dmas = %d \n",i,total_dmas_active);
1096 /*FIX } else if(port_bind.$eoflist[i] && (dma[i].current_deficit <0) ){*/
1097 /* Seems like RTL clears defict regardless of the current defict.. Check with Rahoul*/
1098 } else if(port_bind.$eoflist[i] ){
1099 dma[i].current_deficit = 0;
1100 if(deficit_list[i]==1'b0) {
1101 no_of_dmas_eoflist++;
1102 }
1103 dma[i].add_drr_credits();
1104 printf("Resetting the deficit for DMA_ID %d total_dmas = %d \n",i,total_dmas_active);
1105 }
1106 }
1107 }
1108 dma_deficit_list = dma_deficit_list+no_of_dmas_eoflist;
1109 all_dmas_deficit = ((dma_deficit_list>=total_dmas_active)|| ( total_dmas_active==1)) ;
1110 printf("DRR DEBUG : val of dma_deficit_list %0d\n",dma_deficit_list);
1111 printf("DRR DEBUG : val of total_dmas_active %0d at time 0%d\n",total_dmas_active,{get_time(HI),get_time(LO)});
1112 }
1113 }
1114
1115
1116}
1117
1118}
1119
1120function integer CMacTxPort :: wait_for_addcredit(txc_port_drr port_bind)
1121{
1122
1123 integer no_of_entries,got_new_kick;
1124 CTxDrrTr drr_trigger;
1125
1126 got_new_kick =0;
1127 fork {
1128 no_of_entries = mailbox_get(COPY_WAIT,mbox_id.niu_txdrr[id],drr_trigger);
1129 if(drr_trigger.NewKickSeen) {
1130 got_new_kick = 1;
1131 } else got_new_kick = 0;
1132 }
1133 {
1134 @(posedge port_bind.$clr_eoflist);
1135 printf("GOT TXC_ADD_CREDIT\n");
1136 got_new_kick = 0;
1137 }
1138 join any
1139 wait_for_addcredit = got_new_kick;
1140}
1141
1142task CMacTxPort :: check_pkt_cnt (integer no_of_pkts, (integer timeout_count = 100),(integer chk_type = 0)) {
1143
1144integer no_ofpkts_toprt = 0;
1145integer rtl_tot_pkcnt;
1146integer all_pkts_done = 0;
1147integer timeout_cnt = 0;
1148integer prev_rtl_pkt_cnt = 0;
1149
1150bit [39:0] address;
1151bit [63:0] r_data;
1152
1153 address = TXC_FZC_BASE+ (TXC_PKT_XMIT + port_offset);
1154 no_ofpkts_toprt = get_allpkts_toport(no_of_pkts);
1155 printf("Total_expected_pkts %d from Port %d\n",no_ofpkts_toprt,this.id);
1156
1157 while(!all_pkts_done) {
1158 repeat (timeout_count) @(posedge CLOCK);
1159 gen_pio_drv.pio_rd(address,r_data);
1160 rtl_tot_pkcnt = r_data[15:0];
1161
1162 if(chk_type == 0) {
1163 if(rtl_tot_pkcnt == no_ofpkts_toprt) {
1164 all_pkts_done = 1;
1165 trigger(ON,TX_rvcd_allpkts[id]);
1166 be_msg.print(e_mesg_info,"niu_tx_port","chk_pkt_cnt","All pkts_rvcd at Port %0d\n", id);
1167 } else {
1168 if((timeout_cnt > 1000) && (prev_rtl_pkt_cnt == rtl_tot_pkcnt)) {
1169 all_pkts_done = 1;
1170 trigger(ON,TX_rvcd_allpkts[id]);
1171 be_msg.print(e_mesg_error,"niu_tx_port","chk_pkt_cnt","No change In pkt_cnt for 10000 clocks for Port %0d\n", id);
1172 } else {
1173 if(prev_rtl_pkt_cnt == rtl_tot_pkcnt) {
1174 timeout_cnt++;
1175 } else {
1176 timeout_cnt = 0;
1177 }
1178 prev_rtl_pkt_cnt = rtl_tot_pkcnt;
1179 }
1180
1181 }
1182 } else {
1183 if(rtl_tot_pkcnt >= no_ofpkts_toprt) {
1184 all_pkts_done = 1;
1185 trigger(ON,TX_rvcd_allpkts[id]);
1186 be_msg.print(e_mesg_info,"niu_tx_port","chk_pkt_cnt","All pkts_rvcd at Port %0d\n", id);
1187 } else {
1188 if((timeout_cnt > 100) && (prev_rtl_pkt_cnt == rtl_tot_pkcnt)) {
1189 all_pkts_done = 1;
1190 trigger(ON,TX_rvcd_allpkts[id]);
1191 be_msg.print(e_mesg_error,"niu_tx_port","chk_pkt_cnt","No change In pkt_cnt for 10000 clocks for Port %0d\n", id);
1192 } else {
1193 if(prev_rtl_pkt_cnt == rtl_tot_pkcnt) {
1194 timeout_cnt++;
1195 } else {
1196 timeout_cnt = 0;
1197 }
1198 prev_rtl_pkt_cnt = rtl_tot_pkcnt;
1199 }
1200
1201 }
1202 }
1203 }
1204
1205 if(get_plus_arg (CHECK, "MAC_SPEED0=100"))
1206 repeat (10000) @(posedge CLOCK);
1207 else if(get_plus_arg (CHECK, "MAC_SPEED0=10"))
1208 repeat (60000) @(posedge CLOCK);
1209 else
1210 repeat (2000) @(posedge CLOCK);
1211
1212 // using a plus arg to turn this on
1213
1214 if( get_plus_arg(CHECK,"ENB_TXEXIT_RT")) {
1215
1216 // check for pks stuffed in RE-ORDER fifo & Packets proccessed in PKT_ASSEMBLY
1217 check_pkts_stuffed(no_of_pkts);
1218
1219 // check pkt count for each DMA
1220 check_pkt_cnt_perdma(no_of_pkts);
1221
1222 // check mac tx frame cnt
1223 check_mac_txfrmcnt(no_ofpkts_toprt);
1224 }
1225
1226}
1227
1228//--- task to get check number of pkts on each port
1229//--- random number of pkts per DMA channel
1230
1231task CMacTxPort :: check_randompkt_cnt (integer no_of_pkts[24], (integer timeout_count = 100)) {
1232
1233integer no_ofpkts_toprt = 0;
1234integer rtl_tot_pkcnt;
1235integer all_pkts_done = 0;
1236integer timeout_cnt = 0;
1237integer prev_rtl_pkt_cnt = 0;
1238
1239bit [39:0] address;
1240bit [63:0] r_data;
1241
1242 address = TXC_FZC_BASE+ (TXC_PKT_XMIT + port_offset);
1243 no_ofpkts_toprt = get_allpkts_toport_random(no_of_pkts);
1244 // printf("TOT_PKT_CNT %0d\n",no_ofpkts_toprt);
1245 printf("Total_expected_pkts %d from Port %d\n",no_ofpkts_toprt,this.id);
1246
1247 while(!all_pkts_done) {
1248 repeat (timeout_count) @(posedge CLOCK);
1249 gen_pio_drv.pio_rd(address,r_data);
1250 rtl_tot_pkcnt = r_data[15:0];
1251
1252 if(rtl_tot_pkcnt == no_ofpkts_toprt) {
1253 all_pkts_done = 1;
1254 trigger(ON,TX_rvcd_allpkts[id]);
1255 be_msg.print(e_mesg_info,"niu_tx_port","chk_pkt_cnt","All pkts_rvcd at Port %0d\n", id);
1256 } else {
1257 if((timeout_cnt > 100) && (prev_rtl_pkt_cnt == rtl_tot_pkcnt)) {
1258 all_pkts_done = 1;
1259 trigger(ON,TX_rvcd_allpkts[id]);
1260 be_msg.print(e_mesg_error,"niu_tx_port","chk_pkt_cnt","No change In pkt_cnt for 10000 clocks for Port %0d\n", id);
1261 } else {
1262 if(prev_rtl_pkt_cnt == rtl_tot_pkcnt) {
1263 timeout_cnt++;
1264 } else {
1265 timeout_cnt = 0;
1266 }
1267 prev_rtl_pkt_cnt = rtl_tot_pkcnt;
1268 }
1269
1270 }
1271 }
1272
1273 repeat (2000) @(posedge CLOCK);
1274
1275}
1276
1277
1278//-- Calculte the number of pkts to port
1279//-- Number of pkts per DMA are same
1280
1281function integer CMacTxPort :: get_allpkts_toport (integer no_of_pkts) {
1282
1283integer i;
1284integer t_no_of_pkts = 0;
1285
1286 for(i = 0; i < 24; i ++) {
1287 if(OrigDMAActiveList[i]) {
1288 t_no_of_pkts = t_no_of_pkts + no_of_pkts;
1289 // printf("TOT_PKTS %0d\n",t_no_of_pkts);
1290 }
1291 }
1292
1293 get_allpkts_toport = t_no_of_pkts;
1294}
1295
1296
1297//-- Calculte the number of pkts to port
1298//-- Number of pkts per DMA are same
1299
1300function integer CMacTxPort :: get_allpkts_toport_random (integer no_of_pkts[24]) {
1301
1302integer i;
1303integer t_no_of_pkts = 0;
1304
1305 for(i = 0; i < 24; i ++) {
1306 if(OrigDMAActiveList[i]) {
1307 t_no_of_pkts = t_no_of_pkts + no_of_pkts[i];
1308 // printf("TOT_PKTS %0d\n",t_no_of_pkts);
1309 }
1310 }
1311
1312 get_allpkts_toport_random = t_no_of_pkts;
1313}
1314
1315
1316task CMacTxPort::check_pkt_cnt_perdma (integer no_of_pkts) {
1317
1318 integer i = 0;
1319 bit [63:0] rd_data;
1320 bit [63:0] hd_ptr;
1321 bit [63:0] tail_ptr;
1322
1323 for(i = 0; i < 24; i ++) {
1324 if(OrigDMAActiveList[i]) {
1325 dma[i].Read_TxCs(rd_data);
1326 if(rd_data[59:48] != no_of_pkts) {
1327 be_msg.print(e_mesg_error,"niu_tx_port","check_pkt_cnt_perdma","PKT_CNT MISMATCH for DMA_ID %d\n",i);
1328 }
1329 // read the head and tail and compare they should be equal
1330 dma[i].RdTxRngHDL(hd_ptr);
1331 @(posedge CLOCK);
1332 dma[i].RdTxRngKick(tail_ptr);
1333 if(hd_ptr[19:0] != tail_ptr[19:0]) {
1334 be_msg.print(e_mesg_error,"niu_tx_port","check_pkt_cnt_perdma","HD & TAIL PTRs MISMATCH for DMA_ID %d\n",i);
1335 }
1336 }
1337 }
1338}
1339
1340
1341task CMacTxPort::check_exit_status() {
1342
1343
1344// Tasks to look at the remaining tokens in the mailbox and determine the appropriate
1345// action to be taken
1346
1347 integer no_of_tokens_remaining;
1348 CpgToken pgToken;
1349 integer i;
1350
1351 if( get_plus_arg(CHECK,"BYPASS_TXDRR")) {
1352 // do no checks of the mailbox, drr byppassed in this mode
1353 } else {
1354 printf(" DEBUG- Checking exit status for Tx port %d \n",id);
1355 no_of_tokens_remaining = mailbox_get(NO_WAIT,mbox_id.mac_opp[id], pgToken);
1356 if(no_of_tokens_remaining >0) {
1357 printf("ERROR Not all tokens received by packetchecker at port %d \n",id);
1358 printf("Pending Tokens not received by Packet Checker= %d \n",no_of_tokens_remaining);
1359 be_msg.print(e_mesg_error, "","","ERROR Not all tokens received by packetchecker at port = %d\n",id);
1360
1361 }
1362
1363 for(i = 0; i < 32; i ++) {
1364 if(OrigDMAActiveList[i]) {
1365 if(dma[i].checkTokenHeadValid()) {
1366 printf("ERROR Not all tokens sent to packetchecker at port %d for DMA # %d \n",id,i);
1367 be_msg.print(e_mesg_error, "","","ERROR Not all tokens sent to packetchecker from DRR at port = %d\n",id);
1368 }
1369 }
1370 }
1371 }
1372}
1373
1374task CMacTxPort :: check_pkts_stuffed(integer no_of_pkts) {
1375
1376 integer ro_pkts_num = 0;
1377 integer pkt_ass_pkts_num = 0;
1378 integer num_pkts_sent = 0;
1379
1380 bit [39:0] address;
1381 bit [63:0] r_data;
1382
1383 address = TXC_FZC_BASE+ (TXC_PKT_STUFFED + port_offset);
1384 gen_pio_drv.pio_rd(address,r_data);
1385
1386 ro_pkts_num = r_data[31:16];
1387 pkt_ass_pkts_num = r_data[15:0];
1388
1389 num_pkts_sent = get_allpkts_toport(no_of_pkts);
1390
1391 if(ro_pkts_num != num_pkts_sent)
1392 be_msg.print(e_mesg_error,"CMacTxPort","check_pkts_stuffed","RO_fifo pkts stuffed check failed for port_id %d\n",this.id);
1393 else
1394 be_msg.print(e_mesg_info,"CMacTxPort","check_pkts_stuffed","RO_fifo pkts stuffed check passed for port_id %d\n",this.id);
1395
1396 if( pkt_ass_pkts_num != num_pkts_sent)
1397 be_msg.print(e_mesg_error,"CMacTxPort","check_pkts_stuffed","Pktassem_fifo pkts stuffed check failed for port_id %d\n",this.id);
1398 else
1399 be_msg.print(e_mesg_info,"CMacTxPort","check_pkts_stuffed","Pktassem_fifo pkts stuffed check passed for port_id %d\n",this.id);
1400
1401}
1402
1403task CMacTxPort :: check_mac_txfrmcnt(integer no_of_pkts) {
1404
1405 bit [39:0] base_addr;
1406 bit[31:0] rd_data, rd_status, rd_mask;
1407
1408 base_addr = mac_util.get_mac_reg_base(this.id);
1409 if((this.id == 0) || (this.id == 1))
1410 mac_pio_class.xmac_pio_rd(base_addr + TxMAC_FRM_CNT, rd_status, 1'b0);
1411 else
1412 mac_pio_class.xmac_pio_rd(base_addr + BTxMAC_FRM_CNT, rd_status, 1'b0);
1413
1414 if(rd_data[20:0] != no_of_pkts)
1415 be_msg.print(e_mesg_error,"CMacTxPort","check_mac_txfrmcnt","MAC Tx_frame_cnt chk failed for port_id %d\n",this.id);
1416 else
1417 be_msg.print(e_mesg_info,"CMacTxPort","check_mac_txfrmcnt","MAC Tx_frame_cnt chk passed for port_id %d\n",this.id);
1418
1419}