Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / rxc_sat / vera / fflp / pkt_configurator.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pkt_configurator.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include "pkt_configurator_defines.vri"
36#include "fflp_test_defines.vri"
37#include "ip_util.vrh"
38#include "rxc_class.vrh"
39#include "ip_ingress_db.vrh"
40#include "pcg_defines.vri"
41#include "pcg_types.vri"
42#include "pack_db.vrh"
43#include "flow_db.vrh"
44#include "flow_db_tasks.vrh"
45#include "pg_top_pp.vrh"
46#include "pc_top_pp.vrh"
47#include "pcg_token.vrh"
48#include "niu_byte_array.vrh"
49#include "fflp_model.vrh"
50#include "pgIdgen.vrh"
51#include "niu_lptoken.vrh"
52
53extern pg pack_gen[16];
54extern mbox_class mbox_id;
55extern Crxc rxc_cl;
56
57extern hdl_task force_tcam_entry (bit [7:0] tcam_index, bit [199:0] tcam_key);
58
59class pkt_class_info {
60
61 bit tcam_disc;
62 bit tcam_sel;
63 bit tcam_ipaddr;
64 bit [4:0] pkt_class;
65
66 task new(integer class_num){
67 tcam_disc = 0;
68 tcam_sel = 0;
69 tcam_ipaddr = 0;
70 pkt_class = class_num;
71 }
72}
73
74class flow_key {
75 bit PORT;
76 bit L2DA;
77 bit VLAN;
78 bit IPSA;
79 bit IPDA;
80 bit PROTO;
81 bit [1:0] L4_0;
82 bit [1:0] L4_1;
83
84 task new(integer class_num){
85 PORT = 0;
86 L2DA = 0;
87 VLAN = 0;
88 IPSA = 0;
89 IPDA = 0;
90 PROTO = 0;
91 L4_0 = 0;
92 L4_1 = 0;
93 }
94}
95
96//extern setup_cam_ram_fcram_class tables_shadow;
97
98class pkt_configurator {
99
100 integer pktgen_mbox_out; // to send the pkt info to pktgen
101 integer total_tcam_entries;
102 integer tcam_l2_rdc_tblnum;
103 bit debug_en;
104 bit force_lookup_hit;
105 CpgIdgen pgIdgen;
106 bit flow_from_test_en;
107
108 bit [31:0] crc_table[256] =
109 {
110 32'h00000000, 32'h77073096, 32'hee0e612c, 32'h990951ba, 32'h076dc419, 32'h706af48f,
111 32'he963a535, 32'h9e6495a3, 32'h0edb8832, 32'h79dcb8a4, 32'he0d5e91e, 32'h97d2d988,
112 32'h09b64c2b, 32'h7eb17cbd, 32'he7b82d07, 32'h90bf1d91, 32'h1db71064, 32'h6ab020f2,
113 32'hf3b97148, 32'h84be41de, 32'h1adad47d, 32'h6ddde4eb, 32'hf4d4b551, 32'h83d385c7,
114 32'h136c9856, 32'h646ba8c0, 32'hfd62f97a, 32'h8a65c9ec, 32'h14015c4f, 32'h63066cd9,
115 32'hfa0f3d63, 32'h8d080df5, 32'h3b6e20c8, 32'h4c69105e, 32'hd56041e4, 32'ha2677172,
116 32'h3c03e4d1, 32'h4b04d447, 32'hd20d85fd, 32'ha50ab56b, 32'h35b5a8fa, 32'h42b2986c,
117 32'hdbbbc9d6, 32'hacbcf940, 32'h32d86ce3, 32'h45df5c75, 32'hdcd60dcf, 32'habd13d59,
118 32'h26d930ac, 32'h51de003a, 32'hc8d75180, 32'hbfd06116, 32'h21b4f4b5, 32'h56b3c423,
119 32'hcfba9599, 32'hb8bda50f, 32'h2802b89e, 32'h5f058808, 32'hc60cd9b2, 32'hb10be924,
120 32'h2f6f7c87, 32'h58684c11, 32'hc1611dab, 32'hb6662d3d, 32'h76dc4190, 32'h01db7106,
121 32'h98d220bc, 32'hefd5102a, 32'h71b18589, 32'h06b6b51f, 32'h9fbfe4a5, 32'he8b8d433,
122 32'h7807c9a2, 32'h0f00f934, 32'h9609a88e, 32'he10e9818, 32'h7f6a0dbb, 32'h086d3d2d,
123 32'h91646c97, 32'he6635c01, 32'h6b6b51f4, 32'h1c6c6162, 32'h856530d8, 32'hf262004e,
124 32'h6c0695ed, 32'h1b01a57b, 32'h8208f4c1, 32'hf50fc457, 32'h65b0d9c6, 32'h12b7e950,
125 32'h8bbeb8ea, 32'hfcb9887c, 32'h62dd1ddf, 32'h15da2d49, 32'h8cd37cf3, 32'hfbd44c65,
126 32'h4db26158, 32'h3ab551ce, 32'ha3bc0074, 32'hd4bb30e2, 32'h4adfa541, 32'h3dd895d7,
127 32'ha4d1c46d, 32'hd3d6f4fb, 32'h4369e96a, 32'h346ed9fc, 32'had678846, 32'hda60b8d0,
128 32'h44042d73, 32'h33031de5, 32'haa0a4c5f, 32'hdd0d7cc9, 32'h5005713c, 32'h270241aa,
129 32'hbe0b1010, 32'hc90c2086, 32'h5768b525, 32'h206f85b3, 32'hb966d409, 32'hce61e49f,
130 32'h5edef90e, 32'h29d9c998, 32'hb0d09822, 32'hc7d7a8b4, 32'h59b33d17, 32'h2eb40d81,
131 32'hb7bd5c3b, 32'hc0ba6cad, 32'hedb88320, 32'h9abfb3b6, 32'h03b6e20c, 32'h74b1d29a,
132 32'head54739, 32'h9dd277af, 32'h04db2615, 32'h73dc1683, 32'he3630b12, 32'h94643b84,
133 32'h0d6d6a3e, 32'h7a6a5aa8, 32'he40ecf0b, 32'h9309ff9d, 32'h0a00ae27, 32'h7d079eb1,
134 32'hf00f9344, 32'h8708a3d2, 32'h1e01f268, 32'h6906c2fe, 32'hf762575d, 32'h806567cb,
135 32'h196c3671, 32'h6e6b06e7, 32'hfed41b76, 32'h89d32be0, 32'h10da7a5a, 32'h67dd4acc,
136 32'hf9b9df6f, 32'h8ebeeff9, 32'h17b7be43, 32'h60b08ed5, 32'hd6d6a3e8, 32'ha1d1937e,
137 32'h38d8c2c4, 32'h4fdff252, 32'hd1bb67f1, 32'ha6bc5767, 32'h3fb506dd, 32'h48b2364b,
138 32'hd80d2bda, 32'haf0a1b4c, 32'h36034af6, 32'h41047a60, 32'hdf60efc3, 32'ha867df55,
139 32'h316e8eef, 32'h4669be79, 32'hcb61b38c, 32'hbc66831a, 32'h256fd2a0, 32'h5268e236,
140 32'hcc0c7795, 32'hbb0b4703, 32'h220216b9, 32'h5505262f, 32'hc5ba3bbe, 32'hb2bd0b28,
141 32'h2bb45a92, 32'h5cb36a04, 32'hc2d7ffa7, 32'hb5d0cf31, 32'h2cd99e8b, 32'h5bdeae1d,
142 32'h9b64c2b0, 32'hec63f226, 32'h756aa39c, 32'h026d930a, 32'h9c0906a9, 32'heb0e363f,
143 32'h72076785, 32'h05005713, 32'h95bf4a82, 32'he2b87a14, 32'h7bb12bae, 32'h0cb61b38,
144 32'h92d28e9b, 32'he5d5be0d, 32'h7cdcefb7, 32'h0bdbdf21, 32'h86d3d2d4, 32'hf1d4e242,
145 32'h68ddb3f8, 32'h1fda836e, 32'h81be16cd, 32'hf6b9265b, 32'h6fb077e1, 32'h18b74777,
146 32'h88085ae6, 32'hff0f6a70, 32'h66063bca, 32'h11010b5c, 32'h8f659eff, 32'hf862ae69,
147 32'h616bffd3, 32'h166ccf45, 32'ha00ae278, 32'hd70dd2ee, 32'h4e048354, 32'h3903b3c2,
148 32'ha7672661, 32'hd06016f7, 32'h4969474d, 32'h3e6e77db, 32'haed16a4a, 32'hd9d65adc,
149 32'h40df0b66, 32'h37d83bf0, 32'ha9bcae53, 32'hdebb9ec5, 32'h47b2cf7f, 32'h30b5ffe9,
150 32'hbdbdf21c, 32'hcabac28a, 32'h53b39330, 32'h24b4a3a6, 32'hbad03605, 32'hcdd70693,
151 32'h54de5729, 32'h23d967bf, 32'hb3667a2e, 32'hc4614ab8, 32'h5d681b02, 32'h2a6f2b94,
152 32'hb40bbe37, 32'hc30c8ea1, 32'h5a05df1b, 32'h2d02ef8d
153 };
154
155 bit [383:0] sample_flow_key [64]; // 16 sample flow keys which can result in a Hash1
156 // of all possible rdc offset values 0-15
157 bit [3:0] calculated_crc4bits [64]; // correspond to the hash1 crc[3:0] for all 16 flow keys
158
159 bit[15:0] packet_id[4]; // packet id for all 4 ports
160
161 bit [3:0] MAC_LOOP_BACK_MODE; // FOR MAC LOOP BACK CASE WITH PKTCFGRT
162
163 //setup_cam_ram_fcram_class tables_shadow;
164 setup_ip_db_class ip_db;
165 fflp_model FFLP_Model;
166 flow_key flow_key_shadow[10]; // shadow of tcam_key register for all 10 classes
167 pkt_class_info pkt_class_shadow[10]; // shadow of tcam_key register for all 10 classes
168 // only classes 8-17 are considered here
169
170 task new() {
171 integer ii;
172 integer i,j;
173 string init_loopback,temp_port;
174 bit [31:0] loopback;
175
176
177 //tables_shadow = new;
178 debug_en = 1;
179 force_lookup_hit = 0;
180 total_tcam_entries = 0;
181 if (get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP"))
182 tcam_l2_rdc_tblnum = 0;
183 else
184 tcam_l2_rdc_tblnum = 0;
185 ip_db = new;
186 rxc_cl = new;
187 pgIdgen = new();
188
189 rxc_cl.setup_ip_db_cl = new;
190 for(ii=0;ii<10;ii++){
191 pkt_class_shadow[ii] = new(ii+8);
192 flow_key_shadow[ii] = new(ii+8);
193 }
194 FFLP_Model = new;
195 for(ii=0;ii<4;ii++){
196 packet_id[ii] = 0;
197 }
198 flow_from_test_en = 0;
199
200 for(i=0;i<4;i++) {
201 if(mbox_id.niu_pktcfglp[i] == -1) {
202 mbox_id.niu_pktcfglp[i] = alloc(MAILBOX,0,1);
203 }
204 }
205
206 if( get_plus_arg( CHECK, "MAC_LOOP_BACK=")) {
207 loopback = get_plus_arg( STR, "MAC_LOOP_BACK=");
208 init_loopback.bittostr(loopback);
209 for (j=0; j<init_loopback.len();j++)
210 { temp_port =init_loopback.substr(j,j);
211 MAC_LOOP_BACK_MODE = MAC_LOOP_BACK_MODE | ( 1<<temp_port.atoi()); }
212 } else MAC_LOOP_BACK_MODE = 0;
213
214
215
216
217 }
218
219 // table search functions
220 // reverse lookup ZCP RDC TABLE with dma no.
221 function integer find_zcp_rdc_offset(integer dma_num);
222 // reverse lookup TCAM and come up with a flow that can hit the given rdc
223 function bit [199:0] matching_tcam_entry(bit [2:0] rdc_tbl_num, bit [3:0] rdc_tbl_offset);
224 // reverse lookup VLAN TABLE with rdc_offset
225 function bit [11:0] find_vlan_id(integer rdc_tbl_num, integer mac_id, (integer path = 9));
226 // reverse lookup MACDA TABLE with rdc_tbl no.
227 function bit [47:0] find_mac_da(integer rdc_tbl_num, integer mac_id);
228 // send pkt fields picked up from tables to pktgen
229 task send_flow_db (integer path_num, (integer dma_num = 0));
230
231 // setup the tables in "setup_cam_ram_fcram_class" class
232 task setup_macda_table(integer mac_id);
233 task prog_mac_reg(bit [1:0] mac_id, integer index, bit [51:0] mac_entry);
234 task setup_vlan_table((integer mode = 0));
235 task prog_vlan_entry(integer index, bit [17:0] vlan_entry, (bit backdoor = 0));
236 task setup_zcp_rdc_table((integer mode = 0));
237 task setup_ext_hash_table(bit [19:0] address, bit [63:0] data);
238 task setup_tcam(integer total_entries, integer path, (integer mode = 0), (bit overwrite_asdata_disc=0));
239 function bit [199:0] get_tcam_shadow(integer index);
240 function bit [199:0] get_tcam_mask(integer index);
241 function bit [63:0] get_assoc_data(integer index);
242 task pio_write_tcam_key_rand();
243 task pio_write_assoc_data_rand();
244 task pio_read_tcam_key_rand();
245 task pio_read_assoc_data_rand();
246 function bit [31:0] hash1_crc32(byte_array buf, integer len);
247 task setup_flow_keys(bit [1:0] mac_id);
248 function bit [31:0] calculate_H1_poly (bit [383:0] flow_key);
249 function bit [383:0] find_matching_flow_key(bit [3:0] rdc_offset);
250 task configure_flow_key_classes();
251 task program_tcam_key_reg(bit [11:0] tcam_disc, bit [11:0] tcam_tsel, bit[11:0] tcam_ipaddr);
252 task program_tcam_key_asdata(integer cam_index, bit [199:0] cam_data, bit [63:0] assoc_data, (bit[199:0] cam_mask={200{1'b1}}), (bit frontdoor=0));
253 task zcp_rdc(integer index, integer Zdma);
254 task prog_flow_key(integer class_num, bit [9:0] flow_key);
255 task prog_initial_h1_poly (bit [31:0] h1_poly_init);
256 function byte_array convert_cntl_fifo_to_byte_array (cntl_fifo ctl_fifo);
257 task pio_compare_tcam_key_rand () ;
258 task SendPktForLoopBack(flow_desc flow, integer data_length,integer dma_num,integer mac_id, integer last_packet = 0);
259
260
261 // This function programs the tables/reverse searches so as to hit the specified path
262 task pkt_configurator_genPkt(integer path, integer data_length, integer dma_num, integer mac_id, integer last_packet, (flow_desc flow_in = null));
263
264}
265
266task pkt_configurator::prog_initial_h1_poly(bit [31:0] h1_poly_init) {
267 bit [39:0] addr;
268 bit [63:0] wr_data;
269
270 // update fflp model
271 FFLP_Model.update_initial_h1_poly(h1_poly_init);
272 // update RTL, pio write
273 wr_data = {32'h0, h1_poly_init};
274 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_FLOW_H1POLY;
275 fflp_util.fflp_pio_wrapper(addr, wr_data);
276}
277
278task pkt_configurator::prog_flow_key(integer class_num, bit [9:0] flow_key) {
279 bit [39:0] addr;
280 bit [63:0] wr_data;
281
282 // First write the flow_key into RTL
283 case(class_num){
284 4: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_4;
285 5: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_5;
286 6: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_6;
287 7: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_7;
288 8: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_8;
289 9: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_9;
290 10: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_A;
291 11: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_B;
292 12: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_C;
293 13: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_D;
294 14: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_E;
295 15: addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_F;
296 default: printf("pkt_configurator::prog_flow_key. NOT a valid class %0d for FLOW classification\n", class_num);
297 }
298
299 wr_data = {54'h0, flow_key};
300 fflp_util.fflp_pio_wrapper(addr, wr_data);
301
302
303 // Now, update the shadow registers of flow_key in FFLP Model
304 FFLP_Model.update_flow_key_cntl_shadow(class_num, flow_key);
305}
306
307task pkt_configurator::prog_mac_reg(bit [1:0] mac_id, integer index, bit [51:0] mac_entry) {
308 FFLP_Model.update_mac_da_shadow(mac_id, index, mac_entry); // Just the shadow
309 case (mac_id) {
310 0,1:
311 ip_db.prog_mac_reg(index+16*mac_id, mac_entry[47:0], mac_entry[51:48]); // PIOs to RTL
312 2,3:
313 ip_db.prog_mac_reg(32+index+8*(mac_id-2), mac_entry[47:0], mac_entry[51:48]); // PIOs to RTL
314 default: { }
315 }
316
317}
318
319function bit [383:0] pkt_configurator::find_matching_flow_key(bit [3:0] rdc_offset) {
320integer index;
321
322 for(index=0;index<64;index++){
323 printf ("pkt_configurator::find_matching_flow_key calculated_crc4bits[index]=%h, rdc_offset=%h\n", calculated_crc4bits[index], rdc_offset);
324 if (calculated_crc4bits[index] === rdc_offset) {
325 find_matching_flow_key = sample_flow_key[index];
326 return;
327 }
328 }
329 find_matching_flow_key = {200{1'bz}};
330
331}
332
333function bit [31:0] pkt_configurator:: calculate_H1_poly (bit [383:0] flow_key) {
334
335 bit [39:0] rd_addr;
336 bit [32:0] shtol_h1poly = 33'h0;
337 bit [63:0] flow_keyb[6];
338 bit [63:0] flow_keyb_tmp;
339 integer i, j;
340
341 flow_keyb[0] = flow_key[63:0];
342 flow_keyb[1] = flow_key[127:64];
343 flow_keyb[2] = flow_key[191:128];
344 flow_keyb[3] = flow_key[255:192];
345 flow_keyb[4] = flow_key[319:256];
346 flow_keyb[5] = flow_key[383:320];
347
348 for (i=0;i<6;i++)
349 {
350 for (j=63;j>=0;j--)
351 {
352 if (j === 63)
353 {
354 flow_keyb_tmp = flow_keyb[i];
355 }
356 else
357 {
358 flow_keyb_tmp = flow_keyb_tmp;
359 }
360 shtol_h1poly = shtol_h1poly << 1;
361 if (shtol_h1poly[32] ^ flow_keyb_tmp[j])
362 {
363 shtol_h1poly = {1'b0,(shtol_h1poly[31:0] ^ H1_CRC_32C_POLY)};
364 }
365 else
366 {
367 shtol_h1poly = {1'b0, shtol_h1poly[31:0]};
368 }
369 }
370 }
371
372 calculate_H1_poly = shtol_h1poly[31:0];
373 printf("pkt_configurator::calculate_H1_poly() CALCULATED H1 HASH = %h.\n",calculate_H1_poly);
374
375}
376
377task pkt_configurator::setup_flow_keys(bit [1:0] mac_id) {
378 bit [3:0] flow_key_vlan_valid;
379 bit [47:0] flow_key_da_addr;
380 bit [11:0] flow_key_tci;
381 bit [127:0] flow_key_ipsrc_addr = 128'hff000000_00000000_00000000_33221100;
382 bit [127:0] flow_key_ipdst_addr = 128'hff000000_00000000_00000000_66554400;
383 bit [15:0] flow_key_L4_0 = 16'hbaba;
384 bit [15:0] flow_key_L4_1 = 16'hcaca;
385 bit [7:0] flow_key_protocol;
386 bit [1:0] flow_key_port = mac_id;
387 bit [31:0] hash1_crc;
388 integer ii, TOT_MAC_DAs, start_index;
389
390 case (mac_id) {
391 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; }
392 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; }
393 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; }
394 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; }
395 default: { TOT_MAC_DAs = 0; start_index = 0; }
396 }
397
398 flow_key_tci = random() % 4096; // generate a random VLAN ID
399
400 flow_key_da_addr = ip_db.mac_entry(start_index);
401
402 if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_UDP")) // UDP
403 flow_key_protocol = 17;
404 else // TCP
405 flow_key_protocol = 06;
406
407 if (!get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_IPV6")) { // if ipv4, set the upper bits to 0
408 flow_key_ipsrc_addr = {96'h0, flow_key_ipsrc_addr[31:0]};
409 flow_key_ipdst_addr = {96'h0, flow_key_ipdst_addr[31:0]};
410 }
411
412 if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED"))
413 flow_key_vlan_valid = 4'b1111;
414 else
415 flow_key_vlan_valid = 4'b0000;
416
417 for(ii=0;ii<16;ii++) {
418 sample_flow_key[16*mac_id + ii] =
419 {flow_key_vlan_valid,
420 flow_key_da_addr + ii,
421 flow_key_tci,
422 flow_key_ipsrc_addr,
423 flow_key_ipdst_addr,
424 flow_key_L4_0,
425 flow_key_L4_1,
426 flow_key_protocol,
427 flow_key_port,
428 22'h0};
429 if (debug_en)
430 printf("sample_flow_key[%0d]=%h\n", 16*mac_id + ii, sample_flow_key[16*mac_id + ii]);
431 hash1_crc = calculate_H1_poly(sample_flow_key[16*mac_id + ii]);
432 calculated_crc4bits[16*mac_id + ii] = hash1_crc[3:0];
433 }
434
435}
436
437task pkt_configurator::configure_flow_key_classes() {
438
439 bit [39:0] addr;
440 bit [63:0] wr_data;
441
442 // Scan FFLP (Khosrow's) run_args to find out FLOW_KEY info for all 12 classes (which fields go for Hash1)
443 if (get_plus_arg (CHECK, "HOW_FLOW_IPORT_12HEX="))
444 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport = get_plus_arg( HNUM, "HOW_FLOW_IPORT_12HEX=");
445 if (get_plus_arg (CHECK, "HOW_FLOW_DA_12HEX="))
446 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr = get_plus_arg( HNUM, "HOW_FLOW_DA_12HEX=");
447 if (get_plus_arg (CHECK, "HOW_FLOW_VLAN_12HEX="))
448 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan = get_plus_arg( HNUM, "HOW_FLOW_VLAN_12HEX=");
449 if (get_plus_arg (CHECK, "HOW_FLOW_IPSRC_12HEX="))
450 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc = get_plus_arg( HNUM, "HOW_FLOW_IPSRC_12HEX=");
451 if (get_plus_arg (CHECK, "HOW_FLOW_IPDST_12HEX="))
452 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst = get_plus_arg( HNUM, "HOW_FLOW_IPDST_12HEX=");
453 if (get_plus_arg (CHECK, "HOW_FLOW_PID_12HEX="))
454 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid = get_plus_arg( HNUM, "HOW_FLOW_PID_12HEX=");
455
456 if (get_plus_arg (CHECK, "HOW_FLOW_L40_24HEX="))
457 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = get_plus_arg( HNUM, "HOW_FLOW_L40_24HEX=");
458 else if (get_plus_arg (CHECK, "HOW_FLOW_L40_B1_B2"))
459 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = 24'haa_aaaa;
460 else if (get_plus_arg (CHECK, "HOW_FLOW_L40_B5_B6"))
461 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = 24'hff_ffff;
462
463 if (get_plus_arg (CHECK, "HOW_FLOW_L41_24HEX="))
464 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = get_plus_arg( HNUM, "HOW_FLOW_L41_24HEX=");
465 else if (get_plus_arg (CHECK, "HOW_FLOW_L41_B3_B4"))
466 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = 24'haa_aaaa;
467 else if (get_plus_arg (CHECK, "HOW_FLOW_L41_B7_B8"))
468 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = 24'hff_ffff;
469
470 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_4;
471 wr_data = {54'h0,
472 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[0],
473 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[0],
474 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[0],
475 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[0],
476 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[0],
477 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[0],
478 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[1:0],
479 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[1:0]};
480 fflp_util.fflp_pio_wrapper(addr, wr_data);
481
482 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_5;
483 wr_data = {54'h0,
484 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[1],
485 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[1],
486 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[1],
487 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[1],
488 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[1],
489 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[1],
490 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[3:2],
491 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[3:2]};
492 fflp_util.fflp_pio_wrapper(addr, wr_data);
493
494 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_6;
495 wr_data = {54'h0,
496 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[2],
497 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[2],
498 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[2],
499 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[2],
500 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[2],
501 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[2],
502 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[5:4],
503 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[5:4]};
504 fflp_util.fflp_pio_wrapper(addr, wr_data);
505
506 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_7;
507 wr_data = {54'h0,
508 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[3],
509 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[3],
510 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[3],
511 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[3],
512 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[3],
513 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[3],
514 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[7:6],
515 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[7:6]};
516 fflp_util.fflp_pio_wrapper(addr, wr_data);
517
518 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_8;
519 wr_data = {54'h0,
520 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[4],
521 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[4],
522 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[4],
523 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[4],
524 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[4],
525 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[4],
526 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8],
527 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[9:8]};
528 fflp_util.fflp_pio_wrapper(addr, wr_data);
529
530 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_9;
531 wr_data = {54'h0,
532 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[5],
533 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[5],
534 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[5],
535 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[5],
536 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[5],
537 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[5],
538 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10],
539 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]};
540 fflp_util.fflp_pio_wrapper(addr, wr_data);
541
542 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_A;
543 wr_data = {54'h0,
544 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[6],
545 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[6],
546 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[6],
547 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[6],
548 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[6],
549 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[6],
550 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[13:12],
551 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[13:12]};
552 fflp_util.fflp_pio_wrapper(addr, wr_data);
553
554 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_B;
555 wr_data = {54'h0,
556 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[7],
557 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[7],
558 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[7],
559 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[7],
560 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[7],
561 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[7],
562 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[15:14],
563 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[15:14]};
564 fflp_util.fflp_pio_wrapper(addr, wr_data);
565
566 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_C;
567 wr_data = {54'h0,
568 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[8],
569 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[8],
570 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[8],
571 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[8],
572 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[8],
573 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[8],
574 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[17:16],
575 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[17:16]};
576 fflp_util.fflp_pio_wrapper(addr, wr_data);
577
578 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_D;
579 wr_data = {54'h0,
580 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[9],
581 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[9],
582 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[9],
583 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[9],
584 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[9],
585 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[9],
586 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[19:18],
587 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[19:18]};
588 fflp_util.fflp_pio_wrapper(addr, wr_data);
589
590 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_E;
591 wr_data = {54'h0,
592 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[10],
593 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[10],
594 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[10],
595 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[10],
596 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[10],
597 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[10],
598 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[21:20],
599 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[21:20]};
600 fflp_util.fflp_pio_wrapper(addr, wr_data);
601
602 addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_F;
603 wr_data = {54'h0,
604 rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[11],
605 rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[11],
606 rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[11],
607 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[11],
608 rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[11],
609 rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[11],
610 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[23:22],
611 rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[23:22]};
612 fflp_util.fflp_pio_wrapper(addr, wr_data);
613
614}
615
616task pkt_configurator::setup_macda_table(integer mac_id) {
617integer ii, tbl_num;
618integer total_loc;
619
620printf ("In pkt_configurator::setup_macda_table, mac_id=%0d\n", mac_id);
621case (mac_id) {
6220,1: total_loc = 16;
6232,3: total_loc = 8;
624default: printf("ERROR: There is no such mac_id as %0d\n", mac_id);
625}
626
627for(ii=0;ii<total_loc;ii++) {
628 tbl_num = ii%8;
629 case (mac_id) {
630 0,1: rxc_cl.setup_ip_db_cl.prog_mac_reg(ii+16*mac_id, 48'hf00102030020+ii+mac_id*'h100, {1'b0,tbl_num});
631 2,3: rxc_cl.setup_ip_db_cl.prog_mac_reg(ii+32+8*(mac_id-2), 48'hf00102030020+ii+mac_id*'h100, {1'b0,tbl_num});
632 default: printf("ERROR: There is no such mac_id as %0d\n", mac_id);
633 }
634}
635}
636
637task pkt_configurator::zcp_rdc(integer index, integer Zdma) {
638 void=rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, index, 3'b001, Zdma);
639 FFLP_Model.update_zcp_rdc_tbl_shadow(index, Zdma);
640}
641
642task pkt_configurator::setup_zcp_rdc_table((integer mode = 0)) {
643
644 bit [4:0] ret;
645 integer n,loc, inc_dma;
646 integer total_rx_dmas;
647 case (mode) {
648 // mode = 0 means any valid dma number (0-15) is written only once in the
649 // entire ZCP_RDC table. All other entries have an invalid dma number (like 31)
650 // i.e. when searched for a dma number, we'll find it only once in the entire table
651 0: {
652 for(n=0;n<MAX_RDC_TABLE;n++) {
653 for(loc=0;loc<MAX_DMA_CHAN;loc++) {
654 if (loc==0) {
655 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, 2*n);
656 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, 2*n);
657 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, 2*n);
658 }
659 else if (loc==8) {
660 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, 2*n+1);
661 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, 2*n+1);
662 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, 2*n+1);
663 }
664 else {
665 //ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, INVALID_DMA_NUM);
666 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, INVALID_DMA_NUM);
667 //printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, INVALID_DMA_NUM);
668 }
669 }
670 }
671 }
672 // mode = 1 means incremental dma_num through the entire ZCP_RDC table
673 1: {
674 for(n=0;n<MAX_DMA_CHAN*MAX_RDC_TABLE;n++) {
675 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, n, 3'b001, n%MAX_DMA_CHAN);
676 FFLP_Model.update_zcp_rdc_tbl_shadow(n, n%MAX_DMA_CHAN);
677 }
678 }
679 // mode = 2 means a valid dma_num is present only on the first entry of each TABLE (MAC type, offset = 0)
680 // dma numbers 0-7 are programmed
681 2: {
682 for(n=0;n<MAX_RDC_TABLE;n++) {
683 for(loc=0;loc<MAX_DMA_CHAN;loc++) {
684 if (loc==0) {
685 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, n);
686 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, n);
687 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, n);
688 }
689 }
690 }
691 }
692 // mode = 3 means a valid dma_num is present only on the first entry of each TABLE (MAC type, offset = 0)
693 // dma numbers 8-15 are programmed
694 3: {
695 for(n=0;n<MAX_RDC_TABLE;n++) {
696 for(loc=0;loc<MAX_DMA_CHAN;loc++) {
697 if (loc==0) {
698 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, 8+n);
699 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, 8+n);
700 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, 8+n);
701 }
702 }
703 }
704 }
705 4: { // 112 entries are programmed (subtable 0 is not programmed), suitable for tcam match test cases
706
707 if (get_plus_arg (CHECK,"TOTAL_NO_OF_RXDMA"))
708 total_rx_dmas = get_plus_arg(NUM,"TOTAL_NO_OF_RXDMA");
709 else
710 total_rx_dmas = 16;
711
712 inc_dma = 0;
713 for(n=1;n<MAX_RDC_TABLE;n++) {
714 for(loc=0;loc<MAX_DMA_CHAN;loc++) {
715 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, inc_dma%total_rx_dmas);
716 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, inc_dma%16);
717 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, inc_dma%total_rx_dmas);
718 inc_dma ++ ;
719 }
720 }
721 }
722 5 : { // all 128 entries are programmed, suitable for flow_key Hash1 test cases
723 inc_dma = 0;
724 for(n=0;n<MAX_RDC_TABLE;n++) {
725 for(loc=0;loc<MAX_DMA_CHAN;loc++) {
726 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*n+loc, 3'b001, inc_dma%16);
727 FFLP_Model.update_zcp_rdc_tbl_shadow(16*n+loc, inc_dma%16);
728 printf("writing to ZCP table index = %0d, value = %0d\n", 16*n+loc, inc_dma%16);
729 inc_dma ++ ;
730 }
731 }
732 }
733 default: {}
734 }
735
736}
737
738task pkt_configurator::setup_vlan_table((integer mode = 0)) {
739bit[2:0] rdctbl0,rdctbl1,rdctbl2,rdctbl3;
740bit parity0, parity1, vpr0, vpr1, vpr2, vpr3;
741integer i;
742bit[17:0] vlan_entry;
743bit[31:0] tmp;
744
745case (mode) {
746 0:{ for(i=0;i<MAX_VLAN_ENTRIES;i++) {
747 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
748 rdctbl0 = 0;
749 else
750 rdctbl0 = i%8;
751 vpr0 = 1;
752 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
753 rdctbl1 = 0;
754 else
755 rdctbl1 = (i+1)%8;
756 vpr1 = 1;
757 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
758 rdctbl2 = 0;
759 else
760 rdctbl2 = (i+2)%8;
761 vpr2 = 1;
762 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
763 rdctbl3 = 0;
764 else
765 rdctbl3 = (i+3)%8;
766 vpr3 = 1;
767
768 if(get_plus_arg (CHECK, "PKT_CFG_VLAN_PARITY_ERR")) {
769 parity0 = !(^{vpr1,rdctbl1,vpr0,rdctbl0}); // parity bit is corrupted for creating ERROR
770 parity1 = !(^{vpr3,rdctbl3,vpr2,rdctbl2}); // parity bit is corrupted for creating ERROR
771 }
772 else {
773 parity0 = ^{vpr1,rdctbl1,vpr0,rdctbl0}; // correct even parity
774 parity1 = ^{vpr3,rdctbl3,vpr2,rdctbl2}; // correct even parity
775 }
776
777 rxc_cl.setup_cam_ram_fcram_cl.prog_vlan_table(i,parity0,vpr1,rdctbl1,vpr0,rdctbl0);
778 vlan_entry = {parity1,parity0,vpr3,rdctbl3,vpr2,rdctbl2,vpr1,rdctbl1,vpr0,rdctbl0};
779
780 FFLP_Model.update_vlan_shadow(i, vlan_entry);
781 }
782 }
783 1:{ for(i=0;i<MAX_VLAN_ENTRIES;i++) { //random: rdctbl0, rdctbl1, vpr0, vpr1
784 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
785 rdctbl0 = 0;
786 else rdctbl0 = random();
787 if(get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP") || get_plus_arg (CHECK, "PKT_CFG_HASH1_HIT"))
788 rdctbl1 = 0;
789 else rdctbl1 = random();
790 tmp=random();
791 vpr0 = tmp[1]; vpr1 = tmp[0];
792
793 if(get_plus_arg (CHECK, "PKT_CFG_VLAN_PARITY_ERR"))
794 parity0 = !(^{vpr1,rdctbl1,vpr0,rdctbl0}); // parity bit is corrupted for creating ERROR
795 else
796 parity0 = ^{vpr1,rdctbl1,vpr0,rdctbl0}; // correct even parity
797
798 rxc_cl.setup_cam_ram_fcram_cl.prog_vlan_table(i,parity0,vpr1,rdctbl1,vpr0,rdctbl0);
799 vlan_entry = {1'b0,parity0,8'h0,vpr1,rdctbl1,vpr0,rdctbl0};
800 FFLP_Model.update_vlan_shadow(i, vlan_entry);
801 }
802 }
803 default: {}
804} // case
805
806}
807
808task pkt_configurator::prog_vlan_entry(integer index, bit [17:0] vlan_entry, (bit backdoor = 0)) {
809bit parity0, parity1;
810bit [63:0] addr;
811bit [63:0] wr_data;
812
813 addr = FFLP_VLAN_TBL_ADDRESS_RANGE + (index*8);
814 parity0 = ^vlan_entry[7:0];
815 parity1 = ^vlan_entry[15:8];
816 wr_data = {46'h0, parity1, parity0, vlan_entry[15:0]};
817
818 if (backdoor==0) {
819 gen_pio_drv.pio_wr(addr, wr_data);
820 }
821 else {
822 rxc_cl.setup_cam_ram_fcram_cl.prog_vlan_table ( index,
823 parity0,
824 vlan_entry[7],
825 vlan_entry[6:4],
826 vlan_entry[3],
827 vlan_entry[2:0] );
828 }
829
830 // Update the FFLP model's vlan entry shadow
831 FFLP_Model.update_vlan_shadow(index, vlan_entry);
832
833 printf("pkt_configurator::prog_vlan_entry index %0d, vlan_entry 0x%h backdoor = %b\n",
834 index, vlan_entry, backdoor);
835
836}
837
838function integer pkt_configurator::find_zcp_rdc_offset(integer dma_num) {
839 integer i,j;
840 integer dma_value_got;
841
842 for(i=0;i<MAX_RDC_TABLE;i++) {
843 for(j=0;j<16;j++) {
844 dma_value_got = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(1'b0,16*i+j,3'b000,5'h0);
845 if (dma_value_got == dma_num) {
846 find_zcp_rdc_offset = 16*i+j;
847 return;
848 }
849 else {
850 find_zcp_rdc_offset = 32'hdeadc0de;
851 }
852 if (debug_en)
853 printf("pkt_configurator::find_zcp_rdc_offset(): dma_num from zcp_rdc_tbl[%0d]=%0d\n", 16*i+j, dma_value_got);
854 }
855 }
856}
857
858function bit [11:0] pkt_configurator::find_vlan_id(integer rdc_tbl_num, integer mac_id, (integer path = 9)) {
859integer i;
860bit [15:0] vlan_id_line;
861
862 // search in the VLAN table, and find out the index (indices) which has the given rdc_tbl_num
863 // The index number is the VLAN_ID, which should be sent to pkt_gen to construct the packet
864
865 for(i=0;i<MAX_VLAN_ENTRIES;i++) {
866 vlan_id_line = rxc_cl.setup_cam_ram_fcram_cl.get_vlan_entry(i);
867 case(path) {
868 9:{
869 if( (vlan_id_line[(4*mac_id+2):(4*mac_id)] == rdc_tbl_num) && (vlan_id_line[4*mac_id+3]==1) ) {
870 find_vlan_id = i;
871 return;
872 }
873 else { find_vlan_id = 12'hzzz; }
874 }
875 default: {}
876 }
877 if (debug_en)
878 printf("pkt_configurator::find_vlan_id(): VLAN_TABLE_ENTRY[%0d]=%h\n", i, vlan_id_line);
879 }
880}
881
882
883function bit [199:0] pkt_configurator::matching_tcam_entry(bit [2:0] rdc_tbl_num, bit [3:0] rdc_tbl_offset) {
884
885bit [63:0] temp_assoc_data;
886integer index;
887
888 // search the associative RAM for the given rdc_offset and rdc_tbl_num
889 // and use that index to fetch the corresponding TCAM entry (200 bits)
890
891 for(index=0;index<total_tcam_entries;index++){
892 temp_assoc_data = rxc_cl.setup_cam_ram_fcram_cl.get_assoc_data(index);
893 printf ("get_assoc_data=%h, tcam_rdc_tbl=%h, tcam_rdc_offset=%h, rdc_tbl=%h, rdc_offset=%h\n", temp_assoc_data, temp_assoc_data[9:7], temp_assoc_data[5:2], rdc_tbl_num, rdc_tbl_offset);
894 if ((temp_assoc_data[9:7]===rdc_tbl_num) && (temp_assoc_data[5:2]===rdc_tbl_offset)){
895 matching_tcam_entry = rxc_cl.setup_cam_ram_fcram_cl.get_tcam_key(index);
896 return;
897 }
898 }
899 matching_tcam_entry = {200{1'bz}};
900}
901
902function bit [47:0] pkt_configurator::find_mac_da(integer rdc_tbl_num, integer mac_id) {
903
904 bit [51:0] mac_table_entry;
905 integer i, TOT_MAC_DAs, start_index;
906
907 // search the MAC_DA table to find out which entry has the given rdc_tbl num
908 // and pass that MAC_DA to pkt_gen to build the packet
909
910 case (mac_id) {
911 0: {
912 TOT_MAC_DAs = MAX_DA_10G;
913 start_index = 0;
914 }
915 1: {
916 TOT_MAC_DAs = MAX_DA_10G;
917 start_index = 16;
918 }
919 2: {
920 TOT_MAC_DAs = MAX_DA_1G;
921 start_index = 32;
922 }
923 3: {
924 TOT_MAC_DAs = MAX_DA_1G;
925 start_index = 40;
926 }
927 default: {
928 TOT_MAC_DAs = 0;
929 start_index = 0;
930 }
931 }
932
933 for(i=start_index;i<(start_index+TOT_MAC_DAs);i++) {
934 mac_table_entry = ip_db.mac_entry(i);
935 if (debug_en)
936 printf ("In mac_table, pri=%b, mac_table_entry[50:48]=%0d, mac_da=%h, rdc_tbl_num=%0d\n",
937 mac_table_entry[51], mac_table_entry[50:48], mac_table_entry[47:0], rdc_tbl_num);
938 if (rdc_tbl_num==mac_table_entry[50:48]) {
939 find_mac_da = mac_table_entry[47:0];
940 return;
941 }
942 else {
943 find_mac_da = 48'hzzzz_zzzz_zzzz;
944 }
945 }
946}
947
948task pkt_configurator::program_tcam_key_reg(bit [11:0] tcam_disc, bit [11:0] tcam_tsel, bit[11:0] tcam_ipaddr) {
949bit [63:0] addr, wr_data, assoc_data;
950
951// Enable the TCAM lookup for all IP classes 8-15 (All ipv4 and ipv6 classes)
952 printf("Enabling the TCAM lookup for all classes 8-15 (All ipv4 and ipv6 classes)\n");
953 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_4;
954 wr_data = {60'h0,tcam_disc[0],tcam_tsel[0],1'b0,tcam_ipaddr[0]};
955 fflp_util.fflp_pio_wrapper(addr, wr_data);
956 FFLP_Model.update_tcam_reg_shadow(4, {tcam_disc[0],tcam_tsel[0],tcam_ipaddr[0]});
957 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_5;
958 wr_data = {60'h0,tcam_disc[1],tcam_tsel[1],1'b0,tcam_ipaddr[1]};
959 fflp_util.fflp_pio_wrapper(addr, wr_data);
960 FFLP_Model.update_tcam_reg_shadow(5, {tcam_disc[1],tcam_tsel[1],tcam_ipaddr[1]});
961 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_6;
962 wr_data = {60'h0,tcam_disc[2],tcam_tsel[2],1'b0,tcam_ipaddr[2]};
963 fflp_util.fflp_pio_wrapper(addr, wr_data);
964 FFLP_Model.update_tcam_reg_shadow(6, {tcam_disc[2],tcam_tsel[2],tcam_ipaddr[2]});
965 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_7;
966 wr_data = {60'h0,tcam_disc[3],tcam_tsel[3],1'b0,tcam_ipaddr[3]};
967 fflp_util.fflp_pio_wrapper(addr, wr_data);
968 FFLP_Model.update_tcam_reg_shadow(7, {tcam_disc[3],tcam_tsel[3],tcam_ipaddr[3]});
969 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_8;
970 wr_data = {60'h0,tcam_disc[4],tcam_tsel[4],1'b0,tcam_ipaddr[4]};
971 fflp_util.fflp_pio_wrapper(addr, wr_data);
972 FFLP_Model.update_tcam_reg_shadow(8, {tcam_disc[4],tcam_tsel[4],tcam_ipaddr[4]});
973 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_9;
974 wr_data = {60'h0,tcam_disc[5],tcam_tsel[5],1'b0,tcam_ipaddr[5]};
975 fflp_util.fflp_pio_wrapper(addr, wr_data);
976 FFLP_Model.update_tcam_reg_shadow(9, {tcam_disc[5],tcam_tsel[5],tcam_ipaddr[5]});
977 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_A;
978 wr_data = {60'h0,tcam_disc[6],tcam_tsel[6],1'b0,tcam_ipaddr[6]};
979 fflp_util.fflp_pio_wrapper(addr, wr_data);
980 FFLP_Model.update_tcam_reg_shadow(10, {tcam_disc[6],tcam_tsel[6],tcam_ipaddr[6]});
981 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_B;
982 wr_data = {60'h0,tcam_disc[7],tcam_tsel[7],1'b0,tcam_ipaddr[7]};
983 fflp_util.fflp_pio_wrapper(addr, wr_data);
984 FFLP_Model.update_tcam_reg_shadow(11, {tcam_disc[7],tcam_tsel[7],tcam_ipaddr[7]});
985 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_C;
986 wr_data = {60'h0,tcam_disc[8],tcam_tsel[8],1'b0,tcam_ipaddr[8]};
987 fflp_util.fflp_pio_wrapper(addr, wr_data);
988 FFLP_Model.update_tcam_reg_shadow(12, {tcam_disc[8],tcam_tsel[8],tcam_ipaddr[8]});
989 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_D;
990 wr_data = {60'h0,tcam_disc[9],tcam_tsel[9],1'b0,tcam_ipaddr[9]};
991 fflp_util.fflp_pio_wrapper(addr, wr_data);
992 FFLP_Model.update_tcam_reg_shadow(13, {tcam_disc[9],tcam_tsel[9],tcam_ipaddr[9]});
993 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_E;
994 wr_data = {60'h0,tcam_disc[10],tcam_tsel[10],1'b0,tcam_ipaddr[10]};
995 fflp_util.fflp_pio_wrapper(addr, wr_data);
996 FFLP_Model.update_tcam_reg_shadow(14, {tcam_disc[10],tcam_tsel[10],tcam_ipaddr[10]});
997 addr = FFLP_ADDRESS_RANGE + FFLP_HOW_TCAM_KEY_CLS_F;
998 wr_data = {60'h0,tcam_disc[11],tcam_tsel[11],1'b0,tcam_ipaddr[11]};
999 fflp_util.fflp_pio_wrapper(addr, wr_data);
1000 FFLP_Model.update_tcam_reg_shadow(15, {tcam_disc[11],tcam_tsel[11],tcam_ipaddr[11]});
1001}
1002
1003task pkt_configurator::program_tcam_key_asdata(integer cam_index, bit [199:0] cam_data, bit [63:0] assoc_data, (bit[199:0] cam_mask={200{1'b1}}), (bit frontdoor=0)) {
1004//bit [199:0] cam_mask = {200{1'b1}};
1005bit [15:0] syndrome;
1006bit v4_ecc_ck;
1007bit [129:0] adata_cam_key;
1008bit [4:0] pkt_class;
1009bit [63:0] addr, wr_data;
1010
1011 pkt_class = cam_data[TCAM_CLS_CODE];
1012
1013 if(get_plus_arg (CHECK, "TCAM_FRONTDOOR") || (frontdoor==1)) {
1014 fflp_util.pio_wr_tcam_key(cam_index, cam_data, cam_mask);
1015 repeat(50) @(posedge CLOCK);
1016 }
1017 else { // Backdoor forcing of TCAM memory data
1018 force_tcam_entry(cam_index, cam_data);
1019 }
1020
1021 // Update the tcam_key shadow in the FFLP Model
1022 FFLP_Model.update_tcam_key_shadow(cam_index, cam_data);
1023 FFLP_Model.update_tcam_mask_shadow(cam_index, cam_mask);
1024
1025 adata_cam_key = {assoc_data[25:1],1'b0,cam_data[103:0]};
1026 v4_ecc_ck = assoc_data[13];
1027
1028 syndrome=0;
1029 //always check parity, SYNDROME field has even parity (4bits) the assoc_data[25:0]
1030 // Bit 0 for bits [7:0], bit 1 for [15:8], bit 2 for [23:16], bit 3 for [25:24]
1031 syndrome[3:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_asdata_parity (cam_index,assoc_data);
1032
1033 //overwrite parity with ecc if v4_type && v4_ecc_chk
1034 // for bits { Associated_data[25:1], 1'b0, CAM_KEY[103:0] }
1035 if(v4_ecc_ck && (pkt_class>=8) && (pkt_class<=11)) {
1036 syndrome[7:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[64:0]);
1037 syndrome[15:8] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[129:65]);
1038 }
1039 assoc_data = {22'h0,syndrome,assoc_data[25:0]};
1040
1041 // Always programming the associated data using regular PIO Writes
1042 fflp_util.pio_wr_tcam_asdata(cam_index, assoc_data);
1043 repeat(50) @(posedge CLOCK);
1044
1045 // Update the assoc_data shadow in the FFLP Model
1046 FFLP_Model.update_tcam_assoc_data_shadow(cam_index, assoc_data);
1047 repeat(50) @(posedge CLOCK);
1048}
1049
1050task pkt_configurator::setup_tcam(integer total_entries, integer path, (integer mode = 0), (bit overwrite_asdata_disc=0)) {
1051bit [2:0] l2_rdc_tbl_num;
1052bit [7:0] cam_addr;
1053integer cam_addr_int;
1054bit [3:0] cam_addr_4bit;
1055bit [199:0] ipv4_cam_key, ipv6_cam_key, cam_lmask;
1056bit [4:0] pkt_class;
1057bit [63:0] addr, wr_data, assoc_data;
1058bit [129:0] adata_cam_key;
1059bit [15:0] syndrome;
1060bit [3:0] asdata_parity_value;
1061bit [11:0] zfid;
1062bit [11:0] tcam_disc;
1063bit v4_ecc_ck;
1064bit asdata_disc;
1065bit [1:0] tres;
1066bit [4:0] asdata_offset;
1067bit [2:0] asdata_rdctbl;
1068bit zfvld;
1069bit asdata_age;
1070integer inc_offset;
1071bit [3:0] suggested_cam_lat;
1072bit [63:0] rd_data;
1073
1074 if (get_plus_arg (CHECK, "TCAM_DISC_12HEX="))
1075 tcam_disc = get_plus_arg( HNUM, "TCAM_DISC_12HEX=");
1076 else
1077 tcam_disc = 12'h000;
1078
1079// TCAM_KEY Registers programmed for classes 4->15
1080// For all 12 classes: DISC TSEL IPADDR
1081 program_tcam_key_reg(tcam_disc, 12'hfff, 12'h000);
1082
1083if (total_entries > MAX_CAM_ENTRIES) total_tcam_entries = MAX_CAM_ENTRIES;
1084else total_tcam_entries = total_entries;
1085
1086if (get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP"))
1087 l2_rdc_tbl_num = 0;
1088else
1089 l2_rdc_tbl_num = 0;
1090
1091 inc_offset = 0;
1092
1093// change the CAM latency to 4 for both niu/neptune
1094 suggested_cam_lat = 4;
1095 gen_pio_drv.pio_rd(FFLP_ADDRESS_RANGE+FFLP_CONFIG, rd_data, 1'b0);
1096 printf ("pkt_configurator: Rewriting the default value of cam_latency(%0d) with %0d\n", rd_data[19:16], suggested_cam_lat);
1097 rd_data[19:16] = suggested_cam_lat;
1098 gen_pio_drv.pio_wr(FFLP_ADDRESS_RANGE+FFLP_CONFIG, rd_data);
1099
1100 case (mode) {
1101 0: { // mode=0 programs a mix of IPv4(5-tuple) and IPv6(4-tuple) entries
1102 for(cam_addr_int=0;cam_addr_int<total_tcam_entries;cam_addr_int++) {
1103 cam_addr = cam_addr_int;
1104 cam_addr_4bit = cam_addr;
1105 /*###################### Setting up TCAM entry/Associative data for IPv6 ######################*/
1106/*
1107 pkt_class = 12 + cam_addr%4;
1108 ipv6_cam_key = {pkt_class,
1109 3'b000,
1110 {2'b00,l2_rdc_tbl_num},
1111 nop,
1112 10'h0,
1113 tos,
1114 pkt_next_hdr,
1115 src_tcp_udp_port,
1116 dst_tcp_udp_port,
1117 ipv6_addr};
1118 fflp_util.pio_wr_tcam_key(cam_addr, ipv6_cam_key, cam_lmask);
1119 fflp_util.pio_wr_tcam_asdata(cam_addr, assoc_data);
1120*/
1121 /*###################### Setting up TCAM entry/Associative data for IPv4 ######################*/
1122
1123 //pkt_class = 8 + cam_addr%4;
1124 pkt_class = 8;
1125 cam_lmask = { 200 {1'b1} };
1126
1127 ipv4_cam_key = {pkt_class, // packet CLASS
1128 3'b000, // Reserved
1129 {2'b00,l2_rdc_tbl_num}, // Layer 2 RDC TBL NUM
1130 1'b0, // NOPORT
1131 74'h0, // Reserved
1132 8'h00, // TOS
1133 8'h06, // protocol_id
1134 16'h3322, // L4_port_or_spi
1135 16'h1100, // L4_port_or_spi
1136 32'hffff3400+cam_addr_4bit, // ip_addr_sa
1137 32'hfefe1200+cam_addr_4bit}; // ip_addr_da
1138
1139/*
1140 cam_key = {pkt_class,
1141 3'b000,
1142 {2'b00,l2_rdc_tbl_num[i]},
1143 nop,
1144 74'h0,
1145 tos,
1146 pkt_protocol,
1147 src_tcp_udp_port,
1148 dst_tcp_udp_port,
1149 ip_src_addr,
1150 ip_dst_addr};
1151*/
1152
1153 syndrome = 0;
1154 zfid = 0;
1155
1156 // take the argument to see if the test wants ecc checking on v4 entries
1157 if (get_plus_arg(CHECK, "PKT_CFG_ASDATA_ECC_EN"))
1158 v4_ecc_ck = 1;
1159 else
1160 v4_ecc_ck = 0;
1161
1162 // set DISC bit in all entries of associated RAM if specified by the run
1163 if (get_plus_arg(CHECK, "PKT_CFG_SET_ASDATA_DISC_BIT"))
1164 if(overwrite_asdata_disc)
1165 asdata_disc = 0;
1166 else
1167 asdata_disc = 1;
1168 else
1169 asdata_disc = 0;
1170
1171 if (path==2)
1172 tres = 2'b11; // means: override L2_rdc_num, take tcam rdc_num/offset and "no further flow lookup".
1173 else if (path==3)
1174 tres = 2'b00; // means: use the L2_rdc_num, and continue to flow lookup.
1175 asdata_rdctbl = 1;
1176 asdata_offset = inc_offset ++; // just to make sure tcam always results in a non-zero offset
1177 zfvld = 0;
1178 asdata_age = 1;
1179
1180 adata_cam_key = {assoc_data[25:1],1'b0,ipv4_cam_key[103:0]};
1181
1182 assoc_data = {22'h0,syndrome,zfid,v4_ecc_ck,asdata_disc,tres,asdata_rdctbl,asdata_offset,zfvld,asdata_age};
1183 // If ECC Check is enabled, SYNDROME field has ECC_SYNDROME calculated
1184 // for the bits { Associated_data[25:1], 1'b0, CAM_KEY[103:0] }
1185 if ((v4_ecc_ck) && (pkt_class>=8) && (pkt_class<=11)) { // Only IPv4 classes
1186 syndrome[7:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[64:0]);
1187 syndrome[15:8] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[129:65]);
1188 }
1189 // If ECC Check is enabled, SYNDROME field has even parity (4bits) for the assoc_data[25:0]
1190 // Bit 0 for bits [7:0], bit 1 for [15:8], bit 2 for [23:16], bit 3 for [25:24]
1191 else { // if v4_ecc_ck=0 (OR) if it is IPv6 or L2
1192 syndrome[3:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_asdata_parity (cam_addr,assoc_data);
1193 syndrome[15:4] = 0;
1194 }
1195
1196 // corrupting tcam assoc data ECC if asked for
1197 if (get_plus_arg(CHECK, "PKT_CFG_ASDATA_ECC_ERR"))
1198 syndrome ^= random()%256;
1199
1200 assoc_data = {22'h0,syndrome,zfid,v4_ecc_ck,asdata_disc,tres,asdata_rdctbl,asdata_offset,zfvld,asdata_age};
1201
1202 // If plus_arg +TCAM_FRONTDOOR is given, PIOs are done to TCAM key regs. Otherwise, backdoor loaded (NIU only)
1203 if (get_plus_arg (CHECK, "TCAM_FRONTDOOR")) {
1204 // PIO Writes into the RTL
1205 fflp_util.pio_wr_tcam_key(cam_addr, ipv4_cam_key, cam_lmask);
1206 repeat(50) @(posedge CLOCK);
1207 }
1208 else {
1209 force_tcam_entry(cam_addr, ipv4_cam_key);
1210 }
1211
1212
1213 // Update the tcam_key shadow in the FFLP Model
1214 FFLP_Model.update_tcam_key_shadow(cam_addr, ipv4_cam_key);
1215
1216 // Always programming the associated data using regular PIO Writes
1217 fflp_util.pio_wr_tcam_asdata(cam_addr, assoc_data);
1218
1219 // update the tcam_key/assoc_data shadow to be able to read quickly for searching
1220 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key[cam_addr] = ipv4_cam_key;
1221 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_lmask[cam_addr] = cam_lmask;
1222 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata[cam_addr] = assoc_data;
1223
1224 printf("cam_index=%d, SHADOW_ADATA %h.\n",cam_addr,rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata [cam_addr]);
1225 printf("cam_index=%d, SHADOW_KEY %h.\n",cam_addr,rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key [cam_addr]);
1226
1227 // Update the assoc_data shadow in the FFLP Model
1228 FFLP_Model.update_tcam_assoc_data_shadow(cam_addr, assoc_data);
1229 if(cam_addr%16 == 15) {
1230 l2_rdc_tbl_num++;
1231 }
1232 }
1233 }
1234 1: { // mode=1 programs all entries with IPv4 5-tuple type entries
1235 }
1236 2: { // mode=2 programs all entries with IPv6 4-tuple type entries
1237 }
1238 default: { }
1239 }
1240
1241
1242
1243/*
1244// program the remaining entries with all 0s (so class=0, an invalid class)
1245 for(cam_addr=total_tcam_entries;cam_addr<MAX_CAM_ENTRIES;cam_addr++) {
1246 cam_lmask = { 200 {1'b1} };
1247
1248 ipv4_cam_key = { 200 {1'b0} };
1249
1250 assoc_data = { 64 {1'b0} };
1251
1252 // If plus_arg +TCAM_FRONTDOOR is given, PIOs are done to TCAM key regs. Otherwise, backdoor loaded
1253 if (get_plus_arg (CHECK, "TCAM_FRONTDOOR")) {
1254 // PIO Writes into the RTL
1255 fflp_util.pio_wr_tcam_key(cam_addr, ipv4_cam_key, cam_lmask);
1256 }
1257 else {
1258 force_tcam_entry(cam_addr, ipv4_cam_key);
1259 }
1260
1261 // Always programming the associated data using regular PIO Writes
1262 fflp_util.pio_wr_tcam_asdata(cam_addr, assoc_data);
1263
1264 // SHADOW update the tcam_key/assoc_data shadow
1265 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key[cam_addr] = ipv4_cam_key;
1266 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_lmask[cam_addr] = cam_lmask;
1267 rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata[cam_addr] = assoc_data;
1268
1269 printf("cam_index=%d, SHADOW_ADATA %h.\n",cam_addr,rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata [cam_addr]);
1270 printf("cam_index=%d, SHADOW_KEY %h.\n",cam_addr,rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key [cam_addr]);
1271
1272 }
1273*/
1274}
1275
1276
1277function bit[199:0] pkt_configurator::get_tcam_mask(integer index) {
1278 get_tcam_mask = FFLP_Model.tcam_mask[index];
1279}
1280
1281function bit [199:0] pkt_configurator::get_tcam_shadow(integer index) {
1282 if (get_plus_arg(CHECK, "USE_FFLP_SAT_SHADOW"))
1283 get_tcam_shadow = rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key[index];
1284 else
1285 get_tcam_shadow = FFLP_Model.get_tcam_entry(index);
1286}
1287
1288function bit [63:0] pkt_configurator::get_assoc_data(integer index) {
1289 if (get_plus_arg(CHECK, "USE_FFLP_SAT_SHADOW"))
1290 get_assoc_data = rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata[index];
1291 else
1292 get_assoc_data = FFLP_Model.tcam_assoc_data[index];
1293}
1294
1295task pkt_configurator::pio_write_tcam_key_rand () {
1296
1297 bit [63:0] wr_data;
1298 bit [39:0] addr;
1299 bit [199:0] wr_tcam_mask = {200{1'b1}};
1300 bit [199:0] wr_tcam_key;
1301 bit [9:0] rand_index;
1302
1303 rand_index = random() % total_tcam_entries;
1304 wr_tcam_key = get_tcam_shadow(rand_index);
1305
1306 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_MASK_REG0;
1307 wr_data = {56'h0,wr_tcam_mask[199:192]};
1308 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1309
1310 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_MASK_REG1;
1311 wr_data = wr_tcam_mask[191:128];
1312 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1313
1314 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_MASK_REG2;
1315 wr_data = wr_tcam_mask[127:64];
1316 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1317
1318 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_MASK_REG3;
1319 wr_data = wr_tcam_mask[63:0];
1320 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1321 printf("PKT_CONFIG'TOR: Index = %d, Write_TCAM_Mask Value = %h.\n",rand_index,wr_tcam_mask);
1322
1323 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_REG0;
1324 wr_data = {56'h0,wr_tcam_key[199:192]};
1325 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1326
1327 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_REG1;
1328 wr_data = wr_tcam_key[191:128];
1329 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1330
1331 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_REG2;
1332 wr_data = wr_tcam_key[127:64];
1333 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1334
1335 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_REG3;
1336 wr_data = wr_tcam_key[63:0];
1337 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1338 printf("PKT_CONFIG'TOR: Index = %d, Write_TCAM Value = %h.\n",rand_index,wr_tcam_key);
1339
1340 //****************************************
1341 // CPU write to command register *********
1342 //****************************************
1343 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_CONTROL;
1344 wr_data = {43'h0,3'b000,8'h00,rand_index};
1345 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1346 repeat(50) @(posedge CLOCK);
1347
1348}
1349
1350task pkt_configurator::pio_compare_tcam_key_rand () {
1351
1352 bit [63:0] wr_data;
1353 bit [39:0] addr;
1354 bit [9:0] rand_index;
1355
1356 rand_index = random() % MAX_CAM_ENTRIES;
1357
1358 //****************************************
1359 // CPU write to command register *********
1360 //****************************************
1361 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_CONTROL;
1362 wr_data = {43'h0,3'b010,8'h00,rand_index};
1363 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1364 repeat(50) @(posedge CLOCK);
1365
1366}
1367
1368task pkt_configurator::pio_read_tcam_key_rand () {
1369
1370 bit [63:0] wr_data;
1371 bit [39:0] addr;
1372 bit [199:0] wr_tcam_mask = {200{1'b1}};
1373 bit [199:0] wr_tcam_key;
1374 bit [9:0] rand_index;
1375
1376 rand_index = random() % MAX_CAM_ENTRIES;
1377 wr_tcam_key = get_tcam_shadow(rand_index);
1378
1379 //****************************************
1380 // CPU write to command register *********
1381 //****************************************
1382 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_CONTROL;
1383 wr_data = {43'h0,3'b001,8'h00,rand_index};
1384 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1385 repeat(50) @(posedge CLOCK);
1386
1387}
1388
1389task pkt_configurator::pio_write_assoc_data_rand () {
1390
1391 bit [63:0] wr_data;
1392 bit [39:0] addr;
1393 bit [9:0] rand_index;
1394
1395 rand_index = random() % MAX_CAM_ENTRIES;
1396
1397 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_KEY_REG1;
1398 wr_data = get_assoc_data(rand_index);
1399 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1400
1401 printf("PKT_CONFIG'TOR: Index = %d, Write_Assoc_Data Value = %h.\n",rand_index,wr_data);
1402
1403 //****************************************
1404 // CPU write to command register *********
1405 //****************************************
1406 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_CONTROL;
1407 wr_data = {43'h0,3'b100,8'h00,rand_index};
1408 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1409 repeat(50) @(posedge CLOCK);
1410
1411}
1412
1413task pkt_configurator::pio_read_assoc_data_rand () {
1414
1415 bit [63:0] wr_data;
1416 bit [39:0] addr;
1417 bit [199:0] wr_adata;
1418 bit [9:0] rand_index;
1419
1420 rand_index = random() % MAX_CAM_ENTRIES;
1421 wr_adata = get_assoc_data(rand_index);
1422
1423 printf("PKT_CONFIG'TOR: Index = %d, Read_Assoc_Data Value = %h.\n",rand_index,wr_adata);
1424
1425 //****************************************
1426 // CPU write to command register *********
1427 //****************************************
1428 addr = FFLP_ADDRESS_RANGE + FFLP_CAM_CONTROL;
1429 wr_data = {43'h0,3'b101,8'h00,rand_index};
1430 fflp_util.fflp_pio_wrapper ( addr, wr_data);
1431 repeat(50) @(posedge CLOCK);
1432
1433}
1434
1435task pkt_configurator::pkt_configurator_genPkt(integer path, integer data_length, integer dma_num, integer mac_id, integer last_packet, (flow_desc flow_in = null)) {
1436bit [11:0] pkt_vlan_id;
1437bit [47:0] pkt_mac_da;
1438integer zcp_tblnum_offset, zcp_tblnum;
1439bit [2:0] tblnum;
1440bit [3:0] offset;
1441integer dma_reqd;
1442integer pkt_path;
1443flow_desc flow;
1444bit [13:0] pkt_length;
1445CRxToken RxToken;
1446CpgToken pgToken;
1447bit [4:0] ret;
1448integer TOT_MAC_DAs;
1449integer start_index;
1450Cpkt_info pkt_info;
1451bit [199:0] tcam_entry;
1452bit [63:0] rd_data;
1453bit [383:0] flow_entry;
1454cntl_fifo ctl_fifo;
1455byte_array buf_18B;
1456bit[23:0] r;
1457bit[15:0] id;
1458bit[1:0] m;
1459bit[5:0] d;
1460
1461 pkt_path = path;
1462 flow = new;
1463 RxToken = new();
1464 pkt_info = new;
1465 ctl_fifo = new();
1466 buf_18B = new();
1467
1468 if (get_plus_arg (CHECK, "FLOW_FROM_TEST") || flow_from_test_en) {
1469 flow = flow_in;
1470
1471 // Before sending the packet to the FFLP Model, fill in the right Pkt_ID
1472 // Generate an ID on the mac SA so the checker can sort the packets.
1473 // Since getMacSA increments pktid
1474 flow.src_node.l2_addr[15:0] = pgIdgen.packet_id[mac_id];
1475 flow.src_node.l2_addr[17:16] = mac_id;
1476 flow.src_node.l2_addr[23:18] = dma_num;
1477 flow.src_node.l2_addr[47:24] = random();
1478 // pkt_info = rxc_cl.setup_cam_ram_fcram_cl.construct_flow(0, TCP_SYN, flow);
1479 // dma_reqd = pkt_info.zcp_dma_chnl;
1480
1481
1482 if(get_plus_arg (CHECK, "SKIP_PAUSE_FRAME_PREDICTION")) { // This is for pauseframe tests
1483 // Skip predict_control_fifo call for pause frames since any way it is going to be dropped by MAC
1484 if(flow.dst_node.l2_addr !== 48'h0180c2000001) {
1485 ctl_fifo = FFLP_Model.predict_control_fifo(mac_id, flow);
1486 } else {
1487 ctl_fifo.final_dma_chnl = dma_num;
1488 ctl_fifo.port_num = mac_id; // 7:6
1489 }
1490 } else { // This is normal route for all tests except pause frame tests
1491 ctl_fifo = FFLP_Model.predict_control_fifo(mac_id, flow);
1492 }
1493
1494 dma_reqd = ctl_fifo.final_dma_chnl;
1495 if(get_plus_arg (CHECK, "RX_DROP_PKT_CHECK")) {
1496
1497 //flow.src_node.l2_addr = pgIdgen.getMacSA(dma_reqd,mac_id);
1498 // Fill up variables for backward compatibility
1499 packet_id[mac_id] = flow.src_node.l2_addr[15:0];
1500 id = flow.src_node.l2_addr[15:0];
1501 m = flow.src_node.l2_addr[17:16];
1502 d = flow.src_node.l2_addr[23:18];
1503 printf("pkt_configurator::genPkt() Replaced MAC_SA with ID - 0x%x\n", flow.src_node.l2_addr);
1504 }
1505 // At this point dma_reqd is avaliable
1506 printf ("PKT_CONFIGURATOR send frame mac.seq=%0d.%0d len=%4d dma=%0d LastPkt=%0d\n", mac_id, packet_id[mac_id], data_length, dma_reqd, last_packet);
1507
1508 // convert ctl_fifo information to an 18B byte array, to send it to end checker
1509 if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK"))
1510 buf_18B = convert_cntl_fifo_to_byte_array(ctl_fifo);
1511 }
1512
1513 else {
1514
1515 dma_reqd = dma_num;
1516 printf ("PKT_CONFIGURATOR: REVERSE. FLOW_FROM_PKT_CFG. path %0d pkt_len %0d dma_num %0d mac_id %0d IsLastPkt %0d\n",
1517 pkt_path, data_length, dma_reqd, mac_id, last_packet);
1518 // The following case{} block will construct the flow_desc object, according to the "path"
1519 case (pkt_path) {
1520
1521 0: { // NO CLASS MATCH MAC RDC TBL NUMBER, RDC OFFSET=0
1522
1523 // If asked for guaranteed lookup, program the entries so we have all the (relevant) hits
1524 if (force_lookup_hit) {
1525 // Let the dma_num go randomly into one of the 8 tables
1526 ret = rxc_cl.setup_cam_ram_fcram_cl.program_zcp_rdc_tbl(0, 16*dma_num, 3'b001, dma_num);
1527 }
1528
1529 // First lookup the ZCP RDC table to findout which table has the required DMA num
1530 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
1531 // randomly select the rdc_tbl_num and find out which of the 8 MAC_DAs corresponds to that
1532 zcp_tblnum = zcp_tblnum_offset/16;
1533 pkt_mac_da = find_mac_da(zcp_tblnum, mac_id);
1534 if (debug_en)
1535 printf ("zcp_tblnum_offset=0x%h, zcp_tblnum=%0d, mac_id=%0d, pkt_mac_da for pkt = %h\n",
1536 zcp_tblnum_offset, zcp_tblnum, mac_id, pkt_mac_da);
1537
1538 // set the TYPE/LEN field to have "NO CLASS MATCH"
1539 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
1540 flow.src_node.tos = 8'hf5;
1541 flow.src_node.tci = 16'hcb00;
1542 flow.src_node.ip_addr = 32'hcccc_0000;
1543 flow.src_node.src_port = 20'h00001;
1544
1545 flow.dst_node.l2_addr = pkt_mac_da;
1546 flow.dst_node.tci = 16'hcb00;
1547 flow.dst_node.ip_addr = 32'h8888_0000;
1548 flow.dst_node.src_port = 20'h00001;
1549
1550 flow.tup.src_tcp_udp_port = 16'h1234;
1551 flow.tup.dst_tcp_udp_port = 16'hABCD;
1552
1553 flow.frame.frame_type = 5'b00010;
1554 flow.frame.frame_class = CL_ICMP; // This will be recognized as "NO CLASS MATCH" by FFLP
1555 flow.frame.type = -1;
1556 flow.frame.class_mask = 0;
1557 flow.frame.class_funct = CLF_SRC;
1558 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
1559 flow.frame.data_seed = 128;
1560
1561 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
1562 flow.fl_state.tcp_flags = 6'b00_0010;
1563 flow.flow_no = 0;
1564
1565 }
1566 1: { // L2 CLASS MATCH NO CAM MATCH MAC RDC TBL NUMBER, RDC OFFSET=0
1567
1568 // First lookup the ZCP RDC table to findout which table has the required DMA num
1569 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
1570 // randomly select the rdc_tbl_num and find out which of the 8 MAC_DAs corresponds to that
1571 zcp_tblnum = zcp_tblnum_offset/16;
1572 pkt_mac_da = find_mac_da(zcp_tblnum, mac_id);
1573 if (debug_en)
1574 printf ("zcp_tblnum_offset=0x%h, zcp_tblnum=%0d, mac_id=%0d, pkt_mac_da for pkt = %h\n", zcp_tblnum_offset, zcp_tblnum, mac_id, pkt_mac_da);
1575
1576 // set the TYPE/LEN field to have "L2 CLASS MATCH"
1577 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
1578 flow.src_node.tos = 8'hf5;
1579 flow.src_node.tci = 16'hcb00;
1580 flow.src_node.ip_addr = 32'hcccc_0000;
1581 flow.src_node.src_port = 20'h00001;
1582
1583 flow.dst_node.l2_addr = pkt_mac_da;
1584 flow.dst_node.tci = 16'hcb00;
1585 flow.dst_node.ip_addr = 32'h8888_0000;
1586 flow.dst_node.src_port = 20'h00001;
1587
1588 flow.tup.src_tcp_udp_port = 16'h1234;
1589 flow.tup.dst_tcp_udp_port = 16'hABCD;
1590
1591 if (data_length < 128) {
1592 randcase {
1593 30:{ // IPV4, TCP
1594 flow.frame.frame_type = 5'b00010;
1595 flow.frame.frame_class = CL_TCP;
1596 }
1597 20:{ // IPV4, UDP
1598 flow.frame.frame_type = 5'b00010;
1599 flow.frame.frame_class = CL_UDP;
1600 }
1601 20:{ // IPV4, AH/ESP
1602 flow.frame.frame_type = 5'b00010;
1603 flow.frame.frame_class = CL_IP_SEC_AH;
1604 }
1605 20:{ // IPV4, SCTP
1606 flow.frame.frame_type = 5'b00010;
1607 flow.frame.frame_class = CL_SCTP;
1608 }
1609 10:{ // ARP
1610 flow.frame.frame_type = 5'b00010;
1611 flow.frame.frame_class = CL_ARP;
1612 }
1613 }
1614 }
1615 else if (data_length >= 128) {
1616 randcase {
1617 20:{ // IPV4, TCP
1618 flow.frame.frame_type = 5'b00010;
1619 flow.frame.frame_class = CL_TCP;
1620 }
1621 10:{ // IPV4, UDP
1622 flow.frame.frame_type = 5'b00010;
1623 flow.frame.frame_class = CL_UDP;
1624 }
1625 10:{ // IPV4, AH/ESP
1626 flow.frame.frame_type = 5'b00010;
1627 flow.frame.frame_class = CL_IP_SEC_AH;
1628 }
1629 10:{ // IPV4, SCTP
1630 flow.frame.frame_type = 5'b00010;
1631 flow.frame.frame_class = CL_SCTP;
1632 }
1633 10:{ // IPV6, TCP
1634 flow.frame.frame_type = 5'b01010;
1635 flow.frame.frame_class = CL_TCP_IP_V6;
1636 }
1637 10:{ // IPV6, UDP
1638 flow.frame.frame_type = 5'b01010;
1639 flow.frame.frame_class = CL_UDP_IP_V6;
1640 }
1641 10:{ // IPV6, AH/ESP
1642 flow.frame.frame_type = 5'b01010;
1643 flow.frame.frame_class = CL_IP_V6_SEC_AH;
1644 }
1645 10:{ // IPV6, SCTP
1646 flow.frame.frame_type = 5'b01010;
1647 flow.frame.frame_class = CL_SCTP_IP_V6;
1648 }
1649 10:{ // ARP
1650 flow.frame.frame_type = 5'b00010;
1651 flow.frame.frame_class = CL_ARP;
1652 }
1653 }
1654 }
1655
1656 if (get_plus_arg(CHECK, "IP_FRAG_BUG_ERR")) {
1657 case (packet_id[mac_id]%3) {
1658 0: {
1659 flow.frame.frame_class = CL_UDP_FRAG;
1660 flow.frame.frame_type = 5'b00010;
1661 }
1662 1: {
1663 flow.frame.frame_class = CL_TCP_FRAG;
1664 flow.frame.frame_type = 5'b00010;
1665 }
1666 2: {
1667 flow.frame.frame_class = CL_SCTP_FRAG;
1668 flow.frame.frame_type = 5'b00010;
1669 }
1670 }
1671 flow.frame.error_code = PG_CHKSUM_ERR;
1672 flow.frame.ip_frag = 16'h6000;
1673 }
1674
1675 flow.frame.type = -1;
1676 flow.frame.class_mask = 0;
1677 flow.frame.class_funct = CLF_SRC;
1678 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
1679 flow.frame.data_seed = 128;
1680
1681 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
1682 flow.fl_state.tcp_flags = 6'b00_0010;
1683 flow.flow_no = 0;
1684
1685 }
1686 2: { // L3 CLASS MATCH CAM MATCH MAC RDC TBL NUMBER, RDC OFFSET=0
1687
1688 // First lookup the ZCP RDC table to findout which subtable+offset has the required DMA num
1689 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
1690
1691 // Then search the tcam associated data to find out which tcam entry has that rdc+offset
1692 tblnum = zcp_tblnum_offset/16;
1693 offset = zcp_tblnum_offset%16;
1694 tcam_entry = matching_tcam_entry(tblnum,offset);
1695
1696 // choose a vlan id, all the entries should result in an RDC=l2_rdc_tbl_num
1697 pkt_vlan_id = random()%MAX_VLAN_ENTRIES;
1698
1699 // choose one of 16 MAC_DAs randomly, all the mac_cntl_words should result in RDC=l2_rdc_tbl_num
1700 case (mac_id) {
1701 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; }
1702 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; }
1703 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; }
1704 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; }
1705 default: { TOT_MAC_DAs = 0; start_index = 0; }
1706 }
1707 printf("index %0d, TOT_MAC_DAs %0d, mac_id %0d \n",
1708 start_index+random()%TOT_MAC_DAs, TOT_MAC_DAs, mac_id);
1709
1710 pkt_mac_da = ip_db.mac48_da[start_index+random()%TOT_MAC_DAs];
1711
1712 if (debug_en)
1713 printf ("zcp_entry=0x%h tblnum=%02d offset=%02d Port=%0d DA for pkt %h, vlan=%04d, tcam_key=%h\n",
1714 zcp_tblnum_offset, tblnum, offset, mac_id, pkt_mac_da, pkt_vlan_id, tcam_entry);
1715
1716 // set the TYPE/LEN field to have "L3 CLASS MATCH"
1717 // ###############################################################################################
1718 // frame_type[4:0] bit definitions for pkt_gen
1719 //
1720 // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt
1721 // | | | | |
1722 // | | | | |
1723 // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0]
1724 // ###############################################################################################
1725
1726 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
1727 flow.src_node.tci = pkt_vlan_id;
1728 flow.src_node.src_port = 20'h00001;
1729
1730 flow.dst_node.l2_addr = pkt_mac_da;
1731 flow.dst_node.tci = 16'hcb00;
1732 flow.dst_node.src_port = 20'h00001;
1733
1734
1735 if (debug_en)
1736 printf ("tcam_entry[CLASS]=%0d,", tcam_entry[TCAM_CLS_CODE]);
1737
1738 case (tcam_entry[TCAM_CLS_CODE]){
1739
1740 8,9,10,11: {
1741 flow.src_node.tos = tcam_entry[IPV4_CAM_TOS];
1742 flow.src_node.ip_addr = tcam_entry[IPV4_CAM_IP_ADDR_SA];
1743 flow.dst_node.ip_addr = tcam_entry[IPV4_CAM_IP_ADDR_DA];
1744 flow.tup.src_tcp_udp_port = tcam_entry[IPV4_CAM_L4_SRC_PORT];
1745 flow.tup.dst_tcp_udp_port = tcam_entry[IPV4_CAM_L4_DST_PORT];
1746 }
1747 12,13,14,15: {
1748 flow.src_node.tos = tcam_entry[IPV6_CAM_TOS];
1749 if (pkt_class_shadow[tcam_entry[TCAM_CLS_CODE]].tcam_ipaddr)
1750 flow.src_node.ipv6_addr = tcam_entry[IPV6_CAM_IP_ADDR];
1751 else
1752 flow.dst_node.ipv6_addr = tcam_entry[IPV6_CAM_IP_ADDR];
1753 flow.tup.src_tcp_udp_port = tcam_entry[IPV6_CAM_L4_SRC_PORT];
1754 flow.tup.dst_tcp_udp_port = tcam_entry[IPV6_CAM_L4_DST_PORT];
1755 }
1756
1757
1758 }
1759
1760 if (debug_en)
1761 printf ("flow.src_node.tos=%h,flow.src_node.ip_addr=%h,flow.dst_node.ip_addr=%h, flow.tup.src_tcp_udp_port=%h,flow.tup.dst_tcp_udp_port=%h\n",
1762 flow.src_node.tos,flow.src_node.ip_addr,flow.dst_node.ip_addr, flow.tup.src_tcp_udp_port,flow.tup.dst_tcp_udp_port);
1763
1764 case (tcam_entry[TCAM_CLS_CODE]){
1765 8:{ // IPV4, TCP
1766 flow.frame.frame_type = 5'b00010;
1767 flow.frame.frame_class = CL_TCP;
1768 }
1769 9:{ // IPV4, UDP
1770 flow.frame.frame_type = 5'b00010;
1771 flow.frame.frame_class = CL_UDP;
1772 }
1773 10:{ // IPV4, AH/ESP
1774 flow.frame.frame_type = 5'b00010;
1775 flow.frame.frame_class = CL_IP_SEC_AH;
1776 }
1777 11:{ // IPV4, SCTP
1778 flow.frame.frame_type = 5'b00010;
1779 flow.frame.frame_class = CL_SCTP;
1780 }
1781 12:{ // IPV6, TCP
1782 flow.frame.frame_type = 5'b01010;
1783 flow.frame.frame_class = CL_TCP_IP_V6;
1784 }
1785 13:{ // IPV6, UDP
1786 flow.frame.frame_type = 5'b01010;
1787 flow.frame.frame_class = CL_UDP_IP_V6;
1788 }
1789 14:{ // IPV6, AH/ESP
1790 flow.frame.frame_type = 5'b01010;
1791 flow.frame.frame_class = CL_IP_V6_SEC_AH;
1792 }
1793 15:{ // IPV6, SCTP
1794 flow.frame.frame_type = 5'b01010;
1795 // flow.frame.frame_class = CL_SCTP_IP_V6; // Not defined in PKTGEN yet
1796 }
1797 default: { }
1798 }
1799
1800 // If VLAN tag is asked for, generate a tagged packet from PKTGEN
1801 if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED"))
1802 flow.frame.frame_type[2] = 1;
1803
1804 if (debug_en)
1805 printf ("flow.frame.frame_type=%h, flow.frame.frame_class=%h\n", flow.frame.frame_type,flow.frame.frame_class);
1806
1807 flow.frame.type = -1;
1808 flow.frame.class_mask = 0;
1809 flow.frame.class_funct = CLF_SRC;
1810 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
1811 flow.frame.data_seed = 128;
1812
1813 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
1814 flow.fl_state.tcp_flags = 6'b00_0010;
1815 flow.flow_no = 0;
1816
1817 }
1818 3: { // L3 CLASS MATCH, NO CAM MATCH, MAC RDC TBL NUMBER, HASH1 RDC OFFSET
1819
1820
1821 // First lookup the ZCP RDC table to findout which subtable+offset has the required DMA num
1822 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
1823
1824 // Then search the tcam associated data to find out which tcam entry has that rdc+offset
1825 tblnum = zcp_tblnum_offset/16;
1826 offset = zcp_tblnum_offset%16;
1827
1828 // find a matching flow key, given this rdc_offset
1829 flow_entry = find_matching_flow_key(offset);
1830 // VLAN id should match what's there in the flow_entry, to have a hash1_hit
1831 pkt_vlan_id = flow_entry[FLOW_KEY_VLAN_ID];
1832 // pkt_mac_da
1833 pkt_mac_da = flow_entry[FLOW_KEY_MAC_DA];
1834
1835 printf ("zcp_entry=0x%h tblnum=%02d offset=%02d Port=%0d DA for pkt %h, vlan=%04d, flow_entry=%h\n", zcp_tblnum_offset, tblnum, offset, mac_id, pkt_mac_da, pkt_vlan_id, flow_entry);
1836
1837 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
1838 flow.src_node.tci = pkt_vlan_id;
1839 flow.src_node.src_port = flow_entry[63:48];
1840
1841 flow.dst_node.l2_addr = pkt_mac_da;
1842 flow.dst_node.tci = 16'hcb00;
1843 flow.dst_node.src_port = 20'h00001;
1844
1845 if (debug_en)
1846 printf ("flow.src_node.tos=%h,flow.src_node.ip_addr=%h,flow.dst_node.ip_addr=%h, flow.tup.src_tcp_udp_port=%h,flow.tup.dst_tcp_udp_port=%h\n",
1847 flow.src_node.tos,flow.src_node.ip_addr,flow.dst_node.ip_addr, flow.tup.src_tcp_udp_port,flow.tup.dst_tcp_udp_port);
1848
1849 if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_UDP")) {
1850 flow.frame.frame_class = CL_UDP;
1851 if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10]==2'b10)
1852 flow.tup.src_tcp_udp_port = flow_entry[FLOW_KEY_L4_0];
1853 //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10]==2'b11)
1854 // flow.tup.udp_length = flow_entry[FLOW_KEY_L4_0];
1855
1856 if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b10)
1857 flow.tup.dst_tcp_udp_port = flow_entry[FLOW_KEY_L4_1];
1858 //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b11)
1859 // flow.tup.udp_checksum = flow_entry[FLOW_KEY_L4_1];
1860 }
1861 else {
1862 flow.frame.frame_class = CL_TCP;
1863 if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8]==2'b10)
1864 flow.tup.src_tcp_udp_port = flow_entry[FLOW_KEY_L4_0];
1865 //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8]==2'b11)
1866 // flow.tup.seq_num[31:16] = flow_entry[FLOW_KEY_L4_0];
1867
1868 if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b10)
1869 flow.tup.dst_tcp_udp_port = flow_entry[FLOW_KEY_L4_1];
1870 //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b11)
1871 // flow.tup.seq_num[15:0] = flow_entry[FLOW_KEY_L4_1];
1872 }
1873
1874 // Take an option of IPv4 or IPv6
1875 if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_IPV6")) {
1876 flow.frame.frame_type[3] = 1; // v6
1877 flow.frame.frame_type[1] = 1; // IP
1878 flow.src_node.ipv6_addr = flow_entry[FLOW_KEY_IPV6_SA];
1879 flow.dst_node.ipv6_addr = flow_entry[FLOW_KEY_IPV6_DA];
1880 }
1881 else {
1882 flow.frame.frame_type[3] = 0; // v4
1883 flow.frame.frame_type[1] = 1; // IP
1884 flow.src_node.ip_addr = flow_entry[FLOW_KEY_IPV4_SA];
1885 flow.dst_node.ip_addr = flow_entry[FLOW_KEY_IPV4_DA];
1886 }
1887 // If VLAN tag is asked for, generate a tagged packet from PKTGEN
1888 if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED"))
1889 flow.frame.frame_type[2] = 1;
1890
1891 if (debug_en)
1892 printf ("flow.frame.frame_type=%h, flow.frame.frame_class=%h\n", flow.frame.frame_type,flow.frame.frame_class);
1893
1894 if (debug_en)
1895 printf ("IPSA=%h,IPDA=%h, L4_0=%h, L4_1=%h\n",
1896 flow.src_node.ip_addr,flow.dst_node.ip_addr, flow.tup.src_tcp_udp_port, flow.tup.dst_tcp_udp_port);
1897
1898 flow.frame.type = -1;
1899 flow.frame.class_mask = 0;
1900 flow.frame.class_funct = CLF_SRC;
1901 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
1902 flow.frame.data_seed = 128+dma_reqd;
1903
1904 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
1905 flow.fl_state.tcp_flags = 6'b00_0010;
1906 flow.flow_no = 0;
1907
1908 }
1909 9: {
1910
1911 // First lookup the ZCP RDC table to findout which table has the required DMA num
1912 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
1913 zcp_tblnum = zcp_tblnum_offset/16;
1914 pkt_vlan_id = find_vlan_id(zcp_tblnum, mac_id);
1915 case (mac_id) {
1916 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; }
1917 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; }
1918 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; }
1919 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; }
1920 default: { TOT_MAC_DAs = 0; start_index = 0; }
1921 }
1922 printf ("mac_index = %0d\n", start_index+random()%TOT_MAC_DAs);
1923 pkt_mac_da = ip_db.mac_entry(start_index+random()%TOT_MAC_DAs);
1924 if (debug_en)
1925 printf ("rdctbl_offset=%0d, rdc_tblnum=%0d, mac_id=%0d, pkt_mac_da %h, pkt_vlan %h\n", zcp_tblnum_offset, zcp_tblnum, mac_id, pkt_mac_da,pkt_vlan_id);
1926
1927 // set the TYPE/LEN field to have "L3 CLASS MATCH"
1928 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
1929 flow.src_node.tos = 8'hf5;
1930 flow.src_node.tci = {4'h0, pkt_vlan_id[11:0]};
1931 flow.src_node.ip_addr = 32'hcccc_0000;
1932 flow.src_node.src_port = 20'h00001;
1933
1934 flow.dst_node.l2_addr = pkt_mac_da;
1935 flow.dst_node.tci = 16'hcb00;
1936 flow.dst_node.ip_addr = 32'h8888_0000;
1937 flow.dst_node.src_port = 20'h00001;
1938
1939 flow.tup.src_tcp_udp_port = 16'h1234;
1940 flow.tup.dst_tcp_udp_port = 16'hABCD;
1941
1942 // ###############################################################################################
1943 // frame_type[4:0] bit definitions for pkt_gen
1944 //
1945 // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt
1946 // | | | | |
1947 // | | | | |
1948 // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0]
1949 // ###############################################################################################
1950
1951 if (data_length < 128) {
1952 randcase {
1953 30:{ // IPV4, TCP
1954 flow.frame.frame_type = 5'b00110;
1955 flow.frame.frame_class = CL_TCP;
1956 }
1957 20:{ // IPV4, UDP
1958 flow.frame.frame_type = 5'b00110;
1959 flow.frame.frame_class = CL_UDP;
1960 }
1961 20:{ // IPV4, AH/ESP
1962 flow.frame.frame_type = 5'b00110;
1963 flow.frame.frame_class = CL_IP_SEC_AH;
1964 }
1965 20:{ // IPV4, SCTP
1966 flow.frame.frame_type = 5'b00110;
1967 flow.frame.frame_class = CL_SCTP;
1968 }
1969 10:{ // ARP
1970 flow.frame.frame_type = 5'b00110;
1971 flow.frame.frame_class = CL_ARP;
1972 }
1973 }
1974 }
1975 else if (data_length >= 128) {
1976 randcase {
1977 20:{ // IPV4, TCP
1978 flow.frame.frame_type = 5'b00110;
1979 flow.frame.frame_class = CL_TCP;
1980 }
1981 10:{ // IPV4, UDP
1982 flow.frame.frame_type = 5'b00110;
1983 flow.frame.frame_class = CL_UDP;
1984 }
1985 10:{ // IPV4, AH/ESP
1986 flow.frame.frame_type = 5'b00110;
1987 flow.frame.frame_class = CL_IP_SEC_AH;
1988 }
1989 10:{ // IPV4, SCTP
1990 flow.frame.frame_type = 5'b00110;
1991 flow.frame.frame_class = CL_SCTP;
1992 }
1993 10:{ // IPV6, TCP
1994 flow.frame.frame_type = 5'b01110;
1995 flow.frame.frame_class = CL_TCP_IP_V6;
1996 }
1997 10:{ // IPV6, UDP
1998 flow.frame.frame_type = 5'b01110;
1999 flow.frame.frame_class = CL_UDP_IP_V6;
2000 }
2001 10:{ // IPV6, AH/ESP
2002 flow.frame.frame_type = 5'b01110;
2003 flow.frame.frame_class = CL_IP_V6_SEC_AH;
2004 }
2005 10:{ // IPV6, SCTP
2006 flow.frame.frame_type = 5'b01110;
2007 flow.frame.frame_class = CL_SCTP_IP_V6;
2008 }
2009 10:{ // ARP
2010 flow.frame.frame_type = 5'b00110;
2011 flow.frame.frame_class = CL_ARP;
2012 }
2013 }
2014 }
2015
2016 flow.frame.type = -1;
2017 flow.frame.class_mask = 0;
2018 flow.frame.class_funct = CLF_SRC;
2019 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
2020 flow.frame.data_seed = 128;
2021
2022 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
2023 flow.fl_state.tcp_flags = 6'b00_0010;
2024 flow.flow_no = 0;
2025 }
2026 10: {
2027
2028 // First lookup the ZCP RDC table to findout which table has the required DMA num
2029 zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd);
2030 zcp_tblnum = zcp_tblnum_offset/16;
2031 pkt_vlan_id = find_vlan_id(zcp_tblnum, mac_id%2);
2032 case (mac_id) {
2033 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; }
2034 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; }
2035 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; }
2036 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; }
2037 default: { TOT_MAC_DAs = 0; start_index = 0; }
2038 }
2039 pkt_mac_da = ip_db.mac_entry(start_index+random()%TOT_MAC_DAs);
2040 if (debug_en)
2041 printf ("rdctbl_offset=%0d, rdc_tblnum=%0d, mac_id=%0d, pkt_mac_da %h, pkt_vlan %h\n", zcp_tblnum_offset, zcp_tblnum, mac_id, pkt_mac_da,pkt_vlan_id);
2042
2043 // set the TYPE/LEN field to have "L3 CLASS MATCH"
2044 flow.src_node.l2_addr = 48'hde_f0_72_94_38_15;
2045 flow.src_node.tos = 8'hf5;
2046 flow.src_node.tci = {4'h0, pkt_vlan_id[11:0]};
2047 flow.src_node.ip_addr = 32'hcccc_0000;
2048 flow.src_node.src_port = 20'h00001;
2049
2050 flow.dst_node.l2_addr = pkt_mac_da;
2051 flow.dst_node.tci = 16'hcb00;
2052 flow.dst_node.ip_addr = 32'h8888_0000;
2053 flow.dst_node.src_port = 20'h00001;
2054
2055 flow.tup.src_tcp_udp_port = 16'h1234;
2056 flow.tup.dst_tcp_udp_port = 16'hABCD;
2057
2058 // ###############################################################################################
2059 // frame_type[4:0] bit definitions for pkt_gen
2060 //
2061 // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt
2062 // | | | | |
2063 // | | | | |
2064 // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0]
2065 // ###############################################################################################
2066
2067 flow.frame.frame_type = 5'b00110;
2068 flow.frame.frame_class = CL_ARP; // This will be recognized as "L2 CLASS MATCH" by FFLP
2069 flow.frame.type = -1;
2070 flow.frame.class_mask = 0;
2071 flow.frame.class_funct = CLF_SRC;
2072 flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT;
2073 flow.frame.data_seed = 128;
2074
2075 flow.rx_param.rcv_isn = 32'hA5A5_F5F5;
2076 flow.fl_state.tcp_flags = 6'b00_0010;
2077 flow.flow_no = 0;
2078 }
2079 } // case
2080
2081 // Reverse mode should fill in the "modeled control header info" too
2082 ctl_fifo = FFLP_Model.predict_control_fifo(mac_id, flow);
2083 // convert ctl_fifo information to an 18B byte array, to send it to end checker
2084 if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK"))
2085 buf_18B = convert_cntl_fifo_to_byte_array(ctl_fifo);
2086
2087 } // else
2088
2089 // Before sending the packet, see if RX_DROP_PKT_CHECK is enabled.
2090 // If so, generate an ID on the mac SA so the checker can sort the packets.
2091 if(get_plus_arg (CHECK, "RX_DROP_PKT_CHECK")) {
2092 //id = packet_id[mac_id]++;
2093 //m = mac_id;
2094 //d = dma_reqd;
2095 //flow.src_node.l2_addr = {r,d,m,id};
2096 flow.src_node.l2_addr = pgIdgen.getMacSA(dma_reqd,mac_id);
2097 // Fill up variables for backward compatibility
2098 packet_id[mac_id] = flow.src_node.l2_addr[15:0];
2099 id = flow.src_node.l2_addr[15:0];
2100 m = flow.src_node.l2_addr[17:16];
2101 d = flow.src_node.l2_addr[23:18];
2102 printf("pkt_configurator::genPkt() Replaced MAC_SA with ID - 0x%x dma_num:%0d d, mac_id:%0d, id:%0d \n",
2103 flow.src_node.l2_addr, d, m, id);
2104 }
2105
2106 if(0 /*MAC_LOOP_BACK_MODE[mac_id]*/ /*CHANGETHIS*/) {
2107 SendPktForLoopBack(flow, data_length,dma_reqd,mac_id,last_packet);
2108 } else {
2109 // Now, the flow object is done, now create the RxToken object
2110 pack_gen[mac_id].pkt_gen(flow, data_length, 3, pgToken, O_WAIT_SEND);
2111 pack_gen[mac_id].display_db(pgToken.pack_db);
2112 RxToken.id=pgToken.gId;
2113 RxToken.pkt_length = data_length;
2114 RxToken.pgToken = new pgToken;
2115 RxToken.dma_num=dma_reqd;
2116 RxToken.port_num=mac_id;
2117 RxToken.last_packet=last_packet;
2118
2119 if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK"))
2120 RxToken.rx_cntl_hdr = buf_18B.object_copy();
2121
2122 mailbox_put(mbox_id.niu_rxpath_mb[mac_id],RxToken);
2123
2124 if (last_packet) {
2125
2126 // print all FFLP Error Status registers if this is the last_packet
2127 gen_pio_drv.pio_rd(FZC_FFLP_BASE_ADDRESS+20'h08000, rd_data, 0); // FFLP_VLAN_PAR_ERR Register
2128 printf ("FFLP_VLAN_PAR_ERR_REG[ERR] = %b\n", rd_data[31]);
2129 printf ("FFLP_VLAN_PAR_ERR_REG[MULTI_ERR] = %b\n", rd_data[30]);
2130 printf ("FFLP_VLAN_PAR_ERR_REG[ADDRESS] = 0x%h\n", rd_data[29:18]);
2131 printf ("FFLP_VLAN_PAR_ERR_REG[DATA] = 0x%h\n", rd_data[17:0]);
2132
2133 gen_pio_drv.pio_rd(FZC_FFLP_BASE_ADDRESS+20'h200d8, rd_data, 0); // FFLP_TCAM_ERR Register
2134 printf ("FFLP_TCAM_ERR[ERR] = %b\n", rd_data[31]);
2135 printf ("FFLP_TCAM_ERR[P_ECC] = %b\n", rd_data[30]);
2136 printf ("FFLP_TCAM_ERR[MULT] = %b\n", rd_data[29]);
2137 printf ("FFLP_TCAM_ERR[ADDR] = 0x%h\n", rd_data[23:16]);
2138 printf ("FFLP_TCAM_ERR[SYNDROME] = 0x%h\n", rd_data[15:0]);
2139
2140 // FFLP Functional path coverage Summary, done by FFLP Model.
2141 FFLP_Model.path_analysis.print_histogram_summary();
2142
2143 }
2144
2145 }
2146
2147}
2148
2149function bit [31:0] pkt_configurator::hash1_crc32(byte_array buf, integer len) {
2150 bit[31:0] val;
2151 integer i;
2152
2153 val = 32'hffffffff;
2154 i = 0;
2155 while (len--)
2156 {
2157 val = crc_table[(val ^ buf.val[i]) & 8'hff] ^ (val >> 8'h08);
2158 i++;
2159 }
2160 val = ~val;
2161 hash1_crc32 = val;
2162}
2163
2164function byte_array pkt_configurator::convert_cntl_fifo_to_byte_array (cntl_fifo ctl_fifo) {
2165integer i;
2166byte_array buf_tmp;
2167
2168 printf("port_num %h maccheck %h packet_class %h vlan %h llcsnap %h noport %h badip %h tcamhit %h tres %h tzfvld %h\n",
2169 ctl_fifo.port_num,ctl_fifo.maccheck,ctl_fifo.packet_class,ctl_fifo.vlan,ctl_fifo.llcsnap,ctl_fifo.noport,
2170 ctl_fifo.badip,ctl_fifo.tcamhit,ctl_fifo.tres,ctl_fifo.tzfvld);
2171
2172buf_tmp = new();
2173
2174 buf_tmp.val[0] = { ctl_fifo.port_num, // 7:6
2175 ctl_fifo.maccheck, // 5
2176 ctl_fifo.packet_class // 4:0
2177 };
2178 buf_tmp.val[1] = { ctl_fifo.vlan, // 7
2179 ctl_fifo.llcsnap, // 6
2180 ctl_fifo.noport, // 5
2181 ctl_fifo.badip, // 4
2182 ctl_fifo.tcamhit, // 3
2183 ctl_fifo.tres, // 2:1
2184 ctl_fifo.tzfvld // 0
2185 };
2186 for(i=2;i<18;i++)
2187 buf_tmp.val[i] = 0;
2188
2189 convert_cntl_fifo_to_byte_array = buf_tmp;
2190}
2191
2192
2193task pkt_configurator::SendPktForLoopBack(flow_desc flow, integer data_length,integer dma_num,integer mac_id, integer last_packet = 0 ) {
2194 CpktCfgLp pktCfgLp;
2195
2196
2197 pktCfgLp = new();
2198 pktCfgLp.flow = flow;
2199 pktCfgLp.rx_dma = dma_num;
2200 pktCfgLp.port_id = mac_id;
2201 pktCfgLp.last_packet = last_packet;
2202 pktCfgLp.data_length = data_length;
2203
2204 mailbox_put(mbox_id.niu_pktcfglp[mac_id],pktCfgLp);
2205
2206}