Maîtriser $display en Verilog : Techniques efficaces de débogage et de contrôle d’affichage

目次

1. Introduction : L’importance et le but de « display » en Verilog

Que signifie « display » en Verilog ?

En Verilog, $display est une tâche système utilisée comme outil pour « afficher » l’état interne d’un design pendant la simulation. À l’image du printf de C, elle permet d’envoyer des signaux, des valeurs de variables et des chaînes de caractères vers un terminal ou une console — jouant ainsi un rôle central dans le débogage et la vérification fonctionnelle.

Pourquoi $display est‑il essentiel pour le développement en Verilog ?

  • Efficacité de débogage améliorée : dans les conceptions de circuits complexes, visualiser si les signaux internes fonctionnent correctement est crucial. En utilisant $display, vous pouvez vérifier instantanément les valeurs des signaux d’intérêt pendant la simulation.
  • Visualisation de la simulation : lorsqu’on suit les transitions de valeurs à des instants précis, les formes d’onde seules peuvent être insuffisantes. Les journaux d’affichage offrent un moyen fiable d’indiquer ces moments exacts.
  • Utile également pour la documentation : lorsqu’on transmet l’intention du design ou les règles de fonctionnement à d’autres ingénieurs, insérer des journaux d’affichage annotés peut améliorer la compréhension du code.

Objectif et structure de cet article

Dans cet article, nous expliquerons méthodiquement les points suivants :

  1. Syntaxe de base et utilisation : une introduction soigneuse à la syntaxe fondamentale et à l’usage de $display.
  2. Comparaison avec d’autres tâches système : nous organiserons les différences entre les tâches liées à l’affichage telles que $write, $strobe et $monitor.
  3. Spécificateurs de format et techniques avancées : l’utilisation de spécificateurs comme %d, %b, %h, %s et des techniques d’affichage spéciales sera présentée.
  4. Exemples d’utilisation pratiques : nous montrerons des cas concrets dans des bancs de test et du code, en fournissant un savoir‑faire immédiatement applicable.
  5. Applications de contrôle d’affichage : des exemples d’utilisation incluront la sortie matérielle vers un LCD ou le contrôle d’un moniteur, ainsi que l’affichage de texte/image.

Avec cette structure, les débutants comme les utilisateurs intermédiaires pourront comprendre correctement $display en Verilog et l’appliquer en pratique. Dans chaque section suivante, nous avancerons clairement en utilisant des exemples et des diagrammes chaque fois que possible.

2. Bases de $display : Syntaxe, cas d’utilisation et précautions

Syntaxe de base de $display

Lorsqu’on utilise $display en Verilog, la syntaxe de base est la suivante.

$display("string or format specifiers", signal1, signal2, ...);
  • Partie chaîne : écrivez n’importe quel texte ou spécificateur de format (par exemple : %d, %b, %h).
  • Arguments : listez les noms de signaux ou de variables à afficher selon le format correspondant.

Exemple : affichage du compteur d’horloge et des valeurs de signaux

$display("Time=%0t : clk=%b, reset=%b", $time, clk, reset);

Dans cet exemple, le temps de simulation et les valeurs des signaux d’horloge/réinitialisation sont affichés.

Cas d’utilisation de $display

  1. Suivi de la progression de la simulation : en insérant $display à des points spécifiques de votre design, vous pouvez vérifier quelle partie du code a été exécutée.
  2. Vérification des valeurs de signaux : même lorsque les visualiseurs de formes d’onde rendent difficile la compréhension intuitive des branches conditionnelles ou des transitions d’état, l’affichage sous forme de texte facilite la compréhension.
  3. Affichage conditionnel de messages : en le combinant avec des instructions if, vous pouvez consigner des messages uniquement lorsque certaines conditions sont remplies.
    verilog if (reset) $display("Reset asserted at %0t", $time);

Différence entre $display et $write

$display ajoute automatiquement un saut de ligne à la fin de la sortie. En revanche, $write poursuit l’affichage sans ajouter de saut de ligne.
Exemple :

$display("Hello");
$display("World");

Sortie :

Hello
World
$write("Hello");
$write("World");

Sortie :

HelloWorld

Si vous avez besoin de journaux ligne par ligne plus clairs, utilisez $display. Lorsque vous souhaitez formater plusieurs sorties sur une même ligne, utilisez $write.

Précautions

  1. Éviter une sortie excessive Si vous utilisez $display à chaque cycle d’horloge, les journaux deviennent volumineux et la lisibilité diminue. → Utilisez une condition pour réduire la sortie.
  2. Utiliser l’affichage du temps Afficher $time ou $realtime vous permet de capturer avec précision le timing des opérations.
  3. Tâche uniquement pour la simulation $display ne peut pas être utilisé pour la synthèse (implémentation FPGA/ASIC). C’est strictement un outil de débogage réservé à la simulation.

3. Comparaison des tâches système d’affichage de journal : $display, $write, $strobe, $monitor

Verilog propose des tâches système au-delà de $display pour la sortie. Leurs différents cas d’utilisation et leurs timings font qu’il est utile de comprendre comment les utiliser distinctement.

$display : tâche d’affichage standard

  • Caractéristiques Ajoute automatiquement un saut de ligne et consigne une ligne par appel.
  • Cas d’utilisation La méthode de débogage de base la plus courante ; vous pouvez l’appeler à tout moment pour une sortie ponctuelle.

$write : affichage sans saut de ligne

  • Caractéristiques N’ajoute pas de saut de ligne et continue donc la sortie sur la même ligne.
  • Cas d’utilisation Utile lorsque vous voulez afficher plusieurs valeurs côte à côte.
  • Exemple $write("A=%d, ", a); $write("B=%dn", b); → Sortie : A=5, B=10.

$strobe : sortie à la fin du cycle de simulation

  • Caractéristiques Imprime les valeurs après que toutes les évaluations de simulation de l’étape courante soient terminées.
  • Cas d’utilisation Pratique pour éviter les conditions de course (lorsque plusieurs signaux changent simultanément).
  • Exemple $strobe("Time=%0t, signal=%b", $time, sig); → Alors que $display peut montrer des valeurs intermédiaires, $strobe montre les valeurs stabilisées.

$monitor : suivi automatique de la sortie

  • Caractéristiques Affiche automatiquement chaque fois qu’un signal surveillé change.
  • Cas d’utilisation Pratique lorsque vous voulez surveiller en continu un ensemble de signaux.
  • Exemple $monitor("At %0t: a=%b, b=%b", $time, a, b); → Consigne chaque fois que a ou b change.

Tableau récapitulatif

TâcheNouvelle ligneMoment de la sortieCas d’utilisation principal
$displayOuiLors de l’appelSortie de journal de base
$writeNonLors de l’appelFormatage côte à côte
$strobeOuiAprès la fin du cycle de simulationVérifier les valeurs stabilisées
$monitorOuiAutomatiquement au changement de signalSurveillance continue des signaux

Conseils pour une utilisation efficace

  • Utilisez $display par défaut : lisible et facile pour les débutants.
  • Utilisez $write lorsque vous voulez une sortie combinée sur une seule ligne.
  • Utilisez $strobe lorsque vous avez besoin de valeurs stabilisées après des changements.
  • Utilisez $monitor lorsque vous avez besoin d’une surveillance continue des signaux.

4. Spécificateurs de format et techniques d’affichage avancées

Avec des tâches comme $display ou $write, vous pouvez inclure des « spécificateurs de format » dans les chaînes pour afficher des signaux ou des variables dans les formats souhaités. Comme cela ressemble à printf en C, les utiliser correctement selon votre objectif améliore considérablement l’efficacité du débogage.

Spécificateurs de format de base

SpécificateurDescriptionExemple de sortie
%bbinaire1010
%ddécimal10
%hhexadécimalA
%ooctal12
%ccaractère ASCIIA
%schaîne de caractèresHello
%ttemps de simulation#100 etc.
%mnom de la hiérarchie du moduletop.u1.u2

Exemples pratiques

  1. Afficher un signal sous plusieurs formats
    verilog reg [7:0] data = 8'b10101010; $display("data = %b (bin), %d (dec), %h (hex)", data, data, data);
    → Exemple de sortie : data = 10101010 (bin), 170 (dec), AA (hex)

  2. Vérifier la hiérarchie du module
    verilog $display("Current module hierarchy is %m");
    → Exemple de sortie : Current module hierarchy is top.u1.counter

  3. Afficher le temps de simulation
    verilog $display("Time=%0t: clk=%b", $time, clk);
    → Exemple de sortie : Time=100: clk=1

Techniques d’affichage avancées

  • Zero-padding & field width Vous pouvez spécifier le remplissage de zéro ou la largeur de champ comme %0d. Exemple : $display("Count=%04d", count); → Sortie : Count=0012
  • Signed vs unsigned distinction %d traite les valeurs comme signées, %u les traite comme non signées. Si une valeur négative n’est pas affichée comme prévu, revoyez le spécificateur.
  • Multi-line messages formatting Utilisez n pour couper les lignes afin d’améliorer la lisibilité. Exemple : $display("Start of** : Les signaux Verilog peuvent avoir des largeurs différentes ; l’utilisation de%d` peut entraîner des problèmes de troncature ou d’extension de signe.
  • Handling undefined values (X, Z) : Si vous incluez des bits indéfinis, l’utilisation de %b affichera directement x ou z.

5. Exemples pratiques : Utilisation de $display dans les bancs de test et les modules

À partir d’ici, nous présenterons des utilisations efficaces de $display à travers des exemples de code Verilog réels, couvrant les bases des bancs de test insérant $display dans un banc de test, vous pouvez observer le comportement pendant la simulation.

module tb_counter;
  reg clk;
  reg reset;
  wire [3:0] count;

  // DUT (Device Under Test)
  counter uut (
    .clk(clk),
    .reset(reset),
    .count(count)
  );

  // Clock generation
  initial begin
    clk = 0;
    forever #5 clk = ~clk;  // invert every 5 units
  end

  // Test scenario
  initial begin
    reset = 1;
    #10 reset = 0;

    #50 $finish;
  end

  // Display state
  always @(posedge clk) begin
    $display("Time=%0t | reset=%b | count=%d", $time, reset, count);
  end
endmodule

Dans cet exemple, chaque front montant de l’horloge déclenche la sortie de reset et count. Comme vous pouvez inspecter les journaux texte ainsi que les formes d’onde, le suivi du comportement devient plus facile.

Exemple d’affichage conditionnel

En le combinant avec des instructions if, vous pouvez enregistrer uniquement lorsque des conditions spécifiques sont remplies.

always @(posedge clk) begin
  if (count == 4'd10) begin
    $display("Count has reached 10 (Time=%0t)", $time);
  end
end

→ Cela vous permet d’éviter les journaux superflus tout en ciblant les événements qui vous intéressent.

Exemple de message de débogage

Lors du débogage de la conception, il est efficace de détecter lorsqu’un signal entre dans un « état inattendu ».

always @(posedge clk) begin
  if (count > 4'd12) begin
    $display("WARNING: count overflow detected! Time=%0t, value=%d", $time, count);
  end
end

→ Vous pouvez rapidement découvrir des défauts de conception ou un comportement de simulation inattendu.

Surveillance de plusieurs signaux ensemble

Lors de la sortie de nombreux signaux, les regrouper sur une seule ligne avec $display rend les journaux plus lisibles.

$display("Time=%0t | clk=%b | reset=%b | A=%h | B=%h | SUM=%h",
         $time, clk, reset, A, B, SUM);

Résumé des conseils pratiques

  • Placez $display dans le banc de test pour visualiser la progression
  • Utilisez des branches conditionnelles pour affiner les journaux
  • Générez des messages d’avertissement pour détecter les anomalies
  • Consolidez plusieurs signaux sur une ligne pour améliorer la lisibilité

6. Applications de contrôle d’affichage (Pixel/Texte/Image)

Jusqu’à présent, nous avons présenté $display pour les journaux de simulation. Par ailleurs, Verilog est également largement utilisé pour le « contrôle d’affichage » dans les implémentations matérielles (sortie LCD, VGA, HDMI). Dans cette section, nous présentons brièvement comment implémenter l’affichage à l’écran au niveau matériel.

Concept fondamental du contrôle d’affichage

Pour afficher du texte ou des images sur un écran, vous devez générer des signaux vidéo plutôt que d’utiliser simplement $display.

Les signaux de contrôle typiques comprennent :

  • HSYNC (Synchronisation horizontale) : Signal qui indique la fin de chaque ligne
  • VSYNC (Synchronisation verticale) : Signal qui indique la fin de chaque trame
  • RGB Data : Signal représentant la couleur de chaque pixel (par ex., 8 bits × 3 = couleur 24 bits)

En Verilog, vous contrôlez ces signaux via des compteurs et des machines d’état et les sortez en fonction du timing pour réaliser un « affichage à l’écran ».

Exemple 1 : Affichage de barres de couleur

L’exemple le plus basique consiste à afficher des barres de couleur horizontalement sur un écran.

always @(posedge clk) begin
  if (h_counter < 100)       rgb <= 24'hFF0000; // red
  else if (h_counter < 200)  rgb <= 24'h00FF00; // green
  else if (h_counter < 300)  rgb <= 24'h0000FF; // blue
  else                       rgb <= 24'h000000; // black
end

→ Cela produit des barres de couleur rouge, verte et bleue alignées horizontalement sur l’écran.

Exemple 2 : Affichage de texte

Pour l’affichage de texte, vous préparez une ROM de police et convertissez le motif de points de chaque caractère en pixels.

// Referencing the pattern of 'A' from the font ROM and displaying
if (font_rom[char_code][y][x] == 1'b1)
    rgb <= 24'hFFFFFF;  // white for display
else
    rgb <= 24'h000000;  // black background

→ Cela dessine un caractère particulier (par ex., « A ») à l’écran.

Exemple 3 : Affichage d’image

Pour afficher une image, vous lisez les données bitmap préstockées (ROM ou mémoire externe) et les convertissez en sortie pixel.

rgb <= image_rom[addr];  // Retrieve color data from ROM

Dans les systèmes embarqués utilisant des FPGA, cette méthode vous permet d’afficher des icônes ou logos simples.

Différence par rapport au débogage $display

  • $display est une sortie texte (simulation uniquement)
  • Le contrôle d’affichage est la génération de signal vidéo (implémentable en matériel)

Bien que leurs objectifs diffèrent, les apprenants de Verilog confondent souvent les deux.

  • « Je veux vérifier le comportement pendant la simulation » → Utilisez $display
  • « Je veux sortir vers un écran réel sur FPGA » → Concevez la logique de signal vidéo

Extension des applications

  • Sur les cartes FPGA d’apprentissage, le Verilog est fréquemment utilisé pour l’affichage LED 7 segments ou un petit affichage LCD.
  • En progressant davantage, vous pouvez créer des systèmes supportant la sortie VGA/HDMI pour le développement de jeux ou l’affichage d’interface graphique.
  • En combinant la connaissance de $display avec la logique de contrôle d’affichage, vous pouvez gérer le « display » à la fois en simulation et sur le matériel réel.

7. Utilisation appropriée et conseils selon les scénarios d’application

Lorsque nous parlons de « display » en Verilog, il y a deux aspects : les tâches $display uniquement en simulation, et le contrôle d’affichage implémenté en matériel. Utiliser chacun de manière appropriée conduit à un développement et un débogage efficaces.

Utilisation en simulation

  1. $display comme journal de débogage
    • Affichez les variables ou signaux critiques avec $display pour vérifier si votre conception se comporte comme prévu.
    • Vérifier les « valeurs sous conditions spécifiques » ou le « compteur atteignant des points » via les journaux est efficace.
  2. Éviter une sortie excessive
    • Sortir à chaque cycle d’horloge inonde les journaux et réduit la lisibilité. Restreignez les conditions.
    • Exemple : if (state == ERROR) $display("Error occured at %0t", $time);
  3. Différencier les tâches
    • $monitor → Pour les signaux que vous souhaitez surveiller en continu
    • $strobe → Lorsque vous devez sortir des valeurs stabilisées
    • $write → Pour une sortie horizontale formatée

Utilisation du contrôle d’affichage matériel

  1. Affichage 7 segments pour l’apprentissage
    • Dans les projets FPGA pour débutants, afficher la valeur d’un compteur sur un LED 7 segments est standard.
    • Combinez avec la sortie de simulation $display pour approfondir la compréhension de l’affichage vs la simulation.
  2. Contrôle d’écran LCD ou VGA
    • Utilisez une ROM de police ou une ROM d’image pour afficher du texte ou une image.
    • En utilisant également $display en simulation, vous pouvez doubler la vérification que la génération du signal vidéo est correcte.
  3. Superposition de débogage en matériel
    • Vous pouvez superposer la « valeur du compteur », les « coordonnées », les « messages de débogage » sur la sortie vidéo réelle.
    • Dans le développement FPGA, il est courant de « faire de l’écran un outil de débogage ».

Conseils pratiques

  • Suivre la simulation → flux matériel Utilisez d’abord $display pour vérifier le comportement en simulation, puis passez à la logique de contrôle d’affichage pour l’implémentation matérielle.
  • Utiliser les journaux et les formes d’onde conjointement Les journaux texte de $display indiquent le « moment de l’occurrence d’un événement », tandis que les formes d’onde montrent les « transitions détaillées ». Utiliser les deux augmente la précision du débogage.
  • Unifier le format des messages en développement d’équipe Standardiser le format des messages $display (préfixe, affichage du temps, etc.) facilite l’analyse des journaux lorsque plusieurs personnes travaillent ensemble.

Résumé

  • Les tâches de type $display sont des « outils d’observation » réservés à la simulation.
  • Le contrôle d’affichage correspond à une implémentation matérielle « méthode d’affichage ».
  • En utilisant chaque approche de manière appropriée et en les combinant, vous pouvez favoriser un développement efficace.

8. FAQ (Foire aux questions)

Q1. Quelle est la différence entre $display et $monitor ?

R. $display affiche une fois au moment où il est appelé. En revanche, $monitor affiche automatiquement chaque fois qu’un signal enregistré change.

  • Pour un débogage ponctuel → $display
  • Pour une surveillance continue → $monitor

Q2. Quand devrais-je utiliser $strobe ?

R. $strobe affiche la valeur stabilisée à la fin d’un cycle de simulation. Par exemple, lorsque plusieurs signaux changent simultanément sur un front d’horloge, $display peut montrer des valeurs intermédiaires. Dans ces cas, $strobe est pratique pour afficher les valeurs finales.

Q3. À quoi sert le spécificateur de format %m ?

R. %m affiche le nom de la hiérarchie du module courant. Dans les grands designs, consigner « de quelle hiérarchie provient le message » facilite grandement l’analyse.

$display("Current module: %m");

Example output:

Current module: top.u1.counter

Q4. Mes journaux sont devenus énormes parce que j’ai utilisé de nombreux $display. Que faire ?

R. Les mesures suivantes sont efficaces :

  • Utiliser des instructions if pour filtrer la sortie
  • N’afficher que la détection d’erreurs ou des événements spécifiques
  • Utiliser $monitor pour ne surveiller que les signaux strictement nécessaires
  • Exporter vers un fichier de journal et appliquer des outils de filtrage lors de l’analyse

Q5. $display peut-il être utilisé pour la synthèse (FPGA/ASIC) ?

R. Non. $display est strictement une tâche réservée à la simulation. Les outils de synthèse l’ignorent, il n’apparaît donc pas dans le matériel réel. Si vous souhaitez afficher une sortie sur du matériel réel, vous devez concevoir avec des « LED 7 segments », « LCD », « logique de contrôle VGA », etc., en Verilog.

Q6. Comment afficher du texte ou des images sur du matériel réel ?

R. Pas avec $display, mais en générant des signaux vidéo.

  • Affichage 7 segments → Pour un affichage numérique ou de caractères simple
  • VGA/LCD → Générer les signaux HSYNC, VSYNC, RGB et les contrôler
  • Texte → Utiliser une ROM de polices et sortir les motifs de points
  • Images → Stocker des bitmaps dans une ROM ou une mémoire externe et sortir les pixels en conséquence

9. Conclusion & Prochaines étapes

Résumé de cet article

Dans cet article, nous avons couvert le « display » en Verilog, des fondamentaux aux applications. Les points clés incluaient :

  1. Bases de $display
    • Une tâche de simulation qui affiche des signaux ou des variables, utilisable de façon similaire à printf en C.
  2. Différences avec les tâches connexes
    • $write → Affiche sans saut de ligne
    • $strobe → Affiche les valeurs stabilisées à la fin du cycle de simulation
    • $monitor → Surveille automatiquement les changements de signaux
  3. Utilisation des spécificateurs de format
    • En utilisant %b, %d, %h, %m, %t, vous pouvez produire des journaux plus clairs et plus pratiques.
  4. Exemples pratiques
    • Insérer $display dans les bancs de test pour suivre la progression.
    • Utiliser des messages conditionnels pour permettre un débogage efficace.
  5. Applications dans le contrôle d’affichage
    • $display est uniquement pour la simulation ; l’implémentation matérielle utilise HSYNC, VSYNC, RGB pour afficher du texte/image.
    • Du apprentissage de l’affichage 7 segments au contrôle avancé VGA/HDMI, les extensions sont possibles.

Prochaines étapes

  • Passer à SystemVerilog → Dans le langage successeur SystemVerilog, vous pouvez utiliser des fonctionnalités de débogage plus avancées (assertions, $display amélioré, etc.).
  • Combiner avec un visualiseur d’ondes → En combinant les journaux $display et les données d’onde, vous pouvez analyser à la fois les valeurs numériques et les transitions, améliorant la précision du débogage.
  • Apprendre la sortie d’affichage matériel → Dans un petit projet sur carte FPGA, essayez de sortir sur un affichage 7 segments ou LCD pour ressentir la différence entre « affichage de simulation » et « contrôle d’affichage matériel ».
  • Appliquer en développement d’équipe → En standardisant le format des messages $display, vous améliorez l’efficacité de l’analyse des journaux dans un développement à plusieurs personnes.

En conclusion

$display est plus qu’une simple « sortie texte ». C’est un outil puissant pour le débogage de simulation. Et lorsque vous vous aventurez dans le monde du contrôle d’affichage, vous pouvez ressentir la joie d’afficher des graphiques sur de vrais moniteurs via FPGA.
J’espère que cet article aidera les apprenants Verilog à comprendre clairement à la fois le « débogage de simulation » et la « sortie d’affichage matériel ».