Make your own free website on
 Synthesis (contd)
 | Comp-Arch | EDA & Tools| VHDL | Verilog | E-group Extracts
| Asynchronous | Synthesis |

VHDL Synthesis Subset

For synthesis purpose, RTL (Register Transfer Level) is the desired level of abstraction. In a RTL design description, the designer explicitly defines the registers of the design and specifies the flow of data through the registers with conditional statements such as IF-THEN-ELSE and CASE, and with the operators, such as addition, subtraction and shifting.

In other words, RTL description is a combination of Structural and Dataflow description. RTL descriptions hence are at a higher level than purely structural descriptions since data flow is .specified with high level statements and operators. RTL descriptions are at a lower level than behavioral descriptions, because there is no structure specified in a behavioral description. At this level of abstraction, the design is also technology independent allowing automatic synthesis to any target technology using a synthesizer (synthesis tool).


Combinational Logic Synthesis

Combinational circuits are those in which the outputs are determined solely based on the current values of the inputs; the circuit doesn't maintain any internal state; the circuit doesn't posses any memory/storage elements. 

A boolean expression used in a concurrent signal assignment will be synthesized to an equivalent logical circuit using the cells available in the target library.

z_out <= (a_in AND b_in) OR c_in;

For example, the above expression may get synthesized to a complex gate, 2 or 3 NAND gates, of simply an AND and an OR gate.

Conditional signal assignments are synthesizable. 

z_out <= "101" WHEN a > b ELSE 
               "100" WHEN b > a ELSE 

In the above example, an ELSE condition complements the condition before it to be used as an enable for the next condition thus resulting in a priority encoder. Synthesis tool may optimize the hardware, but if the conditions aren't mutually exclusive, then the hardware is bound to be priority encoded. Hence it is safer to use a selected signal assignment to be assured of a multiplexer in hardware. Same is the case with IF-THEN-ELSE statement also.

WITH addr(1 downto 0) SELECT
     request <= request_a WHEN "00",
                        request_b WHEN "01",
                        request_c WHEN "10",
                        request_d WHEN "11";

One other situation in which a selected signal assignment statement is appropriate is combinational logic with a tristated buffered output, for example:

data_bus <= r_bus (15 downto 0) WHEN enable = '1' ELSE

We can also use a process statement to describe combinational logic. It is most essential to take care of the following aspects:

  • The sensitivity list must contain all the inputs used in the combinational logic.

  • All outputs must be assigned values in all possible execution paths of the process. This statement gets highlighted when multiple outputs.

PROCESS (rd_en, a, b, c)
        IF (rd_en = '1') THEN
                x <= a AND b;
                y <= c OR a;
                z <= NOT b;
                x <= "zzzz";
                y <= "zzzz";
                z <= "zzzz";
        END IF;

Thus the logic inferred is purely combinatorial and synthesis results in tristate drivers on the outputs x, y & z.


HDLPlanet (                                                            Synthesis Page


Sequential Logic Synthesis

Sequential circuits are those in which the the circuit maintains internal states; the circuit posseses memory/storage elements; the outputs they produce in response to the given inputs depend on the history of inputs received previously. Most sequential circuits are synchronous or clocked. They use rising or falling edge of a clock, or a level of an enable signal, to control advance of the state or the storage of data.

The synthesis standard prescribes the use of a number of templates for processes describing edge-triggered sequential logic:

process_label : process (clock_signal)
    if clock_edge then
    end if;
end process;

The clock_edge expression being an event expression can take any of the following formats

clock_signal'event and clock_signal = '1'
clock_signal = '1' and clock_signal'event
not clock_signal'stable and clock_signal = '1'
clock_signal = '1' and not clock_signal'stable 

Above formats describe a rising clock edge, and similar formats for falling edge also exists. One important aspect to remember is that the sequential statements within the if statement must not include any wait statements or any references to clock edge expressions.

Using the "wait" statement
An edge sensitive storage element may be modeled using a clock edge as a condition in a wait until statement. The wait until statement shall be the first statement in the process. No additional wait until statements should be within the same process, including any procedures called within the process. Following is the template for modeling such an edge sensitive storage element:

process_label : process
   wait until <clock_edge>
end process [process_label] ;

Point to remember is that the wait until statement must be the first statement of the process. Hence asynchronous override (like set, reset) of edge sensitive storage elements can not be represented using wait until statement form of modeling.

Level Sensitive Logic Inferring Storage
Level sensitive sequential logic maintains states, but does not respond to clock edges. Instead, state is updated under the control of an enable signal. When the enable signal is asserted, the state can change according to the inputs. While the enable signal is negated, inputs are ignored and the circuit maintains its current state. In synthesizable models, we need not explicitly specify the storage for the state, instead the synthesis tool infers the storage from the model behavior. Following is the model of a transparent latch:

latch : process (enable, d)
    if enable = '1' then
        q <= d;
    end if;
end process latch;

There are two general cases when the synthesis tool must infer storage for a process that does not include any reference to a clock edge expression. In either of the cases, the process must include in its sensitivity list, all input signals that are being used in it. First case arises when there are possible executions of the process that does not result in any signal assignments. The above latch example explains this fact. The following process is another example, involving storage inference for a variable:

latch_with_reset : process (enable, reset d)
    variable stored_value : bit;
    if reset = '1' then
        stored_value := '0';
    elsif enable = '1' then
        stored_value := d;
    end if;
    q <= stored_value;
end process latch_with_reset; 

In this example, the output q is assigned on every execution of the process, so no storage is inferred for it. However, the stored_value is not assigned when both enable and reset are '0'; hence storage is inferred for this variable.

Second case arises where there are possible executions in which a signal or variable is read before it is assigned. Following is an erroneous process intended to describe a counter with reset:

counter: process (count_en)
    variable count : natural range 0 to 15;
    q <= (q+1) mod 16;
end process counter;


HDLPlanet (                                                            Synthesis Page


State Machine Synthesis

Many designs expressed at the register-transfer level consists of combinatorial data paths controlled by finite state machines. Also, the finite state machine by itself contains some combinatorial logic for calculating the next state. Synthesis tools have separate algorithms for optimizing combinatorial logic and sequential logic. Hence the preferred approach is to separate the state machine implementation into two processes, one describing the combinatorial logic and the other for sequential activities.

The combinatorial process (logic process in the example) sensitivity list must include all inputs used by the process statement and must avoid latching by setting process outputs to their inactive values. The sequential process must include clock edge detection. On the edge of the clock, present state register values are set to the next state values. 

Following is the ARCHITECTURE block of one such "State Machine":

ARCHITECTURE fsm_example OF example IS
    TYPE state IS (a, b, c, d);
    SIGNAL next_state, present_state : state;
    reg: PROCESS (clk)
        IF (clk'event AND clk = '1') THEN
            present_state <= next_state;
        END IF;
    END PROCESS reg;
    logic: PROCESS (present_state, x)
        z <= '0';
        CASE present_state IS
            WHEN a => 
                IF x = '0' THEN next_state <= a; ELSE next_state <= b; END IF;
            WHEN b =>
                IF x = '0' THEN next_state <= c; ELSE next_state <= b; END IF;
            WHEN c =>
                IF x = '0' THEN next_state <= a; ELSE next_state <= d; END IF;
            WHEN d =>
                IF x = '0' THEN next_state <= c; ELSE next_state <= b; END IF;
        END CASE;
        IF present_state = d THEN z <= '1'; END IF;
    END PROCESS logic;
END fsm_example;

The sequential process of a state machine can however include logic for various mechanisms for set, reset or pre-load. Another verilog example representing the separation of combinational & sequential logic:

Poor Coding Style:

always @(posedge clk)
  a <= b + c;

Recommended Coding Style:

always @(b or c)
  a_nxt <= b + c;

always @(posedge clk)
  a <= a_nxt;


HDLPlanet (                                                            Synthesis Page



Last Updated on 27th Jan 2002

Feedback/Suggestions accepted at