Electronic – Hello world VHDL program – blinking LED

blinkfpgaledvhdl

I am trying to get a simple blinking LED program working on my FPGA and I am having problems. Instead of blinking the LED stays on the entire time. I tried writing my on but then I just copied an example program so I'm sure the program is fine.

Thi sis the board I am using: http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,836&Prod=ATLYS
From what I've read you are supposed to use DCMs for all clock needs but in my example I have just attached my clock to the global clock which is supposed to be 100MHz.

Any help for my poor noobie self would be appreciated! Below is my code and my ucf which can be verified with the ucf listed at the above link.

By the way, do any of you know offhand how to import a DCM in ISE? I can figure out how to use it I just can't find an import reference.

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;

ucf file

# 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;

Best Answer

Have you simulated the code to make sure it does behave OK in the ideal world?

Also, 100MHz is quite a fast clock and unless you tell the tools that's how fast you want to go, you might find it doesn't work. The logfiles should report what the final timing numbers are. You don't need to use a DCM, but if you want to, in the libraries guide there is a sample VHDL instantiation template, or you can use CoreGen.

As others have said, it's conventional to use the rst signal to reset your design, especially your counter. With FPGAs you can get them to startup in a known state. but it's often easier (especially to get it to match with simulation) to have an explicit reset. When you do this, check the polarity of the reset signal - sometimes they are active-high and sometimes active-low.

If you are using XST for synthesis, it should work fine with initial values. And even if it doesn't, the blink inversion will work, it'll just start from '0' not '1'. And the counter will start from all-zeros.

So:

  • Simulate the design, make sure it toggles in simulation first.
  • Add a PERIOD constraint to the UCF file to put a 10ns constraint on the clk signal.
  • Also, check the .pad file to see that the things you think you have constrained to the pins actually have gone on the right pins.