← Design Verification Interviews

Interview Question · Concept

Import Versus Include

L1 JuniorL2 Mid-Levelsystemverilogpackagesscope

The Question

The interviewer asks

What is the difference between import axi_pkg::*; and an include "axi_txn.svh" directive? How can the wrong choice break a testbench?

Reveal the Model Answer

An include directive pastes text, so every file that includes a class declares its own copy. Copies declared in different scopes are different types, and you cannot assign one to the other. import makes the names of one compiled package visible, so every importer shares one type. Include class files only inside their package, and import the package wherever the classes are used.

Two Includes Make Two TypesOne class file included into two packages, and the fix. Arrows from the file are text pasted by include; other arrows show where each type comes from.
Two includes make two typesOne class file included into two packages, and the fix. Arrows from the file are text pasted by `include`; other arrows show where each type comes from. component txn.svh class txn ... endclass component package a_pkg `include "txn.svh" component package b_pkg `include "txn.svh" component a_pkg::txn one type component b_pkg::txn a different type,same text component Assignment fails a handle of onecannot hold the other component The fix: packagecommon_pkg include txn.svh once;other packagesimport it pastedpasted againincluded once
Read the diagram as text
  • txn.svh: class txn ... endclass
  • package a_pkg: `include "txn.svh"
  • package b_pkg: `include "txn.svh"
  • a_pkg::txn: one type
  • b_pkg::txn: a different type, same text
  • Assignment fails: a handle of one cannot hold the other
  • The fix: package common_pkg: include txn.svh once; other packages import it
  • txn.svh → package a_pkg: pasted
  • txn.svh → package b_pkg: pasted again
  • package a_pkg → a_pkg::txn
  • package b_pkg → b_pkg::txn
  • a_pkg::txn → Assignment fails
  • b_pkg::txn → Assignment fails
  • txn.svh → The fix: package common_pkg: included once

include copies text. import shares one compiled declaration, so every user sees the same type.

Include inside the package, import everywhere else.
// axi_pkg.sv: the only place the class files are included
package axi_pkg;
  `include "axi_txn.svh"
  `include "axi_driver.svh"
endpackage

// any user
module tb;
  import axi_pkg::*;
  axi_txn t;     // one type, shared by every importer
endmodule

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer calls include a text paste and import a way to make names visible. It keeps every include inside one package.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyBreak ItCompareScale It

  1. Import Versus Include
  2. WhyWhy Two Identical Classes Are Two TypesL1 JuniorL2 Mid-Level

    The two item classes are character-for-character identical. Why does the compiler refuse to assign one to the other?

    Reveal the Model Answer

    Class types match by declaration, not by their text. Each declaration creates its own type, with its own static members and its own place in the hierarchy. If the compiler matched classes by text, a change to one copy would silently change the meaning of code using the other. Verilator 5.052 reports it as "expects a CLASSREFDTYPE 'item', got CLASSREFDTYPE 'item'", which looks absurd until you see the two scopes.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Add ifndef guards to the class file and the duplicate goes away."

    Guards stop a second paste within one compilation unit. Two packages are separate scopes, so each still declares its own class.

  3. Break ItTwo Packages That Export the Same NameL2 Mid-Level

    A module does import apb_pkg::*; import axi_pkg::*; and both packages define config_t. When does it fail, and how do you fix it?

    Reveal the Model Answer

    Importing both is legal; it fails only where config_t is referenced, because the name is visible from two packages and neither wins. Write axi_pkg::config_t at the use, or import that one name explicitly with import axi_pkg::config_t;.

    Self-Check

    Tick each key point you covered in your answer.

    Spec Misquote

    "The package imported last wins."

    Wildcard imports have no priority order. A reference to a name made visible by two wildcard imports is an error.

    Source IEEE 1800-2017 §26.3

  4. CompareWildcard, Explicit and Scoped Package ReferencesL1 Junior

    Compare import pkg::*;, import pkg::name; and writing pkg::name at each use.

    Reveal the Model Answer

    A wildcard import offers every name, but only where nothing local claims it first. An explicit import brings one name in as if it were declared there. A local declaration of the same name is then a compile error, not a silent winner. A scoped reference pkg::name needs no import and names the source at every use. It is the clearest choice in shared code.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "An explicit import and a wildcard import behave the same for one name."

    They differ exactly when a local declaration exists: it hides the wildcard name quietly but collides with the explicit import.

    Source IEEE 1800-2017 §26.3

  5. Scale ItPackage Structure for Reusable Verification IPL2 Mid-LevelL3 Senior

    Asked if they mention reuse across teams

    Several teams will reuse your AXI and APB agents in one SoC bench. How do you organise the packages and files?

    Reveal the Model Answer

    Use one package per agent, holding its transaction, driver, monitor and configuration. Include the class files only there, and put nothing at compilation-unit scope. Shared types live in a small common package that the agent packages import. The dependency graph then has no cycles, and compile order is fixed. Interfaces stay outside packages, because a package cannot contain them.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer draws the package dependency graph and keeps it free of cycles. It names the cost of a common package: every change to it recompiles everything.

    Wrong Altitude

    Puts every class of every agent in one big package "to keep it simple".

    Every team then recompiles and re-reviews everything for a change in one agent, and name collisions between agents become likely.

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"Including the same class file in two packages still gives one class."

Type identity comes from where a class is declared, not from its text. a_pkg::item and b_pkg::item are different types, and assigning one to the other is a compile error.

Source IEEE 1800-2017 §6.22.1

Missed Corner

"A wildcard import always brings in the package's value."

A wildcard import only fills names that are not declared locally. The twin has a leftover local with the same name, and the package value is silently ignored.

Run It

A package value and a local declaration with the same name, after import cfg_pkg::*.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: timeout=50 FAIL: the local declaration hides the wildcard import, so the package value is never used
See the Fix
package cfg_pkg;
  int timeout_cycles = 1000;
endpackage
module tb;
  import cfg_pkg::*;
  int timeout_cycles = 50;      // a local left over from a quick debug session
  initial begin
    $display("timeout=%0d", cfg_pkg::timeout_cycles);
    if (cfg_pkg::timeout_cycles == 1000) $display("PASS: the explicit package reference reads the package value");
  end
endmodule

Prints: timeout=1000 PASS: the explicit package reference reads the package value

Half-Truth

"Use wildcard imports everywhere; they are harmless."

They are convenient until two packages export the same name. Referring to it is then an error, and a local declaration can hide either one, so shared code benefits from explicit pkg::name.

Learn It, Then Prove It