RTL綜合----for循環

對於現在的仿真器,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數據的高電平位數,綜合後的電路:
RTL
看着不錯,但是真的實現了所要的功能了嗎?編寫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

仿真波形如下:
sim
可以看出,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

仿真波形:
sim


似乎for循環綜合這種依賴之前結果的電路會出現問題,一般只建議綜合簡單的分立的簡單賦值:

for (i=0; i<8; i=i+1)
    out[i] <= a[i] & b[i];

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章