From 18a2c00cdc021b4003d7a5b0506c224a132030db Mon Sep 17 00:00:00 2001 From: Unai Martinez-Corral Date: Fri, 30 Sep 2022 20:05:55 +0100 Subject: [PATCH 1/2] f4pga/flows: vpr_specific_values as a list, not a function Signed-off-by: Unai Martinez-Corral --- f4pga/flows/common.py | 7 +------ f4pga/flows/modules/analysis.py | 2 +- f4pga/flows/modules/fasm.py | 2 +- f4pga/flows/modules/pack.py | 4 +--- f4pga/flows/modules/place.py | 2 +- f4pga/flows/modules/route.py | 2 +- 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/f4pga/flows/common.py b/f4pga/flows/common.py index fb89da2..e024be6 100644 --- a/f4pga/flows/common.py +++ b/f4pga/flows/common.py @@ -179,7 +179,7 @@ def vpr(mode: str, vprargs: VprArgs, cwd=None): ) -_vpr_specific_values = [ +vpr_specific_values = [ "arch_def", "rr_graph_lookahead_bin", "rr_graph_real_bin", @@ -189,11 +189,6 @@ _vpr_specific_values = [ ] -def vpr_specific_values(): - global _vpr_specific_values - return _vpr_specific_values - - def options_dict_to_list(opt_dict: dict): """ Converts a dictionary of named options for CLI program to a list. diff --git a/f4pga/flows/modules/analysis.py b/f4pga/flows/modules/analysis.py index 40d2115..eb8a196 100644 --- a/f4pga/flows/modules/analysis.py +++ b/f4pga/flows/modules/analysis.py @@ -72,7 +72,7 @@ class analysisModule(Module): self.no_of_phases = 2 self.takes = ["eblif", "route", "sdc?"] self.produces = ["merged_post_implementation_v", "post_implementation_v", "analysis_log"] - self.values = ["device", "vpr_options?"] + vpr_specific_values() + self.values = ["device", "vpr_options?"] + vpr_specific_values ModuleClass = analysisModule diff --git a/f4pga/flows/modules/fasm.py b/f4pga/flows/modules/fasm.py index 3ac06bb..8c61dbb 100644 --- a/f4pga/flows/modules/fasm.py +++ b/f4pga/flows/modules/fasm.py @@ -81,7 +81,7 @@ class FasmModule(Module): self.no_of_phases = 2 self.takes = ["eblif", "net", "place", "route", "fasm_extra?", "sdc?"] self.produces = ["fasm"] - self.values = ["device", "top", "pnr_corner?"] + vpr_specific_values() + self.values = ["device", "top", "pnr_corner?"] + vpr_specific_values self.prod_meta = {"fasm": "FPGA assembly file"} diff --git a/f4pga/flows/modules/pack.py b/f4pga/flows/modules/pack.py index 4c01dae..0d90fe1 100644 --- a/f4pga/flows/modules/pack.py +++ b/f4pga/flows/modules/pack.py @@ -77,9 +77,7 @@ class PackModule(Module): self.no_of_phases = 2 self.takes = ["eblif", "sdc?"] self.produces = ["net", "util_rpt", "timing_rpt", "pack_log!"] - self.values = [ - "device", - ] + vpr_specific_values() + self.values = ["device"] + vpr_specific_values ModuleClass = PackModule diff --git a/f4pga/flows/modules/place.py b/f4pga/flows/modules/place.py index e3f5aab..4962786 100644 --- a/f4pga/flows/modules/place.py +++ b/f4pga/flows/modules/place.py @@ -82,7 +82,7 @@ class PlaceModule(Module): self.no_of_phases = 2 self.takes = ["build_dir", "eblif", "sdc?", "place_constraints?", "io_place?"] self.produces = ["place"] - self.values = ["device", "vpr_options?"] + vpr_specific_values() + self.values = ["device", "vpr_options?"] + vpr_specific_values ModuleClass = PlaceModule diff --git a/f4pga/flows/modules/route.py b/f4pga/flows/modules/route.py index 5d08582..91ed793 100644 --- a/f4pga/flows/modules/route.py +++ b/f4pga/flows/modules/route.py @@ -62,7 +62,7 @@ class RouteModule(Module): self.no_of_phases = 2 self.takes = ["eblif", "place", "sdc?"] self.produces = ["route"] - self.values = ["device", "vpr_options?"] + vpr_specific_values() + self.values = ["device", "vpr_options?"] + vpr_specific_values ModuleClass = RouteModule From 94df736bee0ac41f8889e6234bbe35c22b9a7a9c Mon Sep 17 00:00:00 2001 From: Unai Martinez-Corral Date: Fri, 30 Sep 2022 20:17:55 +0100 Subject: [PATCH 2/2] f4pga/flows: split vpr to a file; create subdir 'tools'; mv nextpnr and vpr Signed-off-by: Unai Martinez-Corral --- f4pga/flows/common.py | 82 ----------------- f4pga/flows/modules/analysis.py | 4 +- f4pga/flows/modules/fasm.py | 3 +- f4pga/flows/modules/nextpnr_ice40.py | 2 +- f4pga/flows/modules/pack.py | 5 +- f4pga/flows/modules/place.py | 4 +- f4pga/flows/modules/place_constraints.py | 2 +- f4pga/flows/modules/route.py | 4 +- f4pga/flows/{modules => tools}/nextpnr.py | 0 f4pga/flows/tools/vpr.py | 106 ++++++++++++++++++++++ 10 files changed, 119 insertions(+), 93 deletions(-) rename f4pga/flows/{modules => tools}/nextpnr.py (100%) create mode 100644 f4pga/flows/tools/vpr.py 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)