verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)

verilog语法-----generate结构

文章主要观点是从verilog-IEEE-2005里面提取的,讲的不透彻的,可以查看英文原本

Generate constructs

generate constructs用于在一个module中生成有条件的或嵌套的generate blocks。generate blocks是一个或多个module的集合。generate blocks可能不包含端口声明,参数声明,特定块或specparam声明。包含generate blocks在内的所有其他中module,允许出现在generate blocks中。generate blocks使参数值影响模型结构称为可能。它能更简洁地描述具有重复结构的模块,并使递归模块实例化成为可能。
有两种generate结构:循环和条件。 循环构造允许将单个generate blocks多次实例化为module的块。包括if-generate和case-generate构造的条件generate结构,最多可以从一组可替代的generate 块中实例化一个generate块。术语“generate scheme”是指确定哪个或多少个generate块需要被实例化。 它包括条件表达式,大小写替换和循环生成构造中出现的控制语句。
在模型生成期间评估generate scheme。 评估在HDL完成之后,simulation之前; 它涉及module实例化,计算参数值,解析层次结构名称(请参见12.5),建立网络连接,及为simulation准备模型。尽管generate scheme使用的语法类似于行为声明,但重要的是要它们不会在仿真时执行。 它在评估的时候完成,在simulation开始之前得到结果。 因此,generate scheme中的所有表达式都应为常量表达式,并在评估时确定。 有关详细说明的更多信息,请参见12.8。
一个generate结构的生成可以由一个或多个实例化的generate block构成。一个实例化的generate block在某种方式上和一个实例化的module是类似的。它创建了一个新的层次结构。它使block中的对象,行为构造和模块实例可以加入到已实现的模块中。这些结构添加到一个module中和一个已存在的module中加入module是类似的,只不过可以直接引用封闭范围中的对象声明(请参见12.7)。实例化的命名生成块中的名称可以按12.5中的描述分层引用。
关键字generate和endgenerate可以在模块中使用以定义generate region。generate region是module描述中可能会出现generate constructs的文本范围。使用generate regions是可选的。 使用generate region 时,模块中没有语义差异。 编译器可能会选择识别generate region,以针对误用的generate关键字生成不通的错误消息。generate region不会嵌套,它们只能直接出现在module内。 如果使用了generate关键字,则应与endgenerate关键字匹配。
The syntax for generate constructs is given in Syntax 12-5.
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第1张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第2张图片

Loop generate constructs

循环generate constructs允许使用类似于for循环语句的语法将generate block实例化多次。循环索引变量必须在genvar声明中声明,然后才能在循环generate scheme中使用。
genvar在elaboration 期间用作整数,以评估generate循环并创建generate块的实例,但在仿真时不存在。genvar不得在循环生成方案以外的任何地方引用。
循环生成方案中的初始化和迭代分配都应分配给相同的genvar。初始化分配不得引用右侧的循环索引变量(如genvar i)。
在循环generate construct的generate block 中,有一个隐式localparam声明。这是一个整数参数,具有与循环索引变量相同的名称和类型,并且它在generate块的每个实例中的值都是在实例化时索引变量的值。此参数可以在generate块中可以使用具有整数值的常规参数的任何位置使用。
可以使用层次结构名称进行引用.
由于此隐式localparam与genvar具有相同的名称,因此在循环generate block中对此名称的任何引用将是对localparam的引用,而不是对genvar的引用。结果,不可能有两个使用相同genvar的嵌套循环生成构造.
循环generate constructs中的generate块可以命名或不命名,它们只能包含一项,而不必由begin / end关键字包围。即使没有开始/结束关键字,它仍然是一个生成块,与所有生成块一样,它在实例化时包括单独的作用域和新的层次结构级别。
如果generate块被命名,则它是generate block实例数组的声明。此数组中的索引值是elaboration过程中genvar假定的值。
这可以是一个间断数组,因为genvar值不必形成连续的整数范围。即使循环generate scheme未生成generate block的实例,也认为该数组声明。如果generate块未命名,除了在generate块本身实例化的层次结构中之外,不能使用层次结构名称来引用其中的声明。
如果generate block实例数组的名称与任何其他声明(包括任何其他generate block实例数组)发生冲突,则将是一个错误。如果循环generate scheme没有终止,那将是一个错误。如果在循环generate scheme的评估期间重复一个genvar值,将是一个错误。如果在评估循环generate scheme的过程中将genvar的任何位设置为x或z,将是一个错误。
Example 1—Examples of legal and illegal generate loops
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第3张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第4张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第5张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第6张图片
示例3和示例4中的模型是使用循环生成Verilog门基元进位链加法器的参数化模块。 示例3在generate循环外部使用二维网络声明在门基元之间建立连接,而示例4在generate循环内部使用net声明来为循环的每次迭代生成连接门基元所需的线网。
Example 3—Generated ripple adder with two-dimensional net declaration outside of the generate loop
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第7张图片
Example 4—Generated ripple adder with net declaration inside of the generate loop
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第8张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第9张图片
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第10张图片
备注:
这篇文章是博客里面最常见的一个,但是包含错误: 特点(2),(3)是错误的
https://blog.csdn.net/weixin_33714884/article/details/93500760?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-4
verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第11张图片

==========================================================================================
example 1----综合实现正确

module	iddr_ctrl(
	input	wire		rst_n,
	//from phy
	input	wire[3:0]	rx_dat,//双沿4bit数据  一个时钟周期传输8bit数据
	input	wire		rx_ctrl,//上升沿对应dv  下降沿对应err
	input	wire		rx_clk,//phy传输来的时钟相移90
	//to mac
	output	reg[7:0]	rx_data,//单沿8bit数据
	output	reg		rx_en//8bit数据对应有效信号
);

wire		tmp_dv;
wire		tmp_err;
wire[7:0]	tmp_data;

 IDDR #(
      .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 
                                      //    or "SAME_EDGE_PIPELINED" 
      .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
      .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
      .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" 
   ) IDDR_dv (
      .Q1(tmp_dv), // 1-bit output for positive edge of clock 
      .Q2(tmp_err), // 1-bit output for negative edge of clock
      .C(rx_clk),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D(rx_ctrl),   // 1-bit DDR data input
      .R(1'b0),   // 1-bit reset
      .S(~rst_n)    // 1-bit set
   );

genvar i;
generate
      for (i=0; i < 4; i=i+1)
      begin
         IDDR #(
      .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 
                                      //    or "SAME_EDGE_PIPELINED" 
      .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
      .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
      .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" 
   ) IDDR_data (
      .Q1(tmp_data[i]), // 1-bit output for positive edge of clock 
      .Q2(tmp_data[i+4]), // 1-bit output for negative edge of clock
      .C(rx_clk),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D(rx_dat[i]),   // 1-bit DDR data input
      .R(1'b0),   // 1-bit reset
      .S(~rst_n)    // 1-bit set
   );
      end
endgenerate

always @(posedge rx_clk or negedge rst_n)
	if(!rst_n)
		rx_en <= 1'b0;
	else
		rx_en <= tmp_dv;

always @(posedge rx_clk or negedge rst_n)
	if(!rst_n)
		rx_data <= 8'b0;
	else
		rx_data <= tmp_data;

endmodule

verilog语法-----generate结构-(IEEE Std 1364™-2005翻译)_第12张图片

example 2 ----综合,实现正确

module gry2bin #(
    parameter length = 4
    )
    (
    input  wire [length-1:0] Gry,
    output reg  [length-1:0] Bin
    );

    integer i;
    generate 
    always @(*)
    begin
        Bin[length - 1'b1] = Gry[length - 1'b1];  
        //generate    
            for(i=0; i<=length-2; i=i+1) begin       
                Bin[i] = Bin[i + 1'b1] ^ Gry[i] ;
            end 
        //endgenerate
    end 
    endgenerate
endmodule

example 3 ----综合错误

module gry2bin #(
    parameter length = 4
    )
    (
    input  wire [length-1:0] Gry,
    output reg  [length-1:0] Bin
    );

    integer i;
    always @(*)
    begin
        Bin[length - 1'b1] = Gry[length - 1'b1];  
        generate    
            for(i=0; i<=length-2; i=i+1) begin       
                Bin[i] = Bin[i + 1'b1] ^ Gry[i] ;
            end 
        endgenerate
    end 
endmodule

你可能感兴趣的:(verilog)