使用generate編碼參數(shù)化的時序邏輯Verilog
掃描二維碼
隨時隨地手機看文章
編碼不同參數(shù)的時序邏輯代碼非常重要,這樣的代碼風格更加結(jié)構(gòu)化。
通用寄存器模塊的Verilog代碼
寄存器中的數(shù)據(jù)寬度是可以變化的主要參數(shù)。因此,數(shù)據(jù)寬度可以被視為“參數(shù)”。通用代碼可以取數(shù)據(jù)寬度的任何值。如果寬度為1,那么它將變成一個簡單的D觸發(fā)器。代碼如下
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
一般延遲模塊
當在復雜的設(shè)計中我們需要不同的延遲時,通用延遲塊非常有用。在某些階段,我們可能需要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是之前定義的,它在這里用于實現(xiàn)一拍延遲的觸發(fā)器。如果我們需要4個時鐘周期的延遲,那么我們將需要4個regN模塊。如果參數(shù)D的值為4,則“generate”命令將生成4個regN塊。模塊生成將使用“genvar”命令基于一個名為“p”的變量完成。
需要注意的是,genvar變量的名稱和參數(shù)的名稱不應該相同。如果一個參數(shù)名稱是N,genvar變量是n,那么代碼將合成實際所需的結(jié)構(gòu)。
一般計數(shù)器模塊
在復雜的設(shè)計中,有時也需要通用計數(shù)器模塊,以便一個verilog代碼可以在任何地方使用。下面寫有一個通用計數(shù)器模塊。
這個計數(shù)器可以作為加法計數(shù)器實現(xiàn),也可以作為減法計數(shù)器實現(xiàn)。
(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```





