2009年2月24日星期二

SV中mailbox的使用

下面为学习mailbox写的一个简单的sv代码,主要功能是一方发送随机数量的packet,一方接收该packet,两者的channel使用mailbox来实现。在questasim 6.5版本上编译通过,仿真通不过,具体的原因是questasim对mailbox的内容要求为packed类型。在VCS 200812版本上编译通过,仿真通过。
program automatic test_mailbox;
timeunit 1ns;
timeprecision 1ps;
int run_for_n_pkt = 10;

class packet;
rand bit [3:0] addr;
rand bit [7:0] din;
rand reg [7:0] payload[];

function new();
endfunction

constraint pkt_ct {
addr dist {[0:3] :=40,[4:7] :=60};
din inside {[0:$]};
payload.size() inside {[2:4]};
foreach(payload[i])
payload[i] == i;
}
endclass

class tx_pkts;
string name;
int num_pkt;
packet tx_pkt;
mailbox tx_mbx;

function new(string name = "TXP" ,mailbox tx_mbx = null,int num_pkt);
this.name = name;
this.tx_mbx = tx_mbx;
if(num_pkt <= 0 )
this.num_pkt = 1;
else
this.num_pkt = num_pkt;
endfunction

function void display();
$display("tx_pkt name is %s",name);
endfunction

task send_pkts();
fork
for(int i=0 ; i< num_pkt ;i++)
begin
packet temp_pkt;
temp_pkt = new();
if(!(temp_pkt.randomize()))
begin
$display("%t : randomize failed,please check your svtb! :%m",$realtime);
$finish;
end
tx_mbx.put(temp_pkt);
$display("transmitting data at %t:\n",$realtime);
$display("addr = %4b ; din = %8b;",temp_pkt.addr,temp_pkt.din);
foreach(temp_pkt.payload[j])
$display("payload[%d] = %2h;",j,temp_pkt.payload[j]);
#3;
end
join_none
endtask
endclass

class rx_pkts;
event done;
string name;
int num_pkt;
packet rx_pkt;
mailbox rx_mbx;

function new(string name = "RXP",mailbox rx_mbx = null);
this.name = name;
this.rx_mbx = rx_mbx;
this.num_pkt = 0;
endfunction

task receive_pkts();
fork
while(1)
begin
packet temp_pkt;
rx_mbx.get(temp_pkt);
$display("receiving data at %t:\n",$realtime);
$display("addr = %4b ; din = %8b;",temp_pkt.addr,temp_pkt.din);
foreach(temp_pkt.payload[j])
$display("payload[%d] = %2h;",j,temp_pkt.payload[j]);
num_pkt++;
if(num_pkt >= run_for_n_pkt)
->done;
end
join_none
endtask
endclass

initial
begin
mailbox p_mbx;
tx_pkts txp;
rx_pkts rxp;
p_mbx = new();
txp = new("INTEL",p_mbx,run_for_n_pkt);
rxp = new("VIMICRO",p_mbx);
#10;
txp.send_pkts();
rxp.receive_pkts();
wait(rxp.done.triggered);
end

endprogram

没有评论: