Skip to content

Commit

Permalink
Squashed 'clash-vexriscv/' changes from 2eced423..68886c88
Browse files Browse the repository at this point in the history
68886c88 Merge pull request #46 from clash-lang/run-clang-format
a32dbc98 Add `clang-format-check` to ci
68ca4d0e Format with `clang-format`
9a676aa6 Add `clang` to nix shell
0d4be0e0 Merge pull request #45 from clash-lang/lucas/bump-jtag-interface
61c7719d Bump GHC versions on Docker images and rebuild
5f9a53c9 Add `.scala-build` to `.gitignore`
2c1ec3a3 Remove `openocd-vexriscv` from `nix` and `docker`
deabc085 Switch to `openocd-vexriscv` and use `remote-bitbang`
d987e396 Replace `DebugPlugin` with `EmbeddedRiscvJtag`
59298429 Add `nix` derivation for `openocv-riscv`
2dfda13f Add `.metals` to `.gitignore`
554f4af1 Bump scala and spinal version
720e5d44 Add execute permissions to `update-vexriscv.pu`
ad6edb75 Merge pull request #44 from clash-lang/lucas/add-docker-readme
636ac968 Extend readme with CI info
ac10433d Bump GHA actions (#43)
59215117 Merge pull request #42 from clash-lang/add-all-check
e697bfdd Fix typo: ouput -> output
e7e8e29c Add all check to CI

git-subtree-dir: clash-vexriscv
git-subtree-split: 68886c8879d3df885e977a658f245a8a782079e8
  • Loading branch information
lmbollen committed Jan 8, 2025
1 parent 26856b5 commit bacc4f2
Show file tree
Hide file tree
Showing 27 changed files with 4,338 additions and 2,198 deletions.
4 changes: 2 additions & 2 deletions .github/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

FROM builder AS build-openocd-vexriscv
FROM builder AS build-openocd-riscv

ARG DEPS_OPENOCD_VEXRISCV="autoconf automake libtool pkg-config libusb-1.0-0-dev libftdi-dev libhidapi-dev libusb-dev libyaml-dev"

Expand Down Expand Up @@ -78,5 +78,5 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*

COPY --from=build-verilator /opt /opt
COPY --from=build-openocd-vexriscv /opt /opt
COPY --from=build-openocd-riscv /opt /opt
COPY --from=build-ghc /root/.ghcup /root/.ghcup
6 changes: 4 additions & 2 deletions .github/docker/build-and-publish-docker-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ elif [[ "$1" != "" ]]; then
fi

UBUNTU_VERSION=jammy-20240125
GHC_VERSIONS=( "9.6.6" "9.4.8" "9.2.8" "9.0.2")
CABAL_VERSION="3.10.2.0"
GHC_VERSIONS=( "9.10.1" "9.8.4" "9.6.6" "9.4.8" "9.2.8" "9.0.2")
CABAL_VERSION="3.12.1.0"

for i in "${!GHC_VERSIONS[@]}"
do
GHC_VERSION="${GHC_VERSIONS[i]}"

# If you get an error like "unrecognized argument buildx", consider installing
# the buildx plugin for Docker. E.g., for Ubuntu: `apt install docker-buildx`.
docker buildx build \
--build-arg UBUNTU_VERSION=${UBUNTU_VERSION} \
--build-arg cabal_version=${CABAL_VERSION} \
Expand Down
35 changes: 35 additions & 0 deletions .github/scripts/all_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
"""
Makes sure:
* All jobs are listed in the 'all' job
* Only existing tests are listed
"""

# SPDX-FileCopyrightText: 2022 Google LLC
#
# SPDX-License-Identifier: Apache-2.0

import sys
import yaml

CI_PATH = ".github/workflows/ci.yml"
ALL_TEST = "all"

def main():
ci_yml_fp = open(CI_PATH, "r")
ci_yml_parsed = yaml.load(ci_yml_fp, Loader=yaml.FullLoader)

all_jobs = set(ci_yml_parsed['jobs'].keys()) - {ALL_TEST}
all_needs = set(ci_yml_parsed["jobs"][ALL_TEST]["needs"])

if all_jobs - all_needs:
sys.exit(f"Not all jobs mentioned in {ALL_TEST}.needs: {all_jobs - all_needs}")

if all_needs - all_jobs:
sys.exit(f"Non-existing jobs found in {ALL_TEST}.needs: {all_needs - all_jobs}")


if __name__ == '__main__':
main()
57 changes: 51 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v2
uses: fsfe/reuse-action@v4


rust-checks:
Expand Down Expand Up @@ -96,11 +96,23 @@ jobs:
cd clash-vexriscv-sim; sh bundle_test_binaries.sh
- name: Upload Integration Test Binaries
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: vexriscv-test-binaries
path: clash-vexriscv-sim/vexriscv-test-binaries.tar

c-checks:
name: C checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: clang-format check
uses: jidicula/clang-format-action@v4.14.0
with:
clang-format-version: 16
check-path: '.'

vex-riscv:
name: VexRiscv integration
Expand All @@ -117,7 +129,7 @@ jobs:
- "9.6.6"

container:
image: ghcr.io/clash-lang/clash-vexriscv-ci:${{ matrix.ghc }}-20240823
image: ghcr.io/clash-lang/clash-vexriscv-ci:${{ matrix.ghc }}-20241214

steps:
- name: Checkout
Expand All @@ -129,7 +141,7 @@ jobs:
cabal update
cabal freeze
- name: Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
~/.local/state/cabal/store/
Expand All @@ -151,7 +163,7 @@ jobs:
cabal build clash-vexriscv-sim
- name: Download VexRiscv Integration Tests
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: vexriscv-test-binaries

Expand All @@ -165,7 +177,7 @@ jobs:
- name: OpenOCD bin symlink
run: |
ln -s /opt/bin/openocd /opt/bin/openocd-vexriscv
ln -s /opt/bin/openocd /opt/bin/openocd-riscv
- name: Run `clash-vexriscv` unittests
run: |
Expand All @@ -179,3 +191,36 @@ jobs:
- name: Run `clash-vexriscv-sim` HDL test
run: |
cabal run clash-vexriscv-sim:hdl-test
all:
name: All jobs finished
if: ${{ !cancelled() }}
needs: [
'license-check',
'rust-checks',
'vex-riscv',
'rust-build-programs'
]
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check dependencies for failures
run: |
# Test all dependencies for success/failure
set -x
success="${{ contains(needs.*.result, 'success') }}"
fail="${{ contains(needs.*.result, 'failure') }}"
set +x
# Test whether success/fail variables contain sane values
if [[ "${success}" != "true" && "${success}" != "false" ]]; then exit 1; fi
if [[ "${fail}" != "true" && "${fail}" != "false" ]]; then exit 1; fi
# We want to fail if one or more dependencies fail. For safety, we introduce
# a second check: if no dependencies succeeded something weird is going on.
if [[ "${fail}" == "true" || "${success}" == "false" ]]; then
echo "One or more dependency failed, or no dependency succeeded."
exit 1
fi
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,9 @@ simulation_dump.vcd

# Clash output
verilog

# Metals vscode extension
.metals

# Scala
.scala-build
44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ well as a black-box for Verilog synthesis.
The core interfaces with other components via [Wishbone](https://cdn.opencores.org/downloads/wbspec_b4.pdf)
interfaces, using [`clash-protocols`](https://github.com/clash-lang/clash-protocols) types.

## Building
## Building the project

For building the CPU, the following software needs to be installed and available in the `PATH`:

Expand All @@ -29,11 +29,51 @@ For building the CPU, the following software needs to be installed and available
- `verilator`, at least version 5.001 (development version at time of writing)
- `make` for building the verilated library and FFI code

## Notes for using the core
### Notes for using the core

- VexRiscv has a "reset vector" for the instruction bus. This is the initial PC that gets fetched.
This address only gets presented to the IBUS after at least one cycle of RST being asserted.

- The contents of memories need to be stored in little endian. This means that for example the
contents of an ELF file need to be endian-swapped before being used as the contents of the
instruction storage. This applies to all storages.
___

# Continuous Integration Setup

The Continuous Integration (CI) flow for this project is defined in the `ci.yml` file. The CI has the following goals:
* Verify that the project builds successfully.
* Prevent warnings and errors in the codebase.
* Ensure functional correctness by running tests.
* Ensure code quality by running linters and formatters.

CI uses a separate cabal project file that turns warnings into errors.

### Building and Pushing the Docker Image

To build the Docker image for this project, follow these steps:

1. Navigate to the docker directory:
```sh
cd .github/docker
```

2. Run the `build-and-publish-docker-image.sh` script:
```sh
./build-and-publish-docker-image.sh
```

This script builds the Docker image using the specified Ubuntu and GHC versions. It also installs the necessary dependencies and tools required for the project.

### Authentication for Pushing to GitHub

If you have an authentication token, you can use `docker login <repo_url>` to log in using your docker username and token as password.

If you don't have an authentication token, you can request the maintainers to build and push the image. Please email [devops@qbaylogic.com](mailto:devops@qbaylogic.com) with the following information:
- Repository
- Commit hash
- Branch name

## Additional Support

For other problems or questions, please refer to one of the communication channels listed on [clash-lang.org](https://clash-lang.org).
4 changes: 2 additions & 2 deletions clash-vexriscv-sim/app/VexRiscvChainSimulation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ getRunOpts = RunOpts
)

jtagDaisyChain :: JtagIn -> JtagOut -> JtagIn
jtagDaisyChain (JtagIn tc ms _) (JtagOut to _) = JtagIn tc ms to
jtagDaisyChain (JtagIn tc ms _) (JtagOut to _ _) = JtagIn tc ms to

type CpuSignals =
( CpuOut
Expand Down Expand Up @@ -120,7 +120,7 @@ main = do

_jtagReset = L.foldl (liftA2 go1) (pure False) [jtagOutA, jtagOutB]
where
go1 acc (JtagOut _ tr) = acc || bitToBool tr
go1 acc (JtagOut _ _ tr) = acc || bitToBool tr

cpuOut = bundle (cpuOutA, cpuOutB)

Expand Down
25 changes: 10 additions & 15 deletions clash-vexriscv-sim/data/vexriscv_chain_sim.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Execute using:
#
# openocd-vexriscv -f vexriscv_sim_chain.cfg
# openocd-riscv -f vexriscv_sim_chain.cfg
#

# SPDX-FileCopyrightText: 2024 Google LLC
Expand All @@ -9,32 +9,27 @@

# See vexriscv_sim.cfg for more information on each step taken.

adapter driver jtag_tcp
adapter speed 64000
adapter driver remote_bitbang
transport select jtag

remote_bitbang host 127.0.0.1
remote_bitbang port 7894

set _ENDIAN little
set _TAP_TYPE 1234

if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x10001fff
set _CPUTAPID 0x10002FFF
}

set _CHIPNAME vexrisc_ocd

jtag newtap $_CHIPNAME chain0 -expected-id $_CPUTAPID -irlen 4 -ircapture 0x1 -irmask 0x0F
jtag newtap $_CHIPNAME chain1 -expected-id $_CPUTAPID -irlen 4 -ircapture 0x1 -irmask 0x03
set _CHIPNAME riscv

target create $_CHIPNAME.cpu0 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain1
vexriscv readWaitCycles 10
vexriscv cpuConfigFile clash-vexriscv/example-cpu/ExampleCpu.yaml
jtag newtap $_CHIPNAME chain0 -expected-id $_CPUTAPID -irlen 5
jtag newtap $_CHIPNAME chain1 -expected-id $_CPUTAPID -irlen 5

target create $_CHIPNAME.cpu1 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain0
vexriscv readWaitCycles 10
vexriscv cpuConfigFile clash-vexriscv/example-cpu/ExampleCpu.yaml
target create $_CHIPNAME.cpu0 riscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain1
target create $_CHIPNAME.cpu1 riscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain0

poll_period 50

Expand Down
33 changes: 8 additions & 25 deletions clash-vexriscv-sim/data/vexriscv_sim.cfg
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# Execute using:
#
# openocd-vexriscv -f vexriscv_sim.cfg
# openocd-riscv -f vexriscv_sim.cfg
#

# SPDX-FileCopyrightText: 2024 Google LLC
#
# SPDX-License-Identifier: CC0-1.0

adapter driver jtag_tcp
adapter speed 64000
adapter driver remote_bitbang
transport select jtag

remote_bitbang host 127.0.0.1
remote_bitbang port 7894

set _ENDIAN little
set _TAP_TYPE 1234
Expand All @@ -19,36 +18,20 @@ if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
# set useful default
set _CPUTAPID 0x10001fff
set _CPUTAPID 0x10002FFF
}

set _CHIPNAME vexrisc_ocd
set _CHIPNAME riscv

# The JTAG TAP itself is given the name "bridge", because it refers to the
# JtagBridge that's part of the VexRiscv/SpinalHDL debug infrastructure.
# In the example design, there is the JtagBridge controls a single CPU, but
# the capability is there for 1 JTAG TAP + JtagBridge to control multiple
# VexRiscv CPUs.
jtag newtap $_CHIPNAME bridge -expected-id $_CPUTAPID -irlen 4 -ircapture 0x1 -irmask 0xF
jtag newtap $_CHIPNAME bridge -expected-id $_CPUTAPID -irlen 5

# There is 1 CPU controlled by the "bridge" JTAG TAP, "cpu0"
target create $_CHIPNAME.cpu0 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.bridge

# The JtagBridge/SystemDebugger receives commands in a serialized way. It gets synchronized into
# a parallel bus, and a response is received. Along the way, there may be various clock domain
# crossings or pipeline delays.
# readWaitCycles instructs OpenOCD to insert idle JTAG clock cycles before shifting out
# the response.
# There aren't many transactions where read-back throughput is important, so there's little
# points in lowballing this number.
vexriscv readWaitCycles 10

# When the Verilog of a SpinalHDL design with one or more VexRiscv CPUs is created, the system
# also creates a .yaml file with information that's sideband information that's important for
# OpenOCD to control the CPU correctly.
# A good example of this are the number of hardware breakpoints that are supported by the CPU.
vexriscv cpuConfigFile clash-vexriscv/example-cpu/ExampleCpu.yaml

target create $_CHIPNAME.cpu0 riscv -endian $_ENDIAN -chain-position $_CHIPNAME.bridge
# The rate at which OpenOCD polls active JTAG TAPs to check if there has been a notable
# event. (E.g. to check if the CPU has hit a breakpoint.)
# For some reason, making this number really low has an impact on the CPU while semihosting is
Expand Down
2 changes: 1 addition & 1 deletion clash-vexriscv-sim/src/Utils/Cpu.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cpu dumpVcd jtagIn0 bootIMem bootDMem =

jtagReset =
unsafeFromActiveHigh $ register False $
bitToBool . debugReset <$> jtagOut
bitToBool . ndmreset <$> jtagOut

jtagIn1 = fromMaybe (pure JTag.defaultIn) jtagIn0

Expand Down
Loading

0 comments on commit bacc4f2

Please sign in to comment.