Establecer una señal alta constante a baja

Tengo un circuito de teclado, cuando mantengo presionada una tecla, la señal "key_pressed" siempre es alta, mientras mantenga presionada la tecla, lo cual es normal, cuando la dejo, vuelve a ser baja. Pero no quiero que esta señal sea constantemente alta, no importa cuánto tiempo presione la tecla, me gustaría que se detecte como una sola pulsación corta. En otros medios, debería encontrar una manera de configurar esta tecla presionada en un nivel bajo después de, digamos, 10 ms. Estoy haciendo todo en VHDL, sin condensadores de resistencias... Tampoco puedo esperar a un flanco descendente, entonces no tiene sentido, no se mostrará ninguna tecla en la pantalla LCD hasta que se suelte la tecla, lo que no tiene sentido.

Parece que necesitas un detector de bordes. Suponiendo que el antirrebote ya esté solucionado...
No puedo esperar a que caiga un borde...
Ver la respuesta de Spehro. No estoy seguro de dónde insinué algo que tenga que ver con el borde descendente...

Respuestas (3)

Necesita un detector de flanco ascendente . Esto se hace generando una entrada retrasada que es 1 ciclo de reloj más tarde que la entrada real.

Por ejemplo:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 

                 ^ You want to detect this point, where the signals are not the
                   same. Input has gone high, but because Input_z is delayed, it 
                   isn't high yet 

La entrada retrasada se genera de la siguiente manera:

gen_input_z : process(clk,rst) 
begin
    if (rst = '1') then
        Input_z <= '0';
    elsif (rising_edge(clk)) then
        Input_z <= Input;
    end if;
end process

Ahora desea detectar su flanco ascendente:

gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
    elsif (rising_edge(clk)) then
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
        else 
            Edge_detect <= '0';
        end if;
    end if;
end process

Pero ahora nuestra detección de borde es solo un ciclo de reloj:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        ________
Edge_det   ____________/        \__________________________________________________

Para modificar eso, agregue un contador que solo haga que la detección de bordes caiga después de una cierta cantidad de ciclos de reloj:

-- Port Declarations
signal clk         : in std_logic;
signal rst         : in std_logic;
signal input       : in std_logic;

-- Signal declarations
signal input_z     : std_logic;
signal edge_detect : std_logic;
signal counter     : unsigned(31 downto 0); -- include numeric_std for this


gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
        counter     <= '0';
        input_z     <= '0';
    elsif (rising_edge(clk)) then
        input_z <= input;
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
            counter     <= (others => '0');
        elsif (counter < 2) then          -- we want an edge detect of 2 clock cycles 
            Edge_detect <= '1';
            counter     <= counter + "1"; -- declare counter as unsigned.
        else
            Edge_detect <= '0';
        end if;
    end if;
end process

Ahora está haciendo lo que queremos:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        _____________
Edge_det   ____________/             \_____________________________________________
muchas gracias por contestar, hay 3 procesos con el mismo nombre, supongo que va a haber 1 proceso con combinación de 1 y 3 verdad? Y finalmente Edge_detserá la señal de salida que quiero ¿no?
los tres de los mismos nombres fueron solo un error tipográfico, se supone que son diferentes. sí, 1 + 3 hará el truco. Edge_det es lo que quieres.
Tengo una señal de habilitación en la máquina de estado que es de 100 Hz. Cambio entre estados cada 100 Hz, así que intentaré usar esa señal de habilitación en mi gen_edge_detpero si fallo, intentaré contrarrestar, ¿cómo declaraste el contador? señal counter : integer range 0 to 2 := 0;?
Recibo este error "rising_edge no puede tener tales operandos en este contexto".
Mi reloj se declara como bit tal vez por eso.
Se agregaron declaraciones de señal al tercer proceso, incluido input_delay en el tercer proceso. Esto debería aclarar un poco las cosas.

La forma en que hago esto en el firmware es detectar un cambio en la entrada (después de rechazar el ruido y el rebote) y luego generar un evento basado en la pulsación de una tecla o incluso en la liberación de una tecla para cada tecla.

Luego puede usar los eventos de pulsación y liberación de teclas, junto con temporizadores para realizar todas las funciones habituales que asocia con las teclas en la electrónica moderna. Mantenga presionada la tecla durante 3 segundos para ingresar a un modo especial. Mantenga presionada la tecla y luego suéltela para bloquear una configuración de codificador o lo que sea.

Editar: según sus cambios, en el caso de usar VHDL (hardware), esto se puede lograr con un reloj y chanclas. Simplemente compare la entrada X con una versión retrasada de la entrada X'. Eso le dará un pulso de un reloj para el flanco ascendente de entrada (y, si lo desea, un pulso de un reloj para el flanco descendente de entrada). Funciona igual en un HDL que en código secuencial.

La entrada no cambiará siempre Alto y el mismo valor clave. Edité un poco mi pregunta.

Yo diría que estás buscando un multivibrador monoestable. Puede hacerlos desde un temporizador 555 o usar un chip dedicado. Para TTL, está disponible como componente 74xx123. Funcionan detectando un borde y emitiendo un pulso de duración programable. Puede configurar los parámetros de pulso con resistencias y tapas externas, si no recuerdo mal. Levante una hoja de datos. Deben contener circuitos de ejemplo para que pueda aprender.

74ls121 también funciona. Si no tienes nada de eso, creo que puedes hacer uno con dos inversores y un circuito RC.
Olvide mencionar. Dado que es sensible a los bordes, no es necesario eliminar el rebote. De hecho, este dispositivo funciona como un circuito antirrebote por sí solo.