f4pga enable new eos-s3 flow (#577)
This commit is contained in:
commit
c342fc6ff1
|
@ -1 +1,26 @@
|
|||
{}
|
||||
{
|
||||
"default_part": "EOS3FF512-PDN64",
|
||||
"values": {
|
||||
"top": "top"
|
||||
},
|
||||
"dependencies": {
|
||||
"sources": [
|
||||
"eos-s3/btn_counter/btn_counter.v"
|
||||
],
|
||||
"synth_log": "synth.log",
|
||||
"pack_log": "pack.log",
|
||||
"analysis_log": "analysis.log"
|
||||
},
|
||||
"EOS3FF512-PDN64": {
|
||||
"default_target": "bitstream",
|
||||
"dependencies": {
|
||||
"build_dir": "build/eos-s3",
|
||||
"pcf": "eos-s3/btn_counter/chandalar.pcf",
|
||||
"sdc-in": "eos-s3/btn_counter/dummy.sdc"
|
||||
},
|
||||
"values": {
|
||||
"part": "ql-eos-s3",
|
||||
"package": "PD64"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,26 +115,15 @@ jobs:
|
|||
if: matrix.flow == 'F4PGA'
|
||||
run: |
|
||||
. ./.github/scripts/activate.sh
|
||||
|
||||
cd f4pga-examples
|
||||
f4pga build --flow ../.github/${{ matrix.fam }}_test.json
|
||||
|
||||
# FIXME
|
||||
# Temporarily allow QL example to fail, until https://github.com/chipsalliance/f4pga/pull/577 is merged.
|
||||
case '${{ matrix.fam }}' in
|
||||
eos-s3)
|
||||
f4pga build --flow ../.github/${{ matrix.fam }}_test.json | echo 'See #577'
|
||||
;;
|
||||
*)
|
||||
f4pga build --flow ../.github/${{ matrix.fam }}_test.json
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: '📤 Upload artifact: Arty 35 bitstream'
|
||||
if: matrix.flow == 'F4PGA' && matrix.fam == 'xc7'
|
||||
- name: '📤 Upload artifact: ${{ matrix.fam }} bitstream'
|
||||
if: matrix.flow == 'F4PGA'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.flow }}-arty_35-Bitstream-pyF4PGA
|
||||
path: f4pga-examples/build/arty_35/top.bit
|
||||
name: ${{ matrix.flow }}-${{ matrix.fam }}-Bitstream
|
||||
path: f4pga-examples/build/${{ matrix.fam }}/top.bit
|
||||
if-no-files-found: error
|
||||
|
||||
# SymbiFlow
|
||||
|
@ -163,19 +152,19 @@ jobs:
|
|||
esac
|
||||
|
||||
- name: '📤 Upload artifact: Arty 35 bitstream'
|
||||
if: matrix.flow == 'SymbiFLow' && matrix.fam == 'xc7'
|
||||
if: matrix.flow == 'SymbiFlow' && matrix.fam == 'xc7'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.flow }}-arty_35-Bitstream
|
||||
path: f4pga-examples/xc7/counter_test/build/arty_35/top.bit
|
||||
name: ${{ matrix.flow }}-${{ matrix.fam }}-Bitstream
|
||||
path: f4pga-examples/${{ matrix.fam }}/counter_test/build/arty_35/top.bit
|
||||
if-no-files-found: error
|
||||
|
||||
- name: '📤 Upload artifact: QuickLogic bitstream'
|
||||
if: matrix.flow == 'SymbiFLow' && matrix.fam == 'eos-s3'
|
||||
if: matrix.flow == 'SymbiFlow' && matrix.fam == 'eos-s3'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.flow }}-eos-s3-Bitstream
|
||||
path: f4pga-examples/eos-s3/btn_counter/build/top.bit
|
||||
name: ${{ matrix.flow }}-${{ matrix.fam }}-Bitstream
|
||||
path: f4pga-examples/${{ matrix.fam }}/btn_counter/build/top.bit
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
|
@ -225,4 +214,4 @@ jobs:
|
|||
- name: 🚧 Test pyF4PGA (PYTHONPATH)
|
||||
run: |
|
||||
PYTHONPATH=$(pwd) python3 f4pga/__init__.py
|
||||
PYTHONPATH=$(pwd) python3 f4pga/__init__.py -h
|
||||
PYTHONPATH=$(pwd) python3 f4pga/__init__.py -h
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"XC7A35TCSG324-1": {
|
||||
"default_target": "bitstream",
|
||||
"dependencies": {
|
||||
"build_dir": "build/arty_35",
|
||||
"build_dir": "build/xc7",
|
||||
"xdc": [
|
||||
"xc7/counter_test/arty.xdc"
|
||||
]
|
||||
|
|
|
@ -74,14 +74,13 @@ install_dir = environ.get("F4PGA_INSTALL_DIR", "/usr/local")
|
|||
|
||||
mypath = str(Path(__file__).resolve().parent)
|
||||
|
||||
FPGA_FAM = environ.get('FPGA_FAM', 'xc7')
|
||||
|
||||
bin_dir_path = \
|
||||
environ.get('F4PGA_BIN_DIR', str(Path(sys_argv[0]).resolve().parent.parent))
|
||||
share_dir_path = \
|
||||
environ.get('F4PGA_SHARE_DIR',
|
||||
str(Path(f'{install_dir}/xc7/install/share/f4pga').resolve()))
|
||||
if share_dir_path is None:
|
||||
share_dir_path = str(Path(f'{install_dir}/xc7/install/share/f4pga').resolve())
|
||||
str(Path(f'{install_dir}/{FPGA_FAM}/install/share/f4pga').resolve()))
|
||||
|
||||
class DependencyNotProducedException(F4PGAException):
|
||||
dep_name: str
|
||||
|
@ -532,11 +531,14 @@ def setup_resolution_env():
|
|||
"""
|
||||
Generate initial values, available in configs.
|
||||
"""
|
||||
return {
|
||||
'prjxray_db': common_sub('prjxray-config').decode().replace('\n', ''),
|
||||
conf = {
|
||||
'python3': common_sub('which', 'python3').decode().replace('\n', ''),
|
||||
'noisyWarnings': _noisy_warnings()
|
||||
}
|
||||
if (FPGA_FAM == 'xc7'):
|
||||
conf['prjxray_db'] = common_sub('prjxray-config').decode().replace('\n', '')
|
||||
|
||||
return conf
|
||||
|
||||
r_env.add_values(_generate_values())
|
||||
return r_env
|
||||
|
|
|
@ -174,6 +174,8 @@ def vpr(mode: str, vprargs: VprArgs, cwd=None):
|
|||
modeargs = ['--place']
|
||||
elif mode == 'route':
|
||||
modeargs = ['--route']
|
||||
elif mode == 'analysis':
|
||||
modeargs = ['--analysis']
|
||||
|
||||
return sub(*([
|
||||
'vpr',
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#!/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.common import *
|
||||
from f4pga.module import Module, ModuleContext
|
||||
|
||||
|
||||
def analysis_merged_post_implementation_file(ctx: ModuleContext):
|
||||
return str(Path(ctx.takes.eblif).with_suffix('')) + '_merged_post_implementation.v'
|
||||
|
||||
|
||||
def analysis_post_implementation_file(ctx: ModuleContext):
|
||||
return str(Path(ctx.takes.eblif).with_suffix('')) + '_post_synthesis.v'
|
||||
|
||||
|
||||
class analysisModule(Module):
|
||||
def map_io(self, ctx: ModuleContext):
|
||||
return {
|
||||
'merged_post_implementation_v': analysis_merged_post_implementation_file(ctx),
|
||||
'post_implementation_v': analysis_post_implementation_file(ctx)
|
||||
}
|
||||
|
||||
def execute(self, ctx: ModuleContext):
|
||||
build_dir = str(Path(ctx.takes.eblif).parent)
|
||||
|
||||
vpr_options = []
|
||||
if ctx.values.vpr_options:
|
||||
vpr_options = options_dict_to_list(ctx.values.vpr_options)
|
||||
|
||||
yield 'Analysis with VPR...'
|
||||
vpr(
|
||||
'analysis',
|
||||
VprArgs(
|
||||
ctx.share,
|
||||
ctx.takes.eblif,
|
||||
ctx.values,
|
||||
sdc_file=ctx.takes.sdc
|
||||
),
|
||||
cwd=build_dir
|
||||
)
|
||||
|
||||
if ctx.is_output_explicit('merged_post_implementation_v'):
|
||||
sh_mv(analysis_merged_post_implementation_file(ctx), ctx.outputs.merged_post_implementation_v)
|
||||
|
||||
if ctx.is_output_explicit('post_implementation_v'):
|
||||
sh_mv(analysis_post_implementation_file(ctx), ctx.outputs.post_implementation_v)
|
||||
|
||||
yield 'Saving log...'
|
||||
save_vpr_log('analysis.log', build_dir=build_dir)
|
||||
|
||||
def __init__(self, _):
|
||||
self.name = 'analysis'
|
||||
self.no_of_phases = 2
|
||||
self.takes = [
|
||||
'eblif',
|
||||
'route',
|
||||
'sdc?'
|
||||
]
|
||||
self.produces = [
|
||||
'merged_post_implementation_v',
|
||||
'post_implementation_v',
|
||||
'analysis_log'
|
||||
]
|
||||
self.values = [
|
||||
'device',
|
||||
'vpr_options?'
|
||||
] + vpr_specific_values()
|
||||
|
||||
ModuleClass = analysisModule
|
|
@ -18,6 +18,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from f4pga.common import *
|
||||
from f4pga.module import Module, ModuleContext
|
||||
|
||||
|
@ -97,23 +98,22 @@ class SynthModule(Module):
|
|||
return mapping
|
||||
|
||||
def execute(self, ctx: ModuleContext):
|
||||
split_inouts = os.path.join(ctx.share, 'scripts/split_inouts.py')
|
||||
synth_tcl = os.path.join(ctx.values.tcl_scripts, 'synth.tcl')
|
||||
conv_tcl = os.path.join(ctx.values.tcl_scripts, 'conv.tcl')
|
||||
|
||||
tcl_env = yosys_setup_tcl_env(ctx.values.yosys_tcl_env) \
|
||||
if ctx.values.yosys_tcl_env else {}
|
||||
split_inouts = Path(tcl_env["UTILS_PATH"]) / 'split_inouts.py'
|
||||
synth_tcl = Path(ctx.values.tcl_scripts) / 'synth.tcl'
|
||||
conv_tcl = Path(ctx.values.tcl_scripts) / 'conv.tcl'
|
||||
|
||||
if get_verbosity_level() >= 2:
|
||||
yield f'Synthesizing sources: {ctx.takes.sources}...'
|
||||
else:
|
||||
yield f'Synthesizing sources...'
|
||||
|
||||
yosys_synth(synth_tcl, tcl_env, ctx.takes.sources,
|
||||
yosys_synth(str(synth_tcl), tcl_env, ctx.takes.sources,
|
||||
ctx.values.read_verilog_args, ctx.outputs.synth_log)
|
||||
|
||||
yield f'Splitting in/outs...'
|
||||
sub('python3', split_inouts, '-i', ctx.outputs.json, '-o',
|
||||
sub('python3', str(split_inouts), '-i', ctx.outputs.json, '-o',
|
||||
ctx.outputs.synth_json)
|
||||
|
||||
if not os.path.isfile(ctx.produces.fasm_extra):
|
||||
|
@ -121,7 +121,7 @@ class SynthModule(Module):
|
|||
f.write('')
|
||||
|
||||
yield f'Converting...'
|
||||
yosys_conv(conv_tcl, tcl_env, ctx.outputs.synth_json)
|
||||
yosys_conv(str(conv_tcl), tcl_env, ctx.outputs.synth_json)
|
||||
|
||||
def __init__(self, params):
|
||||
self.name = 'synthesize'
|
||||
|
|
|
@ -2,18 +2,29 @@
|
|||
"stages": {
|
||||
"mk_build_dir": "common:mkdirs",
|
||||
"synth": "common:synth",
|
||||
"prepare_sdc": "common:generic_script_wrapper",
|
||||
"pack": "common:pack",
|
||||
"ioplace": "common:generic_script_wrapper",
|
||||
"place_constraints": "common:generic_script_wrapper",
|
||||
"iomux_jlink": "common:generic_script_wrapper",
|
||||
"iomux_openocd": "common:generic_script_wrapper",
|
||||
"iomux_binary": "common:generic_script_wrapper",
|
||||
"place": "common:place",
|
||||
"route": "common:route",
|
||||
"analysis": "common:analysis",
|
||||
"fasm": "common:fasm",
|
||||
"bitstream": "common:generic_script_wrapper"
|
||||
"bitstream": "common:generic_script_wrapper",
|
||||
"bitstream_bitheader": "common:generic_script_wrapper",
|
||||
"bitstream_binary": "common:generic_script_wrapper",
|
||||
"bitstream_jlink": "common:generic_script_wrapper",
|
||||
"bitstream_openocd": "common:generic_script_wrapper",
|
||||
"fasm2bels": "common:generic_script_wrapper"
|
||||
},
|
||||
|
||||
"values": {
|
||||
"device": "ql-eos-s3",
|
||||
"device_alt": "ql-eos-s3_wlcsp",
|
||||
"pinmap": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_PD64.csv",
|
||||
"pinmap": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"arch_def": "${shareDir}/arch/ql-eos-s3_wlcsp/arch.timing.xml",
|
||||
"rr_graph_lookahead_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.lookahead.bin",
|
||||
"rr_graph_real_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.rr_graph.real.bin",
|
||||
|
@ -52,7 +63,9 @@
|
|||
"synth": {
|
||||
"params": {
|
||||
"takes": [ "pcf?" ],
|
||||
"produces": [ "synth_v" ]
|
||||
"produces": [
|
||||
"synth_v"
|
||||
]
|
||||
},
|
||||
"values": {
|
||||
"tcl_scripts": "${shareDir}/scripts/pp3",
|
||||
|
@ -65,8 +78,67 @@
|
|||
"TECHMAP_PATH": "${shareDir}/techmaps/pp3",
|
||||
"DEVICE_CELLS_SIM": "${shareDir}/arch/ql-eos-s3_wlcsp/cells/ram_sim.v",
|
||||
"DEVICE_CELLS_MAP": "${shareDir}/arch/ql-eos-s3_wlcsp/cells/ram_map.v",
|
||||
"PINMAP_FILE": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_PD64.csv",
|
||||
"PCF_FILE": "${:pcf}"
|
||||
"PINMAP_FILE": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"PCF_FILE": "${:pcf}",
|
||||
"PYTHON3": "${python3}",
|
||||
"UTILS_PATH": "${shareDir}/scripts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"prepare_sdc": {
|
||||
"params": {
|
||||
"stage_name": "prepare_sdc",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${shareDir}/scripts/process_sdc_constraints.py",
|
||||
"outputs": {
|
||||
"sdc": {
|
||||
"mode": "file",
|
||||
"file": "${:eblif[noext]}.sdc",
|
||||
"target": "${:eblif[noext]}.sdc"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"eblif": "${:eblif}",
|
||||
"sdc-in": "${:sdc-in}",
|
||||
"sdc-out": "${:eblif[noext]}.sdc",
|
||||
"pcf": "${:pcf}",
|
||||
"pin-map": "",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pack": {
|
||||
"values": {
|
||||
"device": "ql-eos-s3",
|
||||
"device_alt": "ql-eos-s3_wlcsp",
|
||||
"pinmap": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"arch_def": "${shareDir}/arch/ql-eos-s3_wlcsp/arch.timing.xml",
|
||||
"rr_graph_lookahead_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.lookahead.bin",
|
||||
"rr_graph_real_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.rr_graph.real.bin",
|
||||
"vpr_place_delay": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.place_delay.bin",
|
||||
"vpr_grid_layout_name": "ql-eos-s3",
|
||||
"vpr_options": {
|
||||
"write_block_usage": "block_usage.json",
|
||||
"max_router_iterations": 500,
|
||||
"routing_failure_predictor": "off",
|
||||
"router_high_fanout_threshold": -1,
|
||||
"constant_net_method": "route",
|
||||
"route_chan_width": 100,
|
||||
"clock_modeling": "route",
|
||||
"place_delay_model": "delta_override",
|
||||
"router_lookahead": "extended_map",
|
||||
"check_route": "quick",
|
||||
"strict_checks": "off",
|
||||
"allow_dangling_combinational_nodes": "on",
|
||||
"disable_errors": "check_unbuffered_edges:check_route",
|
||||
"congested_routing_iteration_threshold": "0.8",
|
||||
"incremental_reroute_delay_ripup": "off",
|
||||
"base_cost_type": "delay_normalized_length_bounded",
|
||||
"bb_factor": "10",
|
||||
"initial_pres_fac": "4.0",
|
||||
"check_rr_graph": "off",
|
||||
"pack_high_fanout_threshold": "PB-lOGIC:18",
|
||||
"suppress_warnings": "${noisyWarnings},sum_pin_class:check_unbuffered_edges:load_rr_indexed_data_T_values:check_rr_node:trans_per_R:check_route:set_rr_graph_tool_comment "
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -74,7 +146,7 @@
|
|||
"params": {
|
||||
"stage_name": "ioplace",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${binDir}/python/ql_pp3_create_ioplace.py",
|
||||
"script": "${shareDir}/scripts/pp3_create_ioplace.py",
|
||||
"outputs": {
|
||||
"io_place": {
|
||||
"mode": "stdout",
|
||||
|
@ -85,8 +157,161 @@
|
|||
"blif": "${:eblif}",
|
||||
"net": "${:net}",
|
||||
"pcf": "${:pcf}",
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_PD64.csv",
|
||||
"$PYTHONPATH": "${binDir}/python/"
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"place_constraints": {
|
||||
"params": {
|
||||
"stage_name": "place_constraints",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${shareDir}/scripts/pp3_create_place_constraints.py",
|
||||
"outputs": {
|
||||
"place_constraints": {
|
||||
"mode": "stdout",
|
||||
"target": "${:eblif[noext]}_constraints.place"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"blif": "${:eblif}",
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/clkmap_${package}.csv",
|
||||
"i": "${:io_place}",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"iomux_jlink": {
|
||||
"params": {
|
||||
"stage_name": "iomux_jlink",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${shareDir}/scripts/pp3_eos_s3_iomux_config.py",
|
||||
"outputs": {
|
||||
"iomux_jlink": {
|
||||
"mode": "stdout",
|
||||
"target": "${:eblif[noext]}_iomux.jlink"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"eblif": "${:eblif}",
|
||||
"pcf": "${:pcf}",
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"output-format": "jlink",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"iomux_openocd": {
|
||||
"params": {
|
||||
"stage_name": "iomux_openocd",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${shareDir}/scripts/pp3_eos_s3_iomux_config.py",
|
||||
"outputs": {
|
||||
"iomux_openocd": {
|
||||
"mode": "stdout",
|
||||
"target": "${:eblif[noext]}_iomux.openocd"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"eblif": "${:eblif}",
|
||||
"pcf": "${:pcf}",
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"output-format": "openocd",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"iomux_binary": {
|
||||
"params": {
|
||||
"stage_name": "iomux_binary",
|
||||
"interpreter": "${python3}",
|
||||
"script": "${shareDir}/scripts/pp3_eos_s3_iomux_config.py",
|
||||
"outputs": {
|
||||
"iomux_binary": {
|
||||
"mode": "stdout",
|
||||
"target": "${:eblif[noext]}_iomux.bin"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"eblif": "${:eblif}",
|
||||
"pcf": "${:pcf}",
|
||||
"map": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"output-format": "binary",
|
||||
"$PYTHONPATH": "${shareDir}/scripts/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"route": {
|
||||
"values": {
|
||||
"device": "ql-eos-s3",
|
||||
"device_alt": "ql-eos-s3_wlcsp",
|
||||
"pinmap": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"arch_def": "${shareDir}/arch/ql-eos-s3_wlcsp/arch.timing.xml",
|
||||
"rr_graph_lookahead_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.lookahead.bin",
|
||||
"rr_graph_real_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.rr_graph.real.bin",
|
||||
"vpr_place_delay": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.place_delay.bin",
|
||||
"vpr_grid_layout_name": "ql-eos-s3",
|
||||
"vpr_options": {
|
||||
"write_timing_summary": "timing_summary.json",
|
||||
"max_router_iterations": 500,
|
||||
"routing_failure_predictor": "off",
|
||||
"router_high_fanout_threshold": -1,
|
||||
"constant_net_method": "route",
|
||||
"route_chan_width": 100,
|
||||
"clock_modeling": "route",
|
||||
"place_delay_model": "delta_override",
|
||||
"router_lookahead": "extended_map",
|
||||
"check_route": "quick",
|
||||
"strict_checks": "off",
|
||||
"allow_dangling_combinational_nodes": "on",
|
||||
"disable_errors": "check_unbuffered_edges:check_route",
|
||||
"congested_routing_iteration_threshold": "0.8",
|
||||
"incremental_reroute_delay_ripup": "off",
|
||||
"base_cost_type": "delay_normalized_length_bounded",
|
||||
"bb_factor": "10",
|
||||
"initial_pres_fac": "4.0",
|
||||
"check_rr_graph": "off",
|
||||
"pack_high_fanout_threshold": "PB-lOGIC:18",
|
||||
"suppress_warnings": "${noisyWarnings},sum_pin_class:check_unbuffered_edges:load_rr_indexed_data_T_values:check_rr_node:trans_per_R:check_route:set_rr_graph_tool_comment "
|
||||
}
|
||||
}
|
||||
},
|
||||
"analysis": {
|
||||
"values": {
|
||||
"device": "ql-eos-s3",
|
||||
"device_alt": "ql-eos-s3_wlcsp",
|
||||
"pinmap": "${shareDir}/arch/ql-eos-s3_wlcsp/pinmap_${package}.csv",
|
||||
"arch_def": "${shareDir}/arch/ql-eos-s3_wlcsp/arch.timing.xml",
|
||||
"rr_graph_lookahead_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.lookahead.bin",
|
||||
"rr_graph_real_bin": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.rr_graph.real.bin",
|
||||
"vpr_place_delay": "${shareDir}/arch/ql-eos-s3_wlcsp/rr_graph_ql-eos-s3_wlcsp.place_delay.bin",
|
||||
"vpr_grid_layout_name": "ql-eos-s3",
|
||||
"vpr_options": {
|
||||
"gen_post_synthesis_netlist": "on",
|
||||
"gen_post_implementation_merged_netlist": "on",
|
||||
"post_synth_netlist_unconn_inputs": "nets",
|
||||
"post_synth_netlist_unconn_outputs": "nets",
|
||||
"verify_file_digests": "off",
|
||||
"max_router_iterations": 500,
|
||||
"routing_failure_predictor": "off",
|
||||
"router_high_fanout_threshold": -1,
|
||||
"constant_net_method": "route",
|
||||
"route_chan_width": 100,
|
||||
"clock_modeling": "route",
|
||||
"place_delay_model": "delta_override",
|
||||
"router_lookahead": "extended_map",
|
||||
"check_route": "quick",
|
||||
"strict_checks": "off",
|
||||
"allow_dangling_combinational_nodes": "on",
|
||||
"disable_errors": "check_unbuffered_edges:check_route",
|
||||
"congested_routing_iteration_threshold": "0.8",
|
||||
"incremental_reroute_delay_ripup": "off",
|
||||
"base_cost_type": "delay_normalized_length_bounded",
|
||||
"bb_factor": "10",
|
||||
"initial_pres_fac": "4.0",
|
||||
"check_rr_graph": "off",
|
||||
"pack_high_fanout_threshold": "PB-lOGIC:18",
|
||||
"suppress_warnings": "${noisyWarnings},sum_pin_class:check_unbuffered_edges:load_rr_indexed_data_T_values:check_rr_node:trans_per_R:check_route:set_rr_graph_tool_comment "
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -97,24 +322,152 @@
|
|||
"outputs": {
|
||||
"bitstream": {
|
||||
"mode": "file",
|
||||
"file": "bitstream-${device}.bit",
|
||||
"target": "${build_dir?}/bitstream-${device}.bit"
|
||||
"file": "${:eblif[noext]}.bit",
|
||||
"target": "${:eblif[noext]}.bit"
|
||||
},
|
||||
"bitstream_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${build_dir?}/bitstream-${device}.log"
|
||||
"target": "${:eblif[noext]}.bit.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"#1": "${:fasm}",
|
||||
"#2": "bitstream-${device}.bit",
|
||||
"dev-type": "ql-eos-s3",
|
||||
"db-root": "${shareDir}/fasm_database/pp3"
|
||||
"#2": "${:eblif[noext]}.bit",
|
||||
"dev-type": "ql-eos-s3"
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"build_dir?": "."
|
||||
"build_dir": "."
|
||||
}
|
||||
},
|
||||
"bitstream_bitheader": {
|
||||
"params": {
|
||||
"stage_name": "bitstream_bitheader",
|
||||
"script": "symbiflow_write_bitheader",
|
||||
"outputs": {
|
||||
"bitstream_bitheader": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.h",
|
||||
"target": "${:bitstream}.h"
|
||||
},
|
||||
"bitstream_bitheader_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${:bitstream}.h.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"#1": "${:bitstream}",
|
||||
"#2": "${:bitstream}.h",
|
||||
"#3": "${:iomux_binary}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bitstream_jlink": {
|
||||
"params": {
|
||||
"stage_name": "bitstream_jlink",
|
||||
"script": "symbiflow_write_jlink",
|
||||
"outputs": {
|
||||
"bitstream_jlink": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.jlink",
|
||||
"target": "${:bitstream}.jlink"
|
||||
},
|
||||
"bitstream_jlink_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${:bitstream}.jlink.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"#1": "${:bitstream}",
|
||||
"#2": "${:bitstream}.jlink",
|
||||
"#3": "${:iomux_jlink}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bitstream_openocd": {
|
||||
"params": {
|
||||
"stage_name": "bitstream_openocd",
|
||||
"script": "symbiflow_write_openocd",
|
||||
"outputs": {
|
||||
"bitstream_openocd": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.openocd",
|
||||
"target": "${:bitstream}.openocd"
|
||||
},
|
||||
"bitstream_openocd_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${:bitstream}.openocd.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"#1": "${:bitstream}",
|
||||
"#2": "${:bitstream}.openocd",
|
||||
"#3": "${:iomux_openocd}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bitstream_binary": {
|
||||
"params": {
|
||||
"stage_name": "bitstream_binary",
|
||||
"script": "symbiflow_write_binary",
|
||||
"outputs": {
|
||||
"bitstream_binary": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.bin",
|
||||
"target": "${:bitstream}.bin"
|
||||
},
|
||||
"bitstream_binary_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${:bitstream}.bin.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"#1": "${:bitstream}",
|
||||
"#2": "${:bitstream}.bin",
|
||||
"#3": "${:iomux_binary}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fasm2bels": {
|
||||
"params": {
|
||||
"stage_name": "fasm2bels",
|
||||
"script": "symbiflow_fasm2bels",
|
||||
"outputs": {
|
||||
"fasm2bels_verilog": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.v",
|
||||
"target": "${:bitstream}.v"
|
||||
},
|
||||
"fasm2bels_pcf": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.pcf",
|
||||
"target": "${:bitstream}.pcf"
|
||||
},
|
||||
"fasm2bels_qcf": {
|
||||
"mode": "file",
|
||||
"file": "${:bitstream}.qcf",
|
||||
"target": "${:bitstream}.qcf"
|
||||
},
|
||||
"fasm2bels_log": {
|
||||
"mode": "stdout",
|
||||
"target": "${:bitstream}.log"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"device": "${device}",
|
||||
"part": "${package}",
|
||||
"pcf": "${:pcf}",
|
||||
"bit": "${:bitstream}",
|
||||
"out-verilog": "${:bitstream}.v",
|
||||
"out-pcf": "${:bitstream}.pcf",
|
||||
"out-qcf": "${:bitstream}.qcf",
|
||||
"$F4PGA_INSTALL_DIR": "${shareDir}/../../../../",
|
||||
"$FPGA_FAM": "eos-s3",
|
||||
"$PATH": "${shareDir}/../../../conda/envs/eos-s3/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"$SHARE_DIR_PATH": "${shareDir}",
|
||||
"$BIN_DIR_PATH": "${binDir}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,10 @@ wrapper_entrypoints = [
|
|||
f"{sf}_generate_constraints = {shwrappers}:generate_constraints",
|
||||
f"{sf}_analysis = {shwrappers}:analysis",
|
||||
f"{sf}_fasm2bels = {shwrappers}:fasm2bels",
|
||||
f"{sf}_write_binary = {shwrappers}:write_binary",
|
||||
f"{sf}_write_bitheader = {shwrappers}:write_bitheader",
|
||||
f"{sf}_write_jlink = {shwrappers}:write_jlink",
|
||||
f"{sf}_write_openocd = {shwrappers}:write_openocd",
|
||||
f"ql_{sf} = {shwrappers}:ql",
|
||||
f"vpr_common = {shwrappers}:vpr_common",
|
||||
]
|
||||
|
|
|
@ -120,3 +120,19 @@ def ql():
|
|||
def fasm2bels():
|
||||
print("[F4PGA] Running (deprecated) fasm2bels")
|
||||
run_sh(ROOT / "quicklogic/fasm2bels.f4pga.sh")
|
||||
|
||||
def write_bitheader():
|
||||
print("[F4PGA] Running (deprecated) write bitheader")
|
||||
run_sh(ROOT / "quicklogic/write_bitheader.f4pga.sh")
|
||||
|
||||
def write_binary():
|
||||
print("[F4PGA] Running (deprecated) write binary")
|
||||
run_sh(ROOT / "quicklogic/write_binary.f4pga.sh")
|
||||
|
||||
def write_jlink():
|
||||
print("[F4PGA] Running (deprecated) write jlink")
|
||||
run_sh(ROOT / "quicklogic/write_jlink.f4pga.sh")
|
||||
|
||||
def write_openocd():
|
||||
print("[F4PGA] Running (deprecated) write openocd")
|
||||
run_sh(ROOT / "quicklogic/write_openocd.f4pga.sh")
|
||||
|
|
|
@ -21,8 +21,8 @@ set -e
|
|||
SHARE_DIR_PATH=${SHARE_DIR_PATH:="$F4PGA_SHARE_DIR"}
|
||||
BIN_DIR_PATH=${BIN_DIR_PATH:="$F4PGA_BIN_DIR"}
|
||||
|
||||
OPTS=d:P:p:b:
|
||||
LONGOPTS=device:,part:,pcf:,bit:,
|
||||
OPTS=d:P:p:b:v:o:q
|
||||
LONGOPTS=device:,part:,pcf:,bit:,out-verilog:,out-pcf:,out-qcf:,
|
||||
|
||||
PARSED_OPTS=`getopt --options=${OPTS} --longoptions=${LONGOPTS} --name $0 -- "$@"`
|
||||
eval set -- "${PARSED_OPTS}"
|
||||
|
@ -31,6 +31,9 @@ DEVICE=""
|
|||
PART=""
|
||||
PCF=""
|
||||
BIT=""
|
||||
OUT_VERILOG=""
|
||||
OUT_PCF=""
|
||||
OUT_QCF=""
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
|
@ -50,6 +53,18 @@ while true; do
|
|||
BIT=$2
|
||||
shift 2
|
||||
;;
|
||||
-v|--out-verilog)
|
||||
OUT_VERILOG=$2
|
||||
shift 2
|
||||
;;
|
||||
-o|--out-pcf)
|
||||
OUT_PCF=$2
|
||||
shift 2
|
||||
;;
|
||||
-q|--out-qcf)
|
||||
OUT_QCF=$2
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
break
|
||||
;;
|
||||
|
@ -67,27 +82,26 @@ if [ -z $BIT ]; then
|
|||
fi
|
||||
|
||||
|
||||
# Run fasm2bels
|
||||
if [[ "$DEVICE" =~ ^(ql-eos-s3|ql-pp3e)$ ]]; then
|
||||
|
||||
VPR_DB=`readlink -f ${SHARE_DIR_PATH}/arch/${DEVICE}_wlcsp/db_phy.pickle`
|
||||
FASM2BELS=`readlink -f ${SHARE_DIR_PATH}/scripts/fasm2bels.py`
|
||||
FASM2BELS_DEVICE=${DEVICE/ql-/}
|
||||
VERILOG_FILE="${BIT}.v"
|
||||
PCF_FILE="${BIT}.v.pcf"
|
||||
QCF_FILE="${BIT}.v.qcf"
|
||||
|
||||
if [ ! -z "{PCF}" ]; then
|
||||
PCF_ARGS="--input-pcf ${PCF}"
|
||||
else
|
||||
PCF_ARGS=""
|
||||
fi
|
||||
|
||||
echo "Running fasm2bels"
|
||||
`which python3` ${FASM2BELS} ${BIT} --phy-db ${VPR_DB} --device-name ${FASM2BELS_DEVICE} --package-name ${PART} --input-type bitstream --output-verilog ${VERILOG_FILE} ${PCF_ARGS} --output-pcf ${PCF_FILE} --output-qcf ${QCF_FILE}
|
||||
|
||||
else
|
||||
|
||||
# $DEVICE is not ql-eos-s3 or ql-pp3e
|
||||
if ! [[ "$DEVICE" =~ ^(ql-eos-s3|ql-pp3e)$ ]]; then
|
||||
echo "ERROR: Unsupported device '${DEVICE}' for fasm2bels"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
# Run fasm2bels
|
||||
VPR_DB=`readlink -f ${SHARE_DIR_PATH}/arch/${DEVICE}_wlcsp/db_phy.pickle`
|
||||
FASM2BELS=`readlink -f ${SHARE_DIR_PATH}/scripts/fasm2bels.py`
|
||||
FASM2BELS_DEVICE=${DEVICE/ql-/}
|
||||
|
||||
VERILOG_FILE="${OUT_VERILOG:-$BIT.v}"
|
||||
PCF_FILE="${OUT_PCF:-$BIT.v.pcf}"
|
||||
QCF_FILE="${OUT_QCF:-$BIT.v.qcf}"
|
||||
|
||||
if [ ! -z "{PCF}" ]; then
|
||||
PCF_ARGS="--input-pcf ${PCF}"
|
||||
else
|
||||
PCF_ARGS=""
|
||||
fi
|
||||
|
||||
echo "Running fasm2bels"
|
||||
`which python3` ${FASM2BELS} ${BIT} --phy-db ${VPR_DB} --device-name ${FASM2BELS_DEVICE} --package-name ${PART} --input-type bitstream --output-verilog ${VERILOG_FILE} ${PCF_ARGS} --output-pcf ${PCF_FILE} --output-qcf ${QCF_FILE}
|
||||
|
|
|
@ -18,7 +18,5 @@
|
|||
|
||||
set -e
|
||||
|
||||
source $(dirname "$(readlink -f "$BASH_SOURCE")")/env
|
||||
|
||||
echo "Converting bitstream to flashable binary format"
|
||||
`which python3` -m quicklogic_fasm.bitstream_to_binary $@
|
||||
|
|
|
@ -18,7 +18,5 @@
|
|||
|
||||
set -e
|
||||
|
||||
source $(dirname "$(readlink -f "$BASH_SOURCE")")/env
|
||||
|
||||
echo "Converting bitstream to C Header"
|
||||
`which python3` -m quicklogic_fasm.bitstream_to_header $@
|
||||
|
|
|
@ -18,7 +18,5 @@
|
|||
|
||||
set -e
|
||||
|
||||
source $(dirname "$(readlink -f "$BASH_SOURCE")")/env
|
||||
|
||||
echo "Converting bitstream to JLink script"
|
||||
`which python3` -m quicklogic_fasm.bitstream_to_jlink $@
|
||||
|
|
|
@ -18,7 +18,5 @@
|
|||
|
||||
set -e
|
||||
|
||||
source $(dirname "$(readlink -f "$BASH_SOURCE")")/env
|
||||
|
||||
echo "Converting bitstream to OpenOCD script"
|
||||
`which python3` -m quicklogic_fasm.bitstream_to_openocd $@
|
||||
|
|
Loading…
Reference in New Issue