| #!/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 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 | |
| class FasmModule(Module): | |
| def map_io(self, ctx: ModuleContext): | |
| build_dir = str(Path(ctx.takes.eblif).parent) | |
| return {"fasm": f"{(Path(build_dir)/ctx.values.top)!s}.fasm"} | |
| def execute(self, ctx: ModuleContext): | |
| build_dir = str(Path(ctx.takes.eblif).parent) | |
| vprargs = VprArgs( | |
| share=ctx.share, | |
| eblif=ctx.takes.eblif, | |
| arch_def=ctx.values.arch_def, | |
| lookahead=ctx.values.rr_graph_lookahead_bin, | |
| rr_graph=ctx.values.rr_graph_real_bin, | |
| place_delay=ctx.values.vpr_place_delay, | |
| device_name=ctx.values.vpr_grid_layout_name, | |
| vpr_options=ctx.values.vpr_options if ctx.values.vpr_options else {}, | |
| ) | |
| optional = [] | |
| if ctx.values.pnr_corner is not None: | |
| optional += ["--pnr_corner", ctx.values.pnr_corner] | |
| if ctx.takes.sdc: | |
| optional += ["--sdc", ctx.takes.sdc] | |
| s = [ | |
| "genfasm", | |
| vprargs.arch_def, | |
| str(Path(ctx.takes.eblif).resolve()), | |
| "--device", | |
| vprargs.device_name, | |
| "--read_rr_graph", | |
| vprargs.rr_graph, | |
| ] + vprargs.optional | |
| if get_verbosity_level() >= 2: | |
| yield "Generating FASM...\n " + " ".join(s) | |
| else: | |
| yield "Generating FASM..." | |
| common_sub(*s, cwd=build_dir) | |
| default_fasm_output_name = Path(build_dir) / f"{ctx.values.top}.fasm" | |
| if str(default_fasm_output_name) != ctx.outputs.fasm: | |
| default_fasm_output_name.rename(ctx.outputs.fasm) | |
| if ctx.takes.fasm_extra: | |
| yield "Appending extra FASM..." | |
| with open(ctx.outputs.fasm, "a") as fasm_file, open(ctx.takes.fasm_extra, "r") as fasm_extra_file: | |
| fasm_file.write(f"\n{fasm_extra_file.read()}") | |
| else: | |
| yield "No extra FASM to append" | |
| def __init__(self, _): | |
| self.name = "fasm" | |
| 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.prod_meta = {"fasm": "FPGA assembly file"} | |
| ModuleClass = FasmModule |