f4pga/wrappers/tcl: combine 'conv.*.tcl' into 'synth.*.tcl' (#633)

Signed-off-by: Unai Martinez-Corral <umartinezcorral@antmicro.com>
This commit is contained in:
Unai Martinez-Corral 2022-09-06 23:50:29 +02:00 committed by GitHub
parent df95a8a987
commit ce0c29bddb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 77 additions and 126 deletions

View File

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

View File

@ -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}'

View File

@ -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=[],

View File

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

View File

@ -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}"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +0,0 @@
yosys -import
# Clean
opt_clean
# Write EBLIF
write_blif -attr -cname -param $::env(OUT_EBLIF)

View File

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

View File

@ -1,7 +0,0 @@
yosys -import
# Clean
opt_clean
# Write EBLIF
write_blif -attr -cname -param $::env(OUT_EBLIF)

View File

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

View File

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