具有多个驱动程序的 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
嵌套接口、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