Verilog语法之条件编译指令`ifdef, `ifndef,`else, `elsif, `endif

news2024/11/13 23:16:52

0、前言

        一般情况下,C语言中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译(conditional compile)。条件编译允许只编译源文件中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销,并提高程序的效率,可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。

        Verilog的编译和C语言的编译二者自然不可同日而语,具体到FPGA的开发,其条件编译可以通俗的理解为,根据条件选择性地将指定部分综合为电路,而未被指定部分则不综合成电路,这可以有效地减少电路面积和提高代码的复用性和灵活性。


1、一个小例子

        现在老板让我开发一个模块,功能是要能实现两个4bit输入的与、或、异或运算,但这三种运算不需要同时满足,也就是说在该模块的某次使用中或被调用中可能是使用或运算,也可能是使用与运算,具体是什么说不清楚,得看老板心情。

        这还不简单?针对与、或、异或运算写三条语句,再给它加个选择器就完事了,就像这样:

module op_test(
	input		[3:0]	in1,
	input		[3:0]	in2,
	input		[1:0]	sel,
	output	reg	[3:0]	out
);

wire	[3:0] out_and;
wire	[3:0] out_or;
wire	[3:0] out_xor;

assign out_and = in1 & in2;
assign out_or  = in1 | in2;
assign out_xor = in1 ^ in2;

always@(*)begin
	case(sel)
		2'd0:	out = out_and;
		2'd1:	out = out_or;
		2'd2:	out = out_xor;
		default:out = out_and;
	endcase
end

endmodule

       

        用vivado分析出来的电路是这样的:

        嗯,完美满足老板要求。嘻嘻。

        不料老板看了代码后,对着我劈头盖脸就是一顿臭骂:说了一次只会做一种运算,你给我弄3个运算模块干嘛?做或运算的时候,异或运算和与运算模块就站着看戏?节约资源懂不懂伐?性价比懂不懂伐?钞票懂不懂伐? 

        虽然我内心立马条件反射般地对老板竖了个中指,但是仔细想想老板说的话也确实有道理,所以只好再找找其他办法。

        找了半天还真给我找着了(不愧是我),这就是Verilog语法中的条件编译指令`ifdef, `ifndef,`else, `elsif, `endif。


2、条件编译指令

        条件编译指令可以根据指定条件来生成对应的电路,这可以减少电路面积并提高代码的复用性。

2.1、 `ifdef 的使用  

         `ifdef 需要搭配 `endif 使用,其使用方法为:

`ifdef <define_name>
   <statements>;
`endif

        比如上面的例子(采用与运算时):

`define	OP_AND			//指定条件为与运算,标识符建议使用大写
//`define	OP_OR			//指定条件为或运算,标识符建议使用大写
//`define	OP_XOR			//指定条件为异或运算,标识符建议使用大写

module op_test(
	input		[3:0]	in1,
	input		[3:0]	in2,
	output		[3:0]	out
);

`ifdef OP_AND
	assign out = in1 & in2;	
`endif

`ifdef OP_OR
	assign out = in1 | in2;	
`endif

`ifdef OP_XOR
	assign out = in1 ^ in2;	
`endif

endmodule

        用vivado分析出来的电路是这样的: 

        可以看到,在希望进行与运算时,综合出来的电路已经只有与运算模块了,异或运算模块、或预算模块和选择器模块都没有被综合出来,这有效地减少了电路面积。

        下一次,如果需要进行或运算,则只需要把  `define    OP_AND    这一句注释掉,再把这一句  `define    OP_OR  给有效化,此时就会综合出这样的电路(仅有或运算模块):

        异或运算模块的使用则不赘述。


2.2、 `else 与 `elsif 的使用

        在2.1节为了实现3个模块的条件编译,使用了三个`ifdef···`endif 块,这使得代码看起来很臃肿。就像你通常会使用 else if 和 else 来搭配 if 语句使用一样,你也可以使用  `else 与 `elsif 来搭配 `ifdef 使用。

        `else 与 `elsif 的使用方法:

`ifdef <define_name>
   <statements>;
`elsif <define_name>
   <statements>;
`else
   <statements>;
`endif

        所以,上面的例子可以改成这样的形式(采用与运算时):

`define	OP_AND			//指定条件为与运算,标识符建议使用大写
//`define	OP_OR			//指定条件为或运算,标识符建议使用大写
//`define	OP_XOR			//指定条件为异或运算,标识符建议使用大写

module op_test(
	input		[3:0]	in1,
	input		[3:0]	in2,
	output		[3:0]	out
);

`ifdef OP_AND
	assign out = in1 & in2;	
`elsif OP_OR
	assign out = in1 | in2;	
`else 
	assign out = in1 ^ in2;		
`endif

endmodule

2.3、 `ifndef 的使用

        `ifndef 的作用与 `ifdef 是相反的----当其后的标识符未被定义时,则编译后续的代码段,Verilog语法:

`ifndef <define_name>
   <statements>;
`endif

        举个例子,通过标识符 OP_OR 实现功能:如果OP_OR 未被定义,则实现两个输入的或运算;如果 OP_OR被定义,则实现两个输入的与运算。

       

        不实现或运算(即实现与预算)情况的代码如下:

`define	OP_OR			//指定条件为或运算,标识符建议使用大写

module op_test(
	input		[3:0]	in1,
	input		[3:0]	in2,
	output		[3:0]	out
);

`ifndef OP_OR
	assign out = in1 | in2;	
`else 
	assign out = in1 & in2;		
`endif

endmodule

        此时,定义了  OP_OR ,所以会执行第二句:assign out = in1 & in2;   

        此时综合出来的电路:

        稍微修改一下,实现或运算情况的代码如下(仅注释掉了 `define    OP_OR):

//`define	OP_OR			//指定条件为或运算,标识符建议使用大写

module op_test(
	input		[3:0]	in1,
	input		[3:0]	in2,
	output		[3:0]	out
);

`ifndef OP_OR
	assign out = in1 | in2;	
`else 
	assign out = in1 & in2;		
`endif

endmodule

        此时,未定义  OP_OR ,所以会执行第一句:assign out = in1 | in2;   

        综合出来的电路:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Canal-1-安装-代码

1总体简介 1 mysql需要开启binlog binlog分类 1.1&#xff09;statement: 语句级别&#xff0c;binlog 会记录每一次执行写操作的语句。相对于row模式节省空间&#xff0c;但是会产生数据不一致性&#xff0c;例如&#xff1a;update aa set create_timenew(); 如果用binlo…

Java学习笔记7.2.2 事件处理 - Swing常用事件

文章目录零、本讲学习目标一、Swing常用事件二、窗体事件&#xff08;一&#xff09;窗体事件概述&#xff08;二&#xff09;窗体事件类API概述&#xff08;三&#xff09;窗体事件使用方法&#xff08;四&#xff09;窗体事件案例演示三、鼠标事件&#xff08;一&#xff09;…

【进阶】C语言第一课:深度剖析数据在内存中的存储

目录 前言&#xff1a; 一、数据类型详细介绍&#xff1a; 1.相关知识回顾&#xff1a; 2.类型的基本归类&#xff1a; 整型家族&#xff1a; 浮点型家族&#xff1a; 构造类型&#xff1a; 指针类型&#xff1a; 空类型&#xff1a; 二、整形在内存中的存储&#xff1a; …

PS 更换证件照背景色

哈喽&#xff0c;各位小伙伴&#xff01;今天我们来学习一下如何更换证件照背景色&#xff1f; 常见证件照 常见的证件照一般有白色、蓝色和红色三种样式&#xff0c;我们拍证件照一般只拍一种&#xff0c;为了节省支出&#xff0c;其他两种颜色就需要我们自己调色处理了 蓝…

计算机毕业设计ssm+vue基本微信小程序的客户资源管理系统

项目介绍 基于Vue技术的客户资源管理系统是对客户的一些资料进行有效的管理, 它将企业的经营管理以客户为中心,通过系统管理员就可以轻松有效的对客户的信息进行操作管理。从而实现客户资料的一致性、准确性,查询的及时性等等。 该系统提供了客户管理、系统管理、合同管理、…

Java学习笔记7.1.2 初探Swing世界 - 布局管理器

文章目录零、本讲学习目标一、布局管理器二、边框布局管理器&#xff08;BorderLayout&#xff09;&#xff08;一&#xff09;边框布局管理器概述&#xff08;二&#xff09;边框布局管理器API文档&#xff08;三&#xff09;边框布局管理器使用方法&#xff08;四&#xff09…

Java项目:SSM在线物流综合管理平台系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;后台为管理员登录&#xff1b; 管理员角色包含以下功能 管理员登录,管理员管理,合作公司管理,车型信息,货物基本…

MongoDB 数据库安装详细教程

1. MongoDB 下载流程 &#xff08;急用&#xff09;直接抵达&#xff1a;Download MongoDB Community Server | MongoDB 打开MongoDB官网&#xff1a;MongoDB (点击进入) 下载完成之后双击打开会出现如下界面&#xff1a; 2. MongoDB 环境配置 通过刚刚的安装知道了MongoDB Se…

人工智能--决策树原理与代码实现、特征提取、回归决策树

决策树&#xff1a;本质就是一个拥有多个判断节点的树 1&#xff0c;熵 系统越有序&#xff0c;集中&#xff0c;熵值越低&#xff1b;系统越混乱&#xff0c;越分散&#xff0c;熵值越高 在这里的计算中&#xff0c;log2记为1&#xff0c;通常以2为底 2&#xff0c;决策树…

Matlab|基于粒子群优化算法及鲁棒MPPT控制器提高光伏并网的效率

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

SpringBoot中使用Easyexcel实现Excel导入导出功能(三)

导出的数据包含有图片 导出excel表格的数据包含有图片&#xff0c;这种场景比较少。通Easyexcel实现这样的需求&#xff0c;我认为最简便的方法就是使用前面提到的自定义转换器&#xff08;com.alibaba.excel.converters.Converter&#xff09;&#xff1b;假如有这样一个场景&…

mysql学习-- 聚合函数,group by理解与使用

文章目录聚合函数定义常用的聚合函数group by的使用使用单个列进行分组根据多个列进行分组having 的使用作用要求sql 语法sql92语法&#xff1a;sql99语法&#xff1a;sql语句的执行过程&#xff08;进理解为主&#xff09;&#xff1a;聚合函数 定义 作用一组数据&#xff0…

ArcGIS Pro为CAD设置投影

将CAD加载到GIS中&#xff0c;经常出现与GIS数据不能重合的问题。 现在的国空规划的数据基本都是CGCS2000&#xff0c;不重叠的原因不太可能是因为地理坐标系不统一&#xff0c;那极有可能就是ArcGIS的动态投影与CAD的带号没有统一。 如下图&#xff0c;左边为ArcGIS动态投影…

宠物之家网站大学生网页制作教程 学生HTML静态宠物网页设计作业成品 DIV布局简单动物网页制作代码

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

宝塔无法安装fileinfo扩展解决办法(小白篇)

宝塔无法安装fileinfo扩展解决办法&#xff08;小白篇&#xff09; 宝塔无法php安装fileinfo扩展的方法&#xff1a;手动安装 重装系统登录宝塔先不要安装其他软件&#xff0c;先设置swap是Linux下的虚拟内存&#xff0c;设置内存后先安装PHP版本&#xff0c;安装好PHP以后&…

Python实现数据结构与算法(三)链表

链表 为什么需要链表 顺序表的构建需要预先知道数据大小来申请连续的存储空间&#xff0c;而在进行扩充时又需要进行数据的搬迁&#xff0c;所以使用起来并不是很灵活。 链表结构可以充分利用计算机内存空间&#xff0c;实现灵活的内存动态管理。 链表的定义 链表&#xf…

html内联框架iframe

<!--iframe内联框架src&#xff1a;地址w-h&#xff1a;宽度高度 --> <iframe src"https://www.4399.com" frameborder"0" width"800px" height"800px"></iframe> 使用name属性&#xff1a; <!--回顾&#xff1…

Allegro如何创建差分对操作指导

Allegro如何创建差分对操作指导 Allegro可以在规则管理器里面进行差分对的创建,让两个网络以差分的形式布线,具体操作如下 打开规则管理器 选择Physical-net-All layers 选择两个需要创建差分对的网络,选择Create-Differential Pair 输入差分对的名字 选择Create 差分…

【MATLAB教程案例58】使用matlab实现yolov2网络目标检测功能与仿真分析

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 1.软件版本 2.yolo网络理论概述

Python画3D足球2

文章目录前情提要补点球形膨胀前情提要 足球是正五边形和正六边形拼接而成&#xff0c;由此形成的骨架结构&#xff0c;可通过切割正二十面体获得&#xff0c;所以画足球的第一步是画正二十面体&#xff1a;Python绘制正二十面体 在学会绘制正二十面体之后&#xff0c;就可以…