WeChat official account: FPGA power alliance
Blogger micro signal: fpga_start
WeChat official account link: generate block of verilog
Previous posts introduced the concepts of functions, tasks, macro definitions and parameters that can be used to simplify and optimize logical code. Today's blog introduces the synthesizer of simplified circuits - generate block.
The generating block is the code running in the integrated software. It helps to generate the circuit, but it will not be explicitly reflected in the circuit. We must learn to distinguish the verilog code of the circuit itself from these auxiliary codes!
The keyword of the generating block is "generate". The structural framework of a generating block is as follows:
generate operationsendgenerate
Among them, "operations" is the functional part of the generation block, which is used to describe the actually useful logic.
The functions of generating blocks are divided into three types: condition, case and loop, which are described below:
1. Conditions
The so-called condition is nothing more than an if else structure. Its syntax is:
generate if(condition) operations_1 else operations_2endgenerate
The contents of operations can be instantiated modules, verilog gate primitives, assign assignments, or always/initial process blocks.
Example of condition:
'define HIGH_SPEED 150module adder_4bits_genrerateif#(parameterCLOCK_FREQUENCY = 100)( input[3:0] a,b, input CLK,RST, output[3:0] sum, output c);generateif(CLOCK_FREQUENCY>'HIGH_SPEED) begin adder_4bits_pipelineADDER_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); endelse begin adder_4bitsCOM_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); endendgenerateendmodule
2,case
Just like the relationship between if and case, case is indispensable in the generating block. The syntax of the generated block of its case is as follows:
generate case(constant_express) value_1:operation_1 value_2:operation_2 ...... value_n:operation_n default:operation_default endcaseendgenerate
The content of operation is the same as if, which can be instantiated modules, verilog gate primitives, assign assignments, or always/initial process blocks.
case example:
'define HIGH_SPEED 150module adder_4bits_genrerateif#(parameterCLOCK_FREQUENCY = 100)(input[3:0] a,b,input CLK,RST,output[3:0] sum,output c); parameterHIGH_CHIP = 0; localparamHIGH_CLK = (CLOCK_FREQUENCY>'HIGH_SPEED)generatecase({HIGH_CLK,HIGH_CHIP}) 2'b11:begin adder_4bits_pipelineADDER_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); end 2'b10:begin adder_4bitsCOM_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); end 2'b01:begin adder_4bits_pipelineADDER_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); end 2'b00:begin adder_4bitsCOM_INST( .CLK(CLK), .RST(RST), .sum(sum), .c(c) ); endendcaseendgenerateendmodule
3. Circulation
The circular syntax of the production block is slightly more complex. Let's introduce its syntax structure first:
generategenvargenvar_variable;for(genvar_variable=start_value;loop_condition;circle_express) begin:instance_name operations endendgenerate
Among them, "start_value", "loop_condition" and "circle_express" have the same meaning as the circular statement for. "operations" is the operation of each cycle. It can only be variable declaration, module, verilog gate primitive, assign assignment or always/initial procedure block. "genvar" is the generated variable index keyword, which can be declared inside or outside the generate statement, but can only be used in the generate statement. The biggest difference is that the operation must be enclosed with "begin end", and the so-called index generation name of colon ":" and "instance_name" must be followed by begin. Here are three examples:
Generate for example 1: (assign)
module gray2bin1#(parameter SIZE = 8)(output [SIZE-1:0] bin,input [SIZE-1:0] gray,);genvar i;generatefor(i=0;i<SIZE;i=i+1) begin:bit assignbin[i] = ^gray[SIZE-1:i] endendgenerate endmodule
Generate for example 2: (always procedure block)
genvar i;generatefor(i=1;i<SIZE;i=i+1) begin:delay if(!rst) D[i]<=1'b0; else D[i]<=D[i-1]; endendgenerate
Generate for example 3: (module call)
genvar i;generatefor(i=0;i<SIZE;i=i+1)begin:ADDER adderADDER_INST( .CLK(CLK), .RST(RST), .in(din[i]), .out(dout[i]) );endendgenerate
reference:
1. verilog legend -- HDL code design based on circuit
2. verilog programming art