f4pga/flows: split vpr to a file; create subdir 'tools'; mv nextpnr and vpr (#643)

This commit is contained in:
Unai Martinez-Corral 2022-10-04 21:47:54 +02:00 committed by GitHub
commit 6cb486e096
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 124 additions and 105 deletions

View File

@ -95,44 +95,6 @@ def deep(fun, allow_none=False):
return d 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): class SubprocessException(Exception):
return_code: int return_code: int
@ -152,48 +114,6 @@ def sub(*args, env=None, cwd=None, print_stdout_on_fail=False):
return out.stdout 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 vpr_specific_values():
global _vpr_specific_values
return _vpr_specific_values
def options_dict_to_list(opt_dict: dict): def options_dict_to_list(opt_dict: dict):
""" """
Converts a dictionary of named options for CLI program to a list. Converts a dictionary of named options for CLI program to a list.
@ -215,13 +135,6 @@ def noisy_warnings(device):
environ["OUR_NOISY_WARNINGS"] = f"noisy_warnings-{device}_pack.log" 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): def fatal(code, message):
""" """
Print a message informing about an error that has occured and terminate program with a given return code. Print a message informing about an error that has occured and terminate program with a given return code.

View File

@ -19,7 +19,7 @@
from pathlib import Path 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 from f4pga.flows.module import Module, ModuleContext
@ -42,7 +42,7 @@ class analysisModule(Module):
build_dir = Path(ctx.takes.eblif).parent build_dir = Path(ctx.takes.eblif).parent
yield "Analysis with VPR..." yield "Analysis with VPR..."
common_vpr( vpr(
"analysis", "analysis",
VprArgs( VprArgs(
share=ctx.share, share=ctx.share,
@ -72,7 +72,7 @@ class analysisModule(Module):
self.no_of_phases = 2 self.no_of_phases = 2
self.takes = ["eblif", "route", "sdc?"] self.takes = ["eblif", "route", "sdc?"]
self.produces = ["merged_post_implementation_v", "post_implementation_v", "analysis_log"] 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 ModuleClass = analysisModule

View File

@ -19,7 +19,8 @@
from pathlib import Path 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 from f4pga.flows.module import Module, ModuleContext
@ -81,7 +82,7 @@ class FasmModule(Module):
self.no_of_phases = 2 self.no_of_phases = 2
self.takes = ["eblif", "net", "place", "route", "fasm_extra?", "sdc?"] self.takes = ["eblif", "net", "place", "route", "fasm_extra?", "sdc?"]
self.produces = ["fasm"] 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"} self.prod_meta = {"fasm": "FPGA assembly file"}

View File

@ -20,7 +20,7 @@
import pathlib import pathlib
from f4pga.flows.common import ResolutionEnv from f4pga.flows.common import ResolutionEnv
from f4pga.flows.module import ModuleContext from f4pga.flows.module import ModuleContext
from f4pga.flows.modules.nextpnr import NextPnrBaseModule from f4pga.flows.tools.nextpnr import NextPnrBaseModule
import re import re
from pathlib import Path from pathlib import Path

View File

@ -19,7 +19,8 @@
from pathlib import Path 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 from f4pga.flows.module import Module, ModuleContext
@ -42,7 +43,7 @@ class PackModule(Module):
build_dir = Path(ctx.outputs.net).parent build_dir = Path(ctx.outputs.net).parent
yield "Packing with VPR..." yield "Packing with VPR..."
common_vpr( vpr(
"pack", "pack",
VprArgs( VprArgs(
share=ctx.share, share=ctx.share,
@ -77,9 +78,7 @@ class PackModule(Module):
self.no_of_phases = 2 self.no_of_phases = 2
self.takes = ["eblif", "sdc?"] self.takes = ["eblif", "sdc?"]
self.produces = ["net", "util_rpt", "timing_rpt", "pack_log!"] self.produces = ["net", "util_rpt", "timing_rpt", "pack_log!"]
self.values = [ self.values = ["device"] + vpr_specific_values
"device",
] + vpr_specific_values()
ModuleClass = PackModule ModuleClass = PackModule

View File

@ -20,7 +20,7 @@
from pathlib import Path from pathlib import Path
from re import match as re_match 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 from f4pga.flows.module import Module, ModuleContext
@ -48,7 +48,7 @@ class PlaceModule(Module):
vpr_options.update({"fix_clusters": ctx.takes.place_constraints}) vpr_options.update({"fix_clusters": ctx.takes.place_constraints})
yield "Running VPR..." yield "Running VPR..."
common_vpr( vpr(
"place", "place",
VprArgs( VprArgs(
share=ctx.share, share=ctx.share,
@ -82,7 +82,7 @@ class PlaceModule(Module):
self.no_of_phases = 2 self.no_of_phases = 2
self.takes = ["build_dir", "eblif", "sdc?", "place_constraints?", "io_place?"] self.takes = ["build_dir", "eblif", "sdc?", "place_constraints?", "io_place?"]
self.produces = ["place"] self.produces = ["place"]
self.values = ["device", "vpr_options?"] + vpr_specific_values() self.values = ["device", "vpr_options?"] + vpr_specific_values
ModuleClass = PlaceModule ModuleClass = PlaceModule

View File

@ -19,7 +19,7 @@
from pathlib import Path 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 from f4pga.flows.module import Module, ModuleContext

View File

@ -19,7 +19,7 @@
from pathlib import Path 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 from f4pga.flows.module import Module, ModuleContext
@ -35,7 +35,7 @@ class RouteModule(Module):
build_dir = Path(ctx.takes.eblif).parent build_dir = Path(ctx.takes.eblif).parent
yield "Routing with VPR..." yield "Routing with VPR..."
common_vpr( vpr(
"route", "route",
VprArgs( VprArgs(
share=ctx.share, share=ctx.share,
@ -62,7 +62,7 @@ class RouteModule(Module):
self.no_of_phases = 2 self.no_of_phases = 2
self.takes = ["eblif", "place", "sdc?"] self.takes = ["eblif", "place", "sdc?"]
self.produces = ["route"] self.produces = ["route"]
self.values = ["device", "vpr_options?"] + vpr_specific_values() self.values = ["device", "vpr_options?"] + vpr_specific_values
ModuleClass = RouteModule ModuleClass = RouteModule

106
f4pga/flows/tools/vpr.py Normal file
View File

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