Sign in

Learn

0/8
0/6
0/6
0/6

Practice

Know this already? Skip to the exercise: Bidirectional Pin Driver

Port Directions

Two sensor cards share one status wire. Sometimes card A drives it and sometimes card B does, and both cards can observe its level. What must A do before B starts driving the opposite value?

Port direction describes ownership, which is more than the direction an arrow points in a diagram.

Who drives an ordinary port?

DirectionInside this componentSurrounding design
InputReads the valueSupplies the driver
OutputSupplies the driverReads the value
BidirectionalMay drive or release, and may readFollows the same shared-wire contract

In ordinary RTL, an input is something you read, and assigning to it is a mistake. An output gets one owning driver, and reading it back does not create another.

The keywords are in, out, and inout. GHDL rejects an assignment to an input with a message such as port "line_i" can't be assigned. VHDL-2008 allows reading your own out port. Older code may use an internal signal or the older buffer mode instead.

Releasing a wire

High impedance, written Z, means this driver lets go of the wire. It says nothing about the wire itself, which does not become zero and may still be driven by someone else.

The example's line_driver uses this recipe:

line_io <= value_i when enable_i = '1' else 'Z';
seen_o  <= line_io;

Read the first line as “drive the chosen value while enabled; otherwise disconnect this driver.” The second line observes the shared wire, including whatever another card contributes. Conditional Assignment covers the selection syntax later.

The example declares line_io : inout std_logic, and std_logic resolves the contributions from multiple drivers into the value the simulation observes.

A handover on paper

For this push-pull interface a card can drive either zero or one, and the protocol allows only one enabled card at a time. Assume no pull-up or other driver in this paper trace:

IntervalA contributesB contributes
First1Z
SecondZZ
ThirdZ0

Work out the shared value and what A reads in each interval, then compare with the explanation below.

The shared sequence is 1, Z, 0, and A reads that same sequence, because releasing the wire does not stop it from listening. Driving zero during the middle interval would not count as releasing the wire.

Quick check

A clean value can hide a bug

Question 1 of 1

Electrical contention can stress real output drivers, so guarantee the handover in the design rather than waiting for an unknown waveform value to warn you. A real floating input also needs an appropriate electrical design; a pull-up can provide a defined released level where the interface permits it.

The example waveform

The read-only example connects two line_driver instances to status_line. Find A's release gap and then B's turn, and look at both enable signals and both seen_o outputs as well as the shared value. This waveform demonstrates deliberate turn-taking; it does not contain the overlapping-driver experiment above.

The push-pull rule does not carry over to every bus. On ordinary open-drain I2C, devices pull low or release, multiple low drivers can coexist, and the pull-up supplies the high level. NXP's I2C specification defines that electrical behavior, though you do not need its protocol details for this first ownership exercise.

Tri-State Buses develops arbitration and FPGA I/O implications. The next exercise practices this shared-pin interface.

Key Takeaways

  • Direction identifies who owns a driver and who reads its value.
  • Z releases one driver; the observed wire depends on all its drivers and pulls.
  • Check ownership directly. Neither a clean value nor an X is a complete diagnosis.
Loading editor...
No waveform is available for this example. You can continue with the lesson and example code.