Search code examples
verilogsystem-verilogsystem-verilog-assertions

Continuous Assignment of a net with Class member as driver


I have an interface net, which needs to be assigned with class member.

However, I am not sure, how to do this, as I have tried with always_comb, which passes in compilation, but still doesn't do continuous assignments. assign statement does not work.

interface analog ();
  bit [10:0] r;
endinterface

class abc;
  bit [10:0] t;
endclass

module temp();
  abc a1;

  analog a2 ();

  always_comb begin
    a2.r = a1.t;
  end

  initial begin
    a1 = new();
    a1.t = 10'd35;
    $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
    #1;
    a1.t = 10'd21;
    $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
    #1;
    a1.t = 10'd67;
    $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
  end
endmodule

// Result - 
a1.t - 35, a2.r - 0
a1.t - 21, a2.r - 35
a1.t - 67, a2.r - 35

As you can see that a2.r is only assigned once and no further assignments are done.

Is there any way to resolve this?


Solution

  • A couple of problems with this code.

    1. You have a race condition between the construction of a1 and its first reference. assign is not allowed because a null reference is likely
    2. The always_comb is sensitive to the class variable a1 changing, not any of its members.
    3. Your $display statements are placed so not to see the updated values of t.

    Try this:

    module temp();
      abc a1;
    
      analog a2 ();
    
      initial wait(a1 != null)
        forever begin
           a2.r = a1.t;
           @a1.t;
        end
    
      initial begin
        a1    = new();
        a1.t  = 10'd35;
        #1 $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
        a1.t = 10'd21;
        #1 $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
        a1.t = 10'd67;
        #1 $display("a1.t - %0d, a2.r - %0d", a1.t, a2.r);
      end
    endmodule