ECE - 1551 DIGITAL LOGIC LECTURE 20: REGISTERS AND COUNTERS Assistant Prof. Fareena Saqib Florida Institute of Technology Fall 2015, 11/19/2015 Recap Analysis of sequential circuits State reduction and Assignment Design Procedure With DFF With JK FF With T FF Agenda Design Shift Register and Counters D Flip Flop Clk d q 4 D-FF You should use the following ’templates’ to create latches and FFs, so that the predesigned library cells are inferred by the synthesis tools. library ieee; use ieee.std_logic_1164.all; entity dFF is port( c: in std_logic; d: in std_logic; q: out std_logic ); end dFF; architecture arch of dFF is begin -- observe the sensitivity list. process(clk) begin if (rising_edge(clk)) then q <= d; end if; end process; end arch; 5 Register A clocked sequential circuit consists of a group of flip-flops and combinational gates. All Flip Flops share a common clock An n bit register consists of n flip flops. In addition to flip flops, a register might consist of combinational gates that perform certain data processing tasks. A counter is essentially a register that goes through a predetermined sequence of binary states The gates in a counter are connected in a way as to produce the prescribed sequence of states. Various registers are available, the simplest register is one that consists of flip-flops. Figure shows a Register constructed with a 4 DFFs. Register Multiple D FFs with same clock and reset library ieee; use ieee.std_logic_1164.all; entity reg4 is port( clk, reset: in std_logic; d: in std_logic_vector(3 downto 0); q: out std_logic_vector(3 downto 0) ); end reg4; architecture arch of reg4 is begin process(clk, reset) begin if (reset=’1’) then q <= (others=>’0’); elsif (clk’event and clk=’1’) then q <= d; end if; end process; end arch; 7 2 segment Style Follow the block diagram: • Build the register • Code the next-state and output logic (combinational circuits) • Output logic (combinational circuit) 8 D FF with sync enable Note that the en is controlled by clock Note the sensitivity list 9 D FF with sync enable (2 segment style) library ieee; use ieee.std_logic_1164.all; entity dff_en is port( clk: in std_logic; reset: in std_logic; en: in std_logic; d: in std_logic; q: out std_logic ); end dff_en; architecture two_seg_arch of dff_en is signal q_reg: std_logic; signal q_next: std_logic; begin -- D FF process(clk, reset) begin if (reset=’1’) then q_reg <= ’0’; elsif (clk’event and clk=’1’) then q_reg <= q_next; end if; end process; -- next-state logic q_next <= d when en =’1’ else q_reg; -- output logic q <= q_reg; end two_seg_arch; 10 Toggle Flip Flop 11 Toggle Flip Flop library ieee; use ieee.std_logic_1164.all; entity tff is port( clk: in std_logic; reset: in std_logic; t: in std_logic; q: out std_logic ); end tff; architecture two_seg_arch of tff is signal q_reg: std_logic; signal q_next: std_logic; begin -- D FF process(clk, reset) begin if (reset=’1’) then q_reg <= ’0’; elsif (clk’event and clk=’1’) then q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg when t=’0’ else not(q_reg); -- output logic q <= q_reg; end two_seg_arch; 12 Register with Parallel Load Registers with parallel load are a fundamental building block in digital system. The transfer of new information into a register is referred as loading or updating the register. If all the bits of the register are loaded simultaneously with a common clock pulse, we say that the loading is done in parallel . Parallel Laod Register library ieee; use ieee.std_logic_1164.all; entity shift_right_register is port( clk, reset: in std_logic; load : in std_logic; d: in std_logic_vector(3 downto 0); q: out std_logic_vector(3 downto 0) ); end shift_right_register; architecture two_seg_arch of shift_right_register is signal r_reg: std_logic_vector(3 downto 0); signal r_next: std_logic_vector(3 downto 0); begin -- register process(clk, reset) begin if (reset=’1’) then r_reg <= (others=>’0’); elsif (clk’event and clk=’1’) then if (load <= ‘1’) then r_reg <= d; else r_reg <= r_next; end if; end process; -- output q <= r_reg; end two_seg_arch; 14 Free Running Shift Register A register capable to shifting the binary information held in each cell to its neighboring cell, in a selected direction is called shift register Can be used to carry out parallel-to-serial conversion. 15 Free Running Shift Register Conceptually, we can re-arrange the FFs into a column and treat them as a single memory block (see below) 16 Free Running Shift Register 17 Free Running Shift Register library ieee; use ieee.std_logic_1164.all; entity shift_right_register is port( clk, reset: in std_logic; d: in std_logic; q: out std_logic ); end shift_right_register; architecture two_seg_arch of shift_right_register is signal r_reg: std_logic_vector(3 downto 0); signal r_next: std_logic_vector(3 downto 0); begin -- register process(clk, reset) begin if (reset=’1’) then r_reg <= (others=>’0’); elsif (clk’event and clk=’1’) then r_reg <= r_next; end if; end process; -- next-state logic (shift right 1 bit) r_next <= d & r_reg(3 downto 1); -- output q <= r_reg(0); end two_seg_arch; 18 Universal Shift Register Designed to implement 4 ops: parallel load, shift right, shift left, pause library ieee; use ieee.std_logic_1164.all; entity shift_register is port( clk, reset: in std_logic; ctrl: in std_logic_vector(1 downto 0); d: in std_logic_vector(3 downto 0); q: out std_logic_vector(3 downto 0) ); end shift_register; 21 Universal Shift Register architecture two_seg_arch of shift_register is signal r_reg: std_logic_vector(3 downto 0); signal r_next: std_logic_vector(3 downto 0); begin -- register process(clk, reset) begin if (reset=’1’) then r_reg <= (others=>’0’); elsif (clk’event and clk=’1’) then r_reg <= r_next; end if; end process; -- next-state logic with ctrl select r_next <= r_reg when "00", -- no op r_reg(2 downto 0) & d(0) when "01", -- sft left d(3) & r_reg(3 downto 1) when "10", -- sft rght d when others; -- parallel -- output q <= r_reg; end two_seg_arch; 22 Counter A counter is a register that goes through a prescribed sequence of states upon the application of input pulses. Binary Ripple Counter Positive edge triggered Negative edge triggered ALREADY Discussed the timing waveform in previous classes Counter – D Flip Flop ALREADY Discussed the timing waveform in previous classes. Arbitrary sequence counter A sequential counter circulates a predefined sequence of states. The next state logic determines the patterns in the sequence. For example counter needs to circulates through the following sequence library ieee; use ieee.std_logic_1164.all; entity arbi_seq_counter4 is port( clk, reset: in std_logic; q: out std_logic_vector(2 downto 0) ); end arbi_seq_counter4; Architecture ??? 25 Arbitrary sequence counter -- next-state logic r_next <= "011" when r_reg="000" else "110" when r_reg="011" else "101" when r_reg="110" else "111" when r_reg="101" else "000"; -- r_reg="111" -- output logic Conditional signal Statement q <= r_reg; end two_seg_arch; architecture two_seg_arch of arbi_seq_counter4 is signal r_reg: std_logic_vector(2 downto 0); signal r_next: std_logic_vector(2 downto 0); begin -- register process(clk, reset) begin if (reset=’1’) then r_reg <= (others=>’0’); -- next-state logic elsif (clk’event and clk=’1’) then with r_reg select r_reg <= r_next; r_next <= "011" when "000" else end if; "110" when "011" else end process; "101" when "110" else "111" when "101" else "000"; -- r_reg="111" -- output logic Selected Signal Statement q <= r_reg; 26 end two_seg_arch; Free-Running Binary Counter RTL schematic of free running binary counter A binary counter circulates through a sequence that resembles the unsigned binary number In the following example, signal max_pulse is another output, asserted when counter is all ’1’s 27 Free-Running Binary Counter library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity binary_counter4_pulse is port( clk, reset: in std_logic; max_pulse: out std_logic; q: out std_logic_vector(3 downto 0) ); end binary_counter4_pulse; architecture two_seg_arch of binary_counter4_pulse is signal r_reg: unsigned(3 downto 0); signal r_next: unsigned(3 downto 0); begin 28 Free-Running Binary Counter -- register process(clk, reset) begin if (reset=’1’) then r_reg <= (others=>’0’); elsif (clk’event and clk=’1’) then r_reg <= r_next; end if; end process; -- next-state logic r_next <= r_reg + 1; -- output logic q <= std_logic_vector(r_reg); max_pulse <= ’1’ when (r_reg="1111") else ’0’; end two_seg_arch; 29 Coding Styles Two-segment code Separate memory segment from the rest Can be little cumbersome Has a clear mapping to hardware component One-segment code Mix memory segment and next-state logic / output logic Can sometimes be more compact No clear hardware mapping Error prone 30 Test Bench Test bench consists of component instantiation statement. 1 segment to generate a stimulus for clock Constant T:= time := 10 ns; -- clk period for 100MHz clock Process begin clk <= ‘0’; wait for T/2; clk <= ‘1’; wait for T/2; end process 1 segment for regular inputs. reset <= ‘1’, ‘0’ after T/2; 31 Test Bench For a synchronous system with positive edge-triggered FFs, an input signal must be stable around the rising edge of the clock signal to satisfy the setup and hold time constraints. One easy way to achieve this is to change an input signal’s value during the ’1’-to-’0’ transition of the clk signal. The falling_edge function of the std_logic_1164 package checks this condition, and we can use it in a wait statement: wait until falling-edge (clk) ; Note that each statement represents a new falling edge, which corresponds to the advancement of one clock cycle. For multiple clock cycles, we can use a loop statement: for i in 1 to 10 loop -- count 10 clocks wait until falling-edge (clk) ; end loop; or wait for 10*T; 32