使用generate编码参数化的时序逻辑Verilog

编码不同参数的时序逻辑代码非常重要,这样的代码风格更加结构化。

通用寄存器模块的Verilog代码

寄存器中的数据宽度是可以变化的主要参数。因此,数据宽度可以被视为“参数”。通用代码可以取数据宽度的任何值。如果宽度为1,那么它将变成一个简单的D触发器。代码如下

input [N-1:0] a;
output reg [N-1:0] y;
input clk,reset;
 
always @(posedge clk)
if (reset)
y <= 0;
else
y <= a;
endmodule

一般延迟模块

当在复杂的设计中我们需要不同的延迟时,通用延迟块非常有用。在某些阶段,我们可能需要4个时钟周期的延迟,在另一个阶段,我们可能需要9个时钟周期的延迟。

因此,我们不应该编写单独的模块。一般延迟模块如下所示

parameter D = 4)(clk,reset,a,aN);
input clk,reset;
input [N-1:0] a;
output [N-1:0] aN;
wire [N-1:0] tmp [D:0];
assign tmp[0] = a;
generate
genvar p;
for (p = 1; p <= D; p = p+1) begin: General_delay
regN #(N) rg(tmp[p],clk,reset,tmp[p-1]);
end
endgenerate
assign aN = tmp[D];
endmodule

D = 4的一般延迟块的RTL示意图

28b7e8b4b71804158e054e0e73f083d3.jpeg

模块regN是之前定义的,它在这里用于实现一拍延迟的触发器。如果我们需要4个时钟周期的延迟,那么我们将需要4个regN模块。如果参数D的值为4,则“generate”命令将生成4个regN块。模块生成将使用“genvar”命令基于一个名为“p”的变量完成。
需要注意的是,genvar变量的名称和参数的名称不应该相同。如果一个参数名称是N,genvar变量是n,那么代码将合成实际所需的结构。

一般计数器模块

在复杂的设计中,有时也需要通用计数器模块,以便一个verilog代码可以在任何地方使用。下面写有一个通用计数器模块。

这个计数器可以作为加法计数器实现,也可以作为减法计数器实现。

(count,data,load,en,clk,reset,tc,lmt
    );
output [N-1:0] count;
output tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
generate
case(up)
1'b0 : counterupN #(N) u0(count,data,load,en,clk,reset,tc,lmt);
1'b1 : counterdnN #(N) u1(count,data,load,en,clk,reset,tc,lmt);
endcase
endgenerate
endmodule

module counterupN #(parameter N = 10)(count,data,load,en,clk,reset,tc,lmt);
output [N-1:0] count;
output reg tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
reg [N-1:0] count;

always @(posedge clk)
if (reset) begin
  count <= 1'b0 ;
end else if (load) begin
  count <= data;
end else if (en)
  count <= count + 1'b1;
else count <= count;
always @*
if (count ==lmt)
tc=1;
else tc=0;
endmodule

module counterdnN #(parameter N = 10)(count,data,load,en,clk,reset,tc,lmt);
output [N-1:0] count;
output reg tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
reg [N-1:0] count;

always @(posedge clk)
if (reset) begin
  count <= 1'b0 ;
end else if (load) begin
  count <= data;
end else if (en)
  count <= count - 1'b1;
else count <= count;
always @*
if (count ==lmt)
tc=1;
else tc=0;
endmodule```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值