SystemVerilog 中 import 和 include 的区别与联系

这是初学 SV/UVM 很容易混淆的两个概念。它们都是"引入外部内容" ,但机制完全不同 ------include文本替换import引入 package 的符号


一、```include``(预处理,文本替换)

本质

```include`` 是编译预处理指令 (注意前面有反引号 `````),在编译前 把指定文件的内容原封不动地复制粘贴到当前位置。

用法

复制代码
`include "uvm_macros.svh"
`include "my_driver.sv"

特点

  • 纯文本插入,等同于把那个文件的代码手动抄进来
  • 处理的是文件
  • 常用于包含:宏定义(```define``)、.svh 头文件、宏文件 (如 uvm_macros.svh
  • 谁 include,代码就出现在谁那里

二、import(编译语义,引入符号)

本质

import语言级语句 ,把某个 package(包) 里已经编译好的类、类型、函数、变量等符号引入到当前作用域,让你能直接使用。

用法

复制代码
import uvm_pkg::*;        // 引入 uvm_pkg 里的所有符号
import my_pkg::trans;     // 只引入 my_pkg 里的 trans 类

特点

  • 处理的是 package(包),不是文件
  • 引入的是符号(名字),不是文本
  • package 必须先被编译过,import 只是"让这些名字可见"
  • ::* 表示引入包里所有公开符号;::具体名 表示只引入某一个

三、核心区别对比

对比项 `include import
类别 预处理指令(有反引号) 语言语句
处理对象 文件(内容) package(符号)
机制 文本复制粘贴 引入已编译的符号名
发生时机 编译前(预处理) 编译时(语义解析)
内容会不会重复 会(复制多次可能重定义) 不会(只是引用同一份)
典型用途 宏文件、头文件 使用 package 里的类/类型/函数
是否需要 package 不需要 必须有 package

四、它们的联系(经常一起出现)

在 UVM 里你几乎总能看到这两句配对出现

复制代码
import uvm_pkg::*;          // 引入 uvm 的所有类、类型
`include "uvm_macros.svh"   // 引入 uvm 的宏(如 `uvm_info、`uvm_component_utils)

为什么要一起用?

  • 类、函数、类型 → 放在 package 里 → 用 import 引入
  • 宏(define``)** → **不能** 放进 package(宏是预处理层面的,package 是语义层面的)→ 只能用 **include`` 引入

所以:

  • import uvm_pkg::*; 让你能用 uvm_componentuvm_test
  • include "uvm_macros.svh"`` 让你能用 uvm_info、```uvm_component_utils

两者互补,缺一不可。


五、典型的 package 组织方式

一个常见做法:在 package 内部用 include 把源文件拼进来,外部再 import 这个 package:

复制代码
// ---------- my_pkg.sv ----------
package my_pkg;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  `include "my_trans.sv"      // 把类的定义文本包含进包里
  `include "my_driver.sv"
  `include "my_env.sv"
endpackage

// ---------- tb.sv ----------
module tb;
  import uvm_pkg::*;
  `include "uvm_macros.svh"
  import my_pkg::*;           // 引入 my_pkg 里所有类
  ...
endmodule
  • 包内部 :用 ```include`` 把各个类的源码"拼装"进 package
  • 包外部 :用 import 引入这个 package 的符号

六、易错点

  1. 宏不能靠 import 传递 :即使你 import 了某个 package,那个包里用 define`` 定义的宏在外面**也用不了** ------宏必须靠 include``
  2. 重复 include 会重定义 :同一个含类定义的文件被 include 两次会报"重复定义",所以头文件常用 ```ifndef / define / endif`` 保护
  3. 反引号别漏 :```include`` 前面是反引号 `````,不是普通引号
  4. import ::* 的可见性::* 是"通配导入",只有真正用到时才解析,不会强制引入所有名字造成冲突

一句话总结

include`` 是"文本复制",把文件内容粘过来,主要用于宏/头文件;`import` 是"引入符号",把 package 里编译好的类/类型/函数拿来用。UVM 里两者配对使用------`import uvm_pkg::*` 拿类,include "uvm_macros.svh"`` 拿宏,互补缺一不可。