Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / rxc_sat / vera / monitor / rdmc_mon.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: rdmc_mon.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 "rdmc_mon_if.vri"
37#include "cMesg.vrh"
38
39// constants that needs to be varied based on observations
40#define RDMC_MON_TIMESCALE_ADJUST 1 // to make it nsec
41
42// getting the following defines from plus args way.
43
44extern bit [3:0] rtl_mac;
45extern bit reset_complete;
46extern event RX_chk_done;
47extern Mesg be_msg;
48
49class RdmcMonitorStats {
50
51 string name = "RdmcMonStats";
52 integer time_offset = -1;
53
54 integer index=0; // also can be used as pkt count
55
56 // counters for each transaction
57 bit [63:0] raw_time_stamp[1024*16];
58 bit [63:0] raw_byte_count[1024*16];
59 bit [63:0] raw_bw[1024*16];
60
61 bit [63:0] time_stamp[];
62 bit [63:0] byte_count[];
63
64 bit [63:0] raw_bandwidth[1024*16];
65 bit [63:0] raw_total_byte_count=0;
66
67 bit [3:0] status[];
68 integer moving_average_bandwidth[];
69 bit skip_flag[]; // used to skip unstable bw at the end
70
71 // over all statistics after skipping start and end unsstable bandwidths
72 bit [63:0] total_time=0;
73 bit [63:0] total_byte_count=0;
74 bit [63:0] total_bandwidth=0;
75
76 integer percent_bw_skip;
77 integer moving_average_window;
78
79 task display_transaction((integer index = -1));
80 task display_transaction_short((integer index = -1));
81 task display_short((integer index = -1));
82 task calculate_moving_average_bandwidth();
83 task update_total_time();
84 task update_total_byte_count();
85 task update_total_bandwidth();
86 task update_raw_bandwidth();
87 function bit [63:0] get_time_in_nsec();
88 function bit [63:0] get_moving_average_time();
89 function bit [63:0] get_moving_average_byte_count();
90 function bit [63:0] get_difference(integer val1, integer val2);
91
92 task new(string name_in, integer percent_bw_skip_in, integer moving_average_window_in) {
93 integer i;
94 name = name_in;
95 percent_bw_skip = percent_bw_skip_in;
96 moving_average_window = moving_average_window_in;
97 }
98
99} // class RdmcMonitorStats
100
101// skip calculations until bandwidth stabilizes
102// Example : preBw = 20, currBw = 40, skipPercent = 10
103// if (currBw-prevBw)*100/currBw > skipPercent) then skip bw calculations
104task RdmcMonitorStats::calculate_moving_average_bandwidth() {
105
106 integer i;
107
108 if(index<=moving_average_window) {
109 skip_flag[index] = 1;
110 moving_average_bandwidth[index] = 0;
111 return;
112 } else {
113 skip_flag[index] = 0;
114 }
115
116 // -ve and divide by zero error
117 if(get_moving_average_time()<=0) {
118 moving_average_bandwidth[index] = moving_average_bandwidth[index-1];
119 skip_flag[index] = skip_flag[index-1];
120 return;
121 }
122
123 moving_average_bandwidth[index] = (get_moving_average_byte_count() * 1000 * 8) / // Mbps
124 get_moving_average_time();
125
126
127
128// if((((get_difference(moving_average_bandwidth[index],
129
130// moving_average_bandwidth[index]) >
131// percent_bw_skip) {
132// // skip
133// skip_flag[index] = 1;
134//
135// } else {
136// // don't skip
137// skip_flag[index] = 0;
138// }
139}
140
141function bit [63:0] RdmcMonitorStats::get_difference(integer val1, integer val2) {
142 if(val1 < val2) get_difference = val2 - val1;
143 else get_difference = val1 - val2;
144}
145
146function bit [63:0] RdmcMonitorStats::get_moving_average_time() {
147 integer i;
148 get_moving_average_time = 0;
149 if(index<=moving_average_window) return;
150 get_moving_average_time = time_stamp[index] -
151 time_stamp[index-moving_average_window];
152}
153
154function bit [63:0] RdmcMonitorStats::get_moving_average_byte_count() {
155 integer i;
156 get_moving_average_byte_count = 0;
157 if(index<=moving_average_window) return;
158 for(i=index-moving_average_window+1;i<=index;i++)
159 get_moving_average_byte_count += byte_count[i];
160}
161
162task RdmcMonitorStats::update_total_time() {
163 if(index<=moving_average_window) { total_time = 0; return; }
164 if(skip_flag[index]) return;
165 total_time = time_stamp[index];
166}
167
168task RdmcMonitorStats::update_total_byte_count() {
169 if(index<moving_average_window) { total_byte_count = 0; return; }
170 if(skip_flag[index]) return;
171 total_byte_count += byte_count[index];
172}
173
174task RdmcMonitorStats::update_total_bandwidth() {
175 if(index<=moving_average_window) { total_bandwidth = 0; return; }
176 if(skip_flag[index]) return;
177 // -ve and divide by zero error
178 if(total_time <= 0) { total_bandwidth = 0; return; }
179 total_bandwidth = (total_byte_count * 1000 * 8) / total_time ; // Mbps
180 if(total_bandwidth<0) {
181 printf("<%0d> %s: ERROR: update_total_bandwidth: negative bandwidth detected!\n",
182 get_time(LO), name);
183 printf("total_bandwidth:%0d total_byte_count:%0d total_time:%0d\n",
184 total_bandwidth, total_byte_count, total_time);
185 }
186 //printf("DEBUG: total_byte_count:%0d total_time:%0d total_bandwidth:%0d, index:%0d\n",
187 // total_byte_count, total_time, total_bandwidth, index);
188}
189
190task RdmcMonitorStats::update_raw_bandwidth() {
191 // -ve and divide by zero error
192 if(get_time_in_nsec() <= 0) { raw_bandwidth[index] = 0; return; }
193 raw_bandwidth[index] = (raw_total_byte_count * 1000*8) / get_time_in_nsec(); // Mbps
194 if(total_bandwidth<0) {
195 printf("<%0d> %s: ERROR: update_raw_bandwidth: negative bandwidth detected!\n",
196 get_time(LO), name);
197 printf("raw_bandwidth[%0d]:%0d raw_total_byte_count:%0d total_time:%0d\n",
198 index, raw_bandwidth[index], raw_total_byte_count, get_time_in_nsec());
199 }
200}
201
202task RdmcMonitorStats::display_transaction((integer index_in = -1)) {
203 integer i;
204 if(index_in == -1) { index_in = index; }
205 printf("===============================================================\n");
206 printf("<%0d> %s: transaction statistics for index:%0d\n",
207 get_time(LO), name, index_in);
208 printf("time_stamp:%0d usec, length:%0d, status:%0d, skip_flag[%0d]:%b, rawBw:%0d\n",
209 time_stamp[index_in], byte_count[index_in],
210 status[index_in], index_in, skip_flag[index_in], raw_bandwidth[index_in]);
211 printf("tot_time:%0d usce tot_byte_cnt:%0d, tot_bw:%0d Mbps, MA_bw:%0d Mbps\n",
212 total_time, total_byte_count, total_bandwidth, moving_average_bandwidth[index_in]);
213 printf("===============================================================\n");
214}
215
216task RdmcMonitorStats::display_transaction_short((integer index_in = -1)) {
217 integer i;
218 bit [63:0] bits=0, time_diff;
219 integer moving_average_window_for_display;
220 if(index_in == -1) { index_in = index; }
221
222 if(index_in < (moving_average_window*2)) {
223 raw_bw[index_in] = 0;
224 }
225 else {
226 for(i=moving_average_window;i<=index_in-moving_average_window-1;i++) {
227 bits += raw_byte_count[i]*8;
228 }
229 // Equation
230 // BW = SumOfLengths(MAW, index-MAW-1) / differenceInTime(index-MAW, MAW)
231 //
232
233 time_diff = raw_time_stamp[index_in-moving_average_window] -
234 raw_time_stamp[moving_average_window];
235
236 // divide by zero error
237 if(time_diff <= 0) {
238 raw_bw[index_in] = 0;
239 } else {
240 raw_bw[index_in] = (bits*1000) / time_diff;
241
242
243 // while(raw_bw[index_in] < 0) {
244 // bits /= 2;
245 // time_diff /= 2;
246 // if(time_diff <= 0) {
247 // raw_bw[index_in] = 0;
248 // } else {
249 // raw_bw[index_in] = (bits*1000) / time_diff;
250 // }
251 // }
252 }
253 }
254
255
256 if(index_in-moving_average_window < 0) {
257 moving_average_window_for_display = index_in;
258 } else {
259 moving_average_window_for_display = moving_average_window;
260 }
261
262 printf("<%0d> %s: RDMC_MON index:%0d, start_time:%0d (ns), end_time:%0d (ns), lenght:%0d (bits), bw:%0d (Mbps)\n",
263 get_time(LO), name, index_in, raw_time_stamp[moving_average_window_for_display],
264 raw_time_stamp[index_in-moving_average_window_for_display], bits, raw_bw[index_in] );
265}
266
267task RdmcMonitorStats::display_short((integer index_in = -1)) {
268 integer i;
269 if(index_in == -1) { index_in = index; }
270 if(index_in == 0) {
271 printf("================= stats for %s ==================\n", name);
272 printf("index\tbyteCnt\ttime-us\tTotBw\tMA_BW\tskpFlg\tRawBw\tname:%0s\n", name);
273 }
274
275 printf("%0d\t%0d\t%0d\t%0d\t%0d\t%b\t%0d\t%s\n",
276 index_in,total_byte_count,total_time,total_bandwidth,
277 moving_average_bandwidth[index_in],
278 skip_flag[index_in],raw_bandwidth[index_in],name);
279}
280
281function bit [63:0] RdmcMonitorStats::get_time_in_nsec() {
282 if(time_offset == -1) { get_time_in_nsec = 0; time_offset = get_time(LO);}
283 else get_time_in_nsec = (get_time(LO)-time_offset) / RDMC_MON_TIMESCALE_ADJUST;
284}
285
286class RdmcMonitor {
287
288 integer debugLevel;
289 string name = "RDMC_MON";
290 bit [3:0] valid_mac_ports; // from vera_top.vr @ env/vera/top/vera_top.vr
291 integer port_DRR_weights[]; // for each port
292 integer total_port_weights;
293 integer percent_bw_skip;
294 integer moving_average_window;
295 bit enable_DRR_fairness_monitor;
296 integer index;
297 integer percentBwMarginToIgnore = 20;
298 integer total_num_packets_per_port = 0;
299 integer total_num_valid_mac_ports = 0;
300 integer report_bandwidth_mismatch_error = 0;
301 integer number_of_pkts_sent[4];
302 integer number_of_pkts_rcvd[4];
303 integer prev_length[4];
304
305 //rdmc_mon_port myPort;
306 RdmcMonitorStats rdmcMonStats[]; // index is: 0: port0
307 // ........
308 // 3: port3
309 // 4: dma0
310 // ........
311 // 19: dma15
312 // 20: total
313
314 task run4everMonitorMetaInterface(rdmc_mon_port myPort);
315 task check_DRR_bandwidth_ratio();
316 function bit [63:0] diff_values(integer val1, integer val2);
317 task display_results();
318 task new ((integer debugLevelIn = 10));
319 task store_transactions(bit [1:0] port_num,
320 bit [4:0] dma_num,
321 bit [13:0] length,
322 bit [3:0] status);
323 task report_bandwidth((bit one_time = 0));
324 task report_bandwidth_periodically((integer period /*in us*/ = 100));
325
326} // class RdmcMonitor
327
328task RdmcMonitor::new ((integer debugLevelIn = 10)) {
329
330 string name_tmp;
331 integer i;
332 debugLevel = debugLevelIn;
333 //myPort = rdmc_mon_port_bind;
334
335 while(reset_complete == 0) { repeat(100) @(posedge CLOCK); }
336
337 if(get_plus_arg(CHECK,"RDMC_MON_PERCENT_BW_SKIP="))
338 percent_bw_skip = get_plus_arg(NUM,"RDMC_MON_PERCENT_BW_SKIP=");
339 else
340 percent_bw_skip = 30; // default
341
342 if(get_plus_arg(CHECK,"RDMC_MON_MV_AVG_WINDOW="))
343 moving_average_window = get_plus_arg(NUM,"RDMC_MON_MV_AVG_WINDOW=");
344 else
345 moving_average_window = 30; // default
346
347 if(get_plus_arg(CHECK,"RDMC_MON_PERCENT_DRR_BW_MARGIN="))
348 percentBwMarginToIgnore = get_plus_arg(NUM,"RDMC_MON_PERCENT_DRR_BW_MARGIN=");
349 else
350 percentBwMarginToIgnore = 20; // default
351
352 if(get_plus_arg(CHECK,"RDMC_MON_ENABLE_DRR_FAIRNESS_MONITOR"))
353 enable_DRR_fairness_monitor = 1;
354 else
355 enable_DRR_fairness_monitor = 0; // default
356
357 if(get_plus_arg(CHECK,"RDMC_MON_ENABLE_BANDWIDTH_MISMATCH_ERROR"))
358 report_bandwidth_mismatch_error = 1;
359 else
360 report_bandwidth_mismatch_error = 0; // default
361
362 for(index=0;index<=20;index++) {
363 if(index>=0 && index<4) { sprintf(name_tmp,"rdmcMonPort%0dStats", index); }
364 if(index>=4 && index<20) { sprintf(name_tmp,"rdmcMonDmaCh%0dStats",index-4);}
365 if(index==20) { name_tmp = "rdmcMonTotalStats"; }
366 rdmcMonStats[index] = new(name_tmp, percent_bw_skip, moving_average_window);
367 }
368
369 // default values
370 port_DRR_weights[0] = 0;
371 port_DRR_weights[1] = 0;
372 port_DRR_weights[2] = 0;
373 port_DRR_weights[3] = 0;
374
375 number_of_pkts_sent[0] = 0;
376 number_of_pkts_sent[1] = 0;
377 number_of_pkts_sent[2] = 0;
378 number_of_pkts_sent[3] = 0;
379
380 number_of_pkts_rcvd[0] = 0;
381 number_of_pkts_rcvd[1] = 0;
382 number_of_pkts_rcvd[2] = 0;
383 number_of_pkts_rcvd[3] = 0;
384
385 prev_length[0] = 0;
386 prev_length[1] = 0;
387 prev_length[2] = 0;
388 prev_length[3] = 0;
389
390 valid_mac_ports = rtl_mac; // from vera_top.vr @ env/vera/top/vera_top.vr
391
392 for(i=0;i<4;i++)
393 if(valid_mac_ports[i])
394 total_num_valid_mac_ports++;
395
396 // divide by zero error check
397 if(total_num_valid_mac_ports <= 0) {
398 printf("<%0d> %s: ERROR : total_num_packets_per_port=%0d, rtl_mac:%b\n",
399 get_time(LO), name, total_num_packets_per_port, rtl_mac);
400 return;
401 }
402
403 if(get_plus_arg(CHECK,"PORT0_WT="))
404 port_DRR_weights[0] = get_plus_arg(NUM,"PORT0_WT=");
405 if(get_plus_arg(CHECK,"PORT1_WT="))
406 port_DRR_weights[1] = get_plus_arg(NUM,"PORT1_WT=");
407 if(get_plus_arg(CHECK,"PORT2_WT="))
408 port_DRR_weights[2] = get_plus_arg(NUM,"PORT2_WT=");
409 if(get_plus_arg(CHECK,"PORT3_WT="))
410 port_DRR_weights[3] = get_plus_arg(NUM,"PORT3_WT=");
411 if(get_plus_arg(CHECK,"RXMAC_PKTCNT="))
412 total_num_packets_per_port = get_plus_arg(NUM,"RXMAC_PKTCNT=")/total_num_valid_mac_ports;
413
414 number_of_pkts_sent[0] = total_num_packets_per_port;
415 number_of_pkts_sent[1] = total_num_packets_per_port;
416 number_of_pkts_sent[2] = total_num_packets_per_port;
417 number_of_pkts_sent[3] = total_num_packets_per_port;
418
419 if(get_plus_arg(CHECK,"RXMAC_PORT0_PKTCNT="))
420 number_of_pkts_sent[0] = get_plus_arg(NUM,"RXMAC_PORT0_PKTCNT=");
421 if(get_plus_arg(CHECK,"RXMAC_PORT1_PKTCNT="))
422 number_of_pkts_sent[1] = get_plus_arg(NUM,"RXMAC_PORT1_PKTCNT=");
423 if(get_plus_arg(CHECK,"RXMAC_PORT2_PKTCNT="))
424 number_of_pkts_sent[2] = get_plus_arg(NUM,"RXMAC_PORT2_PKTCNT=");
425 if(get_plus_arg(CHECK,"RXMAC_PORT3_PKTCNT="))
426 number_of_pkts_sent[3] = get_plus_arg(NUM,"RXMAC_PORT3_PKTCNT=");
427
428 total_port_weights = port_DRR_weights[0] +
429 port_DRR_weights[1] +
430 port_DRR_weights[2] +
431 port_DRR_weights[3];
432
433 // divide by zero error
434 if(total_port_weights <= 0) { total_port_weights = 1; }
435
436
437 printf("<%0d> %s: RDMC_MON ====================== instantiating ... ====================\n",
438 get_time(LO), name);
439 printf("RDMC_MON moving average window:%0d, skip percentage :%0d, valid_mac_ports:%b\n",
440 moving_average_window, percent_bw_skip, valid_mac_ports);
441 printf("RDMC_MON port0 weight:%0d, port1 weight:%0d, port2 weight:%0d, port3 weight:%0d\n",
442 port_DRR_weights[0], port_DRR_weights[1], port_DRR_weights[2], port_DRR_weights[3]);
443 printf("<%0d> %s: RDMC_MON ====================== instantiating done ===================\n",
444 get_time(LO), name);
445
446 fork
447 run4everMonitorMetaInterface(rdmc_mon_port_bind);
448 join none
449
450 fork
451 report_bandwidth();
452 join none
453
454 fork
455 check_DRR_bandwidth_ratio();
456 join none
457 fork
458 report_bandwidth_periodically();
459 join none
460
461
462}
463
464task RdmcMonitor::run4everMonitorMetaInterface(rdmc_mon_port myPort) {
465
466 while(1) {
467 @(posedge myPort.$req);
468
469 // we are interested in only posted writes (Data path from rdma->meta)
470 // // bit 5: posted write, bit[2:0]: write memory (3'b001)
471 if((myPort.$req_cmd[5] == 1'b1) && (myPort.$req_cmd[2:0] == 3'b001))
472 store_transactions(myPort.$port_num,
473 myPort.$dma_num,
474 myPort.$req_length,
475 myPort.$status);
476 }
477}
478
479task RdmcMonitor::store_transactions(bit [1:0] port_num,
480 bit [4:0] dma_num,
481 bit [13:0] length,
482 bit [3:0] status) {
483 integer index;
484
485 // counters for each transaction
486 printf("RDMC_MON:store_transaction: port_num:%0d dma_num:%0d length:%0d time:%0d\n",
487 port_num, dma_num, length, {get_time(HI), get_time(LO)});
488
489 // update pkt cnt
490 if(prev_length[port_num] < 4096) { // Needed this since for Jumbo pkts we get 3 transations
491 number_of_pkts_rcvd[port_num]++;
492 }
493
494 prev_length[port_num] = length;
495
496 // update port stats
497 index = rdmcMonStats[port_num].index;
498 rdmcMonStats[port_num].raw_time_stamp[index] = ({get_time(HI), get_time(LO)})/RDMC_MON_TIMESCALE_ADJUST;
499 rdmcMonStats[port_num].raw_byte_count[index] = length;
500 rdmcMonStats[port_num].time_stamp[index] = rdmcMonStats[port_num].get_time_in_nsec();
501 rdmcMonStats[port_num].byte_count[index] = length;
502 rdmcMonStats[port_num].raw_total_byte_count += length;
503 rdmcMonStats[port_num].status[index] = status;
504
505 rdmcMonStats[port_num].calculate_moving_average_bandwidth();
506
507 rdmcMonStats[port_num].update_total_byte_count();
508 rdmcMonStats[port_num].update_total_time();
509 rdmcMonStats[port_num].update_total_bandwidth();
510 rdmcMonStats[port_num].update_raw_bandwidth();
511
512 //rdmcMonStats[port_num].display_transaction();
513 rdmcMonStats[port_num].display_transaction_short();
514 rdmcMonStats[port_num].display_short();
515
516
517 rdmcMonStats[port_num].index++;
518
519 /*
520 // update dma ch stats
521 index = rdmcMonStats[4+dma_num].index;
522 rdmcMonStats[4+dma_num].raw_time_stamp[index] = get_time(LO);
523 rdmcMonStats[4+dma_num].raw_byte_count[index] = length;
524 rdmcMonStats[4+dma_num].time_stamp[index] = rdmcMonStats[4+dma_num].get_time_in_nsec();
525 rdmcMonStats[4+dma_num].byte_count[index] = length;
526 rdmcMonStats[4+dma_num].raw_total_byte_count += length;
527 rdmcMonStats[4+dma_num].status[index] = status;
528
529 rdmcMonStats[4+dma_num].calculate_moving_average_bandwidth();
530
531 rdmcMonStats[4+dma_num].update_total_byte_count();
532 rdmcMonStats[4+dma_num].update_total_time();
533 rdmcMonStats[4+dma_num].update_total_bandwidth();
534 rdmcMonStats[4+dma_num].update_raw_bandwidth();
535
536 //rdmcMonStats[4+dma_num].display_transaction();
537 rdmcMonStats[4+dma_num].display_transaction_short();
538 rdmcMonStats[4+dma_num].display_short();
539 rdmcMonStats[4+dma_num].index++;
540 */
541
542 /*
543 // update total stats
544 index = rdmcMonStats[20].index;
545 rdmcMonStats[20].raw_time_stamp[index] = get_time(LO);
546 rdmcMonStats[20].raw_byte_count[index] = length;
547 rdmcMonStats[20].time_stamp[index] = rdmcMonStats[20].get_time_in_nsec();
548 rdmcMonStats[20].byte_count[index] = length;
549 rdmcMonStats[20].raw_total_byte_count += length;
550 rdmcMonStats[20].status[index] = status;
551
552 rdmcMonStats[20].calculate_moving_average_bandwidth();
553
554 rdmcMonStats[20].update_total_byte_count();
555 rdmcMonStats[20].update_total_time();
556 rdmcMonStats[20].update_total_bandwidth();
557 rdmcMonStats[20].update_raw_bandwidth();
558
559
560 //rdmcMonStats[20].display_transaction();
561 rdmcMonStats[20].display_transaction_short();
562 //rdmcMonStats[20].display_short();
563 rdmcMonStats[20].index++;
564 */
565
566} // task RdmcMonitor::store_transactions
567
568task RdmcMonitor::check_DRR_bandwidth_ratio() {
569
570 integer i, j, index_local;
571 bit [63:0] totalBw=0;
572 bit [63:0] portBw=0;
573 integer portWeightRatio=1;
574
575 if(enable_DRR_fairness_monitor == 0) return;
576
577 // wait for test to end the sim.
578 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : Waiting for RX_chk_done\n", get_time(LO));
579 sync (ALL, RX_chk_done);
580 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : Done. Waiting for RX_chk_done\n", get_time(LO));
581
582 //if(index < moving_average_window*3) { return; }
583
584 for(i=0;i<4;i++) {
585 if(rtl_mac[i]) {
586 totalBw += rdmcMonStats[i].raw_bw[rdmcMonStats[i].index-1];
587 }
588 }
589
590 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : totalBw:%0d\n", get_time(LO), totalBw);
591
592
593 // check for only valid ports
594 for(i=0;i<4;i++) {
595 if(rtl_mac[i]) {
596
597 //totalBw = rdmcMonStats[20].moving_average_bandwidth[index-moving_average_window];
598 portBw = rdmcMonStats[i].raw_bw[rdmcMonStats[i].index-1];
599 portWeightRatio = (port_DRR_weights[i] * 100) / total_port_weights;
600 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : portBw[%0d]:%0d portWeightRatio:%0d total_port_weights:%0d index:%0d\n",
601 get_time(LO), i, portBw, portWeightRatio, total_port_weights, rdmcMonStats[i].index);
602
603 // check if only portBw is valid
604 if(portBw === 'hx || portBw <= 0) {
605 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : Skipping port:%0d DRR report portBW=%0d\n",
606 get_time(LO), i, portBw);
607 continue;
608 }
609
610 // divide by zero error
611 if(portWeightRatio <= 0 || totalBw <= 0) {
612 printf("<%0d> RDMC_MON: check_DRR_bandwidth_ratio : Skipping port:%0d DRR report portWeightRatio=%0d totalBw:%0d \n",
613 get_time(LO), i, portWeightRatio, totalBw);
614 continue;
615 }
616
617 if(diff_values(((portBw*100)/totalBw), portWeightRatio) > percentBwMarginToIgnore ) {
618 printf("<%0d> %s: ERROR : bandwidth ratio mismatch!\n", get_time(LO), name);
619 printf("port[%0d]_total_Bw:%0d totalBw:%0d portWeightRatio:%0d, percentBwMarginToIgnore:%0d\n",
620 i, portBw, totalBw, portWeightRatio, percentBwMarginToIgnore);
621 } else {
622 printf("<%0d> %s: check_DRR_bandwidth_ratio : port%0dBw:%0d totalBw:%0d portWtRatio:%0d, percentDRRwtIgnore:%0d, actual_percentage:%0d\n",
623 get_time(LO), name, i, portBw, totalBw, portWeightRatio,
624 percentBwMarginToIgnore, diff_values(((portBw*100)/totalBw), portWeightRatio));
625 }
626 } // if(valid...)
627 } // for
628}
629
630function bit [63:0] RdmcMonitor::diff_values(integer val1, integer val2) {
631 if(val1 > val2) { diff_values = val1 - val2; }
632 else { diff_values = val2 - val1; }
633}
634
635task RdmcMonitor::report_bandwidth_periodically((integer period /*in us*/ = 100)) {
636 integer iterations = 1;
637 printf("<%0d> RDMC_MON:report_bandwidth_periodically enabled. with period:%0d us \n",
638 get_time(LO), period);
639 while(1) {
640 while({get_time(HI), get_time(LO)} <
641 ((period*1000*RDMC_MON_TIMESCALE_ADJUST) * (iterations)))
642 repeat(period) @(posedge CLOCK);
643 report_bandwidth(1);
644 iterations++;
645 repeat(100) @(posedge CLOCK); // to avoid infinite loop
646 }
647}
648
649task RdmcMonitor::report_bandwidth ((bit one_time = 0)) {
650 integer port_pkt_length[];
651 integer port_speed[];
652 integer port_ipg[];
653 bit [63:0] port_ideal_bw[4];
654 bit [63:0] port_actual_bw[4];
655 bit [63:0] total_ideal_bw=0;
656 bit [63:0] total_actual_bw=0;
657 integer i;
658 integer percentage_bw_to_ignore = 5;
659 integer percentage_bw_difference = 0;
660
661 // wait for test to end the sim.
662 if(one_time == 0) {
663 printf("<%0d> RDMC_MON: report_bandwidth : Waiting for RX_chk_done\n", get_time(LO));
664 sync (ALL, RX_chk_done);
665 printf("<%0d> RDMC_MON: report_bandwidth : Done. Waiting for RX_chk_done\n", get_time(LO));
666 }
667
668 // reset values
669 for(i=0;i<4;i++) {
670 port_pkt_length[i] = 64;
671 if(i<2) port_speed[i] = 10000;
672 if(i>1) port_speed[i] = 1000;
673 port_ipg[i] = 11;
674 port_ideal_bw[i] = 0;
675 port_actual_bw[i] = 0;
676 }
677
678 // get plus arg parameters
679 if(get_plus_arg(CHECK,"MAC_SPEED0="))
680 port_speed[0] = get_plus_arg(NUM,"MAC_SPEED0=");
681
682 if(get_plus_arg(CHECK,"MAC_SPEED1="))
683 port_speed[1] = get_plus_arg(NUM,"MAC_SPEED1=");
684
685 if(get_plus_arg(CHECK,"MAC_SPEED2="))
686 port_speed[2] = get_plus_arg(NUM,"MAC_SPEED2=");
687
688 if(get_plus_arg(CHECK,"MAC_SPEED3="))
689 port_speed[3] = get_plus_arg(NUM,"MAC_SPEED3=");
690
691 if(get_plus_arg(CHECK,"MAC_PKT_LEN=")) {
692 port_pkt_length[0] = get_plus_arg(NUM,"MAC_PKT_LEN=");
693 port_pkt_length[1] = get_plus_arg(NUM,"MAC_PKT_LEN=");
694 port_pkt_length[2] = get_plus_arg(NUM,"MAC_PKT_LEN=");
695 port_pkt_length[3] = get_plus_arg(NUM,"MAC_PKT_LEN=");
696 }
697
698 // Over write if packets lengths are per port basis.
699 if (get_plus_arg (CHECK, "MAC_PORT0_PKT_LEN"))
700 port_pkt_length[0] = get_plus_arg (NUM, "MAC_PORT0_PKT_LEN");
701 if (get_plus_arg (CHECK, "MAC_PORT1_PKT_LEN"))
702 port_pkt_length[1] = get_plus_arg (NUM, "MAC_PORT1_PKT_LEN");
703 if (get_plus_arg (CHECK, "MAC_PORT2_PKT_LEN"))
704 port_pkt_length[2] = get_plus_arg (NUM, "MAC_PORT2_PKT_LEN");
705 if (get_plus_arg (CHECK, "MAC_PORT3_PKT_LEN"))
706 port_pkt_length[3] = get_plus_arg (NUM, "MAC_PORT3_PKT_LEN");
707
708
709 if(get_plus_arg(CHECK,"PKTGEN_PORT0_10G_IPG="))
710 port_ipg[0] = get_plus_arg(NUM,"PKTGEN_PORT0_10G_IPG=");
711
712 if(get_plus_arg(CHECK,"PKTGEN_PORT1_10G_IPG="))
713 port_ipg[1] = get_plus_arg(NUM,"PKTGEN_PORT1_10G_IPG=");
714
715 if(get_plus_arg(CHECK,"PKTGEN_PORT2_1G_IPG="))
716 port_ipg[2] = get_plus_arg(NUM,"PKTGEN_PORT2_1G_IPG=");
717
718 if(get_plus_arg(CHECK,"PKTGEN_PORT3_1G_IPG="))
719 port_ipg[3] = get_plus_arg(NUM,"PKTGEN_PORT3_1G_IPG=");
720
721 // IPG correction
722 for(i=0;i<4;i++) {
723 port_ipg[i] += 9; // since env adds 8+1 byte ipg into actual passed value
724 }
725 // calculate ideal bw
726 // get ideal bw
727 for(i=0;i<4;i++) {
728 if(rtl_mac[i]) {
729 if(port_pkt_length[i]+port_ipg[i] > 0)
730 port_ideal_bw[i] = (port_pkt_length[i] * port_speed[i]) /
731 (port_pkt_length[i]+port_ipg[i]);
732 else
733 port_ideal_bw[i] = 0;
734 total_ideal_bw += port_ideal_bw[i];
735 }
736 }
737
738 // get actual bw
739 for(i=0;i<4;i++) {
740 if(rtl_mac[i]) {
741 if(rdmcMonStats[i].index > 0) {
742 port_actual_bw[i] = rdmcMonStats[i].raw_bw[rdmcMonStats[i].index-1];
743 } else {
744 port_actual_bw[i] = 0;
745 }
746 total_actual_bw += port_actual_bw[i];
747 }
748 }
749
750
751 // report errors
752 if(total_actual_bw <= 0) total_actual_bw = 1; // dive by zero error
753 if(total_ideal_bw <= 0) total_ideal_bw = 1; // dive by zero error
754
755 if(total_ideal_bw < total_actual_bw)
756 percentage_bw_difference = (total_ideal_bw * 100) / total_actual_bw ;
757 else
758 percentage_bw_difference = (total_actual_bw * 100) / total_ideal_bw ;
759
760 percentage_bw_difference = diff_values(100, percentage_bw_difference);
761
762 if(percentage_bw_difference > percentage_bw_to_ignore) {
763 if(report_bandwidth_mismatch_error && (one_time == 0)) {
764 be_msg.print(e_mesg_error,
765 "RDMC_MON",
766 "report_bandwidth",
767 "bandwidth mismatch expected=%0d Mbps actual=%0d Mbps, difference=%0d percent",
768 total_ideal_bw, total_actual_bw, percentage_bw_difference);
769 } else {
770 be_msg.print(e_mesg_info,
771 "RDMC_MON",
772 "report_bandwidth",
773 "bandwidth mismatch expected=%0d Mbps actual=%0d Mbps, difference=%0d percent",
774 total_ideal_bw, total_actual_bw, percentage_bw_difference);
775 }
776 } else {
777 be_msg.print(e_mesg_info,
778 "RDMC_MON",
779 "report_bandwidth",
780 "bandwidth matched expected=%0d Mbps actual=%0d Mbps, difference=%0d percent",
781 total_ideal_bw, total_actual_bw, percentage_bw_difference);
782 }
783
784 printf("<%0d> =============== RDMC_MON REPORT_BW =======================\n", get_time(LO));
785 printf("RDMC_MON REPORT_BW Port#\t\tPort0\tPort1\tPort2\tPort3\n");
786 printf("RDMC_MON REPORT_BW Speed\t\t%0d\t%0d\t%0d\t%0d\n",
787 port_speed[0], port_speed[1], port_speed[2], port_speed[3]);
788 printf("RDMC_MON REPORT_BW PktLen\t\t%0d\t%0d\t%0d\t%0d\n",
789 port_pkt_length[0], port_pkt_length[1], port_pkt_length[2], port_pkt_length[3]);
790 printf("RDMC_MON REPORT_BW SentPktCnt\t\t%0d\t%0d\t%0d\t%0d\n",
791 number_of_pkts_sent[0], number_of_pkts_sent[1],
792 number_of_pkts_sent[2], number_of_pkts_sent[3]);
793 printf("RDMC_MON REPORT_BW RcvdPktCnt\t\t%0d\t%0d\t%0d\t%0d\n",
794 number_of_pkts_rcvd[0], number_of_pkts_rcvd[1],
795 number_of_pkts_rcvd[2], number_of_pkts_rcvd[3]);
796 printf("RDMC_MON REPORT_BW IPG\t\t\t%0d\t%0d\t%0d\t%0d\n",
797 port_ipg[0], port_ipg[1], port_ipg[2], port_ipg[3]);
798 printf("RDMC_MON REPORT_BW Weight\t\t%0d\t%0d\t%0d\t%0d\n",
799 port_DRR_weights[0], port_DRR_weights[1], port_DRR_weights[2], port_DRR_weights[3]);
800 printf("RDMC_MON REPORT_BW IdealBw\t\t%0d\t%0d\t%0d\t%0d\n",
801 port_ideal_bw[0], port_ideal_bw[1], port_ideal_bw[2], port_ideal_bw[3]);
802 printf("RDMC_MON REPORT_BW ActualBw\t\t%0d\t%0d\t%0d\t%0d\n",
803 port_actual_bw[0], port_actual_bw[1], port_actual_bw[2], port_actual_bw[3]);
804 printf("RDMC_MON REPORT_BW TotalIdealBw:\t%0d\n", total_ideal_bw);
805 printf("RDMC_MON REPORT_BW TotalActualBw:\t%0d\n", total_actual_bw);
806 printf("<%0d> =============== RDMC_MON REPORT_BW =======================\n", get_time(LO));
807}
808
809task RdmcMonitor::display_results() {
810}
811
812