For a while, LXC (linux container) technology might have been known for the better chroot. Docker takes this approach even further by letting you mess with changes and undo them easily. You can just install foreign binaries and play with dependencies without compromising your desktop host’s runtime libraries. This article describes how to easily put commercial FPGA toolchains into a docker environment and carry them around on an external hard disk for quick installation on a new developer machine.
Lattice Diamond
The Lattice Diamond toolchain comes as RPM package and is recommended to be run under a Redhat OS. It is possible to convert to a DEB and install and run it on a Debian system likewise, but we try basing it on a minimal RPM compatible environment as an existing CentOS container.
This short howto describes the necessary steps for Diamond v3.10 (older versions work likewise):
First create a file called Dockerfile, like:
FROM centos RUN yum update ; \ yum install -y freetype libSM libXrender fontconfig libXext libXt \ tcl tcsh perl libXft xorg-x11-fonts-Type1 net-tools \ libXScrnSaver-1.2.2 \ libusb-0.1.4 usbutils RUN adduser -u 1000 -g 100 diamond; echo ". env-setup.sh" >> /home/diamond/.bashrc COPY env-setup.sh /home/diamond ENTRYPOINT ["/bin/bash"]
You could automate things more by copying the RPM into the docker container, but that would just take useless space in the image (and stripping this back down would take extra action). Therefore we mount the directory where the RPM was downloaded to into the container. Unfortunately, there is no clean way to pull it from an official source the wget way.
You may have to sort out permissions first (by adding yourself to the ‘docker’ group) or prepend ‘sudo’ to each docker call.
The env-setup.sh is a small setup script needed to initialize the environment:
DIAMOND_DIR=/usr/local/diamond/3.10_x64 export DISPLAY=:0.0 bindir=$DIAMOND_DIR/bin/lin64 export QT_GRAPHICSSYSTEM=native source $bindir/diamond_env export LM_LICENSE_FILE=$HOME/license.dat
Building the container
- Change UID and GID for adduser command in the Dockerfile, if necessary
- Run
docker build -t diamond .
- Then you can start the docker container using the following command. Note you have to replace $ETHADDR by the ethernet MAC address you have registered your license.dat to. Also, make $PATH_TO_RPM_INSTALLDIR point to the directory where the downloaded RPM resides.
docker run -ti -e DISPLAY=:0 \ --mac-address=$ETHADDR \ --privileged --ipc host \ -v $PATH_TO_RPM_INSTALLDIR:/mnt \ -v /dev/bus/usb/:/dev/bus/usb/ \ -v /tmp/.X11-unix/:/tmp/.X11-unix diamond:latest
- Then install diamond by
rpm -i /mnt/diamond_3_10-base_x64-111-2-x86_64-linux.rpm
- You still need to copy your license.dat into your /home/diamond/ directory within the docker container. If it’s supposed to be elsewhere, edit the LM_LICENSE_FILE environment variable in env-setup.sh.
- Then you should be able to start the diamond GUI as user ‘diamond’:
su -l diamond diamond
- Finally, if you are happy with your changes, you might want to commit everything to a new image:
docker commit -m "Diamond install" $HASH_OF_YOUR_CONTAINER diamond:v3.10
A few notes
The -v option takes care about sharing your X11 sockets with the docker sandbox. Note that there also some options inside the env-setup.sh to make QT work in this limited environment. Don’t try to run Diamond as root, as the X11 forwarding will not be allowed.
Lattice iCEcube2
The iCEcube2 2017.0.8 release includes a mix of 32 and 64 bit binaries, therefore requires installation of the i686 variants of some libraries. The minimal Dockerfile would here look as follows:
FROM centos RUN yum update ; \ yum install -y libXext libpng libSM libXi libXrender libXrandr \ libXfixes libXcursor libXinerama freetype fontconfig # 32 bit support: RUN yum install -y glibc.i686 glib2.i686 \ zlib.i686 libXext.i686 libpng12.i686 \ libSM.i686 libXrender.i686 libXfixes.i686 libXrandr.i686 \ libXcursor.i686 freetype.i686 fontconfig.i686 RUN adduser -u 1000 -g 100 icecube2 ENTRYPOINT ["/bin/bash"]
Run the iCEcube2 installer binary obtained from latticesemi.com as user icecube2 and select the license file you have registered via the /mnt directory from your host OS.
Xilinx ISE
The same procedure works for the ISE 14.7 toolchain. The Dockerfile in this case is almost similar, although includes a few X11 extras.
FROM centos RUN yum update ; \ yum install -y freetype libSM libXrender fontconfig libXext \ tcl xorg-x11-fonts-Type1 net-tools libXScrnSaver-1.2.2 \ libXi libXrandr \ libusb-0.1.4 usbutils RUN adduser -u 1000 -g 100 ise; echo ". env-setup.sh" >> /home/ise/.bashrc COPY env-setup.sh /home/ise ENTRYPOINT ["/bin/bash"]
Downloading and unpacking ISE
Make sure you have downloaded the following files from the Xilinx website:
Xilinx_ISE_DS_14.7_1015_1-1.tar
Xilinx_ISE_DS_14.7_1015_1-2.zip.xz
Xilinx_ISE_DS_14.7_1015_1-3.zip.xz
Xilinx_ISE_DS_14.7_1015_1-4.zip.xz
Then untar the first one by
> tar xf Xilinx_ISE_DS_14.7_1015_1-1.tar
This directory path will have to be exported to docker under $PATH_TO_UNPACKED_XILINX_TAR below.
The env-setup.sh file:
#!/bin/bash export DISPLAY=:0.0 XILINXDIR=/opt/Xilinx/14.7/ISE_DS . $XILINXDIR/settings64.sh alias ise=$XILINXDIR/ISE/bin/lin64/ise
Likewise, the docker container is run by something like:
docker run -ti -e DISPLAY=:0 \ --mac-address=$ETHADDR \ --privileged --ipc host \ -v $PATH_TO_UNPACKED_XILINX_TAR:/mnt \ -v /dev/bus/usb/:/dev/bus/usb/ \ -v /tmp/.X11-unix/:/tmp/.X11-unix ise:latest
Once you’re inside docker, install as root by running /mnt/xsetup. This may take a long time. Left to do:
- Install a license file
- Mess with the USB drivers for Impact. This is left open to the user. I am using xc3sprog from my host system.
Thanks for these notes.
Your container setup does not support the programer though.
I have fiddled about a little.
You have to start your container with other option to expose usb devices:
-v /dev/bus/usb/:/dev/bus/usb/
Then you need libusb dependancy:
# yum install libusb-0.1.4 usbutils
Also in host OS you must give access to /dev/bus/usb/../.. device (check lsusb) and remove ftdi_sio module in host OS:
> sudo rmmod ftdi_sio
Thanks.
I’ve updated these.
If you want to use the programmer and UART I/O from your design, like possible on some boards like MACHXO2 breakout, etc., you may also just run an “unbind” command, like:
echo -n 1-3.2:1.0 > /sys/bus/usb/drivers/ftdi_sio/unbind
to get rid of /dev/ttyUSB0, selectively.
Looks like this is missing the env-setup.sh for Lattice?
Fixed that, thanks!
Hi.
Am new to docker but would like to create a lattice diamond 3.10 docker image to allow it to run in debain (MInt). As I have Qt compatibility issues after converting to .deb
Can you recommend any resources for a novice introduction to docker and a tutorial on building docker images?
Hi Martin,
I’ve been following the official docker.com docs. Didn’t bother looking for more. I think you could sort out the Qt issues for 3.10 from the Doxyfile provided for the v3.9 diamond release, likewise. Good luck!
For Lattice Diamond 3.10, tcsh and perl are needed. So add
yum install tcsh perl
Hi,
My Xilinx ISE container has as size of 28 GB after installation. Can anyone tell me how this size can be reduced?
The typical default installation for the latest ISE14.7 has around 18 GB (see also `du -sm /opt/Xilinx`). It is possible to strip some stuff (like support for unused FPGA families or coregen IP) and export/reimport an image with reduced size according to the official docker documentation.
Unfortunately this does not work. ISE seems to expect the data for all families even if they are not used. I tried to open a project for Spartan6 and ISE throws an error: ERROR:PersonalityModule:7 – Unable to open Xilinx data file for Vendor/Device
Module “virtex2”. Please make sure that it has been correctly installed
before continuing.
My Diamond Container is not able to detect any Lattice Cable, neither an original Lattice programmer nor an on-board FTDI chip. Can anyone tell me how I can make this work?
@M Strubel Thanks for the hint!
I was able to connect to connect to Lattice programmer and on-board FTDI after unloading the ftdi_sio kernel module. However, Lattice Programmer does not detect FTDI chips with a changed Product/Vendor ID, which is no problem on Windows. Does anyone have any idea how to fix this?
@Philip: You might want to check this one:
https://www.eevblog.com/forum/fpga/lattice-diamond-v-3-11-on-linux-problem-with-ftdio_sio/
Addendum: see also https://github.com/Gekkio/docker-fpga for ‘maintained future’.
Please understand that I lack the resources for further maintenance, so I can not help you via Email and questions may be left unanswered.