VHDL Constructs CRICOS 00111D TOID 3059 Sequential & Concurrent Statements There are two types of statements –Sequential • Statements within a process • Evaluated sequentially during simulation and UPDATED AT the END of PROCESS –Concurrent • Statements outside of a process • Processes are evaluated concurrently, because they are treated as concurrent statements. Processes Processes Describe Sequential Behaviour. Processes in VHDL are a convenient way of implementing more complex operations that may be difficult to represent by a real circuit A process is a group of sequential statements that are executed when certain events happen. Only certain kinds of statements are allowed within processes. Not every process can be synthesized – Use Processes with Caution in the Code to be Synthesized You may use Processes freely in Testbenches. Process Example Label: process(Sensitivity List) [Declaration Part] begin [Sequential Part] end process; Optional signal A, B, C : std_logic; process( A, B ) begin C <= not B; B <= not A; end process; Sensitivity list. Process is re-executed whenever A or B changes. A process can be given a unique name using an optional LABEL This is followed by the keyword PROCESS The keyword BEGIN is used to indicate the start of the process All statements within the process are executed SEQUENTIALLY. Hence, the order of statements is important. A process must end with the keywords END PROCESS. Processes A VHDL process may have a sensitivity list. Any change in a signal in the sensitivity list causes the process to be re-executed. – Other methods using ‘wait’ are possible – not discussed here (EEE40002) – A process without a sensitivity list will ‘loop’. – WAIT statements are NOT ALLOWED in a processes with SENSITIVITY LIST. Lots of room for error! – Classic is forgetting a signal in the sensitivity list. Generally the simulation will almost work and surprisingly the hardware synthesised may actually be correct. However the simulation will not reflect the real hardware behaviour. Xilinx Synthesis Tool (XST) will warn of this – don’t ignore it! d-time for Processes Statements within a process are executed sequentially unlike statements outside a process. BUT changes to signals all occur at the same time* which is 1 delta-time later (T+d). * If no explicit delay is specified. A B C signal A, B, C : std_logic; process( A, B ) begin B <= not A; C <= not B; end process; Sensitivity list. Process is re-executed whenever A or B changes. - 0 1 0 T 1 1 0 T+d 1 0 0 T+2d 1 0 1 A B C Process executes twice – once for each change of A and B d-time Process Example Process executes twice to propagate the change at A through B to C. d d A A B B C C A B 1 C 2 Zero real time Statements within a Process Executed sequentially. –Sequential in terms of statements later in the process override the effects of earlier statements. –BUT, since the effects of assignments don’t happen until T+d, statements later in the process do not see the new values until the process re-executes. (Ignores waits!) –Only the last of multiple assignments to a signal will have effect. Exercise Complete the timing diagram for the simulation of the process below. signal A, B, C : std_logic; process( A ) begin B <= not A; C <= not B; end process; A B C The process is sensitive to ‘A’ only. How many times will the process be executed? Exercise (Soln.) Missing signal in sensitivity list leads to a simulation error. signal A, B, C : std_logic; process( A, B ) begin B <= not A; C <= not B; end process; A B C Missing Signal, DB doesn’t propagate 1st time process runs 2nd time process runs Problem! Exercise Corrected VHDL & expected operation signal A, B, C : std_logic; process( A, B ) begin B <= not A; C <= not B; end process; A B C 1st (T) & 2nd (T+d) time process runs 3rd & 4th time process runs VHDL statements Behavioral Modelling Sequential Statements within a Process signal assignment. if … elsif … else … end if statements. case statements. loop and exit statements. while loops, for loops. assert statements. Dataflow Modelling Concurrent statements outside the Process signal assignment. Conditional Signal Assignment (CSA) Selected Signal Assignment (SSA) For-Generate statements assert statements. Sequential and Concurrent signal assignment When the signal assignment appears within the body of a process it is regarded as a sequential statement. However, whenever it appears outside a process it is called a concurrent statement. All concurrent statements execute whenever a signal in their sensitivity list changes. The order of the concurrent statements is not important. However the order of sequential statements are important, in the case of overwriting signals. Sequential and Concurrent signal assignment Behavioral Modelling Sequential Signal Assignment Dataflow Modelling Concurrent Signal Assignment Architecture of entity1 is begin Process (A,B,Y) begin A <= B ; Z <= A ; X <= Y ; end process; end; Architecture of entity1 is begin A <= B ; Z <= A ; X <= Y ; end ; if … elsif … else … end if statements The expressions checked in an if statement may be quite complex. There is no requirement that it be a constant. They must evaluate to a Boolean result i.e. true or false. This is not the same as '0' or '1'! Multiple, arbitrary statements may be used for the actions – unlike conditional assignment! Conditional Signal Assignment (CSA) CSA is the concurrent version of “if”. It has only one target Must have unconditional else Whenever an event occurs on any of the signals or conditions, the conditional assignment is executed. The first true condition will have that signal assigned. Syntax target-signal <= waveform-elements when condition1 else waveform-elements when condition2 else waveform-elements when condition3 else … else waveform; If..elsif..else..end if statements = Conditional Signal Assignment (CSA) Behavioral Modeling Sequential Statement in a process [if..elsif..else..end if] Dataflow Modeling Concurrent statement in the architecture [CSA] Arbitrary Boolean conditions that may overlap. Note priority in expression! Each condition is tested in order. if E = '1' then F <= A; elsif D = '1' then F <= '0'; else F <= C; end if; Assignment to signal is dependent on a condition or conditions. Entire expression is re-evaluated whenever any signal on the right changes (A, E, D or C). Note priority in expression! E is more important than D. C 0 0 1 A D 0 1 F <= A when E = '1' else '0' when D = '1' else C; F E Exercise Complete the timing diagram. signal A, B : std_logic; process( A ) begin B <= '0'; if (A = '0') then B <= '1'; end if; end process; A B Exercise (Soln.) Complete the timing diagram. signal A, B : std_logic; ...... process( A ) begin B <= '0'; -- statement #1 if (A='0') then B <= '1'; -- statement #2 end if; st time process 1 end process; nd 2 runs time process runs A B Statement #1 only Statement #1 followed by #2 Note: Only one d-time involved irrespective of path and number of assignments. Exercise Provide truth-tables and draw un-simplified equivalent circuits for the following CSA statements: h <= '0' when '1' j <= a when c b; k <= '0' when '1' when not c; a = '1' else = '1' else a = '1' and b = '1' else a = '0' else Exercise - Working Exercise - Solution * Exercise - Working k <= '0' when a = '1' and b = '1' else '1' when a = '0' else not c; abc 000 001 010 011 100 101 110 111 k * Exercise - Solution k <= '0' when a = '1' and b = '1' else '1' when a = '0' else not c; 1 c a 0 1 0 0 1 k b Note: The final circuit synthesized would be a simplification of the above but MUST function equivalently. e.g. k <= not a or (not b and not c) abc 000 001 010 011 100 101 110 111 k 1 1 1 1 1 0 0 0 case statement The expression checked in a case statement must be a static constant (huh?) This means that the compiler must be able to work out the value of the expression. Another way of saying this is that it can’t depend on the execution of the VHDL. ü3*4 OK since the compiler can calculate 12. ûi>4 not OK since the value of i depends on the execution (unless i is a constant of course). Static expression case statement t <= a&b; case t is when "00" when "01" when "10" when "11" when others end case; I0 I1 I2 I3 => => => => => o o o o o o A B <= <= <= <= <= I0; I1; I2; I3; 'X'; Any sequential statement(s) Needed to handle the other std_logic possibilities. In this case affects simulation but not synthesis (Why?). This statement does not have priority – selection values are expected to be mutually exclusive and exhaustive of possibilities. Use “others” clause to add default action – important to prevent latches. Selected Signal Assignment Statement SSA is the concurrent version of CASE rules are the same as CASE. Only one target The selected signal assignment selects different values for a target signal based on the value of a select expression. Syntax with expression select target-signal<= waveform-elements when choices, waveform-elements when choices, … waveform-elements when choices; Case Statement = Selected Signal Assignment Behavioral Modeling Case Statement Dataflow Modeling Selected Signal Assignment Architecture USE_CASE of … is begin process ( A, B, C, X) begin case X is when 0 to 4 => Z <= B; when 5 => Z <= C; when others => Z <= A; end case; end process; end USE_CASE; Architecture USE_SELECTED of … is begin with X select Z <= B when 0 to 4; C when 5; A when others; end USE_SELECTED ; Exercise signal a,b,c : std_logic; signal t : std_logic_vector(1 downto 0); ...... process( a, b, t ) begin t <= a&b; case t is when "00" => c <= '0'; when "01" => c <= '1'; when "11" => c <= '0'; when others => c <= 'X'; end case; end process; t A B C * Exercise (Soln.) signal a,b,c : std_logic; signal t : std_logic_vector(1 downto 0); ...... process( a, b, t ) begin t <= a&b; case t is when "00" => c <= '0'; when "01" => c <= '1'; when "11" => c <= '0'; when others => c <= 'X'; end case; end process; Process triggered twice each time (T, T+d). A B C XXXXXX for … loop … statements clkLoop: for count in 1 to 9 loop clock <= '0'; wait for 10 ns; clock <= '1'; wait for 10 ns; end loop; Clock runs for 9 periods. Don’t confuse this with a counter. This indicates iteration when running the VHDL code – not a counter in hardware! Useful for simulation. for … loop … statements signal a,b,res : std_logic_vector( 7 downto 0); … for count in 7 downto 0 loop res(count) <= a(count) and b(count); end loop; This code will generate 8 AND-gates – one for each set of corresponding bits of a, b and res. Note: Just an example – it is more sensible to use: res<= a and b; Loop Unrolling for count in 1 to 4 loop a(count) <= b(count) or alf; end loop; a(1) a(2) a(3) a(4) <= <= <= <= b(1) b(2) b(3) b(4) or or or or alf; alf; alf; alf; For-Generate Statements The for-generate statement consists of a generation scheme and a set of enclosed concurrent statements The Label is a must for the For-Generate Statements Label: For identifier in range generate Begin {Concurrent Statements} end generate Label; Provides an easy way of instantiating components when we have an iterative array of identical components For...loop…statements = For…Generate… statements Behavioral Modeling For...loop… Statement Dataflow Modeling For…Generate… statements signal a,b,res : std_logic_vector( 7 downto 0); … process( a, b) begin for count in 7 downto 0 loop res(count) <= a(count) and b(count); end loop; end process; signal a,b,res : std_logic_vector( 7 downto 0); … Gen_AND:for count in 7 downto 0 generate res(count) <= a(count) and b(count); end generate Gen_AND; loop and exit statements clkLoop: loop clock <= '0'; wait for 10 ns; clock <= '1'; wait for 10 ns; exit clkLoop when complete = '1'; end loop; wait; -- endless wait to 'hang' process Exit may exit nested loops – Need optional loop name to identify loop being exited. Exit may be used with any of the loop types while … loop … statements -- Simulation Clock clkLoop: process begin while not complete loop clock <= '0'; wait for 10 ns; clock <= '1'; wait for 10 ns; end loop; wait; -- endless wait to 'hang' process end process clkLoop; 10n s 10n s Remember: This example is only useful for simulation! Why? What do Loops Mean?? In simulation we can use loops as in a more usual language – it just indicates iteration. In synthesis the loop range must be a constant. We can think of loop being unrolled to determine how the VHDL is mapped to hardware. Asserts & Reports ASSERT – Assert is a non-synthesizable statement whose purpose is to write out messages on the screen when problems are found during simulation. – Depending on the severity of the problem, The simulator is instructed to continue simulation or halt. Syntax ASSERT condition [REPORT "message" [SEVERITY severity_level ]; – ASSERT statements are used to print messages at the simulation console when specified runtime conditions are met The message is written when the condition is FALSE. – ASSERT statements defined one of four severity levels • • • • Note -- relays information about conditions to the user Warning -- alerts the user to conditions that are not expected, but not fatal Error -- relays conditions that will cause the model to work incorrectly Failure -- alerts the user to conditions that are catastrophic assert statements Used to flag a condition not being met Useful for verification in a testbench Negative logic for the condition Negative logic to look for a not equal 1, we put the condition for a equal 1 assert a = '1' report "a isn't 1!" severity fatal; Optional report clause. Optional severity level clause. May be: note, warning, error, fatal Level is reported, fatal aborts simulation Unintended Latches Consider process( a, c ) begin if (a = "10") then b <= c; elsif (a = "11") then b <= '1'; end if; end process; What happens when a = '00' or '01' ? Feedback Þ latch c '1' 00 01 10 11 b a – The VHDL synthesis produces hardware to maintain the current value of b. This requires feedback which introduces a latch. Generally unintended and undesirable. Unintended Latches A latch will be produced whenever there are two paths through an entire concurrent statement, one of which assigns to a signal and the other does not. process( X ) begin if (X='0') then B <= '1'; end if; end process; B <= '1' when (X='0'); Statement 0 B <= '1' X? 1 Latch generated to hold B’s value when X=1 Preventing Latches Avoid the previous situation –If a signal is assigned in one path it must be assigned in all paths. –Pay particular attention to if and case statements. –Most often a problem in processes Simple solution – Assign default values to any used signals at top of process. – These values may be over-ridden by later code in the process. – A default of 'X' will show up well in simulation, it synthesises to '0'. (Only applies to non-clocked signal!) Preventing Latches Unless you have a very good reason, there should be no latches in VHDL designs. ûTiming analysis is very difficult. ûThe required feedback paths can oscillate. ûProne to misbehave due to glitches which are almost inevitable unless you do hazard analysis. (Almost impossible in VHDL unless you are doing a structural implementation.) Unintended Latches These latches are different to the intentional edge-triggered FFs created by assignments statements made sensitive to a clock (discussed later). if (rising_edge(clock)) if (a = '1') then b <= c; end if; end if; then Clocked assignments c DB a CE clock Return to later. B Testbenches A testbench is a simulation aid. It is used in a way that resembles the realworld use of test equipment. The testbench is a VHDL module that wraps around the module being tested. It takes the place of the real circuit that the module is intended to operate within. The testbench is not synthesised, only simulated, so it may use all of the VHDL language features. Testbench for 1-of-4 Decoder Ports on module sel_ Signals in Testbench 2 sel o 4 o_ decoder_1_of_4 Testbench Testbench applies stimuli to sel. Check outputs on o. Testbench for 1-of-4 Decoder How would you test a combinational circuit on the bench? – Since there is no “memory” it is possible to test the circuit by applying all possible inputs and verifying the outputs. (Go through the truth-table.) A VHDL testbench can do this. We may verify the outputs visually from a waveform or execution trace but it is better to build in VHDL tests for the expected outputs. Testbench for 1-of-4 Decoder Apply stimulus to the ports of the module: – 00, 01, 10, 11 Compare outputs with expected values: – 0001, 0010, 0100, 1000 Note – It is possible to probe the signals within the module being simulated. This is something that often cannot be done for the real circuit. --------------------------------------------------------- Minimal Testbench for 1 of 4 decoder. -------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY decoderTestbench_vhd IS END ENTITY decoderTestbench_vhd; No ports on the testbench! Empty Entity ARCHITECTURE behavior OF decoderTestbench_vhd IS --Component Declaration for the Unit Under Test (UUT) Component decoder_1_of_4 port( sel : IN std_logic_vector(1 downto 0); o : OUT std_logic_vector(3 downto 0)); --Inputs to the device being tested SIGNAL sel_ : std_logic_vector(1 downto 0) := (others=>'0'); --Outputs from the device being tested SIGNAL o_ : std_logic_vector(3 downto 0); BEGIN -- Instantiate the Unit Under Test (UUT) uut:decoder_1_of_4 port map( sel => sel_, -- connect inputs o => o_ -- connect outputs ); -- Testbench process - Apply stimuli tb : PROCESS BEGIN -- Combinational cct. -- Apply all possible input combinations sel_ <= "00"; wait for 20 ns; sel_ <= "01"; wait for 20 ns; The testbench applies sel_ <= "10"; wait for 20 ns; each input with a sel_ <= "11"; wait for 20 ns; wait; -- will wait forever END PROCESS; END ARCHITECTURE; short wait. Timing Waveforms Behavioural Simulation (unit delay) Post Place & Route Simulation (using estimated device & wire delays) Hazards or skew between outputs Expected delay for real circuit (~8.4 ns)