Mala descripción síncrona - programa vhdl simple

Estoy tratando de hacer un programa VHDL simple que consiste en incrementar un std_logic_vector en uno cada vez que se presiona el botón A. Cuando se presiona el botón B, el valor debe restablecerse.

mi idea era hacerlo asi

entity simple is
    Port ( A : in std_logic;
           B : in std_logic;
           CLK : in std_logic;
           debug : out std_logic_vector (7 downto 0));
end simple;

architecture Behavioral of simple is
    signal state: std_logic_vector(7 downto 0) := "00000000";
begin

   increment: process(state, A, B)
    begin
        if (B'event and B = '1') then 
            state <= "00000000";
        end if;
        if (A'event andA = '1') then 
            state <= std_logic_vector(unsigned(state)+1);
         end if;
    end process;


    led_debug: process(CLK)
    begin
        debug <= state;
    end process;    

end Behavioral;

El problema es que recibo un error: descripción sincrónica incorrecta, que no puedo entender.

Respuestas (2)

Reelaboré su código en una descripción sincrónica completa:

  1. Los diseños síncronos necesitan una señal de reloj, pero una señal de botón no es un reloj. Entonces, cada proceso se desencadena en un borde positivo de Clk.
  2. Cambié el tipo de estado para ahorrar algunas conversiones de tipo.
  3. Si Aestá activo, el contador se pone a cero.
  4. De lo contrario, si Bestá activo, se incrementa.
  5. Asumo que su led_debugproceso debe estar cronometrado, así que agregué una condición de borde ascendente.

Esta solución no resuelve el siguiente problema, si Ay Bson cables de un botón externo:

  • Las señales externas deben sincronizarse con al menos 2 FF para evitar problemas de metaestabilidad.
  • Los botones externos en su mayoría necesitan un circuito antirrebote, porque las entradas de los botones rebotan. También existen soluciones eléctricas o mecánicas posibles para resolver el problema. Echa un vistazo a las descripciones y esquemas de tu placa.
  • En la mayoría de los casos, desea contar las pulsaciones de botones. Su solución actual mide cuánto tiempo ha presionado el botón (esto también necesita un contador más grande). Este problema se puede resolver mediante un circuito de detección de bordes.

Aquí está el código reescrito:

entity simple is
  Port (
    CLK : in std_logic;
    A : in std_logic;
    B : in std_logic;
    debug : out std_logic_vector (7 downto 0)
  );
end entity;

architecture rtl of simple is
  signal state : unsigned(7 downto 0) := (others => '0');

begin
  increment : process(Clk)
  begin
    if rising_edge(Clk) then
      if (B = '1') then 
        state <= "00000000";
      elsif (A = '1') then 
        state <= state + 1;
      end if;
    end if;
  end process;

  led_debug : process(CLK)
  begin
    if rising_edge(Clk) then
      debug <= std_logic_vector(state);
    end if;
  end process;    
end architecture;
Agregar otro registro para debugno es del todo necesario.
Traduje su código. Y sí, en algunos casos necesitará de 1 a 3 etapas de registro para un puerto de depuración a un estado interno. Por supuesto, el circuito de depuración es más que un LED ...

Me di cuenta de que estaba verificando en 2 flancos ascendentes dentro del mismo proceso, lo que hacía que el sistema fuera sensible a 2 relojes, lo que le estaba dando una mala sincronía.

El botón B se puede utilizar como reinicio asíncrono.