Eine blinkende LED ist das "Hello World!" der Hardware. 
Man kann daran erkennen, dass die Versorgung funktioniert, die Logik arbeitet und anhand der Blinkfrequenz einen Zähler beurteilen. Also schon einiges, was so eine einzelne Funzel einem sagen kann :-) 
Leider funktioniert diese einfache Variante eines Blinklichts nur in der Simulation:
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
 
entity BlinkLED is 
    Port (led : buffer  STD_LOGIC := '0'); 
end BlinkLED; 
 
architecture Behavioral of BlinkLED is 
begin 
   led <= not led after 500 ms;    -- LED alle 500 ms toggeln 
end Behavioral;
Warum geht das nicht? Es gibt keine "einstellbaren Verzögerungsglieder" (ähnlich wie Monoflops oder RC-Glieder...) im FPGA. Alles, was mit Zeiten zu tun hat, muss in einem FPGA als Zähler aufgebaut werden, der einen Takt mitzählen und beim Erreichen eines passenden Endwertes eine Reaktion auslöst. 
Also brauchen wir einen Takt und einen Zähler. In der Regel ist am FPGA ein Quarz mit z.B. 50MHz angeschlossen. Für eine halbe Sekunde müssen also 25 Millionen Takte gezählt werden. Das ergibt eine Registerkette mit 25 Bits (mit diesen 25 Bit wären maximal 2^25=33554432 Zählschritte möglich).
Und diese 25 Register werden mit einem festen Wert 24999999 verglichen. Warum 24999999 und nicht 25000000? 
Weil 0...24999999 schon 25000000 Schritte sind. Einfacher wird es vielleicht mit kleineren Zahlen: ein Zähler, der 5 Schritte abzählen muß, braucht die Zahlen 0, 1, 2, 3 und 4.
Also zusammengefasst:
Ein Takt geht auf einen Zähler, der mit einem festen Wert verglichen wird, bei dessen Erreichen zurückgesetzt wird und gleichzeitig eine Aktion auslöst: die LED wird getoggelt.
Hier ist der VHDL-Quellcode für so ein Blinklicht:
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
 
entity BlinkLED is 
    Port ( clk : in  STD_LOGIC; 
           led : out  STD_LOGIC); 
end BlinkLED; 
 
architecture Behavioral of BlinkLED is 
signal c : integer range 0 to 24999999 := 0; -- 0,5s bei 50MHz fosc
signal x : std_logic:= '0';  
begin 
   process begin  
      wait until rising_edge(clk); -- warten bis zum nächsten Takt 
      if (c<24999999) then         -- 0…24999999 = 25000000 Takte = 1/2 Sekunde bei 50MHz 
          c <= c+1;                -- wenn kleiner: weiterzählen 
      else                         -- wenn Zählerende erreicht: 
          c <= 0;                  -- Zähler zurücksetzen 
          x <= not x;              -- und Signal x togglen 
      end if; 
   end process; 
   led <= x;                       -- Signal x an LED ausgeben 
end Behavioral;
Zur Funktionsweise:
mit einem Zähler werden 25 Millionen Takte eines 50 MHz Taktes abgezählt (also 0..24999999). Wenn der Zählerendwert erreicht wurde, wird der Zähler zurückgesetzt und gleichzeitig ein lokales Signal x getoggelt. Dieses Signal wird dann an den led Ausgang gegeben.
Das lokale Signal x brauchen wir, weil der Port led als out deklariert ist, und daher entsprechend den VHDL Richtlinien nicht lesbar ist.
Und um den Schlauen zuvorzukommen: Nein, es ist keine gute Idee, den Port led als buffer oder inout zu deklarieren, nur damit er zurückgelesen werden und so ein lokales Signal gespart werden kann. Das ist eher ein Kündigungsgrund oder sollte wenigstens einen strengen Verweis in der Personalakte nach sich ziehen...
Als kleiner Lichtblick: ab VHDL 2008 können auch out Ports wieder zurückgelesen werden, diese Ports verhalten sich dann ähnlich wie buffer. So ist es dann möglich, z.B. einen Zähler direkt auf einen out Port zu erzeugen.
 
Und hier die kompakte Stimuli-"Testbench":
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL;  
  
entity tb_BlinkLED is 
                                   -- leere Entity --> Testbench
end tb_BlinkLED; 
  
architecture behavior of tb_BlinkLED is
   component BlinkLED 
   port( clk : IN  std_logic; 
         led : OUT  std_logic ); 
   end component; 
    
   signal clk : std_logic := '0';  -- lokale Signale der Testbench
   signal led : std_logic;         -- werden an den Prüfling angeschlossen
begin
   uut: BlinkLED                   -- der Prüfling wird verdrahtet
   port map ( clk => clk, 
              led => led ); 
 
   clk <= not clk after 10 ns;     -- einen 50MHz Takt erzeugen
end;
Wer dieses Blinklicht zum ersten Mal mit ISE realisieren will, der kann sich die Schritt-für-Schritt Anleitung HIER mal ansehen.
Für alle, die noch nicht genug haben kommt hier der Binärzähler auf 8 LEDs.
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
 
entity BinaryLED is 
    Port ( clk  : in  STD_LOGIC; 
           leds : out STD_LOGIC_VECTOR(7 downto 0)); 
end BinaryLED; 
 
architecture Behavioral of BinaryLED is 
signal c : integer range 0 to 12499999 := 0; -- 0,25s bei 50MHz fosc
signal x : unsigned (7 downto 0) := (others=>'0');  
begin 
   process begin  
      wait until rising_edge(clk); -- warten bis zum nächsten Takt 
      if (c<12499999 ) then        -- 0..12499999 = 12500000 Takte = 1/4 Sekunde bei 50MHz 
          c <= c+1;                -- wenn kleiner: c weiterzählen 
      else                         -- wenn Zählerende erreicht: 
          c <= 0;                  -- Zähler c zurücksetzen 
          x <= x+1;                -- und Zähler x hochzählen 
      end if; 
   end process; 
   leds <= std_logic_vector(x);    -- Signal x an LEDs ausgeben 
end Behavioral;
Im Großen und Ganzen ist das Beispiel gleich wie das obere. Nur wird hier statt der einzelnen LED ein unsigned-Vektor hochgezählt. Das Hochzählen von Vektoren hat den Vorteil, dass der Überlauf von 11111111bin = 255dez nach 00000000bin = 0dez automatisch passiert. 
Ich hätte den Zähler x natürlich wie den Zähler c auch als integer machen können, dann hätte der Code (für eine fehlerfreie Simulation) aber so aussehen müssen:
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
 
entity BinaryLED is 
    Port ( clk  : in  STD_LOGIC; 
           leds : out STD_LOGIC_VECTOR(7 downto 0)); 
end BinaryLED; 
 
architecture Behavioral of BinaryLED is 
signal c : integer range 0 to 12499999 := 0; -- 0,25s bei 50MHz fosc
signal x : integer range 0 to 255 := 0;  
begin 
   process begin  
      wait until rising_edge(clk); -- warten bis zum nächsten Takt 
      if (c<12499999 ) then        -- 0..12499999 = 12500000 Takte 
          c <= c+1;                -- wenn kleiner: c weiterzählen 
      else                         -- wenn Zählerende erreicht: 
          c <= 0;                  -- Zähler c zurücksetzen 
          if (x<255) then          -- ist Zähler x schon "oben" angekommen
             x <= x+1;             -- nein: Zähler x hochzählen 
          else
             x <= 0;               -- ja: zurücksetzen
          end if;
      end if; 
   end process; 
   -- Signal konvertieren und casten und an LEDs ausgeben 
   leds <= std_logic_vector(to_unsigned(x,8)); 
end Behavioral;
Der nächste logische Schritt ist dann, die Erzeugung des Fortschaltimpulses in einem eigenen Prozess zu erzeugen.
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
 
entity BinaryLED is 
    Port ( clk  : in  STD_LOGIC; 
           leds : out STD_LOGIC_VECTOR(7 downto 0)); 
end BinaryLED; 
 
architecture Behavioral of BinaryLED is 
signal c : integer range 0 to 12499999 := 0; -- 0,25s bei 50MHz fosc
signal t : std_logic := '0';
signal x : integer range 0 to 255 := 0;  
begin 
   process begin  
      wait until rising_edge(clk); -- warten bis zum nächsten Takt 
      if (c<12499999 ) then        -- 1/4 Sekunde bei 50MHz 
          c <= c+1;                -- wenn kleiner: c weiterzählen 
          t <= '0';                
      else                         -- wenn Zählerende erreicht: 
          c <= 0;                  -- Zähler c zurücksetzen 
          t <= '1';                -- Flag für Tick setzen
      end if; 
   end process; 
   process begin  
      wait until rising_edge(clk); -- warten bis zum nächsten Takt 
      if (t='1') then              -- sind schon wieder 0,25 sec vorbei?
          if (x<255) then          -- ist Zähler x schon "oben" angekommen
             x <= x+1;             -- nein: Zähler x hochzählen 
          else
             x <= 0;               -- ja: zurücksetzen
          end if;
      end if; 
   end process; 
   -- Signal konvertieren und casten und an LEDs ausgeben 
   leds <= std_logic_vector(to_unsigned(x,8)); 
end Behavioral;
Wie man klar sieht, gibt es in diesem Design nur und genau einen einzigen Takt clk. Das ist der Quarzoszillator, der aussen am FPGA angeschlossen ist. Mit diesem Takt läuft das ganze Design. Für Anfänger gilt: 
Der Takt ist wie der Highlander: es kann nur einen geben.