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

Add nextpnr ECP5 images #22

Closed
wants to merge 1 commit into from

Conversation

antonblanchard
Copy link
Contributor

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
Copy link
Collaborator

eine commented Jan 16, 2020

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:

  • We want to distribute ghdl/synth:trellis just as we distribute ghdl/synth:icestorm. Hence, it is ok to have dependencies for device programming in this image and not in with nextprn.
  • Are libftdi1-2 usbutils the actual dependencies of prjtrellis? Is OpenOCD included in any of those packages?
    • Should the answer be true, was it built with --enable-ftdi, as required?
    • Should the answer be false, are those packages actual dependencies of OpenOCD (so we need them anyway)?

@antonblanchard, overall:

  • Do you have any ECP5 board?
  • Did you try to program/configure it from a Docker container?
  • Does prjtrellis include any tool such as iceprog?

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
Copy link
Collaborator

eine commented Jan 16, 2020

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)

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
Copy link
Contributor Author

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
Copy link
Collaborator

eine commented Jan 17, 2020

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
Copy link
Contributor Author

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
Copy link
Collaborator

eine commented Jan 17, 2020

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:

  • Unfortunately, there is no open source USBIP client for Windows. Nevertheless, I could make it work with VirtualHere. I gathered the notes in https://github.com/ghdl/docker/tree/master/usbip.
  • Using USBIP is interesting in other contexts too. For example, you might have the board connected to a GNU/Linux host and run all the tools as containers in a remote machine (say an VPS on the cloud).
  • For serial USB communications (i.e., when the device can be shared as a COM or TTYUSB), open source clients exist (for Windows too). Hence, once the board is programmed, tests that use UART/RS232 are easier to run. This is because socat works, there is no need for the USBIP kernel module.
    • It would be potentially possible, although slow, to write a bootloader that accepts bitstream through UART, instead of requiring FTDI drivers.

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
Copy link
Collaborator

eine commented Jan 17, 2020

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
Copy link
Collaborator

eine commented Jan 18, 2020

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
Copy link
Contributor Author

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
Copy link
Collaborator

eine commented Jan 19, 2020

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants