Macros
A macro defined with `define is a declaration like any other: navigation, Find Usages and Rename work on it,
across files.
Where a macro is used
Section titled “Where a macro is used”| Use | Example |
|---|---|
| A macro call, with or without arguments, in any expression or as a statement | `WIDTH, `MAX(a, b), `LOG("hi") |
| Conditional compilation | `ifdef WIDTH, `ifndef WIDTH, `elsif WIDTH |
| Undefining it | `undef WIDTH |
| Inside the body of another macro | `define BUS_W (`WIDTH * 2) |
A macro call on its own line is a statement or item whether or not it ends with ;: in
`uvm_info("ID", "msg", UVM_LOW)x = 1;x = 1; is an assignment to x. A macro used as a type declares the name after it only on the same line
(`REG_T(8) r;). Arguments may be empty (`M(, x)) or be code other than an expression, such as a
constraint block in `uvm_do_with(req, { addr == 5; }); names inside such an argument are not navigable.
From any of these, Navigate | Declaration or Usages (⌘B / Ctrl+B) opens the `define. If the macro
is defined in several places, you choose; a `define in an inactive `ifdef branch is not a definition (see
Conditional compilation). Find Usages
(⌥F7 / Alt+F7) on a `define lists every use above, and Rename (⇧F6 / Shift+F6) renames the
definition and all its uses. The macro’s name is what is renamed; its formal arguments (`define MAX(a, b)) are
not part of the name.
Names passed to a macro
Section titled “Names passed to a macro”A name passed on its own as a macro argument is a use of that name. Go to Declaration works on it, and Find Usages and Rename of the declaration include it:
class my_item extends uvm_sequence_item; rand bit [7:0] addr; `uvm_object_utils_begin(my_item) // the class my_item `uvm_field_int(addr, UVM_ALL_ON) // the property addr `uvm_object_utils_endendclassThe macro’s body decides how an argument is used, so the name refers to whatever declaration of it is visible at
that point: a class or type, a variable or parameter, a function or task, a module, or a package. The usual lookup
applies: a local declaration hides a class of the same name elsewhere in the project, pkg::name names a package
member, and a name from a package that is not imported gets the same warning and quick
fix as anywhere else. This holds for macro calls inside expressions
(x = `CREATE(my_item);) and for nested calls (`A(`B(my_item))). A name that is only part of an argument
(`MAX(a + 1, b), `SHOW(h.f), `M(f(1, a))) is resolved like that expression outside a macro.
Completion and documentation
Section titled “Completion and documentation”After a backtick, Code | Code Completion (⌃Space / Ctrl+Space) offers the project’s macros, marked
macro and shown with their formal arguments (`WAIT_CYCLES(n)), and the compiler directives (`define,
`ifdef, `include, …), marked directive. Ordinary names and keywords are not offered there.
Names match from their start, ignoring case (`la offers LANES). Not inside strings, comments, or after a
token-pasting ``.
Quick Documentation (F1 / Ctrl+Q) on a macro use shows its `define with the body (the first 40
lines) and the file it is defined in; hovering with ⌘ (Ctrl) shows the `define line. For a macro
defined in several places, there is one entry per definition.
Macros are also listed by Go to Symbol (⌥⌘O / Ctrl+Alt+Shift+N).
Limitations
Section titled “Limitations”- Predefined macros (
`__FILE__,`__LINE__) and macros defined on the tool’s command line (+define+) have no`defineto go to. - Formal arguments inside a macro body are not navigable.
- Names declared by the code a macro expands to, such as
type_idinmy_item::type_id::create, are not navigable (see Known limitations).
Try it
Section titled “Try it”- Open
rtl/top.svfrom the sample project. ⌘-click (Ctrl-click)`LANESin the generate loop.rtl/defines.svhopens at`define LANES 2. - In
rtl/defines.svh, ⌘-clickDEFINES_SVHin`ifndef DEFINES_SVH. You land on the`define DEFINES_SVHline below it. - Put the caret on
LANESin`define LANES 2and press ⌥F7 (Alt+F7): the use inrtl/top.svis listed. - Press ⇧F6 (Shift+F6) and rename it to
LANE_COUNT. The`defineand the use inrtl/top.svboth change. Undo afterwards. - In
rtl/top.sv, add a linelocalparam int N = `LAand press ⌃Space (Ctrl+Space). The only match,LANES, is completed. Undo afterwards. - Open
uvm/my_pkg.sv, put the caret onmy_driverinclass my_driver extendsand press ⌥F7 (Alt+F7). The use in`uvm_component_utils(my_driver)on the next line is listed.