Use this checklist to guide you through the firmware creation.
Collect the following information from the donor PCIe device:
- Device ID (
0xXXXX
) - Vendor ID (
0xYYYY
) - Subsystem ID (
0xZZZZ
) - Subsystem Vendor ID (
0xWWWW
) - Revision ID (
0xRR
) - Class Code (
0xCCCCCC
) - Base Address Registers (BARs) Configuration:
- BAR0 to BAR5 sizes, types (Memory or I/O), prefetchable status
- Capabilities:
- Power Management settings
- MSI/MSI-X settings
- Device Serial Number (DSN) (
0xXXXXXXXXYYYYYYYY
)
-
Modify
cfg_deviceid
:cfg_deviceid <= 16'hXXXX; // Replace XXXX with donor's Device ID
-
Modify
cfg_vendorid
:cfg_vendorid <= 16'hYYYY; // Replace YYYY with donor's Vendor ID
-
Modify
cfg_subsysid
:cfg_subsysid <= 16'hZZZZ; // Replace ZZZZ with donor's Subsystem ID
-
Modify
cfg_subsysvendorid
:cfg_subsysvendorid <= 16'hWWWW; // Replace WWWW with donor's Subsystem Vendor ID
-
Modify
cfg_revisionid
:cfg_revisionid <= 8'hRR; // Replace RR with donor's Revision ID
-
Modify
cfg_classcode
:cfg_classcode <= 24'hCCCCCC; // Replace CCCCCC with donor's Class Code
-
Modify
cfg_dsn
:cfg_dsn <= 64'hXXXXXXXXYYYYYYYY; // Replace with donor's DSN
-
Open Vivado and run the appropriate Tcl script in the Tcl Console:
cd <project_directory> source vivado_generate_project_<your_board>.tcl -notrace
- Replace
<project_directory>
with your project path. - Replace
<your_board>
with your FPGA board identifier (e.g.,squirrel
).
- Replace
- File: Open the generated
.xpr
project file in Vivado.
- File to Edit:
pcie_7x_0.xci
- Action: Right-click and select Customize IP.
- Device ID: Set to donor's Device ID.
- Vendor ID: Set to donor's Vendor ID.
- Subsystem ID: Set to donor's Subsystem ID.
- Subsystem Vendor ID: Set to donor's Subsystem Vendor ID.
- Revision ID: Set to donor's Revision ID.
- Class Code: Set to donor's Class Code.
For each BAR (BAR0 to BAR5):
- Enable/Disable: Match donor device.
- Type: Memory (32-bit or 64-bit) or I/O.
- Size: Set to donor's BAR size.
- Prefetchable: Match donor's setting.
- Maximum Link Speed: Set to match donor device (e.g., Gen2, Gen3).
- Link Width: Set to match donor device (e.g., x1, x4).
- Enable Power Management if the donor device supports it.
- Enable MSI/MSI-X if the donor device supports it.
-
Apply: Click OK to save IP core settings.
-
Lock IP Core: In the Tcl Console, run:
set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]
-
File to Edit:
pcileech_pcie_cfg_a7.sv
-
Modify
cfg_cap_pointer
:cfg_cap_pointer <= 8'hXX; // Replace XX with donor's capability pointer
-
In PCIe IP Core: Set Max Payload Size and Max Read Request Size to match donor device.
-
In Firmware (
pcileech_pcie_cfg_a7.sv
):max_payload_size_supported <= 3'bYYY; // Binary value corresponding to donor's Max Payload Size
-
Mapping:
Payload Size (Bytes) Binary Value 128 3'b000
256 3'b001
512 3'b010
1024 3'b011
2048 3'b100
4096 3'b101
-
- File to Edit:
pcileech_pcie_cfg_a7.sv
- Add Logic to handle power state transitions if applicable.
-
In PCIe IP Core: Enable MSI or MSI-X capability and set the number of supported vectors.
-
In Firmware (
pcileech_pcie_tlp_a7.sv
):- Add Interrupt Logic to handle MSI/MSI-X interrupts.
- File to Edit:
pcileech_tlps128_bar_controller.sv
- Location:
pcileech-fpga/pcileech-wifi-main/src/pcileech_tlps128_bar_controller.sv
- Modify the address decoding logic to match the BAR sizes and addresses of the donor device.
For each enabled BAR:
- Implement Read/Write Handlers corresponding to the BAR's purpose.
- File to Edit:
pcileech_pcie_tlp_a7.sv
-
Implement logic to handle specific TLP types required by the donor device:
- Memory Read Requests
- Memory Write Requests
- Configuration Read/Write Requests
- Vendor-Defined Messages
- Verify that TLPs are correctly formatted according to PCIe specifications.
In Vivado:
- Run Synthesis
- Run Implementation
- Generate Bitstream
- Connect your FPGA device via JTAG.
- Open Hardware Manager.
- Program Device with the generated bitstream.
- Check that the FPGA appears as the donor device on the host system.
- Use donor device drivers if required.
- Test all functionalities expected from the donor device.
- Check system logs for any errors or warnings related to the device.
- Insert ILA cores to monitor internal signals if necessary.
- Use PCIe protocol analyzers to debug communication issues.
- Iterate on your firmware code to fix bugs and improve performance.