Difference between revisions of "Une led qui clignote avec le spartan 3"

From ArmadeusWiki
Jump to: navigation, search
m
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Category: FPGA]]
 
[[Category: FPGA]]
Pour me faire la main avec le kit et surtout avec le fpga je me suis mis en tête de faire clignoter le une led du fpga. Pour cela je me suis un peu inspiré du montage proposé [[FPGA_and_led]] que j'ai modifié pour pouvoir tester ensuite [http://www.hackaday.com/2007/12/16/diy-led-multi-touch-panel/ la led en capteur de lumière].
+
Pour me faire la main avec le kit et surtout avec le FPGA je me suis mis en tête de faire clignoter le une LED du FPGA. Pour cela je me suis un peu inspiré du montage proposé [[FPGA_and_led]] que j'ai modifié pour pouvoir tester ensuite [http://www.hackaday.com/2007/12/16/diy-led-multi-touch-panel/ la led en capteur de lumière].
  
[[Image:diode.png]]
+
[[image:diode.png|center|frame|'''figure 1''' - ''LED wiring'']]
  
L'intérêt du clignotement d'une led est relativement limité, cependant il permet de prendre en main la totalité de la chaine de développement sur la carte Armadeus.
+
L'intérêt du clignotement d'une LED est relativement limité, cependant il permet de prendre en main la totalité de la chaine de développement sur la carte Armadeus.
  
 
Après avoir installé le [[Installation_de_ISE_sur_Ubuntu_Linux | Xilinx Web Pack]] généreusement offert par Xilinx, il suffit de réaliser un compteur qui divisera la fréquence de l'horloge de manière à avoir un clignotement de quelques Hertz (La fréquence du spartan3 étant de 96MHz nous diviserons par 48000000 !).
 
Après avoir installé le [[Installation_de_ISE_sur_Ubuntu_Linux | Xilinx Web Pack]] généreusement offert par Xilinx, il suffit de réaliser un compteur qui divisera la fréquence de l'horloge de manière à avoir un clignotement de quelques Hertz (La fréquence du spartan3 étant de 96MHz nous diviserons par 48000000 !).
  
 
<source lang="VHDL">
 
<source lang="VHDL">
library IEEE;
+
library IEEE;
 
  use IEEE.STD_LOGIC_1164.ALL;
 
  use IEEE.STD_LOGIC_1164.ALL;
 
  use IEEE.numeric_std.all;
 
  use IEEE.numeric_std.all;
 
   
 
   
 
  entity Clk_div_led is
 
  entity Clk_div_led is
     Port ( Clk : in  std_logic;
+
     Port (  
           led_cathode         : out std_logic;
+
          Clk             : in  std_logic;
           led_anode         : out std_logic);
+
           led_cathode     : out std_logic;
 +
           led_anode       : out std_logic
 +
    );
 
  end Clk_div_led;
 
  end Clk_div_led;
 
   
 
   
 
  architecture RTL of Clk_div_led is
 
  architecture RTL of Clk_div_led is
constant max_count : natural := 48000000;
+
  constant max_count : natural := 48000000;
 
   signal Rst_n : std_logic;
 
   signal Rst_n : std_logic;
 
  begin
 
  begin
 
   
 
   
        Rst_n <= '1';
+
    Rst_n <= '1';
 +
    led_cathode <= '0';
 
   
 
   
-- compteur de 0 à max_count
+
    -- compteur de 0 à max_count
compteur : process(Clk)
+
    compteur : process(Clk)
variable count : natural range 0 to max_count;
+
        variable count : natural range 0 to max_count;
begin
+
    begin
      if Rst_n = '0' then
+
        if Rst_n = '0' then
        count := 0;
+
            count := 0;
        led_anode <= '1';
+
            led_anode <= '1';
         led_cathode <= '0';
+
         elsif rising_edge(Clk) then
elsif rising_edge(Clk) then
+
            if count < max_count/2 then
if count < max_count/2 then
+
                led_anode   <='1';
led_anode <='1';
+
                count := count + 1;
led_cathode <='0';
+
            elsif count < max_count then
count := count + 1;
+
                led_anode   <='0';
elsif count < max_count then
+
                count := count + 1;
led_anode <='0';
+
            else
led_cathode <='0';
+
                count := 0;
count := count + 1;
+
                led_anode   <='1';
else
+
            end if;
count := 0;
+
        end if;
led_anode <='1';
+
    end process compteur;  
led_cathode <='0';
+
end if;
+
end if;
+
end process compteur;  
+
 
  end RTL;
 
  end RTL;
 
</source>
 
</source>
Line 55: Line 54:
  
 
Pour que ISE puisse savoir sur quels pins brancher chaque signal, il est nécessaire de lui fournir un fichier de contraintes en *.ucf :
 
Pour que ISE puisse savoir sur quels pins brancher chaque signal, il est nécessaire de lui fournir un fichier de contraintes en *.ucf :
 
+
<source lang="VHDL">
NET "Clk" LOC = "P55";
+
NET "Clk" LOC = "P55";
NET "Clk" TNM_NET = "Clk";
+
NET "Clk" TNM_NET = "Clk";
TIMESPEC "TS_Clk" = PERIOD "Clk" 10 ns HIGH 50 %;
+
TIMESPEC "TS_Clk" = PERIOD "Clk" 10 ns HIGH 50 %;
NET "led_cathode" LOC = "P119"| IOSTANDARD = LVCMOS33 ;
+
NET "led_cathode" LOC = "P118"| IOSTANDARD = LVCMOS33 ;
NET "led_anode"  LOC = "P118"| IOSTANDARD = LVCMOS33 ;
+
NET "led_anode"  LOC = "P116"| IOSTANDARD = LVCMOS33 ;
 +
</source>
  
 
Des exemples de ucf peuvent être trouvés dans le répertoire firmware du projet Armadeus.
 
Des exemples de ucf peuvent être trouvés dans le répertoire firmware du projet Armadeus.
Line 66: Line 66:
 
Une fois que ces deux fichiers sont écrits il suffit de générer le bitstream en double cliquant sur "Synthetize - XST" puis sur "Implement Design" et enfin "Generate Programming File". Si ces opérations se sont bien passées, on se retrouve avec un fichier Clk_div_led.bit (du nom du vhdl).
 
Une fois que ces deux fichiers sont écrits il suffit de générer le bitstream en double cliquant sur "Synthetize - XST" puis sur "Implement Design" et enfin "Generate Programming File". Si ces opérations se sont bien passées, on se retrouve avec un fichier Clk_div_led.bit (du nom du vhdl).
  
C'est à partir de maintenant que les ennuis commencent (ou les choses intéressante c'est selon). Il faut télécharger le bitstream dans le fpga. Pour cela j'ai utilisé UBoot, en ayant bien pris soin de configurer le réseau correctement comme expliqué sur la page [[Connection_with_U-Boot_on_Linux]].
+
C'est à partir de maintenant que les ennuis commencent (ou les choses intéressante c'est selon). Il faut télécharger le bitstream dans le FPGA. Pour cela j'ai utilisé UBoot, en ayant bien pris soin de configurer le réseau correctement comme expliqué sur la page [[Connection_with_U-Boot_on_Linux]].
  
 
il faut donc mettre le bitstream dans le répertoire tftpboot :
 
il faut donc mettre le bitstream dans le répertoire tftpboot :
 +
<pre class="host">
 
  cp Clk_div_led.bit /tftpboot
 
  cp Clk_div_led.bit /tftpboot
 +
</pre>
  
 
Puis via la carte armadeus, le télécharger en ram :
 
Puis via la carte armadeus, le télécharger en ram :
 +
<pre class="apf">
 
  BIOS> tftpboot 08000000 Clk_div_led.bit
 
  BIOS> tftpboot 08000000 Clk_div_led.bit
 
  dm9000 i/o: 0x15c00000, id: 0x90000a46  
 
  dm9000 i/o: 0x15c00000, id: 0x90000a46  
Line 82: Line 85:
 
  done
 
  done
 
  Bytes transferred = 131029 (1ffd5 hex)
 
  Bytes transferred = 131029 (1ffd5 hex)
 +
</pre>
  
 
L'enregistrer en flash :
 
L'enregistrer en flash :
 +
<pre class="apf">
 
  BIOS> run flash_firmware
 
  BIOS> run flash_firmware
 
  .. done
 
  .. done
Line 89: Line 94:
 
  Copy to Flash... done
 
  Copy to Flash... done
 
  Flashing Firmware succeed
 
  Flashing Firmware succeed
 +
</pre>
  
 
+
Puis le lancer en utilisant l'adresse du FPGA mappée en 0x10060000 (voir [[Target_Software_Installation]]) et la taille du bitstream donnée au moment du téléchargement (Bytes transferred = 131029 (1ffd5 hex)) :
 
+
<pre class="apf">
Puis le lancer en utilisant l'adresse du fpga mappée en 0x10060000 (voir [[Target_Software_Installation]]) et la taille du bitstream donnée au moment du téléchargement (Bytes transferred = 131029 (1ffd5 hex)) :
+
 
  BIOS> fpga load 0 010060000 1ffd5
 
  BIOS> fpga load 0 010060000 1ffd5
 +
</pre>
  
 
Si vous ne voulez pas flasher le bitstream à chaque fois, vous pouvez le charger directement depuis la ram via la commande:
 
Si vous ne voulez pas flasher le bitstream à chaque fois, vous pouvez le charger directement depuis la ram via la commande:
 +
<pre class="apf">
 
  BIOS>fpga load 0 08000000 1ffd5
 
  BIOS>fpga load 0 08000000 1ffd5
 +
</pre>
  
Et voila, si tout c'est bien passé, la led clignote ...
+
Et voila, si tout c'est bien passé, la LED clignote ...

Latest revision as of 12:43, 5 March 2009

Pour me faire la main avec le kit et surtout avec le FPGA je me suis mis en tête de faire clignoter le une LED du FPGA. Pour cela je me suis un peu inspiré du montage proposé FPGA_and_led que j'ai modifié pour pouvoir tester ensuite la led en capteur de lumière.

figure 1 - LED wiring

L'intérêt du clignotement d'une LED est relativement limité, cependant il permet de prendre en main la totalité de la chaine de développement sur la carte Armadeus.

Après avoir installé le Xilinx Web Pack généreusement offert par Xilinx, il suffit de réaliser un compteur qui divisera la fréquence de l'horloge de manière à avoir un clignotement de quelques Hertz (La fréquence du spartan3 étant de 96MHz nous diviserons par 48000000 !).

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.numeric_std.all;
 
 entity Clk_div_led is
    Port ( 
           Clk             : in  std_logic;
           led_cathode     : out std_logic;
           led_anode       : out std_logic
    );
 end Clk_div_led;
 
 architecture RTL of Clk_div_led is
   constant max_count : natural := 48000000;
   signal Rst_n : std_logic;
 begin
 
    Rst_n <= '1';
    led_cathode <= '0';
 
    -- compteur de 0 à max_count
    compteur : process(Clk)
        variable count : natural range 0 to max_count;
    begin
        if Rst_n = '0' then
            count := 0;
            led_anode <= '1';
        elsif rising_edge(Clk) then
            if count < max_count/2 then
                led_anode    <='1';
                count := count + 1;
            elsif count < max_count then
                led_anode    <='0';
                count := count + 1;
            else
                count := 0;
                led_anode    <='1';
            end if;
        end if;
    end process compteur; 
 end RTL;


Pour que ISE puisse savoir sur quels pins brancher chaque signal, il est nécessaire de lui fournir un fichier de contraintes en *.ucf :

NET "Clk" LOC = "P55";
NET "Clk" TNM_NET = "Clk";
TIMESPEC "TS_Clk" = PERIOD "Clk" 10 ns HIGH 50 %;
NET "led_cathode" LOC = "P118"| IOSTANDARD = LVCMOS33 ;
NET "led_anode"   LOC = "P116"| IOSTANDARD = LVCMOS33 ;

Des exemples de ucf peuvent être trouvés dans le répertoire firmware du projet Armadeus.

Une fois que ces deux fichiers sont écrits il suffit de générer le bitstream en double cliquant sur "Synthetize - XST" puis sur "Implement Design" et enfin "Generate Programming File". Si ces opérations se sont bien passées, on se retrouve avec un fichier Clk_div_led.bit (du nom du vhdl).

C'est à partir de maintenant que les ennuis commencent (ou les choses intéressante c'est selon). Il faut télécharger le bitstream dans le FPGA. Pour cela j'ai utilisé UBoot, en ayant bien pris soin de configurer le réseau correctement comme expliqué sur la page Connection_with_U-Boot_on_Linux.

il faut donc mettre le bitstream dans le répertoire tftpboot :

 cp Clk_div_led.bit /tftpboot

Puis via la carte armadeus, le télécharger en ram :

 BIOS> tftpboot 08000000 Clk_div_led.bit
 dm9000 i/o: 0x15c00000, id: 0x90000a46 
 MAC: 00:0e:32:00:00:01
 operating at 10M half duplex mode
 TFTP from server 192.168.0.143; our IP address is 192.168.0.10
 Filename 'Clk_div_led.bit'.
 Load address: 0x8000000
 Loading: T ##########################
 done
 Bytes transferred = 131029 (1ffd5 hex)

L'enregistrer en flash :

 BIOS> run flash_firmware
 .. done
 Erased 2 sectors
 Copy to Flash... done
 Flashing Firmware succeed

Puis le lancer en utilisant l'adresse du FPGA mappée en 0x10060000 (voir Target_Software_Installation) et la taille du bitstream donnée au moment du téléchargement (Bytes transferred = 131029 (1ffd5 hex)) :

 BIOS> fpga load 0 010060000 1ffd5

Si vous ne voulez pas flasher le bitstream à chaque fois, vous pouvez le charger directement depuis la ram via la commande:

 BIOS>fpga load 0 08000000 1ffd5

Et voila, si tout c'est bien passé, la LED clignote ...