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 1/2

Noter ce billet
par , 18/08/2023 à 13h00 (9314 Affichages)
On ne le rappellera jamais assez... Les langages de description de matériel (ou HDL pour Hardware Description Language) tels VHDL ou Verilog/SystemVerilog ne sont pas des langages de programmation classiques comme C, C++, Java, etc. Même si on retrouve des séquences procédurales dans la syntaxe de ces langages, il ne s'agit plus de produire des suites d'instructions exécutées séquentiellement par un CPU.

Nom : quartus-view.png
Affichages : 5158
Taille : 62,3 Ko

Le but des HDL est de générer des circuits logiques qui répondront aux spécifications, et qui seront finalement implémentés physiquement dans la puce FPGA.
Les HDL permettent à ce titre au développeur de faire des descriptions de matériel à différents niveaux d'abstraction. Les trois niveaux d'abstraction reconnus sont :
  • niveau structurel (structural) : le plus bas niveau, le circuit est vu comme des blocs de primitives ou fonctions logiques aux entrées-sorties connectées entre elles ;
  • niveau flot de données (flow data) : un niveau d'abstraction au-dessus, un signal peut être décrit par une équation logique, mais aussi avec une syntaxe un peu plus avancée parfois proche des langages procéduraux comme C ou C++ ;
  • niveau comportemental (behavorial) : le plus haut niveau d'abstraction, on ne décrit plus la structure du circuit mais comment il doit se comporter. Le langage HDL permet alors des structures de contrôle avancées avec des if... else ou des case, comme en C, C++, Java, etc. (mais on n'oublie pas la première phrase de ce billet).

Lors de la phase dite de « compilation », le synthétiseur prend en charge le programme en HDL pour générer le circuit logique d'abord, pour finalement produire le fichier binaire bitstream qui va configurer la puce FPGA cible avec le placement et le routage des composants de façon la plus optimisée possible.

À titre de démonstration, on propose de découvrir ces trois niveaux d'abstraction à travers la description d'un circuit logique combinatoire simple appelé multiplexeur (parfois appelé sélecteur) en SystemVerilog (une extension du langage Verilog).

Définition d'un multiplexeur (abrégé MUX)

L'entrée a ou b est dirigée vers la sortie s suivant la valeur du signal de sélection sel. Si sel = 0, ce sera le signal a qui sera dirigé vers la sortie s, et si sel = 1, ce sera le signal b qui sera dirigé vers la sortie s.

Nom : mux.png
Affichages : 2033
Taille : 5,6 Ko
Schéma d'un multiplexeur

À partir de la définition, on peut établir la table de vérité d'un multiplexeur :

sel a b s
0 0 0 0
0 0 1 0
0 1 0 1
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 0
1 1 1 1

Et on en déduit l'équation logique de la sortie s : Formule mathématique

Voyons quelques descriptions de ce composant logique à des niveaux d'abstraction différents.

Description structurelle

De l'équation logique, on en déduit la structure avec des portes logiques élémentaires, ici des portes AND, OR et NOT.

Nom : mux_logic_cells.png
Affichages : 1807
Taille : 5,5 Ko
Schéma logique du multiplexeur

On s'aide du schéma ci-dessus pour, en SystemVerilog, instancier des portes logiques et faire du câblage :

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
module mux21  // multiplexeur 2 entrées - 1 sortie
   (
      output   logic s,
      input    logic a, b, sel      
   );
         
   logic q1, q2, sel_n; 

   not (sel_n, sel);
   and (q1, a, sel_n);  
   and (q2, b, sel);   
   or  (s, q1, q2);
  
endmodule

Faisons évoluer ce multiplexeur. Par exemple, s'il comporte maintenant quatre entrées, il faut une entrée de sélection sel codée sur 2 bits (sel[1] sel[0]).

Nom : mux41.png
Affichages : 1800
Taille : 4,9 Ko

Mais si on écrit l'équation logique à partir de la table de vérité, on se rend compte que notre multiplexeur à 4 entrées peut être obtenu en câblant astucieusement trois multiplexeurs à deux entrées :

Nom : mux41-with-mux21.png
Affichages : 1801
Taille : 6,8 Ko

Là encore, on se retrouve à faire du câblage, mais en réutilisant le module précédent, soit en SystemVerilog :
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 mux41  // 4 entrées, 1 sortie
   (
      output logic s,
      input  logic a, b, c, d,
      input  logic [1:0] sel      
   );
   
   logic q1, q2; // noeuds intermédiaires
   
   // instanciation de 3 multiplexeurs 2/1
   mux21 U0(q1, a, c, sel[1]);
   mux21 U1(q2, b, d, sel[1]);
   mux21 U2(s, q1, q2, sel[0]);
   
endmodule

Ce qui donne le schéma structurel suivant :

Nom : mux41-rtlView.png
Affichages : 1812
Taille : 21,6 Ko

Et que se passe-t-il si l'on veut multiplexer des entrées de type bus ? Avec des bus de largeur 4 bits par exemple :

Nom : mux-bus4bits.png
Affichages : 1807
Taille : 4,8 Ko
Les deux entrées et la sortie sont des bus 4 bits

Là encore, on s'en sort structurellement par association de 4 multiplexeurs élémentaires :
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
module mux_bus #(parameter WIDTH = 4)   // WIDTH=4 par défaut
   (
      output   logic[WIDTH-1:0] s,
      input    logic[WIDTH-1:0] a, b,
      input    logic sel      
   );
   
   
   mux21 mux_inst[WIDTH-1:0] (   // tableau d'instances de mux21
      .s,
      .a,
      .b,
      .sel  
   );
   
endmodule

Le module ici est même paramétré pour une largeur de bus WIDTH quelconque. Le schéma structurel devient :

Nom : mux-bus4bits-rtlView.png
Affichages : 1807
Taille : 33,3 Ko

Bien entendu, même en se limitant à la logique combinatoire, il est difficile de tout concevoir de cette façon pour des fonctionnalités avancées. De plus, il est difficile de modifier la structure si la fonctionnalité doit évoluer, le code est difficilement maintenable. Il faut alors programmer à un plus haut niveau d'abstraction et faire confiance au synthétiseur logique pour générer la structure.

Dans la deuxième partie de ce billet, nous verrons les derniers niveaux d'abstraction : flot de données et comportemental...

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

Mis à jour 01/09/2023 à 17h24 par f-leb

Catégories
FPGA

Commentaires