注意:本节仅适用于7系列FPGA集成PCI Express核心的端点配置。
该核心支持以传统中断、消息信号中断(MSI)或MSI-X中断的形式发送中断请求。模式是通过MSI能力结构的消息控制寄存器中的MSI使能位和MSI-X能力结构的MSI-X消息控制寄存器中的MSI-X使能位来编程的。有关MSI和MSI-X能力结构的更多信息,请参阅PCI Local Base Specification v3.0 [参考文献2]的第6.8节。
MSI使能位和MSI-X使能位的状态分别通过cfg_interrupt_msienable
和cfg_interrupt_msixenable
输出反映。
表3-44根据核心的cfg_interrupt_msienable
和cfg_interrupt_msixenable
输出,描述了设备被编程到的中断模式。
表3-44:中断模式
cfg_interrupt_msixenable=0 | cfg_interrupt_msixenable=1 | |
---|---|---|
cfg_interrupt_msienable=0 | 传统中断(INTx)模式。cfg_interrupt 接口仅发送INTx消息。 | MSI-X模式。 您必须在传输AXI4-Stream接口上构建MWr TLP来生成MSI-X中断;不要使用 cfg_interrupt 接口。cfg_interrupt 接口是活动的并发送INTx消息,但请避免这样做。 |
cfg_interrupt_msienable=1 | MSI模式。cfg_interrupt 接口仅发送MSI中断(MWr TLP)。 | 未定义。 系统软件不应允许这种情况。然而,如果您选择这样做, cfg_interrupt 接口是活动的并发送MSI中断(MWr TLP)。 |
MSI控制寄存器中的MSI使能位、MSI-X控制寄存器中的MSI-X使能位以及PCI命令寄存器中的中断禁用位由根复合体(Root Complex)编程。用户应用程序无法直接控制这些位。核心中的内部中断控制器仅生成传统中断和MSI中断。MSI-X中断需要由用户应用程序生成并在传输AXI4-Stream接口上呈现。cfg_interrupt_msienable
的状态决定了内部中断控制器生成的中断类型:如果MSI使能位被设置为1,那么核心通过发送内存写TLP来生成MSI请求。如果MSI使能位被设置为0,只要PCI命令寄存器中的中断禁用位被设置为0,核心就生成传统中断消息:
cfg_command[10] = 0
:启用INTx中断
cfg_command[10] = 1
:禁用INTx中断(请求被核心阻止)
cfg_interrupt_msienable = 0
:传统中断
cfg_interrupt_msienable = 1
:MSI
无论使用哪种中断类型(传统或MSI),都通过cfg_interrupt
和cfg_interrupt_rdy
来启动中断请求,如表3-45所示。
表3-45:中断信号
端口名 | 方向 | 描述 |
---|---|---|
cfg_interrupt | 输入 | 断言以请求中断。保持断言,直到中断被服务。 |
cfg_interrupt_rdy | 输出 | 当核心接受信号的中断请求时断言。 |
用户应用程序以以下两种方式之一请求中断服务,每种方式将在下文中描述。
如图3-68所示,用户应用程序首先断言cfg_interrupt
和cfg_interrupt_assert
以断言中断。用户应用程序应使用cfg_interrupt_di[7:0]
选择特定的中断(INTA),如表3-46所示。
核心然后断言cfg_interrupt_rdy
以指示中断已被接受。在下一个时钟周期,用户应用程序取消断言cfg_interrupt
,并且如果PCI命令寄存器中的中断禁用位被设置为0,核心将发送一个断言中断消息(Assert_INTA)。
在用户应用程序确定中断已被服务后,它断言cfg_interrupt
,同时取消断言cfg_interrupt_assert
以取消中断。必须通过cfg_interrupt_di[7:0]
指示适当的中断。
核心然后断言cfg_interrupt_rdy
以指示中断取消已被接受。在下一个时钟周期,用户应用程序取消断言cfg_interrupt
,核心发送一个取消中断消息(Deassert_INTA)。
表3-46:传统中断映射
cfg_interrupt_di[7:0] 值 | 传统中断 |
---|---|
00h | INTA |
01h - FFh | 不支持 |
如图3-68所示,用户应用程序首先断言cfg_interrupt
。如果启用了多向量MSI,用户应用程序还需在cfg_interrupt_di[7:0]
上提供一个值。
核心断言cfg_interrupt_rdy
以表示中断已被接受,核心发送一个MSI内存写TLP。在下一个时钟周期,如果不再需要发送更多中断,用户应用程序取消断言cfg_interrupt
。
MSI请求是一个32位可寻址内存写TLP或一个64位可寻址内存写TLP。地址取自MSI能力结构的消息地址和消息上部地址字段,而有效载荷取自消息数据字段。这些值由系统软件通过对MSI能力结构的配置写入来编程。当核心配置为多向量MSI时,系统软件可以通过将非零值写入“多消息使能”字段来允许多向量MSI消息。
发送的MSI TLP类型(32位可寻址或64位可寻址)取决于MSI能力结构中上部地址字段的值。默认情况下,MSI消息被发送为32位可寻址的内存写TLP。只有当系统软件将非零值写入上部地址寄存器时,MSI消息才使用64位可寻址的内存写TLP。
当启用了多向量MSI消息时,用户应用程序可以覆盖每个传输的MSI TLP的消息数据字段中的一个或多个低位,以区分向上传输的各种MSI消息。用户应用程序可用的消息数据字段中的低位数量由Vivado IDE中设置的“多消息能力”字段的值与系统软件设置的“多消息使能”字段的值(可通过核心输出cfg_interrupt_mmenable[2:0]
获得)中的较小值决定。核心会屏蔽cfg_interrupt_di[7:0]
中未被系统软件通过“多消息使能”配置的任何位。
以下伪代码显示了所需的处理:
// 值 MSI_Vector_Num 必须在范围:0 ≤ MSI_Vector_Num ≤ (2^cfg_interrupt_mmenable) - 1 if (cfg_interrupt_msienable) { // MSI已启用 if (cfg_interrupt_mmenable > 0) { // 启用了多向量MSI cfg_interrupt_di[7:0] = {填充0, MSI_Vector_Num}; } else { // 启用了单向量MSI cfg_interrupt_di[7:0] = 填充0; } } else { // 启用了传统中断 // ... }
例如:
如果cfg_interrupt_mmenable[2:0] == 000b
,即启用了1个MSI向量,那么cfg_interrupt_di[7:0] = 00h
;
如果cfg_interrupt_mmenable[2:0] == 101b
,即启用了32个MSI向量,那么cfg_interrupt_di[7:0] = {{000b}, {MSI_Vector#}}
;
其中MSI_Vector#
是一个5位值,允许的范围是00000b ≤ MSI_Vector# ≤ 11111b
。
如果启用了逐向量屏蔽,您必须首先验证被信号通知的向量未在屏蔽寄存器中被屏蔽。这是通过在配置接口上读取该寄存器来完成的(核心不检查屏蔽寄存器)。
核心可选地支持MSI-X能力结构。MSI-X向量表和MSI-X待处理位数组需要作为您逻辑的一部分实现,通过声明一个BAR空间。
如果核心的cfg_interrupt_msixenable
输出被断言,用户应用程序应在传输AXI4-Stream接口上构建并发送MSI-X中断。