When I started to write this, I wanted to ask how to model a bidirectional wire with transport delays but I've come up with a solution that works for my SDRAM sim so I'll post it here. I've done a fairly exhaustive search, and have found many instances of others posing this question, but no other definitive answers. Mr. Bromley, in a recent post, showed me how to model transport (not inertial) delays on unidirectional lines. I was initially able to, using two "wires" at the endpoints and a "reg" in the middle, simulate a tranport delay that worked in either direction, but the problem I kept encountering was this: the signal got "reflected" at the receiving end of the path and retransmitted, bouncing back and forth forever like a photon in a mirrored box. The Verilog "tran" primitive is not useful because it never incurs a delay across its two I/Os. I finally found a way to prevent the reflections that has the limitation described below. To model a bidirectional wire, just instantiate the module below, and the 'a' and 'b' ports correspond to the values at each end of a bidirectional wire with delay. The delay values are reals so that they can be changed during the sim; therefore you must 'force' them using the method described below. The delays can model PCB copper delays only, or, for RTL sims, can incorporate input/output pad delays, in which case the delays may be different in each direction. Here is the model: /***************************************************************** * module triwire: bidirectional wire bus model with delay * * This module models the two ends of a bidirectional bus with * transport (not inertial) delays in each direction. The * bus has a width of WIDTH and the delays are as follows: * a->b has a delay of Ta_b (in `timescale units) * b->a has a delay of Tb_a (in `timescale units) * The two delays will typically be the same. This model * overcomes the problem of "echoes" at the receiving end of the * wire by ensuring that data is only transmitted down the wire * when the received data is Z. That means that there may be * collisions resulting in X at the local end, but X's are not * transmitted to the other end, which is a limitation of the * model. Another compromise made in the interest of simulation * speed is that the bus is not treated as individual wires, so * a Z on any single wire may prevent data from being transmitted * on other wires. * * The delays are reals so that they may vary throughout the * course of a simulation. To change the delay, use the Verilog * force command. Here is an example instantiation template: * real Ta_b=1, Tb_a=1; always@(Ta_b) force triwire.Ta_b = Ta_b; always@(Tb_a) force triwire.Tb_a = Tb_a; triwire #(.WIDTH(WIDTH)) triwire (.a(a),.b(b)); * Kevin Neilson, Xilinx, 2007 *****************************************************************/ module triwire #(parameter WIDTH=8) (inout [WIDTH-1:0] a, b); real Ta_b=1, Tb_a=1; reg [WIDTH-1:0] a_dly = 'bz, b_dly = 'bz; always@(a) a_dly <= #(Ta_b) b_dly==={WIDTH{1'bz}} ? a : 'bz; always@(b) b_dly <= #(Tb_a) a_dly==={WIDTH{1'bz}} ? b : 'bz; assign b = a_dly, a = b_dly; endmodule
Verilog: Simulating Transport Delays on Bidirectional Tristate Lines
Started by ●February 16, 2007