Hello world VHDL programme - LED parpadeante

3

Estoy tratando de hacer que funcione un simple programa de LED parpadeante en mi FPGA y tengo problemas. En lugar de parpadear, el LED permanece encendido todo el tiempo. Intenté escribir mi en pero luego simplemente copié un programa de ejemplo, así que estoy seguro de que el programa está bien.

Este es el tablero que estoy usando: enlace Por lo que he leído, se supone que debe usar DCM para todas las necesidades de reloj, pero en mi ejemplo, acabo de adjuntar mi reloj al reloj global que se supone que es de 100MHz.

¡Cualquier ayuda para mi pobre noobie sería apreciada! A continuación se muestra mi código y mi ucf, que se pueden verificar con el ucf que figura en el enlace anterior.

Por cierto, ¿alguno de ustedes sabe de antemano cómo importar un DCM en ISE? Puedo descubrir cómo usarlo, simplemente no puedo encontrar una referencia de importación.

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


entity counter is
port( clk: in std_logic;
    rst: in std_logic;
    led: out std_logic;
    led2: out std_logic;
    sw0: in std_logic);
end counter;

architecture Behavioral of counter is

constant CLK_FREQ : integer := 1000000;
constant BLINK_FREQ : integer := 1;
constant CNT_MAX : integer := CLK_FREQ/BLINK_FREQ/2 - 1;

signal cnt : unsigned(24 downto 0);
signal blink : std_logic := '1';

begin

process(clk)
begin

    if (clk='1' and clk'event) then
        if cnt = CNT_MAX then
            cnt <= (others => '0');
            blink <= not blink;
        else
            cnt <= cnt + 1;
        end if;
    end if; 

end process;

process(sw0)
begin

    if sw0 = '1' then
        led2 <= '1';
    else led2 <= '0';
    end if;

end process;

led <= blink;

end Behavioral;

archivo ucf

# Bank = 1, Pin name = IO_L42P_GCLK7_M1UDM, Type = GCLK, Sch name = GCLK
NET "clk" LOC = L15;

# Bank = 1, Pin name = IO_L52N_M1DQ15,     Sch name = LD0
NET "led" LOC = U18;

# PlanAhead Generated physical constraints 

NET "led2" LOC = M14;
NET "rst" LOC = F5;
NET "sw0" LOC = A10;
    
pregunta ballaw

2 respuestas

3

¿Ha simulado el código para asegurarse de que se comporte bien en el mundo ideal?

Además, 100MHz es un reloj bastante rápido y, a menos que diga las herramientas, así es como lo rápido que quiere ir, puede que no funcione. Los archivos de registro deben informar cuáles son los números de tiempo finales. No necesita para usar un DCM, pero si lo desea, en la guía de bibliotecas hay una plantilla de creación de instancias de VHDL de ejemplo, o puede usar CoreGen.

Como han dicho otros, es convencional usar la señal rst para restablecer su diseño, especialmente su contador. Con los FPGA, usted puede hacer que se inicien en un estado conocido. pero a menudo es más fácil (especialmente para que coincida con la simulación) tener un restablecimiento explícito. Cuando haga esto, verifique la polaridad de la señal de restablecimiento, que a veces es activa alta y otras activa baja.

Si está utilizando XST para la síntesis, debería funcionar bien con los valores iniciales. E incluso si no lo hace, la inversión blink funcionará, simplemente comenzará desde '0' no desde '1'. Y el contador comenzará desde todos los ceros.

Entonces:

  • Simule el diseño, asegúrese de que alterna en la simulación primero.
  • Agregue una restricción PERIOD al archivo UCF para poner una restricción 10ns en la señal clk.
  • También, revise el archivo .pad para ver si las cosas que cree que ha restringido a los pines se han colocado en los pines correctos.
respondido por el Martin Thompson
3

Sí, como mencionó Andrew en el comentario, cuando escribes la línea

signal blink : std_logic := '1';

que está vinculando el parpadeo de la señal a un valor lógico alto. Si quiere decir que comienza como '1', use una cláusula de restablecimiento de la señal:

if(reset = '1') then
    --initial conditions
    blink <= '1';
elsif (clk='1' and clk'event) then
    if cnt = CNT_MAX then
        cnt <= (others => '0');
        blink <= not blink;
    else
        cnt <= cnt + 1;
    end if;
end if; 

ya que creo que la mayoría de las tarjetas fpga pulsan la señal de reinicio cuando pasan por un ciclo de alimentación. O, al menos, los paneles de demostración Spartan-3/4 que he usado.

Pero ampliando por qué el valor predeterminado no tiene sentido: si algo está ligado a un valor lógico alto, no importa con qué otra cosa lo manejes, siempre será una señal alta.

Editar: Por lo tanto, las dos tablas de demostración que he usado para el Spartan-3 y el Spartan-4 tienen un botón pulsado con el botón de reinicio. Normalmente es un botón de apagado que tiene un resistor de pull-up conectado al pin. Entonces, cuando se presiona el botón de reinicio, la señal de reinicio se pone a tierra. Eso significa que el reinicio es una señal baja activa. Sin embargo, para facilitar la lectura en mi código, generalmente trato de hacer que las señales se activen en nivel alto. Así que mi archivo ucf tendrá la siguiente declaración de red:

net swrst       loc=D15;    # xst-3 RESET pushbutton  

y luego en mi entidad de nivel superior crearé una señal de reinicio global:

signal reset : std_logic;
...
...
...
reset <= not swrst;

Todas las señales de reinicio para cualquier componente que use ahora pueden ser controladas por mi alta señal de reinicio global activa.

    
respondido por el NickHalden

Lea otras preguntas en las etiquetas

Comentarios Recientes

para evento de error - Utilizando la administración de fuentes Winwin, esta es una versión fácil de configurar para una consola interactiva que puedo hacer - / vhdlshow 1: spec -vv call PVS-Studio diagnostics ... / ... Verificando que se encontró el archivo fuente /script/Spec.VgkGui =================== Dirección de destino de la memoria: 24 = 0x100004924 * sneakstep Trace complete ===== ============== Estructura: zothmstr * vwx.dump * server_js /sbin/panic.php * server_js / CONFIG_SERVER.php /.c ..... Init Section.phpc... Lees verder