3

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;
Renan
  • 5,090
  • 2
  • 27
  • 45
ballaw
  • 377
  • 2
  • 6
  • 12
  • 1
    Not gonna put this in an answer but you really should implement a proper reset in the clocked process that initializes the count to zero and sets the LED state. giving a signal a default works great in simulation, but it's not acceptable for hardware. Besides, you don't initialize your counter, even if defaults were acceptable. :-) – akohlsmith Mar 13 '12 at 03:25

2 Answers2

3

Yeah as Andrew mentioned in the comment, when you write the line

signal blink : std_logic := '1';

that is tying the signal blink to a logic high value. If you want to say that it starts as a '1' then use a reset signal clause:

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; 

as I believe most fpga boards pulse the reset signal when they go through a power cycle. Or at least the Spartan-3/4 demo boards that I've used do.

But expanding on why the default value doesn't make sense: If something is tied to a logic high value, it doesn't matter what else you drive it with, it is always going to be a pulled high signal.

Edit: So the two demo boards that I've used for the Spartan-3 and Spartan-4 have a push button labelled reset. It is a normally off button that has a pull-up resistor attached to the pin. So when the reset button is pushed it bring the reset signal to ground. That means reset is an active low signal. However, for readability in my code, I generally try to make signals active high. So my ucf file will have the following net statement:

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

and then in my top level entity I will create a global reset signal:

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

All the reset signals for any components I use can now be driven by my active high global reset signal.

NickHalden
  • 4,167
  • 3
  • 31
  • 40
  • "_Most fpga boards pulse the reset signal..._" — Can you give me some more information about it, please? How can I use this feature in my code? Let's say I have several blocks and all of them has async. reset. So sould I tied up all resets and define this line in UCF? – vasco Mar 13 '12 at 09:26
  • Sure, see my edit. – NickHalden Mar 13 '12 at 19:17
  • No, that doesn't drive the signal high. It just sets the power-up value (if the signal happens to end up in a flip-flop, otherwise it will be ignored). – Ben Voigt Mar 13 '12 at 23:09
  • @BenVoigt which part is that in reference to? – NickHalden Mar 14 '12 at 12:58
  • @JGord: Your first paragraph. – Ben Voigt Mar 14 '12 at 13:51
3

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.
Martin Thompson
  • 8,439
  • 1
  • 23
  • 44