diff --git a/f4pga/flows/common_modules/synth.py b/f4pga/flows/common_modules/synth.py index d1fd86b..07ab3c1 100755 --- a/f4pga/flows/common_modules/synth.py +++ b/f4pga/flows/common_modules/synth.py @@ -23,7 +23,6 @@ from pathlib import Path from f4pga.flows.common import decompose_depname, get_verbosity_level, sub as common_sub from f4pga.flows.module import Module, ModuleContext from f4pga.wrappers.tcl import get_script_path as get_tcl_wrapper_path -from f4pga.utils import split_inouts class SynthModule(Module): @@ -52,19 +51,9 @@ class SynthModule(Module): return mapping def execute(self, ctx: ModuleContext): - # Setup environmental variables for YOSYS TCL scripts. - tcl_env = ( - { - key: (" ".join(val) if type(val) is list else val) - for key, val in ctx.values.yosys_tcl_env.items() - if val is not None - } - if ctx.values.yosys_tcl_env - else {} - ) - yield f"Synthesizing sources{f': {ctx.takes.sources}...' if get_verbosity_level() >= 2 else f'...'}" - tcl = f'tcl {str(get_tcl_wrapper_path("synth"))}' + + tcl = f"tcl {str(get_tcl_wrapper_path())}" verilog_files = [] # Use append read_verilog commands to the scripts for more sophisticated # input if arguments are specified. Omit direct input throught `yosys` command. @@ -74,30 +63,31 @@ class SynthModule(Module): tcl = f"read_verilog {args_str} {vfile}; {tcl}" else: verilog_files = ctx.takes.sources + # Set up environment for TCL weirdness env = environ.copy() - env.update(tcl_env) + env.update( + ( + { + key: (" ".join(val) if type(val) is list else val) + for key, val in ctx.values.yosys_tcl_env.items() + if val is not None + } + if ctx.values.yosys_tcl_env + else {} + ) + ) + # Execute YOSYS command common_sub( *(["yosys", "-p", tcl] + (["-l", ctx.outputs.synth_log] if ctx.outputs.synth_log else []) + verilog_files), env=env, ) - yield f"Splitting in/outs..." - split_inouts(ctx.outputs.json, ctx.outputs.synth_json) - if not Path(ctx.produces.fasm_extra).is_file(): with Path(ctx.produces.fasm_extra).open("w") as wfptr: wfptr.write("") - yield f"Converting..." - # Set up environment for TCL weirdness - env = environ.copy() - env.update(tcl_env) - common_sub( - "yosys", "-p", f'read_json {ctx.outputs.synth_json}; tcl {str(get_tcl_wrapper_path("conv"))}', env=env - ) - def __init__(self, params): self.name = "synthesize" self.no_of_phases = 3 diff --git a/f4pga/flows/platforms.yml b/f4pga/flows/platforms.yml index 1693385..4313795 100644 --- a/f4pga/flows/platforms.yml +++ b/f4pga/flows/platforms.yml @@ -231,6 +231,7 @@ ql-eos-s3: read_verilog_args: [] yosys_tcl_env: OUT_JSON: '${:json}' + SYNTH_JSON: '${:synth_json}' OUT_SYNTH_V: '${:synth_v}' OUT_EBLIF: '${:eblif}' OUT_FASM_EXTRA: '${:fasm_extra}' @@ -618,6 +619,7 @@ ql-k4n8_fast: &ql-k4n8 yosys_tcl_env: TOP: '${top}' OUT_JSON: '${:json}' + SYNTH_JSON: '${:synth_json}' TECHMAP_PATH: '${shareDir}/techmaps/qlf_k4n8' OUT_SYNTH_V: '${:synth_v}' OUT_EBLIF: '${:eblif}' diff --git a/f4pga/setup.py b/f4pga/setup.py index 0a3ff03..61a286b 100644 --- a/f4pga/setup.py +++ b/f4pga/setup.py @@ -83,12 +83,12 @@ setuptools_setup( "f4pga.flows": [ "*.yml", ], - "f4pga.wrappers.sh": ["xc7/*.f4pga.sh", "quicklogic/*.f4pga.sh"], + "f4pga.wrappers.sh": [ + "xc7/*.f4pga.sh", + "quicklogic/*.f4pga.sh", + ], "f4pga.wrappers.tcl": [ - "xc7/*.f4pga.tcl", - "eos-s3/*.f4pga.tcl", - "qlf_k4n8/*.f4pga.tcl", - "ice40/*.f4pga.tcl", + "*.f4pga.tcl", ], }, classifiers=[], diff --git a/f4pga/utils/__init__.py b/f4pga/utils/__init__.py deleted file mode 100644 index 079d74d..0000000 --- a/f4pga/utils/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 f4pga.utils.split_inouts import main as split_inouts diff --git a/f4pga/utils/split_inouts.py b/f4pga/utils/yosys_split_inouts.py similarity index 100% rename from f4pga/utils/split_inouts.py rename to f4pga/utils/yosys_split_inouts.py diff --git a/f4pga/wrappers/sh/quicklogic/synth.f4pga.sh b/f4pga/wrappers/sh/quicklogic/synth.f4pga.sh index 55912d5..d5465f9 100755 --- a/f4pga/wrappers/sh/quicklogic/synth.f4pga.sh +++ b/f4pga/wrappers/sh/quicklogic/synth.f4pga.sh @@ -106,21 +106,11 @@ for arg in $@; do done -if [ -z ${FAMILY} ]; then - echo "Please specify device family" - exit 1 -fi - -if [ ${#VERILOG_FILES[@]} -eq 0 ]; then - echo "Please provide at least one Verilog file" - exit 1 -fi +if [ -z ${FAMILY} ]; then echo "Please specify device family"; exit 1; fi +if [ ${#VERILOG_FILES[@]} -eq 0 ]; then echo "Please provide at least one Verilog file"; exit 1; fi PINMAPCSV="pinmap_${PART}.csv" -SYNTH_TCL_PATH="$(python3 -m f4pga.wrappers.tcl synth "${FAMILY}")" -CONV_TCL_PATH="$(python3 -m f4pga.wrappers.tcl conv "${FAMILY}")" - export USE_ROI="FALSE" export OUT_JSON=$TOP.json export SYNTH_JSON=${TOP}_io.json @@ -160,7 +150,7 @@ YOSYS_COMMANDS="${YOSYS_COMMANDS//$'\n'/'; '}" LOG=${TOP}_synth.log -YOSYS_SCRIPT="tcl ${SYNTH_TCL_PATH}" +YOSYS_SCRIPT="tcl $(python3 -m f4pga.wrappers.tcl "${FAMILY}")" for f in ${VERILOG_FILES[*]}; do YOSYS_SCRIPT="read_verilog ${f}; $YOSYS_SCRIPT" @@ -171,5 +161,3 @@ if [ ! -z "${YOSYS_COMMANDS}" ]; then fi `which yosys` -p "${YOSYS_SCRIPT}" -l $LOG -`which python3` -m f4pga.utils.split_inouts -i ${OUT_JSON} -o ${SYNTH_JSON} -`which yosys` -p "read_json $SYNTH_JSON; tcl ${CONV_TCL_PATH}" diff --git a/f4pga/wrappers/sh/xc7/synth.f4pga.sh b/f4pga/wrappers/sh/xc7/synth.f4pga.sh index d5d043a..c5d0d9a 100755 --- a/f4pga/wrappers/sh/xc7/synth.f4pga.sh +++ b/f4pga/wrappers/sh/xc7/synth.f4pga.sh @@ -18,8 +18,6 @@ set -e -SYNTH_TCL_PATH="$(python3 -m f4pga.wrappers.tcl synth)" - VERILOG_FILES=() XDC_FILES=() TOP=top @@ -128,13 +126,8 @@ export PART_JSON=`realpath ${DATABASE_DIR}/$DEVICE/$PART/part.json` export OUT_FASM_EXTRA=${TOP}_fasm_extra.fasm export PYTHON3=${PYTHON3:-$(which python3)} -LOG=${TOP}_synth.log - -if [ -z "$SURELOG_CMD" ]; then - yosys -p "tcl ${SYNTH_TCL_PATH}" -l $LOG ${VERILOG_FILES[*]} -else - yosys -p "plugin -i uhdm" -p "read_verilog_with_uhdm ${SURELOG_CMD[*]} ${VERILOG_FILES[*]}" -p "tcl ${SYNTH_TCL_PATH}" -l $LOG +yosys_read_cmds="read_verilog" +if [ -n "$SURELOG_CMD" ]; then + yosys_read_cmds="plugin -i uhdm; read_verilog_with_uhdm ${SURELOG_CMD[*]}" fi - -python3 -m f4pga.utils.split_inouts -i ${OUT_JSON} -o ${SYNTH_JSON} -yosys -p "read_json $SYNTH_JSON; tcl $(python3 -m f4pga.wrappers.tcl conv)" +yosys -p "$yosys_read_cmds ${VERILOG_FILES[*]}; tcl $(python3 -m f4pga.wrappers.tcl)" -l "${TOP}_synth.log" diff --git a/f4pga/wrappers/tcl/__init__.py b/f4pga/wrappers/tcl/__init__.py index c333e5c..7b73c5c 100644 --- a/f4pga/wrappers/tcl/__init__.py +++ b/f4pga/wrappers/tcl/__init__.py @@ -28,7 +28,7 @@ ROOT = Path(__file__).resolve().parent ARCHS = {"xc7": ["artix7", "artix7_100t", "artix7_200t", "zynq7", "zynq7_z020", "spartan7"], "eos-s3": ["ql-s3", "pp3"]} -def get_script_path(arg, arch=None): +def get_script_path(arch=None): if arch is None: arch = FPGA_FAM for key, val in ARCHS.items(): @@ -37,6 +37,4 @@ def get_script_path(arg, arch=None): break if arch not in ["xc7", "eos-s3", "qlf_k4n8", "ice40"]: raise (Exception(f"Unsupported arch <{arch}>!")) - if arg not in ["synth", "conv"]: - raise Exception(f"Unknown tcl wrapper <{arg}>!") - return ROOT / arch / f"{arg}.f4pga.tcl" + return ROOT / f"{arch}.f4pga.tcl" diff --git a/f4pga/wrappers/tcl/__main__.py b/f4pga/wrappers/tcl/__main__.py index 57c71d9..2598a96 100644 --- a/f4pga/wrappers/tcl/__main__.py +++ b/f4pga/wrappers/tcl/__main__.py @@ -24,4 +24,4 @@ from f4pga.wrappers.tcl import get_script_path if __name__ == "__main__": - print(get_script_path(sys_argv[1], sys_argv[2]) if len(sys_argv) > 2 else get_script_path(sys_argv[1])) + print(get_script_path(sys_argv[1] if len(sys_argv) > 1 else None)) diff --git a/f4pga/wrappers/tcl/eos-s3/synth.f4pga.tcl b/f4pga/wrappers/tcl/eos-s3.f4pga.tcl similarity index 95% rename from f4pga/wrappers/tcl/eos-s3/synth.f4pga.tcl rename to f4pga/wrappers/tcl/eos-s3.f4pga.tcl index 62c93e4..ea438d9 100644 --- a/f4pga/wrappers/tcl/eos-s3/synth.f4pga.tcl +++ b/f4pga/wrappers/tcl/eos-s3.f4pga.tcl @@ -181,3 +181,14 @@ exec $::env(PYTHON3) -m f4pga.utils.quicklogic.yosys_fixup_cell_names $::env(OUT design -reset read_json $::env(OUT_JSON) write_verilog $::env(OUT_SYNTH_V) + +design -reset +exec $::env(PYTHON3) -m f4pga.utils.yosys_split_inouts -i $::env(OUT_JSON) -o $::env(SYNTH_JSON) +read_json $::env(SYNTH_JSON) +yosys -import +opt_clean +write_blif -attr -cname -param \ + -true VCC VCC \ + -false GND GND \ + -undef VCC VCC \ + $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/eos-s3/conv.f4pga.tcl b/f4pga/wrappers/tcl/eos-s3/conv.f4pga.tcl deleted file mode 100644 index 60587b0..0000000 --- a/f4pga/wrappers/tcl/eos-s3/conv.f4pga.tcl +++ /dev/null @@ -1,11 +0,0 @@ -yosys -import - -# Clean -opt_clean - -# Write EBLIF -write_blif -attr -cname -param \ - -true VCC VCC \ - -false GND GND \ - -undef VCC VCC \ - $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/ice40/synth.f4pga.tcl b/f4pga/wrappers/tcl/ice40.f4pga.tcl similarity index 72% rename from f4pga/wrappers/tcl/ice40/synth.f4pga.tcl rename to f4pga/wrappers/tcl/ice40.f4pga.tcl index 3024c89..a66b896 100644 --- a/f4pga/wrappers/tcl/ice40/synth.f4pga.tcl +++ b/f4pga/wrappers/tcl/ice40.f4pga.tcl @@ -27,3 +27,10 @@ setundef -zero -params clean_processes write_json $::env(OUT_JSON) write_verilog $::env(OUT_SYNTH_V) + +design -reset +exec $::env(PYTHON3) -m f4pga.utils.yosys_split_inouts -i $::env(OUT_JSON) -o $::env(SYNTH_JSON) +read_json $::env(SYNTH_JSON) +yosys -import +opt_clean +write_blif -attr -cname -param $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/ice40/conv.f4pga.tcl b/f4pga/wrappers/tcl/ice40/conv.f4pga.tcl deleted file mode 100644 index 12d355f..0000000 --- a/f4pga/wrappers/tcl/ice40/conv.f4pga.tcl +++ /dev/null @@ -1,7 +0,0 @@ -yosys -import - -# Clean -opt_clean - -# Write EBLIF -write_blif -attr -cname -param $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/qlf_k4n8/synth.f4pga.tcl b/f4pga/wrappers/tcl/qlf_k4n8.f4pga.tcl similarity index 77% rename from f4pga/wrappers/tcl/qlf_k4n8/synth.f4pga.tcl rename to f4pga/wrappers/tcl/qlf_k4n8.f4pga.tcl index 06c5bfa..2c8b7f9 100644 --- a/f4pga/wrappers/tcl/qlf_k4n8/synth.f4pga.tcl +++ b/f4pga/wrappers/tcl/qlf_k4n8.f4pga.tcl @@ -30,3 +30,10 @@ stat write_json $::env(OUT_JSON) write_verilog $::env(OUT_SYNTH_V) + +design -reset +exec $::env(PYTHON3) -m f4pga.utils.yosys_split_inouts -i $::env(OUT_JSON) -o $::env(SYNTH_JSON) +read_json $::env(SYNTH_JSON) +yosys -import +opt_clean +write_blif -attr -cname -param $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/qlf_k4n8/conv.f4pga.tcl b/f4pga/wrappers/tcl/qlf_k4n8/conv.f4pga.tcl deleted file mode 100644 index 12d355f..0000000 --- a/f4pga/wrappers/tcl/qlf_k4n8/conv.f4pga.tcl +++ /dev/null @@ -1,7 +0,0 @@ -yosys -import - -# Clean -opt_clean - -# Write EBLIF -write_blif -attr -cname -param $::env(OUT_EBLIF) diff --git a/f4pga/wrappers/tcl/xc7/synth.f4pga.tcl b/f4pga/wrappers/tcl/xc7.f4pga.tcl similarity index 93% rename from f4pga/wrappers/tcl/xc7/synth.f4pga.tcl rename to f4pga/wrappers/tcl/xc7.f4pga.tcl index b379ff0..dbab425 100644 --- a/f4pga/wrappers/tcl/xc7/synth.f4pga.tcl +++ b/f4pga/wrappers/tcl/xc7.f4pga.tcl @@ -243,3 +243,23 @@ clean_processes write_json $::env(OUT_JSON) # Write the design in Verilog format. write_verilog $::env(OUT_SYNTH_V) + +design -reset +exec $::env(PYTHON3) -m f4pga.utils.yosys_split_inouts -i $::env(OUT_JSON) -o $::env(SYNTH_JSON) +read_json $::env(SYNTH_JSON) +yosys -import +opt_clean +# Designs that directly tie OPAD's to constants cannot use the dedicate +# constant network as an artifact of the way the ROI is configured. +# Until the ROI is removed, enable designs to selectively disable the dedicated +# constant network. +if { [info exists ::env(USE_LUT_CONSTANTS)] } { + write_blif -attr -cname -param \ + $::env(OUT_EBLIF) +} else { + write_blif -attr -cname -param \ + -true VCC VCC \ + -false GND GND \ + -undef VCC VCC \ + $::env(OUT_EBLIF) +} diff --git a/f4pga/wrappers/tcl/xc7/conv.f4pga.tcl b/f4pga/wrappers/tcl/xc7/conv.f4pga.tcl deleted file mode 100644 index e2515e9..0000000 --- a/f4pga/wrappers/tcl/xc7/conv.f4pga.tcl +++ /dev/null @@ -1,20 +0,0 @@ -yosys -import - -# Clean -opt_clean - -# Designs that directly tie OPAD's to constants cannot use the dedicate -# constant network as an artifact of the way the ROI is configured. -# Until the ROI is removed, enable designs to selectively disable the dedicated -# constant network. -if { [info exists ::env(USE_LUT_CONSTANTS)] } { - write_blif -attr -cname -param \ - $::env(OUT_EBLIF) -} else { - write_blif -attr -cname -param \ - -true VCC VCC \ - -false GND GND \ - -undef VCC VCC \ - $::env(OUT_EBLIF) -} -