API Reference

This section documents ALY’s Python API for programmatic access.

Overview

ALY’s API is organized into modules:

digraph api { rankdir=TB; node [shape=box, style="rounded,filled", fontname="sans-serif"]; aly [label="aly", fillcolor="#e3f2fd"]; config [label="aly.config", fillcolor="#e8f5e9"]; models [label="aly.config.models", fillcolor="#c8e6c9"]; backends [label="aly.backends", fillcolor="#fff3e0"]; app [label="aly.app", fillcolor="#f3e5f5"]; aly -> config; aly -> backends; aly -> app; config -> models; }

Figure 26 API Module Structure

Configuration API

ProjectConfig

class aly.config.ProjectConfig[source]

Bases: object

Unified configuration manager and component registry for ALY projects.

Loads configuration from .aly/ directory and discovers components through manifest.yaml files in configured paths. Provides unified access to all project settings and components.

Example

config = ProjectConfig.load(“.”)

# Access project info print(config.info.name)

# Get RTL block cpu = config.get_rtl_block(“cpu”)

# Get testbench tb = config.get_testbench(“tb_alu”)

# List all components rtl_blocks = config.list_rtl_blocks()

# Resolve dependencies deps = config.resolve_rtl_deps(tb)

__init__(project_root)[source]

Initialize configuration manager.

Parameters:

project_root (Path)

classmethod load(project_root)[source]

Load configuration from project root.

Parameters:

project_root (Path | str) – Path to project root directory

Returns:

Loaded ProjectConfig instance

Raises:

SystemExit – If configuration is missing or invalid

Return type:

ProjectConfig

discover_all()[source]

Scan all configured paths for manifest.yaml files.

This is the main discovery method that populates the component registry. It’s called lazily on first access to any get/list method.

Return type:

None

get(manifest_type, name)[source]

Get a manifest by type and name.

Parameters:
  • manifest_type (str) – Component type (rtl, ip, testbench, firmware, test_suite)

  • name (str) – Manifest name

Returns:

Manifest object or None if not found.

Return type:

Any | None

list(manifest_type)[source]

List all manifest names of a specific type.

Parameters:

manifest_type (str) – Component type

Returns:

List of manifest names.

Return type:

List[str]

get_all(manifest_type)[source]

Get all manifests of a specific type.

Parameters:

manifest_type (str) – Component type

Returns:

Dict mapping name to manifest object.

Return type:

Dict[str, Any]

get_unit(kind, name)[source]

Get a unit (rtl_module, testbench, firmware_build, …) by kind and name.

Parameters:
Return type:

UnitRef | None

list_units(kind)[source]

List all unit names of a given kind.

Parameters:

kind (str)

Return type:

List[str]

get_rtl_module(name)[source]

Get a single RTL module unit by name.

Parameters:

name (str)

Return type:

UnitRef | None

list_rtl_modules()[source]

List all RTL module unit names.

Return type:

List[str]

iter_rtl_modules()[source]

Iterate over all RTL module units.

Yields:

UnitRef objects for each RTL module.

get_rtl_module_objects()[source]

Get all RTL modules with their parent manifests.

Returns:

module_name -> (module_obj, parent_manifest)

Return type:

Dict

get_rtl_module_files(module_name)[source]

Get compilation files (packages + module files) for a given RTL module.

Module is looked up project-wide, by name.

Parameters:

module_name (str)

Return type:

List[Path]

get_rtl_module_package_files(module_name)[source]

Get package files that apply to a given RTL module.

Parameters:

module_name (str)

Return type:

List[Path]

get_testbench_unit(name)[source]

Get a single testbench unit by name.

Requires that TestbenchManifest exposes a testbenches list and that _register() populates _units[“testbench”].

Parameters:

name (str)

Return type:

UnitRef | None

list_testbench_units()[source]

List all testbench unit names.

Return type:

List[str]

get_testbench(name)[source]

Get a testbench by name (returns Testbench object).

This is a convenience method that returns the testbench object directly, rather than the UnitRef wrapper.

Parameters:

name (str)

Return type:

Any | None

list_testbenches()[source]

List all testbench names.

Convenience alias for list_testbench_units().

Return type:

List[str]

iter_testbenches()[source]

Iterate over all testbench units.

Yields:

UnitRef objects for each testbench.

get_testsuite(name)[source]

Get a test suite by name (searches all testbench manifests).

Returns:

TestSuite object or None if not found.

Parameters:

name (str)

Return type:

Any | None

list_testsuites()[source]

List all test suite names.

Return type:

List[str]

resolve_rtl_deps(unit, _visited=None)[source]

Recursively resolve RTL dependencies for a unit (testbench or RTL module).

Parameters:
  • unit (Any) – Testbench or RTLModule object with dependencies list

  • _visited (set | None) – Internal set to track visited modules and prevent cycles

Returns:

List of UnitRef objects (containing both RTLModule obj and RTLManifest manifest) in dependency order (dependencies before dependents)

Return type:

List[UnitRef]

resolve_package_deps(testbench)[source]

Resolve package dependencies for a testbench.

Parameters:

testbench (Any) – Testbench object with dependencies list

Returns:

List of UnitRef objects (containing RTLPackage obj and parent RTLManifest)

Return type:

List[UnitRef]

resolve_package_dep_files(testbench)[source]

Resolve package dependencies for a testbench and return file paths.

Parameters:

testbench (Any) – Testbench object with dependencies list

Returns:

List of resolved Paths for package files.

Return type:

List[Path]

get_package_unit(name)[source]

Get a package unit by name.

Parameters:

name (str) – The package name to look up.

Returns:

UnitRef containing the RTLPackage obj and parent RTLManifest.

Return type:

UnitRef | None

get_package(name)[source]

Get a package by name (returns RTLPackage object).

This is a convenience method that returns the package object directly, rather than the UnitRef wrapper.

Parameters:

name (str)

Return type:

RTLPackage | None

list_packages()[source]

List all named package names.

Return type:

List[str]

iter_packages()[source]

Iterate over all package units.

Yields:

UnitRef objects for each named package.

get_package_file(name)[source]

Get the resolved file path for a package by name.

Parameters:

name (str) – The package name to look up.

Returns:

Resolved Path if found and exists, None otherwise.

Return type:

Path | None

get_package_files_by_names(names)[source]

Get package files by their names (for dependency resolution).

Parameters:

names (List[str]) – List of package names to include.

Returns:

List of resolved paths for the named packages.

Return type:

List[Path]

get_firmware_build(name)[source]

Get a single firmware build unit by name.

Requires that FirmwareManifest exposes a builds list and that _register() populates _units[“firmware_build”].

Parameters:

name (str)

Return type:

UnitRef | None

list_firmware_builds()[source]

List all firmware build unit names.

Return type:

List[str]

get_firmware(name)[source]

Get a firmware build by name (returns FirmwareBuild object).

This is a convenience method that returns the build object directly, rather than the UnitRef wrapper.

Parameters:

name (str)

Return type:

FirmwareBuild | None

list_firmware()[source]

List all firmware build names.

Convenience alias for list_firmware_builds().

Return type:

List[str]

iter_firmware_builds()[source]

Iterate over all firmware build units.

Yields:

UnitRef objects for each firmware build.

get_toolchain(name)[source]

Get a toolchain by name.

Parameters:

name (str)

Return type:

Toolchain | None

list_toolchains()[source]

List all loaded toolchain names.

Return type:

List[str]

get_ip(name)[source]

Get an IP manifest by name.

Parameters:

name (str)

Return type:

IPManifest | None

list_ips()[source]

List all discovered IP manifest names.

Return type:

List[str]

property sim: SimConfig

Simulation configuration.

property synth: SynthConfig

Synthesis configuration.

property lint: LintConfig

Lint configuration.

property constraints: ConstraintsConfig

Constraints configuration.

property fpga: FPGAConfig

FPGA configuration.

is_enabled(feature)[source]

Check if a feature is enabled.

Parameters:

feature (str)

Return type:

bool

resolve_path(path)[source]

Resolve path relative to project root.

Parameters:

path (str | Path)

Return type:

Path

get_sim_tool(name=None)[source]

Get simulator tool configuration.

Parameters:

name (str | None)

Return type:

SimToolConfig | None

refresh()[source]

Force re-discovery of all manifests.

Return type:

None

summary()[source]

Get a summary of discovered components by type.

Returns:

Dict mapping component type to count

Return type:

Dict[str, int]

validate_all()[source]

Validate all discovered components.

Returns:

Dict mapping component type to list of validation messages

Return type:

Dict[str, List[Any]]

The main configuration class for loading and accessing project settings.

Example:

from aly.config import ProjectConfig

# Load project configuration
config = ProjectConfig.load()

# Access project info
print(f"Project: {config.project.name}")
print(f"Version: {config.project.version}")

# Get simulation config
sim_config = config.simulation
print(f"Default simulator: {sim_config.default_tool}")

Model Classes

RTLManifest

class aly.config.models.RTLManifest

RTL component manifest.

name: str

Manifest name

type: str

Must be “rtl”

modules: List[RTLModule]

List of RTL modules

packages: List[RTLPackage]

SystemVerilog packages

classmethod load(path: Path) RTLManifest

Load manifest from YAML file.

get_module(name: str) RTLModule | None

Get module by name.

get_all_files() List[Path]

Get all RTL source files.

Example:

from pathlib import Path
from aly.config.models import RTLManifest

# Load RTL manifest
manifest = RTLManifest.load(Path("rtl/manifest.yaml"))

# Iterate modules
for module in manifest.modules:
    print(f"Module: {module.name}")
    for f in module.get_files():
        print(f"  - {f}")

RTLModule

class aly.config.models.RTLModule

Single RTL module definition.

name: str

Module identifier

top: str

Top-level module name

files: List[str]

Source file paths/patterns

deps: List[str]

Dependencies on other modules

get_files() List[Path]

Resolve and return all source files.

resolve_files(manifest_dir: Path) List[Path]

Resolve files relative to manifest directory.

TestbenchManifest

class aly.config.models.TestbenchManifest

Testbench manifest for simulation.

name: str

Manifest name

testbenches: List[Testbench]

Testbench definitions

test_suites: List[TestSuite]

Test suite groupings

classmethod load(path: Path) TestbenchManifest

Load from YAML file.

get_testbench(name: str) Testbench | None

Get testbench by name.

Testbench

class aly.config.models.Testbench

Single testbench definition.

name: str

Testbench identifier

top: str

Top module name

files: List[str]

Testbench source files

rtl_deps: List[str]

RTL module dependencies

fw_deps: List[str]

Firmware dependencies

timeout: str | None

Simulation timeout

FirmwareManifest

class aly.config.models.FirmwareManifest

Firmware build manifest.

name: str

Manifest name

toolchain: Toolchain

Compiler toolchain config

builds: List[FirmwareBuild]

Build definitions

classmethod load(path: Path) FirmwareManifest

Load from YAML file.

get_build(name: str) FirmwareBuild | None

Get build by name.

IPManifest

class aly.config.models.IPManifest

Vendor IP block manifest.

name: str

IP name

vendor: str

Vendor name

version: str

IP version

files: List[str]

RTL source files

binaries: Dict[str, str]

Precompiled models

parameters: Dict[str, Any]

Configurable parameters

classmethod load(path: Path) IPManifest

Load from YAML file.

get_rtl_files() List[Path]

Get RTL source files.

has_simulation_model() bool

Check for precompiled simulation model.

Backend API

Backends provide tool abstraction for simulation and synthesis.

@startuml
skinparam backgroundColor transparent
skinparam defaultFontName sans-serif

interface SimulatorBackend {
   +compile(sources, options)
   +elaborate(top, options)
   +simulate(options)
}

interface SynthBackend {
   +synthesize(sources, top, options)
   +implement(options)
   +generate_bitstream()
}

class XSimBackend
class QuestaBackend
class VerilatorBackend

class VivadoBackend
class YosysBackend

SimulatorBackend <|.. XSimBackend
SimulatorBackend <|.. QuestaBackend
SimulatorBackend <|.. VerilatorBackend

SynthBackend <|.. VivadoBackend
SynthBackend <|.. YosysBackend
@enduml

Figure 27 Backend Class Hierarchy

SimulatorBackend

Base interface for simulation backends.

class aly.backends.SimulatorBackend

Abstract base for simulator backends.

abstractmethod compile(sources: List[Path], options: Dict) bool

Compile HDL sources.

abstractmethod elaborate(top: str, options: Dict) bool

Elaborate design hierarchy.

abstractmethod simulate(options: Dict) SimResult

Run simulation.

SynthBackend

Base interface for synthesis backends.

class aly.backends.SynthBackend

Abstract base for synthesis backends.

abstractmethod synthesize(sources: List[Path], top: str, options: Dict) bool

Run synthesis.

abstractmethod implement(options: Dict) bool

Run implementation (place & route).

abstractmethod generate_bitstream() Path

Generate programming file.

Utility Functions

Logging

aly.log.get_logger(name: str) Logger

Get a configured logger.

Parameters:

name – Logger name

Returns:

Configured logger instance

aly.log.setup_logging(level: str = 'INFO')

Configure logging for CLI usage.

Parameters:

level – Log level (DEBUG, INFO, WARNING, ERROR)

Configuration Utilities

aly.configuration.find_project_root(start: Path = None) Path | None

Find project root by looking for .aly directory.

Parameters:

start – Starting directory (default: current directory)

Returns:

Project root path or None

Template System

class aly.templates.TemplateLoader[source]

Load and render project templates.

classmethod list_templates() List[TemplateInfo][source]

List available templates.

load(name: str) TemplateLoader

Load template by name.

render(output_dir: Path, variables: Dict)

Render template to output directory.

Usage Examples

Loading a Project

from aly.config import ProjectConfig
from aly.configuration import find_project_root

# Find and load project
root = find_project_root()
if root:
    config = ProjectConfig.load(root)
    print(f"Loaded project: {config.project.name}")

Running Simulation

from pathlib import Path
from aly.config import ProjectConfig
from aly.config.models import RTLManifest, TestbenchManifest
from aly.sim_xsim import XSimBackend

# Load configuration
config = ProjectConfig.load()

# Load manifests
rtl = RTLManifest.load(Path("rtl/manifest.yaml"))
tb = TestbenchManifest.load(Path("tb/manifest.yaml"))

# Get testbench
testbench = tb.get_testbench("tb_counter")

# Collect sources
sources = []
for dep in testbench.rtl_deps:
    module = rtl.get_module(dep)
    sources.extend(module.get_files())
sources.extend(testbench.get_files())

# Run simulation
backend = XSimBackend(config.simulation)
backend.compile(sources, {"waves": True})
backend.elaborate(testbench.top, {})
result = backend.simulate({"timeout": "1ms"})

print(f"Simulation {'passed' if result.passed else 'failed'}")

Programmatic Synthesis

from pathlib import Path
from aly.config import ProjectConfig
from aly.config.models import RTLManifest
from aly.synth_vivado import VivadoBackend

# Load configuration
config = ProjectConfig.load()
rtl = RTLManifest.load(Path("rtl/manifest.yaml"))

# Get target configuration
target = config.synthesis.get_target("arty_a7")

# Collect all RTL files
sources = rtl.get_all_files()

# Run synthesis
backend = VivadoBackend(config.synthesis)
backend.synthesize(
    sources=sources,
    top=target.top,
    part=target.part,
    constraints=target.constraints
)

Next Steps