====== RTL-Style ====== ===== Process Types ===== {{:courses:system_design:synthesis:folie119_rtlstyle.svg?nolink&600|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. ===== Combinational Process: Sensitivity List ===== 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. ===== Wait Statement <-> Sensitivity List ===== process begin if SEL = ‘1’ then 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. ===== Combinational Process: Incomplete Assignments ===== 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 = ‘1’ then 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 = ‘1’ then Z<= A; end if; end process; end OK1; architecture OK2 of MX is begin process (A, B, SELECT) begin if SELECT = ‘1’ then 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. ===== Clocked Process: Clock Edge Detection ===== * New standard for synthesis: IEEE 1076.6 | if | wait until | | clock_signal_name’EVENT and clock_signal_name=’1’ clock_signal_name=’1’ and clock_signal_name’EVENT not clock_signal_name’STABLE and clock_signal_name=’1’ clock_signal_name=’1’ and not clock_signal_name’STABLE RISING_EDGE (clock_signal_name) | clock_signal_name’EVENT and clock_signal_name=’1’ clock_signal_name=’1’ and clock_signal_name’EVENT not clock_signal_name’STABLE and clock_signal_name=’1’ clock_signal_name=’1’ and 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 = ’1’ and 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. ===== Register Inference ===== 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 = ’1’ then 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 {{:courses:system_design:synthesis:folie124_registerinterface.svg?nolink&300|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. ===== Asynchronous Set/Reset ===== 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 =’1’ then 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. ===== Summary: Combinational Process Rules ===== * Complete sensitivity list * RTL behavior identical with hardware realization * Incomplete sensitivity lists can cause warning or errors * No incomplete statements * Inference of transparent latches ===== Summary: Clocked Process Rules ===== * 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 = ‘1’ then -- 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 ===== Quiz ===== Temporary signals.| Signals which contain an assignment. | Signals which have been read. Mixed and analog processes.| Combinational and sequential processes. Concurrent IF-statements.| Forgotten else-paths. | Signal assignments which are not executed in all path of an IF- or CASE-statement. | Incomplete sensitivity lists. By replacing IF-statements by CASE-statements. | By giving default assignments to all signals which contain an assignment in one path, before the IF- or CASE-statement.