A tri-state driver is one which will output either HIGH, LOW or "nothing".
In some architectures, many different modules need to be able to put data onto (to drive) the same bus, at different times. Thus they all connect to the one common bus - but a set of control signals seek to ensure that only one of them is driving a signal at any one time.
In Verilog, this is modelled using different signal "strengths". There is a signal value: z, which is called "high-impedance". This basically means that a node is isolated, that is not driven. It is possible to assign this value to a net.
Normally if two values are simultaneously written to a net, the result is unknown: x; however, if a driven value is also assigned to the same net as a high-impedance value, the driven value will over-ride the z. This is the basis for the following tri-state driver:
module triDriver(bus, drive, value); inout [3:0] bus; input drive; input [3:0] value; assign #2 bus = (drive == 1) ? value : 4'bz; endmodule // triDriver
NOTE: the bus is a wire and is designated as an inout variable on the port declarations.
The following example shows the effect of several control combinations on three tri-state buffers:
module myTest; wire [3:0] bus; reg drive0, drive1, drive2; integer i; triDriver mod1 (bus, drive0, i[3:0]); triDriver mod2 (bus, drive1, 4'hf); triDriver mod3 (bus, drive2, 4'h0); initial begin for (i = 0; i < 12; i = i + 1) begin #5 {drive2, drive1, drive0} = i; #5 $display ($time," %b %b %d", i[2:0], bus, bus); end $finish; end // initial begin endmodule // myTest
10 000 zzzz z 20 001 0001 1 30 010 1111 15 40 011 xx11 X 50 100 0000 0 60 101 0x0x X 70 110 xxxx x 80 111 xxxx x 90 000 zzzz z 100 001 1001 9 110 010 1111 15 120 011 1x11 X