Source code for fabulous.tools.ghdl

"""GHDL tool wrapper.

GHDL elaborates a VHDL design (``--synth --out=verilog``) and writes the resulting
Verilog netlist to stdout. This wrapper captures that output so the VHDL-to-Verilog
conversion no longer needs a raw subprocess call in the caller. Used as a singleton
via `GhdlTool.synthesize_to_verilog(...)`; never instantiated.
"""

import tempfile
from pathlib import Path

from fabulous.fabulous_settings import get_context
from fabulous.tools.tool import Tool


[docs] class GhdlTool(Tool): """Wraps the GHDL executable to elaborate VHDL into a Verilog netlist.""" @classmethod
[docs] def executable(cls) -> Path | str: """Return the GHDL executable from the FABulous context. Returns ------- Path | str The configured GHDL executable. """ return get_context().ghdl_path
@classmethod
[docs] def synthesize_to_verilog( cls, vhdl_file: Path, models_pack: Path, std: str = "08" ) -> str: """Elaborate a VHDL file into Verilog and return the Verilog text. Parameters ---------- vhdl_file : Path The VHDL source file to elaborate. Its stem is used as the top-level entity name passed to ``-e``. models_pack : Path The FABulous models package GHDL needs on its analysis path. std : str The VHDL standard passed to ``--std`` (default "08"). Returns ------- str The Verilog netlist GHDL emits on stdout. """ # FIXME: a fake stub package required by GHDL 1.3 -- unique per-invocation # to avoid collisions when multiple users run FABulous on the same machine. with tempfile.NamedTemporaryFile( suffix=".vhd", mode="w", delete=False ) as stub_file: stub_file.write("package my_package is\nend package;\n") stub = Path(stub_file.name) try: result = cls.run( args=[ "--synth", f"--std={std}", "--out=verilog", str(stub), str(models_pack), str(vhdl_file), "-e", vhdl_file.stem, ], ) finally: stub.unlink(missing_ok=True) return result.stdout