Verilog语法之generate for、generate if、generate case

news/2024/11/29 1:44:49/

0、前言

        Verilog-2005中有3个generate 语句可以用来很方便地实现重复赋值和例化(generate for)或根据条件选择性地进行编译(generate if和generate case)等功能。接下来就一起看下这3个语句的应用场景和应用方法吧。


1、generate for

        假设我希望把2个输入a[4:0]和b[4:0]做一个异或操作,但是顺序要颠倒,也就是这样:

module xor_test(input	[4:0]	a,input	[4:0]	b,output	[4:0]	out
);assign	out[4] = a[4] ^ b[0];
assign	out[3] = a[3] ^ b[1];
assign	out[2] = a[2] ^ b[2];
assign	out[1] = a[1] ^ b[3];
assign	out[0] = a[0] ^ b[4];endmodule

        在vivado中分析出来是这样的:很简单就是两个输出的不同为做一个异或运算。

        vivado综合出来是这样的:用了几个LUT来实现异或功能。


1.1、应用场景

        上面的例子限于篇幅我只假设了输入为5bit的位宽,所以这样写并不会让人觉得有多麻烦,但是假想一下如果位宽变成10、20、100呢?那我手不写断去?

        当你需要进行一些重复性的工作时,比如多次例化同一模块、同一语句等,可以使用generate for语句来解放双手,节省工作量。当然你用脚本语言来生成或者直接用某些编辑器也能很快地实现这个功能,不过在这里我们就不提了。     

        上面的例子用generate for语句写是这样的:

module xor_test(input	[4:0]	a,input	[4:0]	b,output	[4:0]	out
);genvar i;										//定义常量作为重复判断条件generatefor (i = 0; i < 8; i = i + 1)				//重复条件begin: XOR_INST							//begin要起个名字assign	out[i] = a[i] ^ b[4-i];		//需要重复的语句end
endgenerateendmodule

        在vivado中分析出来是这样的:(与上面的方式一致)

        vivado综合出来是这样的: (仍然与上面的方式一致)

       

        这样看, generate for是个不错的提高效率的方案。当然,该语句不光可以对assign进行重复赋值,还适用以下场景:

                (1)模块module;(2)用户定义原语UDP;(3)门级语句;(4)连续赋值语句assign;(5)initial和always块。


1.2、格式

        generate for语句的一般用法:

// Declare the loop variablegenvar <name>;// Code for thegeneratefor (<initial_condition>; <stop_condition>; <increment>) begin// Code to executeendendgenerate

        如果你是一个基于xilinx的开发者,可以使用vivado自带的语法模板:

        (1)打开语法模板:

        (2)搜索generate:

        (3)把上图右侧的语句复制到你自己的代码里边。

        关于generate for语句的使用需要注意:

  • generate for 语句必须使用genvar关键字定义for循环变量
  • generate for 循环必须加 begin…end, 哪怕只有一句
  • 不要使用 i++这种C语言式的自增语句(Verilog没有i++这个语法),而是使用 i = i + 1
  • generate后不加begin,里面的语法:for循环、if…else…、case语句 后面的begin后面一定要加名字,且名字唯一,否则会导致无法比对通过的问题
  • 过多的generate会导致收集覆盖率缓慢,要注意使用

2、generate if

        generate if的使用场景和条件编译语句类似,比如你的代码中包含了一个加法模块和一个减法模块,对于2个输入a和b,希望使用POL来进行控制:如POL=1则进行加法,反之亦然----POL=1----out = a + b;POL=0----out = a - b。

        代码是这样写的:

module xor_test(input	[4:0]	a,input	[4:0]	b,output	[4:0]	out
);localparam	integer	POL = 1;		//根据POL的值来生成对应的电路generateif (POL == 1) begin: POL1assign	out = a + b;end else begin: POL0assign	out = a - b;end
endgenerateendmodule

        定义成POL = 1时会由vivado综合成一个加法器:

        定义成POL = 0时则会由vivado综合成一个减法器: 

        

        假如不使用generate if语法,则代码是这样的:

module xor_test(input		[4:0]	a,input		[4:0]	b,input				POL,output	reg	[4:0]	out
);always@(*)beginif(POL == 1)out = a + b;elseout = a - b;
endendmodule

        这样综合出来的就是加法电路和减法电路一起: 

        使用generate if可以根据需要来灵活地生成对应电路,不会浪费资源,适用于某些根据特定需求来实现电路的场景。而不使用该语句则会把所有潜在的电路均综合出来,会使电路面积增大,但是灵活性却较高。

        这是vivado自带的语法模板:

   generateif (<condition>) begin: <label_1><code>;end else if (<condition>) begin: <label_2><code>;end else begin: <label_3><code>;endendgenerate

3、generate case

        generate case和generate if作用上是差不多的,都是用于选择性综合电路,区别就是if语句和case语句的区别,如果你会用其中一个,那另一个也很简单,模板如下:

   generatecase (<constant_expression>)<value>: begin: <label_1><code>end<value>: begin: <label_2><code>enddefault: begin: <label_3><code>endendcaseendgenerate

        上面的例子照着改就是这样了:

module xor_test(input	[4:0]	a,input	[4:0]	b,output	[4:0]	out
);localparam	integer	POL = 1;		//根据POL的值来生成对应的电路generatecase(POL)1'b1: begin: POL1assign	out = a + b;end1'b0: begin: POL0assign	out = a - b;enddefault:begin:	DEFAULT end	endcase
endgenerateendmodule

  • 📣博客主页:wuzhikai.blog.csdn.net
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵!
  • 📣您有任何问题,都可以在评论区和我交流📞!
  • 📣创作不易,您的支持是我持续更新的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!


http://www.ppmy.cn/news/2522.html

相关文章

Laravel 某个固定数据排序在列表顶部sql查询(自定义排序)

业务需要列表中某个固定用户数据处于列表顶部&#xff0c;该用户author状态有多个值&#xff08;例如&#xff1a;1-999&#xff09;&#xff0c;需要置于顶部的为中间的某个值&#xff08;例如&#xff1a;author68&#xff09; 实现方式&#xff1a; 1、判断 author的值是不…

Web服务器通信原理

电脑&#xff1a; Windows 系统 微软开发 闭源 Linux 开源的系统&#xff08;无数的子系统&#xff09; Mac os 苹果系统 WEB 安全 > WEB的安全&#xff08;网站安全&#xff09; 服务器&#xff1a; 就是一台不关机的电…

Properties类的使用

Properties类是一个配置文件类&#xff0c;主要作用就是用来封装配置文件&#xff0c;将配置文件加载成为一个Properties对象。 注意&#xff1a;Properties类一般用来加载 .properties配置文件 首先看一下.properties配置文件的样子 driverClassNamecom.mysql.cj.jdbc.Drive…

LeetCode刷题复盘笔记—一文搞懂完全背包之139. 单词拆分问题(动态规划系列第十六篇)

今日主要总结一下动态规划完全背包的一道题目&#xff0c;139. 单词拆分 题目&#xff1a;139. 单词拆分 Leetcode题目地址 题目描述&#xff1a; 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意&#xff1a;…

字符串处理【AC自动机】 - 原理 AC自动机详解

字符串处理【AC自动机】 - 原理 AC自动机详解 AC自动机&#xff08;Aho-Corasick automaton&#xff09;在1975年产生于贝尔实验室&#xff0c;是著名的多模匹配算法。 学习AC自动机&#xff0c;要有KMP和Trie&#xff08;字典树&#xff09;的基础知识。 KMP是单模匹配算法&a…

还记得上学时每周要换座位吗?第四组换到第一组、第一组换到第二组……现在用一个字母表示一个组,请你计算经历n周之后座位的情况。

还记得上学时每周要换座位吗&#xff1f;第四组换到第一组、第一组换到第二组…… 现在用一个字母表示一个组&#xff0c;请你计算经历n周之后座位的情况。 解析&#xff1a; //约瑟夫问题 #include<iostream> (720)#include<string> #include<algorithm&…

第十七章 优先队列优化Dijkstra算法

第十七章 优先队列优化Dijkstra算法一、普通dijkstra算法的缺陷1、选出最小距离的过程&#xff1a;2、松弛所有点的过程&#xff1a;二、如何优化1、代码模板&#xff08;1&#xff09;问题&#xff1a;&#xff08;2&#xff09;模板&#xff1a;2、详细解读三、优化分析1、使…

Logistic回归

通常&#xff0c;Logistic回归用于二分类问题&#xff0c;例如预测明天是否会下雨。当然它也可以用于多分类问题. Logistic回归是分类方法&#xff0c;它利用的是Sigmoid函数阈值在[0,1]这个特性。Logistic回归进行分类的主要思想是&#xff1a;根据现有数据对分类边界线建立回…