I was wondering about the 'buffer' i/o option for entities in the VHDL language. I have found that my code is much cleaner if I use the 'buffer' option instead of 'out' in any circumstance where I want to act on the outgoing signal somewhere within the entity. I find that I can think of very few reasons to use 'out' ever and I'm tempted to just always use 'buffer' in every case. So, my question is, under what circumstances should I set my outputs as 'out' (even when that means I have to add an extra signal declaration and assignment) and when is it ok to use 'buffer'?

  • \$\begingroup\$ The only 2 problems with buffer are: (1) mixing out on one hierarchical level with buffer on another is disallowed (one way round; can't remember which!) and (2) Some tools produce reams of fussy but meaningless warnings about buffer (but still work anyway!). Buffer is absolutely fine. \$\endgroup\$
    – user16324
    Commented Jul 29, 2014 at 21:43
  • \$\begingroup\$ By "tempted to just always use 'buffer' in every case" do you mean to quit using out-mode ports completely, or only in the cases where you want to read their values from within the design entity? \$\endgroup\$
    – rick
    Commented Jul 30, 2014 at 4:37
  • 2
    \$\begingroup\$ I should also ask whether your tools support VHDL-2008, in which case you would be able to read out-mode ports without any problem. \$\endgroup\$
    – rick
    Commented Jul 30, 2014 at 4:38
  • 1
    \$\begingroup\$ Nobody uses buffer type in actual designs. Never seen it any SoCs. And on Fpgas, it is discouraged to use it. Xilinx, Altera both discourage its use for synthesis. \$\endgroup\$
    – Mitu Raj
    Commented Sep 6, 2021 at 5:08

2 Answers 2


One case, that probably doesn't apply, is if you're using a standard older than VHDL-2002. Before than, buffer could not connect directly to out. So in a hierarchical design, the signal path would need to be declared as a buffer on all levels. Also, when adhering to these older standards, some tools have problems synthesizing buffers correctly. They may or may not warn you about this.

These should no longer be an issue if you're using a newer standard. From the VHDL-2002 Standard:

a) For a formal port of mode in, the associated actual must be a port of mode in, inout, or buffer.

b) For a formal port of mode out, the associated actual must be a port of mode out, inout, or buffer.

c) For a formal port of mode inout, the associated actual must be a port of mode inout, or buffer.

d) For a formal port of mode buffer, the associated actual must be a port of mode out, inout, or buffer.

e) For a formal port of mode linkage, the associated actual may be a port of any mode.

I also often see advice stating that a buffer should never be tri-stated. If you need the ability to tri-state a bus, then you would need to use out. I could find no direct reference to how buffers handled tri-stating in the standard. But it is probably good advice to follow. Again, your tools may or may not complain if you attempt to synthesis a tri-stated buffer.

  • 1
    \$\begingroup\$ Additionally you could note that in the pre-2002 case a buffer can have at most one source. \$\endgroup\$
    – user8352
    Commented Jul 30, 2014 at 0:36
  • \$\begingroup\$ @DavidKoontz I actually had a similar statement in my answer to begin with, but took it out because I could find no explicit reference in the standard to allowing multiple drivers to a buffer. But that is also good information to have. \$\endgroup\$ Commented Jul 30, 2014 at 13:07

I'm not going to restate embedded.kyle's very nice answer, but I will clarify the "buffer should never be tri-stated" bit.

First, IEEE 1164 std_logic is a resolved version of std_ulogic which is just an enum with values of 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H' and '-'. Due to the way VHDL handles enums of chars you can get arrays of enums by using strings. TL;DL: VHDL does not treat IEEE types specially, synthesis tools might, but the standard does not.

Second, the tri-state signal has no special importance. It simply has a line in the resolution table (again defined by IEEE 1164, not VHDL) that corresponds more or less to the other values. The '-' uninitialized value together with 'Z' actually goes to 'X', but all other values just get maintained when combined with 'Z'.

Finally, taking those into account, what actually matter is whether the port is "read" into the inside context from the instantiating context. IN, INOUT and LINKAGE (not used in the port interface) do read values, BUFFER does not. What this means is that if you write a value to a buffer, it will not get resolved with external signals. So if you write a '1', something outside writes a '0', you will not see the 'X'. Similarly, writing a 'Z' to it will not grant you access to the external signal. In this sense you need to think of it either like a real buffer (in the sense that nothing that happens outside the circuit can get back through the buffer) or just think of it as programming instead of as a circuit and realize that BUFFER means that the signal goes out and allows reading inside but doesn't pull in from the outside.

From section 4.3.2:

The value of an object is said to be read when one of the following conditions is satisfied:

— When the object is evaluated, and also (indirectly) when the object is associated with an interfac eobject of the modes in, inout, or linkage

The value of an object is said to be updated when one of the following conditions is satisfied:

— When it is the target of an assignment, and also (indirectly) when the object is associated with an interface object of the modes out, buffer, inout, or linkage


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.