Verilog的generate语句能够帮助我们写出可配置可综合的RTL,主要用于重复性实例化模块或者有条件地实例化模块。这篇文章将简单回顾一下verilog generate语句。
Verilog generate语句的类型一
有两种不同的generate语句结构。
Generate loop能够将一段代码例化多次,通过一个index变量来控制。
conditional generate语句能够在多段代码中选择一段进行例化。Conditional generate包括了if-generate和case-generate两种不同模式。
Verilog的generate语句在仿真/综合的elaborate阶段进行分析,这个步骤发生在HDL语言解析之后,在仿真/综合之前。因此generate结构中包含的所有表达式在elaborate的时候都要是确定的表达式,不能包含动态变量。比如,generate中的语句能受parameter影响,但不能被动态变量影响。
一个verilog generate模块创建了一个新的层次,就像实例化了一个模块一样。
关键字generate和end generate(以及begin/end)实际上不是必须的,如果使用的话,那么他们就定义了一块generate的区域,generate的区域只能存在于在module这个scope里。
generate loop一
Generate loop的语法和for loop很类似。Index变量要先用genvar关键字来定义,genvar所定义的index变量会被用在elaboration中。Genvar可以存在于generate region(由generate-endgenerate关键字来限定)之内或之外。同一个genvar定义的index可以被用在多个generate loop中,只要这些loop没有互相嵌套。
如果将generate loop展开,在每个generate loop instance中,都会创建一个隐含的localparam,其名字和类型与genvar所定义的index相同,其值就是当前的循环次数。这个localparam能够用来控制生成代码。
Generate loop所生成的模块可以被命名也可以不被命名。如果被命名,那么将会生成以所给名字开头的一个数组,每个数组元素是一个模块hierarchy。有些工具对于未命名的generate loop会给予警告,因此最好将其命名。
下面的例子是一个使用verilog generate loop来生成的格雷码->二进制码的转换器:
另外一个来自verilog-2005 LRM的例子阐述了每个verilog generate loop是如何生成一个新的scope的。注意到wire t1,t2,t3都是在generate loop中被声明的,每个loop iteration都创建了完全不冲突的三个t1,t2,t3。他们都被用于在每个不同的数组模块中连接相应的电路。并且注意到这些被实例化的xor,and的命名方式。
generate loop同样能嵌套。只需要单一一个generate/endgenerate来包裹这些嵌套的generate loop。每个generate loop都建立一个新的scope。
if-generate一
Conditional if-generate会从一组互斥的generate block中最多选择一个generate block。注意到这里说的是最多选择一个,也有可能一个都不选。而这个判断语句在elaborate的时候也必须是常量表达式。
与generate loop一样,conditional if-generate可以命名也可以不命名,可以使用也可以不使用begin-end。它同样会创建一个新的scope以及hierarchy层次。因为conditional generate选择至多一个block的代码,对于互斥的block code,在同一个if-generate结构里可以有同样的命名。这能够帮助保留层次名,无论哪个block的代码被选择。而不同的generate结构则一定要有不同的名字。
case-generate一
与if-generate类似。case-generate最多会从一组互斥的generate block中选择一个generate block。它的用法和传统的case语句一样。
嵌套的 conditional generate block没有用begin end来切割会被归为单独一个scope/hierarchy。这能够避免在同一个module中创建没变要的scope/hierarchy。下面的例子是一个嵌套conditional generate block的例子
generate结构会选择至多一个叫u1的generate block。而g1的hierarchcal名字是test.u1.g1。当嵌套if-generate 结构的时候,else永远属于最近的if。注意到这里任何多余的begin-end会违反这个direct nest规则,从而生成新的hierarchy。
generate模块命名一
推荐给generate construct命名来简化层次索引。并且有些工具对于不命名的generate block会报错。
如果不命名的话, 首先,每个generate construct在一个scope中都被赋予了一个数字,从1开始。看其在rtl code中是第几个出现的generate就被赋值为几。这个数字对于命名和未命名的generate block都有。所有未命名的block都会被取一个叫genblk【n】的名字,n就是被赋予的数字。
很明显随着RTL规则的改动这些未命名的generate construct的名字也会改变。这样对于保证RTL层次化会有困难。因此建议总是对generate block进行命名。
小结一
Generate 结构在创建可配置的RTL的时候很有用。Generate loop能够让语句实例化多次,通过index来控制。而conditional generate能够选择性地实例化语句。最重要的是要记得对generate construct进行命名,这能够帮助简化层次对象以及代码维护。
全部0条评论
快来发表一下你的评论吧 !