渐渐地,发现自己已经习惯于发现细节,喜欢打破常规,真的非常喜欢这种feel。
相信很多人在书上或者博文上都有提出“在FPGA中使用for语句是很占用资源的”的观点,特权同学也不例外。那么,这种观点正确吗?我的答案是:对一半,错一半。在某些情况下,使用for循环也许真的挺占用资源的。但我并不想去探讨这种情况。而是谈谈在另外一些情况下使用for语句的好处。
第一个好处:有时使用for循环不但不会浪费多余的资源,而且可以减少代码量,从而提高编码效率;第二个好处是:方便模块的移植。下面举个移位寄存器的简单例子来说明就一目了然了。假设设计一个深度为16、位宽为8的移位寄存器。
1、基于非for语句的移位寄存器电路设计如下:
moduleshift_register
#(
parameterDATA_WIDTH=8
)
(
inputclk,
input[DATA_WIDTH-1:0]din,
output[DATA_WIDTH-1:0]dout
);
//---------------------------------------------
reg[DATA_WIDTH-1:0]mem[0:15];
always@(posedgeclk)
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
assigndout=mem[15];
endmodule
综合后资源消耗为:
2、基于for语句的移位寄存器电路设计如下:
moduleshift_register_for
#(
parameterDATA_WIDTH=8,
parameterSHIFT_LEVEL=16
)
(
inputclk,
input[DATA_WIDTH-1:0]din,
output[DATA_WIDTH-1:0]dout
);
//-------------------------------------------------------
reg[DATA_WIDTH-1:0]mem[0:SHIFT_LEVEL-1];
always@(posedgeclk)
begin:shift_reg
integeri;
for(i=0;i<SHIFT_LEVEL-1;i=i+1)
mem[i+1]<=mem[i];
mem[0]<=din;
end
assigndout=mem[SHIFT_LEVEL-1];
endmodule
综合后资源消耗为:
通过对比,两者消耗资源一样,但使用for语句可大大减少代码量。在这里,我问大家一个问题,如果我想要一个深度为40、位宽为8的移位寄存器,怎么办?对基于for语句的移位寄存器很容易实现,只要将SHIFT_LEVEL=16改为SHIFT_LEVEL=40就可以了;而对于没有使用for语句的移位寄存器并没有快捷的修改方法,只能乖乖地按部就班了,如下所示:
moduleshift_register
#(
parameterDATA_WIDTH=8
)
(
inputclk,
input[DATA_WIDTH-1:0]din,
output[DATA_WIDTH-1:0]dout
);
//--------------------------
reg[DATA_WIDTH-1:0]mem[0:15];
always@(posedgeclk)
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
assigndout=mem[39];
endmodule
由此,使用for语句的移位寄存器很方便移植。
总结:在一些情况下,适当使用for语句不但可以节省设计的时间,还有利于设计的移植。