Layered Testbench for convolutional encoder

Hi,
This is the verilog code for a convolutional encoder with constraint length=3 and code rate=1/2 where dff is the d flipflop that I have called in the code.

module conv_enc(clk,rst,ip,cw);
input clk,rst;
input ip;
wire c0,c1;
output [15:0]cw;

wire d1,d0;

dff u0(clk,rst,ip,d1);
dff u1(clk,rst,d1,d0);

assign c0=ip^d1^d0;
assign c1=ip^d0;
assign cw = {c0,c1};

endmodule

I have to write a system verilog layered testbench for the same.
This is the layered testbench code I have written but I’m not getting the correct values.

//------------------------------------------------------------------- 
//Transaction 
//------------------------------------------------------------------- 

class transaction;
  
  //declaring the transaction items
 
       rand bit ip;
       bit [15:0]cw;
       
  
  function void display(string name);
    $display("- %s ",name);
    $display("-ip = %b,- cw = %b",ip,cw);

  endfunction
endclass

//------------------------------------------------------------------- 
//Generator 
//-------------------------------------------------------------------  

class generator;   
  //declaring transaction class  
  rand transaction trans; 
 //repeat count, to specify number of items to generate 
  int  repeat_count; 
  //mailbox, to generate and send the packet to driver 
  mailbox gen2driv;  
  //event, to indicate the end of transaction generation 
  event ended;  

  //constructor   
  function new(mailbox gen2driv); 
    //getting the mailbox handle from env, in order to share the transaction packet between the generator and driver, the same mailbox is shared between both. 
    this.gen2driv = gen2driv; 
  endfunction 

  //main task, generates(create and randomizes) the repeat_count number of transaction packets and puts into mailbox 
  task main(); 
    repeat(repeat_count) begin 
      trans = new();       
      if(!trans.randomize())  
      $fatal("GEN::transaction randomization failed");
      trans.display("[ Generator ]"); 
      gen2driv.put(trans);
    end
    -> ended; //triggering indicates the end of generation
  endtask 
endclass 


//--------------------------------------------------------------------------------------- 
//Interface 
//---------------------------------------------------------------------------------------  

interface intf(input logic clk,rst);   

  //declaring the signals
  logic ip;
  logic [15:0]cw;
  logic valid;
endinterface 


//--------------------------------------------------------------------------------------- 
//Driver 
//--------------------------------------------------------------------------------------- 


  class driver;  


  int no_transactions;   
  
  virtual intf vif;
  mailbox gen2driv,driv2scb;
  
  function new(virtual intf vif,mailbox gen2driv,driv2scb);     
    this.vif = vif;   
    this.gen2driv = gen2driv; 
	   this.driv2scb = driv2scb;
  endfunction   

  
  task rst; 
    wait(vif.rst); 
    $display("[ DRIVER ] ----- Reset Started -----"); 
    vif.ip <= 0; 
    vif.valid <= 0;
    wait(!vif.rst); 
    $display("[ DRIVER ] ----- Reset Ended   -----"); 
  endtask   

  
  task main; 
    forever begin 
      transaction trans; 
      gen2driv.get(trans); 
      @(posedge vif.clk);
      vif.ip <= trans.ip;
      vif.valid <= 1;
      @(posedge vif.clk); 
      vif.valid <= 0;  
      trans.cw = vif.cw; 
      @(posedge vif.clk); 
      driv2scb.put(trans);
      trans.display("[ Driver ]"); 
	    no_transactions++;
      end
  endtask
endclass


//------------------------------------------------------------------------------ 
//Monitor 
//------------------------------------------------------------------------------ 

class monitor;   

  //creating virtual interface handle
  virtual intf vif;    

  //creating mailbox handle 
  mailbox mon2scb;

  //constructor 
  function new(virtual intf vif,mailbox mon2scb); 
    //getting the interface 
    this.vif = vif; 
    //getting the mailbox handles from  environment 
    this.mon2scb = mon2scb; 
    
  endfunction    

  //Samples the interface signal and send the sample packet to scoreboard 
  task main; 
    forever begin 
      transaction trans; 
      trans = new(); 
      
      @(posedge vif.clk);
      wait(vif.valid); 
      trans.ip = vif.ip;  
      
      @(posedge vif.clk); 
      trans.cw = vif.cw;   
      @(posedge vif.clk);
      mon2scb.put(trans); 
      trans.display("[ Monitor ]"); 
    end 
  endtask  
endclass 


//------------------------------------------------------------------------------------ 
//Scoreboard 
//------------------------------------------------------------------------------------  

class scoreboard; 
  mailbox mon2scb, driv2scb;   

  
  int no_transactions; 
  
   
  function new(mailbox mon2scb, driv2scb); 
    
  this.mon2scb = mon2scb; 
	this.driv2scb = driv2scb; 
  endfunction   

  
  task main; 
    transaction trans1,trans2; 
	forever begin 
		mon2scb.get(trans1); 
		driv2scb.get(trans2);
		$display("transaction No : %0d", no_transactions+1);
		if((no_transactions+1) == 8) begin
		  if (trans1.cw == trans2.cw)
		  //if (trans1.c1 == trans2.c1)
		    $display("Result is as Expected Driver to Scoreboard : %p, Monitor to Scoreboard : %p", trans1, trans2);
		  else
			 $error("Wrong Result.\n\tDriver to Scoreboard : %p, Monitor to Scoreboard : %p", trans1, trans2); 
			end
		no_transactions++;
		//trans.display("[ Scoreboard ]"); 
		 
    end 
  endtask
endclass


//---------------------------------------------------------------------------------------- 
// Environment 
//---------------------------------------------------------------------------------------- 

//`include "transaction.sv"
//`include "generator.sv"
//`include "driver.sv"
//`include "monitor.sv"
//`include "scoreboard.sv"

class environment;    

  //generator and driver instance 
  generator 	gen; 
  driver    	driv; 
  monitor   	mon; 
  scoreboard	scb;  

  //mailbox handle's 
  mailbox gen2driv; 
  mailbox mon2scb;
  mailbox driv2scb;   

  //virtual interface 
  virtual intf vif;   

  //constructor 
  function new(virtual intf vif); 
    //get the interface from test 
    this.vif = vif;     

    //creating the mailbox (Same handle will be shared across generator and driver) 
    gen2driv = new(); 
    mon2scb  = new();    
    driv2scb = new();
    
    //creating generator and driver 
    gen  = new(gen2driv); 
    driv = new(vif,gen2driv,driv2scb); 
    mon  = new(vif,mon2scb); 
    scb  = new(driv2scb,mon2scb);
  endfunction   

  // 
  task pre_test(); 
    driv.rst(); 
  endtask   

  task test(); 
    fork  
      gen.main();
      driv.main(); 
      mon.main(); 
      scb.main();
    join_any
  endtask    

  task post_test(); 
    wait(gen.ended.triggered);
    wait(gen.repeat_count == driv.no_transactions); 
    //Optional 
    wait(gen.repeat_count == scb.no_transactions); 
  endtask     

  //run task 
  task run; 
    pre_test(); 
    test(); 
    post_test(); 
      $finish; 
  endtask  
endclass

//------------------------------------------------------------------------------------ 
//Random test 
//------------------------------------------------------------------------------------ 
program test(intf i_intf);   

  //declaring environment instance 
  environment env;    

  initial begin 
    //creating environment 
    env = new(i_intf);     

    //setting the repeat count of generator as 8, means to generate 8 packets 
    env.gen.repeat_count = 8;    
    
     

    //calling run of env, it interns calls generator and driver main tasks. 
    env.run(); 
  end 
endprogram


//------------------------------------------------------------------------------- 
// testbench 
//------------------------------------------------------------------------------- 

module new_testb_top;  

  //clock and reset signal declaration 
  bit clk; 
  bit rst;   

  //clock generation 
  always #5 clk = ~clk;   

  //reset Generation 
  initial begin 
    rst = 1; 
    #5 rst =0; 
  end    

  //creatinng instance of interface, inorder to connect DUT and testcase 
  intf i_intf(clk,rst); 
   
  //Testcase instance, interface handle is passed to test as an argument 
  test t1(i_intf);   

  //DUT instance, interface signals are connected to the DUT ports 
  conv_enc DUT ( 
    .clk(i_intf.clk), 
    .rst(i_intf.rst),
    .ip(i_intf.ip),
    .cw(i_intf.cw)
   );   
endmodule

Thanks in advance

In reply to parvatinair:

Your design has 1 bit outputs for c0 and c1, yet your interface and transaction have 8 bits for c0 and c1. Which is correct?

In reply to cgales:

No, you’re right. It was a mistake. I have updated the modified codes. Please go through that one.

Thank you

In reply to parvatinair:

This is a lot of code to go through. And since you didn’t give us 100% of the code needed to run the example, it is difficult to help you. Also, it might help if you told us what the correct values are supposed to be versus what you are seeing.