Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aji_openocd: OpenOCD with virtual JTAG for Quartus #37

Merged
merged 8 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ updates:
directory: "/quartus-prime"
schedule:
interval: "weekly"
directory: "/quartus-prime-aji"
schedule:
interval: "weekly"

16 changes: 13 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@ on:
workflow_dispatch:

env:
# Names of container images for their respective registries. (Space separated)
dockerhub: "esp-idf-qemu android-ci"
github: "speki-ci tanks-ci vhdl_rpn-ci tdd-platform zephyr-dev zephyr-fuzz quartus-prime"
# Names of container images for their respective registries.
dockerhub:
esp-idf-qemu
android-ci
github:
speki-ci
tanks-ci
vhdl_rpn-ci
tdd-platform
zephyr-dev
zephyr-fuzz
quartus-prime
quartus-prime-aji

jobs:

Expand Down
64 changes: 64 additions & 0 deletions quartus-prime-aji/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
FROM ubuntu:18.04 as openocd_builder

# Install neccessary tools and dependencies, libaji_client and aji_openocd use
# old compiler flags that are incompatible with gcc > 8.
RUN apt-get -q -y update \
&& apt-get -q -y install \
autoconf automake m4 libtool pkg-config texinfo \
make gcc-8 g++-8 \
git \
libusb-1.0-0-dev libftdi-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& update-alternatives \
--install /usr/bin/gcc gcc /usr/bin/gcc-8 60 \
--slave /usr/bin/g++ g++ /usr/bin/g++-8 \
&& update-alternatives --config gcc

# Clone, configure and build libaji_client
# The library has -Werror enabled and has warnings that we cant fix, the below
# sed commands fix the hard errors to just warnings.
ARG LIBAJI_CLONE_URL=https://github.com/intel/libaji_client.git
ARG LIBAJI_CLONE_TAG=R22.4
RUN git clone $LIBAJI_CLONE_URL -b $LIBAJI_CLONE_TAG --depth 1 \
&& cd libaji_client \
&& ./bootstrap \
&& ./configure \
&& sed -i 's/# error/\/\/# error/g' ./src/h/aji_macros_sys.h \
&& sed -i 's/-Werror / /g' ./Makefile \
&& sed -i 's/-Werror / /g' ./src/jtag/Makefile \
&& make \
&& cd ..

# Clone, configure and build aji_openocd
#
# The aji fork uses C++ and as such the OpenOCD link step needs to happen with
# g++ instead of gcc. The following removes unsupported gcc compiler flags from
# the makefiles, then builds the project once. The build will fail during
# linking. A second make invocation then actually links with g++. If the project
# is not (partly) compiled already make seems to call configure to fix the
# makefile. So changing the linker and builing in one go is not possible.
ARG AJI_OPENOCD_CLONE_URL=https://github.com/intel/aji_openocd.git
ARG AJI_OPENOCD_CLONE_TAG=R22.4
RUN git clone $AJI_OPENOCD_CLONE_URL -b $AJI_OPENOCD_CLONE_TAG --depth 1 \
&& cd aji_openocd \
&& ./bootstrap \
&& ./configure --enable-aji_client --enable-usb-blaster \
&& cp ./../libaji_client/src/jtag/.libs/libaji_client.a ./src/ \
&& sed -i 's/-fstack-clash-protection / /g' ./src/jtag/drivers/aji_client/Makefile.am \
&& sed -i 's/-fstack-clash-protection / /g' ./src/jtag/drivers/aji_client/aji/Makefile.am \
&& make || true \
&& sed -i 's/CCLD = \$(CC)/CCLD = g++/g' ./Makefile \
&& make

# Import built openocd into quartus prime container.
FROM ghcr.io/nikleberg/quartus-prime:latest
COPY --from=openocd_builder /aji_openocd/src/openocd /opt/aji_openocd/
COPY --from=openocd_builder /aji_openocd/tcl /opt/aji_openocd/tcl

# Install additional required packages for USB FTDI JTAG support
RUN apt-get -q -y update \
&& apt-get -q -y install \
libusb-1.0-0 libftdi-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
56 changes: 56 additions & 0 deletions quartus-prime-aji/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# quartus-prime-aji
Extenstion to the [`quartus-prime`](../quartus-prime/README.md) image with AJI virtual JTAG infrastructure and OpenOCD. It allows to use this virtual JTAG system with OpenOCD for example to debug IP Cores in the FPGA.

This container contains the following:
* Everything from `quartus-prime`
* [OpenOCD](https://github.com/intel/aji_openocd) fork that enables aji

## What is AJI?
AJI stands for Altera Virtual JTAG Interface. It enables the extenstion of the physical JTAG chain with ore or multiple virtual JTAG chains inside the FPGA fabric. This is extensively used for Altera's own products like _Signal Tap Logic Analyzer_ or _NIOS II Debugger_. But by instanciating the [`sld_virtual_jtag`](https://cdrdv2-public.intel.com/666577/ug_virtualjtag-683705-666577.pdf) entity one can extend this with custom JTAG TAPs. The required System Level Debug (SLD) infrastructure is then automatically instantiated when synthesizing with quartus. See the excellent [blog](https://tomverbeure.github.io/2021/05/02/Intel-JTAG-UART.html#the-intels-virtual-jtag-system) of tomverbeure for more in depth explanation.

## Usage
For general usage see [readme](../quartus-prime/README.md) of `quartus-prime` image.

To access the _USB Blaster_ hardware we need to forward the USB tree to the docker container. We do this by mounting the full `/dev` tree and giving it privileged access. One could also only map the specific USB device but this would not survive a un-plug / re-plug.
Forwarding can be done with the following run flags:
```shell
docker run --privileged -v /dev/bus/usb:/dev/bus/usb ghcr.io/nikleberg/quartus-prime-aji
```

Inside the container you need to start the jtag server of quartus before you can connect with OpenOCD. The quartus programmer uses the same server, so either start the programmer after which the server will live on for about ~2 mins, or start the server manually with the below command. The server should stay around and allow every access from the local host (e.g. OpenOCD).
```shell
jtagd
```

To check if the USB Blaster is detected correctly run the following command:
```shell
jtagconfig --enum
```
It should output the detected cable name and the attached FPGA. Something like so:
```
root@quartus-prime-aji:~# jtagconfig --enum
1) USB-Blaster [1-1]
020F20DD 10CL016(Y|Z)/EP3C16/EP4CE15
```

After that you can start OpenOCD and connect to the virtual JTAG inside the FPGA. OpenOCD expects a script with name `openocd.cfg` in the current directory. Alternatively you can specify the exact script file to run with the `-f` flag.
```bash
/opt/aji_openocd/openocd -f <script.cfg>
```
See the example script [`neorv32.cfg`](neorv32.cfg) that sets this up for the excellent [NEORV32](https://github.com/stnolting/neorv32) soft core running on a Cyclone IV E. Or have a look at the Intel examples in `/opt/aji_openocd/tcl/boards` where you find `altera_arria10__aji_client.cfg` and `altera_arria10_niosv__aji_client.cfg`.

OpenOCD now exposes a GDB server on port `3333` (default) and you may debug the soft core if you have specified it. Alternatively if you only have simple IR / DR registers in your virtual JTAG TAP you can access them with the lowlevel JTAG commands `irscan` and `drscan` in OpenOCD. See [here](https://openocd.org/doc-release/html/JTAG-Commands.html) for documentation.

## Additional Information
Note that OpenOCD was only compiled with AJI support. All other adapters (USB, FTDI, etc.) are not compiled in.

To debug the enumeration of virtual SLD JTAG TAPs there is the `system-console` that lists the detected endpoints. To use it you need to install an additional package beforehand:
```bash
apt update
apt install libxi-dev
$QUARTUS_ROOTDIR/quartus/sopc_builder/bin/system-console
```
In the left side of the window in the _System Explorer_ expand _devices_ > \<FPGA type\> > _(link)_ > _JTAG_. There you find the SLD nodes that are described within in the FPGA.

## License
[MIT](./../LICENSE) © [NikLeberg](https://github.com/NikLeberg).
8 changes: 8 additions & 0 deletions quartus-prime-aji/pre_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

# https://stackoverflow.com/questions/51903877/docker-load-no-space-left-on-device-rhel
docker system prune -a -f --volumes

# Skip Trivy and Dockle scan steps, image needs too much disk space.
echo "trivy_skip=skip" >> $GITHUB_OUTPUT
echo "dockle_skip=skip" >> $GITHUB_OUTPUT