目前在hdlbits刷题,在处理popcount时使用generate for实现该功能时,无论怎样都不可以实现,但是使用for却轻易的实现了,因此让我有了一些对两种语法的思考。
那么废话少说,先上这个问题的题目:
A “population count” circuit counts the number of '1’s in an input vector. Build a population count circuit for a 3-bit input vector.
使用for语句对每个输入位进行判断,若为1时,输出加1,那么很容易就实现了:
module top_module(
input [2:0] in,
output [1:0] out );
int i;
always@(*)begin
out=2'b00;
for (i=0;i<3;i++)begin
if(in[i])
out=out+1'b1;
else
out=out+1'b0;
end
end
endmodule
然而使用generate for语句实现时,却怎么都无法成功,下面是我类比for语句写的代码,当然这个代码是错误的,没有办法运行。
module top_module(
input [2:0] in,
output [1:0] out );
genvar i;
generate
for(i=0;i<3;i++)begin:pop3
initial out=2'b0;
always@(*)begin
if(in[i])
out=out+1'b1;
else
out=out+1'b0;
end
end
endgenerate
endmodule
错误结果如下:
Warning (10240): Verilog HDL Always Construct warning at top_module.v(9): inferring latch(es) for variable “out”, which holds its previous value in one or more paths through the always construct File: /home/h/work/hdlbits.222493/top_module.v Line: 9
使用generate for语句时,首先出现无法对out的初值进行赋值,在这里我使用的initial对其赋值,因为out是寄存器变量,因此使用assign则会报错。
此外,因为generate for和for之间的always顺序不相同,使用generate for语句时,由于always在后则会出现同时对一个变量进行多次赋值,因此报错。
当然,怎样用generate for语句实现这个功能我也在摸索,但是感觉得不偿失,有的时候能用多种方法实现固然是好的,但是若效果大大降低那么便是钻牛角尖了。
在最后,放一下我在别人那里看到的二者区别吧(以下为转载)
Generate blocks are useful when change the physical structure of then module via parameters. For example choosing negedge or posedge clock and only enabling one:
if ( param_use_pos == 1) begin : use_pos always @(posedge sysclk) begin ... end end else begin : use_neg always @(negedge sysclk) begin ... end end
If you are not changing the physical structure, it is typically better to use for loops and if-else statements inside the always block. Both approaches can synthesize the same but when running RTL simulation the non-generate block approach will typically simulate faster. This is because simulators normally can process a single N-bit operation faster than N 1-bit operations. Again synthesis is the same result
// faster :: 1 always block, simulator can optimize the for loop always @(posedge sysclk) begin for (i = 0; i < 3 ; i = i + 1) begin temp[i] <= 1'b0; end end // slower :: creates 4 always blocks, harder for the simulator to optimize genvar i; generate // optional if > *-2001 for (i = 0; i < 3 ; i = i + 1) begin always @(posedge sysclk) begin temp[i] <= 1'b0; end end endgenerate // match generate