- Muchas notas - Fran Acién

20201015 - VHDL 5 - Diseño secuencial

Circuitos secuenciales -> La salida depende de las entradas y del estado (memoria).

D Latch

library ieee;
use ieee.std_logic_1164.all;
entity dlatch is
    port(
        c: in std_logic;
        d: in std_logic;
        q: out std_logic
    );
end dlatch;
architecture arch of dlatch is
begin
    process (c, d)
    begin
        if (c='1') then
            q <= d;
        end if;
    end process;
end arch;

Pos edge-triggered D FF

library ieee;
use ieee.std_logic_1164.all;
entity dff is
    port(
        clk: in std_logic;
        d: in std_logic;
        q: out std_logic
    );
end dff;
architecture arch of dff is
begin
    process (clk)
    begin
        if (clk'event and clk='1') then
            q <= d;
        end if;
    end process;
end arch;

D FF with async reset

library ieee;
use ieee.std_logic_1164.all;
entity dffr is
    port(
        clk: in std_logic;
        reset: in std_logic;
        d: in std_logic;
        q: out std_logic
    );
end dffr;
architecture arch of dffr is
begin
    process (clk, reset)
    begin
        if (reset='1') then
            q <='0';
        elsif (clk'event and clk='1') then
            q <= d;
        end if;
    end process;
end arch;

Basic Block Diagram

state_reg -> Memory element next-state logic -> Circuito conbinacional output logic -> Circuito combinacional

Cuando se produce un flanco de reloj, state_next se guarda en registro -> state_reg

El valor de next_state determina el nuevo valor para la lógica de salida.

Vuelve a subir l flanco de reloj y el nuevo valor de state_next se guarda en registro

Ejemplo de un contador

Ejemplo de un contador con enable, que hace “000”, “001”, “011”, “101”, “111”, “010”

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity my_count is
    Port ( rst : in STD_LOGIC;
           clk : in STD_LOGIC;
           en : in STD_LOGIC;
           count : out UNSIGNED (2 downto 0));
end my_count;

architecture Behavioral of my_count is

signal current_state, next_state: UNSIGNED (2 downto 0);

begin

--next state logic
process(current_state)
begin
    case current_state is
        when "000" =>
            next_state <= "001";
        when "001" =>
            next_state <= "011";
        when "011" =>
            next_state <= "101";
        when "101" =>
            next_state <= "111";
        when "111" =>
            next_state <= "010";
        when others =>
            next_state <= "000";
    end case;
end process;

--state register
process(clk, rst)
begin
  if(rst = '1') then
    current_state <= (others => '0');
  elsif(clk'event and clk= '1') then
    if(en = '1') then
      current_state <= next_state;
    end if;
  end if;
end process;

--output logic
count <= current_state;

end Behavioral;

Ejemplo rotar a la derecha con un parallel load

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity my_shift is
    Port ( rst : in STD_LOGIC;
           clk : in STD_LOGIC;
           parallel_load : in STD_LOGIC;
           rotate : in STD_LOGIC_VECTOR(2 downto 0);
           parallel_in : in STD_LOGIC_VECTOR(7 downto 0);
           data_out : out STD_LOGIC_VECTOR(7 downto 0));
end my_shift;

architecture Behavioral of my_shift is

signal current_state, next_state: STD_LOGIC_VECTOR (7 downto 0);

begin

--next state logic
process(current_state, parallel_load, rotate, parallel_in)
begin
    if(parallel_load = '1') then
        next_state <= parallel_in;
    else
        next_state <= std_logic_vector(shift_right(unsigned(current_state), to_integer(unsigned(rotate))));
    end if;
end process;

--state register
process(clk, rst)
begin
  if(rst = '1') then
    current_state <= (others => '0');
  elsif(clk'event and clk= '1') then
    current_state <= next_state;
  end if;
end process;

--output logic
data_out <= current_state;

end Behavioral;

Síntesis del código

Después de ver el código secuencial podemos hacernos una idea de cómo se sintetizará en el circuito. Se pocederá viendo la siguiente imagen:

1.png