From 281839da6da855b2118e9bc10ad5e89073bff637 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 09:21:29 -0800 Subject: [PATCH 1/6] Add initial CI tutorial area --- .github/workflows/chipyard-tutorials.yml | 57 ++++++++++++++++++++++++ scripts/tutorial-first-verilog-build.sh | 35 +++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 .github/workflows/chipyard-tutorials.yml create mode 100755 scripts/tutorial-first-verilog-build.sh diff --git a/.github/workflows/chipyard-tutorials.yml b/.github/workflows/chipyard-tutorials.yml new file mode 100644 index 0000000000..0119f676ef --- /dev/null +++ b/.github/workflows/chipyard-tutorials.yml @@ -0,0 +1,57 @@ +name: chipyard-tutorials + +# TODO: figure out when to run tutorials +on: + # run ci on pull requests targeting following branches (runs on the merge commit) + pull_request: + branches: + - main + - '1.[0-9]*.x' + +# nicer shell to run commands in +defaults: + run: + shell: bash -leo pipefail {0} + +env: + CHIPYARD_DIR: ${{ secrets.BUILDDIR }}/cy-ci-shared/cy-${{ github.sha }} + JAVA_TMP_DIR: /tmp/cy-${{ github.sha }}-full + +jobs: + cancel-prior-workflows: + name: cancel-prior-workflows + runs-on: ubuntu-latest + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.11.0 + with: + access_token: ${{ github.token }} + + setup-chipyard-tutorial: + name: nice name + needs: [cancel-prior-workflows] + runs-on: as4 + steps: + # workaround actions/checkout not 'cleaning' submodules on new checkouts. see https://github.com/actions/checkout/issues/358 + - name: Delete old checkout + run: | + rm -rf ${{ github.workspace }}/* || true + rm -rf ${{ github.workspace }}/.* || true + - uses: actions/checkout@v3 + # copy repository to globally visible area (useful for if tutorials need to be split across multiple GH-A jobs). + # in this case, a tutorial run is within a single GH-A job so you could just use the $GITHUB_WORKSPACE + - name: Setup repository + run: | + git clone ${{ github.workspace }} $CHIPYARD_DIR + mkdir $JAVA_TMP_DIR + # TODO: should/could be autogenerated from the docs + # a script with all the tutorial commands + - name: Run tutorial + run: | + cd $CHIPYARD_DIR # cd's into globally visible directory 1st (otherwise would run out of the $GITHUB_WORKSPACE which is per-job) + scripts/tutorial-first-verilog-build.sh + - name: Delete repository (and other misc. data) + if: ${{ always() }} # always run at the end + run: | + rm -rf ${{ env.REMOTE_WORK_DIR }} + rm -rf ${{ env.JAVA_TMP_DIR }} diff --git a/scripts/tutorial-first-verilog-build.sh b/scripts/tutorial-first-verilog-build.sh new file mode 100755 index 0000000000..75fdf691fd --- /dev/null +++ b/scripts/tutorial-first-verilog-build.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# exit script if any command fails +set -e +set -o pipefail + +# $CHIPYARD_DIR should be defined and pointing to the top-level folder in Chipyard +if [[ -z "${CHIPYARD_DIR}" ]]; then + echo "Environment variable \$CHIPYARD_DIR is undefined. Unable to run script." + exit 1 +fi + +cd $CHIPYARD + +# speed up setup +export MAKEFLAGS="-j32" + +# run setup +./build-setup.sh -f -v + +# use chipyard env +source env.sh + +# build first set of verilog +cd sims/verilator +make verilog + +# build and make verilator binary for verilog built +make + +# see verilog +ls -alh generated-src + +# see verilator binary +ls -alh simulator* From 8bbf74553e8be3db295d229d3b2dcbfd12e23f01 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 09:24:26 -0800 Subject: [PATCH 2/6] Update titles --- .github/workflows/chipyard-tutorials.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/chipyard-tutorials.yml b/.github/workflows/chipyard-tutorials.yml index 0119f676ef..a9c9a9b1da 100644 --- a/.github/workflows/chipyard-tutorials.yml +++ b/.github/workflows/chipyard-tutorials.yml @@ -19,7 +19,7 @@ env: jobs: cancel-prior-workflows: - name: cancel-prior-workflows + name: Cancel Prior Workflows runs-on: ubuntu-latest steps: - name: Cancel Previous Runs @@ -27,8 +27,8 @@ jobs: with: access_token: ${{ github.token }} - setup-chipyard-tutorial: - name: nice name + first-verilog-build-tutorial: + name: First Verilog Build Tutorial needs: [cancel-prior-workflows] runs-on: as4 steps: From 1379a8244130306524d1970f6b80af57f0241fb5 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 09:26:11 -0800 Subject: [PATCH 3/6] Fix tutorial path --- scripts/tutorial-first-verilog-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tutorial-first-verilog-build.sh b/scripts/tutorial-first-verilog-build.sh index 75fdf691fd..4dbf3c7c54 100755 --- a/scripts/tutorial-first-verilog-build.sh +++ b/scripts/tutorial-first-verilog-build.sh @@ -10,7 +10,7 @@ if [[ -z "${CHIPYARD_DIR}" ]]; then exit 1 fi -cd $CHIPYARD +cd $CHIPYARD_DIR # speed up setup export MAKEFLAGS="-j32" From 628f47f0ea46ccb1718e84d36e85ec2e60a6eb42 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 10:37:11 -0800 Subject: [PATCH 4/6] Automated RST tutorial --- .github/workflows/chipyard-tutorials.yml | 34 ++++++++- docs/Tutorials/First-Verilog-Build.rst | 39 +++++++++++ docs/Tutorials/index.rst | 13 ++++ docs/index.rst | 2 + scripts/generate-script-from-tutorial-rst.py | 72 ++++++++++++++++++++ 5 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 docs/Tutorials/First-Verilog-Build.rst create mode 100644 docs/Tutorials/index.rst create mode 100755 scripts/generate-script-from-tutorial-rst.py diff --git a/.github/workflows/chipyard-tutorials.yml b/.github/workflows/chipyard-tutorials.yml index a9c9a9b1da..4aedc4517d 100644 --- a/.github/workflows/chipyard-tutorials.yml +++ b/.github/workflows/chipyard-tutorials.yml @@ -27,6 +27,7 @@ jobs: with: access_token: ${{ github.token }} + # example of running a tutorial given a pre-made script first-verilog-build-tutorial: name: First Verilog Build Tutorial needs: [cancel-prior-workflows] @@ -44,7 +45,6 @@ jobs: run: | git clone ${{ github.workspace }} $CHIPYARD_DIR mkdir $JAVA_TMP_DIR - # TODO: should/could be autogenerated from the docs # a script with all the tutorial commands - name: Run tutorial run: | @@ -55,3 +55,35 @@ jobs: run: | rm -rf ${{ env.REMOTE_WORK_DIR }} rm -rf ${{ env.JAVA_TMP_DIR }} + + # example of running a tutorial from an auto-generated script built from .rst + first-verilog-build-automated-tutorial: + name: First Verilog Build Automated Tutorial + needs: [cancel-prior-workflows] + runs-on: as4 + steps: + # workaround actions/checkout not 'cleaning' submodules on new checkouts. see https://github.com/actions/checkout/issues/358 + - name: Delete old checkout + run: | + rm -rf ${{ github.workspace }}/* || true + rm -rf ${{ github.workspace }}/.* || true + - uses: actions/checkout@v3 + # copy repository to globally visible area (useful for if tutorials need to be split across multiple GH-A jobs). + # in this case, a tutorial run is within a single GH-A job so you could just use the $GITHUB_WORKSPACE + - name: Setup repository + run: | + git clone ${{ github.workspace }} $CHIPYARD_DIR + mkdir $JAVA_TMP_DIR + # run the autogenerated script with all the tutorial commands + - name: Run tutorial + run: | + cd $CHIPYARD_DIR # cd's into globally visible directory 1st (otherwise would run out of the $GITHUB_WORKSPACE which is per-job) + scripts/generate-script-from-tutorial-rst.py docs/Tutorials/First-Verilog-Build.rst tutorial.sh + echo "Created tutorial.sh >>>" && cat tutorial.sh && echo "<<< Done tutorial.sh" + chmod +x tutorial.sh + ./tutorial.sh + - name: Delete repository (and other misc. data) + if: ${{ always() }} # always run at the end + run: | + rm -rf ${{ env.REMOTE_WORK_DIR }} + rm -rf ${{ env.JAVA_TMP_DIR }} diff --git a/docs/Tutorials/First-Verilog-Build.rst b/docs/Tutorials/First-Verilog-Build.rst new file mode 100644 index 0000000000..de03d23afb --- /dev/null +++ b/docs/Tutorials/First-Verilog-Build.rst @@ -0,0 +1,39 @@ +First Verilog Build +=================== + +This tutorial guides you through setting up Chipyard for the first time and building Verilog (specifically a Rocket core SoC). + +.. code-block:: shell + + cd $CHIPYARD_DIR + +.. only:: replace-code-above + + cd $CHIPYARD_DIR + export MAKEFLAGS="-j32" + +.. code-block:: shell + + ./build-setup.sh + +.. only:: replace-code-above + + ./build-setup.sh -f -v + +.. code-block:: shell + + source env.sh + +.. code-block:: shell + + cd sims/verilator + make verilog + +.. code-block:: shell + + make + +.. code-block:: shell + + ls -alh generated-src + ls -alh simulator* diff --git a/docs/Tutorials/index.rst b/docs/Tutorials/index.rst new file mode 100644 index 0000000000..40e027ba22 --- /dev/null +++ b/docs/Tutorials/index.rst @@ -0,0 +1,13 @@ +Tutorials +================ + +This section holds various tutorials for specific features, workflows, and more within Chipyard. +Each requires you to checkout the Chipyard repo and set the ``CHIPYARD_DIR`` environment variable before continuing on. + +.. Warning:: Tutorials are only guaranteed to work on released versions of Chipyard. + +.. toctree:: + :maxdepth: 2 + :caption: Tutorials: + + First-Verilog-Build diff --git a/docs/index.rst b/docs/index.rst index 48791642da..f611867620 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,6 +43,8 @@ Table of Contents Prototyping/index + Tutorials/index + Indices and tables ================== diff --git a/scripts/generate-script-from-tutorial-rst.py b/scripts/generate-script-from-tutorial-rst.py new file mode 100755 index 0000000000..3369df9d35 --- /dev/null +++ b/scripts/generate-script-from-tutorial-rst.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +import sys + +# $1 - rst file to parse +# $2 - output bash file to write + +if len(sys.argv) != 3: + sys.exit("[ERROR] Incorrect # of args.") + +rstFile = sys.argv[1] +bashFile = sys.argv[2] + +codeBlocks = [] # ordered list of blocks, each block is (type: String, lines: List[Strings]) + +with open(rstFile, 'r') as rstF: + inBlock = False + skipEmpty = False + curBlockType = "" + curBlockLines = [] + for line in rstF.readlines(): + if inBlock: + if len(line) == 1 and line == '\n': + # empty line + if not skipEmpty: + # empty line (done with block) + inBlock = False + codeBlocks.append((curBlockType, curBlockLines)) + curBlockType = "" + curBlockLines = [] + skipEmpty = False + else: + assert (line[0:4] == ' ' * 4), "Must only strip whitespace (ensure RST only has 4 spaces before code lines)" + curBlockLines.append(line[4:]) # strip the first 4 spaces (indent) + else: + if ".. code-block:: shell" in line: + inBlock = True + curBlockType = "code-block" + skipEmpty = True + elif ".. only:: replace-code-above" in line: + inBlock = True + curBlockType = "replace-above" + skipEmpty = True + +idxToDelete = [] +for idx, cb in enumerate(codeBlocks): + if cb[0] == "replace-above": + idxToDelete.append(idx) + +# TODO: could check that replace-code-above directives cannot follow one another + +idxToDelete.reverse() +for idx in idxToDelete: + assert idx - 1 >= 0, "replace-code-above directives must come after a code-block directive" + codeBlocks.pop(idx - 1) + +with open(bashFile, 'w') as bashF: + header = """#!/usr/bin/env bash + +# exit script if any command fails +set -e +set -o pipefail + +# $CHIPYARD_DIR should be defined and pointing to the top-level folder in Chipyard +if [[ -z "${CHIPYARD_DIR}" ]]; then + echo "Environment variable \$CHIPYARD_DIR is undefined. Unable to run script." + exit 1 +fi +""" + bashF.writelines([header, '\n']) + for cb in codeBlocks: + bashF.writelines(cb[1]) From f5b06d6b9e844597e95f63dceb2a9f7332a33f2b Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 10:41:39 -0800 Subject: [PATCH 5/6] Remove global Chipyard dir --- .github/workflows/chipyard-tutorials.yml | 32 +++--------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/.github/workflows/chipyard-tutorials.yml b/.github/workflows/chipyard-tutorials.yml index 4aedc4517d..289a3e8a19 100644 --- a/.github/workflows/chipyard-tutorials.yml +++ b/.github/workflows/chipyard-tutorials.yml @@ -13,10 +13,6 @@ defaults: run: shell: bash -leo pipefail {0} -env: - CHIPYARD_DIR: ${{ secrets.BUILDDIR }}/cy-ci-shared/cy-${{ github.sha }} - JAVA_TMP_DIR: /tmp/cy-${{ github.sha }}-full - jobs: cancel-prior-workflows: name: Cancel Prior Workflows @@ -32,6 +28,8 @@ jobs: name: First Verilog Build Tutorial needs: [cancel-prior-workflows] runs-on: as4 + env: + CHIPYARD_DIR: ${{ github.workspace }} steps: # workaround actions/checkout not 'cleaning' submodules on new checkouts. see https://github.com/actions/checkout/issues/358 - name: Delete old checkout @@ -39,28 +37,18 @@ jobs: rm -rf ${{ github.workspace }}/* || true rm -rf ${{ github.workspace }}/.* || true - uses: actions/checkout@v3 - # copy repository to globally visible area (useful for if tutorials need to be split across multiple GH-A jobs). - # in this case, a tutorial run is within a single GH-A job so you could just use the $GITHUB_WORKSPACE - - name: Setup repository - run: | - git clone ${{ github.workspace }} $CHIPYARD_DIR - mkdir $JAVA_TMP_DIR # a script with all the tutorial commands - name: Run tutorial run: | - cd $CHIPYARD_DIR # cd's into globally visible directory 1st (otherwise would run out of the $GITHUB_WORKSPACE which is per-job) scripts/tutorial-first-verilog-build.sh - - name: Delete repository (and other misc. data) - if: ${{ always() }} # always run at the end - run: | - rm -rf ${{ env.REMOTE_WORK_DIR }} - rm -rf ${{ env.JAVA_TMP_DIR }} # example of running a tutorial from an auto-generated script built from .rst first-verilog-build-automated-tutorial: name: First Verilog Build Automated Tutorial needs: [cancel-prior-workflows] runs-on: as4 + env: + CHIPYARD_DIR: ${{ github.workspace }} steps: # workaround actions/checkout not 'cleaning' submodules on new checkouts. see https://github.com/actions/checkout/issues/358 - name: Delete old checkout @@ -68,22 +56,10 @@ jobs: rm -rf ${{ github.workspace }}/* || true rm -rf ${{ github.workspace }}/.* || true - uses: actions/checkout@v3 - # copy repository to globally visible area (useful for if tutorials need to be split across multiple GH-A jobs). - # in this case, a tutorial run is within a single GH-A job so you could just use the $GITHUB_WORKSPACE - - name: Setup repository - run: | - git clone ${{ github.workspace }} $CHIPYARD_DIR - mkdir $JAVA_TMP_DIR # run the autogenerated script with all the tutorial commands - name: Run tutorial run: | - cd $CHIPYARD_DIR # cd's into globally visible directory 1st (otherwise would run out of the $GITHUB_WORKSPACE which is per-job) scripts/generate-script-from-tutorial-rst.py docs/Tutorials/First-Verilog-Build.rst tutorial.sh echo "Created tutorial.sh >>>" && cat tutorial.sh && echo "<<< Done tutorial.sh" chmod +x tutorial.sh ./tutorial.sh - - name: Delete repository (and other misc. data) - if: ${{ always() }} # always run at the end - run: | - rm -rf ${{ env.REMOTE_WORK_DIR }} - rm -rf ${{ env.JAVA_TMP_DIR }} From 997dfe844a009578f469db43b55d3ec587ab54fe Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Thu, 7 Dec 2023 11:25:34 -0800 Subject: [PATCH 6/6] Add a bit of text to tutorial --- docs/Tutorials/First-Verilog-Build.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/Tutorials/First-Verilog-Build.rst b/docs/Tutorials/First-Verilog-Build.rst index de03d23afb..887ddefbab 100644 --- a/docs/Tutorials/First-Verilog-Build.rst +++ b/docs/Tutorials/First-Verilog-Build.rst @@ -3,6 +3,9 @@ First Verilog Build This tutorial guides you through setting up Chipyard for the first time and building Verilog (specifically a Rocket core SoC). +First navigate to the Chipyard directory. +Ensure that ``$CHIPYARD_DIR`` is set to the top-level directory. + .. code-block:: shell cd $CHIPYARD_DIR @@ -12,6 +15,8 @@ This tutorial guides you through setting up Chipyard for the first time and buil cd $CHIPYARD_DIR export MAKEFLAGS="-j32" +Next, run the Chipyard setup script. + .. code-block:: shell ./build-setup.sh @@ -20,19 +25,28 @@ This tutorial guides you through setting up Chipyard for the first time and buil ./build-setup.sh -f -v +Chipyard should be setup. +Next, source the ``env.sh`` script to setup your ``PATH`` and other environment variables. + .. code-block:: shell source env.sh +Next, let's build some Verilog specifically the default SoC which includes a Rocket in-order core. + .. code-block:: shell cd sims/verilator make verilog +Next, let's build the Verilator simulator binary of that SoC that can run a RISC-V binary (like a "Hello, World" program). + .. code-block:: shell make +Finally, look at the ``generated-src`` directory which holds the Verilog sources and the ``simulator-*`` file which is the compiled Verilator binary. + .. code-block:: shell ls -alh generated-src