VLSIChaps Academy, Track 01.

Packages, the Single Source of Truth

~12 minHands-on labone exerciseVerilator
Page 16 of 50
01

The Paste Problem at File Scale

On the tasks page, you refactored three pasted stimulus blocks into one routine. The arithmetic was simple: ten copies mean ten places for a bug. The problem generalizes beyond one block. Real projects paste definitions across modules and files; copies drift, and two parts of a testbench begin to disagree about one fact. This file has already drifted: two modules contain two pasted copies of one function, and one has quietly changed.

02

The Package

A package is a named container outside any module. It holds shared definitions, constants, types, and routines, including the functions from Page 15, declared exactly once. It is not hardware and it is not a testbench; it is a shelf. Put a definition on the shelf once, and every module that needs it takes it from the shelf instead of keeping a private copy. Drift becomes structurally impossible: a definition that exists once cannot disagree with itself.

03

Import and Scope

A module reaches the shelf through an import, either wildcard ::* or explicit. Two scoping rules bite in this lab.

Declare before use. In a single file, the package must appear above the modules that import it.

Local wins. If a module still has a local definition of a name, it silently shadows the imported one. A package plus an import is not enough; you must delete the local copies. The import becomes the only source of truth only when nothing local remains to outvote it.

04

Key Insight: Organization Is Correctness

Packages are not tidiness. The starter prints the wrong checksum today because two pasted copies drifted, exactly as real projects drift. You could patch the broken copy in place, and it would look right until the next drift. Or you can remove the possibility: one definition, one shelf, imported everywhere. The fix is not a patched bug; it is an eliminated class of bug. Organization is correctness with a memory.

Lab, one function, one shelf.

This file has alpha_unit and beta_unit, each with its own pasted copy of checksum8. The copies have drifted: beta's copy is buggy, so its wrong checksum on the first run is intended, not a platform fault. Create package chk_pkg at the top of the file, move one correct copy of the function into it, import the package in both modules, and delete both local copies so the package is the only place the function exists. Keep both print lines unchanged. Run and submit. The engine checks both printed checksums and the structure; fixing beta in place will not pass.

Three moves in order — (1) Move: take correct 4-element version of function, place inside package chk_pkg at very top of file. (2) Import: add import of chk_pkg inside each module, before function used. (3) Delete: remove both local copies — local definition silently outvotes import; shelf only becomes source of truth when nothing local remains.
Compiling, linting, and simulating...
Correct. One function, declared once, imported twice, and both checksums are right, including the one that was wrong when you arrived. Notice what actually fixed beta: not a patched loop bound, but the removal of the second copy. A definition that exists once cannot disagree with itself, and you have just made this file's worst bug structurally impossible.
Not quite. One or both checksums are wrong, and the pattern tells the story: one wrong line usually means a stale local copy is still shadowing your import, and two wrong lines that agree with each other usually mean the drifted version is the one you consolidated. The engine output and the mentor below name the module and the cause.
Structure not yet correct. Your output is correct, but the structure is not what this lab requires. The point of this page is not the checksum value, it is where the checksum function lives: once, in a package, imported by both modules, with no local copies left to drift. The mentor below explains which structural condition is unmet and why patching in place leaves the real bug alive.
Simulation timed out. The loop did not make visible progress toward a reachable exit. Check its increment and bound before trying again.
Compile error.
Something went wrong reaching the engine. Try again in a moment.
AI Mentor
Thinking...
📲 Join 20K+ Engineers