具有多个驱动程序的 tri1 的意外行为

Unexpected Behavior of tri1 with multiple driver

嵌套接口、tri1 网络和来自 class/module 的分配出现意外行为。

这是代码。


interface i2c ();
  tri1 sda;
  logic sda_out;

  assign sda = sda_out;
endinterface

interface dev ();
  i2c i();
endinterface

class a;
  virtual interface dev d;

  task run1();
    $display("@%0t : Entering run1 a", $time());
    d.i.sda_out = 1'b0;
    #2; 
    d.i.sda_out = 1'bz;
    #2;
    $display("@%0t : Leaving run1 a", $time());
  endtask
endclass

module b (inout x);
  logic y;

  assign x = y;

  initial begin
    #4;
    y = 1'bz;
    #2;
    y = 1'b0;
  end
endmodule

module temp();
  dev d();
  b b1 (d.i.sda);
  a a1 = new();


  initial begin
    a1.d = d;
    a1.run1();
  end

  always_comb
    $display ("@%0t : d.i.sda - %0b, d.i.sda_out - %0b", $time(), d.i.sda, d.i.sda_out);
endmodule

这是带有 b1 注释和未注释的输出。


// With b1 commented

@0 : Entering run1 a
@0 : d.i.sda - x, d.i.sda_out - 0
@0 : d.i.sda - 0, d.i.sda_out - 0
@2 : d.i.sda - 0, d.i.sda_out - z
@2 : d.i.sda - 1, d.i.sda_out - z
@4 : Leaving run1 a



// With b1 uncommented

@0 : Entering run1 a
@0 : d.i.sda - x, d.i.sda_out - 0
@2 : d.i.sda - x, d.i.sda_out - z
@4 : Leaving run1 a
@4 : d.i.sda - 1, d.i.sda_out - z
@6 : d.i.sda - 0, d.i.sda_out - z

既然 tri1 就像带上拉的电线,它不应该允许多个驱动器吗?

因为当 b1 取消注释时,sda 的赋值语句似乎不起作用。

y 是时间 0 的 X。直到 #4 才将其分配给 Z。 X 将引起总线争用。

在时间零时将 y 初始化为 Z 将解决争用。

initial begin
  y = 1'bz;
  #6;
  y = 1'b0;
end