Commit | Line | Data |
---|---|---|
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 | ||
68 | extern Crxc rxc_cl; | |
69 | extern mbox_class mbox_id; | |
70 | ||
71 | class 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 | ||
86 | class fflp_path { | |
87 | integer 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 | ||
103 | class 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 | ||
262 | class 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 | ||
287 | class 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 | ||
448 | class 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 | ||
525 | task 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 | ||
530 | function 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 | ||
535 | function 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 | ||
540 | task 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 | ||
545 | task 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 | ||
550 | task 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 | ||
555 | task 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 | ||
562 | task 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 | ||
574 | function 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 | ||
591 | function 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 | ||
598 | function 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 | ||
614 | function bit [2:0] fflp_model::predict_l2_rdc_tblnum(bit [1:0] mac_id, flow_desc flow) { | |
615 | bit [3:0] mac_ctl_word, vlan_ctl_word; | |
616 | bit [2:0] mac_rdc_tblnum; | |
617 | bit [2:0] vlan_rdc_tblnum; | |
618 | bit 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 | ||
664 | function cntl_fifo fflp_model::predict_control_fifo(bit [1:0] mac_id, flow_desc flow){ | |
665 | bit [2:0] l2_rdc, tcam_rdc; | |
666 | bit [10:0] tcam_result; | |
667 | bit [3:0] tcam_offset, flow_offset; | |
668 | bit [4:0] class_num; | |
669 | bit [47:0] mac_sa; | |
670 | bit [15:0] seq_id; | |
671 | bit tcam_match, ext_hash, asdata_disc; | |
672 | bit [1:0] TRES; | |
673 | bit [4:0] hash_offset; | |
674 | ||
675 | ctl_fifo = new; | |
676 | control_fifo_chkr = new; | |
677 | path_class = new; index = 0; | |
678 | master_path_class = new; master_index = 0; | |
679 | ||
680 | /*========== FFLP_Path =========*/ path_class.node[index++] = 0; | |
681 | mac_sa = flow.src_node.l2_addr; | |
682 | seq_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 | ||
702 | printf("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 | ||
1005 | path_class.print_path(mac_id, pkt_id[mac_id]); | |
1006 | master_path_class.print_path(mac_id, pkt_id[mac_id]); | |
1007 | ||
1008 | path_analysis.update_l2_histogram(path_class); | |
1009 | path_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 | ||
1017 | function bit [4:0] fflp_model::eval_hash_offset(flow_desc flow, bit [1:0] mac_id) { | |
1018 | bit [383:0] flow_entry, reverse_flow; | |
1019 | bit [4:0] class_num; | |
1020 | bit [31:0] hash1; | |
1021 | bit [31:0] serial_hash1; | |
1022 | bit [15:0] udp_length, ah_length; | |
1023 | integer i; | |
1024 | Cpkt_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 | ||
1181 | function 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 | ||
1190 | predict_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. | |
1191 | predict_tcam_rdc_tblnum_offset[9:8] = 2'b11; // set the TRES to 2'b11 first, TCAM-Hit will overwrite it. | |
1192 | predict_tcam_rdc_tblnum_offset[10] = 0; // DISC bit from assoc data in case of TCAM-Hit | |
1193 | ||
1194 | mac_sa = flow.src_node.l2_addr; | |
1195 | seq_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 | ||
1339 | function bit [3:0] fflp_model::predict_mac_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow) { | |
1340 | integer i; | |
1341 | bit [51:0] mac_entry; | |
1342 | ||
1343 | printf ("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 | ||
1415 | function bit [3:0] fflp_model:: predict_vlan_rdc_tblnum_pri(bit [1:0] mac_id, flow_desc flow) { | |
1416 | integer i; | |
1417 | bit [17:0] vlan_entry; | |
1418 | bit [15:0] vlan_id; | |
1419 | ||
1420 | printf ("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 | ||
1454 | task 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 | ||
1459 | task 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 | ||
1474 | task 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 | ||
1479 | function 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 | ||
1486 | function 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 |