Raspberry Pi 4 PCI-Express Bridge “Chip”

After seeing the work done by Thomasz Mloduchowski and Colin Riley with managing to bridge the Raspberry Pi 4’s PCI-Express bus to a USB 3.0 port, and then seeing these comments on hack-a-day, I thought I would give it a go too!

So, here’s a PCIe bridge “chip” that simply replaces the VL805 USB 3.0 controller chip on the Pi, giving access to the PCI-Express bus on a USB 3.0 port. However, this does mean losing all USB functionality of the Pi. That could be a bit of a problem if you ever mess up the networking and need to attach a keyboard. Never mind, it seems that the USB-C power connector can run as a USB host, allowing a keyboard to be connected if 5V power is supplied through the GPIO header instead.

The bridge “chip” is a 0.8mm thick PCB from OSHPark with copper pads in the same locations as a real VL805 QFN68 IC package, then traces connecting the PCIe pads to the USB pads that connect to the upper USB 3.0 port. RESET, WAKE and a few other signals were also connected to the lower USB 3.0 port.

PCIe SignalDirectionUSB Signal
REFCLK+Host -> DeviceD-
REFCLK-Host -> DeviceD+
HSO+Host (TX) -> Device (RX)RX-
HSO-Host (TX) -> Device (RX)RX+
HSI+Device (TX) -> Host (RX)TX-
HSI-Device (TX) -> Host (RX)TX+
RESETHost -> DeviceD- (lower port)
WAKE (not connected anywhere)Device -> HostD+ (lower port)
CLKREQHost -> DeviceRX+ (lower port)
PONRSTNot a PCIe signal, connected like a reset pin on a microcontroller.RX- (lower port)
HSI and HSO (in and out) are from the perspective of the host controller. Where host HSO/TX will connect to device RX and host HSI/RX to device TX. Man, this is really confusing with TX, RX, device, host, passing through USB, which side is which… 😕

There’s also a small hole near the centre, this allows any leftover solder from the large ground pad to have somewhere to go when placing the chip, otherwise the solder could end up squashed out around the edge, shorting out the pads. The PCB is slightly larger than the QFN68 package, as there is a limit on how close the copper can be to the edge. The fabricated PCB should be sanded down to the correct size, so that the cross-section of the copper pads can be seen at the edge of the PCB, just like on a QFN package.

After replacing the VL805 with the bridge chip I tried a few PCIe cards that were laying around, the first was a Realtek RTL8168 based ethernet adapter… it didn’t work. Then I tried an ASMedia ASM1083 PCIe to PCI converter, that didn’t work either. I looked over all solder joints, checked for continuity, shorts, and everything seemed fine. I tried all kinds of things, like removing the capacitors and swapping the + and – of each signal in case they were swapped at the device end, as this is a feature of PCIe called polarity inversion that maybe the controller did not support. The Pi just would not detect them. It seemed to be unable to train the PCIe link as dmesg showed link down instead of link up, 2.5 Gbps x1 (!SSC). In the end I ordered a USB 3.0 expansion card containing a VL805, the same as the Pi. When it eventually arrived, I plugged it in and it was detected first time! I found a Realtek RTL8111 based ethernet adapter, and that worked too! After installing the driver for the RTL8111 it was able to obtain an IP from the DHCP server and I could ping the interface.

I wonder what it is about the RTL8168 and ASM1083 that makes them incompatible with the Raspberry Pi? Maybe they just don’t like the PCIe signals running through a load of USB connectors and cables.
UPDATE 1: Using an ASM1184e PCIe switch and these two expansion cards are still not detected, so probably not signal issues. The device trees file has been modified to allow more than one PCIe device, as described in Colins blog post. Other cards work in the switch, just not these two.
UDPATE 2: Nevermind, the problem with the ASM1083 was that I hadn’t connected the 5V rail, and is now detected by the Pi. RTL8168 still doesn’t work for some reason.

A quick test using 4 USB 3.0 flash drives plugged into the VL805 expansion card resulted with a total read throughput of 3 Gbps out of a maximum theoretical throughput of 4 Gbps over a 5 Gbps PCIe 2.0 link. The flash drives had their read speeds almost maxed out, probably slowed down slightly from overhead of having to switch between each drive while reading.
UPDATE: Another test with 5 USB flash drives, a USB hub and a USB-to-Ethernet adapter resulted in 3 Gbps again, so this seems like a limitation of the VL805 or CPU. Other RPi4 benchmarks using SSDs through USB 3 also maxed out at 3 Gbps.

The RESET and WAKE traces on the riser board should be cut, otherwise RESET will be connected to GND preventing the card from starting and WAKE will be connected to 5V possibly damaging the device if that pin is not 5V tolerant. The RESET line should then have a 10k pullup connected to the 3.3V supply, or connected to the D- signal of the lower USB 3.0 port of the Pi.

Colin mentioned that Thomasz also had kernel panic problems with his setup, I had a few panics and freezes too, but they seemed to be caused by wiggling the PCIe card a little too much.

This pdf has a full schematic using a VL805 on pages 7 and 8 (pictured below), very handy since any information about the chip is scarce.

These “chips” are available to buy from my Tindie store! Or they can be ordered directly from me, send an email to shop@zakkemble.net

PCB designs and things are on GitHub

11 comments

3 pings

Skip to comment form

    • Nikolay Tsanov on June 16, 2020 at 9:32 am
    • Reply

    Dude, that is great work, really inspiring. I was really hoping that they would expose PCIe on rpi4, opens so much more options. Hope somebody from raspberry pi foundation notices your work and realize that we want PCIe on the pi

    • jj_0 on June 17, 2020 at 8:01 am
    • Reply

    This is rather cool! Btw, you can configure the Pi to use the USB-C port as (USB 2.0) host port and that uses the SoC rather than the VL805 so if you do that you should still be able to use USB devices. More info here: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=246348&p=1678554#p1678554

    1. Thanks, I didn’t know about that. That solves the USB problem then!

    • Daud Mukhamedjanov on June 17, 2020 at 2:44 pm
    • Reply

    What you did is amazing, but choosing usb socket is not a nice idea. Instead it would be a lot more better to use pogo pins/wires or multilayer pcb adapter and take a look on the eye diagram of signals.

    1. Yea, signal integrity might be an issue (I don’t have any equipment that can look at PCIe signals), however I’m able to max out 4 USB drives on a VL805 expansion card for a read throughput of 3 Gbps so it doesn’t seem to be too bad. Anything else would just make it more difficult to connect PCIe risers that cryptocoin miners use, and they’re USB connectors too. USB seems to be a tried and tested way of externally connecting PCIe.

        • Ian H on July 1, 2020 at 10:11 pm
        • Reply

        I doubt it’s an issue, it’s been done with USB ports for years with the riser cards.

    • Ian Guffick on June 18, 2020 at 8:03 pm
    • Reply

    It could be useful to make an expansion board. Take the PCIe to a switch. Then use one port to replace the lost VL805. Add a few M2 slots and PCIe slots. You wouldn’t then lose any existing functionality, but gain 2,3,4,n PCIe ports.

    • Maciej on July 1, 2020 at 9:46 pm
    • Reply

    Nice! I might have a clue why it does not work with some devices. Have you paid attention to trace impedance on this small board?

    I can see that there are 2 layers and its (supposedly) standard ~1.5mm thick. You won’t get with that the required 100ohm. The board is ~8mm wide, there may be unwanted cross-talks / reflections. Consider making it 4-layer so you can have 100ohm differential traces. Isolate pairs (rx and tx) from each other eg. with a ground trace and equalize differential traces lengths. If you poke around the internet there are requirements for routing PCIe signals.

    I’m not 100% that it is an issue but it’s worth a shot.

    1. Signal quality isn’t the issue here as the RTL8168 is still not detected when behind a PCIe switch, but connecting it through the switch to a full PC’s PCIe port works fine. I just found out that the problem with the ASM1083 PCIe-to-PCI converter was that I hadn’t connected the extra 5V power that it needed, and is now detected by the Pi, hah!
      But otherwise, no, I’ve paid absolutely no attention to impendences, other than making sure each trace in the differential pair are the same length. PCIe seems to be pretty resilient to poor routing.

  1. Search for “PCI-E X1 TO 4PCI-E X16 Expansion Card Switch Multiplier” – double check that this uses the same USB 3.0 pairs, but it’s an extender that has 4 PCIE slots and a x1 to 4 x1 switch chip.

    • Chivar on July 16, 2020 at 10:42 am
    • Reply

    it would great to see a raspberry pi 4 ontop o full sized graphics cards 🙂

  1. […] the first to connect a regular PCIe expansion card to a Raspberry Pi 4 SBC. Now [Zak Kemble] has created a new approach, using a bridge PCB that replaces the VL805 USB 3 controller IC. This was also how the original […]

  2. […] blog Zakkembe.net made a clever workaround to access the Pi’s PCLe bus. Via […]

  3. […] this blog post for the connection details. The bridge PCBs are available on his Tindie […]

Leave a Reply

Your email address will not be published.

Are you human? *