f4pga/wrappers/tcl: combine 'conv.*.tcl' into 'synth.*.tcl' (#633)
Signed-off-by: Unai Martinez-Corral <umartinezcorral@antmicro.com>
This commit is contained in:
parent
df95a8a987
commit
ce0c29bddb
|
@ -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.common import decompose_depname, get_verbosity_level, sub as common_sub
|
||||||
from f4pga.flows.module import Module, ModuleContext
|
from f4pga.flows.module import Module, ModuleContext
|
||||||
from f4pga.wrappers.tcl import get_script_path as get_tcl_wrapper_path
|
from f4pga.wrappers.tcl import get_script_path as get_tcl_wrapper_path
|
||||||
from f4pga.utils import split_inouts
|
|
||||||
|
|
||||||
|
|
||||||
class SynthModule(Module):
|
class SynthModule(Module):
|
||||||
|
@ -52,19 +51,9 @@ class SynthModule(Module):
|
||||||
return mapping
|
return mapping
|
||||||
|
|
||||||
def execute(self, ctx: ModuleContext):
|
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'...'}"
|
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 = []
|
verilog_files = []
|
||||||
# Use append read_verilog commands to the scripts for more sophisticated
|
# Use append read_verilog commands to the scripts for more sophisticated
|
||||||
# input if arguments are specified. Omit direct input throught `yosys` command.
|
# 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}"
|
tcl = f"read_verilog {args_str} {vfile}; {tcl}"
|
||||||
else:
|
else:
|
||||||
verilog_files = ctx.takes.sources
|
verilog_files = ctx.takes.sources
|
||||||
|
|
||||||
# Set up environment for TCL weirdness
|
# Set up environment for TCL weirdness
|
||||||
env = environ.copy()
|
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
|
# Execute YOSYS command
|
||||||
common_sub(
|
common_sub(
|
||||||
*(["yosys", "-p", tcl] + (["-l", ctx.outputs.synth_log] if ctx.outputs.synth_log else []) + verilog_files),
|
*(["yosys", "-p", tcl] + (["-l", ctx.outputs.synth_log] if ctx.outputs.synth_log else []) + verilog_files),
|
||||||
env=env,
|
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():
|
if not Path(ctx.produces.fasm_extra).is_file():
|
||||||
with Path(ctx.produces.fasm_extra).open("w") as wfptr:
|
with Path(ctx.produces.fasm_extra).open("w") as wfptr:
|
||||||
wfptr.write("")
|
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):
|
def __init__(self, params):
|
||||||
self.name = "synthesize"
|
self.name = "synthesize"
|
||||||
self.no_of_phases = 3
|
self.no_of_phases = 3
|
||||||
|
|
|
@ -231,6 +231,7 @@ ql-eos-s3:
|
||||||
read_verilog_args: []
|
read_verilog_args: []
|
||||||
yosys_tcl_env:
|
yosys_tcl_env:
|
||||||
OUT_JSON: '${:json}'
|
OUT_JSON: '${:json}'
|
||||||
|
SYNTH_JSON: '${:synth_json}'
|
||||||
OUT_SYNTH_V: '${:synth_v}'
|
OUT_SYNTH_V: '${:synth_v}'
|
||||||
OUT_EBLIF: '${:eblif}'
|
OUT_EBLIF: '${:eblif}'
|
||||||
OUT_FASM_EXTRA: '${:fasm_extra}'
|
OUT_FASM_EXTRA: '${:fasm_extra}'
|
||||||
|
@ -618,6 +619,7 @@ ql-k4n8_fast: &ql-k4n8
|
||||||
yosys_tcl_env:
|
yosys_tcl_env:
|
||||||
TOP: '${top}'
|
TOP: '${top}'
|
||||||
OUT_JSON: '${:json}'
|
OUT_JSON: '${:json}'
|
||||||
|
SYNTH_JSON: '${:synth_json}'
|
||||||
TECHMAP_PATH: '${shareDir}/techmaps/qlf_k4n8'
|
TECHMAP_PATH: '${shareDir}/techmaps/qlf_k4n8'
|
||||||
OUT_SYNTH_V: '${:synth_v}'
|
OUT_SYNTH_V: '${:synth_v}'
|
||||||
OUT_EBLIF: '${:eblif}'
|
OUT_EBLIF: '${:eblif}'
|
||||||
|
|
|
@ -83,12 +83,12 @@ setuptools_setup(
|
||||||
"f4pga.flows": [
|
"f4pga.flows": [
|
||||||
"*.yml",
|
"*.yml",
|
||||||
],
|
],
|
||||||
"f4pga.wrappers.sh": ["xc7/*.f4pga.sh", "quicklogic/*.f4pga.sh"],
|
"f4pga.wrappers.sh": [
|
||||||
|
"xc7/*.f4pga.sh",
|
||||||
|
"quicklogic/*.f4pga.sh",
|
||||||
|
],
|
||||||
"f4pga.wrappers.tcl": [
|
"f4pga.wrappers.tcl": [
|
||||||
"xc7/*.f4pga.tcl",
|
"*.f4pga.tcl",
|
||||||
"eos-s3/*.f4pga.tcl",
|
|
||||||
"qlf_k4n8/*.f4pga.tcl",
|
|
||||||
"ice40/*.f4pga.tcl",
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
classifiers=[],
|
classifiers=[],
|
||||||
|
|
|
@ -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
|
|
|
@ -106,21 +106,11 @@ for arg in $@; do
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -z ${FAMILY} ]; then
|
if [ -z ${FAMILY} ]; then echo "Please specify device family"; exit 1; fi
|
||||||
echo "Please specify device family"
|
if [ ${#VERILOG_FILES[@]} -eq 0 ]; then echo "Please provide at least one Verilog file"; exit 1; fi
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${#VERILOG_FILES[@]} -eq 0 ]; then
|
|
||||||
echo "Please provide at least one Verilog file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
PINMAPCSV="pinmap_${PART}.csv"
|
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 USE_ROI="FALSE"
|
||||||
export OUT_JSON=$TOP.json
|
export OUT_JSON=$TOP.json
|
||||||
export SYNTH_JSON=${TOP}_io.json
|
export SYNTH_JSON=${TOP}_io.json
|
||||||
|
@ -160,7 +150,7 @@ YOSYS_COMMANDS="${YOSYS_COMMANDS//$'\n'/'; '}"
|
||||||
|
|
||||||
LOG=${TOP}_synth.log
|
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
|
for f in ${VERILOG_FILES[*]}; do
|
||||||
YOSYS_SCRIPT="read_verilog ${f}; $YOSYS_SCRIPT"
|
YOSYS_SCRIPT="read_verilog ${f}; $YOSYS_SCRIPT"
|
||||||
|
@ -171,5 +161,3 @@ if [ ! -z "${YOSYS_COMMANDS}" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
`which yosys` -p "${YOSYS_SCRIPT}" -l $LOG
|
`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}"
|
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
SYNTH_TCL_PATH="$(python3 -m f4pga.wrappers.tcl synth)"
|
|
||||||
|
|
||||||
VERILOG_FILES=()
|
VERILOG_FILES=()
|
||||||
XDC_FILES=()
|
XDC_FILES=()
|
||||||
TOP=top
|
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 OUT_FASM_EXTRA=${TOP}_fasm_extra.fasm
|
||||||
export PYTHON3=${PYTHON3:-$(which python3)}
|
export PYTHON3=${PYTHON3:-$(which python3)}
|
||||||
|
|
||||||
LOG=${TOP}_synth.log
|
yosys_read_cmds="read_verilog"
|
||||||
|
if [ -n "$SURELOG_CMD" ]; then
|
||||||
if [ -z "$SURELOG_CMD" ]; then
|
yosys_read_cmds="plugin -i uhdm; read_verilog_with_uhdm ${SURELOG_CMD[*]}"
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
yosys -p "$yosys_read_cmds ${VERILOG_FILES[*]}; tcl $(python3 -m f4pga.wrappers.tcl)" -l "${TOP}_synth.log"
|
||||||
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)"
|
|
||||||
|
|
|
@ -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"]}
|
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:
|
if arch is None:
|
||||||
arch = FPGA_FAM
|
arch = FPGA_FAM
|
||||||
for key, val in ARCHS.items():
|
for key, val in ARCHS.items():
|
||||||
|
@ -37,6 +37,4 @@ def get_script_path(arg, arch=None):
|
||||||
break
|
break
|
||||||
if arch not in ["xc7", "eos-s3", "qlf_k4n8", "ice40"]:
|
if arch not in ["xc7", "eos-s3", "qlf_k4n8", "ice40"]:
|
||||||
raise (Exception(f"Unsupported arch <{arch}>!"))
|
raise (Exception(f"Unsupported arch <{arch}>!"))
|
||||||
if arg not in ["synth", "conv"]:
|
return ROOT / f"{arch}.f4pga.tcl"
|
||||||
raise Exception(f"Unknown tcl wrapper <{arg}>!")
|
|
||||||
return ROOT / arch / f"{arg}.f4pga.tcl"
|
|
||||||
|
|
|
@ -24,4 +24,4 @@ from f4pga.wrappers.tcl import get_script_path
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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))
|
||||||
|
|
|
@ -181,3 +181,14 @@ exec $::env(PYTHON3) -m f4pga.utils.quicklogic.yosys_fixup_cell_names $::env(OUT
|
||||||
design -reset
|
design -reset
|
||||||
read_json $::env(OUT_JSON)
|
read_json $::env(OUT_JSON)
|
||||||
write_verilog $::env(OUT_SYNTH_V)
|
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)
|
|
@ -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)
|
|
|
@ -27,3 +27,10 @@ setundef -zero -params
|
||||||
clean_processes
|
clean_processes
|
||||||
write_json $::env(OUT_JSON)
|
write_json $::env(OUT_JSON)
|
||||||
write_verilog $::env(OUT_SYNTH_V)
|
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)
|
|
@ -1,7 +0,0 @@
|
||||||
yosys -import
|
|
||||||
|
|
||||||
# Clean
|
|
||||||
opt_clean
|
|
||||||
|
|
||||||
# Write EBLIF
|
|
||||||
write_blif -attr -cname -param $::env(OUT_EBLIF)
|
|
|
@ -30,3 +30,10 @@ stat
|
||||||
|
|
||||||
write_json $::env(OUT_JSON)
|
write_json $::env(OUT_JSON)
|
||||||
write_verilog $::env(OUT_SYNTH_V)
|
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)
|
|
@ -1,7 +0,0 @@
|
||||||
yosys -import
|
|
||||||
|
|
||||||
# Clean
|
|
||||||
opt_clean
|
|
||||||
|
|
||||||
# Write EBLIF
|
|
||||||
write_blif -attr -cname -param $::env(OUT_EBLIF)
|
|
|
@ -243,3 +243,23 @@ clean_processes
|
||||||
write_json $::env(OUT_JSON)
|
write_json $::env(OUT_JSON)
|
||||||
# Write the design in Verilog format.
|
# Write the design in Verilog format.
|
||||||
write_verilog $::env(OUT_SYNTH_V)
|
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)
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue