0
点赞
收藏
分享

微信扫一扫

25,verilog之generate生成块


微信公众号:FPGA动力联盟

​​

前面几篇博文介绍了函数、任务、宏定义以及参数这些可以用来简化、优化逻辑代码的概念。今天这篇博客介绍的就是简化电路之集大成者——生成块generate。

生成块是综合软件里运行的代码,它辅助生成电路,但在电路里不会显式体现。我们一定要学会区别电路本身的verilog代码和这些辅助代码!

生成块的关键词是“generate”,一个生成块的结构框架如下:

generate
operations
endgenerate

其中,“operations”是生成块的功能部分,用来描述实际有用的逻辑。

生成块的功能分为条件、case和循环这3个类型,下面分别介绍:

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
#(parameterCLOCK_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_pipelineADDER_INST(
.CLK(CLK),
.RST(RST),
.sum(sum),
.c(c)
);
end
else
begin
adder_4bitsCOM_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#(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)
generate
case({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)
);
end
endcase
endgenerate
endmodule

3,循环

生产块的循环语法稍微复杂一些,我们先介绍其语法结构:

generate
genvargenvar_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
assignbin[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
adderADDER_INST(
.CLK(CLK),
.RST(RST),
.in(din[i]),
.out(dout[i])
);
end
endgenerate

参考文献:

1,verilog传奇——从电路出发的HDL代码设计

2,verilog编程艺术


举报

相关推荐

0 条评论