For-lussen in Verilog beheersen: herbruikbare hardwarelogica bouwen
Een for-lus is de meest gebruikte lus in software, maar wordt in Verilog primair gebruikt om hardwarelogica te repliceren. Het idee achter een for-lus is om een set statements binnen de lus te herhalen zolang de gegeven conditie true is. Dit lijkt veel op de while-lus, maar wordt vaker gebruikt in een context waar een iterator beschikbaar is en de conditie afhangt van de waarde van deze iterator.
Syntax
for (<initiele_conditie>; <conditie>; <stap_toewijzing>) begin
// Statements
end
Het trefwoord for specificeert dit type lus en heeft drie delen:
- Initiële conditie om beginwaarden van signalen op te geven
- Een controle om te evalueren of de gegeven conditie true is
- Update van de controle-variabele voor de volgende iteratie
De initiële conditie en updates van de controle-variabele zijn inbegrepen in de for-lus en hoeven niet apart gespecificeerd te worden zoals bij een while-lus. Een while-lus is meer algemeen en wordt meestal alleen gebruikt wanneer de gegeven statements herhaald moeten worden zolang een gegeven conditie geldt. De for-lus heeft typisch een definitieve begin en eind die gecontroleerd wordt door de stapvariabele.
Hier is een simpel voorbeeld dat het gebruik van een for-lus illustreert.
module my_design;
integer i;
initial begin
// Let op: ++ operator bestaat niet in Verilog!
for (i = 0; i < 10; i = i + 1) begin
$display ("Huidige lus#%0d ", i);
end
end
endmodule
Simulatie-log
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.
Ontwerpvoorbeeld
Laten we kijken hoe een 8-bit linksshiftregister geïmplementeerd kan worden in Verilog zonder een for-lus en vergelijken met de code met een for-lus om de nut van een lusconstructie te waarderen.
module lshift_reg (
input clk,
input rstn,
input [7:0] load_val,
input load_en,
output reg [7:0] op
);
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
for-lus wat de code verkleint en schaalbaar maakt voor verschillende registerbreedtes. Als de breedte van de register een Verilog-parameter wordt, wordt het ontwerp schaalbaar en kan dezelfde parameter binnen de for-lus gebruikt worden.}
module lshift_reg (
input clk,
input rstn,
input [7:0] load_val,
input load_en,
output reg [7:0] op
);
integer i;
always @ (posedge clk) begin
if (!rstn) begin
op <= 0;
end else begin
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
Testbench
De testbench-code instantiateert het ontwerp.
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;
// Instantiateer het ontwerp
lshift_reg u0 (
.clk(clk),
.rstn(rstn),
.load_val(load_val),
.load_en(load_en),
.op(op)
);
initial begin
// 1. Initialiseer testbench-variabelen
clk <= 0;
rstn <= 0;
load_val <= 8'h01;
load_en <= 0;
// 2. Pas reset toe op het ontwerp
repeat (2) @ (posedge clk);
rstn <= 1;
repeat (5) @ (posedge clk);
// 3. Zet load_en voor 1 clk zodat load_val geladen wordt
load_en <= 1;
repeat(1) @ (posedge clk);
load_en <= 0;
// 4. Laat ontwerp 20 klokken lopen en stop dan
repeat (20) @ (posedge clk);
$finish;
end
endmodule
Verilog
- C# For Loops: Syntaxis, Stroom en Praktische Voorbeelden
- C# foreach Loops: Arrays en Collecties Eenvoudig Itereren
- C++ for loops: stap-voor-stap gids
- Verilog Basics: Uw Eerste AND-poort Ontwerpen
- Verilog beheersen: Complete tutorial voor digitale schakelingontwerp
- Verilog concatenatie beheersen: Een praktische gids
- Verilog-toewijzingen begrijpen: types, syntax en best practices
- Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd
- Verilog-functies beheersen voor efficiënt RTL-ontwerp
- Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
- Java-programma om Armstrong-getallen te identificeren met for-lus