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


Tutorials



CONFIGURATION




Configuration class is a transctor. It is extention of rvm_xactor. This class genarates addresses to configure the dut 4 output ports.


CODE:CFG.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