1. Qu’est‑ce qu’une fonction Verilog ? (Concept de base et rôle)
Verilog HDL (Hardware Description Language) est un langage de description matériel utilisé pour concevoir et simuler des circuits numériques. Parmi ses fonctionnalités, la fonction est un mécanisme qui vous permet de modulariser des opérations spécifiques et de les rendre réutilisables.
Comprendre les fonctions Ver non seulement la lisibilité et la maintenabilité du code, mais conduit également à une conception de circuits plus efficace. Dans cet article, nous expliquons le concept de base des fonctions Verilog et leur utilisation dans la conception réelle.Qu’est‑ce qu’une fonction ?
Une fonction Verilog est un bloc qui effectue un calcul ou une opération spécifique et renvoie une seule valeur. En utilisant des fonctions, vous pouvez réduire le code redondant et simplifier la description de votre circuit.Caractéristiques principales des fonctions
- Un ou plusieurs entrées peuvent être spécifiées (seul
input est autorisé) - Une seule sortie (la valeur de retour de la fonction)
- Les délais temporels (ex.
#10) ne sont pas autorisés - Les fonctions doivent toujours décrire une logique combinatoire
- Les fonctions sont définies en dehors des blocs always et sont évaluées immédiatement (contrairement aux tasks)
Quand utiliser les fonctions Verilog
Les fonctions Verilog sont principalement utilisées dans les scénarios suivants :1. Décrire une logique combinatoiretant donné que les fonctions renvoient les résultats immédiatement en fonction des entrées, elles sont souvent utilisées dans la logique combinatoire.
Exemples : addition, soustraction, encodeurs, décodeurs et autres opérations arithmétiques.2. Améliorer la réutilisabilité du code
Vous pouvez éliminer le code redondant en résumant la logique fréquemment utilisée dans des fonctions.
Exemple : transformer une expression conditionnelle complexe en fonction pour améliorer la lisibilité au sein d’un module.3. Réduire les erreurs de conception
En centralisant les calculs ou les opérations logiques dans une fonction unique, vous pouvez réduire les erreurs lors de la modification du code.
Exemples : calculs CRC (Cyclic Redundancy Check) ou vérifications de parité.Différence entre fonctions et tâches
En Verilog, il existe un autre construit appelé task. Bien que fonctions et tâches soient similaires, elles diffèrent de manière importante :| Item | Fonction | Tâche |
|---|
| Sortie | Un seul | Autoriser plusieurs |
| Veuillez fournir le fragment HTML à traduire en français. | Oui | Oui |
| Local Variables | Autorisé | Autorisé |
Délai (#10) | Non autorisé | Autorisé |
Utilisation à l’intérieur de always | Autorisé | Non autorisé |
| Invocation | function_name(arguments) | task_name(arguments); |
Quand utiliser une fonction
- Lorsque vous avez besoin d’un résultat de calcul immédiat
- Pour une logique qui n’inclut pas de délais
- Lorsque une seule valeur de retour suffit
Quand utiliser une tâche
- Lorsque le processus inclut des délais (ex.
#10) - Lorsque plusieurs sorties sont requ
- À des fins de simulation/débogage (ex. sortie de journal)
Résumé
- Une fonction Verilog est une fonction qui prend des entrées et renvoie une seule valeur.
- Elle est idéale pour décrire une logique combinatoire et ne peut pas inclure de délais.
- Utile pour réduire le code redondant et améliorer la lisibilité.
- Les fonctions et les tâches diffèrent ; choisir la bonne dépend de votre cas d’utilisation.
2. Comment écrire une fonction Verilog [Beginner-Friendly Example]
Dans la section précédente, nous avons couvert le concept de base des fonctions Verilog. Ici, nous allons plonger dans la syntaxe réelle et comment écrire des fonctions Verilog en pratique.Syntaxe de base d’une fonction
Une fonction Verilog s’écrit en utilisant la syntaxe générale suivante :function [output_bit_width] function_name;
input [input_bit_width] input1, input2, ...;
begin
function_name = expression;
end
endfunction
Points clés
- Déclarer avec le mot‑clé
function - La valeur de retour est assignée à une variable portant le même nom que la fonction
- Déclarer les entrées avec
input (vous ne pouvez pas utiliser output ou inout ) - Effectuer les calculs à l’intérieur de
begin ... end - Définir la fonction en dehors d’un bloc
always
Exemple simple d’une fonction Verilog
L’exemple suivant montre une fonction qui effectue une addition sur 8 bits :module example;
function [7:0] add_function;
input [7:0] a, b;
begin
add_function = a + b;
end
endfunction
reg [7:0] x, y, sum;
initial begin
x = 8'b00001100; // 12
y = 8'b00000101; // 5
sum = add_function(x, y);
$display("Sum: %d", sum); // Sum: 17
end
endmodule
Explication
add_function prend deux entrées de 8 bits (a et b) et renvoie leur somme- La fonction est appelée avec
sum = add_function(x, y); et assigne le résultat à sum - Le bloc
initial utilise $display pour afficher le résultat
Déclaration des entrées et sorties dans une fonction
Déclaration des entrées
Une fonction Verilog ne peut prendre que des arguments input.function [7:0] my_function;
input [7:0] in1, in2;
begin
my_function = in1 & in2; // AND operation
end
endfunction
Remarque : Vous ne pouvez pas déclarer output dans une fonction. La valeur de retour est toujours la variable portant le même nom que la fonction.Fonction avec instructions conditionnelles
Vous pouvez également utiliser des instructions if ou case à l’intérieur d’une fonction.function [3:0] max_function;
input [3:0] a, b;
begin
if (a > b)
max_function = a;
else
max_function = b;
end
endfunction
Cette fonction renvoie la plus grande valeur entre a et b.Résumé
- Une fonction Verilog est définie avec le mot‑clé
function et renvoie une seule valeur - Seuls les arguments
input sont autorisés (pas de output) - La valeur de retour est assignée à la variable portant le même nom que la fonction
- Les instructions
if et case peuvent être utilisées pour la logique conditionnelle

3. Comment utiliser les fonctions Verilog [With Practical Code Examples]
Dans la section précédente, nous avons appris la syntaxe de base et comment écrire des fonctions Verilog.
Ici, nous expliquerons comment appliquer les fonctions dans une conception réelle avec des exemples pratiques.Comment appeler une fonction
Une fonction Verilog est appelée comme une affectation de variable ordinaire, en utilisant le format function_name(arg1, arg2, ...).
L’exemple suivant définit une fonction XOR de 8 bits et l’utilise à l’intérieur d’un module :module function_example;
function [7:0] xor_function;
input [7:0] a, b;
begin
xor_function = a ^ b;
end
endfunction
reg [7:0] x, y, result;
initial begin
x = 8'b11001100;
y = 8'b10101010;
result = xor_function(x, y); // calling the function
$display("XOR Result: %b", result); // XOR Result: 01100110
end
endmodule
Points clés
- Une fonction est appelée sous la forme
variable = function(arguments); - Elle peut être utilisée à l’intérieur de blocs
always ou initial - Les fonctions fonctionnent comme de la logique combinatoire
Utilisation des fonctions dans la logique combinatoire
Comme les fonctions Verilog sont toujours évaluées immédiatement, elles sont utiles pour construire de la logique combinatoire.
L’exemple suivant montre un décodeur 2‑to‑4 implémenté avec une fonction :module decoder_example;
function [3:0] decoder;
input [1:0] sel;
begin
case (sel)
2'b00: decoder = 4'b0001;
2'b01: decoder = 4'b0010;
2'b10: decoder = 4'b0100;
2'b11: decoder = 4'b1000;
default: decoder = 4'b0000;
endcase
end
endfunction
reg [1:0] select;
wire [3:0] decoded_output;
assign decoded_output = decoder(select); // using the function
initial begin
select = 2'b01;
#10; // add delay to observe simulation changes
$display("Decoded Output: %b", decoded_output); // Decoded Output: 0010
end
endmodule
Explication
- La fonction
decoder convertit une entrée de 2 bits en une sortie de décodeur de 4 bits - Utilise une instruction
case pour déterminer la sortie en fonction de l’entrée assign est utilisé pour mapper la sortie de la fonction à decoded_output → La fonction fonctionne comme une partie de la logique combinatoire
Fonctions vs. Blocs always [Comparison Table]
Les fonctions Verilog et les blocs always sont tous deux utilisés pour décrire la logique, mais leur but et leurs restrictions diffèrent.| Item | Fonction | Toujours bloquer |
|---|
| Emplacement de la définition | En dehors des blocs always | Dans les blocs always |
| Entrées | input | regwire |
| Sorties | Une seule valeur | Peut mettre à jour plusieurs valeurs |
Délai (#10) | Non autorisé | Autorisé |
| Rétention d’état | Non autorisé | Autorisé |
| Main Usage | Logique combinatoire | Logique séquentielle ou traitement basé sur les événements |
Directives clés
- Utilisez les fonctions pour simplifier les opérations logiques simples (logique combinatoire)
- Utilisez les blocs always pour les circuits qui conservent un état (par ex., bascules)
- Si vous avez besoin de délais (comme
#10), utilisez des blocs always plutôt que des fonctions
Résumé : Comment utiliser les fonctions Verilog
✅ Appelez une fonction avec function_name(arguments) ✅ Les fonctions sont idéales pour la logique combinatoire et diffèrent des blocs always ✅ Utilisez les instructions case ou if pour décrire une logique flexible
✅ Utile pour les décodeurs, les opérations arithmétiques, et plus
4. Applications pratiques des fonctions Verilog (Conception de décodeur et d’ALU)
Jusqu’à présent, nous avons appris la syntaxe de base et l’utilisation des fonctions Verilog.
Dans cette section, nous examinerons comment appliquer les fonctions dans la conception de circuits numériques réels, en utilisant des décodeurs et des ALU (Unités Arithmétiques et Logiques) comme exemples.Implémentation fonctionnelle d’un décodeur (décodeur 2‑à‑4)
Un décodeur est un circuit qui convertit un petit nombre de bits d’entrée en un plus grand nombre de bits de sortie.
Par exemple, un décodeur 2‑à‑4 convertit une entrée de 2 bits en une sortie de 4 bits. Implémentons cela à l’aide d’une fonction :module decoder_example;
function [3:0] decoder;
input [1:0] sel;
begin
case (sel)
2'b00: decoder = 4'b0001;
2'b01: decoder = 4'b0010;
2'b10: decoder = 4'b0100;
2'b11: decoder = 4'b1000;
default: decoder = 4'b0000;
endcase
end
endfunction
reg [1:0] select;
wire [3:0] decoded_output;
assign decoded_output = decoder(select); // using the function
initial begin
select = 2'b00; #10;
$display("Decoded Output: %b", decoded_output);
select = 2'b01; #10;
$display("Decoded Output: %b", decoded_output);
select = 2'b10; #10;
$display("Decoded Output: %b", decoded_output);
select = 2'b11; #10;
$display("Decoded Output: %b", decoded_output);
end
endmodule
Implémentation fonctionnelle d’une ALU (Addition, Soustraction, AND, OR)
Une ALU (Unité Arithmétique et Logique) est le circuit central d’un CPU, responsable d’exécuter des opérations arithmétiques et logiques telles que l’addition, la soustraction, AND et OR.
Ici, nous concevons une simple ALU 8 bits en utilisant une fonction Verilog :module alu_example;
function [7:0] alu;
input [7:0] a, b;
input [1:0] op; // 2-bit control signal
begin
case (op)
2'b00: alu = a + b; // Addition
2'b01: alu = a - b; // Subtraction
2'b10: alu = a & b; // AND
2'b11: alu = a | b; // OR
default: alu = 8'b00000000;
endcase
end
endfunction
reg [7:0] x, y;
reg [1:0] opcode;
wire [7:0] result;
assign result = alu(x, y, opcode); // using the function
initial begin
x = 8'b00001100; // 12
y = 8'b00000101; // 5
opcode = 2'b00; #10;
$display("Addition Result: %d", result); // 12 + 5 = 17
opcode = 2'b01; #10;
$display("Subtraction Result: %d", result); // 12 - 5 = 7
opcode = 2'b10; #10;
$display("AND Result: %b", result); // AND operation
opcode = 2'b11; #10;
$display("OR Result: %b", result); // OR operation
end
endmodule
Résumé
✅ Les fonctions peuvent être utilisées efficacement dans les circuits combinatoires tels que les décodeurs et les ALU ✅ L’utilisation d’instructions case permet des descriptions d’opérations flexibles ✅ Les fonctions améliorent la lisibilité et rendent la conception plus réutilisable ✅ Les fonctions conviennent le mieux à la logique combinatoire, mais pas aux circuits séquentiels (car elles ne peuvent pas inclure de délais)
5. Considérations importantes lors de l’utilisation des fonctions Verilog
Les fonctions Verilog sont des outils puissants qui améliorent la lisibilité et la réutilisabilité du code, mais elles comportent également certaines restrictions. Dans cette section, nous expliquerons les points clés dont vous devez être conscient lors de l’utilisation des fonctions.Les appels récursifs ne sont pas autorisés
Dans les fonctions Verilog, les appels récursifs sont interdits.
Cela signifie qu’une fonction ne peut pas s’appeler elle‑même à l’intérieur de son propre corps.❌ Exemple NG : Fonction récursive
function [3:0] factorial;
input [3:0] n;
begin
if (n == 0)
factorial = 1;
else
factorial = n * factorial(n - 1); // ❌ Recursive call not allowed
end
endfunction
Ce code entraînera une erreur de simulation.✅ Solution : Utiliser des boucles à la place
Si la récursion est nécessaire, utilisez une boucle à l’intérieur d’un bloc always ou d’une tâche à la place.task factorial_task;
input [3:0] n;
output [15:0] result;
integer i;
begin
result = 1;
for (i = 1; i <= n; i = i + 1)
result = result * i;
end
endtask
En utilisant des boucles, la récursion peut être évitée.Les délais temporels (#10) ne peuvent pas être utilisés dans les fonctions
Puisque les fonctions Verilog sont évaluées immédiatement (fonctionnent comme une logique combinatoire), elles ne peuvent pas inclure de délais temporels comme #10.❌ Exemple NG : Délai à l’intérieur d’une fonction
function [7:0] delay_function;
input [7:0] in;
begin
#10; // ❌ Delay not allowed inside functions
delay_function = in + 1;
end
endfunction
Ce code provoquera une erreur de compilation.✅ Solution : Utiliser des blocs always à la place
Si des délais sont requis, utilisez un bloc always ou une tâche à la place d’une fonction.task delay_task;
input [7:0] in;
output [7:0] out;
begin
#10;
out = in + 1;
end
endtask
En bref, utilisez des tâches les opérations qui impliquent des délais.Choisir entre fonctions et tâches
En Verilog, il existe à la fois des fonctions et des tâches. Bien qu’elles se ressemblent, elles ont des cas d’utilisation différents et doivent être choisies de manière appropriée.| Item | Fonction | Tâche |
|---|
| Sortie | Un seul | Multiple autorisé |
| Entrée | input | inputoutput |
| Local Variables | Autorisé | Autorisé |
Délai (#10) | Non autorisé | Autorisé |
Utilisation à l’intérieur de always | Autorisé | Non autorisé |
| Invocation | function_name(arguments) | task_name(arguments); |
Quand utiliser une fonction
✅ Lorsque vous avez besoin d’un résultat de calcul immédiat (par ex., addition, soustraction, opérations logiques)
✅ Pour décrire une logique combinatoire sans délais ✅ Lorsque qu’une seule valeur de retour est requiseQuand utiliser une tâche
✅ Lorsque des délais (#10, etc.) sont requis
✅ Lorsque plusieurs sorties sont nécessaires
✅ Pour les opérations de simulation/débogage (surveillance, affichage, etc.)Les fonctions ne peuvent pas être définies à l’intérieur de blocs always
Les fonctions Verilog ne peuvent pas être définies à l’intérieur d’un bloc always.
Les fonctions doivent être définies à l’extérieur puis appelées à l’intérieur d’un always.❌ Exemple NG : Définir une fonction à l’intérieur d’un always
always @(a or b) begin
function [7:0] my_function; // ❌ Not allowed inside always
input [7:0] x, y;
begin
my_function = x + y;
end
endfunction
end
Ce code entraînera une erreur de compilation.✅ Exemple correct
Définissez la fonction en dehors du always et appelez‑la à l’intérieur :function [7:0] add_function;
input [7:0] x, y;
begin
add_function = x + y;
end
endfunction
always @(a or b) begin
result = add_function(a, b); // ✅ call the function
end
Résumé
✅ Les fonctions Verilog ont plusieurs restrictions ✅ Pas d’appels récursifs (utilisez des boucles ou des tâches à la place)
✅ Pas de délais (#10) (utilisez always ou des tâches à la place)
✅ Ne peuvent pas être définies à l’intérieur de blocs always (doivent être définies à l’extérieur)
✅ Une seule valeur de retour (utilisez des tâches si plusieurs sorties sont nécessaires)
✅ Utilisez les fonctions et les tâches de manière appropriée selon la situation
6. [FAQ] Questions fréquemment posées sur les fonctions Verilog
Jusqu’à présent, nous avons couvert les bases, l’utilisation avancée et les considérations importantes des fonctions Verilog.
Dans cette section, nous résumons les questions fréquemment posées et leurs réponses sur les fonctions Verilog.Quelle est la différence entre une fonction et une tâche ?
Q. Quelle est la différence entre une fonction Verilog et une tâche ? Laquelle devrais-je utiliser ?
A. Une fonction est utilisée lorsque vous avez besoin de « renvoyer une seule valeur immédiatement », tandis qu’une tâche est utilisée lorsque vous avez besoin de « plusieurs sorties ou d’opérations impliquant des délais ».
| Item | Fonction | Tâ |
|---|
| Could you please provide the HTML snippet you’d like translated? | Un seul | Autoriser plusieurs |
| Could you please provide the HTML snippet you’d like translated into French? | input | inputoutput |
| Local Variables | Autorisé | Autorisé |
Délai (#10) | Non autorisé | Autorisé |
Utilisation à l’intérieur always | Autorisé | Non autorisé |
| Invocation | function_name(arguments) | task_name(arguments); |
Quand utiliser une fonction
✅ Lorsque vous avez besoin d’un résultat de calcul immédiat (par ex., addition, soustraction, opérations logiques)
✅ Pour décrire une logique combinatoire sans délais ✅ Lorsqu’une seule valeur de retour est nécessaireQuand utiliser une tâche
✅ Lorsque vous avez besoin de délais (par ex., #10)
✅ Lorsque plusieurs sorties sont requises
✅ Lors de l’écriture de code de débogage/surveillance pour la simulationQ. Puis-je utiliser reg à l’intérieur d’une fonction ?
A. Non, vous ne pouvez pas utiliser reg à l’une fonction, mais vous pouvez utiliser integer à la place.
Dans les fonctions Verilog, vous ne pouvez pas déclarer de variables de type reg, mais vous pouvez utiliser integer pour les calculs.✅ Exemple correct (utilisant integer)
function [7:0] multiply;
input [3:0] a, b;
integer temp;
begin
temp = a * b;
multiply = temp;
end
endfunction
Quand devrais-je utiliser des fonctions ?
Q. Dans quelles situations-il approprié d’utiliser des fonctions ?
A. Les fonctions conviennent le mieux aux « opérations arithmétiques simples » et à la « logique combinatoire ».
Exemples où les fonctions sont utiles incluent :- Opérations arithmétiques (addition, soustraction, logique)
- Décodeurs et encodeurs
- Comparaisons (trouver les valeurs maximale/minimale)
- Vérification d’erreurs (par ex., contrôle de parité)
Cependant, les fonctions ne conviennent pas aux circuits séquentiels qui incluent des bascules.Q. Une fonction Verilog peut-elle appeler une autre fonction à l’intérieur ?
A. Oui, une fonction peut appeler une autre fonction, mais soyez prudent avec les dépendances.
function [7:0] add;
input [7:0] a, b;
begin
add = a + b;
end
endfunction
function [7:0] double_add;
input [7:0] x, y;
begin
double_add = add(x, y) * 2; // calling another function
end
endfunction
Q. Comment devrais-je décider d’utiliser une fonction ou un bloc always ?
A. Les fonctions sont utilisées pour la « logique combinatoire », tandis que les blocs always sont utilisés pour la « logique séquentielle ».
| Item | Fonction | Toujours bloquer |
|---|
Délai (#10) | Non autorisé | Autorisé |
| Conservation d’état | Non autorisé | Autorisé |
| Utilisation principale | Logique combinatoire (calculs instantanés) | Logique séquentielle (bascule, compteurs) |
Par exemple, lors d’une addition :✅ Fonction (Logique combinatoire)
function [7:0] add;
input [7:0] a, b;
begin
add = a + b;
end
endfunction
✅ Bloc always (Logique séquentielle)
always @(posedge clk) begin
sum <= a + b; // works as a flip-flop
end
Résumé
✅ Les fonctions sont idéales pour les opérations simples et la logique combinatoire ✅ Comprenez les différences entre fonctions et tâches et utilisez-les de manière appropriée ✅ Les blocs always sont pour la logique séquentielle, les fonctions sont pour la logique combinatoire ✅ Les fonctions ne peuvent pas inclure de délais (#10) ou de tableaux — utilisez des tâches ou des modules à la place