未闻verilog---generate生成块

生成块

生成块语句可以动态的生成Verilog代码。

编写代码时必须在代码中说明生成的实例范围,关键字generate-endgenerate用来指定该范围。

可以允许出现在生成块中的

实例

Verilog允许生成实例,生成实例可以是以下的一个或多个类型:

  1. 模块
  2. 用户定义原语
  3. 门级原语
  4. 连续赋值语句
  5. initial 和 always块

生成的实例具有唯一的标识名,因此可以用层次命名规则引用。

数据类型

Verilog语言允许在生成范围内声明下列数据类型

  1. net(线网),reg(寄存器)
  2. integer(整型数),real(实型数),time(时间型),realtime(实数时间型)
  3. event(事件)

生成的数据类型具有唯一的标识名,可以被层次引用。

任务和函数

任务函数的声明可以出现在生成范围之中,但是不能出现在循环生成(generate -for)之中。生成的任务和函数同样具有唯一的标识符名称,可以被层次引用。

不能出现在生成块中的:

不允许出现在生成范围之中的模块项声明包括:

  1. 参数(parameter),局部参数(localparameter)
  2. 输入,输出和输入/输出声明。
  3. 指定块。

生成块的形式

generate生成块有两种结构

  1. 循环结构(generate-for)
  2. 条件结构(generate-if 和generate-case)

generate-for

允许使用者对下面的模块或者模块项进行多次实例引用:

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

基本结构:

parameter N =..//声明循环的边界,没必要用paramete去声明,这里只是为了方便
genvar i; //声明一个临时循环变量,该变量只用于生成块的循环计算,仿真时并不存在

generate
    for(i=0;i<N;i=i+1)
        begin:block_name        //注意一定要声明块的名字!!!
            ...
        end
endgenerate

generate循环的语法与for循环语句的语法很相似。但是在使用时必须先在genvar声明中声明循环中使用的索引变量名,然后才能使用它。genvar声明的索引变量被用作整数用来判断generate循环。genvar声明可以是generate结构的内部或外部区域,并且相同的循环索引变量可以在多个generate循环中,只要这些环不嵌套。genvar只有在建模的时候才会出现,在仿真时就已经消失了。

在仿真开始之前,仿真器会对生成快中的代码进行展开,将生成快转换为展开的代码,然后对展开的代码进行仿真。生成快循环结构的本质就是用循环内的一条语句代替多条重复的Verilog代码,简化用户的编程

循环生成语句可以嵌套使用,不过使用同一个生成变量作为索引的循环生成语句不能相互嵌套。

Verilog中generate循环中的generate块可以命名也可以不命名。如果已命名,则会创建一个generate块实例数组。如果未命名,则有些仿真工具会出现警告,因此,最好始终对它们进行命名。从上面的例子里,块的名字声明为block_name ,虽然名字是block_name ,但实际上是一个组,每个循环生成块的名字为block_name ,例如当要层次化引用时可以写成block_name[1]

generate-if

条件生成语句允许有条件的调用(实例引用)以下结构:

  1. 模块
  2. 用户定义原语,门级原语
  3. 连续赋值语句
  4. initial或者always块

基本结构

generate
    if(condition)
        ...
    else
        ...
endgenerate

条件语句从很多的备选块中选择最多一个generate块,请注意,在这我说的是最多,因为有可能是一个也不选择的。在建模中,条件必须为常量表达式。

条件if-generate不关心是否命名,并且可以不具有begin / end。当然,上述两个条件只能包含一项。它也会创建单独的范围和层次结构级别,这个和generate循环是一样的。由于最多选择一个代码块,因此在单个的if-generate中以相同的名称命名所有的备用代码块是合法的,而且这有助于保持对代码的分层引用。但是,不同的generate构造中必须具有不同的名称。

generate-case

条件生成语句允许有条件的调用(实例引用)以下结构:

  1. 模块
  2. 用户定义原语,门级原语
  3. 连续赋值语句
  4. initial或者always块

基本结构:

gengerate
    case(..)
        ..
        ..
    endcase   //!!!
endgenerate

case-generate也可用于从几个块中有条件地选择一个代码块。它的用法类似于基本case语句,并且if-generate中的所有规则也适用于case-generate块。

生成块的作用

作用

一个是用来构造循环结构,用来多次实例化某个模块。

一个是构造条件generate结构,用来在多个块之间最多选择一个代码块。

generate-for 与 for之间的区别

参数声明for循环使用integer,generate使用genvar

for循环往往用于always内部,但generate for更加*,内部可以进行循环例化always和assign

generate -if/case 作用

生成逻辑,和generate for 不一样的是他不会复制逻辑。这个更像是C中的#if ... #endif 条件预编译。要知道在verilog里面只有 `ifdef .....`endif这样的条件编译语句。有了generate if 这样的语句之后我们就可以通过参数/宏 ,当然主要是通过参数,来控制哪部分逻辑需要生成。同样这个generate 块里的东西和generate for 相同。

参考引用
(10 封私信 / 80 条消息) Verilog里的generate到底有什么好处? - 知乎 (zhihu.com)
Verilog中generate的使用 - 知乎 (zhihu.com)

上一篇:JavaWeb——Generate toString()使用方法


下一篇:Mysql创建事件定时任务