// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: pkt_configurator.vr // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ #include "pkt_configurator_defines.vri" #include "fflp_test_defines.vri" #include "ip_util.vrh" #include "rxc_class.vrh" #include "ip_ingress_db.vrh" #include "pcg_defines.vri" #include "pcg_types.vri" #include "pack_db.vrh" #include "flow_db.vrh" #include "flow_db_tasks.vrh" #include "pg_top_pp.vrh" #include "pc_top_pp.vrh" #include "pcg_token.vrh" #include "niu_byte_array.vrh" #include "fflp_model.vrh" #include "pgIdgen.vrh" #include "niu_lptoken.vrh" extern pg pack_gen[16]; extern mbox_class mbox_id; extern Crxc rxc_cl; extern hdl_task force_tcam_entry (bit [7:0] tcam_index, bit [199:0] tcam_key); class pkt_class_info { bit tcam_disc; bit tcam_sel; bit tcam_ipaddr; bit [4:0] pkt_class; task new(integer class_num){ tcam_disc = 0; tcam_sel = 0; tcam_ipaddr = 0; pkt_class = class_num; } } class flow_key { bit PORT; bit L2DA; bit VLAN; bit IPSA; bit IPDA; bit PROTO; bit [1:0] L4_0; bit [1:0] L4_1; task new(integer class_num){ PORT = 0; L2DA = 0; VLAN = 0; IPSA = 0; IPDA = 0; PROTO = 0; L4_0 = 0; L4_1 = 0; } } //extern setup_cam_ram_fcram_class tables_shadow; class pkt_configurator { integer pktgen_mbox_out; // to send the pkt info to pktgen integer total_tcam_entries; integer tcam_l2_rdc_tblnum; bit debug_en; bit force_lookup_hit; CpgIdgen pgIdgen; bit flow_from_test_en; bit [31:0] crc_table[256] = { 32'h00000000, 32'h77073096, 32'hee0e612c, 32'h990951ba, 32'h076dc419, 32'h706af48f, 32'he963a535, 32'h9e6495a3, 32'h0edb8832, 32'h79dcb8a4, 32'he0d5e91e, 32'h97d2d988, 32'h09b64c2b, 32'h7eb17cbd, 32'he7b82d07, 32'h90bf1d91, 32'h1db71064, 32'h6ab020f2, 32'hf3b97148, 32'h84be41de, 32'h1adad47d, 32'h6ddde4eb, 32'hf4d4b551, 32'h83d385c7, 32'h136c9856, 32'h646ba8c0, 32'hfd62f97a, 32'h8a65c9ec, 32'h14015c4f, 32'h63066cd9, 32'hfa0f3d63, 32'h8d080df5, 32'h3b6e20c8, 32'h4c69105e, 32'hd56041e4, 32'ha2677172, 32'h3c03e4d1, 32'h4b04d447, 32'hd20d85fd, 32'ha50ab56b, 32'h35b5a8fa, 32'h42b2986c, 32'hdbbbc9d6, 32'hacbcf940, 32'h32d86ce3, 32'h45df5c75, 32'hdcd60dcf, 32'habd13d59, 32'h26d930ac, 32'h51de003a, 32'hc8d75180, 32'hbfd06116, 32'h21b4f4b5, 32'h56b3c423, 32'hcfba9599, 32'hb8bda50f, 32'h2802b89e, 32'h5f058808, 32'hc60cd9b2, 32'hb10be924, 32'h2f6f7c87, 32'h58684c11, 32'hc1611dab, 32'hb6662d3d, 32'h76dc4190, 32'h01db7106, 32'h98d220bc, 32'hefd5102a, 32'h71b18589, 32'h06b6b51f, 32'h9fbfe4a5, 32'he8b8d433, 32'h7807c9a2, 32'h0f00f934, 32'h9609a88e, 32'he10e9818, 32'h7f6a0dbb, 32'h086d3d2d, 32'h91646c97, 32'he6635c01, 32'h6b6b51f4, 32'h1c6c6162, 32'h856530d8, 32'hf262004e, 32'h6c0695ed, 32'h1b01a57b, 32'h8208f4c1, 32'hf50fc457, 32'h65b0d9c6, 32'h12b7e950, 32'h8bbeb8ea, 32'hfcb9887c, 32'h62dd1ddf, 32'h15da2d49, 32'h8cd37cf3, 32'hfbd44c65, 32'h4db26158, 32'h3ab551ce, 32'ha3bc0074, 32'hd4bb30e2, 32'h4adfa541, 32'h3dd895d7, 32'ha4d1c46d, 32'hd3d6f4fb, 32'h4369e96a, 32'h346ed9fc, 32'had678846, 32'hda60b8d0, 32'h44042d73, 32'h33031de5, 32'haa0a4c5f, 32'hdd0d7cc9, 32'h5005713c, 32'h270241aa, 32'hbe0b1010, 32'hc90c2086, 32'h5768b525, 32'h206f85b3, 32'hb966d409, 32'hce61e49f, 32'h5edef90e, 32'h29d9c998, 32'hb0d09822, 32'hc7d7a8b4, 32'h59b33d17, 32'h2eb40d81, 32'hb7bd5c3b, 32'hc0ba6cad, 32'hedb88320, 32'h9abfb3b6, 32'h03b6e20c, 32'h74b1d29a, 32'head54739, 32'h9dd277af, 32'h04db2615, 32'h73dc1683, 32'he3630b12, 32'h94643b84, 32'h0d6d6a3e, 32'h7a6a5aa8, 32'he40ecf0b, 32'h9309ff9d, 32'h0a00ae27, 32'h7d079eb1, 32'hf00f9344, 32'h8708a3d2, 32'h1e01f268, 32'h6906c2fe, 32'hf762575d, 32'h806567cb, 32'h196c3671, 32'h6e6b06e7, 32'hfed41b76, 32'h89d32be0, 32'h10da7a5a, 32'h67dd4acc, 32'hf9b9df6f, 32'h8ebeeff9, 32'h17b7be43, 32'h60b08ed5, 32'hd6d6a3e8, 32'ha1d1937e, 32'h38d8c2c4, 32'h4fdff252, 32'hd1bb67f1, 32'ha6bc5767, 32'h3fb506dd, 32'h48b2364b, 32'hd80d2bda, 32'haf0a1b4c, 32'h36034af6, 32'h41047a60, 32'hdf60efc3, 32'ha867df55, 32'h316e8eef, 32'h4669be79, 32'hcb61b38c, 32'hbc66831a, 32'h256fd2a0, 32'h5268e236, 32'hcc0c7795, 32'hbb0b4703, 32'h220216b9, 32'h5505262f, 32'hc5ba3bbe, 32'hb2bd0b28, 32'h2bb45a92, 32'h5cb36a04, 32'hc2d7ffa7, 32'hb5d0cf31, 32'h2cd99e8b, 32'h5bdeae1d, 32'h9b64c2b0, 32'hec63f226, 32'h756aa39c, 32'h026d930a, 32'h9c0906a9, 32'heb0e363f, 32'h72076785, 32'h05005713, 32'h95bf4a82, 32'he2b87a14, 32'h7bb12bae, 32'h0cb61b38, 32'h92d28e9b, 32'he5d5be0d, 32'h7cdcefb7, 32'h0bdbdf21, 32'h86d3d2d4, 32'hf1d4e242, 32'h68ddb3f8, 32'h1fda836e, 32'h81be16cd, 32'hf6b9265b, 32'h6fb077e1, 32'h18b74777, 32'h88085ae6, 32'hff0f6a70, 32'h66063bca, 32'h11010b5c, 32'h8f659eff, 32'hf862ae69, 32'h616bffd3, 32'h166ccf45, 32'ha00ae278, 32'hd70dd2ee, 32'h4e048354, 32'h3903b3c2, 32'ha7672661, 32'hd06016f7, 32'h4969474d, 32'h3e6e77db, 32'haed16a4a, 32'hd9d65adc, 32'h40df0b66, 32'h37d83bf0, 32'ha9bcae53, 32'hdebb9ec5, 32'h47b2cf7f, 32'h30b5ffe9, 32'hbdbdf21c, 32'hcabac28a, 32'h53b39330, 32'h24b4a3a6, 32'hbad03605, 32'hcdd70693, 32'h54de5729, 32'h23d967bf, 32'hb3667a2e, 32'hc4614ab8, 32'h5d681b02, 32'h2a6f2b94, 32'hb40bbe37, 32'hc30c8ea1, 32'h5a05df1b, 32'h2d02ef8d }; bit [383:0] sample_flow_key [64]; // 16 sample flow keys which can result in a Hash1 // of all possible rdc offset values 0-15 bit [3:0] calculated_crc4bits [64]; // correspond to the hash1 crc[3:0] for all 16 flow keys bit[15:0] packet_id[4]; // packet id for all 4 ports bit [3:0] MAC_LOOP_BACK_MODE; // FOR MAC LOOP BACK CASE WITH PKTCFGRT //setup_cam_ram_fcram_class tables_shadow; setup_ip_db_class ip_db; fflp_model FFLP_Model; flow_key flow_key_shadow[10]; // shadow of tcam_key register for all 10 classes pkt_class_info pkt_class_shadow[10]; // shadow of tcam_key register for all 10 classes // only classes 8-17 are considered here task new() { integer ii; integer i,j; string init_loopback,temp_port; bit [31:0] loopback; //tables_shadow = new; debug_en = 1; force_lookup_hit = 0; total_tcam_entries = 0; if (get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP")) tcam_l2_rdc_tblnum = 0; else tcam_l2_rdc_tblnum = 0; ip_db = new; rxc_cl = new; pgIdgen = new(); rxc_cl.setup_ip_db_cl = new; for(ii=0;ii<10;ii++){ pkt_class_shadow[ii] = new(ii+8); flow_key_shadow[ii] = new(ii+8); } FFLP_Model = new; for(ii=0;ii<4;ii++){ packet_id[ii] = 0; } flow_from_test_en = 0; for(i=0;i<4;i++) { if(mbox_id.niu_pktcfglp[i] == -1) { mbox_id.niu_pktcfglp[i] = alloc(MAILBOX,0,1); } } if( get_plus_arg( CHECK, "MAC_LOOP_BACK=")) { loopback = get_plus_arg( STR, "MAC_LOOP_BACK="); init_loopback.bittostr(loopback); for (j=0; j=0;j--) { if (j === 63) { flow_keyb_tmp = flow_keyb[i]; } else { flow_keyb_tmp = flow_keyb_tmp; } shtol_h1poly = shtol_h1poly << 1; if (shtol_h1poly[32] ^ flow_keyb_tmp[j]) { shtol_h1poly = {1'b0,(shtol_h1poly[31:0] ^ H1_CRC_32C_POLY)}; } else { shtol_h1poly = {1'b0, shtol_h1poly[31:0]}; } } } calculate_H1_poly = shtol_h1poly[31:0]; printf("pkt_configurator::calculate_H1_poly() CALCULATED H1 HASH = %h.\n",calculate_H1_poly); } task pkt_configurator::setup_flow_keys(bit [1:0] mac_id) { bit [3:0] flow_key_vlan_valid; bit [47:0] flow_key_da_addr; bit [11:0] flow_key_tci; bit [127:0] flow_key_ipsrc_addr = 128'hff000000_00000000_00000000_33221100; bit [127:0] flow_key_ipdst_addr = 128'hff000000_00000000_00000000_66554400; bit [15:0] flow_key_L4_0 = 16'hbaba; bit [15:0] flow_key_L4_1 = 16'hcaca; bit [7:0] flow_key_protocol; bit [1:0] flow_key_port = mac_id; bit [31:0] hash1_crc; integer ii, TOT_MAC_DAs, start_index; case (mac_id) { 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; } 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; } 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; } 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; } default: { TOT_MAC_DAs = 0; start_index = 0; } } flow_key_tci = random() % 4096; // generate a random VLAN ID flow_key_da_addr = ip_db.mac_entry(start_index); if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_UDP")) // UDP flow_key_protocol = 17; else // TCP flow_key_protocol = 06; if (!get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_IPV6")) { // if ipv4, set the upper bits to 0 flow_key_ipsrc_addr = {96'h0, flow_key_ipsrc_addr[31:0]}; flow_key_ipdst_addr = {96'h0, flow_key_ipdst_addr[31:0]}; } if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED")) flow_key_vlan_valid = 4'b1111; else flow_key_vlan_valid = 4'b0000; for(ii=0;ii<16;ii++) { sample_flow_key[16*mac_id + ii] = {flow_key_vlan_valid, flow_key_da_addr + ii, flow_key_tci, flow_key_ipsrc_addr, flow_key_ipdst_addr, flow_key_L4_0, flow_key_L4_1, flow_key_protocol, flow_key_port, 22'h0}; if (debug_en) printf("sample_flow_key[%0d]=%h\n", 16*mac_id + ii, sample_flow_key[16*mac_id + ii]); hash1_crc = calculate_H1_poly(sample_flow_key[16*mac_id + ii]); calculated_crc4bits[16*mac_id + ii] = hash1_crc[3:0]; } } task pkt_configurator::configure_flow_key_classes() { bit [39:0] addr; bit [63:0] wr_data; // Scan FFLP (Khosrow's) run_args to find out FLOW_KEY info for all 12 classes (which fields go for Hash1) if (get_plus_arg (CHECK, "HOW_FLOW_IPORT_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport = get_plus_arg( HNUM, "HOW_FLOW_IPORT_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_DA_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr = get_plus_arg( HNUM, "HOW_FLOW_DA_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_VLAN_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan = get_plus_arg( HNUM, "HOW_FLOW_VLAN_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_IPSRC_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc = get_plus_arg( HNUM, "HOW_FLOW_IPSRC_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_IPDST_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst = get_plus_arg( HNUM, "HOW_FLOW_IPDST_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_PID_12HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid = get_plus_arg( HNUM, "HOW_FLOW_PID_12HEX="); if (get_plus_arg (CHECK, "HOW_FLOW_L40_24HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = get_plus_arg( HNUM, "HOW_FLOW_L40_24HEX="); else if (get_plus_arg (CHECK, "HOW_FLOW_L40_B1_B2")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = 24'haa_aaaa; else if (get_plus_arg (CHECK, "HOW_FLOW_L40_B5_B6")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40 = 24'hff_ffff; if (get_plus_arg (CHECK, "HOW_FLOW_L41_24HEX=")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = get_plus_arg( HNUM, "HOW_FLOW_L41_24HEX="); else if (get_plus_arg (CHECK, "HOW_FLOW_L41_B3_B4")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = 24'haa_aaaa; else if (get_plus_arg (CHECK, "HOW_FLOW_L41_B7_B8")) rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41 = 24'hff_ffff; addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_4; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[1:0], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[1:0]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_5; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[1], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[3:2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[3:2]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_6; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[2], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[5:4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[5:4]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_7; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[3], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[7:6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[7:6]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_8; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[4], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[9:8]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_9; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[5], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_A; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[6], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[13:12], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[13:12]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_B; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[7], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[15:14], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[15:14]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_C; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[8], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[17:16], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[17:16]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_D; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[9], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[19:18], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[19:18]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_E; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[10], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[21:20], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[21:20]}; fflp_util.fflp_pio_wrapper(addr, wr_data); addr = FFLP_FLOW_ADDRESS_RANGE + FFLP_HOW_FLOW_KEY_CLS_F; wr_data = {54'h0, rxc_cl.setup_cam_ram_fcram_cl.how_flow_iport[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_da_addr[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_vlan[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipsrc[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_ipdst[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_pid[11], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[23:22], rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[23:22]}; fflp_util.fflp_pio_wrapper(addr, wr_data); } task pkt_configurator::setup_macda_table(integer mac_id) { integer ii, tbl_num; integer total_loc; printf ("In pkt_configurator::setup_macda_table, mac_id=%0d\n", mac_id); case (mac_id) { 0,1: total_loc = 16; 2,3: total_loc = 8; default: printf("ERROR: There is no such mac_id as %0d\n", mac_id); } for(ii=0;ii=8) && (pkt_class<=11)) { syndrome[7:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[64:0]); syndrome[15:8] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[129:65]); } assoc_data = {22'h0,syndrome,assoc_data[25:0]}; // Always programming the associated data using regular PIO Writes fflp_util.pio_wr_tcam_asdata(cam_index, assoc_data); repeat(50) @(posedge CLOCK); // Update the assoc_data shadow in the FFLP Model FFLP_Model.update_tcam_assoc_data_shadow(cam_index, assoc_data); repeat(50) @(posedge CLOCK); } task pkt_configurator::setup_tcam(integer total_entries, integer path, (integer mode = 0), (bit overwrite_asdata_disc=0)) { bit [2:0] l2_rdc_tbl_num; bit [7:0] cam_addr; integer cam_addr_int; bit [3:0] cam_addr_4bit; bit [199:0] ipv4_cam_key, ipv6_cam_key, cam_lmask; bit [4:0] pkt_class; bit [63:0] addr, wr_data, assoc_data; bit [129:0] adata_cam_key; bit [15:0] syndrome; bit [3:0] asdata_parity_value; bit [11:0] zfid; bit [11:0] tcam_disc; bit v4_ecc_ck; bit asdata_disc; bit [1:0] tres; bit [4:0] asdata_offset; bit [2:0] asdata_rdctbl; bit zfvld; bit asdata_age; integer inc_offset; bit [3:0] suggested_cam_lat; bit [63:0] rd_data; if (get_plus_arg (CHECK, "TCAM_DISC_12HEX=")) tcam_disc = get_plus_arg( HNUM, "TCAM_DISC_12HEX="); else tcam_disc = 12'h000; // TCAM_KEY Registers programmed for classes 4->15 // For all 12 classes: DISC TSEL IPADDR program_tcam_key_reg(tcam_disc, 12'hfff, 12'h000); if (total_entries > MAX_CAM_ENTRIES) total_tcam_entries = MAX_CAM_ENTRIES; else total_tcam_entries = total_entries; if (get_plus_arg (CHECK, "PKT_CFG_TCAM_LOOKUP")) l2_rdc_tbl_num = 0; else l2_rdc_tbl_num = 0; inc_offset = 0; // change the CAM latency to 4 for both niu/neptune suggested_cam_lat = 4; gen_pio_drv.pio_rd(FFLP_ADDRESS_RANGE+FFLP_CONFIG, rd_data, 1'b0); printf ("pkt_configurator: Rewriting the default value of cam_latency(%0d) with %0d\n", rd_data[19:16], suggested_cam_lat); rd_data[19:16] = suggested_cam_lat; gen_pio_drv.pio_wr(FFLP_ADDRESS_RANGE+FFLP_CONFIG, rd_data); case (mode) { 0: { // mode=0 programs a mix of IPv4(5-tuple) and IPv6(4-tuple) entries for(cam_addr_int=0;cam_addr_int=8) && (pkt_class<=11)) { // Only IPv4 classes syndrome[7:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[64:0]); syndrome[15:8] = rxc_cl.setup_cam_ram_fcram_cl.calculate_ecc_syndrome (adata_cam_key[129:65]); } // If ECC Check is enabled, SYNDROME field has even parity (4bits) for the assoc_data[25:0] // Bit 0 for bits [7:0], bit 1 for [15:8], bit 2 for [23:16], bit 3 for [25:24] else { // if v4_ecc_ck=0 (OR) if it is IPv6 or L2 syndrome[3:0] = rxc_cl.setup_cam_ram_fcram_cl.calculate_asdata_parity (cam_addr,assoc_data); syndrome[15:4] = 0; } // corrupting tcam assoc data ECC if asked for if (get_plus_arg(CHECK, "PKT_CFG_ASDATA_ECC_ERR")) syndrome ^= random()%256; assoc_data = {22'h0,syndrome,zfid,v4_ecc_ck,asdata_disc,tres,asdata_rdctbl,asdata_offset,zfvld,asdata_age}; // If plus_arg +TCAM_FRONTDOOR is given, PIOs are done to TCAM key regs. Otherwise, backdoor loaded (NIU only) if (get_plus_arg (CHECK, "TCAM_FRONTDOOR")) { // PIO Writes into the RTL fflp_util.pio_wr_tcam_key(cam_addr, ipv4_cam_key, cam_lmask); repeat(50) @(posedge CLOCK); } else { force_tcam_entry(cam_addr, ipv4_cam_key); } // Update the tcam_key shadow in the FFLP Model FFLP_Model.update_tcam_key_shadow(cam_addr, ipv4_cam_key); // Always programming the associated data using regular PIO Writes fflp_util.pio_wr_tcam_asdata(cam_addr, assoc_data); // update the tcam_key/assoc_data shadow to be able to read quickly for searching rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_key[cam_addr] = ipv4_cam_key; rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_cam_lmask[cam_addr] = cam_lmask; rxc_cl.setup_cam_ram_fcram_cl.setup_ip_db_cl.ip_db[0].ip_cam.shadow_adata[cam_addr] = assoc_data; 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]); 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]); // Update the assoc_data shadow in the FFLP Model FFLP_Model.update_tcam_assoc_data_shadow(cam_addr, assoc_data); if(cam_addr%16 == 15) { l2_rdc_tbl_num++; } } } 1: { // mode=1 programs all entries with IPv4 5-tuple type entries } 2: { // mode=2 programs all entries with IPv6 4-tuple type entries } default: { } } /* // program the remaining entries with all 0s (so class=0, an invalid class) for(cam_addr=total_tcam_entries;cam_addr= 128) { randcase { 20:{ // IPV4, TCP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_TCP; } 10:{ // IPV4, UDP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_UDP; } 10:{ // IPV4, AH/ESP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_IP_SEC_AH; } 10:{ // IPV4, SCTP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_SCTP; } 10:{ // IPV6, TCP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_TCP_IP_V6; } 10:{ // IPV6, UDP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_UDP_IP_V6; } 10:{ // IPV6, AH/ESP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_IP_V6_SEC_AH; } 10:{ // IPV6, SCTP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_SCTP_IP_V6; } 10:{ // ARP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_ARP; } } } if (get_plus_arg(CHECK, "IP_FRAG_BUG_ERR")) { case (packet_id[mac_id]%3) { 0: { flow.frame.frame_class = CL_UDP_FRAG; flow.frame.frame_type = 5'b00010; } 1: { flow.frame.frame_class = CL_TCP_FRAG; flow.frame.frame_type = 5'b00010; } 2: { flow.frame.frame_class = CL_SCTP_FRAG; flow.frame.frame_type = 5'b00010; } } flow.frame.error_code = PG_CHKSUM_ERR; flow.frame.ip_frag = 16'h6000; } flow.frame.type = -1; flow.frame.class_mask = 0; flow.frame.class_funct = CLF_SRC; flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT; flow.frame.data_seed = 128; flow.rx_param.rcv_isn = 32'hA5A5_F5F5; flow.fl_state.tcp_flags = 6'b00_0010; flow.flow_no = 0; } 2: { // L3 CLASS MATCH CAM MATCH MAC RDC TBL NUMBER, RDC OFFSET=0 // First lookup the ZCP RDC table to findout which subtable+offset has the required DMA num zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd); // Then search the tcam associated data to find out which tcam entry has that rdc+offset tblnum = zcp_tblnum_offset/16; offset = zcp_tblnum_offset%16; tcam_entry = matching_tcam_entry(tblnum,offset); // choose a vlan id, all the entries should result in an RDC=l2_rdc_tbl_num pkt_vlan_id = random()%MAX_VLAN_ENTRIES; // choose one of 16 MAC_DAs randomly, all the mac_cntl_words should result in RDC=l2_rdc_tbl_num case (mac_id) { 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; } 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; } 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; } 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; } default: { TOT_MAC_DAs = 0; start_index = 0; } } printf("index %0d, TOT_MAC_DAs %0d, mac_id %0d \n", start_index+random()%TOT_MAC_DAs, TOT_MAC_DAs, mac_id); pkt_mac_da = ip_db.mac48_da[start_index+random()%TOT_MAC_DAs]; if (debug_en) printf ("zcp_entry=0x%h tblnum=%02d offset=%02d Port=%0d DA for pkt %h, vlan=%04d, tcam_key=%h\n", zcp_tblnum_offset, tblnum, offset, mac_id, pkt_mac_da, pkt_vlan_id, tcam_entry); // set the TYPE/LEN field to have "L3 CLASS MATCH" // ############################################################################################### // frame_type[4:0] bit definitions for pkt_gen // // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt // | | | | | // | | | | | // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0] // ############################################################################################### flow.src_node.l2_addr = 48'hde_f0_72_94_38_15; flow.src_node.tci = pkt_vlan_id; flow.src_node.src_port = 20'h00001; flow.dst_node.l2_addr = pkt_mac_da; flow.dst_node.tci = 16'hcb00; flow.dst_node.src_port = 20'h00001; if (debug_en) printf ("tcam_entry[CLASS]=%0d,", tcam_entry[TCAM_CLS_CODE]); case (tcam_entry[TCAM_CLS_CODE]){ 8,9,10,11: { flow.src_node.tos = tcam_entry[IPV4_CAM_TOS]; flow.src_node.ip_addr = tcam_entry[IPV4_CAM_IP_ADDR_SA]; flow.dst_node.ip_addr = tcam_entry[IPV4_CAM_IP_ADDR_DA]; flow.tup.src_tcp_udp_port = tcam_entry[IPV4_CAM_L4_SRC_PORT]; flow.tup.dst_tcp_udp_port = tcam_entry[IPV4_CAM_L4_DST_PORT]; } 12,13,14,15: { flow.src_node.tos = tcam_entry[IPV6_CAM_TOS]; if (pkt_class_shadow[tcam_entry[TCAM_CLS_CODE]].tcam_ipaddr) flow.src_node.ipv6_addr = tcam_entry[IPV6_CAM_IP_ADDR]; else flow.dst_node.ipv6_addr = tcam_entry[IPV6_CAM_IP_ADDR]; flow.tup.src_tcp_udp_port = tcam_entry[IPV6_CAM_L4_SRC_PORT]; flow.tup.dst_tcp_udp_port = tcam_entry[IPV6_CAM_L4_DST_PORT]; } } if (debug_en) 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", 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); case (tcam_entry[TCAM_CLS_CODE]){ 8:{ // IPV4, TCP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_TCP; } 9:{ // IPV4, UDP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_UDP; } 10:{ // IPV4, AH/ESP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_IP_SEC_AH; } 11:{ // IPV4, SCTP flow.frame.frame_type = 5'b00010; flow.frame.frame_class = CL_SCTP; } 12:{ // IPV6, TCP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_TCP_IP_V6; } 13:{ // IPV6, UDP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_UDP_IP_V6; } 14:{ // IPV6, AH/ESP flow.frame.frame_type = 5'b01010; flow.frame.frame_class = CL_IP_V6_SEC_AH; } 15:{ // IPV6, SCTP flow.frame.frame_type = 5'b01010; // flow.frame.frame_class = CL_SCTP_IP_V6; // Not defined in PKTGEN yet } default: { } } // If VLAN tag is asked for, generate a tagged packet from PKTGEN if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED")) flow.frame.frame_type[2] = 1; if (debug_en) printf ("flow.frame.frame_type=%h, flow.frame.frame_class=%h\n", flow.frame.frame_type,flow.frame.frame_class); flow.frame.type = -1; flow.frame.class_mask = 0; flow.frame.class_funct = CLF_SRC; flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT; flow.frame.data_seed = 128; flow.rx_param.rcv_isn = 32'hA5A5_F5F5; flow.fl_state.tcp_flags = 6'b00_0010; flow.flow_no = 0; } 3: { // L3 CLASS MATCH, NO CAM MATCH, MAC RDC TBL NUMBER, HASH1 RDC OFFSET // First lookup the ZCP RDC table to findout which subtable+offset has the required DMA num zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd); // Then search the tcam associated data to find out which tcam entry has that rdc+offset tblnum = zcp_tblnum_offset/16; offset = zcp_tblnum_offset%16; // find a matching flow key, given this rdc_offset flow_entry = find_matching_flow_key(offset); // VLAN id should match what's there in the flow_entry, to have a hash1_hit pkt_vlan_id = flow_entry[FLOW_KEY_VLAN_ID]; // pkt_mac_da pkt_mac_da = flow_entry[FLOW_KEY_MAC_DA]; 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); flow.src_node.l2_addr = 48'hde_f0_72_94_38_15; flow.src_node.tci = pkt_vlan_id; flow.src_node.src_port = flow_entry[63:48]; flow.dst_node.l2_addr = pkt_mac_da; flow.dst_node.tci = 16'hcb00; flow.dst_node.src_port = 20'h00001; if (debug_en) 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", 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); if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_UDP")) { flow.frame.frame_class = CL_UDP; if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10]==2'b10) flow.tup.src_tcp_udp_port = flow_entry[FLOW_KEY_L4_0]; //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[11:10]==2'b11) // flow.tup.udp_length = flow_entry[FLOW_KEY_L4_0]; if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b10) flow.tup.dst_tcp_udp_port = flow_entry[FLOW_KEY_L4_1]; //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b11) // flow.tup.udp_checksum = flow_entry[FLOW_KEY_L4_1]; } else { flow.frame.frame_class = CL_TCP; if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8]==2'b10) flow.tup.src_tcp_udp_port = flow_entry[FLOW_KEY_L4_0]; //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l40[9:8]==2'b11) // flow.tup.seq_num[31:16] = flow_entry[FLOW_KEY_L4_0]; if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b10) flow.tup.dst_tcp_udp_port = flow_entry[FLOW_KEY_L4_1]; //else if (rxc_cl.setup_cam_ram_fcram_cl.how_flow_l41[11:10]==2'b11) // flow.tup.seq_num[15:0] = flow_entry[FLOW_KEY_L4_1]; } // Take an option of IPv4 or IPv6 if (get_plus_arg (CHECK, "HASH_HIT_PKT_TYPE_IPV6")) { flow.frame.frame_type[3] = 1; // v6 flow.frame.frame_type[1] = 1; // IP flow.src_node.ipv6_addr = flow_entry[FLOW_KEY_IPV6_SA]; flow.dst_node.ipv6_addr = flow_entry[FLOW_KEY_IPV6_DA]; } else { flow.frame.frame_type[3] = 0; // v4 flow.frame.frame_type[1] = 1; // IP flow.src_node.ip_addr = flow_entry[FLOW_KEY_IPV4_SA]; flow.dst_node.ip_addr = flow_entry[FLOW_KEY_IPV4_DA]; } // If VLAN tag is asked for, generate a tagged packet from PKTGEN if (get_plus_arg (CHECK, "PKTS_VLAN_TAGGED")) flow.frame.frame_type[2] = 1; if (debug_en) printf ("flow.frame.frame_type=%h, flow.frame.frame_class=%h\n", flow.frame.frame_type,flow.frame.frame_class); if (debug_en) printf ("IPSA=%h,IPDA=%h, L4_0=%h, L4_1=%h\n", flow.src_node.ip_addr,flow.dst_node.ip_addr, flow.tup.src_tcp_udp_port, flow.tup.dst_tcp_udp_port); flow.frame.type = -1; flow.frame.class_mask = 0; flow.frame.class_funct = CLF_SRC; flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT; flow.frame.data_seed = 128+dma_reqd; flow.rx_param.rcv_isn = 32'hA5A5_F5F5; flow.fl_state.tcp_flags = 6'b00_0010; flow.flow_no = 0; } 9: { // First lookup the ZCP RDC table to findout which table has the required DMA num zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd); zcp_tblnum = zcp_tblnum_offset/16; pkt_vlan_id = find_vlan_id(zcp_tblnum, mac_id); case (mac_id) { 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; } 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; } 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; } 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; } default: { TOT_MAC_DAs = 0; start_index = 0; } } printf ("mac_index = %0d\n", start_index+random()%TOT_MAC_DAs); pkt_mac_da = ip_db.mac_entry(start_index+random()%TOT_MAC_DAs); if (debug_en) 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); // set the TYPE/LEN field to have "L3 CLASS MATCH" flow.src_node.l2_addr = 48'hde_f0_72_94_38_15; flow.src_node.tos = 8'hf5; flow.src_node.tci = {4'h0, pkt_vlan_id[11:0]}; flow.src_node.ip_addr = 32'hcccc_0000; flow.src_node.src_port = 20'h00001; flow.dst_node.l2_addr = pkt_mac_da; flow.dst_node.tci = 16'hcb00; flow.dst_node.ip_addr = 32'h8888_0000; flow.dst_node.src_port = 20'h00001; flow.tup.src_tcp_udp_port = 16'h1234; flow.tup.dst_tcp_udp_port = 16'hABCD; // ############################################################################################### // frame_type[4:0] bit definitions for pkt_gen // // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt // | | | | | // | | | | | // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0] // ############################################################################################### if (data_length < 128) { randcase { 30:{ // IPV4, TCP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_TCP; } 20:{ // IPV4, UDP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_UDP; } 20:{ // IPV4, AH/ESP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_IP_SEC_AH; } 20:{ // IPV4, SCTP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_SCTP; } 10:{ // ARP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_ARP; } } } else if (data_length >= 128) { randcase { 20:{ // IPV4, TCP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_TCP; } 10:{ // IPV4, UDP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_UDP; } 10:{ // IPV4, AH/ESP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_IP_SEC_AH; } 10:{ // IPV4, SCTP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_SCTP; } 10:{ // IPV6, TCP flow.frame.frame_type = 5'b01110; flow.frame.frame_class = CL_TCP_IP_V6; } 10:{ // IPV6, UDP flow.frame.frame_type = 5'b01110; flow.frame.frame_class = CL_UDP_IP_V6; } 10:{ // IPV6, AH/ESP flow.frame.frame_type = 5'b01110; flow.frame.frame_class = CL_IP_V6_SEC_AH; } 10:{ // IPV6, SCTP flow.frame.frame_type = 5'b01110; flow.frame.frame_class = CL_SCTP_IP_V6; } 10:{ // ARP flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_ARP; } } } flow.frame.type = -1; flow.frame.class_mask = 0; flow.frame.class_funct = CLF_SRC; flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT; flow.frame.data_seed = 128; flow.rx_param.rcv_isn = 32'hA5A5_F5F5; flow.fl_state.tcp_flags = 6'b00_0010; flow.flow_no = 0; } 10: { // First lookup the ZCP RDC table to findout which table has the required DMA num zcp_tblnum_offset = find_zcp_rdc_offset(dma_reqd); zcp_tblnum = zcp_tblnum_offset/16; pkt_vlan_id = find_vlan_id(zcp_tblnum, mac_id%2); case (mac_id) { 0: { TOT_MAC_DAs = MAX_DA_10G; start_index = 0; } 1: { TOT_MAC_DAs = MAX_DA_10G; start_index = 16; } 2: { TOT_MAC_DAs = MAX_DA_1G; start_index = 32; } 3: { TOT_MAC_DAs = MAX_DA_1G; start_index = 40; } default: { TOT_MAC_DAs = 0; start_index = 0; } } pkt_mac_da = ip_db.mac_entry(start_index+random()%TOT_MAC_DAs); if (debug_en) 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); // set the TYPE/LEN field to have "L3 CLASS MATCH" flow.src_node.l2_addr = 48'hde_f0_72_94_38_15; flow.src_node.tos = 8'hf5; flow.src_node.tci = {4'h0, pkt_vlan_id[11:0]}; flow.src_node.ip_addr = 32'hcccc_0000; flow.src_node.src_port = 20'h00001; flow.dst_node.l2_addr = pkt_mac_da; flow.dst_node.tci = 16'hcb00; flow.dst_node.ip_addr = 32'h8888_0000; flow.dst_node.src_port = 20'h00001; flow.tup.src_tcp_udp_port = 16'h1234; flow.tup.dst_tcp_udp_port = 16'hABCD; // ############################################################################################### // frame_type[4:0] bit definitions for pkt_gen // // Tunneling IPv4/IPv6(0/1) VLAN_Tagged IP_Packet LLC/SNAP_Pkt // | | | | | // | | | | | // frame_type[4] frame_type[3] frame_type[2] frame_type[1] frame_type[0] // ############################################################################################### flow.frame.frame_type = 5'b00110; flow.frame.frame_class = CL_ARP; // This will be recognized as "L2 CLASS MATCH" by FFLP flow.frame.type = -1; flow.frame.class_mask = 0; flow.frame.class_funct = CLF_SRC; flow.frame.data_type = DAT_SEQ |DAT_LEN_EXACT; flow.frame.data_seed = 128; flow.rx_param.rcv_isn = 32'hA5A5_F5F5; flow.fl_state.tcp_flags = 6'b00_0010; flow.flow_no = 0; } } // case // Reverse mode should fill in the "modeled control header info" too ctl_fifo = FFLP_Model.predict_control_fifo(mac_id, flow); // convert ctl_fifo information to an 18B byte array, to send it to end checker if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK")) buf_18B = convert_cntl_fifo_to_byte_array(ctl_fifo); } // else // Before sending the packet, see if RX_DROP_PKT_CHECK is enabled. // If so, generate an ID on the mac SA so the checker can sort the packets. if(get_plus_arg (CHECK, "RX_DROP_PKT_CHECK")) { //id = packet_id[mac_id]++; //m = mac_id; //d = dma_reqd; //flow.src_node.l2_addr = {r,d,m,id}; flow.src_node.l2_addr = pgIdgen.getMacSA(dma_reqd,mac_id); // Fill up variables for backward compatibility packet_id[mac_id] = flow.src_node.l2_addr[15:0]; id = flow.src_node.l2_addr[15:0]; m = flow.src_node.l2_addr[17:16]; d = flow.src_node.l2_addr[23:18]; printf("pkt_configurator::genPkt() Replaced MAC_SA with ID - 0x%x dma_num:%0d d, mac_id:%0d, id:%0d \n", flow.src_node.l2_addr, d, m, id); } if(0 /*MAC_LOOP_BACK_MODE[mac_id]*/ /*CHANGETHIS*/) { SendPktForLoopBack(flow, data_length,dma_reqd,mac_id,last_packet); } else { // Now, the flow object is done, now create the RxToken object pack_gen[mac_id].pkt_gen(flow, data_length, 3, pgToken, O_WAIT_SEND); pack_gen[mac_id].display_db(pgToken.pack_db); RxToken.id=pgToken.gId; RxToken.pkt_length = data_length; RxToken.pgToken = new pgToken; RxToken.dma_num=dma_reqd; RxToken.port_num=mac_id; RxToken.last_packet=last_packet; if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK")) RxToken.rx_cntl_hdr = buf_18B.object_copy(); mailbox_put(mbox_id.niu_rxpath_mb[mac_id],RxToken); if (last_packet) { // print all FFLP Error Status registers if this is the last_packet gen_pio_drv.pio_rd(FZC_FFLP_BASE_ADDRESS+20'h08000, rd_data, 0); // FFLP_VLAN_PAR_ERR Register printf ("FFLP_VLAN_PAR_ERR_REG[ERR] = %b\n", rd_data[31]); printf ("FFLP_VLAN_PAR_ERR_REG[MULTI_ERR] = %b\n", rd_data[30]); printf ("FFLP_VLAN_PAR_ERR_REG[ADDRESS] = 0x%h\n", rd_data[29:18]); printf ("FFLP_VLAN_PAR_ERR_REG[DATA] = 0x%h\n", rd_data[17:0]); gen_pio_drv.pio_rd(FZC_FFLP_BASE_ADDRESS+20'h200d8, rd_data, 0); // FFLP_TCAM_ERR Register printf ("FFLP_TCAM_ERR[ERR] = %b\n", rd_data[31]); printf ("FFLP_TCAM_ERR[P_ECC] = %b\n", rd_data[30]); printf ("FFLP_TCAM_ERR[MULT] = %b\n", rd_data[29]); printf ("FFLP_TCAM_ERR[ADDR] = 0x%h\n", rd_data[23:16]); printf ("FFLP_TCAM_ERR[SYNDROME] = 0x%h\n", rd_data[15:0]); // FFLP Functional path coverage Summary, done by FFLP Model. FFLP_Model.path_analysis.print_histogram_summary(); } } } function bit [31:0] pkt_configurator::hash1_crc32(byte_array buf, integer len) { bit[31:0] val; integer i; val = 32'hffffffff; i = 0; while (len--) { val = crc_table[(val ^ buf.val[i]) & 8'hff] ^ (val >> 8'h08); i++; } val = ~val; hash1_crc32 = val; } function byte_array pkt_configurator::convert_cntl_fifo_to_byte_array (cntl_fifo ctl_fifo) { integer i; byte_array buf_tmp; printf("port_num %h maccheck %h packet_class %h vlan %h llcsnap %h noport %h badip %h tcamhit %h tres %h tzfvld %h\n", ctl_fifo.port_num,ctl_fifo.maccheck,ctl_fifo.packet_class,ctl_fifo.vlan,ctl_fifo.llcsnap,ctl_fifo.noport, ctl_fifo.badip,ctl_fifo.tcamhit,ctl_fifo.tres,ctl_fifo.tzfvld); buf_tmp = new(); buf_tmp.val[0] = { ctl_fifo.port_num, // 7:6 ctl_fifo.maccheck, // 5 ctl_fifo.packet_class // 4:0 }; buf_tmp.val[1] = { ctl_fifo.vlan, // 7 ctl_fifo.llcsnap, // 6 ctl_fifo.noport, // 5 ctl_fifo.badip, // 4 ctl_fifo.tcamhit, // 3 ctl_fifo.tres, // 2:1 ctl_fifo.tzfvld // 0 }; for(i=2;i<18;i++) buf_tmp.val[i] = 0; convert_cntl_fifo_to_byte_array = buf_tmp; } task pkt_configurator::SendPktForLoopBack(flow_desc flow, integer data_length,integer dma_num,integer mac_id, integer last_packet = 0 ) { CpktCfgLp pktCfgLp; pktCfgLp = new(); pktCfgLp.flow = flow; pktCfgLp.rx_dma = dma_num; pktCfgLp.port_id = mac_id; pktCfgLp.last_packet = last_packet; pktCfgLp.data_length = data_length; mailbox_put(mbox_id.niu_pktcfglp[mac_id],pktCfgLp); }