UDMAP:在“事件触发”模式下使用时,ICNT 和/或源地址/目标地址未与 64B 对齐的情况下 UDMA 传输失败
详细信息:
注: 以下说明以 C7x DSP 内核为例,但适用于任何可对 UDMA 进行编程的其他处理内核。
对于 C6x/C7x 上的 DSP 算法处理,软件通常使用 NavSS 中的 UDMA 或 MSMC 中的 DRU。许多情况下,使用 UDMA 而非 DRU,因为 DRU 通道在许多用例中保留用于 C7x/MMA 深度学习操作。在典型的 DSP 算法处理中,数据通过 DMA 逐块传输到 L2 存储器进行 DSP,而 DSP 对 L2 存储器中的数据执行操作而不是(通过高速缓存)从 DDR 运行。此操作的典型 DMA 设置和事件触发如下所示;在以下示例中,这被称为“2 维触发等待”。
对于每个“帧”:
- 设置 TR(通常为 3 或 4 维 TR)。
- 设置 TYPE = 4D_BLOCK_MOVE_REPACKING_INDIRECTION
- 设置 EVENT_SIZE = ICNT2_DEC
- 设置 TRIGGER0 = GLOBAL0
- 设置 TRIGGER0_TYPE = ICNT2_DEC
- 设置 TRIGGER1 = NONE
- ICNT0 x ICNT1 为块宽度 x 块高度
- ICNT2 = 块数
- ICNT3 = 1
- src addr = DDR
- dst addr = C6x L2 存储器
- 提交此 TR
- 该 TR 在 GLOBAL TRIGGER0 上启动传输并传输 ICNT0xICNT1 个字节,然后引发事件
- 对于每个块,执行以下操作:
- 通过设置 GLOBAL TRIGGER0 触发 DMA
- 等待指示块已传输的事件
- 执行 DSP 处理
该序列是简化的序列;在实际算法中,可以有多个通道以“乒乓”方式执行 DDR 到 L2 或 L2 DDR 传输,使得 DSP 处理和 DMA 并行运行。在通道 OES 寄存器中对事件本身进行了适当的编程,并使用 UDMA 的 IA 中的空闲位来完成事件状态检查。
当满足以下条件时,第一个触发器不会收到步骤 3.2 中的事件:
- 条件 1:ICNT0xICT1 不是 64 的倍数。
- 条件 2:src 或 dst 不是 64 的倍数。
- 条件 3:ICNT0xICT1 不是 64 的倍数,源地址/目标地址不是 64 的倍数
如果 ICNT0xICNT1 和源地址/目标地址是 16B 或 32B 的倍数,也存在相同的问题,即未收到事件。只有和 64B 对齐才有效。
令其有效的条件:
- 如果 ICNT0xICNT1 是 64 的倍数,并且源地址/目标地址是 64 的倍数,则测试用例通过。
- 如果使用 DRU 而不是 UDMA,则测试通过。必须通过 UDMA DRU 外部通道将 TR 提交至 DRU。使用 DRU 并且 ICNT 和源地址/目标地址未对齐的情况下,用户可以正常地触发和收到事件,前提是对 TR 进行编程,使得一个帧中的事件数量和触发次数为 1,即在上述情况下 ICNT2 = 1 或者 EVENT_SIZE = COMPLETION 且触发器为无。然后,完成事件正常发生。在相关用例中使用是不可行的。
上面是“2 维触发和等待”的示例,“1 维触发和等待”和“3 维触发和等待”的约束条件相同:
- 对于“1 维触发和等待”,ICNT0 必须是 64 的倍数
- 对于“3 维触发和等待”,ICNT0xICNT1xICNT2 必须是 64 的倍数
权变措施:
在 TR 中为 UDMAP 设置 EOL 标志,如以下示例所示:
- 1 维触发和等待
- TR.FLAGS |= CSL_FMK(UDMAP_TR_FLAGS_EOL、CSL_UDMAP_TR_FLAGS_EOL_ICNT0);
- 2 维触发和等待
- TR.FLAGS |= CSL_FMK(UDMAP_TR_FLAGS_EOL、CSL_UDMAP_TR_FLAGS_EOL_ICNT0_ICNT1);
- 3 维触发和等待
- TR.FLAGS |= CSL_FMK(UDMAP_TR_FLAGS_EOL,CSL_UDMAP_TR_FLAGS_EOL_ICNT0_ICNT1_ICNT2);
此权变措施不会影响性能。