注:扫码关注小青菜哥哥的weixin公众号,免费获得更多优质的核探测器与电子学内容~
小青菜哥哥在前面几篇博文介绍了函数、任务、宏定义以及参数这些可以用来简化、优化逻辑代码的概念。今天这篇博客介绍的就是简化电路之集大成者——生成块generate。
生成块是综合软件里运行的代码,它辅助生成电路,但在电路里不会显式体现。我们一定要学会区别电路本身的verilog代码和这些辅助代码!
生成块的关键词是“generate”,一个生成块的结构框架如下:
generate
?????? operations
endgenerate
其中,“operations”是生成块的功能部分,用来描述实际有用的逻辑。
生成块的功能分为条件、case和循环三个类型,下面分别介绍:
1,条件
所谓条件,无非就是if-else这样的结构,其语法为:
generate
?????? if(condition)
????????????? operations_1
?????? else
????????????? operations_2
endgenerate
operations的内容可以是例化的模块、verilog门原语、assign赋值或者always/initial过程块。
条件例子:
'define HIGH_SPEED 150
module adder_4bits_genrerateif#(parameter CLOCK_FREQUENCY = 100)(
??input [3:0] a,b,
??input CLK,RST,
? output [3:0] sum,
? output c
);
generate
? ?if(CLOCK_FREQUENCY>'HIGH_SPEED)
???????????????????? begin
??????????????????????????? adder_4bits_pipeline ADDER_INST(
?????????????????????????????????? .CLK(CLK),
?????????????????????????????????? .RST(RST),
?????????????????????????????????? .sum(sum),
?????????????????????????????????? .c(c)
??????????????????????????? );
???????????????????? end
????????????? else
???????????????????? begin
??????????????????????????? adder_4bits COM_INST(
?????????????????????????????????? .CLK(CLK),
?????????????????????????????????? .RST(RST),
?????????????????????????????????? .sum(sum),
?????????????????????????????????? .c(c)
??????????????????????????? );
???????????????????? end
?????? endgenerate
endmodule
2,case
就和if与case的关系一样,生成块里少不了case来搭配。其case的生成块语法如下:
generate
?????? case(constant_express)
????????????? value_1:operation_1
????????????? value_2:operation_2
????????????? ……
????????????? value_n:operation_n
????????????? default:operation_default
?????? endcase
endgenerate
operation的内容和if是一样的,可以是例化的模块、verilog门原语、assign赋值或者always/initial过程块。
case例子:
'define HIGH_SPEED 150
module adder_4bits_genrerateif#(parameter CLOCK_FREQUENCY = 100)(
??????input [3:0] a,b,
??????input CLK,RST,
??????output [3:0] sum,
????? output c
);
?????? parameter HIGH_CHIP = 0;?????
?????? localparam HIGH_CLK = (CLOCK_FREQUENCY>'HIGH_SPEED)
?????? generate
????????????? case({HIGH_CLK,HIGH_CHIP})
???????????????????? 2'b11:begin
??????????????????????????? adder_4bits_pipeline ADDER_INST(
??????????????????????????? .CLK(CLK),
??????????????????????????? .RST(RST),
??????????????????????????? .sum(sum),
??????????????????????????? .c(c));
???????????????????? end
???????????????????? 2'b10:begin
??????????????????????????? adder_4bits COM_INST(
??????????????????????????? .CLK(CLK),
??????????????????????????? .RST(RST),
??????????????????????????? .sum(sum),
??????????????????????????? .c(c));
???????????????????? end
???????????????????? 2'b01:begin
??????????????????????????? adder_4bits_pipeline ADDER_INST(
??????????????????????????? .CLK(CLK),
??????????????????????????? .RST(RST),
??????????????????????????? .sum(sum),
??????????????????????????? .c(c));
???????????????????? end
???????????????????? 2'b00:begin
??????????????????????????? adder_4bits COM_INST(
??????????????????????????? .CLK(CLK),
??????????????????????????? .RST(RST),
??????????????????????????? .sum(sum),
??????????????????????????? .c(c));
???????????????????? end
????????????? endcase
?????? endgenerate
endmodule
3,循环
生产块的循环语法稍微复杂一些,我们先介绍其语法结构:
generate
?????? genvar genvar_variable;
?????? for(genvar_variable=start_value;loop_condition;circle_express)
????????????? begin:instance_name
???????????????????? operations
????????????? end
endgenerate
其中,“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;
?????? generate
?????? for(i=0;i<SIZE;i=i+1)
????????????? begin:bit
???????????????????? assign bin[i] = ^gray[SIZE-1:i]
????????????? end
?????? endgenerate?
endmodule
generate-for例子2:(always 过程块)
genvar i;
generate
?????? for(i=1;i<SIZE;i=i+1)
????????????? begin:delay
???????????????????? if(!rst)
??????????????????????? D[i]<=1'b0;
???????????????????? else
??????????????????????? D[i]<=D[i-1];
????????????? end
endgenerate?
generate-for例子3:(模块调用)
genvar i;
generate
for(i=0;i<SIZE;i=i+1)
?????? begin:ADDER
????????????? adder ADDER_INST(
???????????????????? .CLK(CLK),
???????????????????? .RST(RST),
???????????????????? .in(din[i]),
???????????????????? .out(dout[i])
???????????????????? );
?????? end
endgenerate?
今天的博文就到这里了,有问题请在小青菜哥哥的公众号留言,谢谢!