ENG6530 RCS ENG6530 Reconfigurable Computing Systems Hardware Description Languages Synthesis
ENG6530 RCS2 Topics Synthesizable/Non-Synthesizable Code Translation to Hardware Simulation vs. Synthesis Synthesis: Hints, Guidelines Summary
ENG6530 RCS3 References –Kenneth Short, “VHDL For Engineers”, Prentice Hall, –Sudhakar Yalamanchili, “Introductory VHDL: From Simulation to Synthesis”, Prentice Hall, –VHDL Guidelines for Synthesis”, Siemens Semiconductor Group. –“RTL Hardware Design Using VHDL”, Pong Chu, Wiley, 2006.
ENG6530 RCS4 Execution Models for VHDL Programs Two classes of execution models govern the application of VHDL programs Simulation For Simulation –Discrete event simulation –Understanding is invaluable in debugging programs Synthesis For Synthesis –Hardware inference –The resulting circuit is a function of the building blocks used for implementation »Primitives: NAND vs. NOR »Cost/performance
5 VHDL for Synthesis VHDL for Simulation VHDL for Synthesis 1. Only a subset 1. Only a subset of the VHDL language is synthesizable 2. You need to understand 2. You need to understand what is meant for simulation versus what is meant for producing hardware (i.e. synthesis) tool specific! 3. The VHDL subset that is synthesizable is tool specific! –Do not expect –Do not expect two different tools to produce the same hardware!
6 Synthesis and Hardware Inference very differentWhy? Processes can produce very different results! Why? Synthesis engine HDL Design Specification Author #1 HDL Author Hardware Design Author #2 HDL
ENG6530 RCS7 Synthesis Hardware implementation of VHDL code depends Coding convention Fitter technology Optimization option Nature of application Not all designs are synthesizable: several constructs defined in the language cannot be synthesized!
ENG6530 RCS8 Non Synthesizable Subset Examples of constructs that cannot be synthesized into hardware: File operations including text I/O Wait and After statements. Assertion/Report statements Loops with no bound (infinite while loop) Real data types are not supported Certain operators e.g., /, **, mod, rem Recursive Functions
ENG6530 RCS9 VHDL Design Styles Components and interconnects structural VHDL Design Styles dataflow Concurrent statements behavioral (algorithmic) Registers State machines Test benches Sequential statements Subset most suitable for synthesis
ENG6530 RCS10 Design Units fundamental building blocks Design units are the fundamental building blocks in a VHDL program. When a program is processed, it is broken into individual design units and each unit is analyzed and stored independently. There are five kinds of design units Entity declaration Architecture declaration Architecture declaration Package declaration Package body Configuration
ENG6530 RCS11 Libraries & Packages Package A Package normally contains a collection of commonly used items, such as data types, subprograms and components, which are needed by many VHDL programs. Each design unit – entity, architecture, configuration package, declaration is analyzed (compiled) and design library placed in a design library. directories Libraries are generally implemented as directories
ENG6530 RCS12 Library: Example For standard logic (std_logic) the basic package is ieee.std_logic_1164. This package defines the values and basic logic operators for type std_logic. The declarations can be made visible in our model file by : library IEEE; Use IEEE.STD_LOGIC_1164.ALL; Library Package
ENG6530 RCS13 VHDL versus C Terminology The following comparison shows some rough equivalents between the VHDL Concepts and C programming. 1. Analyze or compile the package declaration? 2. Instantiate a component? 3. Use a Package?
14 Synthesis: Hardware Translation How does a data type translate to hardware? Integer, Real, Boolean, … How do data objects map to hardware? Signals, variables, constants, … How are statements translated to hardware? Assignments, operators, … How do these constructs differ when translated to hardware? If-Else, Case, For, While, …
15 VHDL Hardware Correspondence
ENG6530 RCS16 Variables versus Signals When a variable is assigned a value, it takes that value immediately (similar to conventional programming languages). When a signal is assigned a value, the assigned value does not take effect immediately. The signal does not take the new value until after the process has suspended. As a general guideline, a variable is used to store data within a process when the new value assigned to the variable is to be used (read) in the same execution of the process.
17 Simple Assignment Statements architecture behavior of stover is signal sig_s1, sig_s2: std_logic; begin proc1: process (x, y, z) is -- Process 1 using variables variable var_s1, var_s2: std_logic; begin var_s1:= x and y; var_s2:= var_s1 xor z; res1 <= var_s1 and var_s2; end process proc1; proc2: process (x, y, z) -- Process 2 using signals begin sig_s1 <= x and y; sig_s2 <= sig_s1 xor z; res2 <= sig_s1 and sig_s2; end process proc2; end architecture behavior ; Variables, Signals usually translate into Wires PS: Simulation mismatch –synthesis collapses multiple simulation cycles var_s1var_s2 sig_s1 sig_s2
18 Variables and Signals
ENG6530 RCS19 Inferring Storage for Variables A variable used before it is defined There exists an execution sequence (first) where use precedes definition architecture behavior of sig_var is begin process variable var_s1, var_s2 :std_logic; begin wait until (rising_edge(clk)); var_s1 := x nand var_s2; var_s2 := var_s1 xor y; res <= var_s1 xor var_s2; end process; end behavior; var_s2 Latch? Why?
20 library IEEE; use IEEE.std_logic_1164.all; ENTITY mux2 is PORT(a : IN std_logic; b : IN std_logic; sel : IN std_logic; y : OUT std_logic); END mux2; ARCHITECTURE behavior OF mux2 IS BEGIN y <= a WHEN (sel = '0') ELSE b WHEN (sel = '1') ELSE 'X'; END behavior; library IEEE; use IEEE.std_logic_1164.all; ENTITY mux2 is PORT(a : IN std_logic; b : IN std_logic; sel : IN std_logic; y : OUT std_logic); END mux2; ARCHITECTURE behavior OF mux2 IS BEGIN y <= a WHEN (sel = '0') ELSE b WHEN (sel = '1') ELSE 'X'; END behavior; Concurrent When Statement
ENG6530 RCS21 library IEEE; use IEEE.std_logic_1164.all; ENTITY mux4 is PORT(a : IN std_logic; b : IN std_logic; c : IN std_logic; d : IN std_logic; sel : IN std_logic_vector(1 DOWNTO 0); y : OUT std_logic); END mux4; ARCHITECTURE behavior OF mux4 IS BEGIN WITH sel SELECT y <= a WHEN "00", b WHEN "01", c WHEN "10", d WHEN "11", 'X' WHEN OTHERS; END behavior; library IEEE; use IEEE.std_logic_1164.all; ENTITY mux4 is PORT(a : IN std_logic; b : IN std_logic; c : IN std_logic; d : IN std_logic; sel : IN std_logic_vector(1 DOWNTO 0); y : OUT std_logic); END mux4; ARCHITECTURE behavior OF mux4 IS BEGIN WITH sel SELECT y <= a WHEN "00", b WHEN "01", c WHEN "10", d WHEN "11", 'X' WHEN OTHERS; END behavior; Concurrent With Statements
ENG6530 RCS22 Synthesis of Case Statement
ENG6530 RCS23 Synthesis of an IF Statement
ENG6530 RCS24 Case vs. If Statements Case vs. If Statements Any case statement does have an equivalent (functionally) formulation in an if-then-elsif form. priority However the if-then-else must produce priority logic to maintain the priority order implicit in the nesting of the branches. This is not the situation for the case statement. Which is more efficient? the case statementa more efficient As a result we would expect that the case statement is a more efficient alternative when there is no priority ordering among the alternatives.
ENG6530 RCS25 Inference of basic Memory Elements VHDL code should be clear so that the pre- designed cells can be inferred. VHDL code can (might) produce: D Latch Positive edge-triggered D FF Negative edge-triggered D FF D FF with asynchronous reset
ENG6530 RCS26 Latch vs. Flip Flop Inference latch inference Predicates in conditional expressions lead to latch inference –if ( sel = ‘1’) then... flip flop inference Edge detection expressions lead to flip flop inference –if (rising_edge(clk)) then... –if (clk’event and clk = ‘0’) then.. –if (clk’lastvalue = ‘0’ and clk = ‘1’ and clk’event)..
ENG6530 RCS27 FlipFlop/Latch Inference Rules
28 D Latch
29 Variable as Latch
ENG6530 RCS30 Nested Constructs: D Latch architecture behavior of nested_if is begin process (x,y,z,sel1,sel2,sel3) begin if (sel1 = ‘1’)then res <= x and y; elsif (sel2 =’1’) then res <= y xor z; elsif (sel3 =’1’) then res <= x or y; end if; end process; Latch inference due to the absence of the last “else” sel1 sel2 sel3 x y z res Condition under which a latch is inferred When sel1,sel2,sel3 are all zero Add an else to avoid latch inferring
31 Positive Edge Triggered FF
32 D FF with Async Reset
33 Two Types of Resets
ENG6530 RCS34 Conditional Statement architecture behavior of inflate is begin process (x, y, z, sel) is variable s1, s2: std_logic; begin if (sel = ‘1’)then s1:= x and z; s2:= s1 xor y; w <= s2 and s1; -- w gets a value only conditionally end if; -- hence a latch is inferred end process; end architecture behavior; conditional body latch enable S1 S2 How can we avoid latch inference?
ENG6530 RCS35 Revisit the Example architecture behavior of inflate is begin process (x, y, z, sel) is variable s1, s2: std_logic; begin w <= ‘0’; -- output signal set to a default value to avoid latch inference if (sel = ‘1’)then s1:= x and z; -- body generates combinational logic s2:= s1 xor y; w <= s2 and s1; end if; end process; end architecture behavior; No Latches
ENG6530 RCS36 Muxes vs. Latches
ENG6530 RCS37 Case Statements Synthesis of a multiplexor Any incomplete when clause syntax error architecture behavior of case_st is begin process (x,y,z,sel) is begin case sel is when 0 => res <= x and y; when 1 => res <= y xor z; when 2 => res <= x nand z; when others => res <= x nor z; end case; end process; end architecture behavior; No Latch
ENG6530 RCS38 Case Statements (cont.) Use of the “null” statement and latch inference How do we avoid a latch in this case? How do we avoid a latch in this case? architecture behavior of case_ex is begin process (x,y,z,sel) is begin case sel is when 0 => res <= x and y; when 1 => res <= y xor z; when 2 => res <= x nand z; when others => null; -- in this case the value of res -- remains unaltered end case; end process; end architecture behavior;
ENG6530 RCS39 Case Statements: Avoiding Latches 1) By having an initialization statement prior to case. 2) Use don’t care values in the “when others” clause often synthesis compilers can use this information to optimize the generated hardware. architecture behavior of case_ex is begin process (x,y,z,sel) is Begin res <= ‘0’; case sel is when 0 => res <= x and y; when 1 => res <= y xor z; when 2 => res <= x nand z; when others => null; -- in this case the value of res -- remains unaltered end case; end process; end architecture behavior;
ENG6530 RCS40 Process: Incomplete Sensitivity List signal a, b, c, y: std_logic ….. process (a, b, c) is begin y <= a and b and c end process; This implies some sort of memory element When the ‘a’ signal changes, the process is activated and the circuit acts as expected. On the other hand, when ‘b’ or ‘c’ signal changes, the process remains suspended and the ‘y’ signal keeps its previous value. This implies that the circuit has some sort of memory element signal a, b, c, y: std_logic ….. process (a) is begin y <= a and b and c end process;
ENG6530 RCS41 Synthesis Modeling Issues Ensuring compatibility between simulation and synthesis. Both VHDL descriptions below generate the same synthesis output, but differ in their simulation. Process (enable, in1, in2) Process (enable, in1, in2, in3) begin if (enable =‘0’) then output <= (in1 and in2) or in3; output <= (in1 and in2) or in3; end if ; end if; end process; Full sensitivity list Note: most synthesis tools ignore the sensitivity list, but IEEE RTL standard recommends using a full sensitivity list to ensure compatibility with the simulation. Incomplete sensitivity list
ENG6530 RCS42 Avoiding Latch Inference Ensure every path computes a value for every signal –Presence of the else branch »Nested structures »if-then-elsif structure –Complete sensitivity list –Use initial values Basic principle: ensure that every combination of input signal values leads to a computation of a value for every output signal combinational logic
ENG6530 RCS43 Synthesis of 3-state Driver To specify that an output should be set to the high-impedance state, we use a signal of type std_logic and assign it a value of ‘Z’
ENG6530 RCS44 Tri-State Buses
45 Signal Selection in VHDL Signal selection in VHDL for some FPGA targets could be different from that used for ASICs, as shown below: General signal selection in VHDL if (sel =‘0’) then output <= signal_0; else output <= signal_1; end if; Preferred signal selection for FPGAs using tri-state busses output <= signal_0 when (EnA = ‘1’) else ‘Z’; output <= signal_1 when (EnB = ‘1) else ‘Z’; Signal selection is implemented here using muxes In some FPGAs, muxes can be expensive, and tri-state buffers are cheaper
ENG6530 RCS46 Loop Statements What/How much hardware should be generated? for loop Most commonly supported is the for loop –Number of iterations is known a priori –Loop is unrolled and optimized as a sequence of sequential statements shift_reg (3) <= shift_reg (2); shift_reg (2) <= shift_reg (1); shift_reg (1) <= shift_reg (0); for N in 3 downto 1 loop shift_reg (n) <= shift_reg (n-1); end loop;
ENG6530 RCS47 While loop: unrolling
48 Replicated Logic: Procedures
ENG6530 RCS49 While Statements
50 Synthesis Modeling Issues optimization through resource sharing Using parentheses in arithmetic expressions facilitates optimization through resource sharing, and specification of concurrency, and improves critical path. The second statement below has a shorter critical path, for instance, d Output <= a + b + c + d; Output <= (a + b) + (c + d) a bcd a b c
51 Efficiency Considerations circuit size Now that we can control latch inferencing what about circuit size and speed? Move common operations (hardware) out of the branches –Good programming practice in general –Trade multiplexors for more expensive hardware Set up operands
52 Efficiency Considerations
53 Efficiency Considerations
54 Efficiency Considerations Computation (logical AND) preceded by operand selection (mux) entity inference is port (sel : in std_logic; x, y, z: in std_logic; w: out std_logic ); end inference; architecture behavior of inference is begin process (x, y, z, sel) variable right: std_logic; begin if (sel = ‘1’)then right:= y; else right:= z; end if; w <= x and right; end process; end behavior; entity inference is port (sel : in std_logic; x, y, z: in std_logic; w: out std_logic ); end entity inference; architecture behavior of inference is begin process (x, y, z, sel) is begin if (sel = ‘1’)then w <= x and y; else w <= x and z; end if; end process; end architecture behavior;
55 Synthesis Hints: Inferring Storage edge-detection expressions will cause flip- flops Generally, edge-detection expressions will cause flip- flops rather than latches to be inferred. Otherwise latches will be inferred. every execution path through the process must assign a value If you wish to avoid having a latch inferred for a signal in a process then every execution path through the process must assign a value for that signal. use variables in a process before they are defined If you use variables in a process before they are defined a latch will be inferred for that variable. make sure that default values are assigned to signals To avoid the inference of latches, make sure that default values are assigned to signals before a conditional block of code. For variables or signals assigned within a for-loop a default value must be assigned before the for-loop to avoid latch inference.
56 Synthesis Hints Avoid programming in C or Java where we try to exploit the sequentially of the code. This will lead to long signal paths. Attempt to minimize dependencies between statements and try to promote concurrency. generally lead to less hardware Move common complex operations out of the branches of if-then-else statements and place them after the conditional code. This will generally lead to less hardware. Using don’t care values to cover the when others case Using don’t care values to cover the when others case in a case statement can enable the synthesis compiler to optimize the logic and create a smaller circuit than if all remaining options were set to values. produce less logic Using a case statement rather than an if-then-else construct will produce less logic since priority logic will have to be generated for if-..
57 Consistency with Simulation In a simulation model delays can be specified using the after clause in the signal assignment statements. During synthesis the delay value of the operations are derived from the synthesized implementation. This may differ from the values that the designer specified for simulation. Include all signals in a process in the sensitivity list of the process to avoid pre-synthesis and post- synthesis simulation mismatches. Use a VARIABLE instead of a SIGNAL; Variables may be synthesized the same as signals but simulation is faster. Minimize the number of processes. This avoids the overhead of multiple processes suspending and restarting.
ENG6530 RCS58
ENG6530 RCS59 Variables vs. Signals: Example proc1: process (x, y, z) is -- Process 1 variable var_s1, var_s2: std_logic; begin L1: var_s1 := x and y; L2: var_s2 := var_s1 xor z; L3: res1 <= var_s1 nand var_s2; end process; proc2: process (x, y, z) -- Process 2 begin L1: sig_s1 <= x and y; L2: sig_s2 <= sig_s1 xor z; L3: res2 <= sig_s1 nand sig_s2; end process; variables signals Distinction between the use of variables vs. signals
ENG6530 RCS60 Relational Operations