CoreIR Python Bindings
Python bindings for CoreIR, an intermediate representation for hardware. This library provides a programmatic interface to build, manipulate, and analyze hardware circuits using Python. Currently at version 2.0.156, it maintains an active development pace with frequent updates, primarily leveraging a Rust-based CoreIR backend.
Common errors
-
ModuleNotFoundError: No module named 'pycoreir'
cause The user attempted to import the library using the repository name (`pycoreir`) instead of the correct PyPI package name (`coreir`).fixChange the import statement to `import coreir`. Ensure the package is installed via `pip install coreir`. -
TypeError: Expected CoreIRType, got <class 'int'> (or similar for other Python types)
cause A native Python type (e.g., `int`, `list`, `bool`) was provided where CoreIR expects its own type objects (e.g., `coreir.Bit()`, `coreir.BitIn().Arr(N)`).fixUse CoreIR context methods to define all types for ports and instances, e.g., `context.Bit()`, `context.BitIn().Arr(width)`, `context.Record(...)`. -
RuntimeError: Failed to load CoreIR library. Ensure it is installed and in your PATH. (or similar DLL/shared library load error)
cause The underlying Rust CoreIR binary library, which the Python bindings depend on, could not be found or loaded. This can indicate a corrupted installation, environment issue, or path problem.fixReinstall `coreir` in a fresh virtual environment (`pip install coreir --force-reinstall`). If the issue persists, verify system PATH and library search paths for the CoreIR shared library (e.g., `.so`, `.dll`, `.dylib`). -
AttributeError: 'Context' object has no attribute 'newModule' (or similar for outdated API calls)
cause The Python API for CoreIR has evolved, and method names (e.g., `newModule` vs `new_module`) or their signatures have changed between versions. The error indicates an attempt to use an old API method.fixConsult the latest CoreIR Python documentation (available at `pycoreir.readthedocs.io`) to update your code to the current API methods and parameter conventions.
Warnings
- breaking The underlying CoreIR library underwent a significant rewrite from C++ (CoreIR 1.x) to Rust (CoreIR 2.x). Python bindings for versions 2.x are incompatible with previous versions, requiring code migration for users coming from very old 'pycoreir' installations.
- gotcha The GitHub repository is named `leonardt/pycoreir`, but the official PyPI package for installation is `coreir`. Attempting `pip install pycoreir` or `import pycoreir` will fail.
- gotcha CoreIR uses a specific internal type system (e.g., `context.Bit()`, `context.BitIn().Arr(N)`). Directly using native Python types (like `int`, `list`, `bool`) where CoreIR types are expected will lead to type errors.
- gotcha CoreIR operations require an active `coreir.Context()` instance. Attempting to create modules, types, or instances without a valid context, or with a context that has gone out of scope, will result in errors.
Install
-
pip install coreir
Imports
- coreir
import pycoreir
import coreir
- Context
context = coreir.Context()
Quickstart
import coreir
# Create a CoreIR context
context = coreir.Context()
# Define a simple module type (e.g., a 16-bit input and output)
coreir_type = context.Record({
"in": context.BitIn().Arr(16),
"out": context.Bit().Arr(16)
})
# Create a new module named 'my_adder' with the defined type
module = context.Gettop().new_module("my_adder", coreir_type)
# Create a definition for the module, where instances and connections will be placed
module_def = module.new_definition()
# Get the 'add' generator and create an instance of a 16-bit adder
add16 = context.get_generator("coreir.add").get_instances({"width": 16})[0]
module_def.add_instance("add_inst", add16)
# Connect the module's input port to the adder instance's input
module_def.connect(module_def.get_port("in"), "add_inst.in")
# Connect the adder instance's output to the module's output port
module_def.connect("add_inst.out", module_def.get_port("out"))
# Set the definition for the module
module.set_definition(module_def)
# Verify the module's type system (optional, but good for validation)
module.type.verify()
print(f"Successfully created CoreIR module: {module.name}")
# print(f"Module definition:
{module_def.str()}") # Uncomment to see the generated IR