Merge remote-tracking branch 'origin/ganesh_dev' into dev

This commit is contained in:
Ganesh Gore 2019-09-02 00:19:19 -06:00
commit e37ac1a565
10 changed files with 486 additions and 40 deletions

View File

@ -1,11 +1,16 @@
language: cpp language: cpp
# cache results # cache results
cache: cache:
directories: directories:
- $TRAVIS_BUILD_DIR/abc
- $TRAVIS_BUILD_DIR/yosys
- $TRAVIS_BUILD_DIR/ace2
- $TRAVIS_BUILD_DIR/libs
- $HOME/.ccache - $HOME/.ccache
# Currently sudo is not required, NO ENV is used # Currently sudo is not required, NO ENV is used
# Supported Operating systems # Supported Operating systems
#os: #os:
@ -13,9 +18,6 @@ cache:
# - osx # - osx
# Create a matrix to branch the building environment # Create a matrix to branch the building environment
matrix: matrix:
allow_failures:
- os: osx
#dist: trusty
include: include:
- os: linux - os: linux
# Compiler is specified in ./travis/common.sh # Compiler is specified in ./travis/common.sh

View File

@ -15,6 +15,7 @@ export -f travis_time_start
export -f travis_time_finish export -f travis_time_finish
function start_section() { function start_section() {
$SPACER
travis_fold start "$1" travis_fold start "$1"
travis_time_start travis_time_start
echo -e "${PURPLE}OpenFPGA${NC}: - $2${NC}" echo -e "${PURPLE}OpenFPGA${NC}: - $2${NC}"
@ -25,6 +26,7 @@ function end_section() {
echo -e "${GRAY}-------------------------------------------------------------------${NC}" echo -e "${GRAY}-------------------------------------------------------------------${NC}"
travis_time_finish travis_time_finish
travis_fold end "$1" travis_fold end "$1"
$SPACER
} }
# For Mac OS, we use g++ and gcc as default compilers # For Mac OS, we use g++ and gcc as default compilers
@ -35,7 +37,7 @@ if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
# export PATH="/usr/local/opt/qt/bin:$PATH" # export PATH="/usr/local/opt/qt/bin:$PATH"
# Install header files in Mojave, if not gcc-4.9 cannot spot stdio.h # Install header files in Mojave, if not gcc-4.9 cannot spot stdio.h
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target / sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
else else
# For linux, we use g++-8 and gcc-8 as default compilers # For linux, we use g++-8 and gcc-8 as default compilers
export CC=gcc-8 export CC=gcc-8
export CXX=g++-8 export CXX=g++-8

View File

@ -3,30 +3,20 @@
source .travis/common.sh source .travis/common.sh
set -e set -e
$SPACER
start_section "OpenFPGA.build" "${GREEN}Building..${NC}" start_section "OpenFPGA.build" "${GREEN}Building..${NC}"
mkdir build
cd build
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
#make
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=debug -DENABLE_VPR_GRAPHICS=off cmake .. -DCMAKE_BUILD_TYPE=debug -DENABLE_VPR_GRAPHICS=off
make -j16
alias python3.5="python3"
ln -s /opt/local/bin/python3 /opt/local/bin/python3.5
else else
# For linux, we enable full package compilation
#make
mkdir build
cd build
cmake --version
cmake .. -DCMAKE_BUILD_TYPE=debug cmake .. -DCMAKE_BUILD_TYPE=debug
make -j16
fi fi
make -j16
end_section "OpenFPGA.build" end_section "OpenFPGA.build"
$SPACER
start_section "OpenFPGA.TaskTun" "${GREEN}..Running_Regression..${NC}"
cd - cd -
# python3.5 ./openfpga_flow/scripts/run_fpga_task.py regression/regression_quick python3 openfpga_flow/scripts/run_fpga_task.py blif_vpr_flow --exit_on_fail
python3.5 openfpga_flow/scripts/run_fpga_task.py blif_vpr_flow --maxthreads 4 end_section "OpenFPGA.TaskTun"

View File

@ -7,7 +7,7 @@ SPHINXBUILD = sphinx-build
SOURCEDIR = source SOURCEDIR = source
BUILDDIR = build BUILDDIR = build
PAPER = PAPER =
PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter PAPEROPT_letter = -D latex_paper_size=letter
ALL_SPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR) ALL_SPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR)
@ -16,7 +16,10 @@ ALL_SPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SO
help: help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
clean: livehtml:
sphinx-autobuild -b html $(ALL_SPHINXOPTS) $(BUILDDIR)/html
clean:
rm -rf $(BUILDDIR)/* rm -rf $(BUILDDIR)/*
.PHONY: help clean Makefile .PHONY: help clean Makefile
@ -27,4 +30,4 @@ clean:
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
#html: #html:
# $(SPHINXBUILD) -b html $@ "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) # $(SPHINXBUILD) -b html $@ "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS)

View File

@ -12,10 +12,15 @@ Welcome to OpenFPGA's documentation!
motivation motivation
.. toctree:: .. toctree::
:caption: Getting Started :caption: Getting Started
eda_flow eda_flow
run_fpga_flow
run_fpga_task
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: Tools Guide :caption: Tools Guide
@ -37,10 +42,10 @@ Welcome to OpenFPGA's documentation!
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: Appendix :caption: Appendix
contact contact
reference reference
For more information on the VTR see vtr_doc_ or vtr_github_ For more information on the VTR see vtr_doc_ or vtr_github_
For more information on the Yosys see yosys_doc_ or yosys_github_ For more information on the Yosys see yosys_doc_ or yosys_github_

183
docs/source/run_fpga_flow.rst Executable file
View File

@ -0,0 +1,183 @@
.. _run_fpga_flow:
OpenFPGA Flow
---------------
This python script executes the supported OpenFPGA flow for a
single benchmark and architecture file for given script parameters.
The script is located at::
${OPENFPGA_PATH}/openfpga_flow/scripts/run_fpga_flow.py
.. program:: run_fpga_flow.py
Basic Usage
~~~~~~~~~~~
At a minimum ``open_fpga_flow.py`` requires following command-line arguments::
open_fpga_flow.py <architecture_file> <benchmark_files> --top_module <top_module_name>
where:
* ``<architecture_file>`` is the target :ref:`FPGA architecture <fpga_architecture_description>`
* ``<circuit_file>`` The list of files in the benchmark (Supports ../directory/\*.v)
* ``<top_module_name>`` The name of the top level module in Verilog project
.. note::
The script will create a ``tmp`` run directory in base OpenFPGA path, unless otherwise specified with the :option:`--run_dir` option.
All stages of the flow will be run within run directory.
Several intermediate files will be generated and maintian in run directory.
The path variables declared in architecture XML file will be resolved with absolute path and copied to the ``tmp/arch`` directory before executing flow.
All the benchmark files provided will be copied to ``tmp/bench`` directory without maintaining any directory structure.
**Users should ensure that no important files are kept in this directory as script will clear directory before each execution**
.. _openfpga-variables:
OpenFPGA Variables
~~~~~~~~~~~~~~~~~~
Frequently, while running OpenFPGA flow User is suppose to refer external files.
To avoid long names and referencing errors user can use
following openfpga variables.
These variables are resolved with absolute path while execution making
each run independent of launch directory.
* ``<OPENFPGA_PATH>`` Path to the base OpenFPGA directory
* ``<OPENFPGA_FLOW_PATH>`` Path to the run_fpga_flow script directory
* ``<SPICENETLIST_PATH>`` Path where spice netlists are saved
* ``<VERILOG_PATH>`` Path where Verilog modules are saved
* ``<TECH_PATH>`` Path where all characterized XML files are stored
For example in architecture file path vairable can be used as follows::
.... lib_path="${TECH_PATH}/PTM_45nm/45nm.pm" ....
Output
~~~~~~
Based on which flow is executed, resulting in intermediate files are generated in run_directory
The output log of the script provides the status of each stage to the user.
If any stage failed to execute, the output log would indicate the stage at which execution failed, and execution traceback.
In case of successful execution, The OpenFPGA flow script will parse
parameters listed in configuration from different result files and will create
``vpr_stat.txt``, ``vpr_stat_power.txt`` \(optional\) file in run_directory.
Advanced Usage
~~~~~~~~~~~~~~
User can pass additional *optional* command arguments to ``run_fpga_flow.py`` script::
run_fpga_flow.py <architecture_file> <benchmark_files> [<options>] [<vpr_options>] [<fpga-verilog_options>] [<fpga-spice_options>] [<fpga-bitstream_options>] [<ace_options>]
where:
* ``<options>`` are additional arguments passed to ``run_fpga_flow.py`` (described below),
* ``<vpr_options>`` Any argument prefixed with ``--vpr-*`` will be forwarded to vpr script as it is. The detail of supported vpr argument is available ``Add corrrect reference``
* ``<fpga-verilog_options>`` are any arguments not recognized by ``run_vtr_flow.pl``. These will be forwarded to VPR.
* ``<ace_options>`` these arguments will be passed to ACE activity estimator program
For example::
run_fpga_flow.py my_circuit.v my_arch.xml -track_memory_usage --pack --place
will run the VTR flow to map the circuit ``my_circuit.v`` onto the architecture ``my_arch.xml``; the arguments ``--pack`` and ``--place`` will be passed to VPR (since they are unrecognized arguments to ``run_vtr_flow.pl``).
They will cause VPR to perform only :ref:`packing and placement <general_options>`.
Detailed Command-line Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. Note:: All the commnadline arguments starting with ``vpr_*`` , ``fpga-verilog_*`` , ``fpga-spice_*`` or ``fpga-bitstream_*`` will be passed to VPR without suffix
General Arguments
^^^^^^^^^^^^^^^^^
.. option:: --top_module <name>
Provide top module name of the benchmark. Default ``top``
.. option:: --run_dir <directory_path>
Using this option user can provide a custom path as a run directory. Default is ``tmp`` directory in OpenFPGA root path.
.. option:: --K <lut_inputs>
This option defines the number of inputs to the LUT. By default, the script parses provided architecture file and finds out inputs to the biggest LUT.
.. option:: --yosys_tmpl <yosys_template_file>
This option allows the user to provide a custom Yosys template
While running a yosys_vpr flow. Default template is stored in a directory ``open_fpga_flow\misc\ys_tmpl_yosys_vpr_flow.ys``. Yosys template script supports ``TOP_MODULE`` ``READ_VERILOG_FILE`` ``LUT_SIZE`` & ``OUTPUT_BLIF`` variables, which can be used as ``${var_name}``. Alternately, user can create a copy and modify according to their need.
.. option:: --debug
To enable detail logs printing.
.. option:: --flow_config
User can provide option flow configuration file to override some of the default script parameters.
for detail information refer :ref:`OpenFPGA Flow Configuration <OpenFPGA_Conf_File>`
ACE Arguments
^^^^^^^^^^^^^
.. option:: --black_box_ace
Performs ACE simulation on the black box [deprecated]
VPR RUN Arguments
^^^^^^^^^^^^^^^^^
.. option:: --fix_route_chan_width <channel_number>
Performs VPR implementation for a fixed number of channels defined as the 'channel_number'
.. option:: --min_route_chan_width <percentage_slack>
Performs VPR implementation to get minimum channel width and then perform fixed channel rerouting with ``percentage_slack`` increase in the channel width.
.. option:: --max_route_width_retry <max_retry_count>
Number of times the channel width should be increased and attempt VPR implementation, while performing ``min_route_chan_width``
.. option:: --power
.. option:: --power_tech
blif_vpr_flow Arguments
^^^^^^^^^^^^^^^^^^^^^^^^
.. option:: --activity_file
Activity to be used for the given benchmark while running ``blif_vpr_flow``
.. option:: --base_verilog
Verilog benchmark file to perform verification while running ``bliff_vpr_flow``
.. _OpenFPGA_Conf_File:
OpenFPGA Flow Configuration file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The OpenFPGA Flow configuration file consists of following sections
* ``CAD_TOOLS_PATH``
Lists executable file path for different CAD tools used in the script
* ``FLOW_SCRIPT_CONFIG``
Lists the supported flows by the script.
* ``DEFAULT_PARSE_RESULT_VPR``
List of default parameters to be parsed from Place, Pack, and Route output
* ``DEFAULT_PARSE_RESULT_POWER``
List of default parameters to be parsed from VPR power analysis output
* ``INTERMIDIATE_FILE_PREFIX``
[Not implemented yet]
Default OpenFPGA_flow Configuration file is located in ``open_fpga_flow\misc\fpgaflow_default_tool_path.conf``.
User-supplied configuration file overrides or extends the default configuration.

View File

@ -0,0 +1,213 @@
.. _run_fpga_task:
OpenFPGA Task
---------------
Tasks provide a framework for running the :ref:`run_fpga_flow` on
multiple benchmarks, architectures and set of OpenFPGA parameters.
The structure of the framework is very similar to
`VTR-Tasks <https://docs.verilogtorouting.org/en/latest/vtr/tasks/>`_
implementation with additional functionality and minor file extention changes.
Task Directory
~~~~~~~~~~~~~~
The tasks are store in a ``TASK_DIRECTORY``, which by default points to
``${OPENFPGA_PATH}/openfpga_flow/tasks``. Every directory or sub-directory in
task directory consisting of ``../config/task.conf`` file can be reffered as a
task.
To create as task name called ``basic_flow`` following directory has to exist::
${TASK_DIRECTORY}/basic_flow/conf/task.conf
Similarly ``regression/regression_quick`` expect following structure::
${TASK_DIRECTORY}/regression/regression_quick/conf/task.conf
Running OpenFPGA Task:
~~~~~~~~~~~~~~~~~~~~~~
At a minimum ``open_fpga_flow.py`` requires following command-line arguments::
open_fpga_flow.py <task1_name> <task2_name> ...
where:
* ``<task_name>`` is the name of the task to run
Craeating A New OpenFPGA Task:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create the folder ``${TASK_DIRECTORY}/<task_name>`` and create a file called
``${TASK_DIRECTORY}/<task_name>/config/task.conf`` in it.
Configuring a New Task
~~~~~~~~~~~~~~~~~~~~~~
The task configuration file ``task.conf`` consists of ``GENERAL``,
``ARCHITECTURES``, ``BENCHMARKS``, ``SYNTHESIS_PARAM`` and
``SCRIPT_PARAM_<var_name>`` sections.
Declaring all the above sections are mandatory.
.. note::
Configuration file supports all the OpenFPGA Variables refer
:ref:`openfpga-variables` section to know more. Variables in configuration
file is declares as ``${PATH:<variable_name>}``
General Section
^^^^^^^^^^^^^^^
.. option:: fpga_flow==<yosys_vpr|vpr_blif>
Defines which OpenFPGA flow to run. By default ``yosys_vpr`` is executed.
.. option:: power_analysis=<true|false>
Specifies whether to perform power analysis or not.
.. option:: power_tech_file=<path_to_tech_XML_file>
Declares which tech XML file to be used while perforing Power Analysis.
.. option:: spice_output=<true|false>
Setting up this variable generates Spice Netlist at the end of the flow.
Equivalent of passing ``--vpr_fpga_spice`` command to :ref:`run_fpga_flow`
.. option:: verilog_output=<true|false>
Setting up this variable generates Verilog Netlist at the end of the flow.
Equivalent of passing ``--vpr_fpga_spice`` command to :ref:`run_fpga_flow`
.. option:: timeout_each_job=<true|false>
Specifies the the timeout for each :ref:`run_fpga_flow` execution. Default
is set to ``20 min``
Architectures Sections
^^^^^^^^^^^^^^^^^^^^^^
User can define the list of architecure files in this section.
.. option:: arch<arch_label>=<xml_architecture_file_path>
The ``arch_label`` variable can be any number of string without
white-spaces. ``xml_architecture_file_path`` is path to the actual XML
architecture file
.. note::
In final OpenFPGA Task result the architecture will be referred by its
``arch_label``.
Benchmarks Sections
^^^^^^^^^^^^^^^^^^^
User can define the list of benchmarks files in this section.
.. option:: bench<bench_label>=<list_of_files_in_benchmark>
The ``bench_label`` variable can be any number of string without
white-spaces. ``xml_architecture_file_path`` is path to the actual XML
architecture file
For Example following code shows how to define a benchmarks,
with single file multiple files and files added from specific directory.
.. code-block:: text
[BENCHMARKS]
# To declare single benchmark file
bench_design1=${BENCH_PATH}/design/top.v
# To declare multiple benchmark file
bench_design2=${BENCH_PATH}/design/top.v,${BENCH_PATH}/design/sub_module.v
# To add all files in specific directory to the benchmark
bench_design3=${BENCH_PATH}/design/top.v,${BENCH_PATH}/design/lib/*.v
.. note::
``bench_label`` is referred again in ``Synthesis_Param`` section to
provide addional information about benchmark
Synthesis Parameter Sections
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
User can define extra parameters for each benchmark defined in the
``BENCHMARKS`` sections.
.. option:: bench<bench_label>_top=<Top_Module_Name>
This defines the Top Level module name for ``bench_label`` benchmark.
By default, the top level module name is cosidereed as a ``top``.
.. option:: bench<bench_label>_yosys_tmpl=<yosys_template_file>
[TODO]
.. option:: bench<bench_label>_chan_width=<chan_width_to_use>
In case of running fixed channel width routing for each benchmark,
this option defines the channel width to be used for ``bench_label``
benchmark
.. option:: bench<bench_label>_act=<activity_file_path>
In case of running ``blif_vpr_flow`` this option provides the activity files
to be used to generate testbench for ``bench_label`` benchmark
.. option:: bench<bench_label>_verilog=<source_verilog_file_path>
In case of running ``blif_vpr_flow`` with verification this option provides
the source verilog design for ``bench_label`` benchmark to be used
while verification.
Script Parameter Sections
^^^^^^^^^^^^^^^^^^^^^^^^^
The script parameter section lists set of commnad line pararmeters to be passed to :ref:`run_fpga_flow` script. The section name is defines as ``SCRIPT_PARAM_<parameter_set_label>`` where `parameter_set_label` can be any word without white spaces.
The section is referred with ``parameter_set_label`` in final result file.
For example following code Specifies the two sets (``Fixed_Routing_30`` and ``Fixed_Routing_50``) of :ref:`run_fpga_flow` arguments.
.. code-block:: text
[SCRIPT_PARAM_Fixed_Routing_30]
# Execute fixed routing with channel with 30
fix_route_chan_width=30
[SCRIPT_PARAM_Fixed_Routing_50]
# Execute fixed routing with channel with 50
fix_route_chan_width=50
Example Task Configuration File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: text
[GENERAL]
spice_output=false
verilog_output=false
power_analysis = true
power_tech_file = ${PATH:TECH_PATH}/winbond90nm/winbond90nm_power_properties.xml
timeout_each_job = 20*60
[ARCHITECTURES]
arch0=${PATH:ARCH_PATH}/winbond90/k6_N10_rram_memory_bank_SC_winbond90.xml
[BENCHMARKS]
bench0=${PATH:BENCH_PATH}/MCNC_Verilog/s298/s298.v
bench1=${PATH:BENCH_PATH}/MCNC_Verilog/elliptic/elliptic.v
[SYNTHESIS_PARAM]
bench0_top = s298
bench1_top = elliptic
[SCRIPT_PARAM_Slack_30]
min_route_chan_width=1.3
[SCRIPT_PARAM_Slack_80]
min_route_chan_width=1.8

View File

@ -1,3 +1,12 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Script Name : run_fpga_flow.py
# Description : This script designed to run different flows supported by
# OpensFPGA project.
# Args : python3 run_fpga_flow.py --help
# Author : Ganesh Gore
# Email : ganeshgore@utah.edu
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
import os import os
import sys import sys
import shutil import shutil
@ -18,6 +27,9 @@ from importlib import util
if util.find_spec("humanize"): if util.find_spec("humanize"):
import humanize import humanize
if sys.version_info[0] < 3:
raise Exception("run_fpga_task script must be using Python 3")
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Initialise general paths for the script # Initialise general paths for the script
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ -31,9 +43,16 @@ openfpga_base_dir = os.path.abspath(
launch_dir = os.getcwd() launch_dir = os.getcwd()
# Path section to append in configuration file to interpolate path # Path section to append in configuration file to interpolate path
script_env_vars = {"PATH": { task_script_dir = os.path.dirname(os.path.abspath(__file__))
"OPENFPGA_FLOW_PATH": flow_script_dir, script_env_vars = ({"PATH": {
"OPENFPGA_PATH": openfpga_base_dir}} "OPENFPGA_FLOW_PATH": task_script_dir,
"ARCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "arch"),
"BENCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "benchmarks"),
"TECH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "tech"),
"SPICENETLIST_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "SpiceNetlists"),
"VERILOG_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "VerilogNetlists"),
"OPENFPGA_PATH": os.path.abspath(os.path.join(task_script_dir, os.pardir,
os.pardir))}})
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Reading command-line argument # Reading command-line argument
@ -54,7 +73,7 @@ parser.add_argument('benchmark_files', type=str, nargs='+')
# Optional arguments # Optional arguments
parser.add_argument('--top_module', type=str, default="top") parser.add_argument('--top_module', type=str, default="top")
parser.add_argument('--fpga_flow', type=str, default="yosys_vpr") parser.add_argument('--fpga_flow', type=str, default="yosys_vpr")
parser.add_argument('--cad_tool_conf', type=str, parser.add_argument('--flow_config', type=str,
help="CAD tools path overrides default setting") help="CAD tools path overrides default setting")
parser.add_argument('--run_dir', type=str, parser.add_argument('--run_dir', type=str,
default=os.path.join(openfpga_base_dir, 'tmp'), default=os.path.join(openfpga_base_dir, 'tmp'),
@ -269,8 +288,8 @@ def read_script_config():
default_cad_tool_conf = os.path.join(flow_script_dir, os.pardir, 'misc', default_cad_tool_conf = os.path.join(flow_script_dir, os.pardir, 'misc',
'fpgaflow_default_tool_path.conf') 'fpgaflow_default_tool_path.conf')
config.read_file(open(default_cad_tool_conf)) config.read_file(open(default_cad_tool_conf))
if args.cad_tool_conf: if args.flow_config:
config.read_file(open(args.cad_tool_conf)) config.read_file(open(args.flow_config))
if not "CAD_TOOLS_PATH" in config.sections(): if not "CAD_TOOLS_PATH" in config.sections():
clean_up_and_exit("Missing CAD_TOOLS_PATH in openfpga_flow config") clean_up_and_exit("Missing CAD_TOOLS_PATH in openfpga_flow config")
cad_tools = config["CAD_TOOLS_PATH"] cad_tools = config["CAD_TOOLS_PATH"]

View File

@ -1,5 +1,5 @@
[GENERAL CONFIGURATION] [GENERAL CONFIGURATION]
task_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks task_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks
misc_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/misc misc_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/misc
python_path=python3.5 python_path=python3
script_default=${PATH:OPENFPGA_PATH}/openfpga_flow/scripts/run_fpga_flow.py script_default=${PATH:OPENFPGA_PATH}/openfpga_flow/scripts/run_fpga_flow.py

View File

@ -1,3 +1,13 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Script Name : run_fpga_task.py
# Description : This script designed to run openfpga_flow tasks,
# Opensfpga task are design to run opefpga_flow on each
# Combination of architecture, benchmark and script paramters
# Args : python3 run_fpga_task.py --help
# Author : Ganesh Gore
#Email : ganeshgore@utah.edu
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
import os import os
import sys import sys
import shutil import shutil
@ -19,6 +29,9 @@ from collections import OrderedDict
if util.find_spec("humanize"): if util.find_spec("humanize"):
import humanize import humanize
if sys.version_info[0] < 3:
raise Exception("run_fpga_task script must be using Python 3")
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configure logging system # Configure logging system
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ -40,6 +53,8 @@ parser.add_argument('--test_run', action="store_true",
help="Dummy run shows final generated VPR commands") help="Dummy run shows final generated VPR commands")
parser.add_argument('--debug', action="store_true", parser.add_argument('--debug', action="store_true",
help="Run script in debug mode") help="Run script in debug mode")
parser.add_argument('--exit_on_fail', action="store_true",
help="Exit script with return code")
parser.add_argument('--skip_tread_logs', action="store_true", parser.add_argument('--skip_tread_logs', action="store_true",
help="Skips logs from running thread") help="Skips logs from running thread")
args = parser.parse_args() args = parser.parse_args()
@ -50,6 +65,11 @@ args = parser.parse_args()
task_script_dir = os.path.dirname(os.path.abspath(__file__)) task_script_dir = os.path.dirname(os.path.abspath(__file__))
script_env_vars = ({"PATH": { script_env_vars = ({"PATH": {
"OPENFPGA_FLOW_PATH": task_script_dir, "OPENFPGA_FLOW_PATH": task_script_dir,
"ARCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "arch"),
"BENCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "benchmarks"),
"TECH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "tech"),
"SPICENETLIST_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "SpiceNetlists"),
"VERILOG_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "VerilogNetlists"),
"OPENFPGA_PATH": os.path.abspath(os.path.join(task_script_dir, os.pardir, "OPENFPGA_PATH": os.path.abspath(os.path.join(task_script_dir, os.pardir,
os.pardir))}}) os.pardir))}})
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
@ -140,6 +160,7 @@ def generate_each_task_actions(taskname):
GeneralSection = task_conf["GENERAL"] GeneralSection = task_conf["GENERAL"]
# Check if specified architecture files exist # Check if specified architecture files exist
# TODO Store it as a dictionary and take reference from the key
archfile_list = [] archfile_list = []
for _, arch_file in task_conf["ARCHITECTURES"].items(): for _, arch_file in task_conf["ARCHITECTURES"].items():
arch_full_path = arch_file arch_full_path = arch_file
@ -151,6 +172,10 @@ def generate_each_task_actions(taskname):
if not len(archfile_list) == len(list(set(archfile_list))): if not len(archfile_list) == len(list(set(archfile_list))):
clean_up_and_exit("Found duplicate architectures in config file") clean_up_and_exit("Found duplicate architectures in config file")
# Get Flow information
logger.info('Running "%s" flow' %
GeneralSection.get("fpga_flow", fallback="yosys_vpr"))
# Check if specified benchmark files exist # Check if specified benchmark files exist
benchmark_list = [] benchmark_list = []
for bech_name, each_benchmark in task_conf["BENCHMARKS"].items(): for bech_name, each_benchmark in task_conf["BENCHMARKS"].items():
@ -180,8 +205,6 @@ def generate_each_task_actions(taskname):
CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width", CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width",
fallback=chan_width_common) fallback=chan_width_common)
logger.info('Running "%s" flow' %
GeneralSection.get("fpga_flow", fallback="yosys_vpr"))
if GeneralSection.get("fpga_flow") == "vpr_blif": if GeneralSection.get("fpga_flow") == "vpr_blif":
# Check if activity file exist # Check if activity file exist
if not SynthSection.get(bech_name+"_act"): if not SynthSection.get(bech_name+"_act"):
@ -233,6 +256,10 @@ def generate_each_task_actions(taskname):
"run_dir": flow_run_dir, "run_dir": flow_run_dir,
"commands": command, "commands": command,
"status": False}) "status": False})
logger.info('Found %d Architectures %d Benchmarks & %d Script Parameters' %
(len(archfile_list), len(benchmark_list), len(ScriptSections)))
logger.info('Created total %d jobs' % len(flow_run_cmd_list))
return flow_run_cmd_list return flow_run_cmd_list
@ -348,6 +375,8 @@ def run_single_script(s, eachJob):
except: except:
logger.exception("Failed to execute openfpga flow - " + logger.exception("Failed to execute openfpga flow - " +
eachJob["name"]) eachJob["name"])
if args.exit_on_fail:
clean_up_and_exit("Faile to run task %s exiting" % name)
eachJob["endtime"] = time.time() eachJob["endtime"] = time.time()
timediff = timedelta(seconds=(eachJob["endtime"]-eachJob["starttime"])) timediff = timedelta(seconds=(eachJob["endtime"]-eachJob["starttime"]))
timestr = humanize.naturaldelta(timediff) if "humanize" in sys.modules \ timestr = humanize.naturaldelta(timediff) if "humanize" in sys.modules \
@ -360,12 +389,12 @@ def run_actions(job_run_list):
thread_sema = threading.Semaphore(args.maxthreads) thread_sema = threading.Semaphore(args.maxthreads)
thred_list = [] thred_list = []
for index, eachjob in enumerate(job_run_list): for index, eachjob in enumerate(job_run_list):
JobID = 'Job_%02d' % (index+1)
logger.info("Running %s = %s" % (JobID, eachjob["name"]))
t = threading.Thread(target=run_single_script, t = threading.Thread(target=run_single_script,
name='Job_%02d' % (index+1), name=JobID, args=(thread_sema, eachjob))
args=(thread_sema, eachjob))
t.start() t.start()
thred_list.append(t) thred_list.append(t)
for eachthread in thred_list: for eachthread in thred_list:
eachthread.join() eachthread.join()