This section looks at the messages that result from attempting to synthesize the VHDL code from Section 10.2, “A 4-bit Multiplier.” The following examples use the line numbers that were assigned in the comments at the end of each line of code in Tables 10.1–10.9. The first problem arises in the following code (line 7 of the full adder in Table 10.1):
The synthesis tool cannot mimic the behavior of a default value on a port in the software model. The default value is the value given to an input if nothing is connected ( 'open' in VHDL). In hardware either an input is connected or it is not. If it is connected, there will be a voltage on the wire. If it is not connected, the node will be floating. Default values are useful in VHDL—without a default value on an input port, an entity–architecture pair will not compile. The default value may be omitted in this model because this input port is connected at the next higher level of hierarchy.
The next problem illustrates what happens when a designer fails to think like the hardware (from line 3 of the zero-detector in Table 10.6),
This code has the advantage of being flexible, but the synthesizer needs to know exactly how wide the bus will be. There are two other similar errors in shiftn, the variable-width shift register (from lines 4–5 in Table 10.7). There are also three more errors generated by the same problem in the component statement for AllZero (from lines 4–5 of package Mult_Components ) and the component statement for shiftn (from lines 10–11 of package Mult_Components ).
Table 12.8 shows the synthesizable version of the shift-register model. The constrained index ranges in lines 6 , 7 , 11 , 18 , 22 , and 23 fix the problem, but are rather ugly. It would be better to use generic parameters for the input and output bus widths. However, a shift register with different input and output widths is not that common so, for now, we will leave the code as it is.
The synthesis tool warns us it does not know how to generate hardware that writes to our screen to implement an assertion statement. The error occurs because a synthesis tool cannot support any of the passive statements (no assignments to signals, for example) that VHDL allows in an entity declaration. Synthesis software usually provides a way around these problems by providing switches to turn the synthesizer on and off. For example, we might be able to write the following:
The disadvantage of this approach is that the code now becomes tied to a particular synthesis tool. The alternative is to move the statement to the architecture to eliminate the error, and ignore the warning.
This error message is precise and uses the terminology of the LRM but does not reveal the source of the problem. To discover the problem we work backward through the model. We declared variable St as follows (lines 12–13 of Table 10.7):
The error is thus linked to the previous problem (undeclared bus widths) in this entity–architecture pair. Because the synthesizer does not know the width of Q , it does not know how many '0' s to put in St when it has to implement St := (others => '0') . There is one more error like this one in the second assignment to St (line 19 in Table 10.7). Again the problem may be solved by sacrificing flexibility and constraining the width of Q to be a fixed value.
Warning : Initial values on signals are only for simulation and setting the value of undriven signals in synthesis. A synthesized circuit can not be guaranteed to be in any known state when the power is turned on.
Signals Low and High are used to tie inputs to a logic '0' and to a logic '1' , respectively. This is because VHDL-87 does not allow '1' or '0' , which are literals, as actual parameters. Thus one way to solve this problem is to change to a VHDL-93 environment, where this restriction was lifted. Some synthesis systems handle VDD and GND nets in a specific fashion. For example, VDD and GND may be declared as constants in a synthesis package. It does not really matter how inputs are connected to VDD and GND as long as they are connected in the synthesized logic.
Turning to the second set of messages first, we need to discover the locations of dffclr_p_dup1: u2 and the other seven similarly named unused instances. We can ask the synthesizer to produce the following hierarchy map of the design:
The eight unused instances in question are inside the 8-bit shift register, register8_p . The only models in this shift register are eight copies of the D flip-flop model, DFFClr . Let us look more closely at the following code:
The synthesizer infers an inverter from the first statement in line 3 ( QB <= not Qi ). What we meant to imply (A) was: “I am trying to describe the function of a D flip-flop and it has two outputs; one output is the complement of the other.” What the synthesizer inferred (B) was: “You described a D flip-flop with an inverter connected to Q.” Unfortunately A does not equal B.
Why were four cell instances ( u5 , u2 , u3 , u4 ) removed from inside a cell with instance name full_adder_p_dup8 ? The top-level cell mult8_p contains cell adder8_p , which in turn contains full_adder_p [x8] . This last entry in the hierarchy map represents eight occurrences or instances of cell full_adder_p . The logic synthesizer appends the suffix '_p' by default to the names of the design units to avoid overwriting any existing netlists (it also converts all names to lowercase). The synthesizer has then added the suffix 'dup8' to create the instance name full_adder_p_dup8 for the eighth copy of cell full_adder_p .
The signal OFL is declared but not used. This means that the formal port name Cout for the entity Adder8 in Table 10.2 is unconnected in the instance full_adder_p_dup8 . Since the carry-out bit is unused, the synthesizer deletes some logic. Before dismissing this message as harmless, let us look a little closer. In the architecture for entity Adder8 we wrote:
In one of the instances of Adder8 , named full_adder_p_dup8 , this statement is redundant since we never use Cout in that particular cell instance. If we look at the synthesized netlist for full_adder_p_dup8 before optimization, we find four NAND cells that produce the signal Cout . During logic optimization the synthesizer removes these four instances. Their instance names are full_adder_p_dup8:u2, u3, u4, u5 .