( ESNUG 132 #1 ) ---------------------------------------------------- [7/8/93]
From: [ all sorts of Synopsys techies who don't want their names known ]
Subject: Working with MUXes using Verilog and VHDL
Where did my mux go? Why can't the tool infer my 32 to 1 mux structure?
The tool is broken!!! How many times have your found yourself in this
situation when you have been using Design Compiler / VHDL Compiler?
Many users write HDL code with the intent of inferring or synthesizing to
multiplexers only to find combinational logic in the resulting circuit.
This article will explain many of the reasons for this as well as provide
some examples of what not to do and finally workarounds for both VHDL and
Verilog.
I. CURRENT METHOD OF APPROACHING MULTIPLEXERS
Synopsys currently approaches synthesis by extracting multiplexers at the
completion of the compile process. It involves breaking all non-threestate
and sequential elements down into boolean equations and optimizing these
equations. In order to take advantage of the algorithms within the tool,
multiplexer structures are also broken down into boolean equations.
When the optimization is complete, the tool attempts to "reconstruct" these
MUXes by identifying the structures that are ideally suited to MUXs. This
attempt is difficult for two reasons: non-ideal multiplexer coding and the
"reconvergence" problem.
Non-ideal multiplexer structures come into play whenever a user deviates
from the standard MUX definition in their code. For example, a 2 to 1
MUX will have two unique variable data inputs and one single bit select
line. (See section III for more information on these structures.)
Reconvergence is a common problem within synthesis. Without going into too
much depth, it can be viewed as the same input affecting more than one
intermediate term in a simple gate. To explain this, take the simple 2 to 1
multiplexer, which can modelled in the following and/inverter structure:
Z = (A & SEL) + (B & !SEL)
Note that SEL is found in both products in the above equation, which can be
shown as:
Z
/ \
T1 T2
/ \ / \
A SEL B
Because of this reconvergence (the fact that "SEL" can be seen along two
paths from the Z pin,) it is very difficult to algorithmically detect these
structures within synthesis and replace them with a multiplexer. Simpler
gates like NAND, NOR, INVERTERs and even AOR gates do not inherently
contain this problem and are ideal candidates for synthesis. (It is
interesting to note that XOR gates also contain reconvergence making
them also a difficult logical construct to use in synthesis.)
II. WHEN MULTIPLEXERS ARE LESS THAN IDEAL
More often than not, users write their HDL with the intent of receiving a
multiplexer after synthesis when the best implementation for their code
would be combinational logic. There are situations when multiplexers ARE
the best way to impelement a circuit, and it is important to note the
differences.
To begin with, lets take in ideal case of a simple 4 to 1 multiplexer.
Using a "case" statement generically, the following code is the best way
to implement the multiplexer. Assume CONDITION is a two bit value, and
all other values are single bit:
case CONDITION
00: Z = A
01: Z = B
10: Z = C
11: Z = D
This represents the simple 4 to 1 multiplexer completely and is best
implemented by inferring a multiplexer.
Unfortunately, very few real-life situations fall into this category and
users often modify the above example to suit their needs. This section
will present many of the modifications that make multiplexers less than
ideal candidates for implementation.
A. Propogations of Constants
Take for example the following modification of the above logic:
case CONDITION
00: Z = 0
01: Z = A
10: Z = 0
11: Z = 1
This is a very common application of the case construct and could very
easily be implemented with a 4 to 1 multiplexer. The implementation of
course would have three of the four multiplexer inputs tied off to a
constant value. These constant values would remain at the inputs of the
multiplexer throughout synthesis. They are not propogated through the
multiplexer in order to retain the multiplexer structure.
If this same circuit was implemented with combinational logic, however,
the constant values can easily eliminate much of the logic that is found
would be required to implement a full multiplexer structure.
B. Multibit Assignments
Another example would be the case where A, B, C and D are multibit values.
Consider the following if each was 4 bits:
case CONDITION /**** A, B, C, D and Z are now 4 bits wide ****/
00: Z = A
01: Z = B
10: Z = C
11: Z = D
To implement this structure with multiplexers, it would require four 4 to 1
multiplexers. Simply multiplying the number of combinational cells required
for a 4 to 1 multiplexer (6 ANDs, 3 ORs and 2 INVERTERs) would produces an
estimate of 44 gates total for this circuit.
However, when this structure is implemented with combinational logic, it only
requires 34 gates. Where does this improvement come from? It results from
the fact that each 4 to 1 MUX includes a decoder that breaks the 2 bit SEL
value up into the various branches of the multiplexer. When the circuit is
implemented with combinational logic, only one decoded needs to be implemented,
effectively saving the 10 gates that would have been duplicated across the
circuit.
C. Other Situations
While the above two situations represent two of the most common cases of
non-ideal multiplexer inference, there are several other situations when this
can occur:
1. Assignment of Same Values -- If more than one branch of a case statement
assigns the the same value, internal MUX logic can be easily removed.
2. Unassigned Input -- If only a subset of the case branches are used, it
may be easier to implement the circuit with a smaller MUX and
combinational logic.
3. One-hot Case Encoding -- If the "case" conditional is in one hot encoding,
an encoder must be built to code these values for the select lines of
the MUX. The multiplexer then must decode these values internally
resulting in redundant logic.
Although using multiplexers can make the functionality of a design easier to
understand at the schematic level, the uses of multiplexers in any but the
most ideal and controlled situations could lead to lower quaility of results
for the user's circuit. It is often quite easy to infer a simple MUX in very
simple situations, but when the code begins to change from the basic model,
the situations become more complex and building algorithms to correctly make
these decisions become very difficult.
III. WORKAROUNDS
As with many deep synthesis based issues, workarounds have been generated to
mitigate the effects of these problems.
The best workaround for this problem is to create a function that provides
two cabilities: 1) The function includes behavioral Verilog or VHDL that
can be simulated and 2) The function includes technology specific synthesis
directives that allows the tool to force the inference of a multiplexer.
The following two examples accomplish exactly that by using GTECH (a technology
independent representation) of the 4 to 1 multiplexer example illustrated
above. After reading the module, include a line in your script to the effect
of:
set_map_only find(reference,GTECH_MUX4)
(For more information about using the GTECH library, see the DesignWare
Databook.)
For Verilog, use:
module MUX (d3,d2,d1,d0,c1,c0,y);
input d3,d2,d1,d0,c1,c0;
output y;
reg y;
always @ (d3 or d2 or d1 or d0 or c1 or c0) begin
y <= mux4 (d3,d2,d1,d0,c1,c0);
end
function mux4;
//synopsys map_to_module GTECH_MUX4
//synopsys return_port_name Z
input D3,D2,D1,D0,A,B;
reg [1:0] c;
reg Z;
begin
c[1] <= A;
c[0] <= B;
case (c) // synopsys full_case parallel_case
2'b00: begin
Z <= D0;
end
2'b01: begin
Z <= D1;
end
2'b10: begin
Z <= D2;
end
2'b11: begin
Z <= D3;
end
endcase
end
endfunction
endmodule
For VHDL, use:
library IEEE, GTECH;
use IEEE.std_logic_1164.all;
use GTECH.GTECH_components.all;
entity MUX is
port (d3,d2,d1,d0,c1,c0 : in STD_LOGIC;
y : out STD_LOGIC);
end MUX;
architecture MY_ARCH of MUX is
function mux4(D3,D2,D1,D0,A,B : STD_LOGIC) return
STD_LOGIC is
variable c : STD_LOGIC_VECTOR (1 downto 0);
variable y : STD_LOGIC;
--synopsys map_to_module GTECH_MUX4
--synopsys return_port_name Z
begin
c(1) := A;
c(0) := B;
case c is
when "00" =>
y := d0;
when "01" =>
y := d1;
when "10" =>
y := d2;
when "11" =>
y := d3;
when others =>
y := d0;
end case;
return y;
end mux4;
begin
process (d3,d2,d1,d0,c1,c0)
begin
y <= mx4(d3,d2,d1,d0,c1,c0);
end process;
end MY_ARCH;
In summary, multiplexers can be used effectively within a design when they
are implemented using an ideal coding structure. When this structure is
modified to become non-ideal, multiplexers become a much more challenging
construct to synthesize . Synopsys is committed to the continued refinement
of our synthesis technology and better multiplexer inferencing presents a
clear opportunity for improvement.
NOTE: Any questions regarding the material presented here should be forwarded
to ESNUG. If you call the hotline with specific questions on this tech note,
they're not briefed on it -- please send your replies/questions/comments to
ESNUG and if you have a very specific issue, John Cooley will forward it on
to the appropriate people at Synopsys. In replying, please indicate whether
you wish your comments to possibly appear on ESNUG or not.
|
|