Can any one tell me how to develop a testbench in system verilog for the below design of OCX transmitter and receiver with two interfaces for both receiver and transmitter and also tell me how to create a driver , generator, monitor and a scoreboard for this . I am providing a testbench also which i have designed but in that scoreboard comparing the same interface . Check and tell me how to rectify those errors
//Design
// Code your design here
`include "ocx_pkg.sv"
module ocx_tx(input logic rst_n, clk,
input logic valid,input logic error,
input logic [511:0]data_in_512,
input logic [5:0]eop_ptr_6,
output port ocx_out
);
logic [511:0] buffer[256];
logic [5:0] temp_ptr[256];
logic [7:0] ptr_count;
logic [6:0] data_count;
logic temp_error[256];
logic temp_valid[256];
logic data_count_en, data_count_rst, data_load, data_store, ptr_count_en, ptr_count_rst;
int i ;
typedef enum {IDLE,TX} state;
state cur_state, next_state;
always_ff @ (posedge clk or negedge rst_n)
if(!rst_n)
cur_state<=IDLE;
else
cur_state<=next_state;
always_comb
begin
data_count_en = 0;
data_count_rst = 0;
ptr_count_rst = 0;
ptr_count_en = 0;
data_load = 0;
data_store = 0;
ocx_out.sop = 0;
ocx_out.eop = 0;
ocx_out.valid = 0;
ocx_out.error = 0;
if(valid)
begin
data_store = 1;
ptr_count_en = 1;
end
case(cur_state)
IDLE:
begin
data_count_rst = 1;
if(i< ptr_count || i==0)
begin
if(ptr_count != 0)
next_state = TX;
else
next_state = IDLE;
end
else
begin
ptr_count_rst = 1;
next_state = IDLE;
i = 0;
end
end
TX:
begin
if(data_count <= temp_ptr[i])
begin
data_count_en = 1;
data_load = 1;
next_state = TX;
ocx_out.valid = temp_valid[i];
if(data_count == 0)
ocx_out.sop = 1;
if(data_count == temp_ptr[i])
begin
ocx_out.eop = 1;
ocx_out.error = temp_error[i];
end
end
else
begin
next_state = IDLE;
i++;
end
end
endcase
end
// data counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || data_count_rst)
begin
data_count <=0;
end
else
begin
data_count <= data_count;
if(data_count_en)
data_count <= data_count+1;
end
end
//ptr_counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || ptr_count_rst)
begin
ptr_count <=0;
end
else
begin
ptr_count <= ptr_count;
if(ptr_count_en)
ptr_count <= ptr_count+1;
end
end
// data register
always_ff @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
buffer <= '{256{0}};
temp_error <= '{256{0}};
temp_valid <= '{256{0}};
temp_ptr <= '{256{0}};
end
else if(data_store)
begin
temp_error[ptr_count] <= error;
temp_valid[ptr_count] <= valid;
temp_ptr[ptr_count] <= eop_ptr_6;
buffer[ptr_count] <= data_in_512;
end
end
always_comb
begin
ocx_out.data_8 <= 0;
if(data_load && data_count<=temp_ptr[i])
ocx_out.data_8 <= buffer[i] >> (8*data_count);
end
endmodule
//ocx_pkg.sv//
//
//
`ifndef DEFS_DONE // if the already-compiled flag is not set...
`define DEFS_DONE // set the flag
package definitions;
/*
ER -- error
ER_IN -- error because of input error pin
ER_SOP -- error because of SOP with out VALID
ER_EOP -- error because of SOP with out VALID
ER_LL -- error if packet length is less than 2
ER_GT -- error if packet length is greater than 64
ER_CYCLE -- error if number of clkcycles per packet is greater than 128
ER_GAP -- error if gap between the packet is less than 1
ER_ER -- error if error goes high without EOP & VALID*/
typedef enum {ER_IN, ER_SOP, ER_EOP, ER_LL, ER_GT, ER_CYCLE, ER_GAP, ER_ER} ER;
typedef struct {
logic sop,valid,eop,error;
logic [7:0]data_8;
} port;
endpackage
import definitions::*; // import package into $unit
`endif
///test bench
//`include "class2.sv"
//`include "class.sv"
`timescale 1ns/100ps;
`include "environment.sv"
module test_top;
bit clk, rst_n=0;
ocx_inter inter(clk, rst_n);
ocx_top top(inter.ocx_in, rst_n, clk, inter.ocx_out);
ocx_test tst(inter);
always #5 clk=~clk;
initial
begin
@(negedge clk)
#5rst_n=1;
inter.ocx_in.valid=1;
$monitor("sop=%d,valid=%d,eop=%d,data_in=%d,data_out=%d",inter.ocx_in.sop,inter.ocx_in.valid,inter.ocx_in.eop,inter.ocx_in.data_8,inter.ocx_out.data_8);
end
endmodule
program ocx_test(ocx_inter inter);
initial
begin
environment env= new(inter);
env.build();
env.run;
end
endprogram
interface ocx_inter(input clk, rst_n);
port ocx_in;
port ocx_out;
clocking cb @(posedge clk);
default input #10ns output #2ns;
input ocx_in;
output ocx_out;
endclocking
endinterface
//environment
`include "driver.sv"
`include "monitor.sv"
class environment;
virtual ocx_inter inter;
mailbox gen_seq, seq_drv;
mailbox mon_sb;
generator gen;
sequencer seq;
driver drv;
monitor mon;
scoreboard sb;
function new(virtual ocx_inter inter);
this.inter = inter;
endfunction
task build();
gen_seq = new();
seq_drv = new();
mon_sb = new();
mon_sb = new();
gen = new(gen_seq);
seq = new(gen_seq, seq_drv);
drv = new(seq_drv, inter);
mon = new(mon_sb,inter);:
sb = new(mon_sb,inter);
endtask
task run();
fork
gen.run();
seq.run();
drv.run();
mon.run();
sb.run();
join
endtask
endclass
//Driver, Generator, Sequencer//
class data_item;
rand bit sop,eop;
rand bit valid,error;
rand bit [7:0] data_8;
rand bit [6:0] length;
rand byte cycles;
constraint normal
{
length inside {[2:63]};
cycles <=128;
}
endclass
class driver;
virtual ocx_inter inter;
mailbox seq_drv;
data_item d_item;
function new( mailbox seq_drv, virtual ocx_inter inter);
this.seq_drv = seq_drv;
this.inter = inter;
this.d_item = d_item;
endfunction
task run();
forever
begin
while(!inter.rst_n)
begin
@(posedge inter.clk);
inter.ocx_in.sop = 0;
inter.ocx_in.valid = 0;
inter.ocx_in.eop = 0;
inter.ocx_in.error = 0;
inter.ocx_in.data_8 = 0;
end
begin
seq_drv.get(d_item);
@(posedge inter.clk);
inter.ocx_in.sop = d_item.sop;
inter.ocx_in.valid = d_item.valid;
inter.ocx_in.eop = d_item.eop;
inter.ocx_in.error = 0;//d_item.error;
inter.ocx_in.data_8 = d_item.data_8;
inter.ocx_out.data_8= d_item.data_8;
end
end
endtask
endclass
typedef enum {min_len,max_len,normal,max_cycles} test;
class states;
rand test case_variable;
endclass
class generator;
mailbox gen_seq;
states sta_item;
data_item d_item;
//sequencer seq;
function new(mailbox gen_seq);
this.gen_seq = gen_seq;
this.sta_item =sta_item;
this.d_item =d_item;
endfunction
task run();
begin
forever
begin
$display($time,"[GENARATOR]states genarator started");
sta_item = new();
if(sta_item.randomize())
begin
//assert(sta_item.randomize());
//sta_item.case_variable= min_len;
gen_seq.put(sta_item);
end
else
$display($time,"[GENARATOR]states genarator randomization fail");
#1;
end
end
endtask
endclass
class sequencer;
//`include "class.sv"
mailbox gen_seq, seq_drv;
data_item d_item;
states sta_item;
//driver drv;
function new( mailbox gen_seq, mailbox seq_drv);
this.gen_seq = gen_seq;
this.seq_drv = seq_drv;
this.d_item = d_item;
this.sta_item = sta_item;
endfunction
task run();
forever
begin
gen_seq.get(sta_item);
case(sta_item.case_variable)
min_len : begin
d_item = new();
assert(d_item.randomize());
d_item.sop = 1;
d_item.valid = 1;
d_item.eop = 0;
seq_drv.put(d_item);
/*$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);
d_item = new();
assert(d_item.randomize());
d_item.sop = 0;
d_item.valid = 1;
d_item.eop = 1;
seq_drv.put(d_item);
//$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);
d_item = new();
assert(d_item.randomize());
d_item.sop = 0;
d_item.valid = 0;
d_item.eop = 0;
seq_drv.put(d_item);
//$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);*/
end
max_len :begin
d_item =new();
assert(d_item.randomize());
d_item.sop=0;
d_item.valid=1;
d_item.eop=1;
seq_drv.put(d_item);
/*$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);
d_item=new();
assert(d_item.randomize());
d_item.sop=1;
d_item.valid=1;
d_item.eop=0;
seq_drv.put(d_item);
//$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);
d_item=new();
assert(d_item.randomize());
d_item.sop=0;
d_item.valid=0;
d_item.eop=0;
seq_drv.put(d_item);
//$display("d_item.sop=%d,d_item.valid=%d,d_item.eop=%d,d_item.data_8=%d",d_item.sop,d_item.valid,d_item.eop,d_item.data_8);*/
end
endcase
end
endtask
endclass
//monitor,scoreboard
class monitor;
mailbox mon_sb;
virtual interface ocx_inter inter;
function new (mailbox mon_sb ,virtual interface ocx_inter inter);
this.mon_sb=mon_sb;
this.inter=inter;
endfunction
task run;
data_item m_sb;
forever begin
@(posedge inter.clk);
m_sb = new();
m_sb.sop = inter.ocx_in.sop;
m_sb.eop = inter.ocx_in.eop;
m_sb.valid = inter.ocx_in.valid;
m_sb.data_8 = inter.ocx_in.data_8;
$display("monitor");
mon_sb.put(m_sb);
end
endtask
endclass
//
//
class scoreboard;
`include "ocx_pkg.sv"
int errors;
virtual ocx_inter inter;
mailbox mon_sb;
port temp;
function new( mailbox mon_sb, virtual ocx_inter inter);
this.inter=inter;
this.mon_sb=mon_sb;
errors=0;
endfunction: new
task run;
fork
dut_in;
mon_out;
join
endtask:run
task dut_in;
forever
begin
if(!inter.rst_n)
begin
temp.sop= 0;
temp.valid= 0;
temp.eop= 0;
temp.error= 0;
temp.data_8=0;
end
@(posedge inter.clk)
begin
temp.sop= inter.ocx_in.sop;
temp.valid= inter.ocx_in.valid;
temp.eop= inter.ocx_in.eop;
temp.error= inter.ocx_in.error;
temp.data_8=inter.ocx_in.data_8;
end
end
endtask:dut_in
task mon_out;
data_item hm;
forever
begin
if(!inter.rst_n)
begin
if(temp.sop==temp.valid==temp.eop==temp.error==temp.data_8== 0)
$display("data matched\n");
else
$display("fail\n");
end
@(posedge inter.clk)
mon_sb.get(hm);//data read from output of monitor
$display("score board------sop=%d,valid=%d,eop=%d,error=%d,data_8=%d\n",hm.sop,hm.valid,hm.eop,hm.error,hm.data_8);
if(temp.sop==hm.sop && temp.valid==hm.valid &&temp.eop==hm.eop && temp.error==hm.error && temp.data_8==hm.data_8)
$display("data matched\n");
else
errors++;
$display("errors=%d\n",errors);
end
endtask:mon_out
endclass:scoreboard
. It will help me a lot if any one help me thanks in advance.