ShareCG: ASICs .. the Book
12.3 Inside a Logic Synthesizer

# 12.3  Inside a Logic Synthesizer

The logic synthesizer parses the Verilog of Figure 12.1 and builds an internal data structure (usually a graph represented by linked lists). Such an abstract representation is not easy to visualize, so we shall use pictures instead. The first Karnaugh map in Figure 12.5 (a) is a picture that represents the sel signal (labeled as the input to the three MUXes in the schematic of Figure 12.1 ) for the case when the inputs are such that ab = 00 . The signal sel is responsible for steering the smallest input, a or b , to the output of the comparator/MUX. We insert a '1' in the Karnaugh map (which will select the input b to be the output) whenever b is smaller than a . When a = b we do not care whether we select a or b (since a and b are equal), so we insert an 'x' , a don’t care logic value, in the Karnaugh map of Figure 12.5 (a). There are four Karnaugh maps for the signal sel , one each for the values ab = 00 , ab = 01 , ab = 10 , and ab = 11 . FIGURE 12.5  Logic maps for the comparator/MUX. (a) If the input b is less than a , then sel is '1' . If a = b , then sel = 'x' (don’t care). (b) A cover for sel .

Next, logic minimization tries to find a minimum cover for the Karnaugh maps—the smallest number of the largest possible circles to cover all the '1' s. One possible cover is shown in Figure 12.5 (b).

In order to understand the steps that follow we shall use some notation from the Berkeley Logic Interchange Format ( BLIF ) and from the Berkeley tools misII and sis . We shall use the logic operators (in decreasing order of their precedence): '!' (negation), '*' (AND), '+' (OR). We shall also abbreviate Verilog signal names; writing a as a2 , for example. We can write equations for sel and the output signals of the comparator/MUX in the format that is produced by sis , as follows (this is the same format as input file for the Berkeley tool eqntott ):

sel = a1*!b1*!b2 + a0*!b1*!b2 + a0*a1*!b2 + a1*!b1*a2 + a0*!b1*a2 + a0*a1*a2 + a2*!b2;[12.1]

outp2 = !sel*a2 + sel*b2;[12.2]

outp1 = !sel*a1 + sel*b1;[12.3]

outp0 = !sel*a0 + sel*b0;[12.4]

Equations 12.1 12.4 describe the synthesized network . There are seven product terms in Eq.  12.1 —the logic equation for sel (numbered and labeled in the drawing of the cover for sel in Figure 12.5 ). We shall keep track of the sel signal separately even though this is not exactly the way the logic synthesizer works—the synthesizer looks at all the signals at once.

Logic optimization uses a series of factoring, substitution, and elimination steps to simplify the equations that represent the synthesized network. A simple analogy would be the simplification of arithmetic expressions. Thus, for example, we can simplify 189 / 315 to 0.6 by factoring the top and bottom lines and eliminating common factors as follows: (3 ¥ 7 ¥ 9) / (5 ¥ 7 ¥ 9) = 3 / 5. Boolean algebra is more complicated than ordinary algebra. To make logic optimization tractable, most tools use algorithms based on algebraic factors rather than Boolean factors.

Logic optimization attempts to simplify the equations in the hope that this will also minimize area and maximize speed. In the synthesis results presented in Table 12.3 , we accepted the default optimization settings without setting any constraints. Thus only a minimum amount of logic optimization is attempted that did not alter the synthesized network in this case.

The technology-decomposition step builds a generic network from the optimized logic network. The generic network is usually simple NAND gates ( sis uses either AND, or NOR gates, or both). This generic network is in a technology-independent form. To build this generic network involves creating intermediate nodes. The program sis labels these intermediate nodes [n] , starting at n = 100 .

sel =  *  *  ;[12.5]

 = !( !a2 *  );

 = !( b2 *  );

 = !( !a2 * b2 );

 = !(  *  *  );

 = !( !a1 * b1 );

 = !( b0 *  );

 = !( a0' *  );

 = !( a1 * !b1 );

outp2 = !(  *  );[12.6]

 = !( a2 * !sel );

 = !( sel * b2 );

There are two other sets of equations, similar to Eq.  12.6 , for outp1 and outp0 . Notice the polarity of the sel signal in Eq.  12.5 is correct and represents an AND gate (a consequence of labeling sel as the MUX select input in Table 12.1 ).

Next, the technology-mapping step (or logic-mapping step) implements the technology-independent network by matching pieces of the network with the logic cells that are available in a technology-dependent cell library (an FPGA or standard-cell library, for example). While performing the logic mapping, the algorithms attempt to minimize area (the default constraint) while meeting any other user constraints (timing or power constraints, for example).

Working backward from the outputs the logic mapper recognizes that each of the three output nodes ( outp2 , outp1 , and outp0 ) may be mapped to a MUX. (We are using the term “node mapping to a logic cell” rather loosely here—an exact parallel is a compiler mapping patterns of source code to object code.) Here is the equation that shows the mapping for outp2 :

outp2 = MUX(a, b, c) = ac + b!c[12.7]

a = b2 ; b = a2 ; c = sel

The equations for outp1 and outp0 are similar.

The node sel can be mapped to the three-input majority function as follows:

sel = MAJ3(w, x, y) = !(wx + wy + xy) [12.8]

w = !a2 ; x = b2 ; y =  ;

Next node  is mapped to an OAI22 cell,

 = OAI22(w, x, y, z) = ! ((w + x)(y + z)) = (!w!x + !y!z) [12.9]

w = a0 ; x = a1 ; y = !b1 z =  ;

Finally, node  is mapped to a two-input NOR with one inverted input,

 = !(b1 + !a1) ; [12.10]

Putting Equations 12.7 12.10 together describes the following optimized logic network (corresponding to the structural netlist and schematic shown in Figure 12.3 ):

sel = !((( !a0 * !(a1&!b1) | (b1*!a1) ) * (!a2|b2) ) | (!a2*b2)) ;[12.11]

outp2 = !sel * a2 | sel * b2;

outp1 = !sel * a1 | sel * b1;

outp0 = !sel * a0 | sel * b0;

The comparator/MUX example illustrates how logic synthesis takes the behavioral model (the HDL input) and, in a series of steps, converts this to a structural model describing the connections of logic cells from a cell library.

When we write a C program we almost never think of the object code that will result. When we write HDL it is always necessary to consider the hardware. In C there is not much difference between i*j and i/j . In an HDL, if i and j are 32-bit numbers, i*j will take up a large amount of silicon. If j is a constant, equal to 2, then i*j take up hardly any space at all. Most logic synthesizers cannot even produce logic to implement i/j . In the following sections we shall examine the Verilog and VHDL languages as a way to communicate with a logic synthesizer. Using one of these HDLs we have to tell the logic synthesizer what hardware we want—we imply A. The logic synthesizer then has to figure out what we want—it has to infer B. The problem is making sure that we write the HDL code such that A = B. As will become apparent, the more clearly we imply what we mean, the easier the logic synthesizer can infer what we want.