欢迎大家关注转发交流,不定时更新!
Verilog-2001新增了generate loops语法,其允许生成多个模块或者原语的实例,以及产生variables,nets,tasks,functions,continues assignments,initial procedures以及always 块等。当然generate进行module的实例化也可以通过if-else或者case进行条件判断然后生成。
为此,Verilog-2001新增了4个关键字:generate,endgenerate,genvar,localparam。genvar是一种存储正整数的新型变量,其与Verilog其他变量重要的不同点在于其能够在compile或者elaborate阶段再对genvar声明的变量进行赋值。
1.1、Verilog generate
通过generate-for语句实现多个模块的例化等,例如下面的例子,其通过例化门电路来实现多bits加法器。

[左上]在这里可能有同学会有疑问,generate-for结构和常规for循环有何不同?在这里我们举一个将格雷码转换成二进制码,来说明两者之间的主要区别。
格雷码转换成二进制码,正常情况下,我们以4bit格雷码转二进制码为例,其转换逻辑如下图所示:

对于上面的代码结构,我们如果能够通过for循环参数化实现,那代码的复用性及简洁性都能好很多,如果我们以for循环来进行实现可以写出如下代码,但是很不幸的是,对于常规for循环来说,Verilog和systemVerilog不允许使用变量索引范围进行部分选择,因此下面实例中的代码虽然在概念上是正确的,但是却编译不成功,我们用FPGA的编译器进行编译结果见下图所示,其提示i不是一个常数。


[左上]那是不是说说我们就不能按照上述的逻辑实现了呢?这个时候相同的代码结构,当我们用generate-for进行书写时将不存在这个问题,具体代码如下图所示,这其实就是generate-for的特点所在,在进行编译阶段通过genvar声明的变量会被指定,所以其对综合工具而已已经是一个明确的量,故能够综合实现没有问题。

[左上]在generate生成的loop结构内部,其实是有一个隐形的localparam声明,这个localparam与genvar保持相同的名字以及数据类型,故如果两个嵌套的generate loop结构,是不能使用同一个genvar变量的。例如下图所示的代码风格是禁止的。

[左上]generate loop代码结构中,generate和endgenrate关键字以及for循环后面的名字都是非必须的,如果for循环后面只有一行指令,那么begin和end关键字也非必须,即便如此这样的结构仍然是一个有效的generate块。
[左上]最后,我们看一个嵌套generate for结构中,每一个例化的instance具体是怎么命名的,每一层的循环由for循环begin关键字后面的命名确定,同一个循环层下面的instance则需要根据genvar value的值进行命名,例如对于instance N1,则其instance命名为:B1[0].N1和B1[1].N1

1.2、 generate 条件语句
generate条件语法主要包括if-generate和case-generate两种,主要是根据条件从备选块中选出最多一个进行实例化。例如下面generate-if实例,其根据a_width和b_width去决定例化各个乘法器module。在generate-if可以嵌套generate-case语句。