Verilog代码优化之for语句<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
这回来谈谈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) num <= num+1;
end
end
endmodule
这段代码的用意是在一个时钟周期内计算出13路脉冲信号为高电平的个数,一般人都会感觉这个任务交给for循环来做再合适不过了,但是for循环能完成这个任务吗?
我们来看看仿真的结果:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
相信你已经发现问题了,为什么每个时钟周期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) num = num+1;end
end
end
assign numout = num;
endmodule
仿真的波形如下:
此波形说明了现在的代码达到了实验目的。看来For语句在这种情况下还是比较省事的,如果不用for语句就比较繁琐了。但是话说回来,for语句综合的效率不高,在对速度要求不高的前提下,还是宁愿用多个时钟周期去实现也不用for语句。
用户377235 2014-4-11 17:31
用户1668914 2014-3-23 21:35
用户1453491 2012-11-19 09:25
用户377235 2012-4-18 17:11
1.对于第二个仿真图没有看出起始的1是怎么来的 2.7后面为什么是8,而不是9?
用户377235 2012-2-9 22:02
用户1514923 2011-5-18 21:40
用户1324799 2011-5-10 17:45
用户1458803 2010-10-18 15:27
xucun915_925777961 2010-9-9 13:28
用户1584993 2010-9-2 14:02