zoukankan      html  css  js  c++  java
  • <转>Verilog HDL宏定义define

    宏定义 `define

    用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:

    `define 标识符(宏名) 字符串(宏内容)

    如:`define signal string

    它的作用是指定用标识符signal来代替string这个字符串,在编译预处理时,把程序中在该命令以后所有的signal都替换成string。这种方法使用户能以一个简单的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号,因此把这个标识符(名字)称为“宏名”,在编译预处理时将宏名替换成字符串的过程称为“宏展开”。`define是宏定义命令。

    [例1]:`define  WORDSIZE 8

    module

    reg[1:`WORDSIZE]  data; //这相当于定义 reg[1:8] data;

    关于宏定义的八点说明:

    1)       宏名可以用大写字母表示,也可以用小写字母表示。建议使用大写字母,以与变量名相区别。

    2)       `define命令可以出现在模块定义里面,也可以出现在模块定义外面。宏名的有效范围为定义命令之后到原文件结束。通常,`define命令写在模块定义的外面,作为程序的一部分,在此程序内有效。

    3)      在引用已定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是一个经过宏定义的名字。

    4)       使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。而且记住一个宏名要比记住一个无规律的字符串容易,这样在读程序时能立即知道它的含义,当需要改变某一个变量时,可以只改变 `define命令行,一改全改。如例1中,先定义WORDSIZE代表常量8,这时寄存器data是一个8位的寄存器。如果需要改变寄存器的大小,只需把该命令行改为:`define WORDSIZE 16。这样寄存器data则变为一个16位的寄存器。由此可见使用宏定义,可以提高程序的可移植性和可读性。

    5)       宏定义是用宏名代替一个字符串,也就是作简单的置换,不作语法检查。预处理时照样代入,不管含义是否正确。只有在编译已被宏展开后的源程序时才报错。

    6)       宏定义不是Verilog HDL语句,不必在行末加分号。如果加了分号会连分号一起进行置换如:

    [例2]:module  test;

      reg  a, b, c, d, e, out;

     `define  expression  a+b+c+d;

    assign out = `expression + e;

      ...

        endmodule

    经过宏展开以后,该语句为:

    assign  out = a+b+c+d;+e;

    显然出现语法错误。

    7)       在进行宏定义时,可以引用已定义的宏名,可以层层置换。如:

    [例3]:module test;

    reg  a, b, c;

    wire out;

    `define aa a + b

    `define cc c + `aa

    assign out = `cc;

        endmodule

    这样经过宏展开以后,assign语句为

    assign  out = c + a + b;

    8)       宏名和宏内容必须在同一行中进行声明。如果在宏内容中包含有注释行,注释行不会作为被置换的内容。如:

    [例4]: module

            `define typ_nand nand #5  //define a nand with typical delay

         `typ_nand g121(q21,n10,n11);

            ………

            endmodule

    经过宏展开以后,该语句为:

    nand #5 g121(q21,n10,n11);

    宏内容可以是空格,在这种情况下,宏内容被定义为空的。当引用这个宏名时,不会有内容被置换。

    注意:组成宏内容的字符串不能够被以下的语句记号分隔开的。

    • 注释行
    • 数字
    • 字符串
    • 确认符
    • 关键词
    • 双目和三目字符运算符

    如下面的宏定义声明和引用是非法的。

    `define  first_half  "start of string

    $display(`first_half end of string");

    注意在使用宏定义时要注意以下情况:

    1)       对于某些 EDA软件,在编写源程序时,如使用和预处理命令名相同的宏名会发生冲突,因此建议不要使用和预处理命令名相同的宏名。

    2)       宏名可以是普通的标识符(变量名)。例如signal_name 和 'signal_name的意义是不同的。但是这样容易引起混淆,建议不要这样使用。

  • 相关阅读:
    main函数的实现解析
    srand()和rand()函数的使用
    shell编程总结
    自动创建字符设备,不需mknod
    linux使用i/o内存访问外设
    Flink之state processor api原理
    Flink之state processor api实践
    软件架构被高估,清晰简单的设计被低估
    技术架构的战略和战术
    Flink task之间的数据交换
  • 原文地址:https://www.cnblogs.com/icdz1990/p/4196714.html
Copyright © 2011-2022 走看看