Verilog für Schleife
Ein for
Schleife ist die am weitesten verbreitete Schleife in Software, wird aber hauptsächlich zum Replizieren verwendet Hardwarelogik in Verilog. Die Idee hinter einer for
Schleife besteht darin, eine Reihe von Anweisungen zu wiederholen, die in der Schleife angegeben sind, solange die angegebene Bedingung wahr ist. Dies ist dem while
sehr ähnlich Schleife, wird aber eher in einem Kontext verwendet, in dem ein Iterator verfügbar ist und die Bedingung vom Wert dieses Iterators abhängt.
Syntax
for (<initial_condition>; <condition>; <step_assignment>) begin
// Statements
end
Das Schlüsselwort for
wird verwendet, um diesen Schleifentyp zu spezifizieren und besteht aus drei Teilen:
- Anfangsbedingung zur Angabe von Anfangswerten von Signalen
- Eine Prüfung, um auszuwerten, ob die gegebene Bedingung wahr ist
- Steuervariable für die nächste Iteration aktualisieren
Die Anfangsbedingung und Aktualisierungen der Steuervariablen sind in for
enthalten Schleife und muss im Gegensatz zu while
nicht separat angegeben werden Schleife. Ein while
Schleife ist allgemeiner und wird meistens nur verwendet, wenn die angegebenen Anweisungen so lange wiederholt werden müssen, wie eine bestimmte Bedingung. Allerdings die for
Schleife hat normalerweise einen bestimmten Anfang und ein Ende, das durch die Schrittvariable gesteuert wird.
Hier ist ein einfaches Beispiel, das die Verwendung einer for-Schleife veranschaulicht.
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
Simulationsprotokoll 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.
Designbeispiel
Schauen wir uns an, wie ein 8-Bit-Linksschieberegister in Verilog ohne for
implementiert werden kann Schleife und vergleiche es dann mit dem Code mit einem for
Schleife, nur um die Nützlichkeit eines Schleifenkonstrukts zu schätzen.
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
Das gleiche Verhalten kann mit einem for
implementiert werden Schleife, die den Code reduziert und für verschiedene Registerbreiten skalierbar macht. Wenn die Breite des Registers zu einem Verilog-Parameter gemacht wird, wird das Designmodul skalierbar und derselbe Parameter kann innerhalb von for
verwendet werden Schleife.
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
Testbench
Der Testbench-Code wird unten gezeigt und instanziiert das Design.
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