"""
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
)