25. generate block of verilog

Posted by shadowq on Sun, 23 Jan 2022 22:34:12 +0100

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

Topics: Verilog