RP2040 + Cyclone 10 FPGA PCB Design Project

In this article, I’ll show you the Raspberry Pi Pico (RP2040) + Cyclone 10 FPGA PCB design project. I’ll explain some of the design decisions I’ve made, how to prepare the files needed for manufacturing, and how to place the PCBA order at NextPCB which is kindly sponsoring this project.

We’ll also develop some firmware in C & HDL code in Verilog to bring up our board and play around with its two sides: The RP2040 & The FPGA. Without further ado, let’s get right into it!

This Project is Sponsored By NextPCB

Table of Contents

  1. Top-Level Hardware/Software Architecture
  2. RP2040+FPGA HW Design Guidelines & Documents
  3. PCB Layout, Sections, and Board Pinout
  4. Placing PCBA Order @ NextPCB + HQ-Online
  5. Hardware Smoke Test & Precautions
  6. RP2040 GPIO Test (LED Blinking)
  7. RP2040 ADC + PWM Example
  8. Cyclone 10 FPGA IO Test (DIP Switches + LEDs)
  9. Cyclone 10 FPGA JTAG Programming
  10. Cyclone 10 FPGA QSPI Flash Configuration Testing
  11. Project Core Test: RP2040 + FPGA (SPI-Link)
  12. RP2040 + FPGA SPI Max Speed
  13. RP2040 OLED Display Demo Examples
  14. Extra Board Peripherals Testing
  15. Wrap Up
  16. [YouTube Video] RP2040 + Cyclone 10 FPGA PCB Design Project

Top-Level Hardware/Software Architecture

First of all, the motive behind this project is to design a board that incorporates the RP2040 microcontroller with a low-cost FPGA chip to experiment with digital inter-chip communication schemes using an SPI bus and a custom IO bus (using PIO).

We can set things up in such a way that the FPGA is fully transparent from the RP2040’s point of view and it acts like an MMIO peripherals extension. Or the other way around, we can set up a softcore processor on the FPGA side and configure the RP2040 as a slave device. It is very flexible with endless application possibilities.

Below is a top-level diagram that shows the target hardware/software system architecture that we’re going to implement in this project.

Raspberry Pi Pico RP2040 & FPGA PCB Project Hardware-Software Architecture

RP2040 Side

On the RP2040 side, we’ll have a master SPI peripheral that handles the low-level communication with the FPGA. In firmware (software stack), we’ll implement some sort of MMIO addressing, IO (read/write) operations, decoding, and so on. In this way, we could abstract the MMIO peripherals addressing away from the firmware application layer.

Then, we can add some firmware device drivers for the custom hardware peripherals that we’ll implement on the FPGA. Again, this will also abstract the custom peripherals operation details away from the application point of view.

In the end, it’ll be nearly the same to use a hardware timer peripheral on the RP2040 microcontroller itself or a custom-designed hardware timer peripheral on the FPGA fabric.

This is just an example of how this system will end up working, of course, we won’t be doing all of that to have some extra timer peripherals. But you get the idea.

FPGA (Cyclone 10) Side

On the FPGA side, we’ll implement a hardware slave SPI peripheral to handle the communication with the RP2040. Then we’ll pass the received data to a custom bus manager that should have some sort of state machine to decode/encode the incoming/outgoing SPI data. At that point, serial SPI data will be transformed into parallel bus data/control signals.

Then, we’ll hook up an MMIO controller that controls the custom peripherals’ memory IO operations and standardizes the way each custom peripheral is attached to it. Which makes the system more expandable and portable.

Again, this is just an example of how this system is going to work, and of course, it can bridge the SPI bus to an AXI-4/AXI-Lite bus to allow hooking up a softcore processor or standard hardware IP blocks, and so many other possibilities to say the least.

RP2040-FPGA Inter-Chip Connections

There are two buses connecting between the RP2040 microcontroller and the Cyclone 10 FPGA chip, which are listed below:

1) SPI Bus (4-Wire)

Using an SPI bus we can make use of the hardware peripheral in the RP2040 to allow for high-speed communication with the FPGA chip (up to 62.5Mbps). We can also implement bulk data transfers with the DMA unit inside the RP2040 to achieve extremely low CPU intervention.

2) Custom IO Bus (4-Wire)

Using the RP2040’s PIO, we can easily implement any custom digital communication protocol to achieve very high-speed data transfers. This leaves the door open for endless possibilities and experimentation in the future.


RP2040+FPGA HW Design Guidelines & Documents

For designing a system like this, the official documentation & guidelines are our best friends. Intel/Altera provides so many useful documents that I’ve used while designing this board. Which include the following files:

The same goes for the RP2040, which has several helpful documents on Raspberry Pi’s official website as listed below:

You can also reference my previous project using RP2040 which demonstrates how to design a custom PCB board around the RP2040 microcontroller. Which I’ve used exactly as it is in this project as well.

Raspberry Pi Pico (RP2040) Schemtatic & PCB Design - KiCAD

This PCB design project will help you get started with designing a custom RP2040-based PCB project. It’ll provide you with all the details needed to make your own RP2040-based PCB project. You’ll also learn how to bring up your custom RP2040 board and program it in C/C++ and in Arduino C++ as well.


PCB Layout, Sections, and Board Pinout

This is the board layout in KiCAD 3D view for the top side and bottom side. I was keen on keeping everything sectioned in a logical manner and also keeping it easy to use. It’s so easy to make a non-userfriendly PCB given how large it looks in the CAD software then it turns out to be awkward to handle in real life. I’ve done my best to place the components that the user will interact with in such a way that is easy to reach and handle.

The board dimensions are: 6cm x 9cm (it’s pretty small, not as large as it appears to be in CAD software)

RP2040 + Intel Cyclone 10 LP FPGA PCB Design Project Layout

1. DC PWR In + USB

There are two USB-C ports that I’m using for power input (+5v) as well as USB communication that’s required for UF2 flash programming of the Raspberry Pi Pico (RP2040) chip. And the other USB port is connected to a USB-UART bridge that goes to the FPGA chip.

2. Power Supplies (Voltage Regulators)

There are three DC/DC buck converters (power supplies), and an analog voltage reference on this board. They’re as follows:

  • +3V3 (FPGA+RP2040 Vcc)
  • +1V2 (FPGA Core)
  • +2V5 (FPGA Aux.)
  • +3.3VA (REF3033)

Below is the schematic diagram for the USB-C ports & power supplies section.

RP2040 With FPGA PCB Board Schematic (Power Supplies Section)

3. RP2040 MCU Circuitry + QSPI FLASH

The RP2040 microcontroller requires a +3.3v input voltage @ IOVdd pin, +1.1v from the internal regulator that powers the DVDD, 100nF decoupling capacitors, and a 12MHz crystal oscillator.

Unlike most microcontrollers in the market, the RP2040 doesn’t have an internal flash memory. Therefore, an external Quad-SPI (QSPI) flash chip is required. You can add a 2MB, 4MB, 8MB, or 16MB flash chip.

On my board, I’ve used the maximum flash size allowed by the RP2040’s XIP (eXcute-In-Place) interface which is 16MB (128Mbit).

I’ve also added a RESET button to reset the microcontroller when needed. And we’ll need it every time we try to flash a new firmware to the chip. For UF2 programming, a BOOT button is also needed on the QSPI CS line.

4. Cyclone 10 LP (10CL006) FPGA Circuitry

The FPGA chip has a lot of banks and special function IO pins that need to be connected in a certain way which is demonstrated in detail within the official documents by Intel/Altera that I’ve linked to earlier.

The VCCIO pins, VCCA, and VCCINT pins are all connected as suggested in the datasheet. The MSEL[2:0] = ASx1 (Active Serial) mode allows the FPGA to load the configuration bitstream from an SPI serial flash chip. I’ve used a 64MBit QSPI flash chip.

The CMOS oscillator that I’ve used as a main clock source for the FPGA is a 50MHz oscillator. And of course, we can manipulate that frequency internally using the 2x PLL units inside the FPGA chip (up to 400MHz is achievable with this FPGA’s PLLs).

5. RP2040 OnBoard Peripherals

Below are the onboard peripherals that are connected to the RP2040 microcontroller:

  • 2x Buttons (Reset, Boot)
  • 1x LED (PWM)
  • 1x OLED 0.96″
  • 1x Rotary Potentiometer
  • 1x 6-Axis IMU Sensor (ICM-42670)

6. FPGA OnBoard Peripherals

Below are the onboard peripherals that are connected to the Cyclone 10 LP FPGA:

  • 8x DIP Switches
  • 8x LEDs
  • 4x Push Buttons
  • 1x Analog RGB (PWM) LED
  • 1x NeoPixel RGB (WS2812) LED
  • 1x 64kBit I2C EEPROM Chip (24C64)

7. IO Ports

There are 4 pin headers (ports) on this board which are as follows:

  • 2x (25×2) IO Pinheaders: RP2040 = 15 IOs, FPGA = 41 IOs
  • 1x FPGA JTAG Header
  • 1x RP2040 SWD Header

RP2040+FPGA (Pico Logic Bridge) Board Pinout

This is the pinout diagram for our project’s board.

PicoLogicBridge Pinout Diagram


Placing PCBA Order @ NextPCB + HQ-Online

For this PCB project, I’ve decided to use NextPCB service for PCBA (PCB Fabrication + Assembly). They also have an electronic components sourcing company (HQ-Online) to make it even more efficient to source parts required for PCBA orders in a timely manner.

I’ve selected all the parts needed in my PCB design BOM (bill of materials) using the HQ-Online website to add the Manufacturer number of each part needed into my BOM file. Here is an example of how it goes:

NextPCB + HQ-Online PCB Order 1

After searching for the part you need, you should use the parts that will “Ship Immediately” because these are currently in stock at HQ-Online and your PCB assembly will start as soon as PCB Fabrication is done.

However, if the parts that you need are marked as “Ship in 4-7WD”, it’s still fine to use and normally they get shipped much quicker than announced. A couple of days delay may be justified by how cheap the listing prices of some parts on there. It’s definitely worth it according to my experience.

Get the manufacturer number (Mfr Part #) for all parts in your design into your BOM editor in KiCAD (or any other CAD tool). Then, we’ll generate the fabrication/assembly files and head over to NextPCB website to place our PCBA order.

You can use this KiCAD Plugin below to export all fabrication files needed by NextPCB in the proper format they expect with just one click of a button.

1. Upload Your Gerber File & Check PCB Fab. Options

The next step is to upload our PCB Gerber files and modify the PCB fabrication options as needed in the project.

Enable the PCB assembly (1 side or 2 sides). In my project’s case, I’ve chosen the 2 side assembly.

NextPCB Quote (Gerber)

2. Upload BOM & CPL Files

The next step is to upload your design’s BOM file and the components positions file (CPL) to NextPCB and let it check the files and report the stock status and total number of components to be assembled, their cost, and so on.

You can even choose to assemble only 1 board (if that is what you need). However, the cost goes down significantly after the first sample board is produced. Therefore, you might find assembling 5 boards a very good option as well.

NextPCB Quote (Assembly)

Check everything and make sure the components are selected correctly from the HQ-Online SMT library.

3. Pay To Place Your Order

The last step to place your order is to pay for the invoice and you can apply any valid discount coupon at this step to reduce the cost.

4. Wait For Delivery & Get Ready For Testing!

Here is how it turned out at the end.

RP2040 + Cyclone FPGA PCB (PicoLogicBridge)


Hardware Smoke Test & Precautions

First of all, I have to manually assemble/mount the parts shown below:

RP2040 Cyclone10 FPGA 10CL006 PCB Design Testing

Then, I gave it a quick inspection under the microscope with a “Fine Needle” DMM probe to check up on any critical short circuit and also the continuity of critical power paths (VCC, VCCINT, VCCA, etc).

Everything looks perfect to me at this point. So, the next step is to power the board from my “Current Limited” power supply (+5V/50mA). Just in case anything goes wrong, it won’t push enough current to cause serious damage. Thankfully, it worked like a charm while drawing a few milli-amps.

Here are the actual power supplies measurements:

RP2040 FPGA PCB Project Testing (Power Supplies)

At that point, I was confident enough to plug in the USB cable and start doing some real work!


RP2040 GPIO Test (LED Blinking)

This is the first “RP2040 life test” example project in which we’ll blink the onboard LED.

Open the Pico-Visual Studio Code software, create a new project, and copy the example test code below. The exact project creation steps are demonstrated in detail in this tutorial: Raspberry Pi Pico RP2040 GPIO Tutorial (C/C++ SDK)

RP2040 LED Blinking GPIO Example Code

The Application Code For This Example (main.c)

Compile & Flash the firmware to the board using the UF2 bootloader.

LED Blinking Test Result

Raspberry Pi Pico C C++ SDK Programming (And Pico W)

This tutorial is the ultimate guide for getting started with Raspberry Pi Pico using C/C++ SDK. You’ll learn how to install the Pico C/C++ SDK toolchain, create a project from scratch, and build/flash your Embedded-C/C++ projects to the Raspberry Pi Pico (RP2040-based) boards.

Raspberry Pi Pico Read Digital Input & Write Digital Output (C SDK)

This article will give more in-depth information about GPIO digital input output pins in Raspberry Pi Pico (RP2040) using C/C++ SDK. With a couple of code examples & simulations for digital pin read and write operations.


RP2040 ADC + PWM Example

Next up, we’ll test the RP2040’s ADC by reading the onboard analog rotary potentiometer then we’ll use that as a duty cycle control signal for the onboard LED brightness control.

RP2040 ADC + PWM Example Code

The Application Code For This Example (main.c)

 

Compile & Flash the firmware to the board using the UF2 bootloader.

RP2040 ADC + PWM Test Result


Cyclone 10 FPGA IO Test (DIP Switches + LEDs)

This is the first “FPGA life test” example project in which I’ll route the 8x DIP Switches through the FPGA internally to control the 8x LEDs’ states. I will also route the 3x Buttons (S1, S2, and S3) to the analog RGB LED pins (Red, Green, Blue) to light each color LED using the respective push button.

This is a very basic test example to verify that the FPGA is at least working and able to take a bitstream file and do something accordingly.

Below is the demo example testing after uploading the bitstream to the FPGA through the JTAG. Note how everything gets wiped out after pressing the FPGA_Reset button near the end of the demo video.

Cyclone10 FPGA IO Test Result


Cyclone 10 FPGA JTAG Programming

To load the bitstream onto my Cyclone 10 FPGA, I’ve tried both Altera USB Blasters commonly found on the market. The waveshare USB blaster v2 was the one that worked for me since I’m using the latest version of Quartus Prime (Lite).

However, the cheap USB blaster also works and gets detected by the PC, the driver gets installed, and everything is fine. But it doesn’t show up in Quartus Prime software in my case. Maybe it does work under older versions of the software package.

Cyclone 10 LP FPGA JTAG USB Blaster


Cyclone 10 FPGA QSPI Flash Configuration Testing

As you’ve seen in the previous example demo video, the FPGA configuration (bitstream) gets wiped out whenever we click on the reset button or when the power goes off.

Therefore, we need to test the QSPI Flash Configuration option on our board. To do this, I’ll prepare the bitstream in JIC (JTAG indirect configuration) file format. Then flash it to the QSPI memory over the JTAG connection.

This will make our FPGA design permanently stored on the QSPI flash memory and gets loaded automatically upon power up or after a reset button press event. Below is a demo video testing this feature.

Cyclone10 FPGA SPI Flash Config Test Result


And now let’s get to the real test example. This is actually the core of our project. In this example, we’ll do the following on each side:

RP2040 Firmware (C):

The RP2040 will read the analog potentiometer using the ADC, then will scale it down from 12Bits to 8Bits, and send it over SPI to the FPGA chip.

Cyclone10 FPGA HDL (Verilog):

On the FPGA, we’ll create a hardware SPI slave module and a PWM generator. Whenever the SPI slave device receives a byte of data, it’ll get latched and loaded into the PWM’s duty cycle control register. The PWM output will be connected to the onboard RGB’s blue LED.

RP2040 + FPGA SPI Communication Test Example

Therefore, the RP2040’s potentiometer will control the PWM output of the FPGA that goes to the blue LED of the onboard RGB.

The SPI communication speed will be set to 1Mbps to make sure everything works fine. Then we’ll pump it up to see what is the maximum speed our design will be able to handle before communication failure.

RP2040 -> FPGA SPI Communication Test Result


RP2040 + FPGA SPI Max Speed

After being confident about the system’s performance at 1Mbps SPI speed, I started to gradually increase the SPI communication speed. At 30Mbps, the communication started to fail and that was due to the fact I was using the onboard raw 50MHz clock source for my FPGA.

Therefore, I’ve enabled one of the PLL units inside the FPGA to pump up the clock to 300MHz and feed that clock to all my HDL modules (especially the SPI slave). After doing this, we could easily maintain proper SPI communication between the RP2040 & the FPGA at 62.5Mbps. Which is the maximum SPI speed for the RP2040 running @ 125MHz system clock.

This is absolutely amazing for me at this point given that I’ve seen a lot of information online about SPI lines termination and problems at speeds (>30MHz). Given that I’ve not used any parallel or inline termination resistors, only followed common best practices of routing for signal integrity.


RP2040 OLED Display Demo Examples

One last example demo before concluding this project is the onboard 0.96″ OLED RGB display. Here is a demo video showing some images stored on the RP2040 and displayed on the OLED screen.

RP2040 OLED Display Test Result


Extra Board Peripherals Testing

Given that this is the first iteration of this hardware design PCB project. And at this point, everything has proven to work as expected with no issues at all. This is a big W already!

Getting any other secondary peripheral to work as well will be an extra win. The remaining untested peripherals are:

  • IMU (ICM-42670) – [RP2040]
  • I2C EEPROM (24C64) – [FPGA]
  • Neopixel RGB (WS2812) LED – [FPGA]

I didn’t have the time to develop some device drivers for these parts above, but I’m sure they’ll also work just as fine.


Wrap Up

By the end of this project, I hope you’ve found it helpful, inspiring, or at least interesting to follow along with. I’ve got so many things to experiment with using this board, especially the digital communication between the microcontroller & the FPGA. I’ll do my best to document that work and hopefully share some of it on our YouTube Channel, so stay tuned for that.

If you’ve got any questions or would like me to do a specific application using this board or even create a new one with different specs (FPGA, MCU, Sensors, Peripherals, etc..), Just let me know in the comments. I’ll be glad to hear your take on this!

[YouTube Video] RP2040 + Cyclone 10 FPGA PCB Design Project

More projects are coming soon. Subscribe to our channel to stay in touch!

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment