Verilog for 循环语句
在Verilog 语法中,定义了多种循环语句,其中for是应用最广泛的一种语句,不仅可以在顺序语句中使用,在并发语句中也有相应的模型。for 循环语句可以用在实体模块中,也可以用在仿真模块中。在实体模块中for循环语句是可综合的。
顺序语句中使用for 循环
for循环语句的格式
for(表达式1; 表达式2; 表达式3) begin
语句1;
语句2;
…
语句n;
end
说明:如果只有一条语句,begin和end关键字可以省略。
一般在for循环中循环变量都使用integer类型。例如:
integer i;
reg [15:0] a,b;
for(i=0; i<16;i=i+1;)
a[ i ] = b [ i ];
for循环执行步骤如下:
step1: 求解表达式1;
step2: 求解表达式2,若其值为真(非0),则执行for语句中指定的内嵌语句,然后执行下面的第3步。若为假(0),则结束循环,转到第5步。
step3: 执行,若表达式为真,在执行指定的语句后,求解表达式3。
step4: 返回,返回上面的第2步骤继续执行。
step5: 结束循环,执行for循环之后的语句。
例1 :利用for循环实现二进制到格雷码转换
module binary2gray
(
input [3:0] a,
output [3:0] g
);
integer i;
function [3:0] gray(input [3:0] b);
begin
gray[3] = b[3];
for(i = 0; i < 3; i = i + 1)
gray[ i ] = b[ i ] ^ b[ i+1 ];//在function中使用for循环
end
endfunction
assign g = gray(a);
endmodule
仿真程序:
`timescale 1 ns / 1 ps
module tb_test
(
);
reg [3:0] ta;
wire [3:0] tg;
integer i;
initial begin
ta = 0;
#10
for(i = 0; i < 16; i = i + 1) begin
ta = i;
#10;
end
end
binary2gray binary2gray_inst
(
.a (ta),
.g (tg)
);
endmodule
Modelsim的仿真波形如图1:
图1
for循环也可以用在always过程中,甚至在时钟边沿驱动的always过程中。
例2:利用for循环实现4 X 4乘法器
module for_mult
(
input inclk,
input [3:0] a, b,
output reg [7:0] p
);
integer i;
always@(posedge inclk) begin
p = 0;
for( i = 0; i < 4; i = i + 1) begin
if(b[ i ])
p = p + (a<
end
end
endmodule
在时钟边沿驱动的always过程中,每次有上升沿的时候,for循环执行一遍。for循环的这种用法也是可综合的。当循环次数较多时,程序打编码效率较高。
仿真程序如下:
`timescale 1 ns / 1 ps
module tb_test
(
);
reg clk;
parameter PERIOD = 20;
initial
begin
clk = 1'b0;
#(PERIOD/2);
forever
#(PERIOD/2) clk = ~clk;
end
reg [3:0] ta = 0;
reg [3:0] tb = 0;
wire [7:0] tp;
always@(posedge clk) begin
ta <= ta + 1;
if(ta==15)
tb <= tb + 1;
end
for_mult for_mult_inst
(
.inclk (clk),
.a (ta),
.b (tb),
.p (tp)
);
endmodule
Modelsim仿真波形如图1:
图1
2.在并发过程中使用for循环
并发过程for循环语句的格式
genvar var; //定义循环变量 var
generate
for (var=0; var< limit; var=var+1)
begin: //隐式例化
语句1;
…
语句 n;
end
endgenerate
其实在并发语句中的循环是由generate创建的,generate创建过程本身也是一个独立的语法结构,不仅能使用for循环,还能使用if,case等语法结构。可以认位在并发过程中,generate创建了顺序语句过程,因此if, case ,for这些原本只能在顺序语句使用的语法结构,在这里也能使用。generate for还支持循环嵌套。
genvar var1, var2; //循环变量
generate
for (var1=0; var1 < limit; var1=var1+1)
begin:
for (var2=0; var2 < limit; var2=var2+1)
begin:
end
end
endgenerate
例:存储器初始化
reg [7:0] mem[0:255];
genvar i;
generate
for (i = 0; i < 256 ; i = i + 1) begin:
//always @(posedge sysclk) begin
mem[ i ] <= 8’b0;
//end
end
endgenerate
generate for 与普通的for循环不同点
generate for 每次循环都会生成一个例化,虽然没有明确指出例化过程,但例化结果是真实存在的。如果在generate 过成中使用always过程 ,generate 生成的for循环,always只能在for循环之内;而一般for循环,for在always之内。如:
reg [3:0] temp;
genvar i;
generate
for (i = 0; i < 3 ; i = i + 1)
begin:
always @(posedge sysclk)
begin
temp[ i ] <= 1'b0;
end
end
endgenerate
更详细的能容,在generate过程中描述。
作业题:在例2中由如下语句:
always@(posedge clk)
begin
ta <= ta + 1;
if(ta==15)
tb <= tb + 1;
end
如果替换成的语句如下:
always@(posedge clk)
begin
ta = ta + 1;
if(ta==15)
tb = tb + 1;
end
请比较两段代码的结果有何不同?