verilogsystem-verilog

Why am I not getting output after pass through design in testbench module driver and monitor?


Here is my design and testbench environment code.

This is design module:

module router_1x3 (
    input wire clk,
    input wire rst,
    input wire [7:0] data_in,  // 8-bit data input
    input wire [1:0] sel,      // 2-bit select signal
    output reg [7:0] out0,     // Output channel 0
    output reg [7:0] out1,     // Output channel 1
    output reg [7:0] out2      // Output channel 2
);

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            out0 <= 8'b0; // Reset output 0
            out1 <= 8'b0; // Reset output 1
            out2 <= 8'b0; // Reset output 2
        end else begin
            case (sel)
                2'b00: begin
                    out0 <= data_in;
                    out1 <= 8'b0;
                    out2 <= 8'b0;
                end
                2'b01: begin
                    out0 <= 8'b0;
                    out1 <= data_in;
                    out2 <= 8'b0;
                end
                2'b10: begin
                    out0 <= 8'b0;
                    out1 <= 8'b0;
                    out2 <= data_in;
                end
                default: begin
                    out0 <= 8'b0;
                    out1 <= 8'b0;
                    out2 <= 8'b0;
                end
            endcase
        end
    end

endmodule

interface.sv

interface intf();
    logic clk;
    logic rst;
    logic [7:0] data_in;
    logic [1:0] sel;
    logic [7:0] out0;
    logic [7:0] out1;
    logic [7:0] out2;
endinterface

transaction.sv

class transaction;
  rand bit [7:0] data_in;
  rand bit [1:0] sel;
  bit [7:0] out0;
  bit [7:0] out1;
  bit [7:0] out2;
  
  constraint valid_sel {sel <= 2'b10;}
  
  function void display(string name);
    $display("---------- %s --------- %t", name, $time);
    $display("data_in=%h, sel=%h, out0=%h, out1=%h, out2=%h", 
             data_in, sel, out0, out1, out2);
  endfunction
endclass

generator.sv

class generator;
  
    transaction tx;
    mailbox gen2drv;
  
    // Constructor
    function new(mailbox gen2drv);
        this.gen2drv = gen2drv;
    endfunction

    task main();
        tx = new();
      if (tx.randomize()) begin
        tx.display("generator");
        gen2drv.put(tx);
        
        end
    endtask
endclass

driver.sv

class driver;
  transaction trans;
  virtual intf vif;
  
  mailbox gen2driv;
  
  function new(virtual intf vif, mailbox gen2driv);
    this.vif = vif;
    this.gen2driv = gen2driv;
  endfunction
  
  task main();
    
    repeat(1)
      begin
        
        gen2driv.get(trans);
        
        trans.display("Driver");
        
//         vif.data_in = trans.data_in;
//         vif.sel = trans.sel;
        
//         vif.out0 = trans.out0;
//      vif.out1 = trans.out1;
//         vif.out2 = trans.out2 ;
        
        vif.data_in <= trans.data_in;
        vif.sel <= trans.sel;
        
        vif.out0 <= trans.out0;
        vif.out1 <= trans.out1;
        vif.out2 <= trans.out2 ;
        
        
        
      end
  endtask
  
endclass

monitor.sv

class monitor;
  virtual intf vif;
  mailbox mon2sbc;
  transaction trans;
  function new(virtual intf vif, mailbox mon2sbc);
    this.vif = vif;
    this.mon2sbc = mon2sbc;
    
  endfunction
  
  task main();
    repeat(1)
      #3;
      begin
        
        trans = new();
        trans.data_in = vif.data_in;
        trans.sel = vif.sel;
        
//         trans.out0 = vif.out0;
//         trans.out1 = vif.out1;
//         trans.out2 = vif.out2;
        
         vif.out0 = trans.out0;
         vif.out1 = trans.out1;
         vif.out2 = trans.out2;
        
        
        mon2sbc.put(trans);
        #1
        trans.display("Monitor");
      end
  endtask
endclass

scoreboard.sv

class scoreboard;
   mailbox mon2sbc;
   transaction trans;
  function new(mailbox mon2sbc);
    this.mon2sbc = mon2sbc;
    
  endfunction
  
  task main();
    
    repeat(1)
      begin
        
        mon2sbc.get(trans);
        

        trans.display("Scoreboard");
        
          
      end
  endtask
   
endclass

environment.sv

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

class environment;// it's complete environment of dut
                    // which is contain all component of testbench and connect tham  
  generator gen;    
  driver driv;
  monitor mon;
  scoreboard scb;
  
  mailbox m1;
  mailbox m2;
  
  virtual intf vif;
  
  function new(virtual intf vif);
    this.vif = vif;
    
    m1 = new();
    m2 = new();
    gen = new(m1);
    driv = new(vif,m1);
    mon = new(vif, m2);
    scb = new(m2);
    
  endfunction
  
  task test();
    fork
      gen.main();
      driv.main();
      mon.main();
      scb.main();
      
    join_none
  endtask
  
  task run;
    test();
    #100
    $finish;
  endtask
  
endclass

test.sv

`include "environment.sv"

program test(intf i_intf);//this connect interface to testbech environment
  environment env;
  
  initial
  begin
    env = new(i_intf);
    env.run();
    
  end
endprogram

testbenchtop.sv

// Code your testbench here
// or browse Examples
`include "interface.sv"
`include "test.sv"

module tbench_top;
  intf router_vif();
  test t1(router_vif);
  
 router_1x3 dut (
        .clk(router_vif.clk),
        .rst(router_vif.rst),
        .data_in(router_vif.data_in),
        .sel(router_vif.sel),
        .out0(router_vif.out0),
        .out1(router_vif.out1),
        .out2(router_vif.out2)
    );

  
  // Clock generation
    initial begin
        router_vif.clk = 0;
        forever #5 router_vif.clk = ~router_vif.clk;
    end

    // Reset logic
    initial begin
        router_vif.rst = 1;
        #20;
        router_vif.rst = 0;
    end

  initial
    begin
      $dumpfile("dump.vcd");
      $dumpvars;
    end
  
endmodule
 

by running this code in eda (link of code: https://edaplayground.com/x/F7jS) i get following output

ERNEL: ASDB file was created in location /home/runner/dataset.asdb
# KERNEL: ---------- generator ---------                    0
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Driver ---------                    0
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Scoreboard ---------                    3
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Monitor ---------                    4
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# RUNTIME: Info: RUNTIME_0068 environment.sv (44): $finish called.

As I expected when monitor runs, out2=35, but it's not given.

Please suggest me something which I need to change in my code?


Solution

  • There are problems in the monitor.

      task main();
        repeat(1)
          #3;
    

    The first problem is the delay:

    #3;
    

    The main task starts running at time 0. The #3 delay advances time by 3 time units (3ns). That is when you construct the trans object in the monitor. When you look at waveforms, out2 is 0 at 3ns. You need to wait until out2 changes to 'h35 at time 25ns. You can do so by changing the delay to:

    #30ns;
    

    The second problem is that you commented out the code that samples the out2 signals from the interface. Since you never change the value of trans.out2, it remains at its default value of 0, no matter what the initial delay is.

    You need to uncomment these lines:

         trans.out0 = vif.out0;
         trans.out1 = vif.out1;
         trans.out2 = vif.out2;
    

    Another problem is that the monitor should not set interface signals. You should remove these lines from the monitor:

         vif.out0 = trans.out0;
         vif.out1 = trans.out1;
         vif.out2 = trans.out2;
    

    In the driver, you should not set the "out" signals in the interface. Delete these lines:

        vif.out0 <= trans.out0;
        vif.out1 <= trans.out1;
        vif.out2 <= trans.out2 ;
    

    This is the output I get, which shows out2=35:

    # KERNEL: ---------- Scoreboard ---------   30.000000 ns
    # KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=35
    # KERNEL: ---------- Monitor ---------   31.000000 ns
    # KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=35