首页 > 其他分享 >SV编译器指令(Compiler Directives)

SV编译器指令(Compiler Directives)

时间:2022-08-24 22:46:00浏览次数:66  
标签:定义 timescale SV 编译器 指令 Directives display define

SystemVerilog 提供大量编译器指令来指导代码进程,比如`define、`ifdef、`elsif、`ifndef、`timescale、`default_nettype等。

它们前面是 ( ` ) 字符(重音字符)(不要将其与撇号字符 ( ' ) 混淆)。

`define

`define 是使用最广泛的编译器指令之一,它是一个文本替换宏。它可以为常用的文本片段提供有意义的名称。例如,在整个描述中重复使用常量的情况下,文本宏很有用,因为如果需要更改常量的值,则只需更改源描述中的一个位置。例如:

`define widebus 16'hFFFF

并在整个源描述中使用 `widebus。如果以后widebus的定义改成32'hFFFF_FFFF,只需要改一行: `define widebus 32'hFFFF_FFFF

新的定义将应用到源代码中。

允许重新定义文本宏;编译器以遇到的最新定义为准。

看一个例子,展示了许多不同的方式来使用 `define :

  `define busWidth 31      // logic [0:`buswidth] bus;

       `define delay #10        // forever `delay clk = !clk;

       `define nandD(dly) nand #dly     // `nandD(10) n1(o1, i1, i2); //expands to - nand #10 n1(o1, i1, i2);

       `define comment $display("this is a long ”, \

       “comment that spans multiple lines");          //定义一个跨越两行的宏文本。为了做到这一点,在文本的下一行行之前使用“\”(反斜杠)

                       //使用:initial `comment

       `define disp(x,y) initial $display(x, y);  // `disp("GoX"," GoY")

       `define tdisp(a = 5, b = 10, c) initial $display(a,,b,,c);    //`tdisp( , , 15) //5 10 15

       `define conditional(a,b) (a > b ? a : b)    // assign bus = `conditional(20,10); //=(20 > 10 ? 20 : 5)

       `define mF(filename) `"/springer/mydir/filename`"

 

`undef and `undefineall

如果先前由 `define 宏定义,则指令 `undef 取消定义指定的文本宏。例如 `undef delay

`undefineall 将取消定义以前由 `define 指令定义的所有文本宏。它可以出现在源码中的任何位置,并且不带任何参数。

 

 `ifdef, `else, `elsif, `endif, and `ifndef

模板:

`ifdef text_macro_identifier (OR `ifndef text_macro_identifier)
            <lines of code>
       `elsif text_macro_identifier
            <lines of code>
       `endif

请注意,可以在模块中声明 text_macro_identifier。也可以在命令行上将它们声明为编译类型选项(如下所述)。让我们看一个例子:

       `define true
       `define false
       `define behavioral
       module directive;
         wire a, b, c;
         initial begin
           `ifdef true
           $display("TRUE");
              `ifdef false
                 $display("NESTED FALSE after TRUE");
             `endif
           `else
             $display("NONE");
           `endif
         end
         `ifndef behavioral  //if 'behavioral' is -not- defined
            and a1 (a, b, c);
            initial $display("GATE LEVEL");
         `else
            assign a = b & c;
            initial $display("BEHAVIORAL");
         `endif
       endmodule

 

仿真结果:

Compiler version S-2021.09; Runtime version S-2021.09;  Aug 24 09:59 2022
TRUE
NESTED FALSE after TRUE
BEHAVIORAL
           V C S   S i m u l a t i o n   R e p o r t 

我们已经声明了三个`define,即`define true、`define false和`define behavior。注意这些是如何声明的,只是在 `define 关键字之后给出了一个 text_macro_name。这不同于做文本替换: `define true 1'b1

然后在代码中,我们使用`ifdef true 选择一个分支,并使用嵌套的`ifdef false 选择一个额外的分支。这两个嵌套的 `ifdef 被执行,如仿真中通过 $display 所示。

我们还在代码中使用`ifndef(即,如果未定义)在行为代码和结构代码之间进行选择。 `ifndef 行为意味着如果没有定义“behavioral”,则选择与 `ifndef 关联的分支。在我们的例子中,我们确实定义了“behavioral”,因此 `else 分支被执行。

请注意,如前所述,不必在代码本身中有 `defines。可以避免在代码中声明所有三个 `defines,编译指令上提供这些定义。例如,可以在命令行上执行以下操作:

  +define+true
       +define+false
       +define+true+false+behavioral    //all three with one +define+

在命令行上提供这些`define的优势就是不必更改源码。可以有条件地从命令行本身选择编译代码。

 

 `timescale

这是一个广泛使用的编译器指令,主要在测试平台级别。它指定其后设计(和#<delay>)的时间单位和时间精度。时间单位是时间值的测量单位,例如仿真时长和延迟时长。

语法: `timescale time_unit / time_precision

time_unit 参数指定时间和延迟的测量单位,time_precision 参数指定延迟在用于仿真之前如何四舍五入。例如:`timescale 1 ns/1 ps

在你的代码中有:#1.123ns a = 0

仿真器会将 1.123 时间单位转换为 1123 时间刻度,即将 1.123 ns 转换为 1123 ps。

`timescale 作为编译器指令本质上是全局的。一旦定义,它将跨越文件/模块边界。

假设你有三个文件,TS1.v、TS2.v 和 TS3.v:

TS1.v
`timescale 1 ns/1 ns
module TS1 (…);

TS2.v
`timescale 10 ns/1 ns
module TS2(…);

TS3.v
//NO TIMESCALE
module TS3(…);

以下是根据编译顺序选择 `timescale 的结果:

verilog TS1.v TS2.v TS3.v //TS3 timescale is 10 ns/1 ns.
verilog TS2.v TS1.v TS3.v //TS3 timescale is 1 ns/1 ns. TS2也变成1ns/1ns?我觉得是,因为`timescale默认是全局的。
verilog TS3.v TS1.v TS2.v //Compile ERROR – TS3 has no timescale. 采用仿真器默认值

 

 `default_nettype

设置默认线网类型。我们知道,默认情况下,线网(net)类型是“wire”。但是可以使用 `default_nettype 编译指令覆盖默认线网(net)类型:

  `default_nettype default_nettype_value

其中 default_nettype_value 可以是任何线网类型,例如 wire、tri、tri0、tri1、wand、triand、wor、trior、trireg、uwire 或“none”。

当它设置为“none”时,所有网线网必须明确声明(否则会得到一个error)。该指令必须在模块之外定义

允许使用多个 `default_ nettype。最后一次出现控制线网的类型。 `resetall 指令将指令重置为其默认值。

 

`resetall 

`resetall 将所有现有的编译器指令重置为默认值。在模块(任何设计元素)之前,使用`resetall 指令来重置所有先前定义的编译器指令。这确保只有编译特定源文件所需的指令才处于有效状态。请注意,`define  和 `include  没有默认值,因此不受`resetall 的影响。

标签:定义,timescale,SV,编译器,指令,Directives,display,define
From: https://www.cnblogs.com/fuqiangblog/p/16622366.html

相关文章

  • gcc编译器的常用命令行参数
    在学习常用的gcc命令行参数前,先了解gcc在执行编译工作的过程1、预处理,生成.i的文件[预处理器cpp]2、将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs]3......
  • SV中的包(Package)
    SystemVerilog中的包提供对许多不同数据类型、包括nets、variable、task、function、assertionsequences、property和checker声明的封装。封装再包内的数据可以在多个modu......
  • windows10-msys2-msvc编译ffmpeg4.4.2
    下载msys2在msys2安装目录下创建文件msys2_ffmpeg.batcall"D:\ProgramFiles\MicrosoftVisualStudio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"setMSY......
  • C#下载csv代码总结(解决中文乱码问题)
    ///<summary>///下载///</summary>///<paramname="startTime"></param>///<paramname="endTime"></param>publicvoidDownload(DateTime?startTime,D......
  • svg学习
    svg学习基础知识参考资料https://baike.baidu.com/item/SVG格式/3463453?fr=aladdinSVG指可伸缩矢量图形(ScalableVectorGraphics)SVG用来定义用于网络的基于......
  • 一天一个知识点-----vue项目简单引入svg
    项目背景:vue3.0+elementPlus注意项目结构,主要涉及的几个文件及文件夹---直接上代码----1.最开始是要下载包npminstallsvg-sprite-loader2.配置项目的配置文件vu......
  • gcc编译器
    一、gcc,即GNUCCompile  gcc仅仅是一个编译器,没有界面,必须在命令行模式下使用。通过gcc命令可以将源文件编译成可执行文件。  gcc既可以一次性完成C语言源文件......
  • csv
    importcsv#withopen('write.csv','r')asf:#打开#text=csv.reader(f)#读取##print(text)#forrowintext:#必须这样才可以读取出数据#......
  • svn客户端检出的工程导入eclipse后不显示SVN信息
    1、首先确定原因:是由于SVN客户端与SVN插件版本不对应导致的,因此需要更换SVN插件版本1.1、SVN插件与SVN客户端版本对应关系插件svn1.4.x对应TortoiseSvn1.5.x插件svn1.6......
  • 日常学习(2)sv赋值、寻址方式、正则
    sv赋值方式sv的赋值方式可以采用.形参(参数)的方式,更清晰功能https://gitee.com/bai-mengwei/my_uart_tb/blob/11126a220e740ea070c128f1949078daaaf5cad7/uvm_tb/registe......