Verilog代码优化之for语句
0赞这回来谈谈for语句,硬件里的for语句不像软件那样频繁 的使用。一方面是因为for语句的使用是很占用硬件资源的,另一方面是因为在设计中往往是采用时序逻辑设计用到for循环的地方不多。
下面是一个用到for循环设计的代码:
module test_3(clk,rst_n,data,num);
input clk;
input rst_n;
input[12:0] data; //输入13路数据
output[15:0] num; //13路数据电平为高的路数
reg[3:0] i;
reg[15:0] num;
always @ (posedge clk) begin
if(!rst_n) begin
num <= 0;
end
else begin
for(i=0;i<13;i=i+1) //用for循环进行计算
if(data[i]) num <= num+1;
end
end
endmodule
这段代码的用意是在一个时钟周期内计算出13路脉冲信号为高电平的个数,一般人都会感觉这个任务交给for循环来做再合适不过 了,但是for循环能完成这个任务吗?
我们来看看仿真的结果:
相信你已经发现问题了,为什么每个时钟周期for循环只执行一次num <= num+1呢?笔者也很困惑,或 许综合工具遇到for也无能为力了吧!所以,慎用for语句!
补充:首先感谢EDN的网友wp061的指点。Always语句中使用非阻塞赋值<=时,是在always结束后才把值赋给左边 的寄存器,因此才出现了上面的情况。我重新用阻塞语句写了如下程序:
module test_3(clk,rst_n,data,numout);
input clk;
input rst_n;
input[12:0] data; //输入13路数据
output[15:0] numout; //13路数据电平为高的路数
wire[15:0] numout;
reg[3:0] i;
reg[15:0] num;
always @ (posedge clk) begin
if(!rst_n) begin
num = 0;
end
else begin
for(i=0;i<13;i=i+1) begin //用for循环进行计算
if(data[i]) num = num+1;end
end
end
assign numout = num;
endmodule
仿真的波形如下:
此波形说明了现在的代码 达到了实验目的。看来For语句在这种情况下还是比 较省事的,如果不用for语句就比较繁琐了。但是 话说回来,for语句综合的效率不高,在 对速度要求不高的前提下,还是宁愿用多个时钟周期去实现也不用for语句。