ループ用 Verilog
for
ループはソフトウェアで最も広く使用されているループですが、主に複製に使用されます Verilog のハードウェア ロジック。 for
の背後にある考え方 ループは、指定された条件が真である限り、ループ内で指定されたステートメントのセットを繰り返します。これは while
に非常に似ています ループしますが、反復子が使用可能で、条件がこの反復子の値に依存するコンテキストでより多く使用されます。
構文
for (<initial_condition>; <condition>; <step_assignment>) begin
// Statements
end
キーワード for
このタイプのループを指定するために使用され、次の 3 つの部分があります。 <オール>
for
には、初期状態と制御変数の更新が含まれています。 while
とは異なり、個別に指定する必要はありません。 ループ。 while
loop はより汎用的な目的であり、ほとんどの場合、指定された条件が続く限り、指定されたステートメントを繰り返す必要がある場合にのみ使用されます。ただし、for
通常、ループにはステップ変数によって制御される明確な開始と終了があります。
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
シミュレーションログ 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.
設計例
Verilog で for
なしで 8 ビットの左シフト レジスタを実装する方法を見てみましょう。 ループしてから for
を使用してコードと比較します ループ構成の有用性を理解するためだけにループします。
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
for
を使用して同じ動作を実装できます これにより、コードが削減され、さまざまなレジスタ幅に対してスケーラブルになります。レジスタの幅を Verilog パラメータにすると、設計モジュールがスケーラブルになり、for
内で同じパラメータを使用できるようになります。 ループ。
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
テストベンチ
以下に示すテストベンチ コードは、デザインをインスタンス化します。
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