Fonctions, tâches et portée
Factoriser les calculs et les séquences de test sans cacher les dépendances ni mélanger RTL et temporisation.
Une fonction pour calculer une valeur
Une fonction renvoie une valeur et s'exécute sans consommer de temps de simulation. Elle convient aux calculs combinatoires répétés.
function automatic logic [7:0] saturating_add8(
input logic [7:0] a,
input logic [7:0] b
);
logic [8:0] wide_sum;
wide_sum = {1'b0, a} + {1'b0, b};
if (wide_sum[8])
return 8'hFF;
return wide_sum[7:0];
endfunctionLe mot-clé automatic donne un stockage propre à chaque appel. C'est le comportement le plus sûr pour une fonction réentrante ou appelée en parallèle dans un testbench. Une fonction déclarée dans un module peut être utilisée par ce module. Une fonction placée dans un package peut être partagée.
Dans le RTL, une fonction ne crée pas forcément une ressource partagée. La synthèse peut dupliquer la logique à chaque point d'appel. Le matériel obtenu dépend du contexte et des optimisations.
Une tâche pour une suite d'actions
Une tâche peut avoir plusieurs sorties et, dans un testbench, contenir des contrôles de temps ou d'événements.
task automatic send_word(
input logic [31:0] value
);
i_valid <= 1'b1;
i_data <= value;
do @(posedge i_clk); while (!o_ready);
i_valid <= 1'b0;
endtaskCette tâche appartient au testbench car elle attend des fronts d'horloge. Elle ne doit pas être copiée dans le RTL synthétisable.
Une tâche utilisée en RTL doit rester dans le sous-ensemble accepté par l'outil, sans #delay, @event, wait ni constructions dynamiques. Même dans ce cas, une fonction est souvent plus simple lorsqu'une seule valeur doit être calculée.
Arguments et sens des données
SystemVerilog accepte input, output, inout et ref dans les sous-programmes.
inputcopie une valeur à l'entrée ;outputrenvoie une valeur à la fin ;inoutcopie dans les deux sens ;refdonne un accès direct à la variable d'origine.
ref est utile dans certains utilitaires de test, mais crée une dépendance plus forte. Pour un code facile à relire, préférer des entrées et sorties explicites.
Portée et noms qualifiés
Un nom est recherché dans la portée locale, puis dans les portées englobantes selon les règles du langage. Cette recherche devient délicate lorsque plusieurs packages exportent le même identifiant.
logic [crc_pkg::CRC_WIDTH-1:0] crc;
assign crc = crc_pkg::next_crc(data, previous_crc);Le préfixe du package montre immédiatement d'où viennent la constante et la fonction. Il évite aussi qu'un import ajouté plus tard change la résolution d'un nom.
À retenir
- Une fonction calcule une valeur sans avancer le temps de simulation.
- Une tâche peut renvoyer plusieurs valeurs et attendre des événements dans un testbench.
automaticévite de partager le stockage entre appels.- Un appel de fonction RTL peut être dupliqué en matériel.
- Les noms qualifiés rendent les dépendances plus faciles à suivre.
📝 Tester mes connaissances - Quiz du chapitre