shobgj132/nvme-pcileech-fpga-75t
GitHub: shobgj132/nvme-pcileech-fpga-75t
在 Artix-7 75T FPGA 上实现 NVMe SSD 的 PCIe 端点仿真,用于协议学习与安全研究。
Stars: 2 | Forks: 0
# nvme-pcileech-fpga-75t
## 关于
在 Artix-7 75T FPGA 上对 NVMe 控制器进行行为仿真,面向 SM2263 系列 NVMe SSD 控制器(NE-256 参考设备)。该设计运行一个 PCIe 端点,使主机将其识别为 NVMe 存储控制器,包含 BAR0 寄存器文件、管理队列引擎和 MSI-X 支持。
本项目仅供 **硬件研究、PCIe/NVMe 协议学习与安全研究** 使用,请自行承担风险;作者不承担任何误用责任。
## 当前功能(2026-04-16)
- 带轮询调度的管理队列 + 8 个 I/O 队列对
- 单次 I/O 传输最大 32 KB,支持 PRP 列表
- SMART / 健康日志上报
- 异步事件通知(AER)
- 设置/获取特性支持
- MSI-X 中断投递
- 函数级复位(FLR)处理
- D3hot / D0 电源状态切换支持
- 多主板 BIOS/UEFI 兼容性
- 在 Artix-7 75T 上实现时序干净的构建(LUT ~43%,BRAM 50%)
## 快照
- 板级项目目录:`NVM_Express_Pcileech_FPGA_75T/`
- Vivado 项目名称:`pcileech_enigma_x1`
- 顶层模块:`nvm_express_pcileech_fpga_75t_top`
- 构建输出:`NVM_Express_Pcileech_FPGA_75T/pcileech_enigma_x1.bin`
- 构建输入工作区:`pipeline/build_inputs/`
## 仓库结构
```
NVM_Express_Pcileech_FPGA_75T/
src/
nvm_express_pcileech_fpga_75t_top.sv
nvm_express_pcileech_fpga_75t.xdc
pcileech_com.sv
pcileech_fifo.sv
pcileech_pcie_a7.sv
pcileech_tlps128_cfgspace_shadow.sv
pcileech_tlps128_bar_controller.sv
pcileech_nvme_controller.sv
pcileech_nvme_engine.sv
ip/
nvmexp_cfgspace.coe
nvmexp_cfgspace_mask.coe
nvmexp_bar0.coe
nvme_identify_ctrl.hex
nvme_identify_ns.hex
vivado_generate_project_75t.tcl
vivado_configure_profile_75t.tcl
vivado_build_75t.tcl
pipeline/
01_capture_config_profile.py
02_capture_bar0_profile.py
03_verify_identity_profile.py
04_build_init_images.py
05_crosscheck_reference.py
target_collect_configspace.ps1
target_collect_profile.ps1
build_inputs/
```
## 模块作用
| 模块 | 作用 | 关键接口 |
| --- | --- | --- |
| `nvm_express_pcileech_fpga_75t_top` | 板级外壳、复位生成、FT601 与 PCIe 顶层连接 | `clk`、`ft601_clk`、PCIe 结构、FT601 引脚 |
| `pcileech_com` | FT601 通信桥接,32 位到 64 位打包,系统域时钟交叉 | `clk_com -> clk`、`IfComToFifo` |
| `pcileech_fifo` | 命令/TLP/配置路由,连接通信核心与 PCIe 子系统 | `IfComToFifo`、`IfPCIeFifo*`、`IfShadow2Fifo` |
| `pcileech_pcie_a7` | PCIe 端点封装,锁链稳定的门控、PCIe 用户时钟域、NVMe TX 多路复用 | Xilinx `pcie_7x_0`、`IfAXIS128` |
| `pcileech_tlps128_cfgspace_shadow` | 配置空间影子 BRAM 路径,用于配置读写转发与主机侧重放 | 配置 TLP 流、影子 FIFO |
| `pcileech_tlps128_bar_controller` | BAR 读/写引擎、BAR 分发、BAR0 NVMe 寄存器文件连接 | BAR TLP 解码、读/写引擎 |
| `pcileech_nvme_controller` | BAR0 寄存器映射、CC/CSTS/AQA/ASQ/ACQ 处理、门铃、MSI-X 表存储 | BAR0 访问、引擎控制输出 |
| `pcileech_nvme_engine` | 管理 SQ 获取、命令解析/执行、DMA 写生成、CQ 写回、MSI-X 触发 | 原始 RX 完成、TX AXIS 输出 |
## 构建输入流程
构建流水线与 FPGA 项目分离,以实现更清晰的数据到构建流程。
```
flowchart LR
A["Target / Reader Capture"] --> B["pipeline/build_inputs"]
B --> C["01_capture_config_profile.py"]
B --> D["02_capture_bar0_profile.py"]
B --> E["03_verify_identity_profile.py"]
C --> F["04_build_init_images.py"]
D --> F
E --> F
B --> G["05_crosscheck_reference.py"]
F --> H["NVM_Express_Pcileech_FPGA_75T/ip"]
H --> I["Vivado Generate / Configure / Build"]
```
## 运行时架构
在运行时,FPGA 设计分为三个实用平面:
- 通信平面:FT601 主机桥接与 FIFO 传输。
- PCIe 端点平面:Xilinx PCIe 核心、配置空间影子与 BAR TLP 处理。
- NVMe 仿真平面:BAR0 寄存器文件、管理队列引擎、完成生成与 MSI-X 信号。
```
flowchart LR
subgraph Host["Host System"]
H1["PCIe Root Complex / NVMe Driver"]
H2["FT601 Control Host"]
end
subgraph FPGA["NVM_Express_Pcileech_FPGA_75T"]
subgraph Comm["Communication Plane"]
C1["pcileech_com"]
C2["pcileech_fifo"]
end
subgraph EP["PCIe Endpoint Plane"]
P1["pcileech_pcie_a7"]
P2["pcileech_pcie_cfg_a7"]
P3["pcileech_pcie_tlp_a7"]
P4["pcileech_tlps128_cfgspace_shadow"]
P5["pcileech_tlps128_bar_controller"]
end
subgraph NVMe["NVMe Emulation Plane"]
N1["pcileech_nvme_controller"]
N2["pcileech_nvme_engine"]
end
end
H2 <-- FT601 --> C1
C1 <--> C2
H1 <-- PCIe --> P1
C2 <--> P2
C2 <--> P3
C2 <--> P4
P1 --> P2
P1 --> P3
P3 --> P4
P3 --> P5
P5 --> N1
N1 --> N2
N2 --> P3
```
## 详细运行时流程
### 1. 板级上电
- `nvm_express_pcileech_fpga_75t_top` 生成复位并连接 FT601、FIFO 与 PCIe 块。
- `pcileech_pcie_a7` 在链路稳定的延迟门控后保持 PCIe 子系统。
- 延迟门控防止平台就绪前发生早期总线主控活动。
### 2. 配置空间处理
- 标准配置访问由 Xilinx PCIe 核心与管理路径中介。
- 转发的配置 TLP 可由 `pcileech_tlps128_cfgspace_shadow` 提供服务。
- 影子配置内容存储在 BRAM 中,初始化自 `nvmexp_cfgspace.coe` 与写掩码镜像。
### 3. BAR0 寄存器处理
- BAR 内存 TLP 由 `pcileech_tlps128_bar_controller` 分类。
- BAR0 请求路由至 `pcileech_nvme_controller`。
- BAR0 读返回仿真控制器值,写更新控制寄存器、队列指针、门铃与 MSI-X 表项。
### 4. 管理队列执行
- 当主机更新 SQ0 尾指针时,`pcileech_nvme_controller` 触发 `admin_sq_db_written`。
- `pcileech_nvme_engine` 发起 MRd 以获取 64 字节提交队列条目。
- 完成节拍收集到本地 SQ 缓冲区。
- 引擎解析操作码、PRP1、CDW10 与 CDW11。
- 根据命令,引擎选择内部响应源,发出 DMA 写,写入 CQ 条目,并在需要时发出 MSI-X 写。
### 5. 数据返回路径
- 标识数据来源于 `nvme_identify_ctrl.hex` 与 `nvme_identify_ns.hex`。
- 配置空间影子数据由 BRAM 支持。
- BAR0 状态由寄存器支持。
- TLP 响应通过 `pcileech_pcie_tlp_a7` 多路复用回 PCIe 发送流。
## 时钟域
| 域 | 来源 | 主要模块 | 用途 |
| --- | --- | --- | --- |
| `clk` | 100 MHz 板载时钟 | `pcileech_fifo`、顶层控制、FT601 系统侧缓冲 | 系统控制平面 |
| `ft601_clk` / `clk_com` | FT601 接口时钟 | `pcileech_com`、`pcileech_ft601` | 通信 I/O 域 |
| `clk_pcie` | 来自 `pcie_7x_0` 的 62.5 MHz PCIe 用户时钟 | `pcileech_pcie_a7`、配置影子、BAR 引擎、NVMe 引擎 | 实时 PCIe 事务域 |
当前项目配置使用 62.5 MHz PCIe 用户时钟。活动的 Vivado 配置文件将 `CONFIG.User_Clk_Freq` 设置为 `62.5`,且 RTL 中的 PCIe 侧时序常量以此值为基础。
## 事务时序
最重要的运行时路径是管理命令循环。下图映射了用于 Identify、Get Log Page 等管理命令的实际引擎流程。
```
sequenceDiagram
participant Host as Host / NVMe Driver
participant BAR0 as NVMe BAR0 Controller
participant ENG as NVMe Engine
participant PCIe as PCIe TX/RX Path
Host->>BAR0: Write SQ0 doorbell
BAR0->>ENG: Pulse admin_sq_db_written
ENG->>PCIe: MRd 64B for SQ entry
PCIe-->>ENG: CplD beats with SQE payload
ENG->>ENG: Parse opcode and command fields
alt Data payload required
loop One or more MWr TLPs
ENG->>PCIe: MWr header + payload beats
PCIe-->>Host: DMA response data
end
end
ENG->>PCIe: MWr completion queue entry
PCIe-->>Host: CQE writeback
opt MSI-X enabled and vector unmasked
ENG->>PCIe: MWr MSI-X message
PCIe-->>Host: Interrupt write
end
ENG->>ENG: Advance SQ head / CQ tail
```
## NVMe 引擎状态流
`pcileech_nvme_engine.sv` 中的内部管理引擎以下执行链:
```
stateDiagram-v2
[*] --> ST_IDLE
ST_IDLE --> ST_FETCH_SQ: sq_has_pending
ST_FETCH_SQ --> ST_WAIT_CPLD
ST_WAIT_CPLD --> ST_PARSE_CMD: 64B SQE assembled
ST_WAIT_CPLD --> ST_ADVANCE_HEAD: timeout / skip
ST_PARSE_CMD --> ST_EXECUTE
ST_EXECUTE --> ST_DMA_WRITE: data payload needed
ST_EXECUTE --> ST_CQ_HDR: CQ only
ST_EXECUTE --> ST_ADVANCE_HEAD: no CQ path
ST_DMA_WRITE --> ST_DMA_HDR
ST_DMA_HDR --> ST_DMA_DATA
ST_DMA_DATA --> ST_DMA_WRITE: more payload remains
ST_DMA_DATA --> ST_CQ_HDR: payload done
ST_CQ_HDR --> ST_CQ_DATA
ST_CQ_DATA --> ST_SEND_MSIX
ST_SEND_MSIX --> ST_MSIX_HDR: vector active
ST_SEND_MSIX --> ST_ADVANCE_HEAD: masked / disabled
ST_MSIX_HDR --> ST_MSIX_DATA
ST_MSIX_DATA --> ST_ADVANCE_HEAD
ST_ADVANCE_HEAD --> ST_IDLE
```
## 构建流程
### 1. 生成 Vivado 项目
```
cd NVM_Express_Pcileech_FPGA_75T
source vivado_generate_project_75t.tcl -notrace
```
### 2. 应用 PCIe 配置文件
```
source vivado_configure_profile_75t.tcl
```
### 3. 构建比特流
```
source vivado_build_75t.tcl -notrace
```
预期输出:
```
NVM_Express_Pcileech_FPGA_75T/pcileech_enigma_x1.bin
```
## 构建输入命令
将参考文件放置于:
```
pipeline/build_inputs/
```
然后运行:
```
python pipeline/01_capture_config_profile.py
python pipeline/02_capture_bar0_profile.py
python pipeline/03_verify_identity_profile.py
python pipeline/04_build_init_images.py
python pipeline/05_crosscheck_reference.py
```
## 致谢
- 上游:[ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga) —— 由 Ulf Frisk 提供的 PCILeech FPGA 框架(MIT 许可证)。
- 本变体:NVMe 控制器仿真层、75T 板适配与构建输入流水线。
## 许可证
MIT License —— 参见 [LICENSE](./LICENSE)。紧凑型 75T NVMe FPGA 项目,流程精简、构建输入结构化、运行文档工程化。
[](./LICENSE) [](./README.zh-CN.md)    标签:32KB 传输, 75T, admin queue, AER, Artix-7, BIOS, D0, D3hot, Feature Set, FLR, FPGA, Function Level Reset, I/O queue, MSI-X, NE-256, NVMe, NVMe SSD 控制器, PCIe, PCIe endpoint, PRP, SM2263, SMART, UEFI, Vivado, 中文文档, 仿真, 健康日志, 协议学习, 多主板兼容性, 工程化文档, 异步事件通知, 电源管理, 硬件学习, 硬件研究, 端点, 轮询调度