hdlpkg

HDL IP Packager

Ship hardware IP
the way software
ships code.

Package, version, resolve, and distribute Verilog / VHDL / SystemVerilog IP cores — with the reproducibility your software teams already take for granted.

$ pip install hdlpkg
Read the docs → View on GitHub
v0.14.1 open source · MIT ip.toml → ip.lock

The problem

HDL reuse today is copy-paste and crossed fingers

Today, reusing hardware IP means copying directories and pinning git submodules. It mostly works — until it doesn’t, and the cost lands at the worst possible time.

Versions drift

Copied folders and pinned submodules go stale silently. A “^1.2.0” means something different the moment the producer publishes again.

Every desk resolves differently

No shared solver, no shared lockfile. Two engineers integrate the same core and end up with two different builds.

No proof for the tape-out

When it ships, nobody can say which exact FIFO went in — let alone reproduce that build five years later for an audit.

How it works

Manifest → resolver → lockfile → cache

The same mental model as pip, npm, or cargo — applied to RTL. Constraints in, an exact verified graph out.

01

Describe ip.toml

Declare each IP core once in a small manifest — vendor, library, name, version, filesets, and tool targets.

02

Resolve the graph

A backtracking solver walks the entire transitive dependency graph and picks one exact, mutually-compatible version of every core.

03

Lock ip.lock

The solved graph is pinned to exact versions, sources, and SHA-256 checksums in a committed lockfile — your reproducibility contract.

04

Install --locked

Fetch exactly the locked versions into a content-addressed cache, verifying every digest. Then generate inputs for your sim / synth flow.

# ip.toml — describe your core once
[package]
vendor  = "gbra"
library = "fpga-ip"
name    = "uart"
version = "1.2.0"

[dependencies]
"gbra:fpga-ip:fifo" = "^1.0.0"

[targets.sim]
toolflow = "icarus"
filesets = ["rtl", "verification"]
# resolve + fetch + verify + write lock
$ hdlpkg install
# reproducible CI install from the lock
$ hdlpkg install --locked

Fits your environment

Drops into the flow you already have

hdlpkg doesn’t ask you to migrate your tools or your infrastructure. It slots in beside them.

Your registries

Publish over infrastructure you already run — Artifactory, Harbor, or a plain directory. One team publishes a core; every other team consumes the exact same verified bits.

Your tool flows

Generates ready-to-run inputs for your simulator and synthesis flows without touching your existing Makefile or scripts.

Real hardware messiness

Handles vendor version codes, Tcl-generated IP, and multi-version conflicts — the things that break naïve folder copies.

Audit-ready by default

Every build ships with an SBOM and content checksums, so you can prove exactly which bits went into the design.

Tool flows: Icarus VerilogVerilatorVivadoGHDLYosys

Proof

Reproducible, audit-ready builds

Minutes

Integration measured in minutes, not weeks.

Bit-identical

Every desk and CI runner rebuilds the same versions, verified against the lock.

SBOM + checksums

Reproducible, audit-ready builds out of the box.

“Less time integrating and re-verifying. More time designing.”

Get started

Install it in one line

Open source under the MIT license. The 1.0 format-stability freeze is underway — try it on a real core today.

$ pip install hdlpkg
# grab a core and peek at its files
$ hdlpkg pull gbra:fpga-ip:fifo:1.0.0
# resolve + install your project's dependencies
$ hdlpkg install
# publish a core to your registry
$ hdlpkg publish