前言

之前使用generate和for时候一直糊里糊涂的使用,所以今天静下心来总结一下,顺便看看有哪些坑。

做一个模块,输入为多路data通过bit map型vld信号作为标记,输出为单路data,取多路信息中port num值最大的那一路数据,同时输出这一拍共多少路有数据;

信号 端口 位宽 含义
in_vld input PORT_NUM bitmap型vld信号,每一bit标志一路数据有效
in_data input PORT_NUM * DATA_WD 共PORT_NUM路数据,每路数据位宽为DATA_WD
out_vld output 1 输出数据有效
out_data output DATA_WD 输出数据
out_cnt output PORT_WD 共多少路输入vld有效计数
参数 含义
FLOP_FLAG 输出数据是否打拍
PORT_NUM 输入vld位宽
DATA_WD 单路数据位宽

OK,下面的归纳与实验都是基于这个场景。

generate归纳

generate使用

generate的主要用法就是两种,第一是构造循环结构,例如多次实例化某个模块,或者是进行连线;第二种是通过if-generate或者case-generate来在多个代码块之间最多选择一个作为综合的rtl代码。

通过循环结构来例化多个模块,一般的语法结构就是:

genvar j;
generatefor(i=0; i<3; i=i+1)begin: inst_rtlflow_proc U_PROC(clk, rst_n, data_vld, in_data);end
endgenerate

注意,generate for begin后面的名字是必须要有的,之后仿真器会通过这个标识来生成结构:

通过循环结构来简化wire连接,写法也是类似,例如我要把若干[DATA_WD -1:0]的数据拼成总线数据:

bit [DATA_WD -1:0]  data_arr [PORT_NUM];
bit [PORT_NUM*DATA_WD -1:0] data_in;genvar i;
generatefor(i=0; i<PORT_NUM; i=i+1)begin:gen_dataassign data_in[i*DATA_WD +:DATA_WD] = data_arr[i];end
endgenerate

当然了,以上都是可以综合的语法。

通过generate来选择代码块,例如在本次场景中,FLOP_FLAG决定输出是否要打拍,那么FLOP_FLAG为0和为1就是完全不同的电路,那么使用generate实现如下:

generateif(FLOP_FLAG)beginalways @(posedge clk)begin: FLOP_OUTif(~rst_n)beginout_vld  <= 0;out_data <= 0;out_cnt  <= 0;endelse beginout_vld <= vld;out_data <= data;out_cnt <= cnt;endendendelse beginalways @(*) begin: NO_FLOP_OUTout_vld = vld;out_data = data;out_cnt = cnt;endend
endgenerate

当FLOP_FLAG==1时,综合出的电路如下图:

当FLOP_FLAG==0时,综合出的电路如下图:

generate注意事项

1. 同一个文件中,generate for循环每次的循环变量名称不能重复,否则lint检查会报错,这也意味着generate不是一个完整的命名空间域吧;

generategenvar i;for(i=0; i<10; i=i+1)begin: RTL1...end
endgenerategenerategenvar i;for(i=0; i<10; i=i+1)begin: RTL2...end
endgenerate

2. generate 后跟begin end可以避免这一报错,但是verilog2005标准中已经明确禁止这种写法(generate begin-end),所以就乖乖的为每一个generate for定义一个genvar变量吧;

3. 把genvar定义在generate之外的话,两个generate都使用了这个变量,那么编译/lint/nlint都不会报错,甚至warning都不会报出,但是却可能引起仿真陷入死循环,也是不推荐,就乖乖定义genvar好了;

genvar i;
generatefor(i=0; i<PORT_NUM; i=i+1)begin:gen_dataassign data_in[i*DATA_WD +:DATA_WD] = data_arr[i];end
endgenerate
generatefor(i=0; i<PORT_NUM; i=i+1)begin:gen_data_tmpassign data_in_tmp[i*DATA_WD +:DATA_WD] = data_arr[i];end
endgenerate

4. genvar定义的变量不要用在always中循环使用,这种场景下乖乖在always里定义integer;

    genvar i; // failalways @(*)begin: gain_data//integer i;  //yesvld  = 0;data = 0;cnt  = 0;               for(i=0; i<PORT_NUM; i=i+1)beginif(in_vld[i])beginvld  = 1'b1;cnt  = cnt + {DATA_WD{1'b1}};data = in_data[DATA_WD*i +:DATA_WD];endendend

5. if-generate(或case-generate)的每一个if-else块也建议有一个名字,而不只是always块有名字。尽管在编译和lint检查时不会报错,但是可能会引发后续的formal报错,这是听一位大佬说的,不过说实话,我平时也不加这个名字;

6. generate中的代码块名字不要与文件中定义的信号名重复;

reg inst_rtl;
genvar j;
generatefor(i=0; i<3; i=i+1)begin:inst_rtlflow_proc U_PROC(clk, rst_n, data_vld, in_data);end
endgenerate

7. generate for里的参数必须直接调用,例如for(i=0; i<DEPTH; i=i+1),不能够出现运算例如for(i=0; i<DEPTH*5; i=i+1),如果一定需要这样做,那么要将参数提前处理好再拿来用;

8. generate for中支持data[3i+8 : 3i]的取值方式,但是单纯的for循环不支持,只支持data[3i +: 8]写法;

【Verilog】generate和for循环的一些使用总结(1)相关推荐

  1. verilog generate语法总结

    一.语法介绍 generate语句允许细化时间(Elaboration-time)的选取或者某些语句的重复.这些语句可以包括模块实例引用的语句.连续赋值语句.always语句.initial语句和门级 ...

  2. Verilog generate循环

    一:generate Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function, ...

  3. verilog generate 生成语句

    循环生成 1.generate不放在always块中,而是always块等包含在generate中. 2.generatefor 的名字放在for的begin后面,不要忘记加: 3.task不能放在g ...

  4. 关于genvar及generate用法的总结【Verilog】

    Abtract generate语句允许细化时间(Elaboration-time)的选取或者某些语句的重复.这些语句可以包括模块实例引用的语句.连续赋值语句.always语句.initial语句和门 ...

  5. Verilog中generate语法和作用

    Verilog中generate语句的用法 在Verilog-2001中新增了语句generate,通过generate循环,可以产生一个对象(比如一个元件或者是一个模块)的多次例化,为可变尺度的设计 ...

  6. 【Verilog 语法】~ if-else、case、for、generate、函数 function、任务 task、过程块、位宽计算、阻塞/非阻塞、时间尺度、存储器设计、

    文章目录 1. if-else 1.1 设计要点 2. case 2.1 概述 2.2 语法 2.3 注意事项 3. for 3.1 区别与其它语言的for循环 3.2 注意事项 4. generat ...

  7. [转载]关于generate用法的总结【Verilog】

    转载自http://www.cnblogs.com/nanoty/archive/2012/11/13/2768933.html Abtract generate语句允许细化时间(Elaboratio ...

  8. 关于generate用法的总结【Verilog】

    Abtract generate语句允许细化时间(Elaboration-time)的选取或者某些语句的重复.这些语句可以包括模块实例引用的语句.连续赋值语句.always语句.initial语句和门 ...

  9. 8.Verilog的for循环语句使用

    FPGA教程目录 MATLAB教程目录 -------------------------------------------------------------------------------- ...

最新文章

  1. 用 Python 和 OpenCV 检测图片上的条形码Detecting Barcodes in Images with Python and OpenCV
  2. Luogu P4168 [Violet]蒲公英 分块
  3. 学生信息管理系统问题集锦(一)
  4. linux ssh客户端乱码,Win10专业版下Open ssh客户端乱码咋办?
  5. centos7 搭建本地git_小白也能看懂,30 分钟搭建个人博客!
  6. linq to sql 查询操作(3):Insert/Update/Delete操作
  7. c语言吧五子棋纯干货注释,请帮我注释下这个五子棋程序
  8. DNF私服搭建的利弊关系
  9. 2021-04-26
  10. 《FLUENT 14流场分析自学手册》——导读
  11. 永久关闭iptables和selinux
  12. 骑士cms(74cms)个人版 整合UC
  13. 4.证券投资基金的监管
  14. 茶有真香 | 一款茶好不好喝自己说了才算
  15. 你是否了解APP耗电问题?深入探索 Android 电量优化,flutter插件推荐
  16. 怎么把wps转换成word
  17. xlwings使用笔记
  18. MOOS程序解析记录(7)pMarinePID解析
  19. C#之windous界面应用编程
  20. hdu 6447YJJ's Salesman 离散化+树状数组+DP

热门文章

  1. python爬取天猫_python scrapy 爬取天猫商品
  2. LED背光车载驱动IC 可支持48通道
  3. 转染诱导ips细胞实验操作
  4. 绘制文字(QFont字体)
  5. VBox 下win10 不能调节分辨率问题
  6. Qt QPushButton(一) 按钮进入、按下、抬起 背景转换
  7. 电荷泵(charge pump)原理
  8. window.parent和contentWindow
  9. python中webdriver_Python3中使用webdriver
  10. mathplotlib库学习笔记