courses:system_design:synthesis:rtl-style

RTL-Style

RTL-Style

Notes

In RTL (Register Transfer Level) style modelling, the design is split up into storing elements, i.e. flip flops or often simply called registers, and combinational logic which constitute the transfer function from one register to the succeeding register.

A process is required for each of them:

  • a combinational process, which describes the functionality,
  • and a clocked process, which generates all storing elements.

Of course, it is possible to combine these two processes into a single clocked one which models the complete functionality.

process (A, B, SELECT)
begin
   if (SELECT =1) then
     OUT <= A;
   else
     Out <= B;
   end if;
end process;
Sensitivity list is usually ignored during synthesis
Equivalent behavior of simulation model and hardware: sensitivity list has to contain all signals that are read by the process
What kind of hardware is modelled?
What will be the simulation result if SELECT is missing in the sensitivity list?

Notes

The sensitivity list of a combinational process consists of all signals which will be read within the process. It is especially important not to forget any signals, because synthesis tools generally ignore sensitivity lists in contrast to simulation tools.

During simulation, a process will only be executed, if there an event occurs on at least one of the signals of the sensitivity list. During synthesis, VHDL code is simply mapped to logic elements. Consequently a forgotten signal in the sensitivity list will most probably lead to a difference in behavior between the simulated VHDL model and the synthesized design. Superfluous signals in the sensitivity list will only slow down simulation speed.

The code example models a multiplexer. If the signal SELECT was missing, synthesis would create exactly the same result, namely a multiplexer, but simulation will show a completely different behavior. The multiplexer would work properly as long as an event on SELECT would coincide with events on A or B. But without an event on A or B the process would not be activated and thus an event exclusively on SELECT would be ignored in simulation. Consequently, during simulation, the output value OUT would only change, if the input signals A or B were modified.

process 
begin
   if SEL =1then
    Z <= A;
   else
    Z <= B;
   end if;
   wait on A, B, SEL;
end process;
process (A, B, SEL)
begin
   if (SEL =1) then
     Z <= A;
   else
     Z <= B;
   end if;
 
end process;
  • Equivalent simulation processes (wait on not synthesizable)
  • Mutually exclusive:
    • Either sensitivity list
    • Or wait statements

Notes

Instead of using a sensitivity list, it is possible to model the same behavior by the use of a WAIT ON statement. It should be placed as last statement in the process and should quote the same signals of course.

In case of a sensitivity list, the process is started whenever an event occurs on one of the signals in the list. All sequential statements are executed and after the last sequential statement the process is suspended until the next event.

In case of a wait statement, the process runs through the sequential statements to the wait statement and suspends until the condition of the wait statement is fulfilled. Process execution must be interrupted via wait statements if no sensitivity list is present as the simulator would be stuck in an endless loop otherwise. Please remember again, that it is not allowed to use a sensitivity list and a wait statement simultaneously in the same process.

entity MX is
  port (A, B, SELECT : in std_logic;
        Z            : out std_logic);
end MX;
architecture NOTOK of MX is
begin
   process (A, B, SELECT)
   begin 
 
    if SELECT =1then
      Z<= A;
    end if;     -- incomplete if-statement
  end process;
end NOTOK;
What is the value of Z if SELECT = ‘0’ ?
What hardware would be generated during synthesis?
architecture OK1 of MX is
begin
   process (A, B, SELECT)
   begin 
    Z <= B;     -- default case before if-statement
    if SELECT =1then
      Z<= A;
    end if;
  end process;
end OK1;
architecture OK2 of MX is
begin
   process (A, B, SELECT)
   begin 
 
    if SELECT =1then
      Z<= A;
    else
      Z <= B;   -- complete if-statement for every case
    end if;
  end process;
end OK2;

Notes

Special care is necessary when modelling combinational hardware in order to avoid the generation of latches. The leftmost code example lacks an unconditional else branch.

Therefore the value of Z is preserved in case of SELECT=’0’, even if the input signals change. Synthesis would have to generate an adequate storing element, i.e. a latch which is transparent whenever the level of SELECT is ’1’.

This kind of storing elements is not recommended for synchronous designs. Edge triggered flip flops are preferred because possibly illegal intermediate signal values are filtered out as long as the combinational logic settles to its final state before the next active clock edge.

Additionally latches cannot be tested by a scan test. In scan test mode all flip flops are combined to a single shift register the so called scan path. They are all supplied with the same clock signal. This make it possible to set all registers to specific values by shifting them into the chip using an additional input pin (scan_in). After one system clock period the registers contain new values which are shifted out using an additional output pin (scan_out). This way, scan test provides access to otherwise invisible internal states. Scan test is current state of the art technology to improve testability for production tests.

The two coding alternatives are functionally identical and are mapped to purely combinational logic (multiplexer) by synthesis tools. The difference lies in the implementation of the default assignment. Please remember that signal values are updated at the end of the process execution, only! This way the default assignment of B to Z in the architecture OK1 will be overwritten if the IF condition is true.

  • New standard for synthesis: IEEE 1076.6
if
wait until
clock_signal_name’EVENT and clock_signal_name=1’
clock_signal_name=1and clock_signal_name’EVENT
not clock_signal_name’STABLE and clock_signal_name=1’
clock_signal_name=1and not clock_signal_name’STABLE
RISING_EDGE (clock_signal_name)
clock_signal_name’EVENT and clock_signal_name=1’
clock_signal_name=1and clock_signal_name’EVENT
not clock_signal_name’STABLE and clock_signal_name=1’
clock_signal_name=1and not clock_signal_name’STABLE
RISING_EDGE (clock_signal_name)
clock_signal_name=1
IEEE 1076.6 is not fully supported by all tools, yet

In Std_Logic_1164 package

function RISING_EDGE (signal CLK : std_ulogic) return boolean is
begin
  if (CLK’event and CLK =1and CLK’last_value =0) then
    return true;
  else
    return false;
  end if;
end RISING_EDGE;
process
begin
   wait until RISING_EDGE(CLK);
   Q <= D;
end process;

Notes

As the sensitivity list is usually ignored by synthesis tools and wait statements are not synthesizable in general, a solution to the problem of modelling storage elements has to be found.

Synthesis tools solved this issue by looking for certain templates in the VHDL code, namely the first option (’if/wait until X’event and X=’1’ then’) of the two process styles. All alternatives show the same behavior during simulation, however. Please note that the event detection in the ’wait until’ statement is redundant as an event is implicitly required by the ’wait until’ construct.

In the meantime, the IEEE standard 1076.6 was passed that lists that the VHDL constructs that should infer register generation. As this standard is not fully supported by synthesis tools, yet, the first option is still the most common way of describing a rising/falling clock edge for synthesis. When asynchronous set or reset signals are present, only the IF variant is applicable. The RISING_EDGE function is just mentioned for sake of completeness as it is not supported by synthesis tools. Nevertheless it may be useful for simulation.

library IEEE;
use IEEE.std_logic_1164.all;
entity COUNTER is
  port (CLK: in std_logic;
        Q : out integer range 0 to 15);
end COUNTER;
architecture RTL of COUNTER is
  signal COUNT : integer range 0 to 15;
begin
  process (CLK)
  begin
    if CLK’event and CLK =1then
      if (COUNT >= 9) then
         COUNT <= 0;
      else
         COUNT <= COUNT +1;
      end if;
    end if;
  end process;
  Q <= COUNT;
end RTL;
  • Storage elements are synthesized for all signal that are driven within a clocked process
What the Synthesis Tool is looking for?
How many FF? COUNT: 4 flip flops
Q: not used in clocked process

Register Interface

Notes

The example shows the VHDL model of a simple 1 digit decimal counter. Several things are worth mentioning:

  • First, the design is not resetable. This is not a problem for simulation as initial values can be assigned to the signals. Real world hardware does not behave this nicely, however, and the state of internal storage elements is unknown after power up. In order to avoid strange and inexplicable behavior it is recommended to provide a reset feature that brings the design into a well defined state.
  • Second, the range of the integer signals has been restricted. Synthesis tools have to map all data types onto a bit pattern that can be transported via wires. Without explicit range definition, the range for integers would be from -2,147,483,647 to +2,147,483,647, which equals 32 bits. As the maximum counter value is 9 it would be natural to specify a valid range for signal values from 0 to 9. During synthesis, however, 4 bits will be needed to represent the number 9, i.e. the theoretical maximum value of the signal would be 15. In order to avoid possible shortcomings of synthesis tools and to make sure that the counter restarts with 0, indeed, the range is set to match the synthesized hardware.
  • Third, the internal signal COUNT has been declared in addition to the output port Q. This is due to the fact that Q is declared with port mode ’out’, i.e. its value can not be read within the architecture. As its next value depends on the previous one, however, it is necessary to declare the intermediate signal COUNT which is used within the counter process. The process itself is a clocked process without any asynchronous control signals and thus the CLK signal is the only signal in the sensitivity list.

Flip flops are inferred by clocked processes, only. Every signal that might be updated in a clocked process receives a register. Therefore, four storage elements will be created for the COUNT signal. The assignment of the output value is done concurrently, i.e. the outputs of the flip flops will be connected directly to the outputs of the COUNTER module.

library IEEE;
use IEEE.std_logic_1164.all;
entity ASYNC_FF is
  port (D, CLK, SET, RST : in std_logic;
        Q                : out std_logic);
end ASYNC_FF;
architecture RTL of ASYNC_FF is
begin
  process (CLK, RST, SET)
  begin
    if (RST =1) then
      Q <=0;
    elsif SET =1then
      Q <=1;
    elsif (CLK’event and CLK =1) then
      Q <= D;
    end if;
  end process;
end RTL;
  • Only possible in process with sensitivity list
  • If / elsif - structure
    • Reset in first IF condition
    • Clock edge detection as last condition
    • no unconditional else branch

Notes

As noted before, it is advisable to provide each clocked design with a reset capability. If a synchronous reset strategy is employed, the reset signal is treated just like any other control signal, i.e. the clock signal will be still the only signal in the process’ sensitivity list.

While purely synchronous clocked processes can also be described with the ’wait until’ construct, asynchronous control signals can be modelled with processes with sensitivity list, only. All signals that might trigger the process execution have to be listed again, i.e. the asynchronous signals (usually reset, only) are added. The process itself consists of an IF construct, where the asynchronous signals are checked first, followed by the detection of the active clock edge.

The condition for synchronous actions has to be the last condition of the IF structure because asynchronous control signals are usually treated with higher priority by the underlying hardware cells. An unconditional else path is strictly forbidden as statements that have to be processed whenever the active clock edge is not present do not have a physical representation. It is very important not to forget any of these asynchronous signals. Otherwise simulation will differ from synthesis results, as simulation tools base their simulation on the sensitivity list and synthesis tools usually ignore the sensitivity list completely.

  • Complete sensitivity list
    • RTL behavior identical with hardware realization
    • Incomplete sensitivity lists can cause warning or errors
  • No incomplete statements
    • Inference of transparent latches
  • All signals which receive an assignment → Register
  • WAIT form:
    • no sensitivity list
    • Synchronous reset
process
begin
  wait until CLK’event and CLK=1;
  if RESET =1then
    -- synchronous register reset
  else
    -- combinational
  end if;
end process;
  • IF form:
    • only clock and asynchronous signals (reset) in sensitivity list
    • Synchronous and asynchronous reset
process(CLK, RST)
begin
  if (RST =1) then
    -- asynchronous register reset
  elsif (CLK’event and CLK=1) then
    -- combinational
  end if;
end process;
Registers for all driven signals, synchronous reset preferred (timing!)
All registers should be resetable
Which signals in clocked processes are used for deducing registers?
Which two process types are permitted in the RTL-style?
What causes latches to be created in the synthesized design?
How can unwanted latches be prevented most efficiently?
You Scored % - /

Chapters of System Design > Synthesis