Skip to content

Rewrite the translator on the hierarchical circuit DSL

Alexander requested to merge rewrite-on-hierarchical-dsl into main

The package did not import. translator.py was written against llogic.circuit.circuit, the flat representation llogic dropped when it moved onto the netlist IR, and against lverilog, which is not installed anywhere. Every entry point in it was dead.

The rewrite reads the design through Parser.elaborate_source, which parses, resolves imports and verifies without flattening, so the hierarchy survives into the output: a module becomes a Verilog module, an inst becomes a module instantiation with named port connections, and a gate becomes a continuous assignment. Gate lowering is a table keyed on the basis type name rather than an isinstance ladder, and covers the std_logic, ite and reversible bases.

Three things do not map straight across. Bit ranges run low-to-high in the DSL and high-to-low in Verilog, in declarations and part-selects both. A gate with several outputs -- the reversible basis is built from them -- becomes one assignment per output, since assign drives exactly one signal. And a name Verilog reserves gains a trailing underscore: the DSL's own gate names are Verilog gate primitives, so a component library naming each module after the gate it wraps emitted module and(...) until now.

dff no longer lowers to assign q = d; under a comment admitting it wants a clock. It emits a clocked always block, declares what it drives reg, and gives an implicit clock port to every module that holds one or instantiates a module that does, under a name chosen to dodge any signal already called clk.

Drops the lverilog dependency: its AST has no module instantiation, no vector declarations and no bit-selects, so hierarchical output would have meant extending it, and it is the last ply-based corner of the toolchain. Emitting the text directly costs about forty lines and leaves llogic as the only dependency.

Also brings the packaging up to the rest of the family: Python >= 3.12, a test extra, a Makefile that runs pytest rather than unittest (it was a copy of pycadical's), ruff/pyright/prospector configuration, a rewritten README, and a test suite.

Merge request reports

Loading