使用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示意图
模块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```





