IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Le blog de f-leb

[Actualité] [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2

Note : 3 votes pour une moyenne de 3,67.
par , 01/09/2023 à 08h00 (7294 Affichages)
Lors du billet précédent, nous avions vu comment établir la description d'un composant simple appelé multiplexeur :

Nom : mux.png
Affichages : 2622
Taille : 5,6 Ko
Si sel=0, a est dirigé vers s, et si sel=1, c'est b qui est dirigé vers s

Au niveau d'abstraction le plus bas, le niveau structurel, ce composant est décrit par le câblage de portes logiques élémentaires (portes AND, OR et NOT dans ce cas précis). Voyons comment pourrait-on établir une description de ce composant à un plus haut niveau d'abstraction.


Description par flot de données

En Verilog/SystemVerilog, on reconnait une description de type « flot de données » par le mot-clé assign.

Par exemple, pour le multiplexeur de base :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
module mux21
   (
      output      logic s,
      input       logic a, b,
      input       logic sel      
   );
   
   assign s = (a & ~sel) | (b & sel);
   
endmodule

Alors que signifie cette « assignation » ? Le signe = n'est pas celui d'une « affectation » que l'on rencontre dans les langages de programmation. D'ailleurs ce module générera un circuit logique combinatoire, il n'y a pas d'emplacement mémoire réservé pour stocker une valeur. Ici, les « variables » en jeu sont des nœuds, qui transportent des signaux logiques, sans mémoire.

On souhaite que le signal s vérifie une égalité, continuellement. Toute évolution du terme à droite du signe = due à l'évolution des signaux doit être répercutée sur le signal à gauche du signe =. La sémantique de l'assignation est donc plus forte (pensez à l'« assignation à résidence », l'« assignation en justice », etc. ça ne rigole pas toujours...)

Le terme de droite, et vous l'aurez reconnue, est l'équation logique du multiplexeur (voir billet précédent, où on avait abouti à l'équation Formule mathématique). Une équation logique écrite avec les opérateurs binaires comme en langage C, tout cela est bien rassurant, mais ne perdez jamais de vue l'interprétation de cette syntaxe C-like dans un HDL.

Bien entendu, les concepteurs de HDL ont prévu toutes les situations avec des opérateurs en abondance. Par exemple, si les entrées du multiplexeur sont des bus, disons de largeur 4 bits, au lieu d'écrire bit par bit :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
assign s[0] = (a[0] & ~sel) | (b[0] & sel);
assign s[1] = (a[1] & ~sel) | (b[1] & sel);
assign s[2] = (a[2] & ~sel) | (b[2] & sel);
assign s[3] = (a[3] & ~sel) | (b[3] & sel);
On peut écrire grâce à l'opérateur de réplication de bits : {n{...}} :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
assign s = (a & {4{~sel}}) | (b & {4{sel}});

On y perd quand même en lisibilité, mais tout cela peut encore être remplacé de façon équivalente par :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
assign s = sel ? b : a;
Encore une syntaxe C-like avec l'opérateur ternaire condition ? signal_si_vrai : signal_si_faux (voir la FAQ C pour rappel). À ce niveau d'abstraction, on s'éloigne déjà bien de l'électronique numérique et de ses circuits à logique combinatoire.

Mais il y a encore un niveau d'abstraction au-dessus...

Description comportementale

Au niveau comportemental, un bloc de logique combinatoire débute avec l'instruction always_comb. On peut repartir de l'équation logique du multiplexeur pour écrire un bloc séquentiel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module mux21
   (
      output      logic s,
      input       logic a, b,
      input       logic sel      
   );
        
   logic q1, q2, sel_n;

   always_comb begin
      sel_n = ~sel;
      q1 = a & sel_n;
      q2 = b & sel;
      s = q1 | q2;   
   end

endmodule
Mais il semble plus naturel de décrire le comportement du multiplexeur à partir de sa définition (Si sel=1 alors l'entrée b est dirigée vers la sortie s, sinon...). On en oublierait (presque) toute notion d'électronique numérique.
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module mux21
   (
      output logic s,
      input  logic a, b,
      input  logic sel      
   );
      
   always_comb begin
      if (sel) 
         s = b;
      else
         s = a;
   end

endmodule

Avec always_comb, vous introduisez donc un bloc de logique combinatoire. Au niveau sémantique, on signifie que la logique du bloc doit être évaluée continuellement en fonction de l'évolution des signaux en entrée.

Si le multiplexeur a quatre entrées, l'emploi de case est également possible :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module mux41  // 4 entrées, 1 sortie
   (
      output logic s,
      input  logic a, b, c, d,
      input  logic [1:0] sel  // 2 bits pour la sélection    
   );
     
   always_comb begin
      case(sel)
         0 : s = a;
         1 : s = b;
         2 : s = c;
         3 : s = d;     
      endcase
   end
   
endmodule

Alors vous pouvez toujours établir votre description de façon structurelle ou par flot de données (avec assign et une belle équation qui doit tenir sur une ligne), mais le niveau comportemental permet des descriptions beaucoup plus riches et de façon plus naturelle pour un développeur, avec des calculs, des if...else que l'on peut imbriquer, des case, etc.

Par exemple, si on veut rajouter une entrée d'activation au multiplexeur 4 entrées précédent, on pourra écrire de façon comportementale le code suivant :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module mux41  // 4 entrées, 1 sortie
   (
      output logic s,
      input  logic a, b, c, d, 
      input logic enable_n, // entrée d'activation, active à l'état bas
      input  logic [1:0] sel      
   );
     
   always_comb begin
      if (enable_n)  // si inactif
         s = 0;
      else begin
         case(sel)
            0 : s = a;
            1 : s = b;
            2 : s = c;
            3 : s = d;     
         endcase
      end
   end
   
endmodule

Nom : mux41-enable-rtlView.png
Affichages : 1333
Taille : 10,2 Ko
Analyse par le synthétiseur du multiplexeur 4 entrées avec entrée d'activation

Il faut juste, une fois de plus, ne pas oublier que malgré cette lecture séquentielle du code dans les blocs always_comb, un circuit à logique combinatoire sera généré par le synthétiseur, où tous les signaux évoluent « en même temps ».

Conclusion

LES HDL permettent de synthétiser des systèmes complexes à différents niveaux d'abstraction. À un niveau élevé d'abstraction, le développeur se soucie moins des détails de l'électronique numérique et de son implémentation physique. L'écriture du code en est également facilitée, sa mise au point et sa réutilisation sont favorisées.
Pour autant, dans un projet un peu consistant, vous allez certainement mixer les niveaux d'abstraction. Les fonctionnalités du projet seront découpées en modules logiques plus petits qui seront reliés entre eux ou avec les entrées-sorties du système (description structurelle). À l'intérieur des modules, vous élevez le niveau d'abstraction en fonction de la complexité.

Nom : seg7.png
Affichages : 1279
Taille : 13,0 Ko
Exemple de structure d'un projet de chronomètre (au 1/10è de seconde avec afficheur 7-segments). Un module pour le comptage, un pour l'affichage du compteur, un autre pour filtrer les rebonds d'un bouton-poussoir, etc.

Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Viadeo Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Twitter Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Google Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Facebook Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Digg Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Delicious Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog MySpace Envoyer le billet « [FPGA] Les niveaux d'abstraction dans les langages de description de matériel (HDL) - Partie 2/2 » dans le blog Yahoo

Catégories
FPGA

Commentaires

  1. Avatar de Delias
    • |
    • permalink
    Deux beaux et bons articles de blog.

    Une description courte, pédagogique et qui montre parfaitement la distinction à faire entre la programmation "usuelle" et la programmation matériel.

    A titre perso, j'ai toujours trouver la mise en oeuvre chère et compliquée pour des projets perso. Pour en avoir l'usage il faut quand-même avoir besoin d'une grande vitesse et/ou d'un grand parallélisme de traitement.

    Delias
  2. Avatar de f-leb
    • |
    • permalink
    Merci Delias

    Citation Envoyé par Delias
    Une description courte, pédagogique...
    Avec des exemples et des démonstrations très simples, l'objectif est en effet essentiellement pédagogique.

    Citation Envoyé par Delias
    A titre perso, j'ai toujours trouver la mise en oeuvre chère et compliquée pour des projets perso.
    Je suis d'accord avec toi, dans mes billets et articles sur le FPGA, à part l'exploitation du port VGA en 640x480@60Hz, la plupart de mes petits projets sur FPGA seraient quand même plus faciles et moins couteux à développer sur microcontrôleur. Faire clignoter une LED sur FPGA c'est un peu du gâchis, mais il faut bien en passer par là quand on débute...

    Citation Envoyé par Delias
    Pour en avoir l'usage il faut quand-même avoir besoin d'une grande vitesse et/ou d'un grand parallélisme de traitement.
    Tout à fait. Le FPGA est aussi intéressant pour mettre en oeuvre des protocoles de communication série un peu particuliers. Je pense aux rubans de LED de type ws2812B. Le timing est quand même serré et il faut être précautionneux sur microcontrôleur (surtout si vous devez piloter autre chose en plus sur le micro), alors que la description du protocole en HDL n'est finalement pas très compliquée.