Verilog's generate statement helps us write configurable synthesizable RTL, mainly for repetitive instantiation of modules or conditional instantiation of modules. This article will briefly review the verilog generate statement.
Type 1 of the Verilog generate statement
There are two different generate statement structures.
The Generate loop can instantiate a piece of code multiple times, controlled by an index variable.
The conditional generate statement can select one of the multiple pieces of code for instantiation. Conditional generate includes two different modes, if-generate and case-generate.
Verilog's generate statement is analyzed in the simulation/synthesis of the initial phase, which occurs after the HDL language parsing, before the simulation/synthesis. Therefore, all expressions contained in the generate structure must be deterministic expressions in the case of elasticity, and cannot contain dynamic variables. For example, statements in generate can be affected by parameters, but not by dynamic variables.
A verilog generate module creates a new hierarchy, just like instantiating a module.
The keywords generate and end generate (and begin/end) are not really necessary. If they are used, they define a region of generate. The region of the generate can only exist in the scope of the module.
Generate loop one
The syntax of the Generate loop is very similar to the for loop. The Index variable is first defined with the genvar keyword, and the index variable defined by genvar is used in elaboration. Genvar can exist inside or outside the generate region (defined by the generate-endgenerate keyword). The same genvar defined index can be used in multiple generate loops, as long as these loops are not nested with each other.
If the generate loop is expanded, in each generate loop instance, an implicit localparam is created with the same name and type as the index defined by genvar, and its value is the current number of loops. This localparam can be used to control the generated code.
Modules generated by Generate loop can be named or not named. If named, an array starting with the given name will be generated, and each array element is a module hierarchy. Some tools give warnings about unnamed generate loops, so it's best to name them.
The following example is a Gray code->binary converter that uses the verilog generate loop to generate:
Another example from verilog-2005 LRM illustrates how each verilog generate loop generates a new scope. Note that wire t1, t2, and t3 are all declared in the generate loop, and each loop iteration creates three t1, t2, and t3 that do not conflict at all. They are all used to connect the corresponding circuits in each of the different array modules. And notice the way these instantiated xor, and are named.
The generate loop can also be nested. Only a single generate/endgenerate is needed to wrap these nested generate loops. Each generate loop creates a new scope.
If-generate one
Conditional if-generate selects at most one generate block from a set of mutually exclusive generate blocks. Note that there is a choice of one at most, and one may not be selected. This judgment statement must also be a constant expression when it is used.
Like the generate loop, the conditional if-generate can be named or unnamed, with or without begin-end. It will also create a new scope and hierarchy. Because conditional generate selects code for at most one block, for mutually exclusive block code, the same name can be used in the same if-generate structure. This can help preserve the hierarchical name, no matter which block of code is selected. Different generator structures must have different names.
Case-generate one
Similar to if-generate. Case-generate selects at most one generate block from a set of mutually exclusive generate blocks. Its usage is the same as the traditional case statement.
Nested conditional generate blocks that are not cut with begin end are classified as a single scope/hierarchy. This avoids creating scope/hierarchy that doesn't change in the same module. The following example is an example of a nested conditional generate block
The generate structure selects at most one generate block called u1. The hierarchcal name of g1 is test.u1.g1. When nesting an if-generate structure, else always belongs to the nearest if. Note that any extra begin-end here will violate this direct nest rule, resulting in a new hierarchy.
Generate module named one
It is recommended to name the generate construct to simplify hierarchical indexing. And some tools will report an error to the unnamed generate block.
If not named, first, each generate construct is given a number in a scope, starting with 1. Seeing that it is the first occurrence of the rtl code, the generate is assigned a few. This number is available for both named and unnamed generate blocks. All unnamed blocks will be given a name called genblk[n], where n is the number assigned.
It is clear that the names of these unnamed generate constructs will change as RTL rules change. This will make it difficult to ensure RTL hierarchy. Therefore it is recommended to always name the generate block.
Summary one
The Generate structure is useful when creating configurable RTL. The Generate loop enables the statement to be instantiated multiple times and controlled by index. Conditional generate can selectively instantiate statements. The most important thing to remember is to name the generate construct, which can help simplify hierarchical objects and code maintenance.
Siren Horn,Alarm Horn,Police Horn
Chinasky Electronics Co., Ltd. , https://www.cctv-products.com