Skip to content
celox-simPublic

About

Celox HDL Simulator

Resources

Contributing

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

 

History

4,112 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Celox

npm version crates.io

A compiler-based RTL simulator for Veryl and a synthesizable subset of SystemVerilog.

Celox compiles an elaborated Veryl design into executable simulation kernels and exposes the design through a type-safe TypeScript API. The same kernels can be built from synthesizable SystemVerilog through the Rust API (see SystemVerilog support). It is both a practical way to test RTL with Vitest and an open testbed for exploring how RTL simulators should be structured.

Try the Playground · Read the guide · Use the starter template · Browse the API

Why Celox exists

Celox explores a simple question: what does a modern RTL simulator architecture look like when compilation, scheduling, state representation, code generation, and testbench integration are designed together?

The project makes those boundaries explicit:

  • Veryl-specific analysis ends at a source-independent design representation.
  • Combinational dependencies and clock domains are scheduled before execution.
  • A backend-independent IR and state layout are shared by multiple code generators.
  • Native and WebAssembly execution use the same runtime contract.
  • The testbench sees the same typed design API regardless of the execution backend.

This makes Celox useful as an architecture laboratory without reducing it to a compiler demo: the result can run real RTL tests, in Node.js or in a browser.

What you can do today

  • Import .veryl modules directly into TypeScript with generated port and hierarchy types.
  • Write assertions, fixtures, and parameterized tests with Vitest.
  • Choose explicit event-based stepping or scheduled, time-based simulation.
  • Exercise multiple clock domains and combinational clock cascades.
  • Enable four-state simulation and drive or inspect X and Z values.
  • Override top-level parameters and include test-only Veryl sources.
  • Inspect child instances and emit VCD waveforms.
  • Compile a Veryl design into a native executable and run cocotb tests through VPI.
  • Build an external netlist frontend with the Rust SDK and ship its simulator as a native application binary or a frontend-specific N-API/WASI addon.
  • Run through the custom native backend on x86-64 and AArch64, the Cranelift fallback on other native targets, or WebAssembly in the browser.

Quick start

The fastest way to start is the celox-template. For an existing Veryl project, install Celox, its Vite plugin, and Vitest:

npm add -D @celox-sim/celox @celox-sim/vite-plugin vitest

Enable the plugin in vitest.config.ts:

import { defineConfig } from "vitest/config";
import celox from "@celox-sim/vite-plugin";

export default defineConfig({
  plugins: [celox()],
});

Given a Veryl module such as src/Adder.veryl:

module Adder (
    a: input  logic<16>,
    b: input  logic<16>,
    sum: output logic<17>,
) {
    always_comb {
        sum = a + b;
    }
}

you can import the design and test it as a typed object:

import { describe, expect, test } from "vitest";
import { Simulator } from "@celox-sim/celox";
import { Adder } from "../src/Adder.veryl";

describe("Adder", () => {
  test("adds two values", () => {
    const sim = Simulator.create(Adder);

    try {
      sim.dut.a = 100n;
      sim.dut.b = 200n;
      expect(sim.dut.sum).toBe(300n);
    } finally {
      sim.dispose();
    }
  });
});

The Vite plugin analyzes the project and generates TypeScript sidecars, so port names, signal values, and visible hierarchy are checked by TypeScript. See the Getting Started guide for the required Veryl.toml and tsconfig.json setup.

Two simulation styles

Simulator gives a test direct control over events. It is a good fit for combinational blocks and cycle-oriented unit tests:

const sim = Simulator.create(Counter);
sim.dut.enable = 1n;
sim.tick();
expect(sim.dut.count).toBe(1n);
sim.dispose();

Simulation manages clocks and simulation time. It is intended for multi-clock and time-oriented scenarios:

const sim = Simulation.create(Counter);
sim.addClock("clk", { period: 10 });
sim.reset("rst");
sim.runUntil(100);
expect(sim.time()).toBe(100);
sim.dispose();

Architecture

Veryl source
    │
    ▼
frontend analysis and hierarchy elaboration
    │
    ▼
symbolic logic and dependency scheduling
    │
    ▼
Simulator IR (SIR) and backend-independent optimization
    │
    ▼
shared physical state layout
    │
    ├──► native x86-64
    ├──► native AArch64
    ├──► Cranelift JIT
    └──► WebAssembly
             │
             ▼
      event-driven runtime
             │
             ▼
    Rust / Node.js / browser hosts

The shared pipeline is deliberate. Scheduling and RTL semantics do not have to be reimplemented for every target, while backend implementations can still own their instruction selection, machine IR, register allocation, and code emission. The runtime separates next-state evaluation from commit when clock domains trigger together, then propagates combinational changes until the step settles.

For details, see the architecture overview, compiler components, and SIR reference.

Project scope

Celox is under active development. Its focus is synchronous RTL written in Veryl or in the synthesizable subset of SystemVerilog, tested at the design level. The SystemVerilog guide lists what the subset covers and what it leaves out. Celox is not a general SystemVerilog simulator: it does not run behavioral or verification code (initial, delays, assertions, classes), and it is not a gate-level timing simulator or an implementation of detailed delta-cycle event semantics.

That narrower scope is intentional: it keeps the simulator small enough to make architectural changes, compare execution strategies, and test new compiler and runtime boundaries in a complete working system. Expect unsupported constructs and API changes while the design is still evolving.

Documentation

Development

Celox is a Rust and pnpm workspace. On Linux, run nix develop to enter the locked development environment (also used by both devcontainer variants). See Development environment for nix-direnv setup, mbx cache placement on Btrfs, and devcontainer host-directory configuration.

Choose local checks using the change-based validation matrix. Run the affected regression and integration tests before pushing. Full CI runs daily on the default branch and on develop, including external simulator comparisons, so broader coverage continues even when no files change.

Architecture discussions, bug reports, and focused experiments are welcome in GitHub Issues.

The development environment includes cocotb and Verilator for native VPI integration tests and SystemVerilog benchmarks. Cargo runs through mbx to share compiler outputs and manage target directories.

Reusable Veryl language tests

celox-test-suite provides 648 language cases and a simulator adapter contract for other Veryl implementations, plus an optional Verilator verifier for checking the expectations independently.

License

Licensed under either Apache License 2.0 or MIT, at your option.

About

Celox HDL Simulator

Resources

Contributing

Stars

10 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages