在FPGA中使用for循環一定浪費資源嗎?


 漸漸地,發現自己已經習慣於發現細節,喜歡打破常規,真的非常喜歡這種feel。

    相信很多人在書上或者博文上都有提出“在FPGA中使用for語句是很占用資源的”的觀點,特權同學也不例外。那么,這種觀點正確嗎?我的答案是:對一半,錯一半。在某些情況下,使用for循環也許真的挺占用資源的。但我並不想去探討這種情況。而是談談在另外一些情況下使用for語句的好處。

    第一個好處:有時使用for循環不但不會浪費多余的資源,而且可以減少代碼量,從而提高編碼效率;第二個好處是:方便模塊的移植。下面舉個移位寄存器的簡單例子來說明就一目了然了。假設設計一個深度為16、位寬為8的移位寄存器。

1、基於非for語句的移位寄存器電路設計如下:

module shift_register
#(
    parameter   DATA_WIDTH  = 8
)
(
    input                       clk,
    input   [DATA_WIDTH-1:0]    din,
    output  [DATA_WIDTH-1:0]    dout
);
//---------------------------------------------
reg         [DATA_WIDTH-1:0]    mem     [0:15];
always @(posedge clk)
begin
    mem[0 ] <= din;
    mem[1 ] <= mem[0 ];
    mem[2 ] <= mem[1 ];
    mem[3 ] <= mem[2 ];
    mem[4 ] <= mem[3 ];
    mem[5 ] <= mem[4 ];
    mem[6 ] <= mem[5 ];
    mem[7 ] <= mem[6 ];
    mem[8 ] <= mem[7 ];
    mem[9 ] <= mem[8 ];
    mem[10] <= mem[9 ];
    mem[11] <= mem[10];
    mem[12] <= mem[11];
    mem[13] <= mem[12];
    mem[14] <= mem[13];
    mem[15] <= mem[14];
end

assign  dout = mem[15];

endmodule

    綜合后資源消耗為:

4.png

2、基於for語句的移位寄存器電路設計如下:

module shift_register_for
#(
    parameter   DATA_WIDTH  = 8,
    parameter   SHIFT_LEVEL = 16
)
(
    input                       clk,
    input   [DATA_WIDTH-1:0]    din,
    output  [DATA_WIDTH-1:0]    dout
);
//-------------------------------------------------------
reg         [DATA_WIDTH-1:0]    mem     [0:SHIFT_LEVEL-1];
always @(posedge clk)
begin : shift_reg
    integer     i;
    for(i = 0; i < SHIFT_LEVEL-1; i = i + 1)
        mem[i+1] <= mem[i];
    mem[0] <= din;
end

assign  dout = mem[SHIFT_LEVEL-1];

endmodule

    綜合后資源消耗為:

5.png

    通過對比,兩者消耗資源一樣,但使用for語句可大大減少代碼量。在這里,我問大家一個問題,如果我想要一個深度為40、位寬為8的移位寄存器,怎么辦?對基於for語句的移位寄存器很容易實現,只要將SHIFT_LEVEL=16改為SHIFT_LEVEL=40就可以了;而對於沒有使用for語句的移位寄存器並沒有快捷的修改方法,只能乖乖地按部就班了,如下所示:

module shift_register
#(
    parameter   DATA_WIDTH  = 8
)
(
    input                       clk,
    input   [DATA_WIDTH-1:0]    din,
    output  [DATA_WIDTH-1:0]    dout
);
//--------------------------
reg         [DATA_WIDTH-1:0]    mem     [0:15];
always @(posedge clk)
begin
    mem[0 ] <= din;
    mem[1 ] <= mem[0 ];
    mem[2 ] <= mem[1 ];
    mem[3 ] <= mem[2 ];
    mem[4 ] <= mem[3 ];
    mem[5 ] <= mem[4 ];
    mem[6 ] <= mem[5 ];
    mem[7 ] <= mem[6 ];
    mem[8 ] <= mem[7 ];
    mem[9 ] <= mem[8 ];
    mem[10] <= mem[9 ];
    mem[11] <= mem[10];
    mem[12] <= mem[11];
    mem[13] <= mem[12];
    mem[14] <= mem[13];
    mem[15] <= mem[14];
    mem[16] <= mem[15];
    mem[17] <= mem[16];
    mem[18] <= mem[17];
    mem[19] <= mem[18];
    mem[20] <= mem[19];
    mem[21] <= mem[20];
    mem[22] <= mem[21];
    mem[23] <= mem[22];
    mem[24] <= mem[23];
    mem[25] <= mem[24];
    mem[26] <= mem[25];
    mem[27] <= mem[26];
    mem[28] <= mem[27];
    mem[29] <= mem[28];
    mem[30] <= mem[39];
    mem[31] <= mem[30];
    mem[32] <= mem[31];
    mem[33] <= mem[32];
    mem[34] <= mem[33];
    mem[35] <= mem[34];
    mem[36] <= mem[35];
    mem[37] <= mem[36];
    mem[38] <= mem[37];
    mem[39] <= mem[38];
end

assign  dout = mem[39];

endmodule

    由此,使用for語句的移位寄存器很方便移植。

    總結:在一些情況下,適當使用for語句不但可以節省設計的時間,還有利於設計的移植。

轉載自:http://blog.chinaaet.com/crazybird/p/5100000274


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM