Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / rxc_sat / vera / fflp / fflp_model.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: fflp_model.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/*###########################################################################
36# Copyright (c) 2001 by Sun Microsystems Inc.
37# All rights reserved. No part of this design may be reproduced, stored
38# in a retrieval system, or transmitted, in any form or by any means,
39# electronic, mechanical, photocopying, recording, or otherwise,
40# without prior written permission from Sun Microsystems, Inc.
41#
42# Sun Proprietary/Confidential
43# File Name : fflp_model.vr
44# Author : Saranga Pogula
45# Date : 09-22-2005
46# Description : FFLP Model for DMA Prediction for the end-checker based
47# environment for RX NIU/NEPTUNE.
48###########################################################################*/
49
50#include "pkt_configurator_defines.vri"
51#include "fflp_test_defines.vri"
52#include "pcg_defines.vri"
53#include "pcg_types.vri"
54#include "pack_db.vrh"
55#include "flow_db.vrh"
56#include "flow_db_tasks.vrh"
57#include "pg_top_pp.vrh"
58#include "pc_top_pp.vrh"
59#include "ip_util.vrh"
60#include "ip_ingress_db.vrh"
61#include "rxc_class.vrh"
62#include "pcg_token.vrh"
63#include "mbox_class.vrh"
64#define MAX_FFLP_FLOWCHART_NODES 40
65#define MAX_L2_PATHS 6
66#define MAX_L3_PATHS 17
67
68extern Crxc rxc_cl;
69extern mbox_class mbox_id;
70
71class tcam_key_cl {
72
73 bit tcam_disc;
74 bit tcam_sel;
75 bit tcam_ipaddr;
76 bit [4:0] pkt_class;
77
78 task new(integer class_num){
79 tcam_disc = 0;
80 tcam_sel = 0;
81 tcam_ipaddr = 0;
82 pkt_class = class_num;
83 }
84}
85
86class fflp_path {
87integer node [MAX_FFLP_FLOWCHART_NODES];
88 task new(){
89 integer i;
90 for (i=0;i<MAX_FFLP_FLOWCHART_NODES;i++)
91 node[i] = -1;
92 }
93 task print_path(integer port_id, integer pkt_id) {
94 integer i;
95 printf("PKT%0d.%0d FFLP-Path: ", port_id, pkt_id);
96 for (i=0;i<MAX_FFLP_FLOWCHART_NODES;i++)
97 if(node[i] != -1)
98 printf("%0d ",node[i]);
99 printf("\n");
100 }
101}
102
103class path_analysis {
104
105/*
106 integer standard_l2_path0[MAX_FFLP_FLOWCHART_NODES]={0,1};
107 integer standard_l2_path1[MAX_FFLP_FLOWCHART_NODES]={0,2,3};
108 integer standard_l2_path2[MAX_FFLP_FLOWCHART_NODES]={0,2,4,5};
109 integer standard_l2_path3[MAX_FFLP_FLOWCHART_NODES]={0,2,4,6,7};
110 integer standard_l2_path4[MAX_FFLP_FLOWCHART_NODES]={0,2,4,6,8,9};
111 integer standard_l2_path5[MAX_FFLP_FLOWCHART_NODES]={0,2,4,6,8,10};
112
113 integer standard_l3_path0[MAX_FFLP_FLOWCHART_NODES]={11};
114 integer standard_l3_path1[MAX_FFLP_FLOWCHART_NODES]={12,13,18,19,29};
115 integer standard_l3_path2[MAX_FFLP_FLOWCHART_NODES]={12,13,18,19,30,31};
116 integer standard_l3_path3[MAX_FFLP_FLOWCHART_NODES]={12,13,18,20,21};
117 integer standard_l3_path4[MAX_FFLP_FLOWCHART_NODES]={12,13,18,20,22,23};
118 integer standard_l3_path5[MAX_FFLP_FLOWCHART_NODES]={12,13,18,20,22,24,26};
119 integer standard_l3_path6[MAX_FFLP_FLOWCHART_NODES]={12,13,18,20,22,24,25,27};
120 integer standard_l3_path7[MAX_FFLP_FLOWCHART_NODES]={12,14,15};
121 integer standard_l3_path8[MAX_FFLP_FLOWCHART_NODES]={12,14,16,17,29};
122 integer standard_l3_path9[MAX_FFLP_FLOWCHART_NODES]={12,14,16,17,30,31};
123 integer standard_l3_path10[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,29};
124 integer standard_l3_path11[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,30,31};
125 integer standard_l3_path12[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,20,21};
126 integer standard_l3_path13[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,20,22,23};
127 integer standard_l3_path14[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,20,22,24,26};
128 integer standard_l3_path15[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,20,22,24,25,27};
129 integer standard_l3_path16[MAX_FFLP_FLOWCHART_NODES]={12,14,16,18,19,20,22,24,25,28,31};
130*/
131
132 integer histogram_L2_paths [MAX_L2_PATHS];
133 integer histogram_L3_paths [MAX_L3_PATHS];
134
135 task new(){
136 integer i;
137
138 for (i=0;i<MAX_L2_PATHS;i++)
139 histogram_L2_paths[i] = 0;
140 for (i=0;i<MAX_L3_PATHS;i++)
141 histogram_L3_paths[i] = 0;
142 }
143 task update_l2_histogram(fflp_path l2_path){
144 integer result;
145
146 result = match_l2_path(l2_path);
147 if (result != -1)
148 histogram_L2_paths[result]++;
149
150 printf("matched_l2_path=%0d\n", result);
151 }
152 task update_l3_histogram(fflp_path l3_path){
153 integer result;
154
155 result = match_l3_path(l3_path);
156 if (result != -1)
157 histogram_L3_paths[result]++;
158
159 printf("matched_l3_path=%0d\n", result);
160 }
161 function integer match_l2_path(fflp_path l2path){
162 string str0 = ""; integer i;
163 string str_tmp;
164
165 for(i=0;i<MAX_FFLP_FLOWCHART_NODES;i++)
166 if (l2path.node[i]!=-1)
167 sprintf (str0, "%s%0d,", str0,l2path.node[i]);
168
169 //printf("L2 path_string = %s\n", str0);
170
171
172 if (compare_path(str0, standard_l2_path0))
173 match_l2_path = 0;
174 else if (compare_path(str0, standard_l2_path1))
175 match_l2_path = 1;
176 else if (compare_path(str0, standard_l2_path2))
177 match_l2_path = 2;
178 else if (compare_path(str0, standard_l2_path3))
179 match_l2_path = 3;
180 else if (compare_path(str0, standard_l2_path4))
181 match_l2_path = 4;
182 else if (compare_path(str0, standard_l2_path5))
183 match_l2_path = 5;
184 else
185 match_l2_path=-1;
186
187 //printf("match_l2_path=%0d\n", match_l2_path);
188 }
189 function integer match_l3_path(fflp_path l3path){
190 string str0 = ""; integer i;
191 string str_tmp;
192
193 for(i=0;i<MAX_FFLP_FLOWCHART_NODES;i++)
194 if (l3path.node[i]!=-1)
195 sprintf (str0, "%s%0d,", str0,l3path.node[i]);
196
197 //printf("L3 path_string = %s\n", str0);
198
199 if (compare_path(str0, standard_l3_path0))
200 match_l3_path = 0;
201 else if (compare_path(str0, standard_l3_path1))
202 match_l3_path = 1;
203 else if (compare_path(str0, standard_l3_path2))
204 match_l3_path = 2;
205 else if (compare_path(str0, standard_l3_path3))
206 match_l3_path = 3;
207 else if (compare_path(str0, standard_l3_path4))
208 match_l3_path = 4;
209 else if (compare_path(str0, standard_l3_path5))
210 match_l3_path = 5;
211 else if (compare_path(str0, standard_l3_path6))
212 match_l3_path = 6;
213 else if (compare_path(str0, standard_l3_path7))
214 match_l3_path = 7;
215 else if (compare_path(str0, standard_l3_path8))
216 match_l3_path = 8;
217 else if (compare_path(str0, standard_l3_path9))
218 match_l3_path = 9;
219 else if (compare_path(str0, standard_l3_path10))
220 match_l3_path = 10;
221 else if (compare_path(str0, standard_l3_path11))
222 match_l3_path = 11;
223 else if (compare_path(str0, standard_l3_path12))
224 match_l3_path = 12;
225 else if (compare_path(str0, standard_l3_path13))
226 match_l3_path = 13;
227 else if (compare_path(str0, standard_l3_path14))
228 match_l3_path = 14;
229 else if (compare_path(str0, standard_l3_path15))
230 match_l3_path = 15;
231 else if (compare_path(str0, standard_l3_path16))
232 match_l3_path = 16;
233 else
234 match_l3_path=-1;
235
236 printf("match_l3_path=%0d\n", match_l3_path);
237 }
238 function integer compare_path(string path, string standard_path){
239 // please note 0 is returned by str.compare() if the strings are identical
240 if (path.compare(standard_path))
241 compare_path = 0; // not equal
242 else
243 compare_path = 1; // equal
244 }
245 task print_histogram_summary(){
246 integer loop;
247 printf("######### L2 paths coverage Summary #########\n");
248 printf( "-L2Path: 0 1 2 3 4 5\n-L2Hits: ");
249 for (loop=0;loop<MAX_L2_PATHS;loop++)
250 printf("%4d ", histogram_L2_paths[loop]);
251 printf("\n######### L2 paths coverage Summary #########\n");
252
253 printf("######### L3 paths coverage Summary #########\n");
254 printf( "-L3Path: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n-L3Hits: ");
255 for (loop=0;loop<MAX_L3_PATHS;loop++)
256 printf("%4d ", histogram_L3_paths[loop]);
257 printf("\n######### L3 paths coverage Summary #########\n");
258 }
259
260} // class
261
262class flow_key_cl {
263
264 bit PORT;
265 bit L2DA;
266 bit VLAN;
267 bit IPSA;
268 bit IPDA;
269 bit PROTO;
270 bit [1:0] L4_0;
271 bit [1:0] L4_1;
272 bit [4:0] pkt_class;
273
274 task new(integer class_num){
275 PORT = 0;
276 L2DA = 0;
277 VLAN = 0;
278 IPSA = 0;
279 IPDA = 0;
280 PROTO = 0;
281 L4_0 = 0;
282 L4_1 = 0;
283 pkt_class = class_num;
284 }
285}
286
287class cntl_fifo
288 {
289 integer pkt_len;
290 integer pkt_num;
291 bit [4:0] final_dma_chnl;
292 bit [2:0] final_zcp_rdc_tbl_num;
293 bit [4:0] final_zcp_rdc_tbl_offset;
294 bit tcam_key_drop;
295
296 //@@@@@@@ Control FIFO Fields @@@@@@@@@@@
297 //@@ B0 @@@
298 bit [1:0] port_num;
299 bit maccheck;
300 bit [4:0] packet_class;
301 //@@ B1 @@@
302 bit tzfvld;
303 bit [1:0] tres;
304 bit tcamhit;
305 bit badip;
306 bit noport;
307 bit llcsnap;
308 bit vlan;
309 //@@ B2 @@@
310 bit [4:0] dma_num;
311 bit [4:0] default_dma_num; // {B2[2:0],B4[7:6]}
312 //@@ B3 @@@
313 bit [7:0] tcamm_index;
314 //@@ B4 @@@
315 bit [2:0] hash_index;
316 bit hzfvld;
317 bit hash_exact_match;
318 bit hash_hit;
319 //@@ B5 @@@
320 bit tt_err;
321 bit tt_succeed;
322 //@@ B6 @@@
323 bit [11:0] zc_flow_id; // {B6[3:0],B7[7:0]}
324 bit solicited_event_bit;
325 bit drop_pkt;
326 bit fflp_hw_err;
327 bit mac_promiscuous;
328 //@@ B7 @@@
329//##### if tt_succeed = 0 #####
330 //@@ B8 & B9 @@@
331 bit [15:0] hash_value2;
332 //@@ B10 & B11 & B12 @@@
333 bit [19:0] hash_value1;
334 //@@ B13, B14, B15, B16, B17 @@@
335 bit [39:0] user_data;
336//##### if tt_succeed = 1 #####
337 //@@ B8, B9 @@
338 bit [15:0] tt_hdr_len;
339 //@@ B10, B11 @@@
340 bit [15:0] tcp_payload_len;
341 //@@ B12, B13 @@@
342 bit [15:0] HoQ;
343 //@@ B14, B15,B16 @@@
344 bit [23:0] first_byte_offset;
345 //@@ B17 @@@
346 bit [4:0] win_buf_offset;
347 bit [1:0] dmaw_type_1;
348 bit reach_buf_end;
349//#####
350 //@@ B18 @@@
351 bit [1:0] L4_protocol;
352 bit [3:0] pkt_id;
353 bit ip_version;
354 //@@ B19 @@@
355 bit [4:0] zc_rdc;
356 bit [1:0] dmaw_type;
357 //@@ B20, B21 @@
358 bit [15:0] L3_pkt_len;
359 //@@ B22 @@
360 bit [3:0] tcp_hdr_len;
361 bit [3:0] ipv4_hdr_len;
362 //@@ B23-B26 @@
363 bit [31:0] tcp_seq_num;
364
365 task new()
366 {
367 pkt_len = 0;
368 pkt_num = 0;
369 final_dma_chnl = 5'h0;
370 final_zcp_rdc_tbl_num = 3'h0;
371 final_zcp_rdc_tbl_offset = 5'h0;
372 tcam_key_drop = 0;
373 //@@@@@@@ Control FIFO Fields @@@@@@@@@@@
374 //@@ B0 @@@
375 maccheck = 0;
376 port_num = 0;
377 packet_class = 0;
378 //@@ B1 @@@
379 tzfvld = 0;
380 tres = 0;
381 tcamhit = 0;
382 badip = 0;
383 noport = 0;
384 llcsnap = 0;
385 vlan = 0;
386 //@@ B2 @@@
387 dma_num = 0;
388 default_dma_num = 0; // {B2[2:0],B4[7:6]}
389 //@@ B3 @@@
390 tcamm_index = 0;
391 //@@ B4 @@@
392 hash_index = 0;
393 hzfvld = 0;
394 hash_exact_match = 0;
395 hash_hit = 0;
396 //@@ B5 @@@
397 tt_err = 0;
398 tt_succeed = 0;
399 //@@ B6 @@@
400 zc_flow_id = 0; // {B6[3:0],B7[7:0]}
401 solicited_event_bit = 0;
402 drop_pkt = 0;
403 fflp_hw_err = 0;
404 mac_promiscuous = 0;
405 //@@ B7 @@@
406//##### if tt_succeed = 0 #####
407 //@@ B8 & B9 @@@
408 hash_value2 = 0;
409 //@@ B10 & B11 & B12 @@@
410 hash_value1 = 0;
411 //@@ B13, B14, B15, B16, B17 @@@
412 user_data = 0;
413//##### if tt_succeed = 1 #####
414 //@@ B8, B9 @@
415 tt_hdr_len = 0;
416 //@@ B10, B11 @@@
417 tcp_payload_len = 0;
418 //@@ B12, B13 @@@
419 HoQ = 0;
420 //@@ B14, B15,B16 @@@
421 first_byte_offset = 0;
422 //@@ B17 @@@
423 win_buf_offset = 0;
424 dmaw_type_1 = 0;
425 reach_buf_end = 0;
426//#####
427 //@@ B18 @@@
428 L4_protocol = 0;
429 pkt_id = 0;
430 ip_version = 0;
431 //@@ B19 @@@
432 zc_rdc = 0;
433 dmaw_type = 0;
434 //@@ B20, B21 @@
435 L3_pkt_len = 0;
436 //@@ B22 @@
437 tcp_hdr_len = 0;
438 ipv4_hdr_len = 0;
439 //@@ B23-B26 @@
440 tcp_seq_num = 0;
441 }
442}
443
444
445
446
447
448class fflp_model {
449
450 bit [51:0] mac_da_table0 [MAX_DA_10G]; // MACDA Shadow
451 bit [51:0] mac_da_table1 [MAX_DA_10G]; // MACDA Shadow
452 bit [51:0] mac_da_table2 [MAX_DA_1G]; // MACDA Shadow
453 bit [51:0] mac_da_table3 [MAX_DA_1G]; // MACDA Shadow
454
455 bit [17:0] vlan_table [MAX_VLAN_ENTRIES]; // VLAN Table Shadow
456
457 bit [199:0] tcam_entries [MAX_CAM_ENTRIES]; // TCAM Keys Shadow
458 bit [199:0] tcam_mask [MAX_CAM_ENTRIES]; // TCAM mask Shadow
459 bit [2:0] tcam_key_cntl [MAX_L3_CLASSES]; // DISC,TSEL,IPADDR bits
460 bit [63:0] tcam_assoc_data [MAX_CAM_ENTRIES]; // TCAM Associated data
461
462
463 bit [3:0] zcp_rdc_table [MAX_ZCP_RDC_ENTRIES]; // Shadow of ZCP RDC Table
464
465 tcam_key_cl tcam_key_reg [MAX_L3_CLASSES]; // shadow of tcam_key reg for all 12 classes 4-15
466 flow_key_cl flow_cntl_reg [MAX_L3_CLASSES]; // Fields to be part of Flow Key
467 Cpkt_info control_fifo_chkr; // Object to be sent to control fifo checker
468 cntl_fifo ctl_fifo; // Global object, will be filled in with cntl_hdr info
469 fflp_path path_class,master_path_class; // for coverage measurement of FFLP paths in the flowchart
470 path_analysis path_analysis;
471 integer index,master_index;
472 bit [63:0] initial_h1_poly; // Initial value for the H1 Polynomial
473 bit [3:0] port_pkt_id[4];
474 bit [3:0] pkt_id[4];
475
476 task new() {
477 integer i;
478 for(i=0;i<MAX_L3_CLASSES;i++){
479 tcam_key_reg[i] = new(i+4);
480 }
481 for(i=0;i<MAX_L3_CLASSES;i++){
482 flow_cntl_reg[i] = new(i+4);
483 }
484 initial_h1_poly = 64'h0;
485 for(i=0;i<4;i++){
486 port_pkt_id[i] = 0;
487 pkt_id[i] = 0;
488 }
489 for(i=0;i<MAX_CAM_ENTRIES;i++){
490 tcam_mask[i] = {200{1'b1}};
491 }
492 path_analysis = new;
493 }
494 function bit [3:0] predict_mac_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow);
495 function bit [3:0] predict_vlan_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow);
496 function bit [2:0] predict_l2_rdc_tblnum(bit [1:0] mac_id, flow_desc flow);
497
498 // return value of predict_tcam_rdc_tblnum_offset():
499 // [10]->DISC, [9:8]->TRES, [7]->TCAM-Hit, [6:3]->RDC-Offset, [2:0]->RDC-Table
500 function bit [10:0] predict_tcam_rdc_tblnum_offset(flow_desc flow, bit [2:0] l2_rdc, bit [1:0] mac_id);
501 function bit [3:0] predict_flow_rdc_offset(flow_desc flow);
502 function cntl_fifo predict_control_fifo(bit [1:0] mac_id, flow_desc flow);
503 function bit [3:0] lookup_zcp_rdc_table(bit [2:0] rdc_tbl_num, bit [3:0] rdc_tbl_offset);
504 function bit class_matched(integer class_num);
505 function bit [4:0] find_class(integer class_num);
506 function bit [4:0] eval_hash_offset(flow_desc flow, bit [1:0] mac_id);
507 function bit [31:0] calculate_H1_hash (bit [383:0] flow_key);
508 function bit isThisPktIPFrag (integer frame_class);
509
510
511 task update_zcp_rdc_tbl_shadow(integer index, bit [3:0] dma_num);
512 task update_mac_da_shadow(bit [1:0] port_num, integer index, bit [51:0] mac_entry);
513 task update_vlan_shadow(integer index, bit [17:0] vlan_entry);
514 task update_tcam_key_shadow(integer index, bit [199:0] tcam_entry);
515 task update_tcam_mask_shadow(integer index, bit[199:0] mask);
516 task update_tcam_assoc_data_shadow(integer index, bit [63:0] assoc_data);
517 task update_tcam_reg_shadow(integer class_num, bit [2:0] cntl_info);
518 task update_flow_key_cntl_shadow(integer class_num, bit [9:0] cntl_info);
519 task update_initial_h1_poly(bit [31:0] init_h1_poly);
520
521 function bit [199:0] get_tcam_entry(integer index);
522 function bit[199:0] get_tcam_mask(integer index);
523}
524
525task fflp_model::update_initial_h1_poly(bit [31:0] init_h1_poly) {
526 initial_h1_poly = {32'h0,init_h1_poly};
527 printf("fflp_model::update_initial_h1_poly init_h1_poly=0x%h\n", initial_h1_poly);
528}
529
530function bit[199:0] fflp_model::get_tcam_mask(integer index) {
531 get_tcam_mask = tcam_mask[index];
532 printf("fflp_model::get_tcam_mask index=%0d tcam_mask=0x%h\n", index, tcam_mask[index]);
533}
534
535function bit [199:0] fflp_model::get_tcam_entry(integer index) {
536 get_tcam_entry = tcam_entries[index];
537 printf("fflp_model::get_tcam_entry index=%0d, tcam_entry=0x%h\n", index,tcam_entries[index]);
538}
539
540task fflp_model::update_tcam_assoc_data_shadow(integer index, bit [63:0] assoc_data) {
541 tcam_assoc_data[index] = assoc_data;
542 printf("fflp_model::update_tcam_assoc_data_shadow index=%0d, tcam_entry=0x%h\n", index,tcam_assoc_data[index]);
543}
544
545task fflp_model::update_tcam_mask_shadow(integer index, bit[199:0] mask) {
546 tcam_mask[index] = mask;
547 printf("fflp_model::update_tcam_mask_shadow index=%0d mask=0x%h\n", index, tcam_mask[index]);
548}
549
550task fflp_model::update_tcam_key_shadow(integer index, bit [199:0] tcam_entry) {
551 tcam_entries[index] = tcam_entry;
552 printf("fflp_model::update_tcam_key_shadow index=%0d, tcam_entry=0x%h\n", index,tcam_entries[index]);
553}
554
555task fflp_model::update_tcam_reg_shadow(integer class_num, bit [2:0] cntl_info) {
556 tcam_key_reg[class_num-4].tcam_disc = cntl_info[2];
557 tcam_key_reg[class_num-4].tcam_sel = cntl_info[1];
558 tcam_key_reg[class_num-4].tcam_ipaddr = cntl_info[0];
559 printf("fflp_model:: update_tcam_reg_shadow class=%0d, reg_data[2:0]=0x%h\n", class_num, cntl_info);
560}
561
562task fflp_model::update_flow_key_cntl_shadow(integer class_num, bit [9:0] cntl_info) {
563 flow_cntl_reg[class_num-4].PORT = cntl_info[9];
564 flow_cntl_reg[class_num-4].L2DA = cntl_info[8];
565 flow_cntl_reg[class_num-4].VLAN = cntl_info[7];
566 flow_cntl_reg[class_num-4].IPSA = cntl_info[6];
567 flow_cntl_reg[class_num-4].IPDA = cntl_info[5];
568 flow_cntl_reg[class_num-4].PROTO = cntl_info[4];
569 flow_cntl_reg[class_num-4].L4_0 = cntl_info[3:2];
570 flow_cntl_reg[class_num-4].L4_1 = cntl_info[1:0];
571 printf("fflp_model:: update_flow_key_cntl_shadow class=%0d, reg_data[2:0]=0x%h\n", class_num,cntl_info);
572}
573
574function bit fflp_model::class_matched(integer class_num) {
575 if ( (class_num == CL_TCP) || (class_num==CL_TCP_FRAG) || (class_num==CL_TCP_OPT) ||
576 (class_num == CL_UDP) || (class_num==CL_UDP_FRAG) || (class_num==CL_UDP_OPT) ||
577 (class_num == CL_IP_SEC_AH) || (class_num == CL_IP_SEC_ESP) ||
578 (class_num == CL_SCTP) || (class_num==CL_SCTP_FRAG) || (class_num==CL_SCTP_OPT) ||
579 (class_num == CL_TCP_IP_V6) || (class_num == CL_TCP_FRAG_IP_V6) || (class_num == CL_TCP_OPT_IP_V6) ||
580 (class_num == CL_UDP_IP_V6) || (class_num == CL_UDP_FRAG_IP_V6) || (class_num == CL_UDP_OPT_IP_V6) ||
581 (class_num == CL_IP_V6_SEC_AH) || (class_num == CL_IP_V6_SEC_ESP) ||
582 (class_num == CL_SCTP_IP_V6) ||
583 (class_num == CL_ARP) ||
584 (class_num == CL_RARP)
585 )
586 class_matched = 1;
587 else
588 class_matched = 0;
589}
590
591function bit fflp_model::isThisPktIPFrag(integer frame_class) {
592 isThisPktIPFrag = 0;
593 if((frame_class==CL_TCP_FRAG) || (frame_class==CL_UDP_FRAG) ||
594 (frame_class==CL_SCTP_FRAG) || (frame_class==CL_IP_FRAG) )
595 isThisPktIPFrag = 1;
596}
597
598function bit [4:0] fflp_model::find_class(integer class_num) {
599 case(class_num) {
600 CL_TCP, CL_TCP_FRAG: find_class = 8;
601 CL_UDP, CL_UDP_FRAG: find_class = 9;
602 CL_IP_SEC_AH,CL_IP_SEC_ESP: find_class = 10;
603 CL_SCTP, CL_SCTP_FRAG: find_class = 11;
604 CL_TCP_IP_V6: find_class = 12;
605 CL_UDP_IP_V6: find_class = 13;
606 CL_IP_V6_SEC_AH,CL_IP_V6_SEC_ESP: find_class = 14;
607 CL_SCTP_IP_V6: find_class = 15;
608 CL_ARP: find_class = 16;
609 CL_RARP: find_class =17;
610 default : { find_class = 0; }
611 }
612}
613
614function bit [2:0] fflp_model::predict_l2_rdc_tblnum(bit [1:0] mac_id, flow_desc flow) {
615bit [3:0] mac_ctl_word, vlan_ctl_word;
616bit [2:0] mac_rdc_tblnum;
617bit [2:0] vlan_rdc_tblnum;
618bit mpr, vpr;
619
620 mac_ctl_word = predict_mac_rdc_tblnum_pri(mac_id, flow);
621 mpr = mac_ctl_word[3];
622 mac_rdc_tblnum = mac_ctl_word[2:0];
623
624 if(flow.frame.frame_type[2]==1) { // VLAN Tagged
625 // VLAN tagged
626/*========== FFLP_Path =========*/ path_class.node[index++] = 4;
627/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.vlan = 1;
628/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.vlan = 1;
629 vlan_ctl_word = predict_vlan_rdc_tblnum_pri(mac_id, flow);
630 vpr = vlan_ctl_word[3];
631 vlan_rdc_tblnum = vlan_ctl_word[2:0];
632 case ({vpr,mpr}){
633 2'b00: {
634 predict_l2_rdc_tblnum = mac_rdc_tblnum;
635/*========== FFLP_Path =========*/ path_class.node[index++] = 8;
636/*========== FFLP_Path =========*/ path_class.node[index++] = 10;
637 }
638 2'b01: {
639 predict_l2_rdc_tblnum = mac_rdc_tblnum;
640/*========== FFLP_Path =========*/ path_class.node[index++] = 8;
641/*========== FFLP_Path =========*/ path_class.node[index++] = 9;
642 }
643 2'b10: {
644 predict_l2_rdc_tblnum = vlan_rdc_tblnum;
645/*========== FFLP_Path =========*/ path_class.node[index++] = 7;
646 }
647 2'b11: {
648 predict_l2_rdc_tblnum = vlan_rdc_tblnum;
649/*========== FFLP_Path =========*/ path_class.node[index++] = 7;
650 }
651 default: {}
652 }
653 }
654 else {
655 predict_l2_rdc_tblnum = mac_rdc_tblnum;
656 // Untagged
657/*========== FFLP_Path =========*/ path_class.node[index++] = 3;
658 }
659
660 printf ("fflp_model::predict_l2_rdc_tblnum MAC=%0d mpr=%b vpr=%b mac_rdc=%0d vlan_rdc=%0d, final_l2_rdc=%0d\n",
661 mac_id, mpr, vpr, mac_rdc_tblnum, vlan_rdc_tblnum, predict_l2_rdc_tblnum);
662}
663
664function cntl_fifo fflp_model::predict_control_fifo(bit [1:0] mac_id, flow_desc flow){
665bit [2:0] l2_rdc, tcam_rdc;
666bit [10:0] tcam_result;
667bit [3:0] tcam_offset, flow_offset;
668bit [4:0] class_num;
669bit [47:0] mac_sa;
670bit [15:0] seq_id;
671bit tcam_match, ext_hash, asdata_disc;
672bit [1:0] TRES;
673bit [4:0] hash_offset;
674
675ctl_fifo = new;
676control_fifo_chkr = new;
677path_class = new; index = 0;
678master_path_class = new; master_index = 0;
679
680/*========== FFLP_Path =========*/ path_class.node[index++] = 0;
681mac_sa = flow.src_node.l2_addr;
682seq_id = mac_sa[15:0];
683
684
685#define CLASS_4TO15 ((class_num>=4)&&(class_num<=15))
686
687 l2_rdc = predict_l2_rdc_tblnum(mac_id, flow);
688
689/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.pkt_id = port_pkt_id[mac_id];
690/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.pkt_id = port_pkt_id[mac_id];
691 port_pkt_id[mac_id] = (port_pkt_id[mac_id]+1)%16;
692 pkt_id[mac_id]++;
693
694
695/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.port_num = mac_id;
696/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.mac_prt = mac_id;
697 if(flow.frame.frame_type[0]==1) { // LLC/SNAP packet
698/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.llcsnap = 1;
699/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.llcsnap = 1;
700 }
701
702printf("fflp_model: Algorithm: MAC%0d.%0d err code from pkt=%0d\n", mac_id, seq_id, flow.frame.error_code);
703 if( (!class_matched(flow.frame.frame_class)) ||
704 ((flow.frame.error_code&PG_L4_PROTO_USER_MODE) == PG_L4_PROTO_USER_MODE)) { // no class matched
705 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
706 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
707 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
708/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 11;
709 //printf("fflp_model: Algorithm: MAC%0d.%0d No class matched (or cksum err=%0d). l2_rdc = %0d, dma_num = %0d\n",
710 printf("fflp_model: Algorithm: MAC%0d.%0d No class matched. l2_rdc = %0d, dma_num = %0d\n",
711 mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_dma_chnl);
712 }
713 else { // class matched
714 class_num = find_class(flow.frame.frame_class);
715/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.packet_class = class_num;
716/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.packet_class = class_num;
717/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 12;
718
719 if(CLASS_4TO15) {
720/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 14;
721 if (isThisPktIPFrag(flow.frame.frame_class)) { // check for FRAG packets
722/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.noport = 1;
723/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.noport = 1;
724 }
725 printf("fflp_model: Algorithm: MAC%0d.%0d class is 4-15. class_num = %0d\n", mac_id, seq_id, class_num);
726 if (tcam_key_reg[class_num-4].tcam_disc) { // DISC bit set for this class
727/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 15;
728 ctl_fifo.tcam_key_drop = 1;
729 printf("fflp_model: Algorithm: MAC%0d.%0d DISC bit set for class_num = %0d\n", mac_id, seq_id, class_num);
730 }
731 else { // DISC bit not set for this class
732/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 16;
733 if(tcam_key_reg[class_num-4].tcam_sel) { // tcam lookup required for this class
734/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 18;
735 printf ("fflp_model: Algorithm: MAC%0d.%0d tcam lookup required class_num = %0d\n", mac_id, seq_id, class_num);
736 tcam_result = predict_tcam_rdc_tblnum_offset(flow, l2_rdc, mac_id);
737 tcam_rdc = tcam_result[2:0];
738 tcam_offset = tcam_result[6:3];
739 tcam_match = tcam_result[7];
740 TRES = tcam_result[9:8];
741 asdata_disc = tcam_result[10];
742
743
744
745 if (tcam_match) {
746/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 20;
747
748 if (asdata_disc)
749/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 21;
750 else
751/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 22;
752
753/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.tcamhit = 1;
754/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.tcamhit = 1;
755/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.tres = TRES;
756/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.tres = TRES;
757 printf ("fflp_model: Algorithm: class %0d MAC%0d.%0d TCAM_hit=1, TRES=%b\n", class_num, mac_id, seq_id, TRES);
758 if (TRES[1] == 1'b0) { // take L2 RDC number despite having a TCAM-Hit
759/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 23;
760 if (TRES[0] == 1'b0) { // continue to flow lookup for OFFSET
761/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 25;
762 if ((class_num>=8)&&(class_num<=15)) { // L3 class match, L2_RDC taken, and Hash1/Ext_hash evaluation has to be done
763 if((flow_cntl_reg[class_num-4].PORT !== 0) ||
764 (flow_cntl_reg[class_num-4].L2DA !== 0) ||
765 (flow_cntl_reg[class_num-4].VLAN !== 0) ||
766 (flow_cntl_reg[class_num-4].IPSA !== 0) ||
767 (flow_cntl_reg[class_num-4].IPDA !== 0) ||
768 (flow_cntl_reg[class_num-4].PROTO !== 0) ||
769 (flow_cntl_reg[class_num-4].L4_0 !== 0) ||
770 (flow_cntl_reg[class_num-4].L4_1 !== 0) ) {
771 hash_offset = eval_hash_offset(flow, mac_id);
772 ctl_fifo.final_zcp_rdc_tbl_offset = hash_offset[3:0];
773 }
774 else {
775 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
776 }
777 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
778 ext_hash = hash_offset[4];
779 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
780 printf("fflp_model: Algorithm: class %0d MAC%0d.%0d L3 class, hash done. Ext_Hash = %b, L2_RDC = %0d, Hash Offset evaluated %0d\n",
781 class_num, mac_id, seq_id, ext_hash, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
782 }
783 else { // No L3 class match, no hash required. Ending up with L2_RDC, Offset=0 despite tcam_hit=1
784 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
785 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
786 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
787 printf ("fflp_model: Algorithm: MAC%0d.%0d class %0d No L3 class match, no hash, RDC=L2_RDC %0d, Offset=0 despite tcam_hit=1\n",
788 mac_id, seq_id, class_num, ctl_fifo.final_zcp_rdc_tbl_num);
789 }
790 }
791 else { // TRES[0]==1 terminate the flow lookup and use L2_RDC/Offset=0
792/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 26;
793
794 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES=01, use L2_RDC despite a TCAM hit, tcam_offset, NO flow , class %0d\n",
795 mac_id, seq_id, class_num);
796 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
797 ctl_fifo.final_zcp_rdc_tbl_offset = tcam_offset;
798 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
799 }
800 }
801 else { // TRES[1]==1
802/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 24;
803 if (TRES[0] == 1'b0) { // Take Assoc_data RDC_TBL number and continue to flow lookup for OFFSET. TRES[0]==0
804/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 25;
805 if ((class_num>=8)&&(class_num<=15)) { // L3 class match, L2_RDC taken, and Hash1/Ext_hash evaluation has to be done
806 if((flow_cntl_reg[class_num-4].PORT !== 0) ||
807 (flow_cntl_reg[class_num-4].L2DA !== 0) ||
808 (flow_cntl_reg[class_num-4].VLAN !== 0) ||
809 (flow_cntl_reg[class_num-4].IPSA !== 0) ||
810 (flow_cntl_reg[class_num-4].IPDA !== 0) ||
811 (flow_cntl_reg[class_num-4].PROTO !== 0) ||
812 (flow_cntl_reg[class_num-4].L4_0 !== 0) ||
813 (flow_cntl_reg[class_num-4].L4_1 !== 0) ) {
814 hash_offset = eval_hash_offset(flow, mac_id);
815 ctl_fifo.final_zcp_rdc_tbl_offset = hash_offset[3:0];
816/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 28;
817 }
818 else {
819 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
820/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 27;
821 }
822 ctl_fifo.final_zcp_rdc_tbl_num = tcam_rdc;
823 ext_hash = hash_offset[4];
824 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
825 printf("fflp_model: Algorithm: class %0d MAC%0d.%0d L3 class, hash done. Ext_Hash = %b, L2_RDC = %0d, Hash Offset evaluated %0d\n",
826 class_num, mac_id, seq_id, ext_hash, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
827 }
828 else { // No L3 class match, no hash required. Ending up with L2_RDC, Offset=0 despite tcam_hit=1
829 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
830 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
831 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
832 printf ("fflp_model: Algorithm: MAC%0d.%0d class %0d No L3 class match, no hash, RDC=L2_RDC %0d, Offset=0 despite tcam_hit=1\n",
833 mac_id, seq_id, class_num, ctl_fifo.final_zcp_rdc_tbl_num);
834 }
835
836 }
837 else { // terminate the flow lookup and use Assoc_data RDC_TBL and OFFSET number
838/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 26;
839 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES[1:0]=11, use Assoc_data RDC_TBL and OFFSET, NO flow lookup, class %0d\n",
840 mac_id, seq_id, class_num);
841 ctl_fifo.final_zcp_rdc_tbl_num = tcam_rdc;
842 ctl_fifo.final_zcp_rdc_tbl_offset = tcam_offset;
843 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
844 printf ("fflp_model: Algorithm: class %0d MAC%0d.%0d TCAM hit Found. Resulting in TCAM_rdc %0d, offset %0d dma_num %0d\n",
845 class_num, mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset, ctl_fifo.final_dma_chnl);
846 }
847 }
848 }
849 else { // NO TCAM MATCH
850/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 19;
851 if ((class_num>=8)&&(class_num<=15)) { // L3 class match, L2_RDC finalized, and Hash1/Ext_hash evaluation has to be done
852/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 30;
853/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 31;
854 if ( (flow_cntl_reg[class_num-4].PORT !== 0) ||
855 (flow_cntl_reg[class_num-4].L2DA !== 0) ||
856 (flow_cntl_reg[class_num-4].VLAN !== 0) ||
857 (flow_cntl_reg[class_num-4].IPSA !== 0) ||
858 (flow_cntl_reg[class_num-4].IPDA !== 0) ||
859 (flow_cntl_reg[class_num-4].PROTO !== 0) ||
860 (flow_cntl_reg[class_num-4].L4_0 !== 0) ||
861 (flow_cntl_reg[class_num-4].L4_1 !== 0) ) {
862 hash_offset = eval_hash_offset(flow, mac_id);
863 ctl_fifo.final_zcp_rdc_tbl_offset = hash_offset[3:0];
864/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 28;
865 }
866 else {
867 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
868/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 27;
869 }
870 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
871 ext_hash = hash_offset[4];
872 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
873 printf("fflp_model: Algorithm: class %0d MAC%0d.%0d No tcam_hit, L3 class, hash done. Ext_Hash %b, L2_RDC %0d, Hash Offset %0d\n",
874 class_num, mac_id, seq_id, ext_hash, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
875 }
876 else { // No L3 class match, No TCAM key required, so no hash required. Ending up with L2_RDC, Offset=0
877/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 29;
878 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
879 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
880 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
881 printf ("fflp_model: Algorithm: class %0d MAC%0d.%0d No tcam_hit, not an L3 class. Resulting in l2_rdc = %0d, dma_num = %0d\n",
882 class_num, mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_dma_chnl);
883 }
884 }
885 }
886 else { // No tcam lookup required for this class
887/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 17;
888 printf ("fflp_model: Algorithm: MAC%0d.%0d NO tcam lookup required for class_num = %0d\n", mac_id, seq_id, class_num);
889 if ((class_num>=8)&&(class_num<=15)) { // L3 class match, L2_RDC finalized, and Hash1/Ext_hash evaluation has to be done
890/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 30;
891/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 31;
892 if ( (flow_cntl_reg[class_num-4].PORT !== 0) ||
893 (flow_cntl_reg[class_num-4].L2DA !== 0) ||
894 (flow_cntl_reg[class_num-4].VLAN !== 0) ||
895 (flow_cntl_reg[class_num-4].IPSA !== 0) ||
896 (flow_cntl_reg[class_num-4].IPDA !== 0) ||
897 (flow_cntl_reg[class_num-4].PROTO !== 0) ||
898 (flow_cntl_reg[class_num-4].L4_0 !== 0) ||
899 (flow_cntl_reg[class_num-4].L4_1 !== 0) ) {
900 hash_offset = eval_hash_offset(flow, mac_id);
901 ctl_fifo.final_zcp_rdc_tbl_offset = hash_offset[3:0];
902 }
903 else {
904 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
905 }
906 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
907 ext_hash = hash_offset[4];
908 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
909 printf("fflp_model: Algorithm: class %0d MAC%0d.%0d L3 class, hash done. Ext_Hash = %b, L2_RDC = %0d, Hash Offset evaluated %0d\n",
910 class_num, mac_id, seq_id, ext_hash, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
911 }
912 else { // No L3 class match, No TCAM key required, so no hash required. Ending up with L2_RDC, Offset=0
913/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 29;
914 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
915 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
916 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
917 printf("fflp_model: Algorithm: class %0d MAC%0d.%0d not an L3 class. L2_RDC = %0d, Offset = 0\n",
918 class_num, mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num);
919
920 }
921 }
922 }
923 }
924 else { // classes other than (4->15) will have an unconditional tcam search (ARP,RARP and 2 programmable ETHER classes)
925/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 13;
926 printf("fflp_model: Algorithm: MAC%0d.%0d L2 class. Unconditional TCAM Search done for class %0d\n",
927 mac_id, seq_id, class_num);
928 tcam_result = predict_tcam_rdc_tblnum_offset(flow, l2_rdc, mac_id);
929 tcam_rdc = tcam_result[2:0];
930 tcam_offset = tcam_result[6:3];
931 tcam_match = tcam_result[7];
932 TRES = tcam_result[9:8];
933 asdata_disc = tcam_result[10];
934
935 if (tcam_match) {
936/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 20;
937
938 if (asdata_disc)
939/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 21;
940 else
941/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 22;
942
943/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.tcamhit = 1;
944/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.tcamhit = 1;
945/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.tres = TRES;
946/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.tres = TRES;
947 if (TRES[1] == 1'b0) { // take L2 RDC number despite having a TCAM-Hit
948/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 23;
949 if (TRES[0] == 1'b0) { // continue to flow lookup for OFFSET
950/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 25;
951/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 27;
952 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES[1:0]=00, use L2_RDC despite having a TCAM hit, continue flow lookup, class %0d\n",
953 mac_id, seq_id, class_num);
954 }
955 else { // terminate the flow lookup and use L2_RDC/Offset=0
956/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 26;
957
958 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES[1:0]=01, use L2_RDC despite having a TCAM hit, NO flow lookup, class %0d\n",
959 mac_id, seq_id, class_num);
960 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
961 ctl_fifo.final_zcp_rdc_tbl_offset = tcam_offset;
962 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
963 }
964 }
965 else { // TRES[1]==1
966/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 24;
967 if (TRES[0] == 1'b0) { // Take Assoc_data RDC_TBL number and continue to flow lookup for OFFSET
968/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 25;
969/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 27;
970 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES[1:0]=10, use Assoc_data RDC_TBL, continue flow lookup for OFFSET, class %0d\n",
971 mac_id, seq_id, class_num);
972 }
973 else { // terminate the flow lookup and use Assoc_data RDC_TBL and OFFSET number
974/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 26;
975 printf ("fflp_model: Algorithm: MAC%0d.%0d TRES[1:0]=11, use Assoc_data RDC_TBL and OFFSET, NO flow lookup, class %0d\n",
976 mac_id, seq_id, class_num);
977 ctl_fifo.final_zcp_rdc_tbl_num = tcam_rdc;
978 ctl_fifo.final_zcp_rdc_tbl_offset = tcam_offset;
979 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
980 printf ("fflp_model: Algorithm: class %0d MAC%0d.%0d TCAM hit Found. Resulting in TCAM_rdc %0d, offset %0d dma_num %0d\n",
981 class_num, mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset, ctl_fifo.final_dma_chnl);
982 }
983 }
984 }
985 else {
986/*========== FFLP_Path =========*/ master_path_class.node[master_index++] = 19;
987 ctl_fifo.final_zcp_rdc_tbl_num = l2_rdc;
988 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
989 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
990 printf ("fflp_model: Algorithm: class %0d MAC%0d.%0d No tcam_hit. Resulting in l2_rdc = %0d, dma_num = %0d\n",
991 class_num, mac_id, seq_id, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_dma_chnl);
992 }
993
994 } // No L3 class match
995 }
996 if(flow.frame.error_code==PG_CHKSUM_ERR) {
997 ctl_fifo.final_zcp_rdc_tbl_offset = 0;
998 ctl_fifo.final_dma_chnl = lookup_zcp_rdc_table(ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_zcp_rdc_tbl_offset);
999 printf("fflp_model: Algorithm: MAC%0d.%0d cksum err=%0d. offset=0 l2_rdc = %0d, dma_num = %0d\n",
1000 mac_id, seq_id, flow.frame.error_code, ctl_fifo.final_zcp_rdc_tbl_num, ctl_fifo.final_dma_chnl);
1001 }
1002
1003 predict_control_fifo = ctl_fifo.object_copy();
1004
1005path_class.print_path(mac_id, pkt_id[mac_id]);
1006master_path_class.print_path(mac_id, pkt_id[mac_id]);
1007
1008path_analysis.update_l2_histogram(path_class);
1009path_analysis.update_l3_histogram(master_path_class);
1010
1011 // Send the modeled classification result to "control fifo checker", if enabled
1012 if (get_plus_arg(CHECK, "ENABLE_CTRL_FIFO_CHKR"))
1013 mailbox_put(mbox_id.cntl_chkr_mbox[mac_id], control_fifo_chkr);
1014
1015}
1016
1017function bit [4:0] fflp_model::eval_hash_offset(flow_desc flow, bit [1:0] mac_id) {
1018bit [383:0] flow_entry, reverse_flow;
1019bit [4:0] class_num;
1020bit [31:0] hash1;
1021bit [31:0] serial_hash1;
1022bit [15:0] udp_length, ah_length;
1023integer i;
1024Cpkt_info packet_info;
1025
1026/*
1027 eval_hash_offset[4] = 0; // now, ext hash is not done.
1028 // do we need ext lookup?
1029 if (yes) {
1030 }
1031
1032 else {
1033*/
1034 class_num = find_class(flow.frame.frame_class);
1035 flow_entry = 384'h0; // Fields not found in the pkt will be 0
1036
1037 if (flow_cntl_reg[class_num-4].PORT)
1038 flow_entry[FLOW_KEY_PORT] = mac_id;
1039 if (flow_cntl_reg[class_num-4].L2DA)
1040 flow_entry[FLOW_KEY_MAC_DA] = flow.dst_node.l2_addr;
1041 if (flow.frame.frame_type[2] & flow_cntl_reg[class_num-4].VLAN) {
1042 flow_entry[FLOW_KEY_VLAN_ID] = flow.src_node.tci;
1043 flow_entry[FLOW_KEY_VLAN_VALID] = 4'b1111;
1044 }
1045
1046 if (flow.frame.frame_type[3] && flow.frame.frame_type[1]) { // IPV6
1047 if (flow_cntl_reg[class_num-4].IPSA)
1048 flow_entry[FLOW_KEY_IPV6_SA] = flow.src_node.ipv6_addr;
1049 if (flow_cntl_reg[class_num-4].IPDA)
1050 flow_entry[FLOW_KEY_IPV6_DA] = flow.dst_node.ipv6_addr;
1051 }
1052 else if (!flow.frame.frame_type[3] && flow.frame.frame_type[1]) { // IPV4
1053 if (flow_cntl_reg[class_num-4].IPSA)
1054 flow_entry[FLOW_KEY_IPV4_SA] = flow.src_node.ip_addr;
1055 if (flow_cntl_reg[class_num-4].IPDA)
1056 flow_entry[FLOW_KEY_IPV4_DA] = flow.dst_node.ip_addr;
1057 }
1058
1059
1060 if ((flow.frame.frame_class == CL_UDP) || (flow.frame.frame_class==CL_UDP_FRAG) || (flow.frame.frame_class == CL_UDP_IP_V6)) {
1061 if (flow_cntl_reg[class_num-4].PROTO)
1062 flow_entry[FLOW_KEY_PID] = 8'h11;
1063 udp_length = 0; // TODO need to calculate exact UDP length
1064 case (flow_cntl_reg[class_num-4].L4_0) {
1065 2'b00: {}
1066 2'b10: flow_entry[FLOW_KEY_L4_0] = flow.tup.src_tcp_udp_port;
1067 //2'b11: flow_entry[FLOW_KEY_L4_0] = flow.tup.udp_length;
1068 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_0] - 0x%h class %0d",
1069 flow_cntl_reg[class_num-4].L4_0, class_num);
1070 }
1071 case (flow_cntl_reg[class_num-4].L4_1) {
1072 2'b00: {}
1073 2'b10: flow_entry[FLOW_KEY_L4_1] = flow.tup.dst_tcp_udp_port;
1074 //2'b11: flow_entry[FLOW_KEY_L4_1] = flow.tup.udp_checksum; // TODO It is very tough to do match on checksum
1075 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_1] - 0x%h class %0d",
1076 flow_cntl_reg[class_num-4].L4_1, class_num);
1077 }
1078 }
1079 else if ((flow.frame.frame_class == CL_TCP) || (flow.frame.frame_class==CL_TCP_FRAG) || (flow.frame.frame_class == CL_TCP_IP_V6)) {
1080 if (flow_cntl_reg[class_num-4].PROTO)
1081 flow_entry[FLOW_KEY_PID] = 8'h06;
1082 case (flow_cntl_reg[class_num-4].L4_0) {
1083 2'b00: {}
1084 2'b10: flow_entry[FLOW_KEY_L4_0] = flow.tup.src_tcp_udp_port;
1085 2'b11: flow_entry[FLOW_KEY_L4_0] = flow.tup.tcp_seq_no[31:16];
1086 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_0] - 0x%h class %0d",
1087 flow_cntl_reg[class_num-4].L4_0, class_num);
1088 }
1089 case (flow_cntl_reg[class_num-4].L4_1) {
1090 2'b00: {}
1091 2'b10: flow_entry[FLOW_KEY_L4_1] = flow.tup.dst_tcp_udp_port;
1092 2'b11: flow_entry[FLOW_KEY_L4_1] = flow.tup.tcp_seq_no[15:0];
1093 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_1] - 0x%h class %0d",
1094 flow_cntl_reg[class_num-4].L4_1, class_num);
1095 }
1096 }
1097 else if ((flow.frame.frame_class == CL_IP_SEC_AH) || (flow.frame.frame_class == CL_IP_V6_SEC_AH)) { //TODO
1098 if (flow_cntl_reg[class_num-4].PROTO)
1099 flow_entry[FLOW_KEY_PID] = 8'h33;
1100 ah_length = 0; // TODO need to calculate exact AH length
1101 case (flow_cntl_reg[class_num-4].L4_0) {
1102 2'b00: {}
1103 //2'b10: flow_entry[FLOW_KEY_L4_0] = {ah_length, flow.src_node.nxthdr};
1104 2'b11: flow_entry[FLOW_KEY_L4_0] = flow.src_node.spi[31:16];
1105 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_0] - 0x%h class %0d",
1106 flow_cntl_reg[class_num-4].L4_0, class_num);
1107 }
1108 case (flow_cntl_reg[class_num-4].L4_1) {
1109 2'b00: {}
1110 2'b10: flow_entry[FLOW_KEY_L4_1] = 0;
1111 2'b11: flow_entry[FLOW_KEY_L4_1] = flow.src_node.spi[15:0];
1112 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_1] - 0x%h class %0d",
1113 flow_cntl_reg[class_num-4].L4_1, class_num);
1114 }
1115 }
1116 else if ((flow.frame.frame_class == CL_IP_SEC_ESP) || (flow.frame.frame_class == CL_IP_V6_SEC_ESP)) { //TODO
1117 if (flow_cntl_reg[class_num-4].PROTO)
1118 flow_entry[FLOW_KEY_PID] = 8'h32;
1119 case (flow_cntl_reg[class_num-4].L4_0) {
1120 2'b00: {}
1121 2'b10: flow_entry[FLOW_KEY_L4_0] = flow.src_node.spi[31:16];
1122 2'b11: flow_entry[FLOW_KEY_L4_0] = flow.src_node.esp_ah_seq_no[31:16];
1123 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_0] - 0x%h class %0d",
1124 flow_cntl_reg[class_num-4].L4_0, class_num);
1125 }
1126 case (flow_cntl_reg[class_num-4].L4_1) {
1127 2'b00: {}
1128 2'b10: flow_entry[FLOW_KEY_L4_1] = flow.src_node.spi[15:0];
1129 2'b11: flow_entry[FLOW_KEY_L4_1] = flow.src_node.esp_ah_seq_no[15:0];
1130 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_1] - 0x%h class %0d",
1131 flow_cntl_reg[class_num-4].L4_1, class_num);
1132 }
1133 }
1134 else if ((flow.frame.frame_class == CL_SCTP) || (flow.frame.frame_class==CL_SCTP_FRAG) || (flow.frame.frame_class == CL_SCTP_IP_V6) ) { //TODO
1135 if (flow_cntl_reg[class_num-4].PROTO)
1136 flow_entry[FLOW_KEY_PID] = 8'h84;
1137 case (flow_cntl_reg[class_num-4].L4_0) {
1138 2'b00: {}
1139 2'b10: flow_entry[FLOW_KEY_L4_0] = flow.sctp.src_sctp_port;
1140 2'b11: flow_entry[FLOW_KEY_L4_0] = flow.sctp.sctp_vtag[31:16];
1141 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_0] - 0x%h class %0d",
1142 flow_cntl_reg[class_num-4].L4_0, class_num);
1143 }
1144 case (flow_cntl_reg[class_num-4].L4_1) {
1145 2'b00: {}
1146 2'b10: flow_entry[FLOW_KEY_L4_1] = flow.sctp.dst_sctp_port;
1147 2'b11: flow_entry[FLOW_KEY_L4_1] = flow.sctp.sctp_vtag[15:0];
1148 default: printf("fflp_model::eval_hash_offset ERROR invalid programming into flow_cntl_reg[L4_1] - 0x%h class %0d",
1149 flow_cntl_reg[class_num-4].L4_1, class_num);
1150 }
1151 }
1152 else { // NO L3 class match
1153 flow_entry[FLOW_KEY_L4_0] = 0;
1154 flow_entry[FLOW_KEY_L4_1] = 0;
1155 flow_entry[FLOW_KEY_PID] = 0;
1156 }
1157
1158 // At this point, we have extracted all the fields of FLOW from the incoming Packet
1159 // Now, calculate the Hash1 (CRC-32) function for this 384 bit flow key
1160 //serial_hash1 = rxc_cl.setup_cam_ram_fcram_cl.calculate_H1(0, 3'h0, packet_info);
1161
1162 hash1 = calculate_H1_hash(flow_entry);
1163
1164 eval_hash_offset = {1'b0, hash1[3:0]}; // external hash is not supported now, 12/21/2005
1165 printf("fflp_model::eval_hash_offset flow_entry=0x%h, hash1=0x%h, offset=0x%h\n", flow_entry, hash1, eval_hash_offset[3:0]);
1166
1167
1168 printf("Model FLOW_KEY: VLAN_VALID=0x%h DA=0x%h VLAN_ID=0x%h IPSA=0x%h IPDA=0x%h L4_0=0x%h L4_1=0x%h PID=0x%h PORT=%h\n",
1169 flow_entry[FLOW_KEY_VLAN_VALID],
1170 flow_entry[FLOW_KEY_MAC_DA],
1171 flow_entry[FLOW_KEY_VLAN_ID],
1172 flow_entry[FLOW_KEY_IPV4_SA],
1173 flow_entry[FLOW_KEY_IPV4_DA],
1174 flow_entry[FLOW_KEY_L4_0],
1175 flow_entry[FLOW_KEY_L4_1],
1176 flow_entry[FLOW_KEY_PID],
1177 flow_entry[FLOW_KEY_PORT]);
1178
1179}
1180
1181function bit [10:0] fflp_model::predict_tcam_rdc_tblnum_offset(flow_desc flow, bit [2:0] l2_rdc, bit [1:0] mac_id) {
1182 bit [199:0] pkt_tcam_key;
1183 bit [2:0] tcam_key_register;
1184 bit [4:0] fflp_class;
1185 bit [63:0] matched_assoc_data;
1186 integer i;
1187 bit [47:0] mac_sa;
1188 bit [15:0] seq_id;
1189
1190predict_tcam_rdc_tblnum_offset[7] = 0; // set the tcam_hit bit to 0 first. If there's a hit, it will be set to 1.
1191predict_tcam_rdc_tblnum_offset[9:8] = 2'b11; // set the TRES to 2'b11 first, TCAM-Hit will overwrite it.
1192predict_tcam_rdc_tblnum_offset[10] = 0; // DISC bit from assoc data in case of TCAM-Hit
1193
1194mac_sa = flow.src_node.l2_addr;
1195seq_id = mac_sa[15:0];
1196
1197 pkt_tcam_key[TCAM_CLS_CODE] = find_class(flow.frame.frame_class);
1198 printf ("fflp_model::predict_tcam_rdc_tblnum_offset pkt_tcam_key[TCAM_CLS_CODE] = %0d\n", pkt_tcam_key[TCAM_CLS_CODE]);
1199 case (pkt_tcam_key[TCAM_CLS_CODE]) {
1200 8,9,10,11: {
1201 pkt_tcam_key[194:192] = 0; // RESERVED
1202 pkt_tcam_key[185:112] = 0; // RESERVED
1203
1204 pkt_tcam_key[IPV4_CAM_L2RDC_TBL_NUM] = l2_rdc;
1205 if(flow.frame.frame_class==CL_TCP_FRAG || flow.frame.frame_class==CL_UDP_FRAG || flow.frame.frame_class==CL_SCTP_FRAG)
1206 pkt_tcam_key[IPV4_CAM_NOPORT] = 1;
1207 else pkt_tcam_key[IPV4_CAM_NOPORT] = 0;
1208 pkt_tcam_key[IPV4_CAM_TOS] = flow.src_node.tos;
1209
1210 if (pkt_tcam_key[TCAM_CLS_CODE] == 8) // TCP
1211 pkt_tcam_key[IPV4_CAM_PID] = 6;
1212 else if (pkt_tcam_key[TCAM_CLS_CODE] == 9) // UDP
1213 pkt_tcam_key[IPV4_CAM_PID] = 17;
1214 else if (pkt_tcam_key[TCAM_CLS_CODE] == 10)
1215 {
1216 if (flow.frame.frame_class == CL_IP_SEC_ESP) // ESP
1217 pkt_tcam_key[IPV4_CAM_PID] = 50;
1218 else if (flow.frame.frame_class == CL_IP_SEC_AH) // AH
1219 pkt_tcam_key[IPV4_CAM_PID] = 51;
1220 }
1221 else if (pkt_tcam_key[TCAM_CLS_CODE] == 11) // SCTP
1222 pkt_tcam_key[IPV4_CAM_PID] = 132;
1223
1224 if((pkt_tcam_key[TCAM_CLS_CODE]==8)||(pkt_tcam_key[TCAM_CLS_CODE]==9)||(pkt_tcam_key[TCAM_CLS_CODE]==12)||(pkt_tcam_key[TCAM_CLS_CODE]==13)){ // TCP, UDP
1225 pkt_tcam_key[IPV4_CAM_L4_SRC_PORT] = flow.tup.src_tcp_udp_port;
1226 pkt_tcam_key[IPV4_CAM_L4_DST_PORT] = flow.tup.dst_tcp_udp_port;
1227 }
1228 else if ((pkt_tcam_key[TCAM_CLS_CODE]==11)||(pkt_tcam_key[TCAM_CLS_CODE]==15)){ // SCTP
1229 pkt_tcam_key[IPV4_CAM_L4_SRC_PORT] = flow.sctp.src_sctp_port;
1230 pkt_tcam_key[IPV4_CAM_L4_DST_PORT] = flow.sctp.dst_sctp_port;
1231 }
1232 else if ((pkt_tcam_key[TCAM_CLS_CODE]==10)||(pkt_tcam_key[TCAM_CLS_CODE]==14)){ // AH, ESP
1233 pkt_tcam_key[IPV4_CAM_L4PT_SPI] = flow.src_node.spi;
1234 }
1235
1236 pkt_tcam_key[IPV4_CAM_IP_ADDR_SA] = flow.src_node.ip_addr;
1237 pkt_tcam_key[IPV4_CAM_IP_ADDR_DA] = flow.dst_node.ip_addr;
1238
1239 printf("predict_tcam_rdc V4: MAC%0d.%0d class 0x%h l2_rdc 0x%h noport %b tos 0x%h pid 0x%h L4_src 0x%h L4_dst 0x%h IPSA 0x%h IPDA 0x%h \n",
1240 mac_id, seq_id, pkt_tcam_key[TCAM_CLS_CODE],l2_rdc,pkt_tcam_key[IPV4_CAM_NOPORT],flow.src_node.tos,
1241 pkt_tcam_key[IPV4_CAM_PID], flow.tup.src_tcp_udp_port,flow.tup.dst_tcp_udp_port,
1242 pkt_tcam_key[IPV4_CAM_IP_ADDR_SA], pkt_tcam_key[IPV4_CAM_IP_ADDR_DA]);
1243 printf ("fflp_model::predict_tcam_rdc class %0d IPV4-TCAM entry prepared from PKT 0x%h\n", pkt_tcam_key[TCAM_CLS_CODE], pkt_tcam_key);
1244 }
1245 12,13,14,15: {
1246 pkt_tcam_key[194:192] = 0; // RESERVED
1247 pkt_tcam_key[186:176] = 0; // RESERVED
1248
1249 pkt_tcam_key[IPV6_CAM_L2RDC_TBL_NUM] = l2_rdc;
1250 pkt_tcam_key[IPV6_CAM_TOS] = flow.src_node.tos;
1251
1252 if (pkt_tcam_key[TCAM_CLS_CODE] == 12) // TCP
1253 pkt_tcam_key[IPV6_CAM_NXT_HDR] = 6;
1254 else if (pkt_tcam_key[TCAM_CLS_CODE] == 13) // UDP
1255 pkt_tcam_key[IPV6_CAM_NXT_HDR] = 17;
1256 else if (pkt_tcam_key[TCAM_CLS_CODE] == 14)
1257 {
1258 if (flow.frame.frame_class == CL_IP_V6_SEC_ESP) // ESP
1259 pkt_tcam_key[IPV6_CAM_NXT_HDR] = 50;
1260 else if (flow.frame.frame_class == CL_IP_V6_SEC_AH) // AH
1261 pkt_tcam_key[IPV6_CAM_NXT_HDR] = 51;
1262 }
1263 else if (pkt_tcam_key[TCAM_CLS_CODE] == 15) // SCTP
1264 pkt_tcam_key[IPV6_CAM_NXT_HDR] = 132;
1265
1266 fflp_class = find_class(flow.frame.frame_class);
1267 tcam_key_register = tcam_key_reg[fflp_class-4].tcam_ipaddr;
1268 pkt_tcam_key[IPV6_CAM_L4_SRC_PORT] = flow.tup.src_tcp_udp_port;
1269 pkt_tcam_key[IPV6_CAM_L4_DST_PORT] = flow.tup.dst_tcp_udp_port;
1270 if (tcam_key_register[0]) // tcam_ipaddr
1271 pkt_tcam_key[IPV6_CAM_IP_ADDR] = flow.src_node.ipv6_addr;
1272 else
1273 pkt_tcam_key[IPV6_CAM_IP_ADDR] = flow.dst_node.ipv6_addr;
1274
1275 printf("predict_tcam_rdc V6: MAC%0d.%0d class 0x%h l2_rdc 0x%h tos 0x%h next_hdr 0x%h L4_src 0x%h L4_dst 0x%h IPADDR 0x%h\n",
1276 mac_id, seq_id, pkt_tcam_key[TCAM_CLS_CODE],l2_rdc,flow.src_node.tos,pkt_tcam_key[IPV6_CAM_NXT_HDR],
1277 flow.tup.src_tcp_udp_port,flow.tup.dst_tcp_udp_port, pkt_tcam_key[IPV6_CAM_IP_ADDR]);
1278 printf ("fflp_model::predict_tcam_rdc class %0d IPV6-TCAM entry prepared from PKT 0x%h\n", pkt_tcam_key[TCAM_CLS_CODE], pkt_tcam_key);
1279 }
1280 16,17: {
1281
1282/* // For reference of the field locations
1283 flow[n].arp.hw_type = 1;
1284 flow[n].arp.proto_type = 16'h0800;
1285 flow[n].arp.hlen = 6;
1286 flow[n].arp.plen = 4;
1287 flow[n].arp.operation = 1;
1288 flow[n].arp.src_hw_addr = 48'habcdef000000+n;
1289 flow[n].arp.src_proto_addr = 32'hcafe0000+n;
1290 flow[n].arp.dst_hw_addr = 48'h123456000000+n;
1291 flow[n].arp.dst_proto_addr = 32'h56780000+n;
1292
1293 bit [15:0] hw_type=1; // Hardware type (e.g., Ethernet-0x0001, Packet Radio Net.)
1294 bit [15:0] proto_type=16'h0800; // Protocol type (e.g., IP - 0x0800)
1295 bit [7:0] hlen=6; // byte length of each hardware address
1296 bit [7:0] plen=4; // byte length of each protocol address
1297 bit [15:0] operation=1; // opcode (e.g. REQ or REPLY)
1298 bit [47:0] src_hw_addr=0; // Hardware address of sender of this packet
1299 bit [31:0] src_proto_addr=0; // Protocol address of the sender
1300 bit [47:0] dst_hw_addr=0; // Hardware address of target of this packet (if known)
1301 bit [31:0] dst_proto_addr=0; // Protocol address of the target
1302*/
1303 pkt_tcam_key[103:0] = 0; // initialize all reserved fields to 0
1304 pkt_tcam_key[194:192] = 0; // initialize all reserved fields to 0
1305 pkt_tcam_key[ETHERTYPE_EFRAME] = { flow.arp.src_hw_addr[31:24],
1306 flow.arp.src_hw_addr[39:32],
1307 flow.arp.src_hw_addr[47:40],
1308 flow.arp.operation[7:0],
1309 flow.arp.operation[15:8],
1310 flow.arp.plen,
1311 flow.arp.hlen,
1312 flow.arp.proto_type[7:0],
1313 flow.arp.proto_type[15:8],
1314 flow.arp.hw_type[7:0],
1315 flow.arp.hw_type[15:8]
1316 };
1317 printf ("fflp_model::predict_tcam_rdc class %0d ETHER-TCAM entry prepared from PKT 0x%h\n", pkt_tcam_key[TCAM_CLS_CODE], pkt_tcam_key);
1318 }
1319 }
1320
1321 for (i=0;i<MAX_CAM_ENTRIES;i++){
1322 //printf("fflp_model i=%0d p_key&mask=0x%h t_key&mask=0x%h\n", i, pkt_tcam_key&tcam_mask[i], tcam_entries[i]&tcam_mask[i]);
1323 if((pkt_tcam_key&tcam_mask[i]) == (tcam_entries[i]&tcam_mask[i])) {
1324 matched_assoc_data = tcam_assoc_data[i];
1325 predict_tcam_rdc_tblnum_offset[2:0] = matched_assoc_data[9:7]; // Resulting RDC-Table
1326 predict_tcam_rdc_tblnum_offset[6:3] = matched_assoc_data[5:2]; // Resulting RDC-Offset
1327 predict_tcam_rdc_tblnum_offset[9:8] = matched_assoc_data[11:10]; // Resulting TRES: Tcam RESult
1328 predict_tcam_rdc_tblnum_offset[10] = matched_assoc_data[12]; // DISC bit from assoc data
1329 printf("fflp_model::predict_tcam_rdc class %0d Found a TCAM Hit! At Index %0d, RDC %0d, Offset %0d\n",
1330 pkt_tcam_key[TCAM_CLS_CODE], i, predict_tcam_rdc_tblnum_offset[2:0], predict_tcam_rdc_tblnum_offset[6:3]);
1331 predict_tcam_rdc_tblnum_offset[7] = 1;
1332 return;
1333 }
1334 }
1335}
1336
1337
1338
1339function bit [3:0] fflp_model::predict_mac_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow) {
1340integer i;
1341bit [51:0] mac_entry;
1342
1343printf ("fflp_model::predict_mac_rdc_tblnum_pri mac_id=%0d, mac_da=0x%h\n", mac_id, flow.dst_node.l2_addr);
1344
1345 case (mac_id) {
1346 0: {
1347 for(i=0;i<MAX_DA_10G;i++){
1348 mac_entry = mac_da_table0[i];
1349 if (mac_entry[47:0]==flow.dst_node.l2_addr) {
1350/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.maccheck = 1;
1351/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.maccheck = 1;
1352 predict_mac_rdc_tblnum_pri = mac_entry[51:48];
1353 // DA matched
1354/*========== FFLP_Path =========*/ path_class.node[index++] = 2;
1355 return;
1356 }
1357 }
1358 // At this point, no DA matched. This pkt must have come to FFLP because of promisc mode
1359/*========== FFLP_Path =========*/ path_class.node[index++] = 1;
1360 }
1361 1: {
1362 for(i=0;i<MAX_DA_10G;i++){
1363 mac_entry = mac_da_table1[i];
1364 if (mac_entry[47:0]==flow.dst_node.l2_addr) {
1365/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.maccheck = 1;
1366/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.maccheck = 1;
1367 predict_mac_rdc_tblnum_pri = mac_entry[51:48];
1368 // DA matched
1369/*========== FFLP_Path =========*/ path_class.node[index++] = 2;
1370 return;
1371 }
1372 }
1373 // At this point, no DA matched. This pkt must have come to FFLP because of promisc mode
1374/*========== FFLP_Path =========*/ path_class.node[index++] = 1;
1375 }
1376 2: {
1377 for(i=0;i<MAX_DA_1G;i++){
1378 mac_entry = mac_da_table2[i];
1379 if (mac_entry[47:0]==flow.dst_node.l2_addr) {
1380/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.maccheck = 1;
1381/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.maccheck = 1;
1382 predict_mac_rdc_tblnum_pri = mac_entry[51:48];
1383 // DA matched
1384/*========== FFLP_Path =========*/ path_class.node[index++] = 2;
1385 return;
1386 }
1387 }
1388 // At this point, no DA matched. This pkt must have come to FFLP because of promisc mode
1389/*========== FFLP_Path =========*/ path_class.node[index++] = 1;
1390 }
1391 3: {
1392 for(i=0;i<MAX_DA_1G;i++){
1393 mac_entry = mac_da_table3[i];
1394 if (mac_entry[47:0]==flow.dst_node.l2_addr) {
1395/*@@@@@@@@ Cntl Hdr Info @@@@@@@@*/ ctl_fifo.maccheck = 1;
1396/*@@@@@@@@ Cntl Fifo Info @@@@@@@*/ control_fifo_chkr.maccheck = 1;
1397 predict_mac_rdc_tblnum_pri = mac_entry[51:48];
1398 // DA matched
1399/*========== FFLP_Path =========*/ path_class.node[index++] = 2;
1400 return;
1401 }
1402 }
1403 // At this point, no DA matched. This pkt must have come to FFLP because of promisc mode
1404/*========== FFLP_Path =========*/ path_class.node[index++] = 1;
1405 }
1406 default: {
1407 printf ("ERROR: fflp_model::predict_mac_rdc_tblnum_pri(): Invalid mac_id = %0d\n", mac_id);
1408 return;
1409 }
1410 }
1411 printf("fflp_model::predict_mac_rdc_tblnum_pri mac_rdc_tblnum_pri=%h\n", predict_mac_rdc_tblnum_pri);
1412
1413}
1414
1415function bit [3:0] fflp_model:: predict_vlan_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow) {
1416integer i;
1417bit [17:0] vlan_entry;
1418bit [15:0] vlan_id;
1419
1420printf ("fflp_model:: predict_vlan_rdc_tblnum_pri Detected a VLAN tagged pkt. mac_id %0d, vlan_id=0x%h\n",
1421 mac_id, flow.src_node.tci);
1422
1423 for(i=0;i<MAX_VLAN_ENTRIES;i++){
1424 vlan_id = flow.src_node.tci;
1425 if (vlan_id[11:0] == i) {
1426 vlan_entry = vlan_table[i];
1427 printf("fflp_model::predict_vlan_rdc_tblnum_pri Found a VLAN-Hit! vlan_id=0x%h, entry=0x%h\n", i, vlan_entry);
1428 if (get_plus_arg(CHECK,"PKT_CFG_VLAN_PARITY_ERR")) {
1429 // This means VLAN Table is programmed with wrong parity in all 4096 entries. RTL sees a parity error for this
1430/*========== FFLP_Path =========*/ path_class.node[index++] = 5;
1431 }
1432 else {
1433 // This means VLAN entry has NO parity error
1434/*========== FFLP_Path =========*/ path_class.node[index++] = 6;
1435 }
1436 case(mac_id) {
1437 0: predict_vlan_rdc_tblnum_pri = vlan_entry[3:0];
1438 1: predict_vlan_rdc_tblnum_pri = vlan_entry[7:4];
1439 2: predict_vlan_rdc_tblnum_pri = vlan_entry[11:8];
1440 3: predict_vlan_rdc_tblnum_pri = vlan_entry[15:12];
1441 default: {
1442 printf ("ERROR: fflp_model::predict_vlan_rdc_tblnum_pri(): Invalid mac_id = %0d\n", mac_id);
1443 return;
1444 }
1445
1446 }
1447 return;
1448 }
1449 }
1450 printf("fflp_model::predict_vlan_rdc_tblnum_pri vlan_rdc_tblnum_pri=%h\n", predict_vlan_rdc_tblnum_pri);
1451
1452}
1453
1454task fflp_model::update_vlan_shadow (integer index, bit [17:0] vlan_entry) {
1455 vlan_table[index] = vlan_entry;
1456 //printf ("fflp_model:update_vlan_shadow index=%0d, entry=0x%h\n", index,vlan_table[index]);
1457}
1458
1459task fflp_model::update_mac_da_shadow(bit [1:0] port_num, integer index, bit [51:0] mac_entry){
1460
1461 case (port_num) {
1462 0: mac_da_table0[index]= mac_entry;
1463 1: mac_da_table1[index]= mac_entry;
1464 2: mac_da_table2[index]= mac_entry;
1465 3: mac_da_table3[index]= mac_entry;
1466 default: {
1467 printf ("ERROR: fflp_model::update_mac_da_shadow: Invalid mac_id = %0d\n", port_num);
1468 return;
1469 }
1470 }
1471 printf ("fflp_model:update_mac_da_shadow index=%0d, entry=0x%h\n", index,mac_entry);
1472}
1473
1474task fflp_model::update_zcp_rdc_tbl_shadow(integer index, bit [3:0] dma_num){
1475 zcp_rdc_table[index] = dma_num;
1476 printf ("fflp_model::update_zcp_rdc_tbl_shadow index=%0d, entry=0x%h\n", index, dma_num);
1477}
1478
1479function bit [3:0] fflp_model::lookup_zcp_rdc_table(bit [2:0] rdc_tbl_num, bit [3:0] rdc_tbl_offset) {
1480 printf("fflp_model::lookup_zcp_rdc_table lookedup ZCP_RDC_TBL rdc_tbl_num=%0d, rdc_tbl_offset=%0d \n",
1481 rdc_tbl_num, rdc_tbl_offset);
1482 lookup_zcp_rdc_table = zcp_rdc_table[16*rdc_tbl_num + rdc_tbl_offset];
1483 printf(" dma=%0d\n", lookup_zcp_rdc_table);
1484}
1485
1486function bit [31:0] fflp_model:: calculate_H1_hash (bit [383:0] flow_key) {
1487
1488 bit [39:0] rd_addr;
1489 bit [63:0] initial_h1_poly_tmp;
1490
1491 bit [32:0] shtol_h1poly = 33'h0;
1492 bit [63:0] flow_keyb[6];
1493 bit [63:0] flow_keyb_tmp;
1494 integer i, j;
1495
1496 initial_h1_poly_tmp = initial_h1_poly;
1497
1498 shtol_h1poly = initial_h1_poly_tmp[32:0];
1499
1500 flow_keyb[0] = flow_key[63:0];
1501 flow_keyb[1] = flow_key[127:64];
1502 flow_keyb[2] = flow_key[191:128];
1503 flow_keyb[3] = flow_key[255:192];
1504 flow_keyb[4] = flow_key[319:256];
1505 flow_keyb[5] = flow_key[383:320];
1506
1507 for (i=0;i<6;i++)
1508 {
1509 for (j=63;j>=0;j--)
1510 {
1511 if (j === 63)
1512 {
1513 flow_keyb_tmp = flow_keyb[i];
1514 }
1515 else
1516 {
1517 flow_keyb_tmp = flow_keyb_tmp;
1518 }
1519 shtol_h1poly = shtol_h1poly << 1;
1520 if (shtol_h1poly[32] ^ flow_keyb_tmp[j])
1521 {
1522 shtol_h1poly = {1'b0,(shtol_h1poly[31:0] ^ H1_CRC_32C_POLY)};
1523 }
1524 else
1525 {
1526 shtol_h1poly = {1'b0, shtol_h1poly[31:0]};
1527 }
1528 }
1529 }
1530
1531 calculate_H1_hash = shtol_h1poly[31:0];
1532 printf("fflp_model::calculate_H1_hash() CALCULATED H1 HASH = %h.\n",calculate_H1_hash);
1533
1534}
1535