FPGA pci代码,模块完整,注释完整
PCI 目标接口核心逻辑解析
——基于pcitarget_merged.txt的工程级拆解
- 引言
在 FPGA 领域,PCI 总线依旧是板级互联的“事实标准”。一份完整、可综合的 32 bit/33 MHz 目标端 RTL,不仅要实现协议握手,还需兼顾可配置性、时序收敛与后端设备解耦。本文以pcitarget_merged.txt为蓝本,从“功能框架—地址译码—配置空间—传输引擎—异常处理”五个维度,系统梳理 PCI 目标侧的核心机制,并给出工程落地时的关键注意点。为避免源码泄露,文中仅展示必要接口与伪代码,所有时序参数已做脱敏处理。
- 顶层架构
整个设计采用“单时钟—全同步”方案,对外仅暴露标准 PCI 信号与一组后端总线。内部按功能划分为六大模块:
- glue:输入采样与三态隔离
- baseaddrchk:基址译码与命中检测
- config_mux:配置空间读写、BAR 尺寸解析、数据总线复用
- state_machine:主协议引擎,负责 DEVSEL、TRDY、STOP 等应答时序
- retry_count:防止“死等”的 16 周期超时计数器
- pargen:奇偶校验生成,满足 11 ns Tco 要求
- 地址译码与命中策略
3.1 基址寄存器模型
系统上电后,HOST 对 BAR 写入全“1”回读尺寸,随后写入实际分配地址。RTL 内部用两组 28 bit 寄存器(ba0 / ba1)锁存“可写位”,同时把“只读位”硬编码为 1 M 空间(可参数化)。
3.2 命中检测算法
采用“位与比较”方式:
hit = ((pciaddr & sizemask) == base_reg) ? 0 : 1;
优点:纯组合逻辑,无乘法器,综合后仅一级 LUT;
缺点:size 必须为 2^n,不支持稀疏映射。
工程经验:若需支持非幂次空间,可在 baseaddrchk 外层再包一层“段描述符”表,但会增加一个时钟延迟。
- 配置空间解析
4.1 读写路由
config_mux 根据地址偏移[7:2]与 IDSEL 译码,将 00h、04h、08h…3Ch 等标准寄存器映射到内部常量或寄存器。关键信号:
- cfg_en:配置事务有效
- statcomen:04h 写使能,更新命令/状态寄存器
- ba0en / ba1en:10h / 14h 写使能,更新基址
4.2 BAR 尺寸硬编码
采用parameter数组方式,把 28 bit 地址空间与 3 bit 属性(预取、位置、IO/MEM)打包成 32 bit 常量。综合工具会自动折叠为只读逻辑,不消耗寄存器。
4.3 中断线可写
3Ch 偏移的低 8 bit 定义为 Interrupt Line,可动态改写,方便操作系统做 IRQ 路由。
- 传输引擎状态机
5.1 状态划分
- IDLE:监听 FRAME、IDSEL、C/BE
- CON_WAIT:地址节拍已采样,等待 IRDY 有效
- RW_WAIT:进入数据节拍,等待后端 ready
- RW:持续数据传输(可突发)
- LAST_RW:最后一个数据节拍
- READ_WAIT:读事务专用,等后端数据返回
- RETRY:超时或后端强制重试
- ABORT:后端致命错误,置状态寄存器 Signaled Target Abort
5.2 关键握手信号
- ready_l:后端置位表示“数据有效”
- datastopl:后端拉低表示“我要断开突发”
- bkendabortl:后端拉低表示“致命错误,必须 ABORT”
5.3 超时机制
retrycount 在 RWWAIT 态启动,9 个时钟后若 ready_l 仍未有效,则强制进入 RETRY,防止总线锁死。
- 数据通路与奇偶校验
6.1 三态隔离
PCI AD[31:0] 为双向口,内部使用两组信号:
- pcidatout:目标驱动数据
- bkend_dat:后端驱动数据
通过 bkoe、pciad_oe 分时切换,避免总线冲突。
6.2 奇偶校验
FPGA pci代码,模块完整,注释完整
pargen 模块对 pcidatout 与 C/BE 按字节异或,再整体异或得到偶校验位。关键时序:
- 时钟上升沿采样数据
- 组合逻辑计算奇偶
- 下一时钟沿驱动 PAR 管脚
满足 PCI 规范 11 ns Tco(2.5 V 90 nm 工艺下约 8 ns 余量)。
- 异常与中断
7.1 后端重试
当后端无法立即响应,可拉低 readyl 并保持 datastop_l 为高,状态机在 9 周期后自动 RETRY。
7.2 后端断开
若后端仅想结束突发(非错误),则拉低 datastopl,状态机在当前节拍完成后置 STOP=0,通知主控“我已断开”。
7.3 中断传递
bkendintl 为电平信号,直接映射到 pciintal,无需同步寄存器。注意:
- 中断共享系统时,需外部上拉
- 若后端中断源为脉冲,须在外部做电平保持
- 时序收敛与工程经验
8.1 时钟域
整片仅一个 pci_clk,所有寄存器均落在同一时钟域,避免 CDC 风险。
8.2 输入寄存
glue 模块对 AD、C/BE、IDSEL 做一级寄存,即“输入打一拍”,即能提高 TIMING 余量,也能抑制毛刺。
8.3 输出三态使能
所有输出使能信号(dtsoe、paroe、bk_oe)均由状态机 combinational 产生,经一级寄存后驱动 OBUF,防止出现“使能-数据”窗口违规。
8.4 综合策略
- 对 baseaddrchk 与 configmux 设置 KEEPHIERARCHY,便于后期定位
- 对状态机采用 one-hot,综合后面积略增,但 TIMING 易收敛
- 对 pargen 采用 case 语句显化异或,防止综合器插入额外逻辑级
- 可移植性扩展
9.1 多 BAR 支持
若需 6 个 BAR,可将 baseaddrchk 例化六次,并在 config_mux 中增加 64 bit 掩码参数。
9.2 64 bit 数据位宽
只需将 AD、DAT、PAR、C/BE 位宽翻倍,状态机无需改动;奇偶校验改为 8 bit 一组异或。
9.3 66 MHz 时序
当前设计在 33 MHz 余量充足;若跑 66 MHz,需:
- 将输入寄存改为 IOB 寄存器(xilinx IOB=TRUE,Intel FASTINPUTREGISTER=ON)
- 对 pargen 插入一级流水线,牺牲一个时钟延迟换取 2 ns 余量
- 结语
pcitarget_merged.txt提供了一套“开箱即用”的 PCI 目标端 RTL,覆盖协议握手、配置空间、突发传输、异常处理等完整闭环。通过模块化分割与参数化常量的方式,既保证了可综合性与时序收敛,又为后续多 BAR、64 bit、66 MHz 等升级预留了清晰路径。对于希望在 FPGA 上快速实现 PCI 从设备的团队,可直接以此作为黄金参考,把更多精力投入到后端业务逻辑与驱动开发中。