FSM usando ecuaciones de excitación y VHDL

-2

He estado intentando crear un FSM usando las ecuaciones de excitación que desarrollé. No he tenido mucha suerte. El circuito no tiene salida.

NO QUIERO UTILIZAR 'TIPO' y tipos de estado personalizados. Esa es la manera más fácil de salir. Por favor, no me digas que es lo que harías! Es probablemente lo que yo haría también. Estoy tratando de forzarme a aprender nuevos métodos.

A continuación encontrará mi proceso para la secuencia "2314". Configuré mi DE2 para que a los botones se les asignara un número, es decir, X (0) es el botón 0 o el número "1".

Descubrí que el programa necesitaría 5 estados (3 FF) usando una máquina Moore. Si no hay entrada en el estado ("0000"), la entrada debería mantenerse. Decidí usar las chancletas D para este experimento para facilitar las transiciones. Resulta que no es tan sencillo! Gracias por tu ayuda.

Mis ecuaciones para los flip flops D son las siguientes (derivadas del diagrama de estado / tabla de transición) Es posible que no se simplifiquen por completo, ¡lo siento!

d0 = Q2'.Q0 '. (X1.Q1' + X2.Q1)

d1 = Q2 '. (X2'Q1.Q0' + X3.Q1'.Q0)

d2 = x0.Q2'.Q1.Q0

z = Q2.Q1'.Q0 '

Encontrará el código VHDL a continuación. El componente también se muestra a continuación. El archivo VHDL actual es solo uno de mis muchos intentos fallidos. La simulación no tiene salida, por lo que z es una constante '0'.

library ieee;
use ieee.std_logic_1164.all;

entity sequencedetecttwo is 

port (
        x : in std_logic_vector (3 downto 0);
        clk : in std_logic;
        z : out std_logic       
        );

end entity sequencedetecttwo;

architecture arch of sequencedetecttwo is 

signal q : std_logic_vector (2 downto 0);
signal d : std_logic_vector (2 downto 0);

 component dflipflop is 

    port (
        clk, d : in std_logic; 
        q : out std_logic
        );

end component;



BEGIN

dff0 : dflipflop port map (clk => clk, d => d(0));
dff1 : dflipflop port map (clk => clk, d => d(1));
dff2 : dflipflop port map (clk => clk, d => d(2));

p0 : PROCESS(clk, q)

    BEGIN

    d(0) <= q(0);
    d(1) <= q(1);
    d(2) <= q(2);

        IF (clk'EVENT AND clk = '1') THEN   

        q(0) <= not q(2) and not q(0) and ((x(1) and not q(1)) or (x(2) and q(1)));
        q(1) <= not q(2) and ((not x(2) and q(1) and not q(0)) or (x(3) and not q(1) and q(0)));
        q(2) <= x(0) and not q(2) and q(1) and q(0);


        END IF;

END PROCESS p0;



    z <= q(2) and not q(1) and not q(0);


END ARCHITECTURE arch;

Y el componente flip flop:

library ieee;
use ieee.std_logic_1164.all;

entity dflipflop is 

port (
        clk, d : in std_logic; 
        q : out std_logic
        );
end entity dflipflop;

architecture arch of dflipflop is 

begin 

    p0 : process (clk)

        begin

            if (clk'event and clk = '1') then 

                q <= d;


            end if; 
    end process;
end architecture arch;
    
pregunta atomSmasher

1 respuesta

5

¡Usaría TYPE y ENUM! Ok, sobre todo dije eso para hacer un punto. Y ese punto es que hay cosas en VHDL que hacen que el código sea más fácil de leer y descubrir qué está sucediendo. La forma en que su código es, es casi ilegible. Ciertamente no puedo decirte exactamente lo que está mal, aunque puedo encontrar muchas cosas incorrectas. Antes de comenzar a tratar de hacer las cosas de la manera más difícil, debes perfeccionar las cosas de la manera más fácil.

Dicho esto, aquí hay algunas cosas que encontré mal. Es casi seguro que estos no son su problema principal, pero es mejor que empecemos en algún lugar ...

  1. Su creación de instancias de los D-Flip-Flops es incorrecta. No especificaste dónde van las salidas de los FF. De hecho, me sorprende que el compilador VHDL te permita salir con eso.

  2. No asignó un valor inicial a las señales d o q. Esto podría estar poniendo su máquina de estado en un estado no válido en el inicio. Incluso si no lo es, esta es una mala práctica.

  3. Las líneas "d (x) < = q (x);" en la primera parte de tu proceso tampoco es una gran práctica. Aunque técnicamente está bien, ralentizará las simulaciones y en algunos compiladores más antiguos generará una lógica errónea o simplemente no se compilará. En el contexto de su código, estas líneas podrían eliminarse simplemente ya que no usa d () en ningún lugar. Mientras esté en ello, elimine "q" de la lista de sensibilidad.

  4. En lugar de decir "IF (clk'EVENT AND clk = '1') ENTONCES", use "if rising_edge (clk)". Esto es más claro y, en algunos casos, funciona mejor para simulaciones.

Una vez que elimines todo el código inútil, tu código completo puede reducirse a algo bastante pequeño. Aquí está en su totalidad:

library ieee;
use ieee.std_logic_1164.all;

entity sequencedetecttwo is 
  port (
        x   :in  std_logic_vector (3 downto 0);
        clk :in  std_logic;
        z   :out std_logic       
       );
end entity sequencedetecttwo;

architecture arch of sequencedetecttwo is 
  signal q : std_logic_vector (2 downto 0) := (others=>'0');
  signal d : std_logic_vector (2 downto 0) := (others=>'0');
begin

  p0 : process(clk)
  begin
    if rising_edge(clk) then
      q(0) <= not q(2) and not q(0) and ((x(1) and not q(1)) or (x(2) and q(1)));
      q(1) <= not q(2) and ((not x(2) and q(1) and not q(0)) or (x(3) and not q(1) and q(0)));
      q(2) <= x(0) and not q(2) and q(1) and q(0);
    end if;
  end process p0;

  z <= q(2) and not q(1) and not q(0);
end architecture arch;

Dicho esto, todavía no sé por qué no funciona correctamente. Y, sinceramente, no estoy muy emocionado de averiguarlo (solo porque quieras hacerlo de la manera más difícil no significa que yo también lo haga). Pero con suerte, al aclarar un poco el código, podrás ver mejor lo que está haciendo y por qué podría no ser lo que pretendías.

    
respondido por el user3624

Lea otras preguntas en las etiquetas