Verilog HDL 编译器指令

复杂一点的系统在进行设计或者验证时,都会用到一些编译器指令,那么什么是编译器指令?

Verilog HDL编译器指令由重音符(')开始。在Verilog 语言编译时,特定的编译器指令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令。不完整的标准编译器指令如下:

下面分解一下,每个指令单独说明一下:

’define和’undef

1.’define指令

’define指令用于文本替换,它很像C语言中#define指令。它生成一个文本宏。该指令既可以在模块内部定义,也可以在模块之外定义。一旦编译了’define指令,它在整个编译过程中都有效。

如果已经定义了一个文本宏,那么在它的宏名之前加上重音符号(’)就可以在源程序中'引用该文本宏。

在编译器编译时,将会自动用相应的文本块代替字符串'macro_name。将Verilog HDL中的所有编译指令都看作预定义的宏名,将一个编译指令重新定义为一个宏名是非法的。

一个文本宏定义可以带有一个参数。这样,就允许为每一个单独的应用定制文本宏。

文本宏定义的语法格式如下:

'define <text_macro_name> <macro_text>

其中: (1)<text_macro_name>为文本的宏名字,其语法格式为

text_macro_identifier[<list_of_formal_arguments>]

①text_macro_identifier为宏标识符,要求简单标识符。

②<list_of_formal_arguments>为形参列表。一旦定义一个宏名,就可以在源程序的任何地方使用它,而没有范围限制。

(2)<macro_text>为宏文本,可以是与宏名同行的任意指定文本。

①如果指定的文本超过一行,那么新的一行需要用反斜杠()作为起始。这样,反斜杠后面的文本也将作为宏文本的一部分,参与宏替换。反斜杠本身并不参与宏替换,编译时将忽略它。

②如果宏文本包含了一个单行注释语句(以“//”开始的注释语句),则该语句不属于替换文本,编译时不参与替换。

③宏文本可以空白。

[例] ’define指令Verilog HDL化述的例子1。

'define wordsize 8reg[1:'wordsize] data;
//define a nand with variable delay'define var_nand(dly) nand #dly
'var_nand(2) gl21 (q21, nl0, nil);
'var_nand(5) gl22(q22, nl0, nil);

[例] ’define指令Verilog HDL非法描述的例子2

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

[例] 'define 指令 Verilog HDL 非法描述的例子 3。

'define max(a,b)((a)>(b)?(a):(b))
n = 'max(p + q, r + s) ;

将要扩展为

n = ((p + q ) >(r + s))?(p + q ) :(r + s);

2.'undef指令

'undef指令用于取消前面定义的宏。如果先前并没有使用指令’define进行宏定义,那么使用’undef指令将会导致一个警告。

’undef指令的语法格式如下:

'undef text_macro_identifier

一个取消的宏没有值, 就如同没有被定义一样。

'define SIZE 8
'define xor_b(x,y)(x &!y)|(!x & y)
//These text macros can be used as follow:
reg ['SIZE - 1 : 0] data out;
c = xor_b(a, b);
'undef SIZE

’celldefine和’endcelldefine

这两个指令用于将模块标记为单元模块,它们表示包含模块定义。某些PLI使用单元模块用于这些应用,如计算延迟。

该命令可以出现在源代码描述中的任何地方。但是,推荐将其放在模块定义的外部。

[例] ’celldefine指令Verilog HDL描述的例子。

'celldefine
module my_and(y, a, b);
output y;
input a, b;assign y = a & b;endmodule
'endcelldefine

’default_nettype

该指令用于为隐含网络指定网络类型,也就是为那些没有被说明的连线定义网络类型。它只可以出现在模块声明的外部,允许多个’default_netype指令。

如果没有出现’default_netype指令,或者如果指定了’resetall指令,则隐含的网络类型是wire。当default_netype设置为none时,需要明确地声明所有网络;如果没有明确地声明网络,则产生错误。

’default_netype指令格式为:

'default_nettype default_nettype_value

其中default_nettype_value的值可以是wire、tri、tri0、tri1、wand、triand、wor、trior、trireg、uwire和none。

'ifdef、 'else、 ’elsif、 ’endif 和’ifndef

'ifdef编译器命令

条件编译:

显而易见,即只有在条件满足的时候才对这部分代码进行编译,也就是对一部分内容指定了编译的条件:

当满足条件时对一组语句进行编译,

当条件不满足时则对另外一组语句进行编译。

用途:

1、选择一个模板的不同代表部分。

2、选择不同的时序或结构信息。

3、对不同的EDA工具,选择不同的激励。(如:Verilog代码中的一部分可能因编译环境不同而不同,为避免在不同环境需要替换不同版本的Verilog 设计,条件编译就是一个很好的解决方案)

用法

'ifdef 宏名(标识符)程序段1...
'else程序段2...
'endif

当宏名被定义过了,就编译程序段1;反之,当宏名未被定义过,就编译程序段2;

其中,else部分可以省略。即:当宏名被定义过了,就编译程序段1;反之,不编译程序段1;

[例] ’ifdef 指令 Verilog HDL 描述的例子。

module and_op (a, b, c);
output a;
input b, c;
'ifdef behavioralwire a = b & c;
'elseand a1 (a,b,c);
'endifendmodule

‘ifndef编译器命令

额外的,还有‘ifndef语句,与’ifdef功能相反:

即当宏名没被定义过,就编译程序段1;反之,当宏名未被定义过了,就编译程序段2;

'ifndef 宏名(标识符)程序段1...
'else程序段2...
'endif

[例] ’ifndef 指令 Verilog HDL 描述的例子。

module test;
'ifdef first_block'ifndef second_nestinitial $ display("first_block_is_defined");'elseinitial $ display("first_block and second_nest defined");'endif
'elsif second_block initial $ display( "second_block defined, first_block is not”);
'else'ifndef last_resultinitial $ display("first_block, second_block,"”last_result not defined.");
'elsif real_lastinitial $ display("first_block, second_block not defined,"" last_result and real last defined.");
'elseinitial $ display("Only last result defined!");'endif
'endifendmodule

这里还有一个‘elsif指令,简单说明一下。

'ifndef test_macro_identifier
ifndef_group_of_1ines
{ 'elsif text_macro_identifier elsif_group_of_lines }
[ 'else else_group_of_lines ]
'endif

①当遇到’ifndef时,测试’ifdef文本宏标识符,查看在Verilog HDL源文件描述中是否使用'define作为一个文本宏名字;②如果’ifndef没有定义文本宏标识符,则对’ifndef所包含的行作为描述的一部分进行编译,如果还有’else或者’dsif编译器指令,则忽略这些编译器指令和相关的行组;③如果定义’ifiidef文本宏标识符,则忽略’ifndef所包含的行;④如果有’elsif编译器指令,测试'elsif文本宏标识符,查看在Verilog HDL源文件描述中,是否使用'define作为一个文本宏名字;⑤如果’elsdef定义文本宏标识符,则对’elsdef所包含的行作为描述的一部分进行编译,如果还有’else或者’elsif编译器指令,则忽略这些编译器指令和相关的行组;⑥如果没有定义第一个'elsif文本宏标识符,则忽略第一个’elsif所包含的行;⑦如果有多个’elsif编译器命令,将按照它们在Verilog HDL源文件中的描述顺序和评估第一个’elsif编译器指令的方法,对这些指令进行评估;⑧如果有一个’else编译器命令,则将’else所包含的行作为描述的一部分进行编译。

’include

在编译期间,’include编译器指令用于嵌入另一个文件的内容。既可以用相对路径名定义文件,也可以用全路径名定义文件。其语法格式为:

'include "filename"

使用’inchide编译器指令的优势主要体现在以下几方面:

(1)提供了一个配置管理不可分割的一部分;

(2)改善了VerilogHDL源文件描述的组织结构;

(3)便于维护Verilog HDL源文件描述。

[例 ]’include指令Verilog HDL描述的例子。

'include "parts/count. v"
'include "fileB"
'include "fileB" //包含 fileB

'resetall

该编译器遇到’resetall指令时,会将所有的编译指令重新设置为默认值。推荐在源文件的开始放置’resetall.将'resetall命令放置在模块内或者UDP声明中是非法的。其语法格式为

'resetall

’line

对于Verilog工具来说,跟踪Verilog HDL源文件的名字和文件的行的行号是非常重要的,这些信息可以用于调试错误消息或者源代码,Verilog PL1访问可以它。

然而,在很多情况下,Verilog源文件由其他工具进行了预处理。由于预处理工具可能在Verilog HDL源文件中添加了额外的行,或者将多个源代码行合并为一个行,或者并置多个源文件,等等,可能会丢失原始的源文件和行信息。

'line编译器命令可以用于指定的原始源代码的行号和文件名。如果其他过程修改了源文件,这允许定位原始的文件。当指定了新行的行号和文件名时,编译器就可以正确地定位原始的源文件位置。然而,这要求相应的工具不产生’line命令。

其语法格式为

'line number "filename" level

其中,number是一个正整数,用于指定跟随文本行的新行行号,filename是一个字符串常数,将其看作文件的新名字,文件名可以是全路径名字或者相对路径名字;level为该参数的值,可以是0、1或者2:①当为1的时候,输入一个include行后的下面一行是第一行;②当为2的时候,退出一个inlcude行后的下面一行是第一行;③当为0的时候,指示任何其他行。

[例] 'line 指令 Verilog HDL 描述的例子。

'line3 "orig.v" 2

//该行是 orig.v 存在 include 文件后的第 3 行。

’timescale

在Verilog HDL模型中,所有的时延都用单位时间表述。可使用'timescale编译器指令将时间单位与实际时间相关联,该指令用于定义时延的单位和时延精度。

作用:

timescale用于定义延时的单位和延时的精度,如timescale  1ns/100ps那么时间单位就是1ns,精度就是100ps。

时间单位,表示了仿真时测量的单位,比如延时1,1ns;精度则表示仿真器只识别的范围,比如精度是100ps,那么如果你1.3ns,编译器是识别,但是如果写1.32,那么由于精度达不到那么细,所以0.02被四舍五入掉。

`timescale影响着全部模块,直到遇到另外的timescale。

’timescale编译器指令格式为:

’timescale time_unit/time_precision

其中,time_unit指定用于时间和延迟测量的单位,可选的值为1、10或100;time_precision用于仿真前,确定四舍五入延迟值。时间分辨率子,可选的单位为s \ms\us\ns\ps或fs。

[例] 'timescale 指令 Verilog HDL 描述的例子。

'timescale 10 ns / 1 ns
module test;
reg set;
parameter d = 1.55;
initial begin
# d set = 0;
# d set = 1;
end
endmodule

根据时间精度, 参数 d 的值从 1.55 四舍五入到 1.6。模块的时间单位是 10ns 精度是1 ns。因此, 参数 d 的延迟从 1.6 标定到 16。

’unconnected_drive和'nounconnected_drive

当一个模块所有未连接的端口出现在'unconnected_drive和’nounconnecteddrive指令之间时,将这些未连接的端口上拉或者下拉,而不是按通常的默认值处理。

指令’unconnected_drive使用pull1/pull0参数中的一个:当指定pull时,所有未连接的端口自动上拉;当指定pill0时,所有未连接的端口自动下拉。

建议成对使用’unconnected_drive和'nounconnected_drive指令,但不是强制要求。这些指令在模块外部成对指定。

'resetall指令包括'nounconnected_drive指令的效果。

[例]nounconnected_drive/ 'unconnected drive 指令 Verilog HDL 描述的例子。

'unconnected_drive pull1
module my_and(y, a, b);
output y;
input a, b;
assign y = a & b;
endmodulemodule test;
reg b;
wire y;
my_and ul(y, ,b);
endmodule'nounconnected_drive

'pragma

’pragma指令是一个结构化的说明,它用于改变对Verilog HDL源文件的理解。由这个指令所引入的说明称为编译指示。编译指示不同于Verilog HDL标准所指定的结果,它为指定实现的结果。其语法格式为

’pragma pragma_name [ pragma_expression { , pragma_expression } ]

其中 ,pragma_name 为编译指示的名字, 可以是 $ 开头的系统标识符或者一般标识符; pragma_expression 为编译指示表达式。

注:reset和resetall编译指示将恢复默认值和pragma_keywords所影响的状态。

'begin_keywords和’end_keyword

'begin_keywords和'end_keyword指令用于指定在一个源代码块中,基于不同版本的IEEE_Stdl364标准,确定用于关键字的保留字。该对指令只指定那些作为保留关键字的标识符。只能在设计元素(模块、原语和配置)外指定该关键字,并且需要成对使用。其语法格式为:

'begin_keywords "version_specifier"...
'end_keyword

其中,version_specifier为可选的参数,包括1364-1995、1364-2001、1364-2001-noconfig和1364-2005。

[例] ’begin_keywords 和 'end_keyword 指令 Verilog HDL 描述的例子。

'begin_keywords "1364- 2001" //使 用 IEEE Std 1364- 2001 Verilog 关 键 字
'module  m2(...);
reg[63:0] logic;           //logic 不 是 1364 - 2001 的 关 键 字...endmodule'end_keywords

(补充一)Verilog编译器指示语句

设计者在写设计代码时,有时可能针对仿真写一些语句,这些语句可能是不为DC所接受,也不希望DC接受;设计者如果不对这些语句进行特殊说明,DC读入设计代码时就会产生语法错误。另一种情况是,设计者在写设计代码,有些设计代码是为专有的对象写的(如公司内部),这些专有的设计代码可能不希望被综合。Synopsys提供了引导语句,设计者可以使用这些引导语句控制DC综合的对象

可以利用HDL描述中的一些特定的注释语句来控制综合工具的工作,从而弥补仿真环境和综合环境之间的差异,这些注释语句称为编译器指示语句。

translate_off/ translate_on

这组语句用来指示DC停止翻译 “//synopsys.。.translate_off”之后的Verilog描述,直至出现 “//synopsys translate_on”。当Verilog代码钟含有供仿真用的不可综合语句时,这项功能能使代码方便地在仿真工具与综合工具之间移植。

例1(translate_off/ translate_on指示语句的使用):

//synopsys translate_off//synopsys translate_on

parallel_case/ full_case

DC可能使用带优先级的结构来综合Verilog的case语句,为避免这种情况,可以使用“//synopsys.。.parallel_case”指示DC将case语句综合为并行的多路选择器结构。

(parallel_case指示语句的使用):

always @ (state)case (state) //synopsys parallel_case2’b00:new_state = 2’b01;2’b01:new_state = 2’b10;2’b10:new_state = 2’b00;default:new_state = 2’b00;endcase

另外,Verilog允许case语句不覆盖所有可能情况,当这样的代码由DC综合时将产生锁存器。为避免这种情况,可以使用“//synopsys full_case”指示DC所有可能已完全覆盖。

例2 (full_case指示语句的使用):

always @ (sel or a1 or a2)case (sel) //synopsys full_case2’b00:z = a1;2’b01:z = a2;2’b10:z = a1 & a2;endcase

(补充二)Verilog PL1是什么?

上面有提到过PLI接口,这里简单介绍下,因为用的比较少,所以就一笔带过。

编程语言接口(Program Language Interface,PLI)提供了通过C语言函数对Verilog数据结构进行存储和读取操作的方法。

PLI接口主要提供以下三种功能。

(1)PLI接口允许用户编写自定义的系统任务和系统函数。用户写出相应的PLI程序并连接到仿真器后,就可以在自己写的VerilogHDL程序中使用这些系统任务和系统函数。一旦在仿真过程中调用这些任务或者函数,仿真器就会找到对应的用户所编写的PLI程序并执行,从而实现仿真器的定制。

(2)这个接口还允许用户在自己的PLI程序中与仿真器中例化的VerilogHDL硬件进行交互,如读一个线网络的值、向一排寄存器写值以及设置一个单元的延迟,等等。

对于PLI程序而言,仿真器中的Verilog实例完全透明,用户可以对这些硬件做任何操作(当然,不能修改硬件结构)。有了这个功能,用户就可以在自定义的任务/函数中对硬件执行某些用VerilogHDL语言难以完成的操作。

(3)某些特定的操作需要对仿真过程中一些信号的变化做出响应,虽然可以用always过程语句来监控少量信号的变化,但如果需要监测大量信号,这种机制并不现实。

PLI接口提供了一种函数回调机制解决这个问题。用户可以将某个线网络/寄存器等信号挂上一个PLI程序中的C函数。每当该信号变化时,调用这个C函数,从而很方便地监测信号。

除了上面所说的这些机制外,PLI还能让用户控制仿真的过程,例如暂停、退出以及向日志文件里写信息等,还可以获取仿真过程的数据,如当前仿真时间等。在实际的PLI程序中,同样不可缺少这些功能。

参考资料

1、http://www.elecfans.com/d/651393.html

2、EDA原理及Verilog实现

3、https://www.cnblogs.com/IClearner/p/7258983.html

NOW

学习Xilinx FPGA最好的资料其实就是官方手册,下表总结了部分手册的主要介绍内容,关注我,持续更新中......

文件名 主标题 内容简单介绍 是否有中文版
UG476 7 Series FPGAs GTX/GTH  Transceivers GTX和GTH介绍,PCIe、serdes等学习必备
UG471 7 Series FPGAs SelectIO Resources 描述 7 系列 FPGA 中可用的 SelectIO资源。
UG1114 PetaLinux Tools Documentaton PetaLinux 工具文档 参考指南 是,V2019.2
UG949 UltraFAST 设计方法指南(适用于 Vivado  Design Suite) 赛灵思® UltraFast™  设计方法是用于为当今器件优化设计进程的一套最佳实践。这些设计的规模与复杂性需要执行特定的步骤与设计任务,从而确保设计每一个阶段的成功开展。依照这些步骤,并遵循最佳实践,将帮助您以最快的速度和最高的效率实现期望的设计目标 是,V2018.1
IP手册 pg057 FIFO Generator FIFO生成器IP使用手册
pg104 Complex Multiplier 复数乘法器IP使用手册
pg122 RAM-Based Shift Register  移位寄存器IP使用手册

推荐阅读

【Vivado那些事】如何查找官网例程及如何使用官网例程

【Vivado使用误区与进阶】总结篇

【Vivado那些事】Vivado中常用的快捷键(二)其他常用快捷键

SystemVerilog数字系统设计_夏宇闻 PDF

图书推荐|ARM Cortex-M0 全可编程SoC原理及实现

简谈:如何学习FPGA

1202年了,还在使用虚拟机吗?Win10安装Ubuntu子系统及图形化界面详细教程

Github 上有哪些优秀的 VHDL/Verilog/FPGA 项目

AD936x+ZYNQ搭建收音机(一)

AD936x+ZYNQ搭建OpenWIFI

无招胜有招-Vivado非工程模式下的详细设计

面试中经常会遇到的FPGA基本概念,你会几个?

Vivado ML(机器学习) 2021尝鲜

推荐一些可以获取免费的国外的原版书籍(电子版)网站

【Vivado那些事】FPGA的配置方式

FPGA 的重构

浅析FPGA局部动态可重构技术

ISP(图像信号处理)算法概述、工作原理、架构、处理流程

国产CPU概括

从电子游戏历史看IC发展的助推剂

80年代电子游戏及电脑游戏的发展历史

PCIe总线的基础知识

万字长文带你回顾电子游戏的七十多年历史(完整版)

FPGA中异步复位,同步释放的理解

OpenFPGA系列文章总结

用Verilog设计一个16 位 RISC 处理器

介绍一些新手入门FPGA的优秀网站(新增)

Verilog数字系统基础设计-CR

Verilog数字系统基础设计-奇偶校验

建立和保持时间及时序简单理解

(Xilinx)FPGA中LVDS差分高速传输的实现

Xilinx Multiboot实例演示

高速串行通信常用的编码方式-8b/10b编码/解码
Verilog计时(微秒、毫秒和秒)脉冲的产生及同步整形电路

再说System Verilog 与 Verilog 的关系

图书推荐|一本图像/视频处理的强大工具书

Verilog HDL-同步技术

再说System Verilog 与 Verilog 的关系

数模混合信号建模语言Verilog-AMS

【Vivado那些事儿】强制修改打开Vivado工程使用的Vivado版本

Intel/Altera 系列FPGA简介

一块带给无数人年少欢乐的CPU,别说你没用过它

Verilog在编写第一行代码之前

【例说】Verilog HDL 编译器指令,你见过几个?相关推荐

  1. 例说Verilog HDL和VHDL区别,助你选择适合自己的硬件描述语言

    如果你搜索Verilog和VHDL的区别,你会看到很多讨论这场HDL语言战争的区别页面,但大多数都很简短,没有很好地举例说明,不方便初学者或学生理解. Verilog和VHDL之间的区别将在本文中通过 ...

  2. (61)Verilog HDL模块例化Verilog模块

    (61)Verilog HDL模块例化Verilog模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化Verilog模块 5)结语 1. ...

  3. (62)Verilog HDL模块例化system Verilog模块

    (62)Verilog HDL模块例化system Verilog模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化system Ver ...

  4. (63)Verilog HDL模块例化VHDL模块

    (63)Verilog HDL模块例化VHDL模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化VHDL模块 5)结语 1.2 FPGA ...

  5. (64)Verilog HDL多模块重复例化

    (64)Verilog HDL多模块重复例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL多模块重复例化 5)结语 1.2 FPGA简介 FPG ...

  6. (65)Verilog HDL多模块重复例化:generate for

    (65)Verilog HDL多模块重复例化:generate for 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL多模块重复例化:genera ...

  7. (66)Verilog HDL模块参数化例化

    (66)Verilog HDL模块参数化例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块参数化例化 5)结语 1.2 FPGA简介 FPG ...

  8. (67)Verilog HDL模块条件例化

    (67)Verilog HDL模块条件例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块条件例化 5)结语 1.2 FPGA简介 FPGA( ...

  9. (03)Verilog HDL模块例化

    (03)Verilog HDL模块例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化 5)结语 1.2 FPGA简介 FPGA(Fiel ...

最新文章

  1. 用好ASP.NET 2.0的URL映射
  2. 学习篇之软件测试——初
  3. photoshop8.0 安装步骤及注意事项
  4. oracle 视图使用rownum,Oracle数据对象--视图
  5. 0666 | IPC_CREAT
  6. Nature:压榨学生,论资排辈,现行论文作者制度已死
  7. SAP One Order redesign写操作的详细设计
  8. Linux的简介与虚拟机的管理
  9. Linq中 AsQueryable(), AsEnumerable()和ToList()的区别和用法
  10. 高校智慧教室建设方案
  11. 带圆圈的数字和markdown常用表达式记录
  12. ps抠图插件Topaz ReMask 5
  13. 微美全息正式成立“全息元宇宙事业部”;孩之宝旗下威世智发布一系列万智牌产品;区块链专家赵亮正式加盟宏桥高科 | 全球TMT...
  14. android用代码返回桌面
  15. unity 多点触控
  16. 数据库身份证号用什么类型_油罐内壁防腐施工用什么类型的升降机?
  17. hexo自定义域名以及解析
  18. 项目使用的 safe.cs 帮助类
  19. java线程池介绍(一)
  20. greenplum数据库单机部署

热门文章

  1. 7-4 厘米换算英尺英寸 (15分)
  2. ws550 第三方固件_华为WS550路由器固件升级教程
  3. (附源码)SSM汽车租赁管理系统 毕业设计 052158
  4. 附PPT|阿里巴巴实时数仓最新架构图
  5. OSChina 周六乱弹 —— 你退群吧,丢狗
  6. 基于心理学角度对大班幼儿入园哭闹现象分析
  7. 【数据库】北邮国际学院大二下期末复习
  8. Eclipse 代码提示卡顿
  9. 2022华东杯B题中证红利指数投资问题思路讲解
  10. 什么是冷钱包、热钱包?