For example: IOs A and B are connected have a 10ns io-to-io delay between them. The IOs run at 500MHz (2ns period).
By default Verilog uses inertial delay which acts
Bidirectional transport delay can be achieved using driver strength with the two uni-directional transport delay. The model should assign the nets to a weaker drive strength the the IO drivers. This will give priority to the real driver and prevent driver conflict.
To prevent a feedback loop, use the drive strength as the qualifier to decide if the transport delay should assign the source value or high-Z. An easy way to determine the drive strength is with with %v
, see IEEE Std 1800-2012 § 21.2.1.5 Strength format
module bidi_delay #( parameter INERTIAL=0, TRANSPORT=10 ) (
inout a, b
);
reg a2b, b2a;
reg [23:0] a_strength, b_strength;
always @(a) begin
$sformat(a_strength, "%v", a);
a2b <= #(TRANSPORT) (a_strength[23:16] == "S") ? a : 1'bz;
end
always @(b) begin
$sformat(b_strength, "%v", b);
b2a <= #(TRANSPORT) (b_strength[23:16] == "S") ? b : 1'bz;
end
assign (weak0,weak1) #(INERTIAL) a = b2a;
assign (weak0,weak1) #(INERTIAL) b = a2b;
endmodule
Tested on EDAplayground with Aldec Riviera, Icarus Verilog, and GPL Cver