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

Le blog de f-leb

[Actualité] [FPGA] [Verilog/SystemVerilog] Que fait ce code ?

Note : 2 votes pour une moyenne de 3,00.
par , 02/10/2023 à 09h00 (6626 Affichages)
En Verilog/SystemVerilog, on peut trouver ce genre de code :
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
a <= b;
b <= a;
Mais que fait ce code ? Il renvoie Vrai si a est inférieur ou égal à b... Non, ce n'est pas ça. Le signe <= est surement un opérateur d'affectation : je mets b dans a... puis a dans b ? C'est pour échanger les valeurs de a et b (swap? Mais ça ne peut pas fonctionner, car « normalement » pour faire l'échange, il faut passer par une variable temporaire :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
temp = a;  a = b;  b = temp;
À moins que cela fonctionne comme une sorte d'affectation simultanée (ou parallèle) comme en Python : a, b = b, a.
Il y a de l'idée, mais ce n'est pas encore cela. Car en HDL (Hardware Description Language), il n'y a pas de « variables » comme dans les langages de programmation, mais il y a une notion qui semble s'en rapprocher, celle des registres.

Voyons une démonstration avec deux registres 3 bits synchrones (out1 et out2) dont on peut charger le contenu en mettant le signal de contrôle enable à l'état haut, et que l'on peut permuter en mettant le signal de contrôle swap à l'état haut :
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
module essai 
   (
      input logic clk, enable, swap,
      input logic[2:0] in1, in2,
      output logic[2:0] out1, out2   
   );   
     
   always_ff @(posedge clk) begin  // sensibilité au front montant de l'horloge

      if (enable) begin  // si chargement des registres
         out1 <= in1;
         out2 <= in2;
      end 
      else if (swap) begin // permutation des sorties
         out2 <= out1;
         out1 <= out2;
      end
      
   end
   
endmodule

La simulation fonctionnelle ci-dessous montre un exemple avec le chargement des registres out1 et out2 avec les valeurs 3 et 5 présentées en entrée, sur le premier front montant de l'horloge clk repéré en rouge. Ces valeurs sont maintenues en sortie après ce front, comme mémorisées. On voit ensuite l'effet de la permutation des valeurs de sortie au 2è front montant repéré en rouge :

Nom : swap-waveform2.png
Affichages : 6064
Taille : 14,8 Ko

L'analyse RTL donne le schéma suivant, où j'ai mis en surbrillance le flot des transferts lorsque le signal swap est activé (swap=1, enable=0) :

Nom : rtl-view-swap2a.png
Affichages : 2931
Taille : 13,0 Ko
swap=1, enable=0

On voit en rouge et en bleu que la sortie de chaque registre (3 bits) est dirigée vers l'entrée de l'autre registre, ce qui permet la permutation attendue des signaux en sortie.

Une fois le transfert effectué au front d'horloge, on peut voir ci-dessous le flot formant une boucle où la sortie de chaque registre est redirigée vers son entrée pour maintenir son état :

Nom : rtl-view-swap2b.png
Affichages : 2917
Taille : 12,9 Ko
swap=0, enable=0

Alors comment bien interpréter cette écriture quelque peu déroutante ?
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
         out2 <= out1;
         out1 <= out2;

La sémantique de l'affectation dans les blocs always_ff

L'opérateur <= est donc bien un opérateur d'« affectation ».
  • Le signal du bus en sortie du registre évoqué à droite du signe <= porte l'état du registre à un instant présent. Et cet état est transmis à l'entrée du registre évoqué à gauche du signe <=, et sera pris en compte au front d'horloge suivant. Une ligne comme out2 <= out1; est donc une opération de transfert entre registres.
  • Il n'y a pas d'ordre d'exécution des affectations dans un bloc always_ff. Toutes les instructions d'affectation sont concurrentes et exécutées sur le même front d'horloge.
    On peut aussi bien écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
             out2 <= out1;
             out1 <= out2;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
             out1 <= out2;
             out2 <= out1;

Ce dernier point souligné en gras est fondamental.

Mais alors... Que fait cet autre code ci-dessous ?
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 quefaitcetruc
   (
      input logic clk, in_serial,
      output logic[3:0] Q 
   );   
     
   always_ff @(posedge clk) begin  // sensibilité au front montant de l'horloge
      Q[3] <= in_serial;
      Q[2] <= Q[3];
      Q[1] <= Q[2];
      Q[0] <= Q[1];
   end
   
endmodule

Réponse :
Ce module décrit le comportement d'un registre à décalage SIPO (Serial Input - Parallel Output) :

Nom : simul_shift_register.png
Affichages : 2830
Taille : 11,4 Ko
Simulation registre à décalage 4 bits SIPO

On voit que le bit présenté sur l'entrée série (en jaune) est « décalé » dans le registre 4 bits Q à chaque front montant de l'horloge.
On utilise ce principe lorsque l'on a besoin de convertir des données série sur une entrée (in_serial) en des données présentes sur une sortie parallèle (bus Q).

Exemple en simulation :

Nom : simul_shift_register_2.png
Affichages : 2802
Taille : 32,1 Ko

On voit que la séquence série 1011 (bit de poids faible en premier) est disponible sur le bus Q[3]Q[2]Q[1]Q[0] au 4è front d'horloge.

Les quatre transferts avec l'opérateur <= ci-dessous sont effectifs sur le même front d'horloge pour que le décalage puisse s'opérer.
Code SystemVerilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
      Q[3] <= in_serial;
      Q[2] <= Q[3];
      Q[1] <= Q[2];
      Q[0] <= Q[1];

Structurellement, quatre bascules D synchrones sont chaînées comme sur le schéma ci-dessous :

Nom : mapview_shift_register.png
Affichages : 2814
Taille : 19,5 Ko
Map view Quartus Pro Lite

Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Viadeo Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Twitter Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Google Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Facebook Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Digg Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Delicious Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog MySpace Envoyer le billet « [FPGA] [Verilog/SystemVerilog] Que fait ce code ? » dans le blog Yahoo

Mis à jour 15/10/2023 à 22h32 par f-leb

Tags: fpga
Catégories
FPGA

Commentaires