【Verilog】generate和for循环的⼀些使⽤总结(1)
前⾔
之哲理句 前使⽤generate和for时候⼀直糊⾥糊涂的使⽤,所以今天静下⼼来总结⼀下,顺便看看有哪些坑。
做⼀个模块,输⼊为多路data通过bitmap型vld信号作为标记,输陌生人的英语 出为单路data,取多路信息中portnum值最⼤的那⼀路数据,同时输出这⼀拍共多少路有数据;
信号
端⼝
位宽
含义
bitmap型vld信号,每⼀bit标志⼀路数据有效
共PORT_NUM路数据,每路数
据位宽为DATA_WD
输出数据有效输出数据
共多少路输⼊vld有效计数
in_vldinputPORT_NUM
in_datainput
PORT_NUM*
DATA_WD1
DATA_WDPORT_WD
out_vld
out_data
out_cnt
参数
FLOP_FLAG
PORT_NUMDATA_WD
output
output
output含义
输出数据是否打拍
输⼊vld位宽单路数据位宽
OK,下⾯的归纳与实验都是基于这个场景。
generate归纳
generate使⽤
generate的主要⽤法就是两种,第⼀是构造循环结构,例如多次实例化某个模块,或者是进⾏连线;第⼆种是通过if-generate或者ca-
generate来在多个代码块之间最多选择⼀个作为综合的rtl代码。通过循环结构来例化多个模块,⼀般的语法结构就是:
genvarj;generate
for(i=0;i<3;i=i+1)begin:inst_rtl
flow_procU_PROC(clk,rst_n,data_vld,in_data);
endendgenerate
注意,generateforbegin后⾯的名字是必须要有的,之后仿真器会通过这个标识来⽣成结构:
通过循环结构来简化wire连接,写法也是类似,例如我要把若⼲[DATA_WD-1:0]的数据拼成总线数据:
bit[DATA_WD-1:0]data_arr[PORT_NUM];
bit[PORT_NUM*DATA_WD-1:0]data_in;
genvari;generate
for(i=0;i
assigndata_in[i*DATA_WD+:DATA_WD]=data_arr[i];
endendgenerate
当然了,以上都是可以综合的语法。
通过generate来选择代码块,例如在本次场景中,FLOP_产妇能吃螃蟹吗 FLAG决定输出是否要打拍,那么FLOP_FLAG为0和为1就是完全不同的电路,那么使⽤generate实现如下:
generate
if(FLOP_FLAG)begin
always@(podgeclk)begin:FLOP_OUT
if(~rst_n)begin
out_vld<=0;
out_data<=0;
out_cnt<=0;
end
elbegin
out_vld<=vld;
out_data<=data;
out_cnt<=cnt;
end
end
endelbegin
always@(*)begin:NO_FLOP_OUT
out_vld=vld;
out_data=data;
out_cnt=c奇峰罗列 nt;
end
endendgenerate
当FLOP_FLAG==1时,综合出的电路如下图:
当FLOP_FLAG==0时,综合出的电路如下图:
generate注意事项
1.同⼀个⽂件中,g二的倍数特征 eneratefor循环每次的循环变量名称不能重复,否则lint检查会报错,这也意味着generate不是⼀个完整的命名空间域吧;
generategenvari;
for(i=0;i<10;i=i+1)begin:RTL1
...
end
endgenerate
generategenvari;
for(i=0;i<10;i=i+1)begin:RTL2
...
endendgenerate
te后跟beginend可以避免这⼀报错,但是verilog2对对子大全 005标准中已经明确禁⽌这种写法(generatebegin-end),所以就乖乖的为每⼀个generatefor定义⼀个genvar变量吧;
3.把genvar定义在generate之外的话,两个generate都使⽤了这个变量,那么编译/lint/nlint都不会报错,甚⾄warning都不会报出,但是却可能引起仿真陷⼊死qq聊天记录在哪个文件夹 循环,也是不推荐,就乖乖定义genvar好了;
genvari;generate
for(i=0;i
assigndata_in[i*DATA_WD+:DATA_WD]=data_arr[i];
end
endgenerategenerate
for(i=0;i
assigndata_in_tmp[i*DATA_WD+:DATA_WD]=data_arr[i];
endendgenerate
定义的变量不要⽤在always中循环使⽤,这种场景下乖乖在always⾥定义integer;
genvari;//fail
always@(*)begin:gain_dat六年级语文课本 a
//integeri;//yes
vld=0;
data=0;cnt=0;
for(i=0;i
if(in_vld[i])beginvld=1'b1;
cnt=cnt+{DATA_WD{1'b1}};
data=in_data[DATA_WD*i+:DATA_WD];
end
endend
-generate(或ca-generate)的每⼀个if-el块也建议有⼀个名字,⽽不只是always块有名字。尽管在编译和lint检查时不会报错,但
是可能会引发后续的formal报错,这是听⼀位⼤佬说的,不过说实话,我平时也不加这个名字;te中的代码块名字不要与⽂件中定义的信号名重复;
reginst_rtl;
genvarj;generate
for(i=0;i<3;i=i+1)begin:inst_rtl
flow_procU_PROC(clk,rst_n,data_vld,in_data);
endendgenerate
tefor⾥的参数必须直接调⽤,例如for(i=0;i
tefor中⽀持data[3i+理财计划 8:3i]的取值⽅式,但是单纯的for循环不⽀持,只⽀持data[3i+:8]春晚明星 写法;
本文发布于:2023-04-12 20:26:52,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/fan/90/93016.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |