为了更加直观表现出使用generate的好处,接下来给出使用generate前后的代码描述。该设计实现的功能对信号dina进行20个时钟周期的延时以及对信号dinb进行25个时钟周期的延时。没有使用generate时的Verilog HDL描述如下所示:
`timescale 1ns / 1ps
/*******************************************************
Author : CrazyBird
Filename : delay_tap.v
Data : 2015-4-26
Description : delay of signal
********************************************************/
module delay_tap(
sys_clk,
rst_n,
dina,
dinb,
douta,
doutb
);
// parameter define
parameter DELAY_TAP20 = 20;
parameter DELAY_TAP25 = 25;
// input/output define
input sys_clk;
input rst_n;
input dina;
input dinb;
output douta;
output doutb;
// delay 20 clock period of dina
reg [DELAY_TAP20-1:0] dina_buf;
always @(posedge sys_clk or negedge rst_n)
begin
if(rst_n==1'b0)
dina_buf <= {(DELAY_TAP20){1'b0}};
else
begin
dina_buf[ 0] <= dina;
dina_buf[ 1] <= dina_buf[ 0];
dina_buf[ 2] <= dina_buf[ 1];
dina_buf[ 3] <= dina_buf[ 2];
dina_buf[ 4] <= dina_buf[ 3];
dina_buf[ 5] <= dina_buf[ 4];
dina_buf[ 6] <= dina_buf[ 5];
dina_buf[ 7] <= dina_buf[ 6];
dina_buf[ 8] <= dina_buf[ 7];
dina_buf[ 9] <= dina_buf[ 8];
dina_buf[10] <= dina_buf[ 9];
dina_buf[11] <= dina_buf[10];
dina_buf[12] <= dina_buf[11];
dina_buf[13] <= dina_buf[12];
dina_buf[14] <= dina_buf[13];
dina_buf[15] <= dina_buf[14];
dina_buf[16] <= dina_buf[15];
dina_buf[17] <= dina_buf[16];
dina_buf[18] <= dina_buf[17];
dina_buf[19] <= dina_buf[18];
end
end
assign douta = dina_buf[DELAY_TAP20-1];
// delay 25 clock period of dina
reg [DELAY_TAP25-1:0] dinb_buf;
always @(posedge sys_clk or negedge rst_n)
begin
if(rst_n==1'b0)
dinb_buf <= {(DELAY_TAP25){1'b0}};
else
begin
dinb_buf[ 0] <= dinb;
dinb_buf[ 1] <= dinb_buf[ 0];
dinb_buf[ 2] <= dinb_buf[ 1];
dinb_buf[ 3] <= dinb_buf[ 2];
dinb_buf[ 4] <= dinb_buf[ 3];
dinb_buf[ 5] <= dinb_buf[ 4];
dinb_buf[ 6] <= dinb_buf[ 5];
dinb_buf[ 7] <= dinb_buf[ 6];
dinb_buf[ 8] <= dinb_buf[ 7];
dinb_buf[ 9] <= dinb_buf[ 8];
dinb_buf[10] <= dinb_buf[ 9];
dinb_buf[11] <= dinb_buf[10];
dinb_buf[12] <= dinb_buf[11];
dinb_buf[13] <= dinb_buf[12];
dinb_buf[14] <= dinb_buf[13];
dinb_buf[15] <= dinb_buf[14];
dinb_buf[16] <= dinb_buf[15];
dinb_buf[17] <= dinb_buf[16];
dinb_buf[18] <= dinb_buf[17];
dinb_buf[19] <= dinb_buf[18];
dinb_buf[20] <= dinb_buf[19];
dinb_buf[21] <= dinb_buf[20];
dinb_buf[22] <= dinb_buf[21];
dinb_buf[23] <= dinb_buf[22];
dinb_buf[24] <= dinb_buf[23];
end
end
assign doutb = dinb_buf[DELAY_TAP25-1];
endmodule
如果当延时周期改变了,我们要对该设计修改的地方包括参数定义以及always过程块的内容,要是稍微复杂一点的大工程,代码量将非常多且很不好维护。接下来,看看generate是如何解决这些问题的,相应Verilog HDL描述如下所示:
`timescale 1ns / 1ps
/*******************************************************
Author : CrazyBird
Filename : delay_tap1.v
Data : 2015-4-26
Description : delay of signal
********************************************************/
module delay_tap1(
sys_clk,
rst_n,
dina,
dinb,
douta,
doutb
);
// parameter define
parameter DELAY_TAP20 = 20;
parameter DELAY_TAP25 = 25;
// input/output define
input sys_clk;
input rst_n;
input dina;
input dinb;
output douta;
output doutb;
// delay 20 clock period of dina
wire [DELAY_TAP20:0] dina_buf;
genvar i;
assign dina_buf[0] = dina;
generate
for(i=0;i<=DELAY_TAP20-1;i=i+1)
begin
always @(posedge sys_clk or negedge rst_n)
if(rst_n==1'b0)
dina_buf[i+1] <= 1'b0;
else
dina_buf[i+1] <= dina_buf[i];
end
endgenerate
assign douta = dina_buf[DELAY_TAP20];
// delay 25 clock period of dina
wire [DELAY_TAP25:0] dinb_buf;
genvar j;
assign dinb_buf[0] = dinb;
generate
for(j=0;j<=DELAY_TAP25-1;j=j+1)
begin
always @(posedge sys_clk or negedge rst_n)
if(rst_n==1'b0)
dinb_buf[j+1] <= 1'b0;
else
dinb_buf[j+1] <= dinb_buf[j];
end
endgenerate
assign doutb = dinb_buf[DELAY_TAP25];
endmodule
代码量是不是减少了很多,在大工程中它的优势将更加突出。另外,如果在本设计中改变延时周期,只需修改参数定义就行了,有没有感觉设计变得容易维护了?
总结:在设计中正确使用generate,一方面可使代码量变得简洁清晰,另一方面可使设计更加容易维护。