Commit | Line | Data |
---|---|---|
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 | ||
53 | extern pg pack_gen[16]; | |
54 | extern mbox_class mbox_id; | |
55 | extern Crxc rxc_cl; | |
56 | ||
57 | extern hdl_task force_tcam_entry (bit [7:0] tcam_index, bit [199:0] tcam_key); | |
58 | ||
59 | class 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 | ||
74 | class 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 | ||
98 | class 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 | ||
266 | task 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 | ||
278 | task 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 | ||
307 | task 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 | ||
319 | function bit [383:0] pkt_configurator::find_matching_flow_key(bit [3:0] rdc_offset) { | |
320 | integer 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 | ||
333 | function 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 | ||
377 | task 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 | ||
437 | task 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 | ||
616 | task pkt_configurator::setup_macda_table(integer mac_id) { | |
617 | integer ii, tbl_num; | |
618 | integer total_loc; | |
619 | ||
620 | printf ("In pkt_configurator::setup_macda_table, mac_id=%0d\n", mac_id); | |
621 | case (mac_id) { | |
622 | 0,1: total_loc = 16; | |
623 | 2,3: total_loc = 8; | |
624 | default: printf("ERROR: There is no such mac_id as %0d\n", mac_id); | |
625 | } | |
626 | ||
627 | for(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 | ||
637 | task 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 | ||
642 | task 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 | ||
738 | task pkt_configurator::setup_vlan_table((integer mode = 0)) { | |
739 | bit[2:0] rdctbl0,rdctbl1,rdctbl2,rdctbl3; | |
740 | bit parity0, parity1, vpr0, vpr1, vpr2, vpr3; | |
741 | integer i; | |
742 | bit[17:0] vlan_entry; | |
743 | bit[31:0] tmp; | |
744 | ||
745 | case (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 | ||
808 | task pkt_configurator::prog_vlan_entry(integer index, bit [17:0] vlan_entry, (bit backdoor = 0)) { | |
809 | bit parity0, parity1; | |
810 | bit [63:0] addr; | |
811 | bit [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 | ||
838 | function 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 | ||
858 | function bit [11:0] pkt_configurator::find_vlan_id(integer rdc_tbl_num, integer mac_id, (integer path = 9)) { | |
859 | integer i; | |
860 | bit [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 | ||
883 | function bit [199:0] pkt_configurator::matching_tcam_entry(bit [2:0] rdc_tbl_num, bit [3:0] rdc_tbl_offset) { | |
884 | ||
885 | bit [63:0] temp_assoc_data; | |
886 | integer 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 | ||
902 | function 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 | ||
948 | task pkt_configurator::program_tcam_key_reg(bit [11:0] tcam_disc, bit [11:0] tcam_tsel, bit[11:0] tcam_ipaddr) { | |
949 | bit [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 | ||
1003 | task 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}}; | |
1005 | bit [15:0] syndrome; | |
1006 | bit v4_ecc_ck; | |
1007 | bit [129:0] adata_cam_key; | |
1008 | bit [4:0] pkt_class; | |
1009 | bit [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 | ||
1050 | task pkt_configurator::setup_tcam(integer total_entries, integer path, (integer mode = 0), (bit overwrite_asdata_disc=0)) { | |
1051 | bit [2:0] l2_rdc_tbl_num; | |
1052 | bit [7:0] cam_addr; | |
1053 | integer cam_addr_int; | |
1054 | bit [3:0] cam_addr_4bit; | |
1055 | bit [199:0] ipv4_cam_key, ipv6_cam_key, cam_lmask; | |
1056 | bit [4:0] pkt_class; | |
1057 | bit [63:0] addr, wr_data, assoc_data; | |
1058 | bit [129:0] adata_cam_key; | |
1059 | bit [15:0] syndrome; | |
1060 | bit [3:0] asdata_parity_value; | |
1061 | bit [11:0] zfid; | |
1062 | bit [11:0] tcam_disc; | |
1063 | bit v4_ecc_ck; | |
1064 | bit asdata_disc; | |
1065 | bit [1:0] tres; | |
1066 | bit [4:0] asdata_offset; | |
1067 | bit [2:0] asdata_rdctbl; | |
1068 | bit zfvld; | |
1069 | bit asdata_age; | |
1070 | integer inc_offset; | |
1071 | bit [3:0] suggested_cam_lat; | |
1072 | bit [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 | ||
1083 | if (total_entries > MAX_CAM_ENTRIES) total_tcam_entries = MAX_CAM_ENTRIES; | |
1084 | else total_tcam_entries = total_entries; | |
1085 | ||
1086 | if (get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP")) | |
1087 | l2_rdc_tbl_num = 0; | |
1088 | else | |
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 | ||
1277 | function bit[199:0] pkt_configurator::get_tcam_mask(integer index) { | |
1278 | get_tcam_mask = FFLP_Model.tcam_mask[index]; | |
1279 | } | |
1280 | ||
1281 | function 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 | ||
1288 | function 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 | ||
1295 | task 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 | ||
1350 | task 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 | ||
1368 | task 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 | ||
1389 | task 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 | ||
1413 | task 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 | ||
1435 | task pkt_configurator::pkt_configurator_genPkt(integer path, integer data_length, integer dma_num, integer mac_id, integer last_packet, (flow_desc flow_in = null)) { | |
1436 | bit [11:0] pkt_vlan_id; | |
1437 | bit [47:0] pkt_mac_da; | |
1438 | integer zcp_tblnum_offset, zcp_tblnum; | |
1439 | bit [2:0] tblnum; | |
1440 | bit [3:0] offset; | |
1441 | integer dma_reqd; | |
1442 | integer pkt_path; | |
1443 | flow_desc flow; | |
1444 | bit [13:0] pkt_length; | |
1445 | CRxToken RxToken; | |
1446 | CpgToken pgToken; | |
1447 | bit [4:0] ret; | |
1448 | integer TOT_MAC_DAs; | |
1449 | integer start_index; | |
1450 | Cpkt_info pkt_info; | |
1451 | bit [199:0] tcam_entry; | |
1452 | bit [63:0] rd_data; | |
1453 | bit [383:0] flow_entry; | |
1454 | cntl_fifo ctl_fifo; | |
1455 | byte_array buf_18B; | |
1456 | bit[23:0] r; | |
1457 | bit[15:0] id; | |
1458 | bit[1:0] m; | |
1459 | bit[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 | ||
2149 | function 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 | ||
2164 | function byte_array pkt_configurator::convert_cntl_fifo_to_byte_array (cntl_fifo ctl_fifo) { | |
2165 | integer i; | |
2166 | byte_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 | ||
2172 | buf_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 | ||
2193 | task 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 | } |