Source code for piel.tools.amaranth.export

"""
This module provides a utility to generate Verilog code from an Amaranth module based on a given truth table.
It handles the conversion and export process, integrating with a specified file system structure.
"""

from typing import Any, Literal
from ...file_system import return_path
from ...project_structure import get_module_folder_type_location
from ...types import PathTypes, TruthTable


[docs] def generate_verilog_from_amaranth_truth_table( amaranth_module: Any, truth_table: TruthTable, target_file_name: str, target_directory: PathTypes, backend: Literal["verilog", "vhdl"] = "verilog", ) -> None: """ Exports an Amaranth module to Verilog code and writes it to a specified path. This function converts an Amaranth elaboratable class to Verilog using the specified backend and writes the generated code to a file in the target directory. It supports both direct paths and paths defined by the project's module structure. Args: amaranth_module (amaranth.Elaboratable): The Amaranth module to be converted. truth_table (TruthTable): A truth table object containing input and output connection. target_file_name (str): The name of the target file to write the Verilog code to. target_directory (PathTypes): The target directory where the file will be saved. Can be a direct path or a module type path. backend (amaranth.back.verilog, optional): The backend to use for Verilog conversion. Defaults to `verilog`. Returns: None Raises: AttributeError: If any port specified in the truth table is not found in the Amaranth module. Examples: >>> am_module = MyAmaranthModule() # Assuming this is a defined Amaranth module. >>> truth_table = TruthTable( >>> input_ports=["input1", "input2"], >>> output_ports=["output1"], >>> input1=["00", "01", "10", "11"], >>> output1=["0", "1", "1", "0"] >>> ) >>> generate_verilog_from_amaranth_truth_table(am_module, truth_table, "output.v", "/path/to/save") """ import amaranth as am import types if backend == "verilog": from amaranth.back import verilog backend = verilog elif backend == "vhdl": raise NotImplementedError("This backend is not yet implemented.") if isinstance(amaranth_module, am.Elaboratable): pass else: raise AttributeError("Amaranth module should be am.Elaboratable") ports_list = truth_table.ports_list if isinstance(target_directory, types.ModuleType): # If the path follows the structure of a `piel` path, get the appropriate folder type location. target_directory = get_module_folder_type_location( module=target_directory, folder_type="digital_source" ) else: # Otherwise, convert the target directory to a path. target_directory = return_path(target_directory) target_file_path = target_directory / target_file_name # Iterate over connection list and construct a list of references for the strings provided in `keys_list`. module_ports_list = [] for port_i in ports_list: if hasattr(amaranth_module, port_i): module_port_i = getattr(amaranth_module, port_i) module_ports_list.append(module_port_i) else: raise AttributeError(f"Port {port_i} not found in the Amaranth module.") # Ensure the directory exists. target_directory.mkdir(parents=True, exist_ok=True) # Write the Verilog file to the target path. with open(target_file_path, "w") as file: file.write( backend.convert( amaranth_module, ports=module_ports_list, ) ) print(f"Verilog file generated and written to {target_file_path}")