In reply to bmorris:
okay… here it is…
this is interface...
interface UART_bfm;
int tx_counter;
int rx_counter;
int i;
logic [15:0] TX_REQ;
logic CLK;
logic reset;
logic WR;
logic [3:0] br_sel;
logic RD;
logic txclk;
logic rxclk;
logic ld_tx_data;
logic tx_enable;
logic rx_in;
logic uld_rx_data;
logic rx_enable;
logic [7:0] tx_data;
logic [2:0] R;
//output reg tx_full;
logic tx_empty;
//logic rx_full;
logic tx_fifo_empty;
logic tx_out;
logic tx_fifo_full;
logic [7:0] rx_data;
logic rx_fifo_empty;
logic rx_frame_err_out;
logic rx_over_run_out;
logic rx_busy_out;
logic tx_over_run_out;
logic [3:0] rx_cnt_out;
logic [39:0] RX_FIFO_DATA;
logic rx_fifo_full;
logic rx_empty;
logic [39:0] TX_FIFO_OUT;
logic [39:0] RX_FIFO_OUT;
initial begin
CLK = 1 ;
forever #5 CLK=~CLK; end
//*****************Test case1**********************
//RESET Operation
task reset_UART();
reset =1'b1;
ld_tx_data = 1'b0;
tx_data = 8'h00;
tx_enable = 1'b1;
uld_rx_data = 1'b0;
rx_enable = 1'b1;
#500;
reset =1'b0;
endtask : reset_UART
//*********************test case 2*************************
//basic operation of transmitting and receiving data
task TransmitData(input [0:7]itx_data,[0:15] iTX_REQ );
//BAsic OPeration TX
$display ("Basic Operation ");
br_sel = 2'b00;
WR = 0;
tx_data = itx_data;
TX_REQ = iTX_REQ;
#100;
WR = 1'b1;
#20;
WR = 1'b0;
RD = 1'b0;
#100;
wait (tx_empty == 1);
ld_tx_data = 1'b1;
wait (tx_empty == 0);
$display ($time," Data loaded for send.......lots of love you have reached here..");
ld_tx_data = 1'b0;
wait(tx_empty == 1);
$display ($time, "Data Sent... tx_data = %h", tx_data);
endtask:TransmitData
task ReceiveData( );
//RX UART
$display ("ReceiveData");
tx_enable = 1'b1;
wait (rx_empty == 1'b0);
$display ($time, "RX byte REady....");
uld_rx_data = 1'b1;
$display ($time, "RX byte unloaded.... %h", rx_data);
#100;
RD = 1; // this is not working
#100;
uld_rx_data = 1'b0;
RD = 0;
endtask :ReceiveData
//*********************test case 3*************************
//UART with TX reset//
task TX_UART_RESET(input bit[7:0] rand_tx_data,input bit[15:0] Tx_request);
begin
$display ("TX_UART_RESET");
br_sel = 2'b00;
tx_data = rand_tx_data;
TX_REQ = Tx_request;
#100;
WR = 1'b1;
#20;
WR = 1'b0;
RD = 1'b0;
#500;
ld_tx_data = 1;
reset = 1'b1;
#100;
reset = 1'b0;
ld_tx_data = 0;
$display ("Waiting for tx_empty to become 0");
for ( i=0; i<200; i++)
begin
$display ("after reaset, loading has failed .");
end
end
endtask
task RX_UART_WITH_RESET();
begin
$display ("RX_UART_WITH_RESET ");
tx_enable = 1'b1;
wait(rx_empty == 0);
$display ("RX Byte Ready");
uld_rx_data = 1;
#100;
reset = 1'b0;
for (int i=0; i<500; i++)
begin
$display ("after reaset, loading has failed .");
end
end
endtask
//DIFFERENT BAUD RATES
task TX_UART_BAUDRATES(input bit[7:0] rand_tx_data,input bit[15:0] TX_REQUEST, input [0:1] br_select);
begin
$display ("TX_UART_BAUDRATES ");
br_sel = br_select;
tx_data = rand_tx_data;
TX_REQ = TX_REQUEST;
#100;
WR = 1'b1;
#20;
WR = 1'b0;
RD = 1'b0;
#500;
wait(tx_empty == 1 ) ;
ld_tx_data = 1;
repeat(2) @(negedge txclk);
ld_tx_data = 0;
wait (tx_empty == 0);
$display ("data loaded for send..");
wait (tx_empty == 1);
$display ("Data Sent");
end
endtask;
task RX_UART_BAUDRATE();
begin
$display ("RX_UART_BAUDRATE ");
tx_enable = 1'b1;
wait (rx_empty ==0);
$display ("RX byte READy");
uld_rx_data = 1;
wait (rx_empty == 1);
$display ("RX BYTE UNLOADED... : %0h", rx_data);
#100;
RD = 1;
#100;
uld_rx_data = 0;
RD = 1'b0;
end
endtask
initial
begin
rxclk = 0;
txclk = 0;
tx_counter = 0;
rx_counter = 0;
end
always @(posedge CLK)
begin
if(br_sel == 2'b00)
begin
tx_counter = tx_counter+1;
if (tx_counter == 1)
begin
txclk <= ~txclk;
tx_counter <= 0;
end
rx_counter = rx_counter + 1;
if(rx_counter == 1)
begin
rxclk <= ~rxclk;
rx_counter <= 0;
end
end
else if(br_sel == 2'b01)
begin
tx_counter = tx_counter+1;
if (tx_counter == 2604)
begin
txclk <= ~txclk;
tx_counter <= 0;
end
rx_counter = rx_counter + 1;
if(rx_counter == 163)
begin
rxclk<= ~rxclk;
rx_counter <= 0;
end
end
else if(br_sel == 2'b10)
begin
tx_counter = tx_counter+1;
if (tx_counter == 1302)
begin
txclk <= ~txclk;
tx_counter <= 0;
end
rx_counter = rx_counter + 1;
if(rx_counter == 81)
begin
rxclk<= ~rxclk;
rx_counter <= 0;
end
end
else if(br_sel == 2'b11)
begin
tx_counter = tx_counter+1;
if (tx_counter == 434)
begin
txclk <= ~txclk;
tx_counter <= 0;
end
rx_counter = rx_counter + 1;
if(rx_counter == 27)
begin
rxclk<= ~rxclk;
rx_counter <= 0;
end
end
end
///////////////////
task transmit_uart_tx_full(input [0:7]itx_data,[0:15] iTX_REQ);
begin
bfm.tx_data=itx_data;
bfm.br_sel=2'b00;
bfm.TX_REQ=iTX_REQ;
#100;
bfm.WR =1'b1;
#20;
bfm.WR=1'b0;
bfm.RD=1'b0;
end
endtask
endinterface
here i am calling various tasks from bfm to execute, i want to run specific number of scoreboard tasks against each testcase/ task of my tester.
or you can say i want to run each testcase separately.
for eg i want task bfm.TransmitData(tx_data,TX_REQ) to run and then i want to check my scoreboard task named A and check status of signals. get the the test case result and then test another testcase/ task from tester.
class tester;
virtual UART_bfm bfm;
function new (virtual UART_bfm b);
bfm = b;
endfunction : new
protected function reg[0:7] get_data();
reg [0:7] transmit_data;
transmit_data = $random;
return transmit_data;
endfunction : get_data
protected function reg[0:1] RANDOMB_RATE();
reg [0:1] BAUD_RATE;
BAUD_RATE = $random;
return BAUD_RATE;
endfunction : RANDOMB_RATE
logic [0:7] tx_data;
logic [0:15] TX_REQ;
logic [0:1] Br_sel;
task execute();
bfm.reset_UART();
tx_data = get_data();
TX_REQ=16'h01;
bfm.TransmitData(tx_data,TX_REQ);
bfm.ReceiveData();
bfm.TX_UART_RESET(tx_data,TX_REQ);
bfm.RX_UART_WITH_RESET();
#100;
tx_data = get_data();
TX_REQ = 16'h03;
Br_sel = RANDOMB_RATE();
bfm.TX_UART_BAUDRATES(tx_data, TX_REQ, Br_sel);
bfm.RX_UART_BAUDRATE();
bfm.reset_UART();
endtask : execute
task FIFO_FULL();
begin
$display("Data started");
bfm.reset_UART();
TX_REQ = 16'h00;
for (int i = 0; i<20; i++)
begin
TX_REQ= TX_REQ+1'b1;
tx_data = get_data();
bfm.transmit_uart_tx_full(tx_data, TX_REQ);
end
end
endtask
endclass : tester
---------------------------------------------------------
class scoreboard;
virtual UART_bfm bfm;
function new(virtual UART_bfm b);
bfm = b;
endfunction : new
logic [0:7] sb_tx_data;
logic [0:7] sb_rx_data;
reg tx_par;
reg rx_par;
task execute();
forever begin @(bfm.uld_rx_data)
if (bfm.rx_data)
begin
tx_par = ~(bfm.tx_data[6] ^ bfm.tx_data[5] ^ bfm.tx_data[4] ^ bfm.tx_data[3] ^ bfm.tx_data[2] ^ bfm.tx_data[1] ^ bfm.tx_data[0]);
rx_par = ~(bfm.rx_data[6] ^ bfm.rx_data[5] ^ bfm.rx_data[4] ^ bfm.rx_data[3] ^ bfm.rx_data[2] ^ bfm.rx_data[1] ^ bfm.rx_data[0]);
if (rx_par == bfm.rx_data[7])
begin
$display(" %0d :PARITY CHECK : Good value of data received - CORRECT PARITY,%b, %b,%b ", $time, tx_par,bfm.tx_data[7],bfm.rx_data[7]);
end
if (bfm.tx_data == bfm.rx_data)
begin
$display ( "success:transmited_data : %0h, recieved_data : %0h",bfm.tx_data,bfm.rx_data);
end
else
$display ( "Failed:transmited_data : %0h, recieved_data : %0h",bfm.tx_data,bfm.rx_data);
end
end
forever begin @(bfm.uld_rx_data)
if (bfm.rx_data)
begin
tx_par = ~(bfm.tx_data[6] ^ bfm.tx_data[5] ^ bfm.tx_data[4] ^ bfm.tx_data[3] ^ bfm.tx_data[2] ^ bfm.tx_data[1] ^ bfm.tx_data[0]);
if (tx_par == bfm.tx_data[7])
begin
$display(" %0d :PARITY CHECK : Good value of data tramsmitted - CORRECT PARITY ",$time);
end
end
end
forever
begin @(bfm.txclk)
if (bfm.tx_empty==1)
begin
$display (" TRANSMITTER EMPTY ");
end
end
forever
begin @(bfm.rxclk)
if (bfm.rx_empty==1)
begin
$display ("RECEIVER EMPTY ");
end
end
endtask : execute
////////////////////////////SUB TAsks//////////////////////////////
task tx_rx();
$display("tc_rx execution started....");
forever begin @(bfm.ld_tx_data)
sb_tx_data=bfm.tx_data;
$display ("%0d :scoreboard : scoreboard recieved trasmitted data from driver :%b",$time,sb_tx_data);
sb_rx_data=bfm.rx_data;
$display(" %0d : Scorebooard : Scoreboard received transmitted data from driver:%b ",$time,sb_tx_data);
begin
if (bfm.tx_data == bfm.rx_data)
$display ( "success:transmited_data : %0h, recieved_data : %0h",bfm.tx_data,bfm.rx_data);
else
$display ( "Failed:transmited_data : %0h, recieved_data : %0h",bfm.tx_data,bfm.rx_data);
end
end
endtask : tx_rx
task tx_rx_empty();
$display ("rx_tx empty started");
forever
begin @(bfm.txclk)
if (bfm.tx_empty==1)
begin
$display (" TRANSMITTER EMPTY ");
end
end
forever
begin @(bfm.rxclk)
if (bfm.rx_empty==1)
begin
$display ("RECEIVER EMPTY ");
end
end
endtask:tx_rx_empty
task tx_rx_en ();
$display ("2 rx_tx empty started");
forever
begin @(bfm.txclk)
if(bfm.tx_enable==1)
begin
$display("TRANSMITTER ACTIVE");
end
end
forever
begin @(bfm.rxclk)
if (bfm.rx_enable==1)
begin
$display(" RECEIVER ACTIVE");
end
end
endtask :tx_rx_en
task tx_rx_full();
$display ("rx_tx full started");
forever
begin @(bfm.txclk)
if (bfm.tx_fifo_full==1)
begin
$display (" TRANSMITTER FULL ");
end
end
forever
begin @(bfm.rxclk)
if (bfm.rx_fifo_full==1)
begin
$display ("RECEIVER FULL ");
end
end
endtask:tx_rx_full
task FIFO_FULL_ERROR();
begin
if (bfm.tx_fifo_full==1)
begin
$display (" TRANSMITTER FULL ");
end
else
begin
$display (" TRANSMITTER NOT FULL ");
end
end
endtask
task fr_err();
//packet pkt_rcv,pkt_exp;
forever
begin
if(bfm.rx_frame_err_out == 1)
begin
$display(" %0d : FRAME ERROR : INCORRECT START AND STOP BITS !!!!!",$time);
end
end
endtask : fr_err
task tx_rx_overrun_err();
//packet pkt_rcv,pkt_exp;
forever
begin
if(bfm.tx_over_run_out == 1)
begin
$display(" %0d : OVERRUN ERROR : SLOW TRANSMIT FAST RECEIVE !!!!!",$time);
end
if(bfm.rx_over_run_out == 1)
begin
$display(" %0d : OVERRUN ERROR : FAST TRANSMIT SLOW RECEIVE !!!!!",$time);
end
end
endtask : tx_rx_overrun_err
task parity_chk();
//packet pkt_rcv,pkt_exp;
begin
if(bfm.ld_tx_data == 1)
begin
sb_tx_data = bfm.tx_data;
$display(" %0d : Scorebooard : Scoreboard received transmitted data from driver:%b ",$time,sb_tx_data);
tx_par = ~(sb_tx_data[6] ^ sb_tx_data[5] ^ sb_tx_data[4] ^ sb_tx_data[3] ^ sb_tx_data[2] ^ sb_tx_data[1] ^ sb_tx_data[0]);
if(tx_par == sb_tx_data[7])
$display(" %0d :PARITY CHECK : Good value of data tramsmitted - CORRECT PARITY ",$time);
else
$display(" %0d :PARITY CHECK : Bad value of data tramsmitted - INCORRECT PARITY",$time);
end
if(bfm.uld_rx_data == 1)
begin
sb_rx_data = bfm.rx_data;
$display(" %0d : Scorebooard : Scoreboard received a packet from receiver:%b ",$time,sb_rx_data);
rx_par = ~(sb_rx_data[6] ^ sb_rx_data[5] ^ sb_rx_data[4] ^ sb_rx_data[3] ^ sb_rx_data[2] ^ sb_rx_data[1] ^ sb_rx_data[0]);
if(rx_par == sb_rx_data[7])
$display(" %0d :PARITY CHECK : Good value of data received - CORRECT PARITY ",$time);
else
$display(" %0d :PARITY CHECK : Bad value of data received - INCORRECT PARITY ",$time);
end
end
endtask : parity_chk
endclass :scoreboard
------------------------------------------------------------------
`include "scoreboard.sv"
`include "tester.sv"
`include "coverage.sv"
class testbench_virtual;
virtual UART_bfm bfm;
tester tester_h;
scoreboard scoreboard_h;
coverage coverage_h;
function new (virtual UART_bfm b);
bfm = b;
endfunction : new
task TestCases();
begin
tester_h.FIFO_FULL();
scoreboard_h.FIFO_FULL_ERROR();
$display("NExt Test case");
basicOp();
end
endtask
task basicOp();
fork
tester_h.execute();
scoreboard_h.execute();
join_none
endtask
task execute();
tester_h = new(bfm);
scoreboard_h = new(bfm);
coverage_h = new(bfm);
fork
TestCases();
coverage_h.execute();
/*
tester_h.execute();
scoreboard_h.execute();
coverage_h.execute();
scoreboard_h.tx_rx();
scoreboard_h.tx_rx_empty();
scoreboard_h.tx_rx_full();
scoreboard_h.tx_rx_en();
*/
join_none
endtask : execute
endclass : testbench_virtual
i have written this testbench as of now to serially execute and check the status as some of the testcases run parallel with scoreboard and some serial with scoreboard.but i am confused to decide hwo the UART has to be tested.
DO i need to monitor all the signals ? if yes then how will kow if my tstecase has been failed or succeed coz all the scoreboard task would run in parallel hence difficult to determine which one has been passed which one doesnt if you think there is something wrong with the approach please suggest how can i do it. i am happy to post more details here.