Skip to content

A modern, Python-based Hardware Description Language (HDL) that compiles to SystemVerilog via CIRCT.

License

Notifications You must be signed in to change notification settings

yassinz/elision

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Elision HDL

A modern, Python-based Hardware Description Language (HDL) that compiles to SystemVerilog via CIRCT.

Python 3.12+ License: MIT

Features

  • 🎯 Type-Safe: Strong typing with Logic, Array, Struct, and Union
  • πŸ”§ Composable: Types compose infinitely - Reg[Array[4, Struct]] just works
  • 🐍 Pythonic: Modern Python with PEP 695 generics - class Adder[WIDTH](Module)
  • ⚑ Fast: CIRCT backend for rapid compilation
  • πŸ”¬ Simulation: Built-in LLVM-based simulator with VCD output
  • πŸ“¦ Clean: Predictable mapping to SystemVerilog

Quick Start

Installation

pip install elision

Hello World - Counter

from elision import *

class Counter(Module):
    clk: INPUT[Clock]
    rst: INPUT[Reset]
    out: OUTPUT[Logic[32]]

    def build(self, io):
        count = Reg[Logic[32]]()
        
        with io.clk.posedge, io.rst.negedge:
            count.next = count + 1
            
        io.out = count

# Generate Mlir and Verilog
counter = Counter()
print(counter.mlir())
print(counter.verilog())

# Simulate
with counter.simulate() as sim:
    print(sim.llvm_ir())
    print(sim.machine_asm())
    sim.io.rst = 0
    sim.tick()
    sim.io.rst = 1
    for i in range(10):
        sim.tick()
        print(f"count = {sim.io.out}")

Parameterized Design

class Adder[WIDTH](Module):
    a: INPUT[Logic[WIDTH]]
    b: INPUT[Logic[WIDTH]]
    out: OUTPUT[Logic[WIDTH]]
    
    def build(self, io):
        io.out = io.a + io.b

# Use with different widths
adder8 = Adder[8]()
adder32 = Adder[32]()

Using Structs

class Point[WIDTH](Struct):
    x: Logic[WIDTH]
    y: Logic[WIDTH]

    def __add__(self, other):
        return Point[WIDTH](
            x=self.x + other.x,
            y=self.y + other.y
        )

class PointAdder[WIDTH](Module):
    a: INPUT[Point[WIDTH]]
    b: INPUT[Point[WIDTH]]
    out: OUTPUT[Point[WIDTH]]
    
    def build(self, io):
        io.out = io.a + io.b

addr = PointAdder[8]()
print(addr.verilog())     

Core Concepts

Types

  • Logic[N] - N-bit vectors with full arithmetic/bitwise operations
  • Array[N, T] - Fixed-size arrays of any type
  • Struct - Composite types with named fields
  • Union - Tagged unions for multiple views of data

Primitives

  • Reg[T] - Registers with .next assignment
  • Wire[T] - Forward-declared wires with .assign property
  • Mux[T] - Type-safe multiplexers
  • Map[W, T] - Combinational lookup tables
  • Mem[N, T] - Synchronous memories with .read and .write methods
  • Fifo[N, T] - FIFO with .push and .pop methods

Registers

# Create register
reg = Reg[Logic[32]]()

# With initial value
reg = Reg[Logic[32]](init=42)

# With reset value
reg = Reg[Logic[32]](reset_value=0)

# Assign in clock context
with io.clk.posedge:
    reg.next = reg + 1

Wires

# Create wire
w = Wire[Logic[32]]()

# Use before assignment
io.out = w

# Assign later
w.assign = io.a + io.b

Multiplexers

result = Mux[Logic[32]](sel, true_val, false_val)

Examples

See the examples/ directory for a variety of hardware designs:

  • RV32I: A complete RISC-V RV32I CPU implementation.
  • DSP Components: DotProduct, Pipelined MAC, and FIR filters.
  • Networking: CRC-32 generator and packet protocol inspectors.
  • Systolic Array: Parallel matrix multiplication engine.
  • Basics: ALU, state machines, counters, and logic gates.

Documentation

Project Structure

elision/
β”œβ”€β”€ elision/
β”‚   β”œβ”€β”€ core/           # Module system
β”‚   β”œβ”€β”€ types/          # Type system (Logic, Array, Struct, Union)
β”‚   β”œβ”€β”€ primitives/     # Reg, Wire, Mux
β”‚   β”œβ”€β”€ simulation/     # LLVM-based simulator
β”‚   └── utils/          # Type utilities and parameters
β”œβ”€β”€ examples/           # Example designs
β”œβ”€β”€ test/               # Tests
β”œβ”€β”€ docs/               # Documentation
└── README.md

Requirements

  • Python 3.11+
  • CIRCT (installed via pip)
  • llvmlite

Development

# Install in development mode
pip install -e ".[dev]"

# Run tests
python -m pytest test/

# Run specific test
python test/test_reg.py

Design Philosophy

  1. Types compose infinitely - Any type can contain any other type
  2. Python-first - Use Python's features, don't fight them
  3. Predictable output - Clear mapping to SystemVerilog
  4. Fast compilation - CIRCT backend for speed
  5. Type safety - Catch errors at compile time, not simulation

Status

⚠️ Alpha - Work in progress. API may change.

Current focus:

  • Core type system βœ…
  • Module system βœ…
  • Primitives (Reg, Wire, Mux, Map, Mem, Fifo) βœ…
  • Simulation βœ…
  • Documentation 🚧
  • interfaces/protocols 🚧
  • Fsm and Pipeline 🚧
  • Standard library 🚧

Contributing

Contributions welcome! Areas of interest:

  • Documentation improvements
  • Bug reports and fixes
  • Example designs

License

MIT License - see LICENSE file for details

Acknowledgments

Contact

For questions, issues, or discussions, please open an issue on GitHub.


Note: This is a research/educational project. For production use, consider mature alternatives.

About

A modern, Python-based Hardware Description Language (HDL) that compiles to SystemVerilog via CIRCT.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages