Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
# Copyright 2023 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import json
from decimal import Decimal
import click
from .config import Config
from ..flows.flow import universal_flow_config_variables
from ..steps.yosys import verilog_rtl_cfg_vars
from ..flows.cli import cloup_flow_opts
@click.group
def cli():
pass
@click.command()
@click.option(
"--file-name",
type=click.Path(exists=False, file_okay=True, dir_okay=False),
default="config.json",
prompt="Please input the file name for the configuration file",
help="The file name of the configuration file.",
)
@click.option(
"--design-dir",
type=click.Path(exists=True, dir_okay=True, file_okay=False),
default=".",
prompt="Enter the base directory for your design",
help="The top-level design directory. Typically, the configuration file goes in the design directory as well.",
)
@click.option(
"--design-name",
"--top-module",
type=str,
prompt="Enter the design name (which should be equal to the HDL name of your top module)",
help="The name of the design, i.e. the name of the top-level module of the design.",
)
@click.option(
"--clock-port",
type=str,
prompt="Enter the name of your design's clock port",
help="The identifier for the clock port.",
)
@click.option(
"--clock-period",
type=Decimal,
prompt="Enter your desired clock period in nanoseconds",
help="The clock period, in nanoseconds.",
)
@cloup_flow_opts(
config_options=False,
run_options=False,
sequential_flow_controls=False,
jobs=False,
accept_config_files=False,
)
@click.argument(
"source_rtl",
type=click.Path(
exists=True,
dir_okay=False,
file_okay=True,
),
nargs=-1,
)
def create_config(
pdk_root,
pdk,
scl,
file_name,
design_name,
design_dir,
clock_port,
clock_period,
source_rtl,
):
"""
Generates an LibreLane JSON configuration file for a design interactively.
"""
if len(source_rtl) == 0:
source_rtl = []
try:
while True:
file = input(
f"Input the RTL source file #{len(source_rtl)} (Ctrl+D to stop): "
)
if not os.path.isfile(file):
print(f"Invalid file {file}.", file=sys.stderr)
exit(1)
source_rtl.append(file)
except EOFError:
print("")
if len(source_rtl) == 0:
print("At least one source RTL file is required.", file=sys.stderr)
exit(1)
source_rtl_key = "VERILOG_FILES"
if not all(file.endswith(".sv") or file.endswith(".v") for file in source_rtl):
print(
"Only Verilog/SystemVerilog files are supported by create-config.",
file=sys.stderr,
)
exit(-1)
source_rtl_rel = [f"dir::{os.path.relpath(x, design_dir)}" for x in source_rtl]
config_dict = {
"DESIGN_NAME": design_name,
"CLOCK_PORT": clock_port,
"CLOCK_PERIOD": clock_period,
source_rtl_key: source_rtl_rel,
"meta": {
"version": 2,
},
}
config, _ = Config.load(
config_dict,
universal_flow_config_variables + verilog_rtl_cfg_vars,
design_dir=design_dir,
pdk=pdk,
pdk_root=pdk_root,
scl=scl,
)
with open(file_name, "w") as f:
print(
json.dumps(config_dict, cls=config.get_encoder(), indent=4),
file=f,
)
design_dir_opt = ""
if os.path.abspath(design_dir) != os.path.abspath(os.path.dirname(file_name)):
design_dir_opt = f"--design-dir {design_dir} "
print(f"Wrote config to '{file_name}'.")
print("To run this design, invoke:")
print(f"\tlibrelane {design_dir_opt}{file_name}")
cli.add_command(create_config)
if __name__ == "__main__":
cli()
aaf7a9387This file is pinned to the selected release. Download the original to open it in your design tool.