RouteRTL SDK Troubleshooting Guide
One-stop reference for common errors, organized by SDK phase. Each entry follows: Error → Cause → Fix → Diagnostic.
Use
Ctrl+Fto search for the exact error message you see in your terminal.
1. Environment & Setup
1.1 ModuleNotFoundError: No module named 'routertl'
Cause: The SDK submodule isn't on Python's import path. This happens when running a test from an unexpected directory or before activating the venv.
Fix:
# Option A: Activate the project venv
source .venv/bin/activate
# Option B: Manually inject the path
export PYTHONPATH=$PYTHONPATH:$(pwd)/vendor
The SDK auto-adds the path when project.yml is found above cwd.
1.2 No module named 'tests.ip'
Cause: Missing __init__.py files in the test directory hierarchy.
Fix: Create __init__.py in every directory from sim/cocotb/tests/ down
to your test file:
touch sim/cocotb/tests/__init__.py
touch sim/cocotb/tests/ip/__init__.py
1.3 NameError: name 'Tb' is not defined
Cause: The base testbench class is named TbEnv and lives in
tb.env, not imported automatically by the tb package.
Fix: Always import explicitly:
from tb.env import TbEnv as Tb
1.4 'make' not found / build-essential missing
Cause: Build toolchain not installed.
Fix:
sudo apt update && sudo apt install python3 python3-pip python3-venv git make build-essential
1.5 SDK path resolution fails (parents[N] is wrong)
Cause: Hard-coded path depth doesn't match the test file's directory depth.
Fix: Use the recursive parent-traversal loop instead:
from pathlib import Path
def find_sdk_path():
p = Path(__file__).resolve().parent
while p != p.parent:
candidate = p / "vendor" / "routertl" / "sim" / "cocotb"
if candidate.exists():
return candidate
p = p.parent
return None
1.6 rr doctor reports uninitialized submodules
Cause: The repository was cloned without --recurse-submodules, leaving
submodule directories empty or missing.
Fix:
git submodule update --init --recursive
rr doctor checks submodules recursively — it will also detect missing
nested submodules (e.g., an IP submodule that itself depends on a library
submodule).
1.7 rr doctor warns about missing dependency clones
Cause: The dependencies section in project.yml lists a library (e.g.,
xpm_vhdl) whose clone path doesn't exist yet.
Fix:
rr workspace update-config
This triggers the dependency auto-clone. If the primary URL fails, the SDK
tries fallback_url automatically.
2. Linting
2.1 Pre-commit hook fails with ❌ Linting failed on unrelated files
Cause: The smart linter processes all hierarchies. If a deleted or broken
file is still listed in project.yml, it becomes a Ghost Hierarchy.
Fix:
# 1. Remove the stale file from project.yml sources.syn
# 2. Clean the linter workspace
rm -rf hw/sim/work/
# 3. Re-lint
routertl linting
Diagnostic: Check if the failing entity still exists on disk:
grep -r "entity_name" project.yml
find src/ -name "entity_name*"
2.2 Pre-compilation FAILED on a pure SystemVerilog project
Cause: VHDL packages were found on disk (e.g., SDK shipped .vhd),
triggering VHDL pre-compilation despite the project being SV-only.
Fix: Ensure hardware.language: systemverilog in project.yml. Verify
no stale .vhd files exist in src/. The language-aware linter skips
VHDL Phase 1 for non-VHDL projects.
2.3 Commits blocked even for documentation-only changes
Cause: The pre-commit hook runs linting on the full hierarchy regardless of which files were staged.
Fix: For non-RTL changes only:
git commit -m "docs: update README" --no-verify
Never use
--no-verifyfor RTL changes without runningroutertl lintingfirst.
3. Simulation
3.1 HierarchyArrayObject errors on scalar signals (e.g., CLK)
Cause: GHDL + Cocotb 2.0+ incompatibility. This is an environment issue, not a code defect.
Fix: Switch to NVC as the simulator backend:
# project.yml
simulation:
simulator: nvc
Or set the environment variable: export SIM=nvc
3.2 ValueError: can't convert value 'X' to integer
Cause: Sampling a VHDL signal that is still uninitialized ('U'), unknown ('X'), or high-impedance ('Z') before reset completes.
Fix: Use a safe-read wrapper:
def safe_read(signal, default=-1):
try:
val = signal.value
if hasattr(val, 'is_resolvable'):
return int(val) if val.is_resolvable else default
return int(val)
except (ValueError, TypeError):
return default
3.3 Stale waveforms (GTKWave shows old data)
Cause: The simulator crashed mid-run or a path resolution issue left an old waveform file in place.
Diagnostic:
ls -la sim/cocotb/waves/*.fst # Check modification timestamp
Fix:
rm -rf sim_build/ vendor/routertl/sim/cocotb/build/
# Re-run simulation
routertl sim test_my_module --waves
3.4 Build artifacts land inside vendor/routertl/ instead of project root
Cause: PROJECT_ROOT not detected — no project.yml found above cwd.
Fix: Always run simulations from the project root:
cd my_project
python sim/cocotb/tests/ip/test_my_ip.py
Ensure project.yml exists at the project root.
3.5 Second test in suite hangs or fails (clock not running)
Cause: Python global state tracking clock initialization. Cocotb cleans up
coroutines between @cocotb.test() items — a global _clock_started = False
flag prevents the clock from restarting.
Fix: Always start the clock inside each test or a shared setup_dut():
async def setup_dut(dut):
cocotb.start_soon(Clock(dut.CLK, 10, units="ns").start())
# ... reset logic ...
3.6 Simulator crashes silently (sim_time_ns="0" in results)
Cause: VPI/GPI crash when accessing complex signal types (nested records, large VHDL enums) under heavy simulator load.
Diagnostic: Add marker logs around signal access:
self.log.info(">>> About to read FSM")
fsm_val = dut.fsm.value
self.log.info(f"<<< FSM = {fsm_val}")
Fix: Use try/except blocks around enum accesses, or verify via simpler
signals (bit-vectors, counters). Run failing test in isolation to rule out
sequential suite contamination.
3.7 DeprecationWarning: .integer property is deprecated
Cause: Cocotb 2.0 API change.
Fix: Replace .value.integer with:
value.to_unsigned()— for unsigned vectorsvalue.to_signed()— for signed vectorsint(value)— for simple conversion
3.8 cocotb.log.debug() messages not appearing in log files
Cause: The SDK's simulation log files capture INFO level and above only.
self.log.debug() calls are silently dropped.
Fix: Use self.log.info() for diagnostic prints. Remember to revert them
to self.log.debug() before committing.
4. Synthesis & Implementation
4.1 make synthesis fails: Vivado not found
Cause: Vivado is not on PATH or VIVADO_PATH is not set.
Diagnostic:
routertl workspace check-env
which vivado
Fix: Source the Vivado settings script:
source /opt/Xilinx/Vivado/2024.1/settings64.sh
Or set explicitly in project.yml:
makefile_overrides:
VIVADO_PATH: /opt/Xilinx/Vivado/2024.1
4.2 Regbank generation fails for SystemVerilog projects
Cause: The regbank and ROM-info generators currently emit VHDL only. See LANGUAGE_SUPPORT_TODO.md for the roadmap.
Fix: Set features.regbank: false in project.yml for pure SV projects,
or use the generated VHDL packages alongside your SV code (mixed-language flow).
4.3 build_env.mk is stale / configuration mismatch
Cause: project.yml was modified but build_env.mk wasn't regenerated.
Fix:
routertl workspace update-config
5. Embedded Linux
5.1 Docker container can't find VIVADO_PATH
Cause: The Docker container doesn't inherit host environment variables automatically.
Fix: Pass the path explicitly:
routertl docker run vivado "make synthesis VIVADO_PATH=/tools/Xilinx/Vivado/2024.1"
5.2 sw_repos not cloned
Cause: The linux.sw_repos list is defined but fetch_sw_repos.sh hasn't
been run.
Fix:
routertl linux fetch-sw
5.3 Memory map mismatch between YAML and Vivado block design
Cause: system_memory_map.yml was updated but the Vivado address map
wasn't re-synchronized.
Fix:
routertl linux mmap # Regenerate TCL and update Vivado
routertl linux crosscheck # Verify YAML vs hardware
6. Quick Diagnostic Commands
| Scenario | Command |
|---|---|
| Check tool availability | routertl workspace check-env |
| Full environment health check | routertl doctor |
| View tracked source files | routertl workspace sources |
| List discovered tests | routertl scan-tests |
| Force config regeneration | routertl workspace update-config |
| Clean all build artifacts | routertl workspace clean |
| Verify SDK submodule state | git -C vendor/routertl log -1 --oneline |
| Check all submodules (recursive) | git submodule status --recursive |
| Check for Ghost Hierarchies | routertl linting 2>&1 | grep FAIL |
| Run SDK internal regression | make regression (from vendor/routertl/) |
7. Known Environment Issues
| Issue | Scope | Workaround |
|---|---|---|
GHDL + Cocotb 2.0+ HierarchyArrayObject | Simulation | Use NVC instead of GHDL |
| NVC VPI crash on complex VHDL enums | Rare, sequential suites | Run tests in isolation |
Verilator WIDTHEXPAND warnings | SV simulation | Add -Wno-WIDTHEXPAND to build_args |
| Regbank generates VHDL only | SV projects | Set features.regbank: false |
| Mixed VHDL+SV simulation | All tools | Not yet supported — use Questa/Riviera |
Last updated: 2026-03-08