文章目录
语法
for(<initial_condition>;<condition>;<step_assignment>)
begin
//statements
end
执行过程如下:
- 指定初始循环变量值
- 条件是否为真,条件为假则跳出循环
- 若条件为真则执行控制语句
- 循环变量迭代更新
示例#1:基本循环控制
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.
示例#2: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循环实现:
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
可以看出使用for循环可以大大减少代码量,而且可以方便的扩展到不同位宽的数据,如果把位宽改成parameter类型则更加方便,只需要在使用时指定其宽度即可。
测试代码:
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
仿真结果:
RTL电路: