Verilog中的生成语句主要使用generate语法关键字,按照形式主要分为循环生成与条件生成,主要作用就是提高我们的代码的简洁度以及可读性。

一、循环生成

语法如下:

1 genvar i;
2 generate
3 for (i=0; i< ??; i=i+1)
4   begin:循环的段名
5 
6         内容
7  end
8 endgenerate

关于以上语法有四点注意:

1、循环生成中for语句使用的变量必须用genvar关键字定义,genvar关键字可以写在generate语句外面,也可以写在generate语句里面,只要先于for语句声明即可;

2、必须给循环段起一个名字。这是一个强制规定,并且也是利用循环生成语句生成多个实例的时候分配名字所必须的;

3、for语句的内容必须加begin-end,即使只有一条语句也不能省略。这也是一个强制规定,而且给循环起名字也离不开begin关键字;

4、可以是实例化语句也可以是连续赋值语句。

循环生成语句允许使用者对下面的模块或模块项进行多次的实例引用;

1)变量声明;    2)模块;    3)用户定义原语、门级原语;  4)连续赋值语句;   5)initial 和 always 块。

举例:

 1  input [3:0] a,b;
 2  output [3:0] c,d;
 3 generate
 4 genvar i;
 5 
 6  for (i=0; i < 4; i=i+1)
 7             begin : genExample
 8                myAnd insAnd (.a(a[i]), .b(b[i]), .c(c[i]));
 9             assign d[i] = a[i];
10     end
11 endgenerate

 

 

注意:利用循环生成语句生成的实例名称不能像数组例化那样用方括号表示,否则会报错。那么,你可能会疑惑上例中实例的名字,其实,上述实例化展开来类似:

二、条件生成

    条件生成的目的是为了左右编译器的行为,类似于C语言中的条件选择宏定义,根据一些初始参数来决定载入哪部分代码来进行编译。Verilog中共提供了两种条件生成语句,一种是generate-if语句,一种是generate-case语句,两者的功能几乎相同,只是书写形式不一样而已,分别介绍如下:

该结构可以在设计模块中根据经过仔细推敲并确定表达式,有条件的调用以下结构:

1)模块;  2)用于定义的原语,门级原语;  3)连续赋值语句;  4)initial 或always 块

该语句的语法如下

 1 generate
 2 
 3                          if (<condition>) begin: <label_1>
 4 
 5                                <code>;
 6 
 7                          end else if (<condition>) begin: <label_2>
 8 
 9                                <code>;
10 
11                          end else begin: <label_3>
12 
13                                <code>;
14 
15                          end
16 
17 endgenerate

 

关于该语法有三点注意:

       1、必须是常量比较,例如一些参数,这样编译器才可以在编译前确定需要使用的代码;
  2、if语句的内容中,begin-end只有在 < code > 有多条语句时才是必须的;
  3、每一个条件分支的名称是可选的,这点不像循环生成语句那么严格。

generate-case语句:

case生成语句可以调用以下的结构:

1)模块;  2)用于定义的原语,门级原语;   3)连续赋值语句;  4)initial 或 always块。

该语句的语法如下:

 1             generate
 2 
 3                                case (<constant_expression>)
 4 
 5                                 <value>: begin: <label_1>
 6 
 7                                        <code>
 8 
 9                                        end
10 
11                                 <value>: begin: <label_2>
12 
13            <code>
14 
15                                        end
16 
17                                 ……
18 
19                                 default: begin: <label_N>
20 
21            <code>
22 
23             end
24 
25                           endcase
26 
27                       endgenerate

 

关于该语法也有三点注意,和generate-if类似:

1、<constant_expression>必须是常量比较,例如一些参数,这样编译器才可以在编译前确定需要使用的代码;

2、case语句的内容中,begin-end只有在< code >有多条语句时才是必须的;

3、每一个条件分支的名称是可选的,这点不像循环生成语句那么严格。

三、见解与分析

  (1)在generate block里面存在都是一些模块级别的语句,和我们平常在always 块和initial 块中的语句不一样,级别要高一点,就如文章的开头一样,是为了简化电路的书写。通俗一点来讲,在generate中的要求和在module中很类似,因为generate就是生成一个电路,电路结构就是你在generate中表述的内容。

  (2)可以独立存在于generate块或者module的应当是变量声明,常量定义,assign赋值,门级语句,块声明,实例调用方法(I/O匹配表)可能有些遗漏,不过也差不多了,像if-else,while,for,case这类的语句都是高级语句,是不能独立出现的,必须放在initial或always块中。说白了,就是化繁为简用的,是用来简化代码(不是简化电路),具体实现是用于产生多个模块,相当于复制电路。

  针对循环生成语句,举个例子:我已经有一个模块A,可以产生1位的伪随机码,但我现在需要32位的伪随机码,我就可以用generate-for产生32个模块从而输出32位伪随机码。当然你也可以实例化32次A模块产生32位伪随机码,作用是一样的,但代码简洁很多。(其中模块A,可以是initial块,always块,assign连续赋值语句块,实例化块,原语块,门电路块)。

  针对条件生成语句:它与我们看到的高即别的(就是那些不能单独使用必须放在always块和initial块中的语句)条件语句有本质区别。高级语句中if --else 会生成逻辑电路,而generate if是告诉综合器:除非满足某条件才将以下代码综合为电路。换句话说,如果generate if的条件不满足,那么这段纸面代码会被综合器直接忽略。两者有本质不同。

四、参考文献

  1、https://www.eefocus.com/cl5417/blog/17-02/403819_5c980.html

  2、https://www.cnblogs.com/SYoong/p/5858996.html