// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: pcg_fa.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
// ========== Copyright Header End ============================================
task gen_buf( integer token, byte_array buf, var integer ptr ) {
integer len = -1; // L2 length byte pointer
integer he; // header end
integer tagged = 0; // Tagged frame
flow_id = pack_db[token].flow.flow_no;
buf.val[ptr++] = pack_db[token].ifedx_control[07:0];
buf.val[ptr++] = pack_db[token].ifedx_control[15:8];
da_tmp = pack_db[token].dst_node.l2_addr;
if( check_option( pack_db[token].options, O_USE_MAC_DA) ) {
shadow_class.get_data(addr + MAC_ADDR0, tmp32, mask, dv);
da_tmp[15:00] = tmp32[15:0];
shadow_class.get_data(addr + MAC_ADDR1, tmp32, mask, dv);
da_tmp[31:16] = tmp32[15:0];
shadow_class.get_data(addr + MAC_ADDR2, tmp32, mask, dv);
da_tmp[47:32] = tmp32[15:0];
if( check_option( pack_db[token].options, O_USE_FMAC_DA) ) {
0: da_tmp = shadow_class.mac_shadow_class.fmac0_addr;
1: da_tmp = shadow_class.mac_shadow_class.fmac1_addr;
2: da_tmp = shadow_class.mac_shadow_class.fmac2_addr;
3: da_tmp = shadow_class.mac_shadow_class.fmac3_addr;
pack_db[token].dst_node.l2_addr = da_tmp;
// L2 Header Assembley: Insertion of DA & SA
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = da_tmp;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.l2_addr;
// Check to see what kind of L2 pkt it is (802.3 or 802.Q)
if( pack_db[token].frame.frame_type[2] ) {
// It is a 802.Q Tagged packet
if( pack_db[token].frame.tpid != -1)
'{ buf.val[ptr++], buf.val[ptr++]} = pack_db[token].frame.tpid;
'{ buf.val[ptr++], buf.val[ptr++]} = TPID_8021Q;
'{ buf.val[ptr++], buf.val[ptr++]} = pack_db[token].src_node.tci;
// Check if L3/L4 Header should be appended to packet
if(pack_db[token].frame.frame_type[1] == 1) {
// L3 Header must be included
// Check if packet is is an LLC-SNAP L2 packet
if( pack_db[token].frame.frame_type[0] == 1) {
if( check_option( pack_db[token].options, O_CUSTOM_LS) ) {
tmp32 = cfg_reg[CFG_CUST_LS];
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++]} = tmp32[23:0];
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++]} = LLC_SNAP;
// SNAP values (last 2B comes from class value)
buf.val[ptr++] = H_UNDEF;
buf.val[ptr++] = H_UNDEF;
buf.val[ptr++] = H_UNDEF;
printf("pcg_fa.vr: frame class %d\n", pack_db[token].frame.frame_class);
// Convert frame class to IPv6 if necessary.
// (should not be a user defined class)
if( pack_db[token].frame.frame_type[3] == 1 &&
pack_db[token].frame.frame_type[4] == 0 &&
pack_db[token].frame.frame_class < CL_TCP_OPT )
pack_db[token].frame.frame_class += DELTA;
else if( pack_db[token].frame.frame_type[4] == 1 &&
pack_db[token].frame.tunnel_type[0] == 1 &&
pack_db[token].frame.frame_class < CL_TCP_OPT )
pack_db[token].frame.frame_class += DELTA;
printf("pcg_fa.vr: NEW frame class %d\n", pack_db[token].frame.frame_class);
// Check to see if tunneling option is present
if( pack_db[token].frame.frame_type[4]==1 ) {
printf("pcg_fa.vr: Tunneling option on, tunnel_type: %h \n", pack_db[token].frame.tunnel_type);
case( pack_db[token].frame.tunnel_type[1:0]){
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[CL_IP_TUN_V4_V4].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-14], buf.val[ptr-13]} = pack_db[token].frame.type;
// Insert custom TTL value into IP Header
if(pack_db[token].ttl != -1) buf.val[ptr-4] = pack_db[token].ttl;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ip_addr;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ip_addr;
printf("pcg_fa.vr: frame class %d\n", pack_db[token].frame.frame_class );
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-14], buf.val[ptr-13]} = pack_db[token].frame.type;
// Insert custom TTL value into IP Header
if(pack_db[token].ttl != -1) buf.val[ptr-4] = pack_db[token].ttl;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ip_addr;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ip_addr;
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[CL_IP_TUN_V4_V6].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-14], buf.val[ptr-13]} = pack_db[token].frame.type;
// Insert custom TTL value into IP Header
if(pack_db[token].ttl != -1) buf.val[ptr-4] = pack_db[token].ttl;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ip_addr;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ip_addr;
// Now Insert IPv6 Header
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-10], buf.val[ptr-9]} = pack_db[token].frame.type;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ipv6_addr;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ipv6_addr;
printf("pcg_fa.vr: Tuneling (IPv6/IPv4) doing IPv6\n");
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[CL_IP_TUN_V6_V4].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-10], buf.val[ptr-9]} = pack_db[token].frame.type;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ipv6_addr;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ipv6_addr;
printf("pcg_fa.vr: Tuneling (IPv6/IPv4) doing IPv4\n");
// Now Insert IPv4 Header
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-14], buf.val[ptr-13]} = pack_db[token].frame.type;
// Insert custom TTL value into IP Header
if(pack_db[token].ttl != -1) buf.val[ptr-4] = pack_db[token].ttl;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ip_addr;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ip_addr;
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[CL_IP_TUN_V6_V6].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-10], buf.val[ptr-9]} = pack_db[token].frame.type;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ipv6_addr;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ipv6_addr;
// Now Insert IPv6 Header
// Place packet frame type (L2) & first 12B of L3 Header
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-10], buf.val[ptr-9]} = pack_db[token].frame.type;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ipv6_addr;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ipv6_addr;
// check to see if regular L3 Header should be IPv4 or IPv6
else if( pack_db[token].frame.frame_type[3] == 0 ) {
printf("pcg_fa.vr: Building IPv4 packet \n");
// This is an IPv4 Packet
//Place packet frame type (L2) & first 12B of L3 Header//NVN-- 12 frm 14
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-14], buf.val[ptr-13]} = pack_db[token].frame.type;
// Insert custom TTL value into IP Header
if(pack_db[token].ttl != -1) buf.val[ptr-2] = pack_db[token].ttl;//NVN 2 frm 4
// Initaialize the IP checksum to "0"
'{buf.val[ptr++],buf.val[ptr++]} = 16'h0000;
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ip_addr;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ip_addr;
printf("The val of ptr is %d /n",ptr);
tmp16_ipck = ipv4_cksum(buf,ptr);
// '{buf.val[ptr-10],buf.val[ptr-9]} = 16'h1415;
'{buf.val[ptr-10],buf.val[ptr-9]} = tmp16_ipck;
else if ( pack_db[token].frame.frame_type[3] == 1 ) {
// This is an IPv6 Packet
printf("pcg_fa.vr: Bulding IPv6 Packet \n");
// Place packet frame type (L2) & first 12B of L3 Header//NVN
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
buf.val[ptr++] = class_mask( pack_db[token].frame.class_funct,
l3_class[pack_db[token].frame.frame_class].val[n],
l3_mask[pack_db[token].frame.class_mask].val[n] );
// Insert custom frame type value
if(pack_db[token].frame.type != -1)
'{buf.val[ptr-10], buf.val[ptr-9]} = pack_db[token].frame.type;
// Insert custom TTL value into Hop Limit of IPV6 Header
if(pack_db[token].ttl != -1) buf.val[ptr-1] = pack_db[token].ttl;//NVN
// Insert source/destination IP Addresses
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].src_node.ipv6_addr;
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].dst_node.ipv6_addr;
printf("pcg_fa.vr: Frame_class: %d\n" , pack_db[token].frame.frame_class );
if( pack_db[token].frame.frame_class == CL_UDP |
pack_db[token].frame.frame_class == CL_UDP_OPT |
pack_db[token].frame.frame_class == CL_UDP_FRAG |
pack_db[token].frame.frame_class == CL_UDP_IP_V6 |
pack_db[token].frame.frame_class == CL_UDP_OPT_IP_V6 |
pack_db[token].frame.frame_class == CL_UDP_FRAG_IP_V6 ) {
printf("pcg_fa.vr: Adding UDP Header \n");
udp_psu_hdr = {pack_db[token].src_node.ip_addr,
pack_db[token].dst_node.ip_addr,
// Insert source/destination port numbers
'{ buf.val[ptr++], buf.val[ptr++] } = pack_db[token].tup.src_tcp_udp_port;
'{ buf.val[ptr++], buf.val[ptr++] } = pack_db[token].tup.dst_tcp_udp_port;
tmp32 = cfg_reg[CFG_UDP_LEN];
'{ buf.val[ptr++], buf.val[ptr++] } = tmp32[15:0];
tmp32 = cfg_reg[CFG_UDP_CSM];
'{ buf.val[ptr++], buf.val[ptr++] } = tmp32[15:0];
else if ( pack_db[token].frame.frame_class == CL_TCP |
pack_db[token].frame.frame_class == CL_TCP_OPT |
pack_db[token].frame.frame_class == CL_TCP_FRAG |
pack_db[token].frame.frame_class == CL_TCP_IP_V6 |
pack_db[token].frame.frame_class == CL_TCP_OPT_IP_V6 |
pack_db[token].frame.frame_class == CL_TCP_FRAG_IP_V6 ) {
printf("pcg_fa.vr: Adding TCP Header \n");
tcp_psu_hdr = {pack_db[token].src_node.ip_addr,
pack_db[token].dst_node.ip_addr,
//tcp_hdr_start = ptr + 1;
// Insert source/destination port numbers
'{ buf.val[ptr++], buf.val[ptr++] } = pack_db[token].tup.src_tcp_udp_port;
'{ buf.val[ptr++], buf.val[ptr++] } = pack_db[token].tup.dst_tcp_udp_port;
if( pack_db[token].fl_state.tcp_flags == 2'h02 ) {
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = pack_db[token].rx_param.rcv_isn;
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = flow_db[flow_id].tx_param.last_seqno;
flow_db[flow_id].rx_param.rcv_isn = flow_db[flow_id].tx_param.last_seqno;
flow_db[flow_id].data_length = pack_db[token].data_length;
flow_db[flow_id].tx_param.last_seqno = {(flow_db[flow_id].rx_param.rcv_isn) + (flow_db[flow_id].data_length)};
'{ buf.val[ptr++], buf.val[ptr++],
buf.val[ptr++], buf.val[ptr++] } = cfg_reg[CFG_TCP_ACK];
tmp32[15:0] = {cfg_reg[CFG_TCP_LEN], 6'b000000, pack_db[token].fl_state.tcp_flags} ;
'{ buf.val[ptr++], buf.val[ptr++] } = tmp32[15:0];
tmp32 = cfg_reg[CFG_TCP_WIN];
'{ buf.val[ptr++], buf.val[ptr++] } = tmp32[15:0];
//tmp32 = cfg_reg[CFG_TCP_CSM];
'{ buf.val[ptr++], buf.val[ptr++] } = 16'h00;
tmp32 = cfg_reg[CFG_TCP_URG];
'{ buf.val[ptr++], buf.val[ptr++] } = tmp32[15:0];
} // end if( pack_db[token].frame.frame_type[1] == 1)
printf("pcg_fa.vr: No L3 header selected\n");
tcp_length = pack_db[token].data_length -he -4;
if(pack_db[token].frame.data_type != DAT_FC_PAUSE)
'{buf.val[ptr++], buf.val[ptr++]} = token;
data_gen( pack_db[token].frame.data_type,
pack_db[token].frame.data_seed,
pack_db[token].data_length,
buf, ptr, pack_db[token].options, this, tagged, INTER_FEDX);
// Insert Len value for L2 Header
if( check_option( pack_db[token].options, O_FRM_LEN_ERR1) )
'{buf.val[len], buf.val[len+1] } = cfg_reg[CFG_FRM_LEN];
if(pack_db[token].frame.type == -1) {
'{buf.val[len], buf.val[len+1] } = ptr - (he+1);
'{buf.val[len], buf.val[len+1] } = pack_db[token].frame.type;
printf("TCP hdr start is %d/n",tcp_hdr_start);
tmp16_tcpck = tcp_chksum(tcp_psu_hdr,buf,tcp_hdr_start,ptr);
'{buf.val[he-3],buf.val[he-2]} = tmp16_tcpck;
if(INTER_FEDX) pack_db_add_header(token,buf,2,he); // Start at byte 2 (skip control word)
else pack_db_add_header(token,buf,0,he); // Start at byte 0
tmp32 = crc_gen(buf, 2, ptr);
tmp32 = crc_gen(buf, 0, ptr);
if( check_option( pack_db[token].options, O_CRC_ERR) ) tmp32 = tmp32 ^ cfg_reg[CFG_CRC_MASK];
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = tmp32;
pack_db[token].pack_crc = tmp32;
tmp32 = crc_gen(buf, 0, ptr);
if( check_option( pack_db[token].options, O_IF_CRC_ERR) ) tmp32 = tmp32 ^ cfg_reg[CFG_CRC_MASK];
'{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = tmp32;
pack_db[token].ifedx_crc = tmp32;
pack_db[token].frame_len = ptr;
function bit [15:0] ipv4_cksum( byte_array m, integer len){
tmp[j] = {m.val[len-j], m.val[len-(j+1)]};
cksum = { tmp[19] + tmp[17] + tmp[15] + tmp[13] + tmp[11] + tmp[9] + tmp[7] + tmp[5] + tmp[3] + tmp[1]};
cksum = (cksum & 16'hFFFF) + ( cksum >> 16);
function bit [15:0] tcp_chksum( bit[95:0]psu_hdr,byte_array d, integer start, integer len){
printf("Starting TCP Chksum function \n");
for (i=start;i<len;i=i+2)
tmp[i] = {d.val[i],d.val[i+1]};
tcp_tmp[0] = psu_hdr[95:80];
tcp_tmp[1] = psu_hdr[79:64];
tcp_tmp[2] = psu_hdr[63:48];
tcp_tmp[3] = psu_hdr[47:32];
tcp_tmp[4] = psu_hdr[31:16];
tcp_tmp[5] = psu_hdr[15:0];
// sum_hdr += tcp_tmp[k];
sum_hdr = tcp_tmp[0] + tcp_tmp[1] + tcp_tmp[2] + tcp_tmp[3] + tcp_tmp[4] ;