Mots-clés : while, for, repeat, forever

Les instructions de boucle Verilog ont 4 types : les boucles while, for, repeat et forever. Les instructions de boucle ne peuvent être utilisées que dans les blocs always ou initial, mais peuvent contenir des expressions de délai.

Boucle while

Le format syntaxique de la boucle while est le suivant :

while (condition) begin
    …
end

La boucle while se termine lorsque la condition est fausse.

Si la condition est déjà fausse lors de l'entrée dans la boucle while, l'instruction de boucle ne s'exécutera pas même une seule fois.

Bien sûr, lorsqu'il n'y a qu'une seule instruction d'exécution, les mots-clés begin et end peuvent être omis.

Lorsque le code ci-dessous s'exécute, counter s'exécute 11 fois.

Exemple

`timescale 1ns/1ns
 
module test ;
 
    reg [3:0]    counter ;
    initial begin
        counter = 'b0 ;
        while (counter<=10) begin
            #10 ;
            counter = counter + 1'b1 ;
        end
    end
 
   //arrêter la simulation
    always begin
        #10 ;  if ($time >= 1000) $finish ;
    end
 
endmodule

Le résultat de la simulation est le suivant :

Boucle for

Le format de syntaxe de la boucle for est le suivant :

for(initial_assignment; condition ; step_assignment)  begin
    …
end

initial_assignment est la condition initiale.

condition est la condition de terminaison ; lorsque condition est false, la boucle s'arrête immédiatement.

step_assignment est une instruction d'affectation procédurale qui modifie la variable de contrôle, en incrémentant ou décrémentant généralement le compteur de la variable de boucle.

De manière générale, étant donné que des processus tels que la condition initiale et l'opération d'incrémentation sont déjà inclus dans la boucle for, la syntaxe de la boucle for est plus compacte que celle de while, mais il n'est pas toujours possible d'utiliser une boucle for à la place d'une boucle while.

L'exemple de boucle for suivant produit le même effet que l'exemple de boucle while. Notez que i = i + 1 ne peut pas s'écrire i++ comme en langage C, et i = i -1 ne peut pas non plus s'écrire i --.

Exemple

// instruction de boucle for
entier      i ;
reg [3:0]    counter2 ;
initial begin
    counter2 = 'b0 ;
    for (i=0; i<=10; i=i+1) begin
        #10 ;
        counter2 = counter2 + 1'b1 ;
    end
end

Boucle repeat

Le format de syntaxe de la boucle repeat est le suivant:

repeat (loop_times) begin
    …
end

La fonction de repeat est d'exécuter une boucle un nombre fixe de fois. Elle ne peut pas utiliser une expression logique pour déterminer si la boucle doit continuer, comme le fait une boucle while. Le nombre de répétitions de repeat doit être une constante, une variable ou un signal. Si le nombre de répétitions est un signal variable, le nombre de répétitions est la valeur du signal variable lorsque la boucle repeat commence à s'exécuter. Même si la valeur du signal variable représenté par le nombre de répétitions change pendant l'exécution, le nombre de fois que repeat s'exécute ne changera pas.

L'exemple de boucle repeat suivant produit le même effet que l'exemple de boucle while.

Exemple

// instruction de boucle repeat
reg [3:0]    counter3 ;
initial begin
    counter3 = 'b0 ;
    repeat (11) begin  // répéter 11 fois
        #10 ;
        counter3 = counter3 + 1'b1 ;
    end
end

L'exemple de boucle repeat suivant met en œuvre la fonction de stockage continu de 8 éléments de données :

Exemple

always @(posedge clk or negedge rstn) begin
    j = 0  ;
    if (!rstn) begin
        repeat (8) begin
            buffer[j]   <= 'b0 ;      // affectation sans délai, c.-à-d. affecter tous à 0 en même temps
            j = j + 1 ;
        end
    end
    else if (enable) begin
        repeat (8) begin
            @(posedge clk) buffer[j]    <= counter3 ;       // affectation au prochain front montant de clk
            j = j + 1 ;
        end
     end
end

Le résultat de la simulation est présenté dans la figure ci-dessous.

On peut voir sur la figure que lorsque rstn est mis à l'état haut, les 8 vecteurs de buffer sont affectés à 0 en même temps.

Après le deuxième cycle d'horloge, buffer est affecté séquentiellement par counter3, ce qui réalise la fonction de stockage continu de 8 éléments de données.

Boucle forever

Le format syntaxique de la boucle forever est le suivant :

forever begin
    …
end

L'instruction forever représente une boucle permanente. Elle ne contient aucune expression conditionnelle. Une fois exécutée, elle continue indéfiniment. La fonction système $finish peut sortir de la boucle forever.

forever est équivalent à while(1).

Habituellement, la boucle forever est utilisée conjointement avec des structures de contrôle temporel.

Par exemple, utilisez l'instruction forever pour générer une horloge :

Exemple

reg          clk ;
initial begin
    clk       = 0 ;
    forever begin
        clk = ~clk ;
        #5 ;
    end
end

Par exemple, utilisez l'instruction forever pour implémenter une fonction de transfert de données de registre à registre contrôlée par front d'horloge :

Exemple

reg    clk ;
reg    data_in, data_temp ;
initial begin
    forever @(posedge clk)      data_temp = data_in ;
end

Téléchargement du code source

Téléchargement