ohsh is a humble command-line tool that works out which HDL source files
(SystemVerilog and VHDL) a design needs and in what order to compile them. Each
module gets a manifest.json that lists its sources and the modules it depends
on. ohsh reads the manifests and writes plain .src file lists, one per
library and language.
ohsh works alongside build flows such as hog, Vivado, Quartus, Questa, cocotb and VUnit. It does not run simulators, manage tool projects or parse your HDL.
- Auto-discovers HDL module manifests anywhere under a project tree.
- Resolves module dependencies recursively, across libraries.
- Detects circular dependencies and exits with an error naming the cycle.
- Emits ordered, per-library source lists for SystemVerilog and VHDL.
- Writes the order to compile the libraries in.
- Checks that every listed source file exists.
- Creates, fixes and checks manifests by reading the HDL sources (best effort).
- Pure Python with no runtime dependencies.
pip install ohshOr from a clone, which needs Python 3.9 or newer:
git clone https://github.com/logvik-org/ohsh.git
cd ohsh
pip install .The Getting started guide walks through a small project from install to compiled sources.
ohsh [OPTIONS] MODULEohsh will:
- Search for all
manifest*.jsonfiles starting from--top-dir. - Resolve dependencies for
MODULE(the top-level). - Generate ordered SystemVerilog and VHDL source lists per library.
- Write them as
<lib>_systemverilog.src/<lib>_vhdl.srcin the output directory. - Write the library compile order to
libraries.src.
| Option | Description | Default |
|---|---|---|
-t, --top-dir |
Project top-level directory, the base for manifest discovery. | cwd |
-w, --work |
Library for the top module, which work in its manifest refers to. |
work |
-o, --output |
Directory for the .src lists and libraries.src, created if missing. |
cwd |
--relative-to DIR |
Write the source paths relative to DIR. |
absolute |
--format FORMAT |
plain lists, or the list files of a hog project. |
plain |
-v, --verbose |
Show progress (-v) or debug details (-vv). |
quiet |
--log-file PATH |
Also write logs to a file (no log file is written by default). | none |
--version |
Print version and exit. | |
-h, --help |
Show help and exit. |
These options work on the manifests under --top-dir instead of writing source
lists. They read the sources to find which design units each file declares and
uses. --fix and --check work on all modules, or on MODULE and its
dependencies when one is given. See
Create, fix and check manifests.
| Option | Description | Default |
|---|---|---|
--create |
Write a manifest for every source directory that has none. | |
--fix |
Add missing dependencies to the manifests and sort their sources. | |
--check |
Report manifests that --fix would change, exit 104 if there are any. |
|
--exclude PATTERN |
With --create, skip directories matching this glob pattern. |
none |
-y, --yes |
With --create, write every manifest without asking. |
ask |
--manifest-dir DIR |
With --create, write the manifests under DIR, not next to the sources. |
next to the sources |
--no-deps |
With --fix or --check and MODULE, leave its dependencies alone. |
Give each module a manifest.json next to its sources:
project/
├── accumulator/
│ ├── accumulator.vhd
│ └── manifest.json
└── adder/
├── adder.vhd
└── manifest.json
{
"module": "accumulator",
"sources": ["accumulator.vhd"],
"dependencies": {
"work": ["adder"]
}
}{
"module": "adder",
"sources": ["adder.vhd"]
}Then run ohsh in the project directory with the top module's name:
cd project
ohsh accumulatorIt writes work_vhdl.src with the sources in compile order:
/path/to/project/adder/adder.vhd
/path/to/project/accumulator/accumulator.vhd
and libraries.src with the libraries to compile (here only work). Modules
with SystemVerilog sources go to <lib>_systemverilog.src in the same way. See
the manifest file format
for dependencies across libraries.
libraries.src lists the library names, one per line, in the order to compile
them: each library comes after the libraries it uses. Compile the libraries in
this order rather than hard-coding it. If libraries depend on each other in a
loop (a module in libA uses libB and a module in libB uses libA), no
such order exists. ohsh then logs a warning and writes a best-effort order,
which works for tools that sort files themselves (such as Vivado or Quartus
projects) but may fail with tools that compile one library at a time.
The full documentation is at ohsh.readthedocs.io:
- Getting started
- Manifest file format
- Integrations with simulators and build tools
- Create, fix and check manifests
- Exit codes
- ohsh-demo, a hog project with third-party libraries as git submodules
- Contributing and development
Licensed under the Apache License 2.0. See LICENSE and NOTICE.
Ola Groettvik - GitHub
ohsh started as a hand-written script. Most later development was done with AI assistance, with all changes reviewed and tested by the author.