Source code for piel.integration.amaranth_openlane

"""
This file enhances some functions that easily translates between an `amaranth` function to implement a `openlane` flow.
"""
import amaranth as am
from typing import Optional, Literal
import types
from ..tools.amaranth import (
    construct_amaranth_module_from_truth_table,
    generate_verilog_from_amaranth,
)
from ..file_system import return_path, create_new_directory
from ..project_structure import create_empty_piel_project
from ..tools.openlane.v1 import write_configuration_openlane_v1
from ..tools.openlane.v2 import run_openlane_flow
from ..tools.openlane.defaults import (
    test_basic_open_lane_configuration_v1,
    test_basic_open_lane_configuration_v2,
)
from ..types import PathTypes

__all__ = ["layout_amaranth_truth_table_through_openlane"]


def layout_openlane_from_truth_table(
    truth_table: dict,
    inputs: list[str],
    outputs: list[str],
    parent_directory: PathTypes,
    target_directory_name: Optional[str] = None,
    openlane_version: Literal["v1", "v2"] = "v2",
    **kwargs
):
    our_truth_table_module = construct_amaranth_module_from_truth_table(
        truth_table=truth_table, inputs=inputs, outputs=outputs, **kwargs
    )
    layout_amaranth_truth_table_through_openlane(
        amaranth_module=our_truth_table_module,
        inputs_name_list=inputs,
        outputs_name_list=outputs,
        parent_directory=parent_directory,
        target_directory_name=target_directory_name,
        openlane_version=openlane_version,
        **kwargs
    )


[docs]def layout_amaranth_truth_table_through_openlane( amaranth_module: am.Module, inputs_name_list: list[str], outputs_name_list: list[str], parent_directory: PathTypes, target_directory_name: Optional[str] = None, openlane_version: Literal["v1", "v2"] = "v2", **kwargs ): """ This function implements an amaranth truth-table module through the openlane flow. There are several ways to implement a module. Fundamentally, this requires the verilog files to be generated from the openlane-module in a particular directory. For the particular directory provided, this function will generate the verilog files in the corresponding directory. It can also generate the ``openlane`` configuration files for this particular location. This function does a few things: 1. Starts off from a ``amaranth`` module class. 2. Determines the output directory in which to generate the files, and creates one accordingly if it does not exist. 3. Generates the verilog files from the ``amaranth`` module class. 4. Generates the ``openlane`` configuration files for this particular location. 5. Implements the ``openlane`` flow for this particular location to generate a chip. Args: amaranth_module (amaranth.Module): Amaranth module class. inputs_name_list (list[str]): List of input names. outputs_name_list (list[str]): List of output names. parent_directory (PathTypes): Parent directory PATH. target_directory_name (Optional[str]): Target directory name. If none is provided, it will default to the name of the amaranth elaboratable class. openlane_version (Literal["v1", "v2"]): OpenLane version. Defaults to ``v1``. Returns: None """ # Determines the output directory in which to generate the files, and creates one accordingly if it does not exist. if isinstance(parent_directory, types.ModuleType): parent_directory = return_path(parent_directory) design_directory = parent_directory src_folder = parent_directory / "src" else: parent_directory = return_path(parent_directory) if not parent_directory.exists(): create_new_directory(parent_directory) # Creates a corresponding `piel` project accordingly. target_directory_name = ( target_directory_name if target_directory_name is not None else amaranth_module.__class__.__name__ ) create_empty_piel_project( project_name=target_directory_name, parent_directory=parent_directory, ) design_directory = ( parent_directory / target_directory_name / target_directory_name ) src_folder = design_directory / "src" # Generates the verilog files from the ``amaranth`` elaboratable class. ports_list = inputs_name_list + outputs_name_list generate_verilog_from_amaranth( amaranth_module=amaranth_module, ports_list=ports_list, target_file_name="our_truth_table_module.v", target_directory=src_folder, ) # Generates the ``openlane`` configuration files for this particular location. # Runs the `openlane` flow if openlane_version == "v1": our_amaranth_openlane_config = test_basic_open_lane_configuration_v1 write_configuration_openlane_v1( configuration=our_amaranth_openlane_config, design_directory=design_directory, ) # TODO Copy to the openlane root directory. elif openlane_version == "v2": our_amaranth_openlane_config = test_basic_open_lane_configuration_v2 run_openlane_flow( configuration=our_amaranth_openlane_config, design_directory=design_directory, **kwargs )