SystemVerilog 中 import 和 include 的区别与联系

发布时间:2026/7/3 2:24:08
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 只是让这些名字可见::*表示引入包里所有公开符号::具体名表示只引入某一个三、核心区别对比对比项includeimport类别预处理指令有反引号语言语句处理对象文件内容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_component、uvm_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 的符号六、易错点宏不能靠 import 传递即使你import了某个 package那个包里用define定义的宏在外面也用不了——宏必须靠include重复 include 会重定义同一个含类定义的文件被 include 两次会报重复定义所以头文件常用ifndef / define / endif保护反引号别漏include前面是反引号不是普通引号import::*的可见性::*是通配导入只有真正用到时才解析不会强制引入所有名字造成冲突一句话总结include是文本复制把文件内容粘过来主要用于宏/头文件import是引入符号把 package 里编译好的类/类型/函数拿来用。UVM 里两者配对使用——import uvm_pkg::*拿类include uvm_macros.svh拿宏互补缺一不可。