常用generate语句做三件事情转载学习
-
一个是用来构造循环结构,generate-for,用来多次实例,其中生成的实例可以是多个类型
(1)模块;
(2)用户定义原语;
(3)门级语句;
(4)连续赋值语句;
(5)initial和always。
-
一个是构造条件generate结构,用来在多个块之间最多选择一个代码块,条件generate结构包含if–generate结构和case–generate形式。
-
断言
其中关键字generate-endgenerate用来指定范围。
1.generate for 循环结构
使用时必须先在genvar声明中声明循环中使用的索引变量名,然后才能使用它。genvar声明可以是generate结构的内部或外部区域,并且相同的循环索引变量可以在多个generate循环中,只要这些环不嵌套。genvar只有在建模的时候才会出现,在仿真时就已经消失了。
Verilog中generate循环中的generate块可以命名也可以不命名。如果已命名,则会创建一个generate块实例数组。如果未命名,则有些仿真工具会出现警告,因此,最好始终对它们进行命名。
generate语法上的用法
generate-for语句(通常用于重复例化模块)
(1) 必须有genvar关键字定义for语句的变量。
(2)for语句的内容必须加begin和end(即使就一句)。
(3)for语句必须有个名字。
//通过循环结构来例化多个模块,一般的语法结构就是:
genvar j;
generate
for(i=0; i<3; i=i+1)begin: inst_rtl
//generate for begin后面的名字是必须要有的,之后仿真器会通过这个标识来生成结构:
flow_proc U_PROC(clk, rst_n, data_vld, in_data);
end
endgenerate
//把若干[DATA_WD -1:0]的数据拼成总线数据PPORT_NUM
bit [DATA_WD -1:0] data_arr [PORT_NUM];
bit [PORT_NUM*DATA_WD -1:0] data_in;
genvar i;
generate
for(i=0; i<PORT_NUM; i=i+1)begin:gen_data
assign data_in[i*DATA_WD +:DATA_WD] = data_arr[i]; //起始位位i*data_wd,位宽为data_wd
end
endgenerate
//generate for里的参数必须直接调用,例如for(i=0; i<DEPTH; i=i+1),不能够出现运算例如for(i=0; i<DEPTH*5; i=i+1)
generate循环的语法与for循环语句的语法很相似,区别主要是:
通常,generate for循环和普通 for循环之间的主要区别在于generate for循环正在为每次迭代生成一个实例。但博主通过观察电路图的方式认为两者再综合电路后没有不同。Verilog中关于for与generate for用法和区别的一点愚见
1.1 Verilog 可变的向量域选择
Verilog 支持可变的向量域选择,例如:
- [bit+: width] : 从起始 bit 位开始递增,位宽为 width。
- [bit-: width] : 从起始 bit 位开始递减,位宽为 width。
2.条件generate构造
详细的示例程序条件语句从很多的备选块中选择最多一个generate块,请注意,在这我说的是最多,因为有可能是一个也不选择的。条件必须为常量表达式
2.1 条件if-generate构造
generate
if(FLOP_FLAG)begin
always @(posedge clk)begin: FLOP_OUT
if(~rst_n)begin
out_vld <= 0;
out_data <= 0;
out_cnt <= 0;
end
else begin
out_vld <= vld;
out_data <= data;
out_cnt <= cnt;
end
end
end
else begin
always @(*) begin: NO_FLOP_OUT
out_vld = vld;
out_data = data;
out_cnt = cnt;
end
end
endgenerate
&empt;&empt;由于最多选择一个代码块,因此在单个的if-generate中以相同的名称命名所有的备用代码块是合法的.
2.2.case_generate构造
&empt;&empt;generate_case其实跟generate_if一样的,都是根据模块的参数(必须是常量)作为条件判断,来生成满足条件的电路,不同的地方仅仅是改成使用case 的语法而已。
示例
//如果generate它内部含always块,那么根据所含是组合或者时序逻辑选择不同赋值方式
module generate_case #(
parameter SEL = 1
)(
output [3:0] out
);
generate
case(SEL)
1: begin
assign out = 4'b0001;
end
2: begin
assign out = 4'b0010;
end
3: begin
assign out = 4'b0100;
end
default: begin
assign out = 4'b0000;
end
endcase
endgenerate
endmodule
3.断言和形式验证
verilog断言(SVA)语法
SV_Assertions断言(推荐阅读)
断言assertion被放在verilog设计中,方便在仿真时查看异常情况。当异常出现时,断言会报警。一般在数字电路设计中都要加入断言,断言占整个设计的比例应不少于30%。