moonbit-rtl

    A Verilog-2001 RTL parser, hierarchy analyzer, and lint tool written in MoonBit.

    verilog
    rtl
    lint
    parser
    hardware
    Download zip
    Author
    Version
    0.2.5
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    65

    #moonbit-rtl

    moonbit-rtl is a pure-MoonBit Verilog-2001 front end and RTL structure analyzer for teaching, small FPGA projects, and lightweight CI review. It turns source text into a span-aware syntax tree, semantic index, hierarchy graph, lint diagnostics, and machine-readable reports without requiring an external HDL parser.

    #What it provides

    • Error-recovering lexer and parser for a practical Verilog-2001 subset.
    • Source spans with line/column mapping and stable AST queries.
    • Module, port, signal, driver, instance, and hierarchy indexing.
    • Cross-module connection and width contracts, including unknown-state handling.
    • Control-flow summaries for procedural reads, writes, conditional assignments, and edge-sensitive blocks.
    • Deterministic text, JSON, SARIF, Graphviz DOT, and semantic JSON IR output.
    • Library APIs for batch analysis, source metrics, graph analytics, and reports.
    • A native CLI suitable for local checks and CI smoke tests.

    The project intentionally does not claim complete SystemVerilog support, synthesis, simulation, formal verification, or an LSP server.

    #Quick start

    Install the current stable MoonBit toolchain, then run:

    moon update moon check --target all moon test --target all moon run src/cli -- check examples/counter.v moon run src/cli -- outline examples/hierarchy.v moon run src/cli -- graph examples/hierarchy.v

    On Windows, the repository's WasmGC checks are a portable local smoke path; native test execution may depend on the installed C compiler/runtime.

    #CLI

    moonbit-rtl check <file> [--format=text|json|sarif] moonbit-rtl outline <file> moonbit-rtl graph <file> moonbit-rtl summary <file> moonbit-rtl ir <file> moonbit-rtl tokens <file>

    check returns 0 when no error diagnostic is produced, 1 for source or semantic errors, and 2 for invalid usage or unreadable input. JSON is intended for automation, SARIF for code-scanning clients, DOT for Graphviz, and ir for tools that need a stable semantic snapshot.

    #Library entry point

    The module root exposes a small facade for applications that need one call to connect source identity, parser recovery, and semantic indexing:

    let result = analyze_text(
    "module counter(input clk, output ready); assign ready = clk; endmodule",
    )
    let modules = result.module_count()
    let ok = result.is_valid()

    Use analyze_file(name, text) when diagnostics should retain a real file name. The returned Analysis value also exposes the parser result and semantic index for callers that need detailed recovery diagnostics, module queries, contracts, or graph analytics.

    #Rules

    CodeCategoryMeaningDefault
    RTL101structureduplicate module declarationwarning
    RTL102structureunresolved module instanceerror
    RTL201drivinginternal signal is never drivenwarning
    RTL202drivingsignal has multiple independent driverserror
    RTL203drivingoutput port is never assignedwarning
    RTL204widthknown assignment widths do not matchwarning
    RTL205connectivityinstance port direction/width contract mismatcherror
    RTL206connectivityinstance contract cannot be resolvedwarning
    RTL207control flowprocedural assignment is conditionalinfo

    Unknown widths and incomplete syntax are kept conservative so that missing information does not become a false positive.

    #Library layout

    src/source source files, spans, line indexes, and source bundles src/lexer tokens, lexer, token metrics, and delimiter queries src/syntax public AST, visitors, queries, and design metrics src/parser recovering Verilog parser and recovery analysis src/semantic symbol index, contracts, control flow, IR, and graph analytics src/lint configurable rules, categories, and diagnostic reports src/diagnostic reports, text/JSON/SARIF/DOT/Markdown renderers src/cli command-line entry point and reusable batch analysis API examples valid and intentionally broken RTL fixtures benchmarks deterministic parser/index workload and benchmark instructions docs design, rules, IR, benchmark, and provenance notes

    #Examples and reproducibility

    moon run src/cli -- check examples/broken.v --format=json moon run src/cli -- summary examples/hierarchy.v moon run src/cli -- ir examples/hierarchy.v moon run src/cli -- tokens examples/counter.v moon run benchmarks --target wasm-gc

    The benchmark workload is deterministic. It reports input size, iteration count, modules, hierarchy edges, and diagnostics; wall-clock measurements are environment-specific and are recorded separately in docs/benchmarks.md.

    #Development

    moon fmt moon check --target all moon test --target wasm-gc moon info .\scripts\count-moonbit-lines.ps1

    The GitHub workflow repeats formatting, all-target checks, tests, metadata verification, coverage-oriented smoke tests, and CLI examples on Linux, macOS, and Windows. See CONTRIBUTING.md for code organization and review expectations.

    #License and provenance

    The project is licensed under Apache-2.0. The analyzer implementation is original MoonBit code. It does not copy or vendor a third-party Verilog parser; the only runtime dependency is the official moonbitlang/x package used for filesystem and system access. See SOURCES.md for dependency and fixture provenance.

    #Roadmap

    Future compatible extensions may cover selected SystemVerilog declarations, editor adapters, richer data-flow explanations, and automatic fix suggestions. These are future work and are not represented as current functionality.

    Analysis

    A parsed and semantically indexed RTL source unit.

    Analysis::file

    Return the source file associated with this analysis.

    Analysis::is_valid

    fn Analysis::is_valid(self : Analysis) -> Bool

    Report whether parsing and semantic validation completed without blocking findings.

    Analysis::module_count

    fn Analysis::module_count(self : Analysis) -> Int

    Return the number of modules recovered from the source text.

    Analysis::parse

    Return parser output, including recovery diagnostics and metrics.

    Analysis::semantic

    Return the semantic index built from the recovered syntax tree.

    analyze_file

    fn analyze_file(file_name : String, text : String) -> Analysis

    Analyze named source text while preserving its file identity for diagnostics.

    analyze_text

    fn analyze_text(text : String) -> Analysis

    Analyze an in-memory RTL document.

    Source Files