|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



PACKET




In Vera terminology packets are called tranctions. Tranctions contains the physical data that are to be sent to dut. It also contains some more properties which help in building tranctions. Tranctions are built by extending rvm_data. rvm_data has set of standered methods like copy(),compare(),byte_pack(),byte_unp
ack() etc.


CODE:packet.vr
#ifndef PKT_CLASS
#define PKT_CLASS




// Data units shall be modeled as objects
class packet extends rvm_data {

enum payload_size_t = SMALL_P, MEDIUM_P, LARGE_P ;
enum packet_kind_t = GOOD_P, BAD_P ;
rand packet_kind_t packet_kind ;
rand payload_size_t payload_size;//Control field for the payload size


static rvm_log log = new("packet", "class");
string msg;

rand bit [7:0] len;
rand bit [7:0] da;
rand bit [7:0] sa;

rand bit [7:0] data[*];//Payload using Dynamic array,size is generated on the fly
rand bit [7:0] parity;
static bit [7:0] mem [4];

constraint addr_8bit {(da == mem[3])||(da == mem[0])||(da == mem[1])||(da == mem[2]);}

// Constrain the len according the payload_size control field
constraint len_size {
(payload_size == SMALL_P ) => len in { 5 : 6};
(payload_size == MEDIUM_P ) => len in { 7 : 8};
(payload_size == LARGE_P ) => len in {9 : 10}; }

// Constrain length of data == len
constraint data_size { data.size() ==len;}

constraint len_siz { solve len before data.size() ;}


// May be assigned either a good or bad value,parity will be calculated in portrandomize
constraint parity_type {
(packet_kind == GOOD_P ) => parity == 0;
(packet_kind == BAD_P ) => parity != 0;}




//All data object methods should be virtual
//All data object methods shall be nonblocking
task new();
task do_cfg(Configuration cfg);
virtual function string psdisplay(string prefix );
virtual function rvm_data copy(rvm_data to);
virtual function integer byte_unpack(bit [7:0] bytes[*],integer offset = 0,integer kind = -1);
virtual function bit[7:0] parity_cal();

virtual function bit compare(rvm_data to,var string diff,integer kind =-1);
virtual function integer byte_pack(var bit [7:0] bytes[*],
integer offset =0,
integer kind=-1);
task post_randomize();

}

task packet::new(){
super.new(this.log);
}

task packet::do_cfg(Configuration cfg){
this.mem[0]= cfg.da_port[0];
this.mem[1]= cfg.da_port[1];
this.mem[2]= cfg.da_port[2];
this.mem[3]= cfg.da_port[3];
msg = psprintf(" packet new %x %x %x %x",mem[0],mem[1],mem[2],mem[3]);
rvm_note(this.log,msg);
}


function string packet::psdisplay(string prefix = ""){
integer i;

sprintf(psdisplay,"%s packet #%0d.%0d.%0d\n", prefix,this.stream_id, this.scenario_id, this.object_id);
sprintf(psdisplay,"%s%s da:0x%h sa:0x%h len:0x%h \n", psdisplay, prefix,this.da,this.sa,this.len);
sprintf(psdisplay, "%s%s data:", psdisplay, prefix);
for (i = 0; i < this.len - 1; i++) sprintf(psdisplay,"%s data[%0d] 0x%h", psdisplay,i, data[i]);
}


function rvm_data packet::copy(rvm_data to = null){
packet cpy;

// Copying to a new instance?
if (to == null)
cpy = new;
else

// Copying to an existing instance. Correct type?
if (!cast_assign(cpy, to,CHECK))
{
rvm_fatal(this.log, "Attempting to copy to a non packet instance");
copy = null;
return;
}


super.copy_data(cpy);

cpy.da = this.da;
cpy.sa = this.sa;
cpy.len = this.len;
cpy.data = new[this.len];
foreach(cpy.data,i)
cpy.data[i] = this.data[i];

copy = cpy;
}



//unpacking function for converting recived data to class properties
function integer packet::byte_unpack(bit [7:0] bytes[*],integer offset ,integer kind){
sprintf(msg," bytes size %d",bytes.size());
da = bytes[1];
sa = bytes[2];
len = bytes[3];

sprintf(msg,"packet #%0d.%0d.%0d\n", this.stream_id, this.scenario_id, this.object_id);
sprintf(msg,"da:0x%h sa:0x%h len:0x%h \n", this.da,this.sa,this.len);
rvm_note(this.log,msg);
data = new [len - 4];
parity = bytes[bytes.size()-1];
foreach (data,i) data[i] = bytes[i+4];
}

function bit[7:0] packet::parity_cal(){
integer i;
bit[7:0] result ;
result = result ^ this.da;
result = result ^ this.sa;
result = result ^ this.len;
for (i = 0;i<this.len;i++)
{
result = result ^ this.data[i];
}
parity_cal = result;
}

//post randomize fun to cal parity
task packet::post_randomize(){
parity = parity ^ parity_cal();
sprintf(msg," %x %x %x %x",mem[0],mem[1],mem[2],mem[3]);
rvm_note(this.log,msg);
}


function bit packet::compare(rvm_data to,var string diff,integer kind){
packet cmp;

compare = 1; // Assume success by default.
diff = "No differences found";

if (!cast_assign(cmp, to,CHECK))
{ rvm_fatal(this.log, "Attempting to compare to a non packet instance");
compare = 0;
diff = "Cannot compare non packets";
return;
}

// data types are the same, do comparison:
if (this.da != cmp.da)
{
diff = psprintf("Different DA values: %b != %b", this.da, cmp.da);
compare = 0;
return;
}

if (this.sa != cmp.sa)
{
diff = psprintf("Different SA values: %b != %b", this.sa, cmp.sa);
compare = 0;
return;
}
if (this.len != cmp.len)
{
diff = psprintf("Different LEN values: %b != %b", this.len, cmp.len);
compare = 0;
return;
}

foreach(data,i)
if (this.data[i] != cmp.data[i])
{
diff = psprintf("Different data[%0d] values: 0x%h != 0x%h",i, this.data[i], cmp.data[i]);
compare = 0;
return;
}
if (this.parity != cmp.parity)
{
diff = psprintf("Different PARITY values: %b != %b", this.parity, cmp.parity);
compare = 0;
return;
}
}

function integer packet::byte_pack(var bit [7:0] bytes[*],integer offset ,integer kind){
byte_pack = 0;
bytes = new[this.len + 4];
bytes[0] = this.da;
bytes[1] = this.sa;
bytes[2] = this.len;
foreach(data,i)
bytes[3+i] = data[i];
bytes[this.len + 3 ] = parity;
byte_pack = this.len + 4;
}
#endif
Index
Introduction
Rtl
Top
Interface
Program Block
Environment
Packet
Configuration
Driver
Reciever
Scoreboard

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer