Verilog pour la boucle
Un for
loop est la boucle la plus largement utilisée dans les logiciels, mais elle est principalement utilisée pour répliquer logique matérielle dans Verilog. L'idée derrière un for
boucle consiste à itérer un ensemble d'instructions données dans la boucle tant que la condition donnée est vraie. Ceci est très similaire au while
boucle, mais est plus utilisé dans un contexte où un itérateur est disponible et la condition dépend de la valeur de cet itérateur.
Syntaxe
for (<initial_condition>; <condition>; <step_assignment>) begin
// Statements
end
Le mot clé for
est utilisé pour spécifier ce type de boucle et comporte trois parties :
- Condition initiale pour spécifier les valeurs initiales des signaux
- Une vérification pour évaluer si la condition donnée est vraie
- Mettre à jour la variable de contrôle pour la prochaine itération
La condition initiale et les mises à jour de la variable de contrôle sont incluses dans le for
boucle et n'a pas besoin d'être spécifié séparément contrairement à un while
boucle. Un while
La boucle est plus générale et n'est principalement utilisée que lorsque les instructions données doivent être répétées aussi longtemps qu'une condition donnée. Cependant le for
boucle a généralement un début et une fin définis contrôlés par la variable step.
Voici un exemple simple qui illustre l'utilisation d'une boucle for.
module my_design;
integer i;
initial begin
// Note that ++ operator does not exist in Verilog !
for (i = 0; i < 10; i = i + 1) begin
$display ("Current loop#%0d ", i);
end
end
endmodule
Journal de simulation ncsim> run Current loop#0 Current loop#1 Current loop#2 Current loop#3 Current loop#4 Current loop#5 Current loop#6 Current loop#7 Current loop#8 Current loop#9 ncsim: *W,RNQUIE: Simulation is complete.
Exemple de conception
Voyons comment un registre à décalage gauche 8 bits peut être implémenté dans Verilog sans for
boucle puis comparez-la avec le code en utilisant un for
boucle juste pour apprécier l'utilité d'une construction en boucle.
module lshift_reg (input clk, // Clock input
input rstn, // Active low reset input
input [7:0] load_val, // Load value
input load_en, // Load enable
output reg [7:0] op); // Output register value
// At posedge of clock, if reset is low set output to 0
// If reset is high, load new value to op if load_en=1
// If reset is high, and load_en=0 shift register to left
always @ (posedge clk) begin
if (!rstn) begin
op <= 0;
end else begin
if (load_en) begin
op <= load_val;
end else begin
op[0] <= op[7];
op[1] <= op[0];
op[2] <= op[1];
op[3] <= op[2];
op[4] <= op[3];
op[5] <= op[4];
op[6] <= op[5];
op[7] <= op[6];
end
end
end
endmodule
Le même comportement peut être implémenté en utilisant un for
boucle qui réduira le code et le rendra évolutif pour différentes largeurs de registre. Si la largeur du registre devient un paramètre Verilog, le module de conception deviendra évolutif et le même paramètre pourra être utilisé à l'intérieur du for
boucle.
module lshift_reg (input clk, // Clock input
input rstn, // Active low reset input
input [7:0] load_val, // Load value
input load_en, // Load enable
output reg [7:0] op); // Output register value
integer i;
// At posedge of clock, if reset is low set output to 0
// If reset is high, load new value to op if load_en=1
// If reset is high, and load_en=0 shift register to left
always @ (posedge clk) begin
if (!rstn) begin
op <= 0;
end else begin
// If load_en is 1, load the value to op
// else keep shifting for every clock
if (load_en) begin
op <= load_val;
end else begin
for (i = 0; i < 8; i = i + 1) begin
op[i+1] <= op[i];
end
op[0] <= op[7];
end
end
end
endmodule
Banc de test
Le code de testbench est illustré ci-dessous et instancie la conception.
module tb;
reg clk;
reg rstn;
reg [7:0] load_val;
reg load_en;
wire [7:0] op;
// Setup DUT clock
always #10 clk = ~clk;
// Instantiate the design
lshift_reg u0 ( .clk(clk),
.rstn (rstn),
.load_val (load_val),
.load_en (load_en),
.op (op));
initial begin
// 1. Initialize testbench variables
clk <= 0;
rstn <= 0;
load_val <= 8'h01;
load_en <= 0;
// 2. Apply reset to the design
repeat (2) @ (posedge clk);
rstn <= 1;
repeat (5) @ (posedge clk);
// 3. Set load_en for 1 clk so that load_val is loaded
load_en <= 1;
repeat(1) @ (posedge clk);
load_en <= 0;
// 4. Let design run for 20 clocks and then finish
repeat (20) @ (posedge clk);
$finish;
end
endmodule
Verilog