一:generate 的作用
1)构造循环结构,用来多次实例化某个模块
2)构造条件generate结构,用来在多个块之间最多选择一个代码块,条件generate结构包含if--generate结构和case--generate形式。
3) 断言
generate 循环结构
generate循环的语法与for循环语句的语法很相似。但是在使用时必须先在genvar声明中声明循环中使用的索引变量名,然后才能使用它。genvar声明的索引变量被用作整数用来判断generate循环。genvar声明可以是generate结构的内部或外部区域,并且相同的循环索引变量可以在多个generate循环中,只要这些环不嵌套。genvar只有在建模的时候才会出现,在仿真时就已经消失了。
在“展开”生成循环的每个实例中,将创建一个隐式localparam,其名称和类型与循环索引变量相同。它的值是“展开”循环的特定实例的“索引”。可以从RTL引用此localparam以控制生成的代码,甚至可以由分层引用来引用。Verilog中generate循环中的generate块可以命名也可以不命名。如果已命名,则会创建一个generate块实例数组。如果未命名,则有些仿真工具会出现警告,因此,最好始终对它们进行命名。
module alu( input a,b, output sum,count); assign sum = a + b ; assign cout = a & b ; endmodule module my_design #(parameter N=4) (input [N-1:0] a,b, output [N-1:0] sum,cout); genvar i ; generate (optional) for( i = 0 ; i < N ; i++) begin: gen alu alu_inst (a[i] , b[i] , sum[i] , cout[i] ); end endgenerate endmodule
二、prameter 作用
Verilog中通过使用parameter可以在调用模块时修改模块里面的常数参数,提高模块的复用性,在模块调用时将参数传入模块。
以一个二选一MUX(选择器)为例
module Mux2_1 #(parameter WIDTH=2) (in1,in2,sel,out); //parameter WIDTH=2; input[WIDTH-1:0] in1; input[WIDTH-1:0] in2; input sel; output[WIDTH-1:0] out; assign out=sel?in1:in2; endmodule
顶层模块在调用Mux2_1时,可以在外部修改参数
module ParaDemo(in1,in2,sel,out); parameter WIDTH=4; input[WIDTH-1:0] in1; input[WIDTH-1:0] in2; input sel; output [WIDTH-1:0] out;
Mux2_1 #(WIDTH) //此时Mux2_1中WIDTH值=4
u_mux2_1(
.in1(in1),
.in2(in2),
.sel(sel),
.out(out));
endmodule
如果是一个计数器模块,要对参数化的信号count进行复位和+1的赋值操作,位宽声明如下:
module counter #(parameter WIDTH=16) ( clk,rst_n,count) input clk; input rst_n; output[WIDTH-1:0] count; always@(posedge clk or negedge rst_n)begin if(!rst_n) count<= 0; //赋0语句 或count<=‘b0 ‘之前不需要带位宽; 如果要赋全1: count <= -1; else count <= count + {(WIDTH-1){1'b0},{1'b1}}; end endmodule