在ARM CHI协议中,事务排序是确保多核处理器系统中数据一致性的关键机制。协议通过精细设计的响应机制和排序规则,保证了不同请求节点(RN)与主节点(HN)之间的事务执行顺序。
CHI协议定义了多种响应类型来实现事务排序控制:
关键限制:绝对不允许仅收到DataSepResp就发送CompAck,这会导致排序错误。
DBIDResp/DBIDRespOrd:数据缓冲区ID响应,用于写事务排序。Requester必须等待这些响应后才能发送下一个有序请求。
ReadReceipt:读收据响应,保证读请求已被Completer接受,避免RetryAck情况。
这些响应的交互遵循严格的时序规则。例如图B2.38所示的读事务序列中,ReadNoSnp-2必须等待ReadReceipt-1才能发出,即使遇到RetryAck也需要通过PCrdGrant机制重试,确保严格的顺序执行。
Order字段提供了四种不同强度的排序保证:
| Order[1:0] | 排序类型 | 保证范围 | 适用场景 |
|---|---|---|---|
| 0b00 | 无排序要求 | - | 普通内存访问 |
| 0b01 | 请求接受保证 | HN-F↔SN-F, HN-I↔SN-I | 读请求可靠性 |
| 0b10 | 请求顺序/OWO | 同agent同地址(ReqOrder)或全局观察顺序(OWO) | 关键数据写入序列 |
| 0b11 | 端点顺序 | 同agent同端点地址范围 | PCIe设备寄存器访问 |
特别值得注意的是OWO(Ordered Write Observation)模式,它通过以下机制保证写入顺序:
这种机制非常适合PCIe等需要严格顺序的非松弛写入场景。
内存属性定义了事务在系统中的处理方式,直接影响性能和行为一致性。
MemAttr包含四个核心位域:
EWA(Early Write Ack):是否允许中间节点提前响应
Device:内存类型标识
Cacheable:是否需缓存查找
Allocate:缓存分配建议
Device内存访问有严格限制:
markdown复制1. **读操作**:
- 禁止预取
- 禁止读取超出请求范围的数据
- 必须从端点获取数据(不能从中间写缓冲获取)
2. **写操作**:
- 禁止合并写入
- 必须严格按原始事务大小写入
- EWA=0时必须等待端点响应
3. **事务类型限制**:
- 只允许使用ReadNoSnp、WriteNoSnpPtl/Full/Zero/Def
- 禁止CMO和PrefetchTgt事务
相比之下,Normal内存允许更多优化:
表B2.11展示了属性位与ARM内存类型的对应关系:
| MemAttr[3:0] | 内存类型 | 典型特性 |
|---|---|---|
| 1-0-0-0 | Device nRnE | 严格顺序,无提前响应 |
| 0-0-1-0 | Device nRE | 允许提前响应 |
| 0-0-1-0 | Device RE | 放松顺序要求 |
| 0-0-0-0 | Normal NC-NB | 非缓存非缓冲 |
| 0-0-1-0 | Normal NC-B | 非缓存但可缓冲 |
| 0-1-1-0 | WB No-Alloc | 回写不分配 |
| 1-1-1-0 | WB Alloc | 回写建议分配 |
实际应用中,CPU的MMU会根据页表属性自动设置这些位域。
流式有序写入是CHI协议的重要优化手段,其实现要点包括:
基本流程:
死锁避免:
目标地址优化:
对于使用Multi-request的事务:
协议强制要求:
CompAck过早发送:
OWO顺序破坏:
Device内存违规:
Normal内存访问:
流式写入:
LikelyShared使用:
协议分析仪:
事务追踪:
内存属性检查器:
在实际芯片验证中,我们曾遇到一个典型案例:某PCIe设备寄存器写入偶尔失效。最终发现是OWO流程中CompAck发送条件判断不完整,导致部分写入未真正到达端点就被后续写入覆盖。通过添加严格的Comp收集状态机解决了该问题。