OCX transmitter and receiver

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.

////////RECEIVER////////
module ocx_rx(
		input	port ocx_in,
		input	rst_n, clk,
		output	logic valid, error, 
		output	logic [511:0]data_out_512,
		output	logic [5:0]eop_ptr_6
	      );

logic [7:0] buffer[64];
logic [7:0] clk_count;
logic [6:0] data_count;


logic clk_count_en, clk_count_rst, data_count_en, data_count_rst, data_load, data_store, data_count_prst, clk_count_prst;
logic temp_error;

typedef enum {IDLE, RX, WAIT} 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
	clk_count_en	= 0;
	clk_count_rst	= 0;
	data_count_en	= 0;
	data_count_rst	= 0;
	data_load	= 0;
	data_store	= 0;
	eop_ptr_6	= 0;
	error		= 0;
	valid		= 0;
	data_count_prst	= 0;
	clk_count_prst	= 0;

	case(cur_state)
	IDLE: 
		begin
			temp_error	= 0;
			
			if(ocx_in.sop && ocx_in.valid && !ocx_in.eop)
			begin
				data_count_en	= 1;
				clk_count_en	= 1;
				data_store	= 1;
				next_state	= RX;
			end
			else
			begin
				clk_count_rst	= 1;
				data_count_rst	= 1;
				next_state	= IDLE;
			end
		end

	RX:
		begin
			if(!ocx_in.sop && !ocx_in.eop && ocx_in.valid && clk_count < 128 && data_count < 64 )
			begin
				data_count_en	= 1;
				clk_count_en	= 1;
				data_store	= 1;
				next_state	= RX;
			end
			else if(ocx_in.sop && !ocx_in.eop && ocx_in.valid && clk_count == 1 && data_count == 1 )
			begin
				data_count_en	= 1;
				clk_count_en	= 1;
				data_store	= 1;
				next_state	= RX;
			end
			else if(!ocx_in.sop && !ocx_in.eop && !ocx_in.valid && clk_count < 128 && data_count < 64 )
			begin
				data_count_en	= 0;
				clk_count_en	= 1;
				data_store	= 0;
				next_state	= RX;
			end
			else if(!ocx_in.sop && ocx_in.eop && ocx_in.valid )
			begin
				data_count_en	= 1;
				clk_count_en	= 1;
				data_store	= 1;
				next_state	= WAIT;
			end
			else
			begin
				if(valid)
				begin
					data_count_en	= 1;
					data_store	= 1;
				end
				clk_count_en	= 1;
				temp_error	= 1;
				next_state	= RX;
			end
		end	
			
	WAIT:
		begin
			if(ocx_in.sop && ocx_in.valid &&!ocx_in.eop )
			begin
				temp_error	= 1;
				data_count_prst	= 1;
				clk_count_prst	= 1;
				data_store	= 1;
				next_state	= RX;
			end
			else
			begin	
				clk_count_rst	= 1;
				data_count_rst	= 1;			
				data_load	= 1;
				eop_ptr_6	= data_count - 1;
				error		= temp_error;
				next_state	= IDLE;
				valid		= 1;
			end
		end
	endcase
end		

// clock counter
always_ff @ (posedge clk or negedge rst_n)
begin
	if(!rst_n || clk_count_rst)
	begin
		clk_count<=0;
	end
	else if(clk_count_prst)
			clk_count<=1;
	else
	begin
		clk_count<=clk_count;
		if(clk_count_en)
			clk_count<=clk_count+1;
	end
end

// data counter
always_ff @ (posedge clk or negedge rst_n)
begin
	if(!rst_n || data_count_rst)
	begin
		data_count	<=0;
	end
	else if(data_count_prst)
		data_count	<= 1;
	else
	begin
		data_count	<= data_count;
		if(data_count_en)
			data_count	<= data_count+1;	
	end
end

// data register
always_ff @(posedge clk or negedge rst_n)
begin
	if(!rst_n)
	begin
			buffer <= '{64{8'b0}};
	end
	else if(data_store && data_count_prst)
	begin
		buffer[0] <= ocx_in.data_8;
	end
	else if(data_store)
	begin
		buffer[data_count] <= ocx_in.data_8;
	end
end

always_comb
begin
	if(!rst_n)
	begin
		data_out_512=0;
	end
	else if(data_load)
	begin
		for(int i=0; i<data_count; i++)
		begin
			data_out_512 = {data_out_512,buffer*};
		end
	end
end
		
endmodule

/////TRANSMITTER/////
module ocx_tx(
		input	logic rst_n, clk,
		input	logic valid, 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

[i]In reply to sai ganesh:*