對於現在的仿真器,for循環一般都是可以綜合的。
`timescale 1ns / 1ps
module test(
input clk, rst_n,
input [7:0] data,
output reg [2:0] num
);
//=====================================
integer i;
always@(posedge clk)
begin
if(!rst_n)
num <= 3'd0;
else for (i=0; i<8; i=i+1)
if(data[i])
num <= num + 1'b1;
end
//====================================
endmodule
這個代碼看似是想要在一個時鐘週期計算出八位data數據的高電平位數,綜合後的電路:
看着不錯,但是真的實現了所要的功能了嗎?編寫testbench
`timescale 1 ps/ 1 ps
module test_vlg_tst();
reg clk;
reg [7:0] data;
reg rst_n;
wire [2:0] num;
test i1 (
.clk(clk),
.data(data),
.num(num),
.rst_n(rst_n)
);
initial
begin
rst_n = 0;
#20 rst_n = 1;
#500 $stop;
end
initial
begin
clk = 0;
forever #10 clk = ~clk;
end
initial
begin
data = 8'hA7;
end
endmodule
仿真波形如下:
可以看出,num只是每個時鐘週期加一而已,並不是計算data高電平的位數,always非阻塞賦值,只有always結束後賦值給左邊的,因此出現上面情況。將其改爲如下:
`timescale 1ns / 1ps
module test(
input clk, rst_n,
input [7:0] data,
output reg [7:0] num
);
//==============================================
integer i;
always@(posedge clk)
begin
if(!rst_n)
num = 8'd0;
else for (i=0; i<8; i=i+1)
if(data[i])
num = num + 1'b1;
end
//==============================================
endmodule
仿真波形:
似乎for循環綜合這種依賴之前結果的電路會出現問題,一般只建議綜合簡單的分立的簡單賦值:
for (i=0; i<8; i=i+1)
out[i] <= a[i] & b[i];