VHDL includes an elaborate set of rules and language features to resolve situations in which the same signal is driven to multiple values simultaneously. These situations can be caused unintentionally (by an incomplete or incorrect design specification), or they may represent a desired circuit condition, such as a three-state driver connected to a bus, or they may represent a simple output enable used in a loadable bi-directional register.

 

To handle such situations, VHDL introduces the concept of a signal driver. A signal driver is a conceptual circuit that is created for every signal assignment in your circuit. By default, this conceptual circuit provides a comparison function to ensure that only one driver is active at any given time. The following architecture demonstrates a circuit description that does not meet this requirement:

 

architecture arch4 of nand_circuit is

    signal Sel, A, B: std_logic;

    signal Y: std_logic;

begin

    Y <= not (A and B) and Sel;

    Y <= not (A or B) and not Sel;

end arch4;

 

The intent of this circuit is to provide a single output (Y) that functions either as a NAND gate or as a NOR gate based on the value of Sel. Unfortunately, each of the two assignments results in a driver being created, resulting in a multiple-driver situation.

 

The solution to this, of course, is to completely specify the output Y using only one signal assignment, as in the following:

 

architecture arch4 of nand_circuit is

    signal Sel, A, B: std_logic;

    signal Y,Y1,Y2: std_logic;

begin

    Y1 <= not (A and B);

    Y2 <= not (A or B);

    Y <= Y1 and Sel or Y2 and not Sel;

end arch4;

 

In this example, two intermediate signals have been introduced (Y1 and Y2) and the output Y has been more completely described as a function of these two values. Another method might be to simply combine the three assignments into a larger combinational expression (not (A and B) and Sel or not (A or B) and not Sel) or to use a more concise statement such as a conditional assignment:

 

architecture arch5 of nand_circuit is

    signal Sel, A, B: std_logic;

    signal Y,Y1,Y2: std_logic;

begin

    Y <= not (A and B) when Sel = '1' else

            not (A or B);

end arch5;

 

Of course, these simple examples only show how you might resolve multiple driver situations that have been inadvertently created. You will find that VHDL's signal driver rules can actually help to detect and correct errors in your design that might otherwise go unnoticed. For situations that are intentional, however, how can you get around the rules?  The answer is a feature of VHDL called a resolution function. A resolution function is a special type of function that you (or someone else, such as the IEEE committee that defined the resolved type std_logic) can write to resolve multiple-driver situations for a specific type. For example, the resolution function for a four-value data type consisting of the values '1', '0', 'X' (unknown) and 'Z' (high impedance) might have a resolution function that specifies:

 

1)  that simultaneous values of '1' and '0' appearing on a signal's drivers will result in an 'X' value,

2)  that both 'Z' and 'X' can be over-ridden by values of '1' or '0', and

3)  that 'Z' is over-ridden by 'X'.

 

The section Objects, Data Types and Operators includes an example of a resolution function. That section also describes the concepts of signal drivers, resolved types and resolution functions in more detail. For most design descriptions and test benches, however, you will not need to use resolved types such as these. (In many synthesis tools, resolution functions are not supported anyway. They serve only to let the compiler know whether multiple drivers are allowed for an output.)