前面几篇博文介绍了函数、任务、宏定义以及参数这些可以用来简化、优化逻辑代码的概念。今天这篇博客介绍的就是简化电路之集大成者——生成块generate。
生成块是综合软件里运行的代码,它辅助生成电路,但在电路里不会显式体现。我们一定要学会区别电路本身的verilog代码和这些辅助代码!
生成块的关键词是“generate”,一个生成块的结构框架如下:
generateoperationsendgenerate
其中,“operations”是生成块的功能部分,用来描述实际有用的逻辑。
生成块的功能分为条件、case和循环这3个类型,下面分别介绍:
1,条件
所谓条件,无非就是if-else这样的结构,其语法为:
generateif(condition)operations_1elseoperations_2endgenerate
operations的内容可以是例化的模块、verilog门原语、assign赋值或者always/initial过程块。
条件例子:
'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)beginadder_4bits_pipelineADDER_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));endelsebeginadder_4bitsCOM_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));endendgenerateendmodule
2,case
就和if与case的关系一样,生成块里少不了case来搭配。其case的生成块语法如下:
generatecase(constant_express)value_1:operation_1value_2:operation_2……value_n:operation_ndefault:operation_defaultendcaseendgenerate
operation的内容和if是一样的,可以是例化的模块、verilog门原语、assign赋值或者always/initial过程块。
case例子:
'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:beginadder_4bits_pipelineADDER_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));end2'b10:beginadder_4bitsCOM_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));end2'b01:beginadder_4bits_pipelineADDER_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));end2'b00:beginadder_4bitsCOM_INST(.CLK(CLK),.RST(RST),.sum(sum),.c(c));endendcaseendgenerateendmodule
3,循环
生产块的循环语法稍微复杂一些,我们先介绍其语法结构:
generategenvargenvar_variable;for(genvar_variable=start_value;loop_condition;circle_express)begin:instance_nameoperationsendendgenerate
其中,“start_value”,“loop_condition”,“circle_express”具有和循环语句for一样的含义。“operations”是每次循环的操作,只能是变量声明、模块、verilog门原语、assign赋值或者always/initial过程块。“genvar”是生成的变量索引关键字,可以在generate语句里面声明,也可以在generate语句外面声明,但只能用于generate语句。最大的不同是操作一定要有“begin-end”括在内部,而且begin之后要有冒号“:”和“instance_name”这个所谓的生成索引的名字。下面举3个例子:
generate-for例子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:bitassignbin[i] = ^gray[SIZE-1:i]endendgenerateendmodule
generate-for例子2:(always 过程块)
genvar i;generatefor(i=1;i<SIZE;i=i+1)begin:delayif(!rst)D[i]<=1'b0;elseD[i]<=D[i-1];endendgenerate
generate-for例子3:(模块调用)
genvar i;generatefor(i=0;i<SIZE;i=i+1)begin:ADDERadderADDER_INST(.CLK(CLK),.RST(RST),.in(din[i]),.out(dout[i]));endendgenerate
参考文献:
1,verilog传奇——从电路出发的HDL代码设计
2,verilog编程艺术