# Module 5 – Sequential Logic Design with VHDL

## Presentation on theme: "Module 5 – Sequential Logic Design with VHDL"— Presentation transcript:

Module 5 – Sequential Logic Design with VHDL
EELE 367 – Logic Design Module 5 – Sequential Logic Design with VHDL Agenda Flip-Flops & Latches Counters Finite State Machines State Variable Encoding

Latches Latches we’ve learned all of the VHDL syntax necessary to describe sequential storage elements Let’s review where sequential devices come from SR Latch To understand the SR Latch, we must remember the truth table for a NOR Gate AB F

Latches SR Latch when S=0 & R=0, it puts this circuit into a Bi-stable feedback mode where the output is either: Q=0, Qn=1 Q=1, Qn= AB F AB F (U2) (U1) (U2) (U1) 1 1 1 1

Latches SR Latch - we can force a known state using S & R: Set (S=1, R=0) Reset (S=0, R=1) AB F AB F (U1) (U2) (U1) (U2) (U2) (U1) 1 1 1 1 1 1

Latches SR Latch - we can write a Truth Table for an SR Latch as follows S R Q Qn Last Q Last Qn - Hold Reset Set Don’t Use - S=1 & R=1 forces a 0 on both outputs. However, when the latch comes out of this state it is metastable. This means the final state is unknown.

Latches S’R’ Latch - we can also use NAND gates to form an inverted SR Latch S’ R’ Q Qn Don’t Use Set Reset Last Q Last Qn - Hold

Latches SR Latch w/ Enable - we then can add an enable line using NAND gates remember the Truth Table for a NAND gate AB F a 0 on any input forces a 1 on the output when C=0, the two EN NAND Gate outputs are 1, which forces “Last Q/Qn” when C=1, S & R are passed through INVERTED

Latches SR Latch w/ Enable - the truth table then becomes C S R Q Qn Last Q Last Qn - Hold Reset Set Don’t Use x x Last Q Last Qn - Hold

Latches D Latch - a modification to the SR Latch where R = S’ creates a D-latch when C=1, Q <= D - when C=0, Q <= Last Value C D Q Qn track track x Last Q Last Qn - Hold

Latches VHDL of a D Latch
architecture Dlatch_arch of Dlatch is begin LATCH : process (D,C) begin if (C=‘1’) then Q<=D; Qn<=not D; else Q<=Q; Qn<=Qn; end if; end process; end architecture;

Flip Flops D-Flip-Flops - we can combine D-latches to get an edge triggered storage device (or flop) - the first D-latch is called the “Master”, the second D-latch the “Slave” Master Slave CLK=0, Q<=D “Open” CLK=0, Q<=Q “Close” CLK=1, Q<=Q “Closed” CLK=1, Q<=D “Open” - on a rising edge of clock, D is “latched” and held on Q until the next rising edge

Flip Flops VHDL of a D-Flip-Flop architecture DFF_arch of DFF is begin FLOP : process (CLK) begin if (CLK’event and CLK=1) then recognized by all synthesizers as DFF Q<=D; Qn<=not D; else Q<=Q; Qn<=Qn; end if; end process; end architecture;

Counters Counters - special name of any clocked sequential circuit whose state diagram is a circle - there are many types of counters, each suited for particular applications

Counters Binary Counter - state machine that produces a straight binary count - for n-flip-flops, 2n counts can be produced - the Next State Logic "F" is a combinational SOP/POS circuit - the speed will be limited by the Setup/Hold and Combinational Delay of "F" - this gives the maximum number of counts for n-flip flops

Counters Toggle Flop - a D-Flip-Flop can product a "Divide-by-2" effect by feeding back Qn to D - this topology is also called a "Toggle Flop"

Counters Ripple Counter - Cascaded Toggle Flops can be used to form rippled counter - there is no Next State Logic - this is slower than a straight binary counter due to waiting for the "ripple" - this is good for low power, low speed applications

Counters Synchronous Counter with ENABLE - an enable can be included in a "Synchronous" binary counter using Toggle Flops - the enabled is implemented by AND'ing the Q output prior to the next toggle flop - this gives us the "ripple" effect, but also gives the ability to run synchronously - a little faster, but still less gates than a straight binary circuit

Counters Shift Register - a chain of D-Flip-Flops that pass data to one another - this is good for "pipelining" - also good for Serial-to-Parallel conversion - for n-flip-flops, the data is present at the final state after n clocks

Counters Ring Counter - feeding the output of a shift register back to the input creates a "ring counter" - also called a "One Hot" - The first flip-flop needs to reset to 1, while the others reset to 0 - for n flip-flops, there will be n counts

Counters Johnson Counter - feeding the inverted output of a shift register back to the input creates a "Johnson Counter" - this gives more states with the same reduced gate count - all flip-flops can reset to 0 - for n flip-flops, there will be 2n counts

Counters Linear Feedback Shift Register (LFSR) Counter - all of the counters based off of shift registers give far less states than the 2n counts that are possible - a LFSR counter is based off of the theory of finite fields - created by French Mathematician Evariste Galois ( ) - for each size of shift register, a feedback equation is given which is the sum modulo 2 of a certain set of output bits - this equation produces the input to the shift register - this type of counter can produce 2n-1 counts, nearly the maximum possible

Counters Linear Feedback Shift Register (LFSR) Counter - the feedback equations are listed in Table 8.26 of the textbook - It is defined that bits always shift from Xn-1 to X0 (or Q0 to Qn-1) as we defined the shift register previously - they each use XOR gates (sum modulo 2) of particular bits in the register chain ex) n Feedback Equation 2 X2 = X1  X0 3 X3 = X1  X0 4 X4 = X1  X0 5 X5 = X2  X0 6 X6 = X1  X0 7 X7 = X3  X0 8 X8 = X4  X3  X2  X0 : : : :

Counters Linear Feedback Shift Register (LFSR) Counter ex) 4-flip-flop LFSR Counter Feedback Equation = X1  X0 (or Q2  Q3 as we defined it) # Q(0:3) Sin this is 2n-1 unique counts repeat 1000

Counters Counters in VHDL - strong type casting in VHDL can make modeling counters difficult (at first glance) - the reason for this is that the STANDARD and STD_LOGIC Packages do not define "+", "-", or inequality operators for BIT_VECTOR or STD_LOGIC_VECTOR types

Counters Counters in VHDL - there are a couple ways that we get around this 1) Use the STD_LOGIC_UNSIGNED Package this package defines "+" and "-" functions for STD_LOGIC_VECTOR we can use +1 just like normal the vector will wrap as suspected ( ) one catch is that we can't assign to a Port we need to create an internal signal of STD_LOGIC_VECTOR for counting we then assign to the Port at the end

Counters Counters in VHDL using STD_LOGIC_UNSIGNED use IEEE.STD_LOGIC_UNSIGNED.ALL; call the package entity counter is Port ( Clock : in STD_LOGIC; Reset : in STD_LOGIC; Direction : in STD_LOGIC; Count_Out : out STD_LOGIC_VECTOR (3 downto 0)); end counter;

Counters Counters in VHDL using STD_LOGIC_UNSIGNED
architecture counter_arch of counter is signal count_temp : std_logic_vector(3 downto 0); -- Notice internal signal begin process (Clock, Reset) if (Reset = '0') then count_temp <= "0000"; elsif (Clock='1' and Clock'event) then if (Direction='0') then count_temp <= count_temp + '1'; -- count_temp can be used on both LHS and RHS else count_temp <= count_temp - '1'; end if; end process; Count_Out <= count_temp; assign to Port after the process end counter_arch;

Counters Counters in VHDL 2) Use integers for the counter and then convert back to STD_LOGIC_VECTOR STD_LOGIC_ARITH is a Package that defines a conversion function the function is: conv_std_logic_vector (ARG, SIZE) functions are defined for ARG = integer, unsigned, signed, STD_ULOGIC SIZE is the number of bits in the vector to convert to, given as an integer we need to keep track of the RANGE and Counter Overflow

Counters Counters in VHDL using STD_LOGIC_ARITH use IEEE.STD_LOGIC_ARITH.ALL; call the package entity counter is Port ( Clock : in STD_LOGIC; Reset : in STD_LOGIC; Direction : in STD_LOGIC; Count_Out : out STD_LOGIC_VECTOR (3 downto 0)); end counter;

Counters Counters in VHDL using STD_LOGIC_ARITH
architecture counter_arch of counter is signal count_temp : integer range 0 to 15; -- Notice internal integer specified with Range begin process (Clock, Reset) if (Reset = '0') then count_temp <= 0; integer assignment doesn't requires quotes elsif (Clock='1' and Clock'event) then if (count_temp = 15) then count_temp <= 0; we manually check for overflow else count_temp <= count_temp + 1; end if; end process; Count_Out <= conv_std_logic_vector (count_temp, 4); -- convert integer into a 4-bit STD_LOGIC_VECTOR end counter_arch;

Counters Counters in VHDL 3) Use UNSIGNED data types #'s STD_LOGIC_ARITH also defines "+", "-", and equality for UNSIGNED types UNSIGNED is a Data type defined in STD_LOGIC_ARITH UNSIGNED is an array of STD_LOGIC An UNSIGNED type is the equivalent to a STD_LOGIC_VECTOR type the equality operators assume it is unsigned (as opposed to 2's comp SIGNED) Pro's and Cons - using integers allows a higher level of abstraction and more functionality can be included - easier to write unsynthesizable code or code that produces unwanted logic - both are synthesizable when written correctly

Counters Ring Counters in VHDL - to mimic the shift register behavior, we need access to the signal value before and after clock'event - consider the following concurrent signal assignments: architecture … begin Q0 <= Q3; Q1 <= Q0; Q2 <= Q1; Q3 <= Q2; end architecture… - since they are executed concurrently, it is equivalent to Q0=Q1=Q2=Q3, or a simple wire

Counters Ring Counters in VHDL - since a process doesn't assign the signal values until it suspends, we can use this to model the "before and after" behavior of a clock event. process (Clock, Reset) begin if (Reset = '0') then Q0<='1'; Q1<='0'; Q2<='0'; Q3<='0'; elsif (Clock'event and Clock='1') then Q0<=Q3; Q1<=Q0; Q2<=Q1; Q3<=Q2; end if; end process - notice that the signals DO NOT appear in the sensitivity list. If they did the process would continually execute and not be synthesized as a flip-flop structure

Counters Johnson Counters in VHDL process (Clock, Reset) begin if (Reset = '0') then Q0<='0'; Q1<='0'; Q2<='0'; Q3<='0'; elsif (Clock'event and Clock='1') then Q0<=not Q3; Q1<=Q0; Q2<=Q1; Q3<=Q2; end if; end process

Counters Linear Feedback Shift Register Counters in VHDL process (Clock, Reset) begin if (Reset = '0') then Q0<='0'; Q1<='0'; Q2<='0'; Q3<='0'; elsif (Clock'event and Clock='1') then Q0<=Q3 xor Q2; Q1<=Q0; Q2<=Q1; Q3<=Q2; end if; end process

Counters Multiple Processes - we can now use State Machines to control the start/stop/load/reset of counters - each are independent processes that interact with each other through signals - a common task for a state machine is: 1) at a certain state, load and enable a counter 2) go to a state and wait until the counter reaches a certain value 3) when it reaches the certain value, disable the counter and continue to the next state - since the counter runs off of a clock, we know how long it will count between the start and stop

State Machines State Machines - there is a basic structure for a Clocked, Synchronous State Machine 1) State Memory (i.e., flip-flops) 2) Next State Logic “G” (combinational logic) 3) Output Logic “F” (combinational logic) we’ll revisit F later… - if we keep this structure in mind while designing digital machines in VHDL, then it is a very straight forward task - Each of the parts of the State Machine are modeled with individual processes - let’s start by reviewing the design of a state machine using a manual method

State Machines State Machines “Mealy Outputs” – outputs depend on the Current_State and the Inputs

State Machines State Machines “Moore Outputs” – outputs depend on the Current_State only

State Machines State Machines - the steps in a state machine design are: 1) Word Description of the Problem 2) State Diagram 3) State/Output Table 4) State Variable Assignment 5) Choose Flip-Flop type 6) Construct F 7) Construct G 8) Logic Diagram

State Machines State Machine Example “Sequence Detector” 1) Design a machine by hand that takes in a serial bit stream and looks for the pattern “1011”. When the pattern is found, a signal called “Found” is asserted 2) State Diagram

State Machines State Machine Example “Sequence Detector” 3) State/Output Table Current_State In Next_State Out (Found) S0 0 S S S1 0 S S S2 0 S S S3 0 S S0 1

State Machines State Machine Example “Sequence Detector” 4) State Variable Assignment – let’s use binary Current_State In Next_State Out Q1 Q0 Q1* Q0* Found ) Choose Flip-Flop Type % of the time we use D-Flip-Flops

State Machines State Machine Example “Sequence Detector” 6) Construct Next State Logic “F” Q1* = Q1’∙Q0∙In’ + Q1∙Q0’∙In Q0* = Q0’∙In Q1 Q0 Q1 In 00 01 11 10 2 1 6 4 1 3 7 1 5 In 1 Q0 Q1 Q0 Q1 In 00 01 11 10 2 6 4 1 1 3 7 5 1 In 1 Q0

State Machines State Machine Example “Sequence Detector” 7) Construct Output Logic “G” Found = Q1∙Q0∙In ) Logic Diagram - for large designs, this becomes impractical Q1 Q0 Q1 In 00 01 11 10 2 6 4 1 3 7 1 5 In 1 Q0

State Machines in VHDL State Memory - we use a process that updates the “Current_State” with the “Next_State” - we describe DFF’s using (CLK’event and CLK=‘1’) - this will make the assignment on the rising edge of CLK STATE_MEMORY : process (CLK) begin if (CLK’event and CLK='1') then Current_State <= Next_State; end if; end process; - at this point, we need to discuss State Names

State Machines in VHDL State Memory using “User-Enumerated Data Types" - we always want to use descriptive names for our states - we can use a user-enumerated type for this type State_Type is (S0, S1, S2, S3); signal Current_State : State_Type; signal Next_State : State_Type; - this makes our simulations very readable. State Memory using “Pre-Defined Data Types" - we haven’t encoded the variables though, we can either leave it to the synthesizer or manually do it subtype State_Type is BIT_VECTOR (1 downto 0); constant S0 : State_Type := “00”; constant S1 : State_Type := “01”; constant S2 : State_Type := “10”; constant S3 : State_Type := “11”; signal Current_State : State_Type; signal Next_State : State_Type;

State Machines in VHDL State Memory with “Synchronous RESET” STATE_MEMORY : process (CLK) begin if (CLK’event and CLK='1') then if (Reset = ‘1’) then Current_State <= S0; -- name of “reset” state to go to else Current_State <= Next_State; end if; end if; end process; - this design will only observe RESET on the positive edge of clock (i.e., synchronous)

State Machines in VHDL State Memory with “Asynchronous RESET” STATE_MEMORY : process (CLK, Reset) begin if (Reset = ‘1’) then Current_State <= S0; -- name of “reset” state to go to elsif (CLK’event and CLK='1') then Current_State <= Next_State; end if; end process; - this design is sensitive to both RESET and the positive edge of clock (i.e., asynchronous)

State Machines in VHDL Next State Logic “F” - we use another process to construct “F”

State Machines in VHDL Next State Logic “F” - the process will be combinational logic NEXT_STATE_LOGIC : process (In, Current_State) begin case (Current_State) is when S0 => if (In=‘0’) then Next_State <= S0; elsif (In=‘1’) then Next_State <= S1; end if; when S1 => if (In=‘0’) then Next_State <= S2; elsif (In=‘1’) then Next_State <= S0; end if; when S2 => if (In=‘0’) then Next_State <= S0; elsif (In=‘1’) then Next_State <= S3; end if; when S3 => if (In=‘0’) then Next_State <= S0; elsif (In=‘1’) then Next_State <= S0; end if; end case; end process;

State Machines in VHDL Output Logic “G” - we use another process to construct “G” - the expressions in the sensitivity list dictate Mealy/Moore type outputs - for now, let’s use combinational logic for G (we’ll go sequential later)

State Machines in VHDL Output Logic “G” - Mealy type outputs OUTPUT_LOGIC : process (In, Current_State) begin case (Current_State) is when S0 => if (In=‘0’) then Found <= 0; elsif (In=‘1’) then Found <= 0; end if; when S1 => if (In=‘0’) then Found <= 0; elsif (In=‘1’) then Found <= 0; end if; when S2 => if (In=‘0’) then Found <= 0; elsif (In=‘1’) then Found <= 0; end if; when S3 => if (In=‘0’) then Found <= 0; elsif (In=‘1’) then Found <= 1; end if; end case; end process;

State Machines in VHDL Output Logic “G” - Moore type outputs OUTPUT_LOGIC : process (Current_State) begin case (Current_State) is when S0 => Found <= 0; when S1 => Found <= 0; when S2 => Found <= 0; when S3 => Found <= 1; end case; end process; - this is just an example, it doesn’t really work for this machine

State Machines in VHDL Example - Let’s design a 2-bit Up/Down Gray Code Counter using User-Enumerated State Encoding - In=0, Count Up - In=1, Count Down - this will be a Moore Type Machine - no Reset

State Machines in VHDL Example - let’s collect our thoughts using a State/Output Table Current_State In Next_State Out CNT0 0 CNT CNT3 CNT1 0 CNT CNT0 CNT2 0 CNT CNT1 CNT3 0 CNT CNT2

State Machines in VHDL Example architecture CNT_arch of CNT is type State_Type is (CNT0, CNT1, CNT2, CNT3); signal Current_State, Next_State : State_Type; begin STATE_MEMORY : process (CLK) begin if (CLK’event and CLK='1') then Current_State <= Next_State; end if; end process; NEXT_STATE_LOGIC : process (In, Current_State) begin case (Current_State) is when CNT0 => if (In=‘0’) then Next_State <= CNT1; elsif (In=‘1’) then Next_State <= CNT3; end if; when CNT1 => if (In=‘0’) then Next_State <= CNT2; elsif (In=‘1’) then Next_State <= CNT0; end if; when CNT2 => if (In=‘0’) then Next_State <= CNT3; elsif (In=‘1’) then Next_State <= CNT1; end if; when CNT3 => if (In=‘0’) then Next_State <= CNT0; elsif (In=‘1’) then Next_State <= CNT2; end if; end case; end process; OUTPUT_LOGIC : process (Current_State) begin case (Current_State) is when CNT0 => Out <= “00”; when CNT1 => Out <= “01”; when CNT2 => Out <= “11”; when CNT3 => Out <= “10”; end case; end process; end architecture;

State Machines in VHDL Example - in the lab, we may want to observe the states on the LEDs - in this case we want to explicitly encode the STATE variables architecture CNT_arch of CNT is subtype State_Type is BIT_VECTOR (1 dowto 0); constant CNT0 : State_Type := “00”; constant CNT1 : State_Type := “01”; constant CNT2 : State_Type := “10”; constant CNT3 : State_Type := “11”; signal Current_State, Next_State : State_Type;

State Encoding State Variable Encoding - we can decide how we encode our state variables - there are advantages/disadvantages to different techniques Binary Encoding - straight encoding of states S0 = “00” S1 = “01” S2 = “10” S3 = “11” - for n states, there are log(n)/log(2) flip-flops needed - this gives the Least # of Flip-Flops - Good for “Area” constrained designs - Drawbacks: - multiple bits switch at the same time = Increased Noise & Power - the Next State Logic “F” is multi-level = Increased Power and Reduced Speed

State Encoding Gray-Code Encoding - encoding using a gray code where only one bits switches at a time S0 = “00” S1 = “01” S2 = “11” S3 = “10” - for n states, there are log(n)/log(2) flip-flops needed - this gives low Power and Noise due to only one bit switching - Good for “Power/Noise” constrained designs - Drawbacks: - the Next State Logic “F” is multi-level = Increased Power and Reduced Speed

State Encoding One-Hot Encoding - encoding one flip-flop for each state S0 = “0001” S1 = “0010” S2 = “0100” S3 = “1000” - for n states, there are n flip-flops needed - the combination logic for F is one level (i.e., a Decoder) - Good for Speed - Especially good for FPGA due to “Programmable Logic Block” - Drawbacks: - takes more area

State Encoding State Encoding Trade-Offs - We typically trade off Speed, Area, and Power One-Hot speed area power Binary Gray

Pipelined Outputs Pipelined Outputs - Having combinational logic drive outputs can lead to: multiple delay paths through the logic - potential for glitches - Both reduce the speed at which the system clock can be ran - A good design practice is to pipeline the outputs (i.e., use DFF’s as the output driver)

Pipelined Outputs Pipelined Outputs - This gives a smaller Data Uncertainty window on the output - The only consideration is that the output is not present until one clock cycle later

Pipelined Outputs Pipelined Outputs - we use a 4th process for this stage of the State Machine PIPELINED_OUTPUTS : process (CLK) begin if (CLK’event and CLK='1') then Out <= Next_Out; end if; end process;

Asynchronous Inputs Asynchronous Inputs - Real world inputs are not phase-locked to the clock - this means an input can change within the Setup/Hold window of the clock - this can send the Machine into an incorrect state - we always want to “synchronize” inputs so that this doesn’t happen

Asynchronous Inputs Asynchronous Inputs - We use D-Flip-Flops to take in the input - with one D-Flip-Flop, the input can still occur within the Setup/Hold window - the output of the first DFF may be metastable for a moment of time (trecovery) - a second DFF is used to latch in the metastable input after it has had time to settle - the output of the second flip-flop is now stable and synchronized as long as: Tclk > trecovery + tcomb + tsetup - where tcomb is the delay of any combinational logic in the input path