ghdl / docker

Scripts to build and use docker images including GHDL
40 stars 10 forks source link

Add nextpnr ECP5 images #22

Closed antonblanchard closed 4 years ago

antonblanchard commented 4 years ago

This is a first pass at nextpnr ECP5. I haven't hooked it into the build system yet. I presume we need a separate nextnpr binary for each target but I haven't looked closely.

It's also a separate Docker image to the ICE40, I wonder if we want to just merge them all into one.

eine commented 4 years ago

This is a first pass at nextpnr ECP5. I haven't hooked it into the build system yet.

I took your commit and merged the code into the existing dockerfiles/cache_pnr. We use DOCKER_BUILDKIT=1, so there is no harm in having independent build stages in the same file; a DAG is computed and the required ones are executed only. I pushed it to https://github.com/ghdl/docker/tree/nextpnr-ecp5. I tried to force push this PR, but I don't have permissions to do so.

I presume we need a separate nextnpr binary for each target but I haven't looked closely.

According to Additional notes for building nextpnr, we can use -DARCH=all to build all the supported architectures (I assume that it means ice40 and ecp5 and generic). I don't know if it's possible to set -DARCH=ice40,ecp5.

It's also a separate Docker image to the ICE40, I wonder if we want to just merge them all into one.

Right now we duplicate the build stages and the final images; but, surprisingly, the image for ECP5 only is smaller than the image for ICE40 only.

Hence, I was unnecessarily worried about deps for ECP5 being much larger than the existing image. I believe we should build a single target that supports both architecture families and distribute a single image. This might change when Xilinx's 7 Series devices are supported, but that's not something we need to worry about now.


According to Getting Started, "Recent OpenOCD for device programming (--enable-ftdi required if building from source)" is required. However, in this PR, libftdi1-2 usbutils are installed in stage prjtrellis (which is not published ATM). This is me thinking loud:

@antonblanchard, overall:

I have successfully programmed an Icestick with ghdl/synth:icestorm using iceprog, which depends on libftdi. I'd like to know if a similar procedure works/is required for ECP5 boards.


prjtrellis in stage prjtrellis-build seems to be succesfully built if packages g++ libffi-dev libftdi1-dev pkg-config are removed and clang is added. I'm confident about replacing g++ with clang. What about other packages?

If programming ECP5 boards requires the same packages as icestorm plus OpenOCD, I think we might distribute a single image for programming boards, say ghdl/synth:prog. Otherwise, ghdl/synth:trellis should include the minimal set of tools to program a device given the output of nextpnr from a different container.

eine commented 4 years ago

According to Additional notes for building nextpnr, we can use -DARCH=all to build all the supported architectures (I assume that it means ice40 and ecp5 and generic). I don't know if it's possible to set -DARCH=ice40,ecp5.

The syntax is -DARCH=ice40;ecp5: https://github.com/YosysHQ/nextpnr/issues/383#issuecomment-575060499

I believe we should build a single target that supports both architecture families and distribute a single image. This might change when Xilinx's 7 Series devices are supported, but that's not something we need to worry about now.

In the end, I decided to keep three images: nextpnr-ice40, nextpnr-ecp5 and nextpnr (all). I don't think it is worth having one with ICE40 and ECP5 but not generic. Users worried about the size can already use one of the available images.


If programming ECP5 boards requires the same packages as icestorm plus OpenOCD, I think we might distribute a single image for programming boards, say ghdl/synth:prog. Otherwise, ghdl/synth:trellis should include the minimal set of tools to program a device given the output of nextpnr from a different container.

iceprog can now be optionally built in icestorm. Hence, I created a new ghdl/synth:prog image and ghdl/synth:icestorm does not include it. ghdl/synth:prog needs to be extended to support ECP5 boards yet (see comment above).


All this WIP is in branch pnr-ecp5 (the README is updated accordingly).

antonblanchard commented 4 years ago

According to Additional notes for building nextpnr, we can use -DARCH=all to build all the supported architectures (I assume that it means ice40 and ecp5 and generic). I don't know if it's possible to set -DARCH=ice40,ecp5.

The syntax is -DARCH=ice40;ecp5: YosysHQ/nextpnr#383 (comment)

Good to know.

In the end, I decided to keep three images: nextpnr-ice40, nextpnr-ecp5 and nextpnr (all). I don't think it is worth having one with ICE40 and ECP5 but not generic. Users worried about the size can already use one of the available images.

Great! I tested with both the nextpnr and nextpnr-ecp5 images. Both look good! FYI I have a couple of ECP5 boards, so can test that the LEDs actually blink with ghdl-yosys-blink :)

If programming ECP5 boards requires the same packages as icestorm plus OpenOCD, I think we might distribute a single image for programming boards, say ghdl/synth:prog. Otherwise, ghdl/synth:trellis should include the minimal set of tools to program a device given the output of nextpnr from a different container.

iceprog can now be optionally built in icestorm. Hence, I created a new ghdl/synth:prog image and ghdl/synth:icestorm does not include it. ghdl/synth:prog needs to be extended to support ECP5 boards yet (see comment above).

All this WIP is in branch pnr-ecp5 (the README is updated accordingly).

It looks like the trellis image needs a libboost library:

ecppack: error while loading shared libraries: libboost_python37.so.1.67.0: cannot open shared object file: No such file or directory

Thanks for doing this, it makes using all the tools so much easier.

eine commented 4 years ago

Great! I tested with both the nextpnr and nextpnr-ecp5 images. Both look good!

Note that I didn't push these changes to master yet. Since we have scheduled/cron jobs set up, image nextpnr is likely to be "downgraded" and "updated" kind of randomly. Fortunately, using image nextpnr-ecp5 is safe.

FYI I have a couple of ECP5 boards, so can test that the LEDs actually blink with ghdl-yosys-blink :)

Good! I tried to add ghdl-yosys-blink to the workflow (as a sanity test). See test_pnr.sh. It is failing because of -i -t arguments to docker: https://github.com/ghdl/docker/runs/394711459#step:5:3526. This is because TTY is not supported in GitHub Actions environments. Anyway, in the context of a Makefile, those are not useful (except to get coloured output automatically, actions/runner#241). Would mind removing those args or making them optional?

Some unrelated comments/suggestions that apply to ghdl-yosys-blink (or any other project where you might use these images):

It looks like the trellis image needs a libboost library:

ecppack: error while loading shared libraries: libboost_python37.so.1.67.0: cannot open shared object file: No such file or directory

I now added libboost-all-dev to image trellis. That will hopefully fix it. However, that's the same package that is installed in the build image. Ideally, there should be a (smaller) package with runtime dependencies only. For example, there are libomp-dev and libomp5-7. Are you aware of any other package (or set of packages) that we can use instead of libboost-all-dev. Note that this is not only for trellis, but also for images nextpnr, nextpnr-ice40 and nextpnr-ecp5, since all of them depend on boost.

Apart of that, what about openocd?

https://github.com/antonblanchard/ghdl-yosys-blink/blob/81bc90f2bf9f3425939640342b8c07a917625f59/Makefile#L50-L51

That would fit in image prog. Did you install it from sources?

Thanks for doing this, it makes using all the tools so much easier.

I'm so glad to know that these images are useful! Unfortunately, that hardware community is lagging behind with regard to OCI usage adoption; but I hope that these or other similar images will be useful for new users as the technology spreads (podman, buildkit, WSL2 supported on Windows Home...). Currently, containers seem to be associated to docker and kubernetes, which kind of hides how useful they are for local development/testing with rapidly evolving tools.

BTW, it is possible to use dbhi/qus to build docker images for foreign architectures. For example, in dbhi/docker, GHDL, GtkWave, Octave, etc. are built for amd64, arm and arm64. Each of them is published as a separate image, and a multi-arch manifest is available too.

antonblanchard commented 4 years ago

Good! I tried to add ghdl-yosys-blink to the workflow (as a sanity test). See test_pnr.sh. It is failing because of -i -t arguments to docker: https://github.com/ghdl/docker/runs/394711459#step:5:3526. This is because TTY is not supported in GitHub Actions environments. Anyway, in the context of a Makefile, those are not useful (except to get coloured output automatically, actions/runner#241). Would mind removing those args or making them optional?

Done. I also switched it to default to docker because I presume most people have that and not podman.

Some unrelated comments/suggestions that apply to ghdl-yosys-blink (or any other project where you might use these images):

Great, I removed the absolute path.

I do :) I got one directly from Greg who is currently working on a second revision. Hopefully it will be available sometime. I've been told the ULX3S is nice but it doesn't seem to be available either.

I now added libboost-all-dev to image trellis. That will hopefully fix it. However, that's the same package that is installed in the build image. Ideally, there should be a (smaller) package with runtime dependencies only. For example, there are libomp-dev and libomp5-7. Are you aware of any other package (or set of packages) that we can use instead of libboost-all-dev. Note that this is not only for trellis, but also for images nextpnr, nextpnr-ice40 and nextpnr-ecp5, since all of them depend on boost.

We should be able to install the specific boost images instead of the catch all one. If I get a chance I'll take a look.

Apart of that, what about openocd?

https://github.com/antonblanchard/ghdl-yosys-blink/blob/81bc90f2bf9f3425939640342b8c07a917625f59/Makefile#L50-L51

That would fit in image prog. Did you install it from sources?

I'm just using the Fedora 31 installed version of openocd. I presume any recentish version of openocd would work. I wonder how well a docker image of it would work, we'd need to connect the JTAG USB device to the container.

I'm so glad to know that these images are useful! Unfortunately, that hardware community is lagging behind with regard to OCI usage adoption; but I hope that these or other similar images will be useful for new users as the technology spreads (podman, buildkit, WSL2 supported on Windows Home...). Currently, containers seem to be associated to docker and kubernetes, which kind of hides how useful they are for local development/testing with rapidly evolving tools.

I did wonder if I should convert to a build system which is Windows compatible (cmake, meson?). I don't have much experience here.

BTW, it is possible to use dbhi/qus to build docker images for foreign architectures. For example, in dbhi/docker, GHDL, GtkWave, Octave, etc. are built for amd64, arm and arm64. Each of them is published as a separate image, and a multi-arch manifest is available too.

Very nice!

eine commented 4 years ago

Done. I also switched it to default to docker because I presume most people have that and not podman.

Yes, I think it is interesting because podman is not available on Windows yet. Hence, users of Docker for Windows or WSL are likely to use/require docker yet.

We should be able to install the specific boost images instead of the catch all one. If I get a chance I'll take a look.

Cool. Note that this does not affect any of the features we provide; it'd just be an interesting enhancement. Hence, rather than trying to guess it ourselves, it'd be ok to just remember to ask it whenever we get the chance to talk to someone who is used to developing with boost.

I'm just using the Fedora 31 installed version of openocd. I presume any recentish version of openocd would work. I wonder how well a docker image of it would work, we'd need to connect the JTAG USB device to the container.

Yes, the USB device needs to be shared between the host and the container. On GNU/Linux, this is straightforward, as you just share it with -v (like any other directory or volume). Then, the container works as it would natively. I have successfully done this with FTDI devices (say Icestick).

The same approach works on Windows. However, HyperV (the hypervisor where VMs are executed) does NOT support sharing USB devices other than storage devices (pendrives or hard drives). Hence, a mechanism is needed to make the device/port from the host Windows machine available as a device/port inside the container. This is USB over IP, USBIP. There is an open source USPIP server kernel module that can be installed in the VM where the docker daemon is executed. Further notes:

Summarizing, I'm interested on you being able to program the boards with a local ghdl/synth:prog container, because it is the first step to support other not-so-intuitive setups. These setups are interesting for classrooms/workshops where there might not be one board available for each student; or where low-cost laptops can be used to run intensive tasks in a workstation.

I did wonder if I should convert to a build system which is Windows compatible (cmake, meson?). I don't have much experience here.

I'm a Windows user, but I do use MSYS2 and containers as my main terminals. Hence, I'm not specially interested on using Windows-flavoured scripts/build systems. Although WSL1 was limited to Windows Pro, it seems that WSL2 will be available for any version of Windows. Hence, any user will be able to use GNU/Linux tools.

Regarding other architectures, I don't want to maintain all of the images for all the archs, because that'd be a lot of work. Nonetheless, should you be interested on having some specific image (say nextpnr-ecp5 for ppc64), just let me know.

eine commented 4 years ago

I do :) I got one directly from Greg who is currently working on a second revision. Hopefully it will be available sometime. I've been told the ULX3S is nice but it doesn't seem to be available either.

Oh, I forgot to say that... lucky you! 😄

I do need DDR for the projects I want to test, so ULX3S is not specially useful. Will have to wait until Greg gets his second revision. And to meet him/you at some conference. I don't think that shipping costs will be worth...

eine commented 4 years ago

The test passed cleanly now: https://github.com/ghdl/docker/runs/395612255#step:3:3558. I also added openocd to image ghdl/synth:prog. Should it work, we are all set!

antonblanchard commented 4 years ago

I just tested openocd, and it works with --device /dev/bus/usb. I've updated the Makefile, and cleaned it up a bit. I also tested the ECP5-EVN board.

I added a GENERIC so the LED always blinks at 1 Hz. I also tweeted it out :) Thanks for all your help!

eine commented 4 years ago

Great! I merged into master! Although I didn't pick this PR as is, I preserved your authorship in the first (modified) commit. Hope you are ok with it.

I added a GENERIC so the LED always blinks at 1 Hz. I also tweeted it out :) Thanks for all your help!

That's a cool feature that Tristan added very recently. It's also cool that you tweeted about it! None of us uses twitter, so these enhancements get little exposure. Thank you for testing and spreading the word!