在这篇文章《从几个简单例子聊聊Verilog的参数化设计(parameter、localparam和`define)》中已经讨论过 `define 的一些用法,但不太深入,所以今天再说道说道。

在日常的编码过程中,常常碰到一个参数会被到处调用的情况,比如时钟的定义和调用:

//假设时钟为20ns

always # (20/2)clk1 = ~clk1;        //场景1,使用到时钟20

always # (20/2)clk2 = ~clk2;        //场景2,使用到时钟20

always # (20/2)clk3 = ~clk3;        //场景3,使用到时钟20

always # (20/2)clk4 = ~clk4;        //场景4,使用到时钟20

在调试过程中,如果时钟参数从20ns改成了10ns,则上面这段代码需要改动的地方就会多达5处。很明显,时钟参数被调用的情况越多,则改动代码越麻烦。

宏定义 `define 提供用一个相对简单的文字来表示一大段真正有意义的文字作用。换句话说,就是综合软件见到定义的宏,就用这个宏代表的文字替代这个宏的位置。之后,综合软件再按照替代之后的代码来综合出电路。

简单而言,宏定义就是起到一个替换的作用。它并不会使代码优化,但会使得代码的规模变小,并能够有效提高调试的效率和程序的可复用性。

这种情况下可以使用`define来定义一个时钟宏:

`define clk_period 20                                      //定义时钟宏clk_period

always # (`clk_period/2)clk1 = ~clk1;        //场景1,使用到时钟20

always # (`clk_period/2)clk2 = ~clk2;        //场景2,使用到时钟20

always # (`clk_period/2)clk3 = ~clk3;        //场景3,使用到时钟20

always # (`clk_period/2)clk4 = ~clk4;        //场景4,使用到时钟20

`define的一般格式:

`define macro_name(formal_argu_list) macro_text

  • `define 是宏定义语法的标志,注意符号 `
  • macro_name 是给这个宏定义起的名字,需符合verilog的起名规则
  • macro_text 是宏定义被综合软件重新替代的内容
  • formal_argu_list是宏定义可能的输入参数,里面可以有多个输入。这些变量可以取代macro_text里对应的内容,当不需要参数时,则可以省略这一项

比如用 clk_period 这个文本来替换时钟20ns:

`define clk_period 20           //定义时钟宏clk_period

这相当于告诉综合软件,在程序中遇到的 `clk_period 时均等同于 20。定义宏语句的最后是没有分号 ; 的,如果不小心加了分号,那么这个分号则会被视为“macro_text”的一部分而参与替代工作。

宏定义被调用的格式是:

`macro_name(formal_argu_list)

比如调用上面定义的宏clk_period:

always # (`clk_period/2)clk1 = ~clk1;

请注意符号

`undef 的作用比较简单,就是取消先前定义的文本宏的定义,这意味着从宏定义开始到 `undef 这一句才是宏定义的作用域,这样可以用来精准地控制宏定义的适用范围,其一般格式:

`undef text_macro_identifier

比如解除上面定义的时钟宏:

`undef clk_period

通过上面这一句,就可以精准地把宏定义clk_period的作用范围控制在自己想实现的范围内,不然默认情况下该宏定义的范围则为定义开始的语句到文件尾。

`define用法的一些细节总结:

(1)宏名建议用大写字母表示,以便与变量名进行区分

此项仅为编码习惯,具体请以你的编码规范为准。

(2)'define定义既可以在模块内部定义,也可以在模块外部定义

定义的有效范围为定义之后到本文件结束或遇到 `undef 。通常,'define命令写在模块定义的外面,作为程序的一部分,在此代码内有效。

(3)在引用已定义的宏名时,必须在宏名前面加上符号 `

` 是英文输入法下ESC键下的那个键。

(4)宏定义不是verilog语句,不必在行末加分号

如果加了分号 ; ,则分号 ; 会被视为替代文本的一部分。

(5)宏名和宏内容尽量在同一行中进行声明。如果宏内容中包括注释行,注释行不会被置换

如果需要多行来指定文本,换行符必须在前加反斜杠(\)。第一个不带反斜杠的换行符将结束宏文本。

(6)只对那些确实需要全局定义的而且不会被其它设计更改的标识符才使用宏定义

尽量不要对那些只后在模块内使用的常量使用宏定义,这种情况更应该用localparam定义。

(7)为宏文本指定的文本不应被拆分为以下词法标记:注释、数字、字符串、标识符、关键词、操作符

比如这样的宏定义就是非法的,因为它把字符串拆分了。

`define first_half "start of string
        $display(`first_half end of string");

(8)尽量把所有的宏定义放到一个宏定义文件(例如global_define.v),这样可以更高效地管理多个宏定义

在稍微复杂一点的FPGA工程设计中,难免会出现数个module,一般是推荐一个module使用一个文件管理,所以一般的FPGA工程会有数个文件。假设工程中存在大量参数是多个module都需要使用到的,比如VGA时序相关参数。这样我们就可以单独使用一个文件(命名为:global_define.v)来定义这些参数:

//行同步参数定义
        `define        H_SYNC         10'd96         //行同步
        `define        H_BACK         10'd40         //行时序后沿
        `define        H_LEFT          10'd8           //行时序左边框
        `define        H_VALID         10'd640       //行有效数据
        `define        H_RIGHT        10'd8           //行时序右边框
        `define        H_FRONT       10'd8           //行时序前沿
        `define        H_TOTAL        10'd800       //行扫描周期

1、把所有宏定义放到一个宏定义文件(global_define.v);

2、在某个文件需要使用这些参数时,需要使用该指令--`include "global_define.v" 来将该宏定义文件调用;

3、在需要使用到具体的宏时,直接使用,但是要记得加 ,比如: ` H_SYNC     。

Verilog语法之`define、`undef相关推荐

  1. Verilog语法和典型电路

    这里写目录标题 Verilog语法知识 Q:锁存器 Q:D触发器 Q:消除毛刺 Q:同步复位和异步复位 Q:边沿检测 Q:握手信号 Q:脉冲展宽(单bit慢采快) Q:二进制与格雷码的转换 Q:二进制 ...

  2. 【Verilog 语法】~ 关键字、运算符、数据类型、缩位运算、三态门设计、可综合、VHDL 的结构、VHDL:WAIT 语句格式、原语、编译预处理

    本章目录: 1. 关键字 2. 运算符 2.1 分类 2.1.1 按其功能分类 2.1.2 按其所带操作数的个数分类 2.1.2.1 举例 2.2 优先级 3. 数据类型 1) wire 型 2) r ...

  3. 预处理命令 宏定义 #define #undef

    预处理命令 源程序中以#开头的行称为预处理指令. 预处理指令并不是C语言的语法成分,而是传给编译程序的指令. 包括: 宏定义 #define #undef 文件包含 #include 条件编译 #if ...

  4. FPGA 40 专题 verilog语法编程规范

    FPGA 40 专题 verilog语法编程规范 在这里主要是给自己写一个备忘录,加强个人记忆. 详细可以参考地址1:https://www.runoob.com/w3cnote/verilog2-c ...

  5. [转]verilog语法学习心得

    verilog语法学习心得 1.数字电路基础知识: 布尔代数.门级电路的内部晶体管结构.组合逻辑电路分析与设计.触发器.时序逻辑电路分析与设计 2.数字系统的构成: 传感器  AD  数字处理器  D ...

  6. Verilog 语法入门知识

    Verilog 语法入门知识 一.变量类型 ①数值 数值表示采用 <二进制位数>'<数值表示的进制><数值>的结构. 其中进制可以为b.o.d.h分别代表二.八.十 ...

  7. Verilog语法-005—宏定义

    Verilog语法-005-宏定义 1.Verilog宏定义-`ifdef `ifndef `ifdef FOR_FPGA //如果定义了FOR_FPGA宏,则会执行如下 语句/或者没有语句 `els ...

  8. 【系统设计】Verilog语法及示例(2)

    参考Verilog语法 | 教程 (ustc.edu.cn) 1.7 D触发器 D触发器是一个具有记忆功能.具有两个稳定状态的信息存储器件,是构成时序逻辑的最基本逻辑单元.其具有两个稳定状态,即&qu ...

  9. verilog语法学习目录

    verilog语法实例学习(1) Verilog中注释 Verilog代码中的信号 标识符 信号的值 Verilog中的数字 Verilog中的参数 verilog语法实例学习(2) 线网类型 变量类 ...

最新文章

  1. python组成不重复的三位数是多少_Python输出由1,2,3,4组成的互不相同且无重复的三位数...
  2. Scratch青少年编程能力等级测试模拟题(三级)
  3. “诺奖摇篮”贝尔实验室:从辉煌到衰败的百年沉浮
  4. css3常用方法以及css3选择器
  5. 【C语言】(for循环嵌套)找出1000以内的水仙花数
  6. 作家如何利用Git更好地完成工作
  7. JPM Coin三部曲 (上) :深入理解摩根幣的運作
  8. 苹果sf字体_原来苹果偷偷爱了这些字体
  9. Khronos关于WebGL最新进展
  10. PCB布局布线注意事项
  11. An Introduction to Be-trees and Write Optimization 学习笔记
  12. github注册,使用方法
  13. 3DMAX绘室内装修三维效果图
  14. 使用Wamp在win7上搭WEB服务器
  15. asp毕业设计——基于asp+access的毕业生信息管理系统设计与实现(毕业论文+程序源码)——毕业生信息管理系统
  16. 【题目】用下面的无穷级数公式计算π的值:π=4 - 4/3 +4/5 - 4/7 + 4/9 - 4/11+...打印一张表,分别显示前1项到前100项时计算出的π的近似值。
  17. 无法连接服务器——CMNET与CMWAP的区别
  18. botley编程机器人测评_资深玩家:孩子能用灵跃机器人学编程?!「视频测评」下...
  19. 在Linux中配置vsftpd
  20. linux mmap 函数详解,Linux之mmap函数简介

热门文章

  1. R语言计算回归模型残差平方和(Residual Sum of Squares)实战,并基于残差平方和比较模型优劣
  2. Emacs 主题设置
  3. IE6,IE7,IE8 css bug汇总以及兼容解决方法
  4. 深入解析AAVE智能合约:存款
  5. PlayMaker插件使用
  6. javamail——邮件发送
  7. CT的原始图像.dcm文件的读取
  8. 独家 | 大数据与AI技术助力金融科技:百融金服的探索实例
  9. USBCNC简明教程
  10. Spring Boot 中的热部署方式总结