Hardware projects often reuse the same ideas: stream interfaces, register banks, UARTs, FIFOs, parsers, protocol adapters, test fixtures, and vendor wrappers. Packages are how reusable Livt code can move between projects.
A package is more than a folder of source files. It should provide a clear public API, tests, versioning, and documentation.
What Belongs in a Package
A good package contains a coherent capability:
- a protocol interface and helpers
- a reusable component
- a family of related components
- a simulation fixture
- a vendor wrapper
- shared constants and types
Avoid packages that are just miscellaneous utilities. Reuse works best when the package has a clear domain.
Package vs IP
In FPGA workflows, "IP" often means a reusable hardware block, sometimes with vendor-specific configuration and generated files. A Livt package can contain IP, but the concepts are not identical.
A Livt package may include:
- Livt source code
- interfaces
- tests
- documentation
- generated or wrapped VHDL
- vendor integration notes
An IP block is usually one reusable hardware asset. A package is the delivery and maintenance unit around reusable code.
Public APIs
The public API of a package is what users should depend on:
- public components
- public interfaces
- public constants
- documented constructor parameters
- documented functions and fields
Everything else should be treated as implementation detail. If users depend on private structure, the package becomes hard to change.
Versioning
Reusable hardware code needs versioning. A small change to a signal direction, constructor parameter, reset behavior, or latency can break users.
When changing a package, ask:
- Did a public interface change?
- Did a component constructor change?
- Did timing or latency change?
- Did reset behavior change?
- Did generated VHDL ports change?
If the answer is yes, document the change clearly and update the version in a way that signals compatibility.
Tests in Packages
A package should carry its own tests. Tests are what make reuse safe:
my-stream-package/
|-- src/
| |-- IByteStream.lvt
| `-- StreamBuffer.lvt
`-- tests/
`-- StreamBufferTest.lvt
The package tests should verify the public contract, not every private detail. Users need confidence that the package behaves as advertised.
Documentation
Document the things a user needs to know:
- what the package provides
- how to instantiate the main components
- what interfaces mean
- timing assumptions
- reset behavior
- simulation-only utilities
- vendor requirements
Short examples are often more useful than long prose. Show the smallest correct usage first.
Reuse Guidelines
Before extracting code into a package, make sure the boundary is stable. Code that is still changing rapidly may be easier to keep inside the application until the shape is clearer.
Extract a package when:
- at least two projects or subsystems need the same code
- the interface is stable
- the tests are strong enough to protect users
- the package has a clear owner
Summary
Packages turn local design work into reusable hardware assets. Treat package APIs with care: document them, test them, version them, and keep implementation details private.