DOURNAC.ORG
Français  English
Accueil
Astronomie
Sciences
Philosophie
Informatique
Cv

Informatique > Développement d'un module de robot jouet sur carte FPGA Xilinx Spartan-6 (Nexys 3)



  • 1.Introduction
  • 2.Conception sur MDLE
    • 2.1 Graphe d'états de Moore
    • 2.2 Première méthode - Calcul avec 2 bascules T
    • 2.3 Simulation sur MDLE avec 2 bascules T
    • 2.4 Deuxième méthode - Calcul avec 2 bascules JK
    • 2.5 Simulation sur MDLE avec 2 bascules JK
  • 3.Implémentation sur carte FPGA Xilinx Spartan-6 - Nexys 3
    • 3.1 Création du design avec le logiciel Xilinx ISE
    • 3.2 IHM interagissant en temps réel avec la carte FPGA

1.Introduction :

On désire implémenter sur une carte Nexys 3 un jouet robot capable de simuler l'endormissement. Son interface est la suivante :

Le jouet doit fonctionner de la façon suivante :

  • l'état du jouet est réévaluer toutes les 2 secondes, au rythme de l'horloge H.
  • lorsque le jouet est éveillé, ses yeux sont ouverts, et il rit.
  • lorsque le jouet est en état de sommeil léger, ses yeux sont fermés et il grogne.
  • lorsque le jouet est en état de sommeil profond, ses yeux sont fermés et il ronfle.
  • lorsque le jouet est en état de détresse, il pleure les yeux ouverts.
  • le jouet en état éveillé qu'on laisse à la lumière reste en état éveillé, même s'il y a du bruit.
  • pour mettre le jouet en état de sommeil léger, il faut partir de l'état éveillé, puis éteindre le lumière, en absence de bruit. Eteindre la lumière avec du bruit met le jouet en état de détresse.
  • lorsque le jouet est en état de détresse, il revient à l'état éveillé au prochain front d'horloge où la lumière est allumée, qu'il y ait du bruit ou non. Sinon, il reste en état de détresse.
  • lorsque le jouet est en état de sommeil léger, il passe en sommeil profond si la lumière continue d'être éteinte avec absence de bruit. Toute autre manipulation amène le jouet en état de détresse.
  • le jouet reste en état de sommeil profond tant que la lumière est éteinte et qu'il n'y a pas de bruit.
  • lorsque le jouet est en état de sommeil profond et que la lumière s'allume en absence de bruit, le jouet passe à l'état éveillé. Toute autre manipulation amène le jouet en état de détresse.

2.Conception sur MDLE :

Nous allons d'abord concevoir le graphe d'états du jouet, qui sera de type Moore, puis le module correspondant et l'implémenter en SHDL (Simple Hardware Description Language) selon l'outil MDLE développé par Jean-Christophe Buisson au département Informatique de l'ENSEEIHT.

  • 2.1 Graphe d'états de Moore :

    Les entrées sont notées dans l'ordre lumière - bruit (L - B) et les sorties yeux - voix (s[2] - s[1] - s[0]). D'après les spécifications énoncées ci-dessus, le jouet robot a 4 états possibles :


    • éveillé (yeux ouverts et il rit) ; sortie = 101 ; noté EV
    • sommeil léger (yeux fermés et il grogne) ; sortie = 010 ; noté SL
    • sommeil profond (yeux fermés et il ronfle) ; sortie = 000 ; noté SP
    • détresse (yeux ouverts et il pleure) ; sortie = 111 ; noté DE


    Le graphe d'états est représenté sur la figure suivante :



    Figure : Graphe de Moore du module

    Voici la table de transition qui en résulte :


    entréesétat avantétat après
    00101010
    01101111
    10101101
    11101101
    00111111
    01111111
    10111101
    11111101
    00010000
    01010111
    10010111
    11010111
    00000000
    01000111
    10000101
    11000111

    Nous allons calculer de deux façons les relations entre les sorties et les entrées, la première assignation avec 2 bascules T et la seconde avec 2 bascules JK. Selon les règles heuristiques dont l'idée est de minimiser le nombre de bits qui changent (états ou sorties) lors des changements d'états, nous faisons l'assignation suivante :



    • 2.2 Première méthode - Calcul avec 2 bascules T :


      TxTyLBXY instant nXY instant n+1
      10000010
      01010001
      00100000
      00110000
      00000101
      00010101
      01100100
      01110100
      01001011
      11011001
      11101001
      11111001
      00001111
      10011101
      11101100
      10111101


      On calcule maintenant grâce aux tables de Karnaugh les relations concernant Tx et Ty :


      Table $\,{\large \text{T$_{x}$}}$Table $\,{\large \text{T$_{y}$}}$

      On en déduit :

      \begin{equation} {\large \text{T$_{x}$}=\overline{\text{L}}\,\overline{\text{B}}\,\overline{\text{X}}\,\overline{\text{Y}}+\text{X}\,\text{B}+\text{X}\,\text{L}\quad\quad\quad\quad\quad \text{T$_{y}$}=\text{X}\,\overline{\text{Y}}+\overline{\text{L}}\,\text{B}\,\overline{\text{Y}}+ \text{L}\,\overline{\text{X}}\,\text{Y}+\text{L}\,\overline{\text{B}}\,\text{Y}} \end{equation}

      Exprimons maintenant d'après la table suivante les sorties en fonction de X et Y :


      XYSorties (s[2] s[1] s[0])
      00101
      10010
      01111
      11000

      Il vient :

      \begin{align} S[2]\,&{\large =\overline{\text{X}}\,\overline{\text{Y}}+\overline{\text{X}}\,\text{Y}=\overline{\text{X}}\,(\overline{\text{Y}}+\text{Y})=\overline{\text{X}}}\\ S[1]\,&{\large =\text{X}\,\overline{\text{Y}}+\overline{\text{X}}\,\text{Y}=\text{X}\,\oplus\,\text{Y}}\\ S[0]\,&{\large =\overline{\text{X}}\,\overline{\text{Y}}+\overline{\text{X}}\,\text{Y}=\overline{\text{X}}\,(\overline{\text{Y}}+\text{Y})=\overline{\text{X}}} \end{align}
    • 2.3 Simulation sur MDLE avec 2 bascules T :

      L'outil MDLE permet de simuler le fonctionnement des circuits combinatoires et séquentiels. Il utilise le langage SHDL (Simple Hardware Description Language). Dans le but d'être pédagogique, son écriture est très simple et permet de concevoir des modules d'une manière plus condensée qu'avec d'autres langages habituels de description matérielle comme le VHDL. Pour plus d'informations sur la syntaxe, voir ici.

      Voici le source robot_first.mdl correspondant au module conçu avec 2 bascules T :




      Nous pouvons charger ce design grâce à l'éditeur graphique, ce qui donne :




      Grâce au simulateur de MDLE, on peut parcourir le graphe de Moore en fonction du temps et des entrées. Ceci est illustré sur la vidéo suivante :


      Video not playing? Download file instead.

    • 2.4 Deuxième méthode - Calcul avec 2 bascules JK :


      JxKxJyKyLBXY instant nXY instant n+1
      1000000010
      0010010001
      0000100000
      0000110000
      0000000101
      0000010101
      0001100100
      0001110100
      0010001011
      0110011001
      0110101001
      0110111001
      0000001111
      0100011101
      0101101100
      0100111101


      On calcule maintenant grĂ¢ce aux tables de Karnaugh les relations concernant Jx, Kx, Jy et Ky :


      Table $\,{\large \text{J$_{x}$}}$Table $\,{\large \text{K$_{x}$}}$

      Ce qui donne :

      \begin{equation} {\large \text{J$_{x}$}=\overline{\text{L}}\,\overline{\text{B}}\,\overline{\text{X}}\,\overline{\text{Y}}\quad\quad\quad\quad\quad \text{K$_{x}$}=\text{B}\,\text{X}+\text{L}\,\text{X}} \end{equation}

      Table $\,{\large \text{J$_{y}$}}$Table $\,{\large \text{K$_{y}$}}$

      On obtient :

      \begin{equation} {\large \text{J$_{y}$}=\overline{\text{L}}\,\text{B}\,\overline{\text{Y}}+\text{X}\,\overline{\text{Y}}\quad\quad\quad\quad\quad \text{K$_{y}$}=\text{L}\,\overline{\text{X}}\,\text{Y}+\text{L}\,\overline{\text{B}}\,\text{Y}} \end{equation}
    • 2.5 Simulation sur MDLE avec 2 bascules JK :

      Voici le source robot_second.mdl correspondant au module conçu avec 2 bascules JK :



      Nous pouvons charger ce design grâce à l'éditeur graphique, ce qui donne :



      Comme avec les 2 bascules T, on peut vérifier la bonne modélisation du circuit grâce au simulateur de MDLE.

3.Implémentation sur carte FPGA Xilinx Spartan-6 - Nexys 3 :

Nous allons dans un premier temps implémenter de manière hardware le design que nous avons conçcu ci-dessus. Le logiciel Xilinx ISE permet de faire cela en générant un fichier binaire (.bit) que l'on peut ensuite transférer depuis le PC vers la carte FPGA. Après cette première implémentation, nous allons créer une IHM permettant d'intéragir en temps réel avec la carte.

  • 3.1 Création du design avec le logiciel Xilinx ISE :

    Le logiciel ISE permet de synthétiser le circuit séquentiel de notre module de robot jouet. Pour décrire ce design, ISE nécessite un fichier de description matérielle écrit en langage VHDL (plutôt utilisé en Europe) ou Verilog (plutôt utilisé aux US). Nous choisirons le langage VHDL car nous disposons d'un outil permettant de convertir un source SHDL en un source VHDL. Cet outil s'appelle SHDL2VHDL Converter et est téléchargeable ici : shdl2vhdl2.1.4.jar.


    Utilisons à présent le source SHDL robot_second.mdl (design correspondant au paragraphe 2.4) et convertissons le en VHDL grâce à l'outil SHDL2VHDL, nous obtenons le source robot_second.vhd :


    library IEEE;
    library UNISIM;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity robot_second is
      port (
        l : in std_logic ;
        b : in std_logic ;
        h : in std_logic ;
        rst : in std_logic ;
        s2 : out std_logic ;
        s1 : out std_logic ;
        s0 : out std_logic
      );
    end robot_second;

    architecture synthesis of robot_second is

      -- internal signals declarations
      signal jx : std_logic ;
      signal y : std_logic ;
      signal x : std_logic ;
      signal kx : std_logic ;
      signal jy : std_logic ;
      signal ky : std_logic ;

    begin

      -- concurrent statements
      jx <= (not l) and (not b) and (not y) and (not x) ;
      kx <= (b and x) or (l and x) ;
      jy <= (x and (not y)) or ((not l) and b and (not y)) ;
      ky <= (l and (not b) and y) or (l and (not x) and y) ;
      s2 <= not x ;
      s1 <= (x and (not y)) or ((not x) and y) ;
      s0 <= not x ;

      -- sequential statements
      process (h, rst) begin
        if rst = '1' then
          x <= '0' ;
        elsif h'event and h = '1' then
          x <= ((not kx) and x) or (jx and (not x)) ;
        end if ;
      end process ;
      process (h, rst) begin
        if rst = '1' then
          y <= '0' ;
        elsif h'event and h = '1' then
          y <= ((not ky) and y) or (jy and (not y)) ;
        end if ;
      end process ;

    end synthesis;


    Dans le projet ISE, Il nous faut maintenant un fichier permettant de faire le lien entre les signaux du source VHDL et les connecteurs d'entrée/sorties de la carte FPGA. Ce fichier s'appelle le "User Constraints File" (UCF). Nous choisissons les switch SW3, SW2, SW1 et SW0 pour respectivement les entrées reset (rst), clock (h), lumière (l) et bruit (b). Pour la sortie, nous utilisons les led LD2, LD1 et LD0 respectivement pour les sorties s2 (yeux), et (s1,s0) (voix). On a donc le fichier robot.ucf suivant :

    # Inputs
    NET "l"  LOC = "T9";
    NET "b"  LOC = "T10";
    NET "h"  LOC = "V9";
    NET "rst"  LOC = "M8";

    # Outputs
    NET "s0" LOC = "U16";
    NET "s1" LOC = "V16";
    NET "s2" LOC = "U15";

    Dans le projet ISE, nous ajoutons le source VHDL "robot_second.vhd" ainsi que le fichier de contraintes "robot.ucf". Nous pouvons maintenant générer le fichier .bit. Voici une capture écran :



    Pour charger le fichier binaire depuis un terminal Linux, les commandes sont les suivantes :



    Ici une image de la carte avec les entrées (rst, h, l, b) et les sorties de l'état initial (Eveillé : 101) :



    Dans le design précédent, nous pouvons rajouter 3 afficheurs 7-segments pour les sorties ; c'est ce que nous avons fait dans ce source robotseg.vhd :


    library IEEE;
    library UNISIM;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity robotseg is
      port (
        l : in std_logic ;
        b : in std_logic ;
        h : in std_logic ;
        h1 : in std_logic ;  
        rst : in std_logic ;
        an : inout std_logic_vector (0 to 3) ;
        ss : out std_logic_vector (0 to 2) ;
        ssg : out std_logic_vector (0 to 7)    
      );
    end robotseg;

    architecture synthesis of robotseg is

            -- clock
      
      signal CTR : std_logic_vector (12 downto 0); 

      -- buffer signals declarations
      
      signal ss_int : std_logic_vector (0 to 2) ;

      -- internal signals declarations
      
      signal jx : std_logic ;
      signal y : std_logic ;
      signal kx : std_logic ;
      signal x : std_logic ;
      signal jy : std_logic ;
      signal ky : std_logic ;

    begin
      
     -- concurrent statements

      jx <= (not l) and (not b) and (not y) and (not x) ;
      kx <= (b and x) or (l and x) ;
      jy <= (x and (not y)) or ((not l) and b and (not y)) ;
      ky <= (l and (not b) and y) or (l and (not x) and y) ;
      ss_int(2) <= not x ;
      ss_int(1) <= (x and (not y)) or ((not x) and y) ;
      ss_int(0) <= not x ;
      
      -- buffer signals assignations
      
      ss(0 to 2) <= ss_int(0 to 2) ;
      
      process(h) begin
            if h'event and h= '1' then
         if (CTR="0000000000000") then
              if (an(3)='0') then        
            an(3) <= '1';
                        an(0) <= '0';
            ssg <="11111111";
              elsif (an(0)='0') then 
            an(0) <= '1';
            an(1) <= '0';
                      if ss_int(2)='0' then
             ssg <="00000011";
                  else ssg <="10011111";
                end if;  
                    elsif (an(1)='0') then                
            an(1) <= '1';
                        an(2) <= '0';
                      if ss_int(1)='0' then
             ssg <="00000011";
                  else ssg <="10011111";
          end if;  
                    elsif (an(2)='0') then 
            an(2) <= '1';
                  an(3) <= '0';
                      if ss_int(0)='0' then
             ssg <="00000011";
                  else ssg <="10011111";
          end if;        
            end if;
         end if;
         CTR<=CTR+"0000000000001";
            if (CTR > "1000000000000") then
                CTR<="0000000000000";
      end if;
            end if;
      end process;
      
      -- sequential statements
      
      process (h1, rst) begin
        if rst = '1' then
          x <= '0' ;
              elsif h1'event and h1 = '1' then
          x <= ((not kx) and x) or (jx and (not x)) ;
        end if ;  
      end process ;
      
            process (h1, rst) begin
        if rst = '1' then
          y <= '0' ;
              elsif h1'event and h1 = '1' then
          y <= ((not ky) and y) or (jy and (not y)) ;
        end if ;
      end process ;
      
    end synthesis;

    Le fichier de contraintes associé est robotseg.ucf.

    On obtient le résultat suivant (le robot jouet est dans l'état de Détresse (sortie = 111) :




  • 3.2 IHM interagissant en temps réel avec la carte FPGA :

    Nous allons créer une interface contrôlant en temps réel la carte Nexys 3. Pour cela, il nous faut utiliser les fonctions bas-niveau de la librairie dpcutil. Elles nous permettront d'envoyer et de recevoir des signaux depuis la carte. Le design précédent doit être complété afin d'y inclure la communication USB. Les données d'entrée/sortie seront stockées sur le registre se situant à l'adresse 10 ("regEppAdr=1010" dans dpimref.vhdl). Le fichier de contraintes est pins.ucf. Après avoir généré et transféré le fichier .bit, nous utilisons l'IHM suivante écrite en C avec les librairies GTK/OpenCV :

    •    main.c 


    • Script de compilation :

    #!/bin/sh

    INC="/usr/local/include/digilent/adept"
    LIBDIR="/usr/local/lib64/digilent/adept"
    CFLAGS="-Wall -I $INC -L $LIBDIR"

    g++ $CFLAGS -I/usr/include/gtk-2.0/ -I/usr/include/glib-2.0/ -I/usr/lib/glib-2.0/include/ -I/usr/local/include/opencv/ \
    -I/usr/include/cairo/ -I/usr/include/pango-1.0/ -I/usr/lib/gtk-2.0/include/ -I/usr/include/atk-1.0/ -L/usr/local/lib/ \
    -lcvaux -lhighgui -lcxcore -ldepp -ldmgr main.c


    cette vidéo montre le bon fonctionnement des interactions I/O :


    Video not playing? Download file instead.


ps : contribuez comme moi au projet Cosmology@Home dont le but est d'affiner le modèle décrivant le mieux notre Univers.

    Accueil | Astronomie | Sciences | Philosophie | Informatique | Cv    
- dournac.org © 2003 by fab -

Haut de Page