diff --git a/.gitignore b/.gitignore
index be5e7170..bd402b31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,10 @@
docs/build
docs/.eggs
+.python-version
+local
+pyenv
+
examples/fpga/*/*/*
!examples/fpga/*/*/build.py
!examples/fpga/*/*/Makefile
diff --git a/.gitmodules b/.gitmodules
index cd6e6e66..b16b6213 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,9 @@
[submodule "prga.py"]
path = prga.py
url = https://github.com/PrincetonUniversity/prga.py.git
+[submodule "vtr"]
+ path = vtr
+ url = https://github.com/verilog-to-routing/vtr-verilog-to-routing.git
+[submodule "yosys"]
+ path = yosys
+ url = https://github.com/YosysHQ/yosys.git
diff --git a/docs/source/intro.rst b/docs/source/intro.rst
index e64448f0..c473b56c 100644
--- a/docs/source/intro.rst
+++ b/docs/source/intro.rst
@@ -13,19 +13,23 @@ Tools
PRGA is dependent on the following third-party tools:
-* `Verilog-to-Routing `_
-* `Yosys `_
* `Icarus Verilog `_ or `Synopsys VCS
`_
-Python
-^^^^^^
+Installation
+------------
-PRGA works with Python 2.7.x and Python 3.7.x. However, Python 2.x will reach
-its end of life on `January 1st, 2020
-`_ , so we recommend using Python
-3.7.x if possible.
+PRGA includes `Yosys `_ and `VTR
+`_ as submodules,
+uses `pyenv `_ and `pipenv
+`_ to manage Python interpretter and
+dependecies, and simplifies the installation with one single bash script that
+does not require root access:
+.. code-block:: bash
+
+ cd /path/to/prga/
+ ./envscr/install
Examples
--------
@@ -39,7 +43,7 @@ To build an FPGA, run the following commands:
.. code-block:: bash
cd /path/to/prga/ # cd to the root
- source envscr/settings.sh # set up the environment
+ ./envscr/activate # activate the virtual environment
cd examples/fpga/tiny/k4_N2_8x8 # choose one FPGA building example
make # build the FPGA!
@@ -49,6 +53,6 @@ following commands:
.. code-block:: bash
cd /path/to/prga/ # cd to the root
- source envscr/settings.sh # set up the environment
+ ./envscr/activate # activate the virtual environment
cd examples/target/bcd2bin/tiny_k4_N2_8x8 # choose one design and one FPGA
make # run all the way to verification
diff --git a/envscr/69a8e95.patch b/envscr/69a8e95.patch
new file mode 100644
index 00000000..2267eabc
--- /dev/null
+++ b/envscr/69a8e95.patch
@@ -0,0 +1,12 @@
+diff --git a/utils/fasm/src/fasm.cpp b/utils/fasm/src/fasm.cpp
+index ee7c7cd..ca81beb 100644
+--- a/utils/fasm/src/fasm.cpp
++++ b/utils/fasm/src/fasm.cpp
+@@ -603,6 +603,7 @@ void FasmWriterVisitor::walk_routing() {
+
+ for(const auto &trace : route_ctx.trace) {
+ t_trace *head = trace.head;
++ if (!head) continue;
+ t_rt_node* root = traceback_to_route_tree(head);
+ walk_route_tree(root);
+ free_route_tree(root);
diff --git a/envscr/activate b/envscr/activate
new file mode 100755
index 00000000..313d5e37
--- /dev/null
+++ b/envscr/activate
@@ -0,0 +1,46 @@
+function err() {
+ >&2 echo -e "\033[0;31m[ERROR]\033[0m" $@
+ exit 1
+}
+
+function info() {
+ echo -e "\033[0;34m[INFO]\033[0m" $@
+}
+
+if [ ! -z "${VIRTUAL_ENV}" ]; then
+ err "Already in a Python virtualenv"
+fi
+
+CWD=${PWD}
+OLD_PATH=$PATH
+cd "$( dirname "${BASH_SOURCE[0]}" )"/.. # move to PRGA_ROOT
+
+# choose the correct binaries
+info "Setting \$PATH"
+export PATH=${PWD}/local/bin:$PATH
+
+# activate pyenv
+if command -v pyenv 2>&1 >/dev/null; then
+ info "Active 'pyenv' found. Skipping installation/activation of 'pyenv'"
+else
+ info "Activating 'pyenv'"
+ export PYENV_ROOT=${PWD}/pyenv
+ export PATH=${PYENV_ROOT}/bin:$PATH
+ eval "$( pyenv init - )"
+ info "'pyenv' activated"
+fi
+
+# activate virtual env
+cd prga.py
+info "Entering virtual environment ..."
+PIPENV_VENV_IN_PROJECT=1 pipenv shell cd ${CWD}
+info "Leaving virtual environment ..."
+
+# roll back to the old state
+info "Reverting \$PATH"
+export PATH=$OLD_PATH
+cd $CWD
+
+info "Thanks for using PRGA. We look forward to your next use :)"
+
+# vim: set ft=sh:
diff --git a/envscr/install b/envscr/install
new file mode 100755
index 00000000..12cfde18
--- /dev/null
+++ b/envscr/install
@@ -0,0 +1,144 @@
+#!/usr/bin/env bash
+
+# Choose your desired compiler
+COMP=gcc
+MAKE_JOBCOUNT=8
+PYTHON_VERSION=3.7.2
+
+# Do not modify below this line
+CWD=${PWD}
+cd "$( dirname "${BASH_SOURCE[0]}" )"/.. # move to PRGA_ROOT
+
+trap "cd ${CWD}" EXIT
+trap "cd ${CWD}" SIGINT
+
+function err() {
+ >&2 echo -e "\033[0;31m[ERROR]\033[0m" $@
+ exit 1
+}
+
+function info() {
+ echo -e "\033[0;34m[INFO]\033[0m" $@
+}
+
+# find git
+GIT=$( command -v git 2>/dev/null )
+if [ -z "${GIT}" ]; then
+ err "'git' not found"
+fi
+info "Using 'git': ${GIT}"
+
+# find make
+MAKE=$( command -v make 2>/dev/null )
+if [ -z "${MAKE}" ]; then
+ err "'make' not found"
+fi
+info "Using 'make': ${MAKE}"
+
+# find cmake
+CMAKE=$( command -v cmake3 2>/dev/null )
+if [ -z "${CMAKE}" ]; then
+ CMAKE=$( command -v cmake 2>/dev/null )
+ if [ -z "${CMAKE}" ]; then
+ err "'cmake' not found"
+ elif [[ $( ${CMAKE} --version | cut -d " " -f 3 ) != "3"* ]]; then
+ err "CMake 3.x is required to build VPR"
+ fi
+fi
+info "Using 'cmake': ${CMAKE}"
+
+if [ -z "${COMP}" ]; then
+ COMP=gcc
+fi
+
+if [ -z "${MAKE_JOBCOUNT}" ]; then
+ MAKE_JOBCOUNT=8
+fi
+
+# find C compiler
+CC=$( command -v ${COMP} 2>/dev/null )
+if [ -z "${CC}" ]; then
+ err "'${COMP}' not found"
+fi
+info "Using '${COMP}': ${CC}"
+
+# find or install pyenv
+if command -v pyenv 2>&1 >/dev/null; then
+ info "Active 'pyenv' found. Skipping installation/activation of 'pyenv'"
+else
+ if [ ! -f pyenv/bin/pyenv ]; then
+ info "'pyenv' not found. Installing 'pyenv' locally to ${PWD}/pyenv"
+ ${GIT} clone https://github.com/pyenv/pyenv.git || exit 1
+ info "'pyenv' installed locally to ${PWD}/pyenv"
+ else
+ info "Locally-installed 'pyenv' found. Skipping installation of 'pyenv'"
+ fi
+
+ info "Activating locally-installed 'pyenv'"
+ export PYENV_ROOT=${PWD}/pyenv
+ export PATH=${PYENV_ROOT}/bin:$PATH
+ eval "$( pyenv init - )"
+ info "'pyenv' activated"
+fi
+
+# install the desired python if it's not installed already
+if [ -z "${PYTHON_VERSION}" ]; then
+ PYTHON_VERSION=3.7.2
+fi
+info "Installing Python ${PYTHON_VERSION} with 'pyenv'"
+pyenv install -s ${PYTHON_VERSION} || exit 1
+info "Python ${PYTHON_VERSION} installed with 'pyenv'"
+pyenv local ${PYTHON_VERSION} || exit 1
+if [[ $( python --version | cut -d " " -f 2 ) != "${PYTHON_VERSION}" ]]; then
+ err "'pyenv' is not choosing the correct Python version"
+fi
+info "Python ${PYTHON_VERSION} chosen as the local version"
+
+# install pipenv
+if [ -z "$( pip show pipenv 2>&1 >/dev/null )" ]; then
+ info "'pipenv' already installed. Skipping installation of 'pipenv'"
+else
+ info "Installing 'pipenv'"
+ pip install pipenv || exit 1
+ info "'pipenv' installed"
+fi
+
+# check out submodules
+info "Checking out submodules"
+${GIT} submodule update --init --recursive || exit 1
+
+mkdir -p local
+
+# build VTR
+info "Building VTR"
+cd vtr
+${GIT} apply ../envscr/69a8e95.patch 2>&1 >/dev/null
+${MAKE} -j${MAKE_JOBCOUNT} CMAKE=${CMAKE} || exit 1
+cd ..
+info "VTR built successfully"
+
+# build yosys
+info "Building Yosys"
+cd yosys
+${MAKE} -j${MAKE_JOBCOUNT} CONFIG=${COMP} || exit 1
+${MAKE} install CONFIG=${COMP} PREFIX=${PWD}/../local || exit 1
+cd ..
+info "Yosys built successfully"
+
+# link all binaries
+info "Linking binaries to ${PWD}/local/bin"
+cd local/bin
+ln -s -f ../../vtr/vpr/vpr vpr
+ln -s -f ../../vtr/build/utils/fasm/genfasm genfasm
+cd ../..
+
+# build a virtualenv for prga.py
+info "Creating a virtual environment for prga.py"
+cd prga.py
+PIPENV_VENV_IN_PROJECT=1 pipenv --python ${PYTHON_VERSION} install -e . || exit 1
+cd ..
+info "Virtual environment created for prga.py"
+
+info "Installation finished successfully"
+
+# vim: set ft=sh:
diff --git a/envscr/settings.sh b/envscr/settings.sh
deleted file mode 100644
index 183b66f0..00000000
--- a/envscr/settings.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-function find_binary() {
- binary="$1"
- shift
- /usr/bin/env $binary -h 2>&1 >/dev/null
- if [ "$?" != 0 ]; then
- echo "[Error] Binary not found: $binary"
- echo $@
- return 1
- fi
- return 0
-}
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. >/dev/null && pwd )"
-CWD=$PWD
-cd $DIR/envscr
-
-echo "[INFO] Checking the presence of Python Interpreter"
-find_binary python "Check out Python from https://www.python.org/"
-retval=$?
-if [ "$retval" != 0 ]; then return $retval 2>/dev/null; exit $retval; fi
-
-echo "[INFO] Checking the presence of PIP"
-python -m pip 2>&1 >/dev/null
-retval=$?
-if [ "$?" != 0 ]; then
- echo "[Error] Python module not found: pip"
- echo "Checkout PIP from: https://pypi.org/project/pip/"
- return $retval 2>/dev/null
- exit $retval
-fi
-
-echo "[INFO] Checking if prga.py is installed"
-python -c "from __future__ import absolute_import; import prga" 2>&1 >/dev/null
-retval=$?
-if [ "$retval" != 0 ]; then
- echo "[INFO] Installing prga.py"
- python -m pip install -e $DIR/prga.py --user
-fi
-
-echo "[INFO] Checking the presence of VPR"
-find_binary vpr "Check out VPR from " \
- "https://github.com/verilog-to-routing/vtr-verilog-to-routing, " \
- "compile it and find 'vpr' under \$VTR_ROOT/vpr/"
-retval=$?
-if [ "$retval" != 0 ]; then return $retval 2>/dev/null; exit $retval; fi
-
-echo "[INFO] Checking the presence of VPR utility: genfasm"
-find_binary genfasm "Check out VPR from " \
- "https://github.com/verilog-to-routing/vtr-verilog-to-routing, " \
- "compile it and find 'genfasm' under \$VTR_ROOT/build/utils/fasm/"
-retval=$?
-if [ "$retval" != 0 ]; then return $retval 2>/dev/null; exit $retval; fi
-
-echo "[INFO] Checking the presence of yosys"
-find_binary yosys "Check out Yosys from " \
- "http://www.clifford.at/yosys/, compile and install it"
-retval=$?
-if [ "$retval" != 0 ]; then return $retval 2>/dev/null; exit $retval; fi
-
-rm vpr_stdout.log
-cd $CWD
-
-echo "[INFO] Environmental setup succeeded!"
diff --git a/prga.py b/prga.py
index 336cffab..832526f2 160000
--- a/prga.py
+++ b/prga.py
@@ -1 +1 @@
-Subproject commit 336cffabab0d83b4d750cc56e29e142ffb720ec8
+Subproject commit 832526f2a73536e5e8371fd936bf31f073c6fb06
diff --git a/vtr b/vtr
new file mode 160000
index 00000000..69a8e95a
--- /dev/null
+++ b/vtr
@@ -0,0 +1 @@
+Subproject commit 69a8e95a51ad635f1c605c302aed4ba262e2ca62
diff --git a/yosys b/yosys
new file mode 160000
index 00000000..ccc83d99
--- /dev/null
+++ b/yosys
@@ -0,0 +1 @@
+Subproject commit ccc83d99bafc74f7ec62111bf61d962ca0a0771d