Verilog专题(五)细说for与generate-for

 

    Verilog HDL是一种硬件描述语言,如果期望在代码中实现,则需要EDA工具将其翻译成基本的门逻辑,而在硬件电路中并没有循环电路的原型,因此在使用循环语句时要十分小心,必须时刻注意其可综合性。 

    指导原则:虽然基于循环语句的Verilog HDL设计显得相对精简,阅读起来比较容易;但面向硬件的设计和软件设计的关注点是不一样的,硬件设计并不追求代码的短小,而是设计的时序、面积和性能等特征。在设计中应该使用计数器来代替for循环

    上一期专题四根据HDLBits的题目,介绍了for与generate-for的用法以及优劣,最后总结部分的第三点想单独拿出来再细细分析一下,因为verilog是硬件描述语言,只有分析综合出来的电路图才能判断好坏。

    虽然循环语句可以简化代码,易读,但是在实际应用中要谨慎使用循环,因为在FPGA内部并没有循环结构,FPGA能做的就是将循环结构展开,每个变量独立占用寄存器资源,每条执行语句并不能有效地复用硬件逻辑资源,造成巨大的资源浪费。

 

    简单来说就是:循环语句循环几次,就是将相同的电路复制几次,因此循环次数越多,占用面积越大,综合就越慢。因此在实际应用中通常产生一个计数器来代替循环结构,避免资源的浪费。

    从下面的RTL结果可以看出,将for循环写在always块中,for循环是串行的,电路面积大,速度慢,增加很大的布线难度,甚至会影响整体电路的时序;相反,generate-for循环是并行的,虽然速度会提升,但是面积开销、功耗比较大。因此,在实际应用中用计数器来代替循环结构,有助于节约资源。

 

for循环RTL结果

 

generate-for循环RTL结果

Verilog专题(五)细说for与generate-for_第1张图片

 

计数器RTL结果

Verilog专题(五)细说for与generate-for_第2张图片

 

 

附录

计数器code

module test(            input clk,rst,            input [12:0] data_in,            output reg[15:0] data_out            );        reg [3:0] i;        always @(posedge clk)           if(rst)              i <= 0;           else              i <= i + 1'b1;        always @ (posedge clk)           if(rst)              data_out <= 16'd0;           else if(data_in[i])              data_out <= data_out + 1'b1; endmodule

for循环code

module test(            input clk,rst,            input [12:0] data_in,            output reg[15:0] data_out            );         reg [3:0] i;         always @(posedge clk)begin            if(rst)               data_out <=0;            else begin               for(i=0;i<13;i=i+1)                   if(data_in[i])                   begin                      data_out = data_out+1'b1;                            end             end         endendmodule

generate-for循环code

module top_module(  input clk,rst,  input d,  output reg q);    always @(posedge clk)    if(rst)      q <= 0;    else      q <= d;endmodulemodule test(            input clk,rst,            input [15:0] data_in,            output [15:0] data_out            );        genvar i;        generate          for(i=0;i<16;i=i+1)begin:p            top_module dd(.clk(clk),.rst(rst),.d(data_in[i]),.q(data_out[i]));          end                 endgenerateendmodule

 

微信公众号

     建立了一个微信公众号“Andy的ICer之路”,此公众号主要分享数字IC相关的学习经验(后期打算与csdn同步更新),做公众号的目的就是记录自己的学习过程,很多东西回过头来可能就忘记了,为了记住知识和分享知识,希望自己可以保持更新,有兴趣的朋友可以关注一下!

 

你可能感兴趣的:(HDLBits_Verilog)