parpadeando una pantalla usando el disparador

0

He estado golpeando mi cabeza sobre esto por un tiempo, básicamente tengo este controlador de pantalla que en condiciones normales actualizaría continuamente una pantalla de siete segmentos.
Lo que me gustaría hacer, y lo que estoy tratando de hacer es crear una condición en el módulo que la enviaría a un estado de parpadeo.

Para hacer esto, estoy usando los estados de una máquina de estados de mi ruta de datos principal para almacenar información sobre el parpadeo, y estoy usando una señal "parpadear" para disparar cuándo comenzar la secuencia de parpadeo.

En mi ruta de datos principal siempre que quiero que la pantalla parpadee, asigno la señal "blink < = not (blink)" esencialmente, y luego se supone que mi controlador de pantalla debe notar este cambio y comenzar la secuencia.

El problema es que no se nota el cambio o que no entra en la secuencia.

A continuación se muestra mi código para el controlador de pantalla

--------------------------------------------------------------------------------------------------------------------------
    -- Title       : ssd_driver
    -- Design      : lab3_demo
    -- Function:   : generates signals driving four seven segment displays of the Digilent Basys2 or the Digilent Nexys3 board
--------------------------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.FSM_ATM_pkg.all;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_misc.all;

entity ssd_driver is
    generic (   k : integer := 20 );
        --  k depends on the on the clock frequency selected on the board
        --  k := 20 for fclk = 100 MHz
        --  k := 19 for fclk = 50 MHz
        --  k := 18 for fclk = 25 MHz
    port(
        clk     : in    std_logic;
        rst     : in    std_logic; 
        hex0    : in    std_logic_vector(7 downto 0);
        hex1    : in    std_logic_vector(7 downto 0);
        hex2    : in    std_logic_vector(7 downto 0);
        hex3    : in    std_logic_vector(7 downto 0);
        seg     : out   std_logic_vector(6 downto 0);
        an      : out   std_logic_vector(3 downto 0);
        STATE : in mycases1;
        blink : in std_logic);
end entity;

architecture arch of ssd_driver is

    -- intermediate signals and constants
    signal decoder_out : std_logic_vector(3 downto 0);
    signal q : std_logic_vector(k-1 downto 0);
    signal mux_out : std_logic_vector(7 downto 0);
    signal sel : std_logic_vector(1 downto 0); 

    signal timer: unsigned(31 downto 0):=(others=>'0');
    signal delay: unsigned(3 downto 0):=(others=>'0');
    signal blinktimer: unsigned(31 downto 0):=(others=>'0');
    signal cont_decoder_out: std_logic_vector(3 downto 0);
    signal blink_flip:std_logic;
    signal hex_out:std_logic_vector(31 downto 0);
    signal sequence:std_logic:='0';
    signal hex0tmp,hex1tmp,hex2tmp,hex3tmp:std_logic_vector(7 downto 0);
    signal pastblink:std_logic:='0';
    signal blink_detect: std_logic;

    constant HIGH : std_logic := '1';
    constant LOW : std_logic := '0';
    constant ONESECOND: integer:=100000000;
    constant blink_rate:integer:=ONESECOND/2;


begin   




    process(clk)
        begin
                if rising_edge(clk) then
                    if pastblink /= blink then
                        sequence<='1';
                    end if;
                    if timer>delay*ONESECOND then
                            sequence<='0';
                            pastblink<=blink;
                    end if;
                    if sequence = '1' then  

                        timer<=timer+1;
                        blinktimer<=blinktimer+1;

                        case STATE is 
                            when PIN=> delay<=to_unsigned(3,4);
                            when BAL=> delay<=to_unsigned(0,4);
                            when COUT=> delay<=to_unsigned(5,4);
                            when CIN=>  delay<=to_unsigned(5,4);
                            when CHEC=> delay<=to_unsigned(5,4);
                            when CPIN=> delay<=to_unsigned(3,4);
                            when others=> delay<=to_unsigned(0,4);
                        end case;

                        if blinktimer= to_unsigned(blink_rate,32) then
                            blinktimer<=(others=>'0');
                            blink_flip<=not(blink_flip);
                            case blink_flip is
                                when '1' => cont_decoder_out<="1111";
                                when '0' => cont_decoder_out<=decoder_out;
                                when others => cont_decoder_out<=decoder_out;
                            end case;
                        end if;

                    else 
                        blink_flip<='0';
                        timer<=(others=>'0');
                        blinktimer<=(others=>'0');      
                    end if;
                end if;


    end process;

    hex0tmp<=hex_out(7 downto 0) when sequence ='1' else hex0;
    hex1tmp<=hex_out(15 downto 8) when sequence ='1' else hex1;
    hex2tmp<=hex_out(23 downto 16) when sequence ='1' else hex2;
    hex3tmp<=hex_out(31 downto 24) when sequence ='1' else hex3;

    an <= cont_decoder_out when sequence = '1' else not decoder_out;

    up_counter2 : entity work.up_counter generic map ( k => k ) port map ( clk => clk, rst => rst, init => LOW, enable => HIGH, count => q);

    sel <= q(k-1 downto k-2);


    with sel select  
        mux_out <=  hex0tmp when "00",
                        hex1tmp when "01",
                        hex2tmp when "10",
                        hex3tmp when others;

    with sel select  
        decoder_out <=  "0001" when "00",
                                "0010" when "01",
                                "0100" when "10",
                                "1000" when others;


    -- hex-to-7-segment decoding
    with mux_out select
        seg(6 downto 0) <=  "1000000" when x"00", -- 0  
                            "1111001" when x"01", -- 1  or i
                            "0100100" when x"02", -- 2  
                            "0110000" when x"03", -- 3  
                            "0011001" when x"04", -- 4  
                            "0010010" when x"05", -- 5  
                            "0000010" when x"06", -- 6  
                            "1111000" when x"07", -- 7  
                            "0000000" when x"08", -- 8  
                            "0010000" when x"09", -- 9  
                            "0001000" when x"0a", -- a  
                            "0000011" when x"0b", -- b  
                            "1000110" when x"0c", -- c  
                            "0100001" when x"0d", -- d  
                            "0000110" when x"0e", -- e  
                            "0001110" when x"0f", -- f  
                            "0001100" when x"11", -- p
                            "1001000" when x"12", -- n
                            "1000001" when x"13", --u
                            "0001001" when x"14", -- h
                            "1111111" when others;

end arch;

¿Hay razones obvias por las que no debería estar funcionando? La instrucción blink < = not (blink) está dentro de un proceso cronometrado en la ruta de datos principal, por cierto.

Además, si alguien sabe una mejor manera de implementar esto, eso siempre es útil, aunque realmente me gustaría saber cómo obtener mi idea de notar el cambio de parpadeo para activar la secuencia para que funcione.

¡Gracias de antemano como siempre!

    
pregunta scarlso9

1 respuesta

1

Tu estilo de codificación necesita mucho trabajo. El problema principal es que nunca usa la señal de reinicio del hardware rst para inicializar otra cosa que no sea up_counter2 . Esto significa que todas las variables de su estado pueden comenzar a mantener valores aleatorios.

Su código de activación se puede separar en su propio proceso, como este:

  process (clk) begin
    if rising_edge(clk) then
      if pastblink /= blink then
        sequence <= '1';
      end if;

      if timer > delay*ONESECOND then
        sequence <= '0';
        pastblink <= blink;
      end if;
    end if;
  end process;

Hay dos asignaciones diferentes para sequence . En un proceso, será la asignación final la que se aplique. Supongamos que sus sistemas se inician en un estado en el que sequence es falso, pero la expresión timer > delay*ONESECOND es verdadera. Esto significa que, independientemente de lo que ocurra con blink y pastblink , sequence nunca se puede establecer en true. Además, dado que sequence es falso, ni timer ni delay se actualizarán.

Hay otros problemas en su código. Estos incluyen:

  • Sin asignación a hex_out .
  • La señal an es a veces el complemento de decoder_out y otras veces no lo es.
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas