diff --git a/f4pga/flows/common.py b/f4pga/flows/common.py index e024be6..35c7bd0 100644 --- a/f4pga/flows/common.py +++ b/f4pga/flows/common.py @@ -95,44 +95,6 @@ def deep(fun, allow_none=False): return d -class VprArgs: - """ - Represents argument list for VPR (Versatile Place and Route). - """ - - arch_dir: str - arch_def: str - lookahead: str - rr_graph: str - place_delay: str - device_name: str - eblif: str - optional: list - - def __init__( - self, - share: str, - eblif, - arch_def, - lookahead, - rr_graph, - place_delay, - device_name, - vpr_options={}, - sdc_file: "str | None" = None, - ): - self.arch_dir = str(Path(share) / "arch") - self.arch_def = arch_def - self.lookahead = lookahead - self.rr_graph = rr_graph - self.place_delay = place_delay - self.device_name = device_name - self.eblif = str(Path(eblif).resolve()) - self.optional = options_dict_to_list(vpr_options) - if sdc_file is not None: - self.optional += ["--sdc_file", sdc_file] - - class SubprocessException(Exception): return_code: int @@ -152,43 +114,6 @@ def sub(*args, env=None, cwd=None, print_stdout_on_fail=False): return out.stdout -def vpr(mode: str, vprargs: VprArgs, cwd=None): - """ - Execute `vpr`. - """ - return sub( - *( - [ - "vpr", - vprargs.arch_def, - vprargs.eblif, - "--device", - vprargs.device_name, - "--read_rr_graph", - vprargs.rr_graph, - "--read_router_lookahead", - vprargs.lookahead, - "--read_placement_delay_lookup", - vprargs.place_delay, - ] - + ([f"--{mode}"] if mode in ["pack", "place", "route", "analysis"] else []) - + vprargs.optional - ), - cwd=cwd, - print_stdout_on_fail=True, - ) - - -vpr_specific_values = [ - "arch_def", - "rr_graph_lookahead_bin", - "rr_graph_real_bin", - "vpr_place_delay", - "vpr_grid_layout_name", - "vpr_options?", -] - - def options_dict_to_list(opt_dict: dict): """ Converts a dictionary of named options for CLI program to a list. @@ -210,13 +135,6 @@ def noisy_warnings(device): environ["OUR_NOISY_WARNINGS"] = f"noisy_warnings-{device}_pack.log" -def save_vpr_log(filename, build_dir=""): - """ - Save VPR logic (moves the default output file into a desired path). - """ - sh_mv(str(Path(build_dir) / "vpr_stdout.log"), filename) - - def fatal(code, message): """ Print a message informing about an error that has occured and terminate program with a given return code. diff --git a/f4pga/flows/modules/analysis.py b/f4pga/flows/modules/analysis.py index eb8a196..ea5ffc6 100644 --- a/f4pga/flows/modules/analysis.py +++ b/f4pga/flows/modules/analysis.py @@ -19,7 +19,7 @@ from pathlib import Path -from f4pga.flows.common import vpr_specific_values, vpr as common_vpr, VprArgs +from f4pga.flows.tools.vpr import vpr_specific_values, vpr, VprArgs from f4pga.flows.module import Module, ModuleContext @@ -42,7 +42,7 @@ class analysisModule(Module): build_dir = Path(ctx.takes.eblif).parent yield "Analysis with VPR..." - common_vpr( + vpr( "analysis", VprArgs( share=ctx.share, diff --git a/f4pga/flows/modules/fasm.py b/f4pga/flows/modules/fasm.py index 8c61dbb..79f7d24 100644 --- a/f4pga/flows/modules/fasm.py +++ b/f4pga/flows/modules/fasm.py @@ -19,7 +19,8 @@ from pathlib import Path -from f4pga.flows.common import vpr_specific_values, VprArgs, get_verbosity_level, sub as common_sub +from f4pga.flows.common import get_verbosity_level, sub as common_sub +from f4pga.flows.tools.vpr import vpr_specific_values, VprArgs from f4pga.flows.module import Module, ModuleContext diff --git a/f4pga/flows/modules/nextpnr_ice40.py b/f4pga/flows/modules/nextpnr_ice40.py index 03d97f5..17844d3 100644 --- a/f4pga/flows/modules/nextpnr_ice40.py +++ b/f4pga/flows/modules/nextpnr_ice40.py @@ -20,7 +20,7 @@ import pathlib from f4pga.flows.common import ResolutionEnv from f4pga.flows.module import ModuleContext -from f4pga.flows.modules.nextpnr import NextPnrBaseModule +from f4pga.flows.tools.nextpnr import NextPnrBaseModule import re from pathlib import Path diff --git a/f4pga/flows/modules/pack.py b/f4pga/flows/modules/pack.py index 0d90fe1..49a8019 100644 --- a/f4pga/flows/modules/pack.py +++ b/f4pga/flows/modules/pack.py @@ -19,7 +19,8 @@ from pathlib import Path -from f4pga.flows.common import vpr_specific_values, noisy_warnings, vpr as common_vpr, VprArgs +from f4pga.flows.common import noisy_warnings +from f4pga.flows.tools.vpr import vpr_specific_values, vpr, VprArgs from f4pga.flows.module import Module, ModuleContext @@ -42,7 +43,7 @@ class PackModule(Module): build_dir = Path(ctx.outputs.net).parent yield "Packing with VPR..." - common_vpr( + vpr( "pack", VprArgs( share=ctx.share, diff --git a/f4pga/flows/modules/place.py b/f4pga/flows/modules/place.py index 4962786..2f404a3 100644 --- a/f4pga/flows/modules/place.py +++ b/f4pga/flows/modules/place.py @@ -20,7 +20,7 @@ from pathlib import Path from re import match as re_match -from f4pga.flows.common import vpr_specific_values, vpr as common_vpr, VprArgs, save_vpr_log +from f4pga.flows.tools.vpr import vpr_specific_values, vpr, VprArgs, save_vpr_log from f4pga.flows.module import Module, ModuleContext @@ -48,7 +48,7 @@ class PlaceModule(Module): vpr_options.update({"fix_clusters": ctx.takes.place_constraints}) yield "Running VPR..." - common_vpr( + vpr( "place", VprArgs( share=ctx.share, diff --git a/f4pga/flows/modules/place_constraints.py b/f4pga/flows/modules/place_constraints.py index 1eababf..d5577ba 100644 --- a/f4pga/flows/modules/place_constraints.py +++ b/f4pga/flows/modules/place_constraints.py @@ -19,7 +19,7 @@ from pathlib import Path -from f4pga.flows.common import sub as common_sub +from f4pga.flows.common import sub as common_sub, options_dict_to_list from f4pga.flows.module import Module, ModuleContext diff --git a/f4pga/flows/modules/route.py b/f4pga/flows/modules/route.py index 91ed793..5df4952 100644 --- a/f4pga/flows/modules/route.py +++ b/f4pga/flows/modules/route.py @@ -19,7 +19,7 @@ from pathlib import Path -from f4pga.flows.common import vpr_specific_values, vpr as common_vpr, VprArgs, options_dict_to_list, save_vpr_log +from f4pga.flows.tools.vpr import vpr_specific_values, vpr, VprArgs, save_vpr_log from f4pga.flows.module import Module, ModuleContext @@ -35,7 +35,7 @@ class RouteModule(Module): build_dir = Path(ctx.takes.eblif).parent yield "Routing with VPR..." - common_vpr( + vpr( "route", VprArgs( share=ctx.share, diff --git a/f4pga/flows/modules/nextpnr.py b/f4pga/flows/tools/nextpnr.py similarity index 100% rename from f4pga/flows/modules/nextpnr.py rename to f4pga/flows/tools/nextpnr.py diff --git a/f4pga/flows/tools/vpr.py b/f4pga/flows/tools/vpr.py new file mode 100644 index 0000000..ffe1add --- /dev/null +++ b/f4pga/flows/tools/vpr.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2022 F4PGA Authors +# +# 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. +# +# SPDX-License-Identifier: Apache-2.0 + + +from pathlib import Path +from shutil import move as sh_mv + +from f4pga.flows.common import sub as common_sub, options_dict_to_list + + +class VprArgs: + """ + Represents argument list for VPR (Versatile Place and Route). + """ + + arch_dir: str + arch_def: str + lookahead: str + rr_graph: str + place_delay: str + device_name: str + eblif: str + optional: list + + def __init__( + self, + share: str, + eblif, + arch_def, + lookahead, + rr_graph, + place_delay, + device_name, + vpr_options={}, + sdc_file: "str | None" = None, + ): + self.arch_dir = str(Path(share) / "arch") + self.arch_def = arch_def + self.lookahead = lookahead + self.rr_graph = rr_graph + self.place_delay = place_delay + self.device_name = device_name + self.eblif = str(Path(eblif).resolve()) + self.optional = options_dict_to_list(vpr_options) + if sdc_file is not None: + self.optional += ["--sdc_file", sdc_file] + + +def vpr(mode: str, vprargs: VprArgs, cwd=None): + """ + Execute `vpr`. + """ + return common_sub( + *( + [ + "vpr", + vprargs.arch_def, + vprargs.eblif, + "--device", + vprargs.device_name, + "--read_rr_graph", + vprargs.rr_graph, + "--read_router_lookahead", + vprargs.lookahead, + "--read_placement_delay_lookup", + vprargs.place_delay, + ] + + ([f"--{mode}"] if mode in ["pack", "place", "route", "analysis"] else []) + + vprargs.optional + ), + cwd=cwd, + print_stdout_on_fail=True, + ) + + +vpr_specific_values = [ + "arch_def", + "rr_graph_lookahead_bin", + "rr_graph_real_bin", + "vpr_place_delay", + "vpr_grid_layout_name", + "vpr_options?", +] + + +def save_vpr_log(filename, build_dir=""): + """ + Save VPR logic (moves the default output file into a desired path). + """ + sh_mv(str(Path(build_dir) / "vpr_stdout.log"), filename)