Collection of PCI express related components. Includes PCIe to AXI and AXI lite bridges and a flexible, high-performance DMA subsystem. Currently supports operation with several FPGA families from Xilinx and Intel. Includes full cocotb testbenches that utilize [cocotbext-pcie](https://github.com/alexforencich/cocotbext-pcie) and [cocotbext-axi](https://github.com/alexforencich/cocotbext-axi).
Example designs are included for the following FPGA boards:
The PCIe modules use a generic, FPGA-independent interface for handling PCIe TLPs. This permits the same core logic to be used on multiple FPGA families, with interface shims to connect to the PCIe IP on each target device.
The `pcie_us_if` module is an adaptation shim for Xilinx 7-series, UltraScale, and UltraScale+. It handles the main datapath, configuration space parameters, MSI interrupts, and flow control.
The `pcie_s10_if` module is an adaptation shim for Intel Stratix 10 GX/SX/TX/MX series FPGAs that use the H-Tile or L-Tile for PCIe. It handles the main datapath, configuration space parameters, MSI interrupts, and flow control.
The `pcie_ptile_if` module is an adaptation shim for Intel Stratix 10 DX/Agilex series FPGAs that use the P-Tile for PCIe. It handles the main datapath, configuration space parameters, and flow control.
The `pcie_axi_master`, `pcie_axil_master`, and `pcie_axil_master_minimal` modules provide a bridge between PCIe and AXI. These can be used to implement PCIe BARs.
The `pcie_axi_master` module is more complex, converting PCIe operations to AXI bursts. It can be used to terminate device-to-device DMA operations with reasonable performance.
The split DMA interface/DMA client modules support highly flexible, highly performant DMA operations. The DMA interface and DMA client modules are connected by dual port RAMs with a high performance segmented memory interface. The segmented memory interface is a better 'impedance match' to the PCIe hard core interface - data realignment can be done in the same clock cycle; no bursts, address decoding, arbitration, or reordering simplifies implementation and provides much higher performance than AXI. The architecture is also quite flexible as it decouples the DMA interface from the clients with dual port RAMs, enabling mixing different client interface types and widths and even supporting clients running in different clock domains without datapath FIFOs.
The `dma_psdpram` module is a dual clock, parallel simple dual port RAM module with a segmented interface. The depth is independently adjustable from the address width, simplifying use of the segmented interface. The module also contains a parametrizable output pipeline register to improve timing.
The `dma_if_mux` module enables sharing the DMA interface across several DMA clients. This module handles the tags and select lines appropriately on both the descriptor and segmented memory interface for plug-and-play operation without address assignment - routing is completely determined by component connections. The module also contains a FIFO to maintain read data ordering across multiple clients. Make sure to equalize pipeline delay across all paths for maximum performance.
DMA client modules connect the segmented memory interface to different internal interfaces.
The `dma_client_axis_source` and `dma_client_axis_sink` modules provide support for streaming DMA over AXI stream. The AXI stream width can be any power of two fraction of the segmented memory interface width.
DMA interface mux module. Enables sharing a DMA interface module between multiple DMA client modules. Wrapper for `dma_if_desc_mux` and `dma_ram_demux_wr`.
DMA interface mux module. Enables sharing a DMA interface module between multiple DMA client modules. Wrapper for `dma_if_desc_mux` and `dma_ram_demux_rd`.
PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface. Wrapper for `dma_if_pcie_us_rd` and `dma_if_pcie_us_wr`.
PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface.
PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface.
Minimal PCIe AXI lite master module. Parametrizable interface width. Only supports aligned 32-bit operations, all other operations will result in a completer abort. Only supports 32-bit AXI lite.
MSI-X support module. Implements MSI-X table and pending bit array with AXI lite register interface, accepts interrupt requests on a streaming interface, and generates corresponding write request TLPs.
### `pcie_ptile_cfg` module
Configuration shim for Intel Stratix 10 DX/Agilex series FPGAs (P-Tile).
### `pcie_ptile_if` module
PCIe interface shim for Intel Stratix 10 DX/Agilex series FPGAs (P-Tile). Wrapper for all Intel Stratix 10 DX/Agilex PCIe interface shims.
### `pcie_ptile_if_rx` module
PCIe interface shim (RX) for Intel Stratix 10 DX/Agilex series FPGAs (P-Tile).
### `pcie_ptile_if_tx` module
PCIe interface shim (TX) for Intel Stratix 10 DX/Agilex series FPGAs (P-Tile).
PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for `pcie_us_axi_dma_rd` and `pcie_us_axi_dma_wr`.
PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for `pcie_us_axi_master_rd` and `pcie_us_axi_master_wr`.
Demux module for Xilinx UltraScale CQ interface. Can be used to route incoming requests based on function, BAR, and other fields. Supports 64, 128, 256, and 512 bit datapaths.
Demux module for Xilinx UltraScale RC interface. Can be used to route incoming completions based on the requester ID (function). Supports 64, 128, 256, and 512 bit datapaths.
Running the included testbenches requires [cocotb](https://github.com/cocotb/cocotb), [cocotbext-axi](https://github.com/alexforencich/cocotbext-axi), [cocotbext-pcie](https://github.com/alexforencich/cocotbext-pcie), and [Icarus Verilog](http://iverilog.icarus.com/). The testbenches can be run with pytest directly (requires [cocotb-test](https://github.com/themperek/cocotb-test)), pytest via tox, or via cocotb makefiles.