name: chipyard-ci-full-flow

on:
  # run ci on pull requests targeting following branches (runs on the merge commit)
  pull_request:
    branches:
      - main
      - '1.[0-9]*.x'
  schedule:
    # run at 00:00 on sunday
    - cron: "0 0 * * 0"

defaults:
  run:
    shell: bash -leo pipefail {0}

env:
  REMOTE_WORK_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 }}

  # Set up a set of boolean conditions to control which branches of the CI
  # workflow will execute This is based off the conditional job execution
  # example here: https://github.com/dorny/paths-filter#examples
  change-filters:
    name: filter-jobs-on-changes
    runs-on: ubuntu-latest
    # Queried by downstream jobs to determine if they should run.
    outputs:
      needs-rtl: ${{ steps.filter.outputs.all_count != steps.filter.outputs.skip-rtl_count }}

    steps:
      - uses: actions/checkout@v3
      - name: Git workaround
        uses: ./.github/actions/git-workaround
      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            all:
              - '**'

            # If any of the files changed match, do a doc build
            docs: &docs-filter
              - 'docs/**'
              - '.readthedocs.yml'

            # If all files match to this filter, skip the main ci pipeline
            skip-rtl:
              - *docs-filter
              - '**/*.md'
              - '**/.gitignore'
              - '.github/ISSUE_TEMPLATE/**'

  setup-repo:
    name: setup-repo
    needs: [change-filters, cancel-prior-workflows]
    if: needs.change-filters.outputs.needs-rtl == 'true'
    runs-on: as4
    steps:
      - name: Delete old checkout
        run: |
            ls -alh .
            rm -rf ${{ github.workspace }}/* || true
            rm -rf ${{ github.workspace }}/.* || true
            ls -alh .
      - uses: actions/checkout@v3
      - name: Setup repo copy
        run: |
          git clone $GITHUB_WORKSPACE ${{ env.REMOTE_WORK_DIR }}
      - name: Setup repo
        run: |
          cd ${{ env.REMOTE_WORK_DIR }}
          eval "$(conda shell.bash hook)"
          mkdir ${{ env.JAVA_TMP_DIR }}
          export MAKEFLAGS="-j32"
          ./build-setup.sh -f -v

  run-cfg-finder:
    name: run-cfg-finder
    needs: [setup-repo]
    runs-on: as4
    steps:
      - name: Run config finder
        run: |
          cd ${{ env.REMOTE_WORK_DIR }}
          eval "$(conda shell.bash hook)"
          source env.sh
          cd sims/verilator
          make find-config-fragments

  run-tutorial:
    name: run-tutorial
    needs: [setup-repo]
    runs-on: as4
    steps:
      - name: Run smoke test
        run: |
          cd ${{ env.REMOTE_WORK_DIR }}
          eval "$(conda shell.bash hook)"
          source env.sh
          cd sims/verilator
          make verilog
      - name: VLSI test
        run: |
          cd ${{ env.REMOTE_WORK_DIR }}
          eval "$(conda shell.bash hook)"
          source env.sh

          cd vlsi

          # NOTE: most conda installs are in separate conda envs because they mess up
          #   each other's versions (for no apparent reason) and we need the latest versions
          conda config --add channels defaults
          conda config --add channels litex-hub

          # installs for example-sky130.yml
          conda create -y --prefix ./.conda-sky130 open_pdks.sky130a=1.0.457_0_g32e8f23
          git clone https://github.com/rahulk29/sram22_sky130_macros.git

          # installs for example-openroad.yml
          conda create -y --prefix ./.conda-yosys yosys=0.27_4_gb58664d44
          conda create -y --prefix ./.conda-openroad openroad=2.0_7070_g0264023b6
          conda create -y --prefix ./.conda-klayout klayout=0.28.5_98_g87e2def28
          conda create -y --prefix ./.conda-signoff magic=8.3.376_0_g5e5879c netgen=1.5.250_0_g178b172

          echo "# Tutorial configs" > tutorial.yml
          echo "# pdk" > tutorial.yml
          echo "technology.sky130.sky130A: $PWD/.conda-sky130/share/pdk/sky130A" >> tutorial.yml
          echo "technology.sky130.sram22_sky130_macros: $PWD/sram22_sky130_macros" >> tutorial.yml
          echo "" >> tutorial.yml
          echo "# tools" >> tutorial.yml
          echo "synthesis.yosys.yosys_bin: $PWD/.conda-yosys/bin/yosys" >> tutorial.yml
          echo "par.openroad.openroad_bin: $PWD/.conda-openroad/bin/openroad" >> tutorial.yml
          echo "par.openroad.klayout_bin: $PWD/.conda-klayout/bin/klayout" >> tutorial.yml
          echo "drc.magic.magic_bin: $PWD/.conda-signoff/bin/magic" >> tutorial.yml
          echo "drc.klayout.klayout_bin: $PWD/.conda-klayout/bin/klayout" >> tutorial.yml
          echo "lvs.netgen.netgen_bin: $PWD/.conda-signoff/bin/netgen" >> tutorial.yml
          echo "" >> tutorial.yml
          echo "# speed up tutorial runs & declutter log output" >> tutorial.yml
          echo "par.openroad.timing_driven: false" >> tutorial.yml
          echo "par.openroad.write_reports: false" >> tutorial.yml

          conda config --remove channels litex-hub
          conda config --remove channels defaults

          export tutorial=sky130-openroad
          export EXTRA_CONFS=tutorial.yml
          export VLSI_TOP=RocketTile
          make buildfile
          make syn
          # NOTE: commenting out for now bc this times out - need to debug why
          # openroad freezes during some write commands after detailed route
          # so need to stop the flow & run last step separately
          # make par HAMMER_EXTRA_ARGS="--stop_after_step extraction"
          # make redo-par HAMMER_EXTRA_ARGS="--start_before_step extraction"
          # make drc
          # make lvs


  cleanup:
    name: cleanup
    needs: [run-tutorial]
    runs-on: as4
    if: ${{ always() }}
    steps:
      - name: Delete repo copy and conda env
        run: |
           rm -rf ${{ env.REMOTE_WORK_DIR }}
           rm -rf ${{ env.JAVA_TMP_DIR }}
