blob: f477c2151375c2a75eeade186a888710adf0c53a [file] [log] [blame]
/******************************************************************************
* (C) Copyright 2014 AMIQ Consulting
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* NAME: amiq_eth_packet_jumbo.sv
* PROJECT: amiq_eth
* Description: This file declare the Jumbo Ethernet packet.
* Implementation is done based on: http://en.wikipedia.org/wiki/Jumbo_frame
* Jumbo packets are not supported by IEEE standards:
* SOURCE: http://www.ethernetalliance.org/wp-content/uploads/2011/10/EA-Ethernet-Jumbo-Frames-v0-1.pdf
* Furthermore, IEEE has determined they will not support or define Jumbo frames due to concerns around
* vendor and equipment interoperability.
*******************************************************************************/
`ifndef __AMIQ_ETH_PACKET_JUMBO
//protection against multiple includes
`define __AMIQ_ETH_PACKET_JUMBO
//Ethernet Jumbo packet
class amiq_eth_packet_jumbo extends amiq_eth_packet_ether_type;
`uvm_object_utils(amiq_eth_packet_jumbo)
//MAC Client Data Size
rand amiq_eth_jumbo_client_data_size client_data_size;
constraint client_data_size_c {
client_data_size >= `AMIQ_ETH_MIN_JUMBO_PAYLOAD_SIZE &&
client_data_size <= `AMIQ_ETH_MAX_JUMBO_PAYLOAD_SIZE;
}
//MAC Client Data
rand amiq_eth_data client_data[];
constraint client_data_c {
solve client_data_size before client_data;
client_data.size() == client_data_size;
}
//Frame Check Sequence
rand amiq_eth_fcs fcs;
//determine if to use the correct fcs or not
rand bit use_correct_fcs;
constraint use_correct_fcs_c {
use_correct_fcs == 1;
}
//flag to determine if to pack/unpack the fcs
local bit pack_fcs;
//flag to determine if to pack/unpack the client_data_size
local bit pack_client_data_size;
//constructor
//@param name - the name assigned to the instance of this class
function new(string name = "");
super.new(name);
ether_type = AMIQ_ETH_JUMBO_FRAMES;
pack_fcs = 1;
pack_client_data_size = 1;
endfunction
//pack fcs field
//@param packer - the packer used by this function
virtual function void do_pack_fcs(uvm_packer packer);
`uvm_pack_int(fcs);
endfunction
//unpack fcs field
//@param packer - the packer used by this function
virtual function void do_unpack_fcs(uvm_packer packer);
`uvm_unpack_int(fcs);
endfunction
//pack the entire Ethernet packet
//@param packer - the packer used by this function
virtual function void do_pack(uvm_packer packer);
super.do_pack(packer);
if(pack_client_data_size) begin
`uvm_pack_int(client_data_size)
end
for(int i = 0; i < client_data.size(); i++) begin
`uvm_pack_int(client_data[i]);
end
if(pack_fcs) begin
do_pack_fcs(packer);
end
endfunction
//unpack the entire Ethernet packet
//@param packer - the packer used by this function
virtual function void do_unpack(uvm_packer packer);
super.do_unpack(packer);
if(pack_client_data_size) begin
`uvm_unpack_int(client_data_size);
end
client_data = new[client_data_size];
for(int i = 0; i < client_data.size(); i++) begin
`uvm_unpack_int(client_data[i]);
end
if(pack_fcs) begin
do_unpack_fcs(packer);
end
if(ether_type != AMIQ_ETH_JUMBO_FRAMES) begin
`uvm_fatal("AMIQ_ETH", $sformatf("ether_type (%s) is different then AMIQ_ETH_JUMBO_FRAMES", ether_type.name()))
end
endfunction
function void post_randomize();
if(use_correct_fcs == 1) begin
fcs = get_correct_fcs();
end
endfunction
//converts the information containing in the instance of this class to an easy-to-read string
//@return easy-to-read string with the information contained in the instance of this class
virtual function string convert2string();
string fcs_info;
amiq_eth_fcs correct_fcs = get_correct_fcs();
if(correct_fcs == fcs) begin
fcs_info = $sformatf("FCS is correct");
end
else begin
fcs_info = $sformatf("FCS is wrong - expecting %X", correct_fcs);
end
return $sformatf("%s%sData Size: %0d%sFCS: %X, %s",
super.convert2string(), `AMIQ_ETH_FIELD_SEPARATOR,
client_data_size, `AMIQ_ETH_FIELD_SEPARATOR,
fcs, fcs_info);
endfunction
//function for packing the Ethernet packet into an UVM generic payload class
//@return an instance of the UVM generic payload containing the packed Ethernet packet
virtual function uvm_tlm_generic_payload to_generic_payload();
uvm_tlm_generic_payload result = super.to_generic_payload();
result.set_address(`AMIQ_ETH_PACKET_JUMBO_CODE);
return result;
endfunction
//compares the current class instance with the one provided as an argument
//@param rhs - Right Hand Side object
//@param comparer - The UVM comparer object used in evaluating this comparison - default is "null"
//@return 1 - objects are the same, 0 - objects are different
virtual function bit compare (uvm_object rhs, uvm_comparer comparer=null);
amiq_eth_packet_jumbo casted_rhs;
if(super.compare(rhs, comparer) == 0) begin
return 0;
end
if($cast(casted_rhs, rhs) == 0) begin
return 0;
end
if(client_data_size != casted_rhs.client_data_size) begin
return 0;
end
if(client_data.size() != casted_rhs.client_data.size()) begin
return 0;
end
for(int i = 0; i < client_data.size(); i++) begin
if(client_data[i] != casted_rhs.client_data[i]) begin
return 0;
end
end
if(fcs != casted_rhs.fcs) begin
return 0;
end
return 1;
endfunction
//function for packing the Ethernet packet using only the required information for computing the FCS
//@param bitstream - the packed bit stream is placed in "bitstream" parameter
virtual function void pack_for_fcs(ref bit bitstream[]);
bit current_pack_fcs = pack_fcs;
bit current_pack_client_data_size = pack_client_data_size;
pack_fcs = 0;
pack_client_data_size = 0;
super.pack_for_fcs(bitstream);
pack_fcs = current_pack_fcs;
pack_client_data_size = current_pack_client_data_size;
endfunction
//pack the Ethernet packet to a list of bytes in the format required by Wireshark software
//@param byte_data - array in which to put the packed information
virtual function void to_wireshark_array(ref byte unsigned byte_data[$]);
bit current_pack_client_data_size = pack_client_data_size;
pack_client_data_size = 0;
super.to_wireshark_array(byte_data);
pack_client_data_size = current_pack_client_data_size;
endfunction
endclass
`endif