# CircleCI Configuration File

# version of circleci
version: 2.1

parameters:
    tools-cache-version:
        type: string
        default: "v9"

# default execution env.s
executors:
    main-env:
        docker:
            - image: ucbbar/chipyard-ci-image:1d51bb90
        environment:
            JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit

# re-usable commands
commands:
    toolchain-build:
        description: "Build a toolchain"
        parameters:
            tools-version:
                type: string
                default: "riscv-tools"
        steps:
            - checkout
            - run:
                name: Create hash of toolchains
                command: |
                    .circleci/create-hash.sh
            - restore_cache:
                keys:
                    - << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}
            - run:
                name: Building << parameters.tools-version >>
                command: |
                    .circleci/build-toolchains.sh << parameters.tools-version >>
                no_output_timeout: 120m
            - save_cache:
                key: << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}
                paths:
                    - "/root/<< parameters.tools-version >>-install"

    ssh-checkout:
        description: "Add SSH key and checkout code"
        steps:
            - add_ssh_keys:
                fingerprints:
                    - "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
                    - "32:d6:89:d2:97:fa:db:de:a8:2d:2a:f2:70:dd:80:89"
            - checkout

    setup-tools:
        description: "Get toolchain"
        parameters:
            tools-version:
                type: string
                default: "riscv-tools"
        steps:
            - ssh-checkout
            - run:
                name: Create hash of toolchains
                command: |
                    .circleci/create-hash.sh
            - restore_cache:
                keys:
                    - << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}

    prepare-rtl:
        description: "Run the prepare step of RTL"
        parameters:
            tools-version:
                type: string
                default: "riscv-tools"
            group-key:
                type: string
            timeout:
                type: string
                default: "120m"
            build-script:
                type: string
                default: "do-rtl-build.sh"
            build-type:
                type: string
                default: "sim"
        steps:
            - setup-tools:
                tools-version: "<< parameters.tools-version >>"
            - run:
                name: Building << parameters.group-key >> subproject using Verilator
                command: .circleci/<< parameters.build-script >> << parameters.group-key >> << parameters.build-type >>
                no_output_timeout: << parameters.timeout >>
            - save_cache:
                key: << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
                paths:
                    - "/root/project"

    run-tests:
        description: "Run a set of tests"
        parameters:
            tools-version:
                type: string
                default: "riscv-tools"
            group-key:
                type: string
            project-key:
                type: string
            run-script:
                type: string
                default: "run-tests.sh"
            timeout:
                type: string
                default: "25m"
        steps:
            - setup-tools:
                tools-version: "<< parameters.tools-version >>"
            - restore_cache:
                keys:
                    - << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
            - run:
                name: Run << parameters.project-key >> subproject tests
                command: .circleci/<< parameters.run-script >> << parameters.project-key >>
                no_output_timeout: << parameters.timeout >>

# set of jobs to run
jobs:
    commit-on-master-check:
        executor: main-env
        steps:
            - checkout
            - run:
                name: Check commits of each submodule
                command: |
                    .circleci/check-commit.sh
    tutorial-setup-check:
        executor: main-env
        steps:
            - checkout
            - run:
                name: Check that the tutorial-setup patches apply
                command: |
                    scripts/tutorial-setup.sh
    documentation-check:
        executor: main-env
        steps:
            - checkout
            - run:
                name: Check that documentation builds with no warnings/errors
                command: |
                    sudo apt-get update -y
                    sudo apt-get install -y python3-pip
                    sudo pip3 install -r docs/requirements.txt
                    make -C docs html

    install-riscv-toolchain:
        executor: main-env
        steps:
            - toolchain-build:
                tools-version: "riscv-tools"
    install-esp-toolchain:
        executor: main-env
        steps:
            - toolchain-build:
                tools-version: "esp-tools"
    install-verilator:
        executor: main-env
        steps:
            - ssh-checkout
            - run:
                name: Install Verilator to remote
                command: |
                    .circleci/install-verilator.sh
    build-extra-tests:
        executor: main-env
        steps:
            - ssh-checkout
            - run:
                name: Create hash of toolchains
                command: |
                    .circleci/create-hash.sh
            - restore_cache:
                keys:
                    - riscv-tools-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../riscv-tools.hash" }}
            - run:
                name: Build extra tests
                command: .circleci/build-extra-tests.sh
                no_output_timeout: 120m
            - save_cache:
                key: extra-tests-{{ .Branch }}-{{ .Revision }}
                paths:
                    - "/root/project/tests"

    prepare-chipyard-cores:
        executor: main-env
        steps:
            - prepare-rtl:
                group-key: "group-cores"
    prepare-chipyard-peripherals:
        executor: main-env
        steps:
            - prepare-rtl:
                group-key: "group-peripherals"
    prepare-chipyard-accels:
        executor: main-env
        steps:
            - prepare-rtl:
                tools-version: "esp-tools"
                group-key: "group-accels"
    prepare-chipyard-tracegen:
        executor: main-env
        steps:
            - prepare-rtl:
                group-key: "group-tracegen"
    prepare-chipyard-other:
        executor: main-env
        steps:
            - prepare-rtl:
                group-key: "group-other"

    chipyard-rocket-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-rocket"
    chipyard-hetero-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-hetero"
                timeout: "20m"
    chipyard-boom-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-boom"
    chipyard-cva6-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-cva6"
                timeout: "30m"
    chipyard-sodor-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-sodor"
                timeout: "30m"
    chipyard-multiclock-rocket-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-cores"
                project-key: "chipyard-multiclock-rocket"
    chipyard-dmirocket-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-peripherals"
                project-key: "chipyard-dmirocket"
    chipyard-spiflashwrite-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-peripherals"
                project-key: "chipyard-spiflashwrite"
    chipyard-spiflashread-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-peripherals"
                project-key: "chipyard-spiflashread"
    chipyard-lbwif-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-peripherals"
                project-key: "chipyard-lbwif"

    chipyard-sha3-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-accels"
                project-key: "chipyard-sha3"
    chipyard-streaming-fir-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-accels"
                project-key: "chipyard-streaming-fir"
    chipyard-streaming-passthrough-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-accels"
                project-key: "chipyard-streaming-passthrough"
    chipyard-hwacha-run-tests:
        executor: main-env
        steps:
            - run-tests:
                tools-version: "esp-tools"
                group-key: "group-accels"
                project-key: "chipyard-hwacha"
                timeout: "30m"
    chipyard-gemmini-run-tests:
        executor: main-env
        steps:
            - run-tests:
                tools-version: "esp-tools"
                group-key: "group-accels"
                project-key: "chipyard-gemmini"
    chipyard-nvdla-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-accels"
                project-key: "chipyard-nvdla"
    tracegen-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-tracegen"
                project-key: "tracegen"
    tracegen-boom-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-tracegen"
                project-key: "tracegen-boom"
    icenet-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-other"
                project-key: "icenet"
                timeout: "30m"
    testchipip-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "group-other"
                project-key: "testchipip"
                timeout: "30m"
    firesim-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "extra-tests"
                project-key: "firesim"
                run-script: "run-firesim-scala-tests.sh"
                timeout: "20m"
    fireboom-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "extra-tests"
                project-key: "fireboom"
                run-script: "run-firesim-scala-tests.sh"
                timeout: "45m"
    firesim-multiclock-run-tests:
        executor: main-env
        steps:
            - run-tests:
                group-key: "extra-tests"
                project-key: "firesim-multiclock"
                run-script: "run-firesim-scala-tests.sh"
                timeout: "20m"
    prepare-chipyard-fpga:
        executor: main-env
        steps:
            - prepare-rtl:
                group-key: "group-fpga"
                build-type: "fpga"

# Order and dependencies of jobs to run
workflows:
    version: 2
    submodules-on-master:
        jobs:
            # Check to make sure submodule commits are on master branches
            - commit-on-master-check
        triggers:
            - schedule:
                cron: "0 0 * * *"
                filters:
                    branches:
                        only:
                            - master

    build-and-test-chipyard-integration:
        jobs:
            # Make the toolchains
            - install-riscv-toolchain

            - install-esp-toolchain

            - install-verilator

            - commit-on-master-check

            # Attempt to apply the tutorial patches
            - tutorial-setup-check

            # Check that documentation builds
            - documentation-check

            # Build extra tests
            - build-extra-tests:
                requires:
                    - install-riscv-toolchain

            # Prepare the verilator builds
            - prepare-chipyard-cores:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
            - prepare-chipyard-peripherals:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
            - prepare-chipyard-accels:
                requires:
                    - install-esp-toolchain
                    - install-verilator
            - prepare-chipyard-tracegen:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
            - prepare-chipyard-other:
                requires:
                    - install-riscv-toolchain
                    - install-verilator

            # Run the example tests
            - chipyard-rocket-run-tests:
                requires:
                    - prepare-chipyard-cores
            - chipyard-hetero-run-tests:
                requires:
                    - prepare-chipyard-cores
            - chipyard-boom-run-tests:
                requires:
                    - prepare-chipyard-cores
            - chipyard-cva6-run-tests:
                requires:
                    - prepare-chipyard-cores
            - chipyard-sodor-run-tests:
                requires:
                    - prepare-chipyard-cores
            - chipyard-dmirocket-run-tests:
                requires:
                    - prepare-chipyard-peripherals
            - chipyard-spiflashwrite-run-tests:
                requires:
                    - prepare-chipyard-peripherals
            - chipyard-spiflashread-run-tests:
                requires:
                    - prepare-chipyard-peripherals
            - chipyard-lbwif-run-tests:
                requires:
                    - prepare-chipyard-peripherals

            - chipyard-sha3-run-tests:
                requires:
                    - prepare-chipyard-accels
            - chipyard-streaming-fir-run-tests:
                requires:
                    - prepare-chipyard-accels
            - chipyard-streaming-passthrough-run-tests:
                requires:
                    - prepare-chipyard-accels
            - chipyard-hwacha-run-tests:
                requires:
                    - prepare-chipyard-accels
            - chipyard-gemmini-run-tests:
                requires:
                    - prepare-chipyard-accels
            - chipyard-nvdla-run-tests:
                requires:
                    - prepare-chipyard-accels

            - tracegen-run-tests:
                requires:
                    - prepare-chipyard-tracegen
            - tracegen-boom-run-tests:
                requires:
                    - prepare-chipyard-tracegen

            - icenet-run-tests:
                requires:
                    - prepare-chipyard-other
            - testchipip-run-tests:
                requires:
                    - prepare-chipyard-other

            # Run the firesim tests
            - firesim-run-tests:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
                    - build-extra-tests
            - firesim-multiclock-run-tests:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
                    - build-extra-tests
            - fireboom-run-tests:
                requires:
                    - install-riscv-toolchain
                    - install-verilator
                    - build-extra-tests

            # Prepare the fpga builds (just Verilog)
            - prepare-chipyard-fpga:
                requires:
                    - install-riscv-toolchain
