12.9 The Multiplier
12.9
The Multiplier
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):
Sum <= X xor Y xor Cin after TS;
Warning
: AFTER clause in a waveform element is not supported
This is not a serious problem if you are using a synchronous design style. If you are, then your logic will work whatever the delays (it may run slowly but it will work).
The next problem is from lines
3
–
4
of the 8-bit MUX in Table 10.5,
port (A, B : in BIT_VECTOR (7 downto 0); Sel : in BIT := '0'; Y : out BIT_VECTOR (7 downto 0));
Warning
: Default values on interface signals are not supported
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),
port (X:BIT_VECTOR; F:out BIT );
Error
: An index range must be specified for this data type
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
).
All of these index range problems may be fixed by sacrificing the flexible nature of the code and specifying an index range explicitly, as in the following example:
port (X:BIT_VECTOR(7
downto
0); F:out BIT );
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.
|
TABLE 12.8
A synthesizable version of the shift register shown in Table 10.7.
|
|
entity
ShiftN
is
generic
(TCQ:TIME := 0.3 ns; TLQ:TIME := 0.5 ns;
TSQ:TIME := 0.7 ns);
port
(
CLK, CLR, LD, SH, DIR:
in
BIT;
D:
in
BIT_VECTOR(3
downto
0);
Q:
out
BIT_VECTOR(7
downto
0) );
end
ShiftN;
architecture
Behave
of
ShiftN
is
begin
Shift:
process
(CLR, CLK)
variable
St: BIT_VECTOR(7
downto
0);
begin
if
CLR = '1'
then
St := (
others
=> '0'); Q <= St
after
TCQ;
elsif
CLK'EVENT
and
CLK='1'
then
if
LD = '1'
then
St := (
others
=> '0');
St(3
downto
0) := D;
Q <= St
after
TLQ;
elsif
SH = '1'
then
case
DIR
is
when
'0'=>St:='0' & St(7
downto
1);
when
'1'=>St:=St(6
downto
0) & '0';
end
case
;
Q <= St
after
TSQ;
end
if
;
end
if
;
end
process
;
end
;
|
|
|
CLK Clock
CLR Clear, active high
LD Load, active high
SH Shift, active high
DIR Direction, 1=left
D Data in
Q Data out
Shift register. Input width = 4. Output width = 8. Output is left-shifted or right-shifted under control of DIR. Unused MSBs are zero-padded during load. Clear is asynchronous. Load is synchronous.
Timing:
TCQ
(CLR to Q) = 0.3 ns
TLQ
(LD to Q) = 0.5 ns
TSQ
(SH to Q) =0. 7 ns
|
The next problem occurs because VHDL is not a synthesis language (from lines 6–7 of the variable-width shift register in Table 10.7),
begin assert (D'LENGTH <= Q'LENGTH)
report "D wider than output Q" severity Failure;
Warning
: Assertion statements are ignored
Error
: Statements in entity declarations are not supported
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:
//Compass compile_off
begin assert (D'LENGTH <= Q'LENGTH)
report "D wider than output Q" severity Failure;
//Compass compile_on
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.
The next error message is, at first sight, confusing (from lines 15–16 of the variable-width shift register in Table 10.7),
if CLR = '1' then St := (others => '0'); Q <= St after TCQ;
Error
: Illegal use of aggregate with the choice "others": the derived subtype of an array aggregate that has a choice "others" must be a constrained array subtype
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):
subtype OutB is NATURAL range Q'LENGTH-1 downto 0;
variable St: BIT_VECTOR(OutB);
(to keep the model flexible). Continuing backward we see
Q
is declared as type
BIT_VECTOR
with no index range as follows (lines 4–5 of Table 10.7):
port(CLK, CLR, LD, SH, DIR: in BIT;
D: in BIT_VECTOR; Q: out BIT_VECTOR);
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.
The next warning involves names (line 5 in Table 10.9),
signal SRA, SRB, ADDout, MUXout, REGout: BIT_VECTOR(7 downto 0);
Warning
: Name is reserved word in VHDL-93: sra
This problem can be fixed by (a) changing the signal name, (b) using an escaped name, or (c) accepting that this code will not work in a VHDL-93 environment.
Finally, there is the following warning (line 6 in Table 10.9):
signal Zero, Init, Shift, Add, Low: BIT := '0'; signal High: BIT := '1';
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.
12.9.1 Messages During Synthesis
After fixing the error and warning messages, we can synthesize the multiplier. During synthesis we see these messages:
These unused instances are being removed: in full_adder_p_dup8: u5, u2, u3, u4
These unused instances are being removed: in dffclr_p_dup1: u2
and seven more similar to this for
dffclr_p_dup2: u2
to
dffclr_p_dup8: u2
.
We are suspicious because we did not include any
redundant or unused logic in our input code. Let us dig deeper.
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:
************* Hierarchy of cell "mult8_p" *************
mult8_p
adder8_p
| full_adder_p [x8]
allzero_p
mux8_p
register8_p
| dffclr_p [x8]
shiftn_p [x2]
sm_1_p
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:
architecture
Behave
of
DFFClr
is
signal
Qi : BIT;
begin
QB <=
not
Qi; Q <= Qi;
process
(CLR, CLK)
begin
if
CLR = '1'
then
Qi <= '0'
after
TRQ;
elsif
CLK'EVENT
and
CLK = '1'
then
Qi <= D
after
TCQ;
end
if
;
end
process
;
end
;
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
.
What is so special about the eighth instance of
full_adder_p
inside cell
adder8_p
? The following (line 13 in Table 10.9) instantiates
Adder8
:
A1:Adder8
port
map
(A=>SRB,B=>REGout,Cin=>Low,Cout=>OFL,Sum=>ADDout);
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:
Cout <= (X
and
Y)
or
(X
and
Cin)
or
(Y
and
Cin)
after
TC;
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
.
[ Chapter start ] [ Previous page ] [ Next page ] |