diff --git a/非对称可靠串行传输技术规范.md b/非对称可靠串行传输技术规范.md index 43e5664..2feb6d2 100644 --- a/非对称可靠串行传输技术规范.md +++ b/非对称可靠串行传输技术规范.md @@ -2,7 +2,7 @@ **Asymmetric Reliable Serial Transport Technical Specification** -**版本:V0.7**
+**版本:V0.8**
**日期:2026-10-01**
**作者:周爽** @@ -12,6 +12,7 @@ | 版本 | 日期 | 说明 | |---|---|---| +| V0.8 | 2026-10-01 | 完善重传协议的确定性实现规则;统一协议层`link_up`接口,明确最大接收能力、窗口计时切换、`POLL_REQ`、业务接口契约、状态图说明及重传验证要求。 | | V0.7 | 2026-10-01 | 完善链路训练和运行期监测的异常闭环;明确主端重启可见性、运行入口就绪时机、连续计数与超时优先级、可信方向帧边界切换、方向化重训、恢复候选帧丢弃、单个IDLE恢复、意外固定帧处理及运行期CRC错误门限。 | | V0.6 | 2026-10-01 | 完善主从同步与重新训练状态机;明确重复`SYNC_RESET`、训练应答保护、同步确认和运行入口超时;补充`IDELAY`与`ODELAY`扫描状态机;统一200帧边界搜索与测量周期;修订完整UI环形窗口、`ALL_PASS`及最小通过窗口派生规则。 | | V0.5 | 2026-09-30 | 明确链路重新训练期间的传输状态保持、恢复门控及主从状态机行为;统一`IDLE`和`CRC-32/MPEG-2`术语;修订数据协议边界、封装解析图、发送仲裁、`LEN`校验及帧内字计数规则;更新延迟配置就绪语义、`ODELAY`点间隔确认及运行入口`IDLE`握手。 | @@ -150,8 +151,13 @@ | 新会话初始化 | 同步恢复后,主端通过`POLL_REQ`确认控制帧通路可用、取得从端`WIN_BYTES`,并以响应中的`ACK_NEXT`初始化新会话发送序号的过程 | | 回退N帧(Go-Back-N) | 发生错误后从最早未确认序号开始连续重传的机制 | | 单位间隔(UI) | 一个线路位的持续时间 | +| 接收 | 线路数据进入帧解析器的过程;不表示该帧已经校验通过、被传输协议层接受或提交给上层 | +| 校验通过 | 完整线路帧的CRC和数据协议格式检查全部通过 | +| 接受 | 业务帧的`SEQ`和接收资源满足要求,传输协议层决定保留该帧 | | 提交(commit) | `CRC32`、格式、序号及资源检查完成后,将候选帧正式提交给上层 | | 回滚(rollback) | 丢弃候选帧,并保证该帧未产生任何上层可见副作用 | +| 确认 | 从端通过`ACK_NEXT`对此前已经接受的`DL DATA`业务帧进行累计确认 | +| 释放 | 主端根据有效累计确认删除对应业务帧的重传缓存和描述符 | ### 3.3 通用缩写 @@ -280,7 +286,7 @@ flowchart LR 3. 电气实现满足所选介质的眼图、抖动、共模和耦合要求; 4. 数据链路层看到的比特流满足第9章规定的位序和字节序。 -# 第二篇物理承载、时钟与链路实现配置 +# 第二篇 物理承载、时钟与链路实现配置 ## 6. 同源时钟与物理拓扑 @@ -391,7 +397,7 @@ R_{line}=N_M f_{M,parallel}=N_S f_{S,parallel} 采用AC耦合时,发送端仍必须遵循第16章的扰码规则。固定训练帧和`IDLE`依靠其预定义码型获得均衡性质。扰码不能替代通道级基线漂移、最长连续同码、抖动和眼图验证;具体物理配置必须证明最坏业务数据、最大帧和连续控制流满足接收器要求。 -# 第三篇统一数据协议 +# 第三篇 统一数据协议 ## 8. 数据协议的接口边界 @@ -706,7 +712,7 @@ FRAME_COST = 8 + LEN,单位为字节 AVAILABLE_BYTES = max(WIN_BYTES - OUTSTANDING_BYTES, 0) ``` -只有待发送帧的`FRAME_COST`不大于`AVAILABLE_BYTES`时,才允许首次发送该帧。同一`SEQ`帧的重传不得重复占用窗口额度。`WIN_BYTES`=0 时不得首次发送新的`DATA`,但仍可发送重传帧、`CTRL`、`IDLE`和固定同步类帧。缓存释放后,接收端应通过新的`ACK/UPDATE`公告更新后的`WIN_BYTES`;`POLL_REQ`可用于请求对端重新报告当前状态。 +只有待发送帧的`FRAME_COST`不大于`AVAILABLE_BYTES`时,才允许首次发送该帧。同一`SEQ`帧的重传不得重复占用窗口额度。`AVAILABLE_BYTES`=0 时不得首次发送新的`DATA`,但仍可发送已经占用窗口额度的重传帧、`CTRL`、`IDLE`和固定同步类帧。缓存释放后,接收端应通过新的`ACK/UPDATE`公告更新后的`WIN_BYTES`;`POLL_REQ`可用于请求对端重新报告当前状态。 | `FLAGS` | 名称 | 字段含义 | |---:|---|---| @@ -947,7 +953,7 @@ flowchart LR 这一规则取代“任意CRC失败立即进入边界恢复”的旧行为。 -# 第四篇链路训练、同步与运行期监测 +# 第四篇 链路训练、同步与运行期监测 ## 18. 总体同步流程 @@ -1001,7 +1007,7 @@ sequenceDiagram 14. 主端连续正确检测10个`SYNC_ACK`后,忽略可能剩余的`SYNC_ACK`,检测到第一个`UL` `SYNC`后开始连续计数; 15. 主端连续正确检测10000个`UL` `SYNC`后停止发送`SYNC`并持续发送`IDLE`; 16. 从端检测到首个完整合法的`DL IDLE`后停止发送`SYNC`,使接收方向进入运行期边界监测,并在`UL`连续发送20个`IDLE`;20个`IDLE`完整发送结束前不提交普通协议帧; -17. 主端检测到首个完整合法的`UL IDLE`后进入`M_RUN`并置位`link_sync_up`;剩余`IDLE`按正常空闲码字处理; +17. 主端检测到首个完整合法的`UL IDLE`后进入`M_RUN`并置位`link_up`;剩余`IDLE`按正常空闲码字处理; 18. 主端随后通过`POLL_REQ`确认控制帧通路并取得`WIN_BYTES`;只有新会话初始化完成后才置位`transport_ready`; 19. `SYNC`采用“持续发送、条件终止、超时失败”;不需要额外的“进入业务状态”控制帧。 @@ -1066,7 +1072,7 @@ stateDiagram-v2 | 状态 | 主要动作 | 离开条件 | |---|---|---| -| `M_WAIT_RESOURCE` | 等待时钟、MMCM/PLL和延迟控制资源可用;撤销`link_sync_up` | 资源就绪 | +| `M_WAIT_RESOURCE` | 等待时钟、MMCM/PLL和延迟控制资源可用;撤销`link_up` | 资源就绪 | | `M_RX_TRAIN` | 执行第21章`IDELAY`扫描、`UL`窗口分析和中心点装载 | 找到合法窗口;失败时持续重试 | | `M_TX_TRAIN` | 执行第22章`ODELAY`扫描、点间隔确认、`DL`窗口分析和中心点装载 | 找到合法窗口;失败时按UL健康状态选择重试范围 | | `M_DL_CONFIRM` | `DL`持续发送`SYNC`;等待从端完成10000个`DL SYNC`检测并返回`SYNC_ACK` | 连续收到10个`SYNC_ACK`;收到完整`TRAIN`;或超时 | @@ -1085,7 +1091,7 @@ stateDiagram-v2 - 进入`M_UL_CONFIRM`后,主端允许继续收到从端尚未发送完的`SYNC_ACK`;这些剩余ACK不计为错误; - `M_UL_CONFIRM`检测到第一个完整`SYNC`时将`UL SYNC`连续计数置1;此后任一非`SYNC`固定帧使计数清零,重新等待下一个完整`SYNC`作为新序列起点; - `M_RUN_ENTRY`期间`DL`持续发送`IDLE`,不允许发送协议帧;主端在已知边界完整匹配首个`UL IDLE`后立即进入`M_RUN`,不执行额外连续检测;若超时前仍持续收到完整`UL SYNC`,说明UL可信而从端未接受DL运行入口,返回`M_TX_TRAIN`;若UL也不再可靠,则返回`M_RX_TRAIN`; -- 主端进入`M_RUN`后发送`POLL_REQ`;`link_sync_up`和`transport_ready`必须按第46章分别产生; +- 主端进入`M_RUN`后发送`POLL_REQ`;`link_up`和`transport_ready`必须按第46章分别产生; - `UL`失步返回`M_RX_TRAIN`,随后依次重新训练`UL`和`DL`;能够明确判断为`DL`单向异常时,直接返回`M_TX_TRAIN`; - 点间隔发送满50个有效`IDLE`仍未收到完整`TRAIN`时,不得开始下一`ODELAY`点;UL仍可靠时重新执行完整DL训练,UL不可靠时重新训练UL和DL; - 主端主动请求从运行状态进入链路重新训练时,如果`DL`仍具备传送完整固定帧的条件,应先连续发送20个`SYNC_RESET`;从端完整检测到其中任意一个后,清除当前训练上下文并进入`S_TRAIN`;主端发送完成后根据需要进入`M_TX_TRAIN`,或者进入`M_RX_TRAIN`并在`UL`恢复后继续执行`M_TX_TRAIN`; @@ -1126,7 +1132,7 @@ stateDiagram-v2 | `S_TRAIN` | 分别累计连续`TRAIN`和连续`SYNC`;`TRAIN`达到50后等待`IDLE`结束当前测试点 | 默认连续`TRAIN`;`train_ack_active`有效时持续发送`TRAIN_ACK` | 连续收到10000个有效`SYNC` | | `S_SYNC_ACK_TX` | 继续检查`DL`是否保持`SYNC` | 连续发送20个`SYNC_ACK` | 20个完整发送结束;收到完整`TRAIN`或`SYNC_RESET`;或DL边界/资源失效 | | `S_UL_SYNC_TX` | 继续接收主端`SYNC`,检测首个完整合法`IDLE`;从进入本状态起累计固定帧时间 | 持续发送`SYNC` | 收到首个完整运行入口`IDLE`;收到完整`TRAIN`或`SYNC_RESET`;达到10500个固定帧时间;或DL边界/资源失效 | -| `S_RUN_ENTRY_IDLE_TX` | 启用运行期边界监测但不向传输协议层提交普通帧;保持`link_sync_up=0` | 连续发送20个`IDLE`,不得插入其他帧 | 完整发送20个`IDLE`后进入`S_RUN`并置位`link_sync_up`;同步丢失;收到训练固定帧;或公共资源失效 | +| `S_RUN_ENTRY_IDLE_TX` | 启用运行期边界监测但不向传输协议层提交普通帧;保持`link_up=0` | 连续发送20个`IDLE`,不得插入其他帧 | 完整发送20个`IDLE`后进入`S_RUN`并置位`link_up`;同步丢失;收到训练固定帧;或公共资源失效 | | `S_RUN` | 解析普通帧并监测同步;处理固定帧状态事件 | 优先发送待响应`CTRL`;无帧时发送`IDLE` | 失步、资源失效、`SYNC_RESET`或意外固定帧 | ### 20.3 `TRAIN_ACK`调度 @@ -1154,7 +1160,7 @@ stateDiagram-v2 从端进入`S_UL_SYNC_TX`时启动`S_UL_SYNC_TIMEOUT_FRAMES`计时。该计时按160位固定帧时间累计,固定为10500;在计满前收到首个完整合法`DL IDLE`即正常结束。计满仍未收到`DL IDLE`,或者等待期间收到完整`TRAIN`或`SYNC_RESET`、DL边界失效或公共资源失效,均放弃本次确认并返回`S_TRAIN`。通过条件和超时在同一观察单位成立时,按第18.1节由通过条件优先。 -从端在已知边界检测到首个完整合法`DL IDLE`后,使DL接收方向采用运行期边界监测规则并进入`S_RUN_ENTRY_IDLE_TX`,但保持本端`link_sync_up=0`。已经开始发送的`UL SYNC`必须完整结束;随后从端连续发送20个32位`IDLE`。第20个`IDLE`完整发送结束后,从端进入`S_RUN`并置位本端`link_sync_up`。这20个`IDLE`是运行入口响应,不用于重新验证链路质量。 +从端在已知边界检测到首个完整合法`DL IDLE`后,使DL接收方向采用运行期边界监测规则并进入`S_RUN_ENTRY_IDLE_TX`,但保持本端`link_up=0`。已经开始发送的`UL SYNC`必须完整结束;随后从端连续发送20个32位`IDLE`。第20个`IDLE`完整发送结束后,从端进入`S_RUN`并置位本端`link_up`。这20个`IDLE`是运行入口响应,不用于重新验证链路质量。 从端发送20个`IDLE`期间不得向传输协议层提交普通`DATA`或`CTRL`;期间收到的`POLL_REQ`不锁存、不响应。主端如果尚未收到初始状态响应,必须按`T_POLL_INTERVAL`重新发送`POLL_REQ`。业务应用层的UL发送请求在运行入口序列完成前不得上线。该状态不设置普通流程超时,状态转换以完整发送20个`IDLE`为准;同步丢失、收到训练固定帧或`SYNC_RESET`时返回`S_TRAIN`,公共资源失效时进入`S_WAIT_RESOURCE`。 @@ -1197,7 +1203,7 @@ stateDiagram-v2 | `RX_ANALYZE_WINDOW` | 找最长连续通过区间并选择中心 | 有合法窗口或失败 | | `RX_LOAD_CENTER` | 请求装载中心延迟档位,等待`rx_delay_ready`并重新建立字边界 | 完成后进入`DL`扫描 | -`rx_delay_ready`是抽象就绪条件,表示当前请求的`IDELAY`配置已经生效且接收路径可以开始有效测量。本规范不规定它由器件状态信号、固定等待周期、配置回读还是其他机制产生。设置请求未被接受或就绪条件长期无效时,状态机可以保持在`RX_SET_DELAY`、`RX_WAIT_DELAY_READY`或`RX_LOAD_CENTER`,本规范不要求统一超时;挂起期间必须保持`link_sync_up=0`和`transport_ready=0`,不得启动200帧单点计时、搜索候选边界、累计`TRAIN`、更新扫描位图或发送普通协议帧。资源全局就绪状态撤销时进入`M_WAIT_RESOURCE`,不得把该事件记录为普通失败点。 +`rx_delay_ready`是抽象就绪条件,表示当前请求的`IDELAY`配置已经生效且接收路径可以开始有效测量。本规范不规定它由器件状态信号、固定等待周期、配置回读还是其他机制产生。设置请求未被接受或就绪条件长期无效时,状态机可以保持在`RX_SET_DELAY`、`RX_WAIT_DELAY_READY`或`RX_LOAD_CENTER`,本规范不要求统一超时;挂起期间必须保持`link_up=0`和`transport_ready=0`,不得启动200帧单点计时、搜索候选边界、累计`TRAIN`、更新扫描位图或发送普通协议帧。资源全局就绪状态撤销时进入`M_WAIT_RESOURCE`,不得把该事件记录为普通失败点。 ### 21.3 测试点判定 @@ -1261,7 +1267,7 @@ stateDiagram-v2 | `TX_ANALYZE_WINDOW` | 找最长连续通过区间并选择中心 | 有合法窗口或失败 | | `TX_LOAD_CENTER` | 请求装载中心延迟档位并等待`tx_delay_ready` | 就绪后进入双向`SYNC`确认 | -`tx_delay_ready`是抽象就绪条件,表示当前请求的`ODELAY`配置已经生效且发送路径可以开始有效测量。本规范不规定它由器件状态信号、固定等待周期、配置回读还是其他机制产生。设置请求未被接受或就绪条件长期无效时,状态机可以保持在`TX_SET_DELAY`、`TX_WAIT_DELAY_READY`或`TX_LOAD_CENTER`,本规范不要求统一超时;挂起期间必须保持`link_sync_up=0`和`transport_ready=0`,不得记录扫描结果或发送普通协议帧。延迟切换期间的线路输出不参与任何测试点判定;只有`tx_delay_ready=1`后才能清除旧ACK历史并开始新的`TRAIN`序列和200帧计时。资源全局就绪状态撤销时进入`M_WAIT_RESOURCE`。 +`tx_delay_ready`是抽象就绪条件,表示当前请求的`ODELAY`配置已经生效且发送路径可以开始有效测量。本规范不规定它由器件状态信号、固定等待周期、配置回读还是其他机制产生。设置请求未被接受或就绪条件长期无效时,状态机可以保持在`TX_SET_DELAY`、`TX_WAIT_DELAY_READY`或`TX_LOAD_CENTER`,本规范不要求统一超时;挂起期间必须保持`link_up=0`和`transport_ready=0`,不得记录扫描结果或发送普通协议帧。延迟切换期间的线路输出不参与任何测试点判定;只有`tx_delay_ready=1`后才能清除旧ACK历史并开始新的`TRAIN`序列和200帧计时。资源全局就绪状态撤销时进入`M_WAIT_RESOURCE`。 ### 22.3 测试点判定与应答归属 @@ -1385,7 +1391,7 @@ stateDiagram-v2 MON_LOCKED_BOUNDARY --> MON_RECOVERY: unknown word or illegal length MON_IN_FRAME --> MON_RECOVERY: boundary_invalid MON_RECOVERY --> MON_LOCKED_BOUNDARY: recovery_confirmed / resume at next boundary - MON_RECOVERY --> MON_SYNC_LOST: search_limit_reached / deassert link_sync_up + MON_RECOVERY --> MON_SYNC_LOST: search_limit_reached / deassert link_up MON_LOCKED_BOUNDARY --> MON_SYNC_LOST: receive resource unavailable MON_IN_FRAME --> MON_SYNC_LOST: receive resource unavailable ``` @@ -1404,7 +1410,7 @@ stateDiagram-v2 边界确定必须遵循以下优先级: -1. 接收资源不可用时,当前数据和边界均不可信,必须撤销`link_sync_up`并进入资源恢复或重新训练; +1. 接收资源不可用时,当前数据和边界均不可信,必须撤销`link_up`并进入资源恢复或重新训练; 2. 实现明确报告当前接收边界不再可信时,必须丢弃当前未完成帧、清除解析历史并进入`MON_RECOVERY`; 3. 已经进入普通帧且未发生上述事件时,只能根据该帧已验证的长度计算结束位置; 4. 仅在预期帧边界上识别`IDLE`和`SOF`; @@ -1427,7 +1433,7 @@ stateDiagram-v2 | `LEN`被误码改变但仍落在合法范围 | 接收端暂时无法识别该错误,按收到的`LEN`计数 | 在计算位置校验CRC和下一标志 | CRC或下一标志通常失败,随后进入恢复;等待时间受最大帧长限制 | | 预期边界出现未知32位字 | 原边界与线路内容不一致 | 无法计算下一边界 | 立即进入恢复 | | 实现明确报告当前接收边界或连续数据不再可信 | 原有32位边界不再可信 | 不沿用任何旧长度或边界历史 | 丢弃当前未完成帧,清除解析历史并进入恢复 | -| 接收资源不可用 | 当前接收数据不可信 | 不执行边界搜索 | 立即撤销`link_sync_up`并进入资源恢复或重新训练 | +| 接收资源不可用 | 当前接收数据不可信 | 不执行边界搜索 | 立即撤销`link_up`并进入资源恢复或重新训练 | | 普通帧无缝背靠背发送 | 前一帧长度确定后一帧起点 | 前一帧下一边界直接匹配后一帧`SOF` | 不要求两帧之间插入`IDLE` | `DATA`的线路帧总长度为 `LINE_FRAME_BYTES = 12 + LEN` 字节;`CTRL`固定为16字节;固定训练类帧固定为20字节;`IDLE`固定为4字节。因此,在已知帧起点和合法`LEN`时,RTL应使用字计数直接生成 `expected_next_boundary`,不得通过搜索载荷中的`SOF`推测帧尾。 @@ -1449,7 +1455,7 @@ stateDiagram-v2 ### 25.5 边界恢复搜索 -进入`MON_RECOVERY`时,必须清除当前帧类型、剩余长度、解扰状态、CRC状态、暂定边界标志和此前的`SOF`匹配历史,并禁止向传输协议层提交数据。进入`MON_RECOVERY`本身不撤销`link_sync_up`,也不复位当前传输协议会话;只有恢复搜索失败并产生`sync_lost`时才执行会话复位。 +进入`MON_RECOVERY`时,必须清除当前帧类型、剩余长度、解扰状态、CRC状态、暂定边界标志和此前的`SOF`匹配历史,并禁止向传输协议层提交数据。进入`MON_RECOVERY`本身不撤销`link_up`,也不复位当前传输协议会话;只有恢复搜索失败并产生`sync_lost`时才执行会话复位。 当物理接口适配逻辑输出的当前接收分组仍可信、只有32位协议字起点未知时: @@ -1473,7 +1479,7 @@ stateDiagram-v2 `RECOVERY_SEARCH_LIMIT_WORDS`从进入`MON_RECOVERY`并完成历史清除后的第一个32位接收字开始计数。恢复条件和搜索上限在同一字成立时,恢复成功优先。搜索上限不得小于`2 × MAX_LINE_FRAME_WORDS`加实现所需的接收对齐候选搜索余量;当前最大线路帧为261个32位字,因此不含额外候选余量的基础下限为522个32位字时间。 -恢复成功后,将确认候选结束后的下一位置设为新的可信边界,并为下一帧重新初始化解扰和CRC状态。达到搜索上限仍不能确认时,置位`sync_lost`、撤销`link_sync_up`并按第26.2节复位当前协议会话和进入方向化重新训练。 +恢复成功后,将确认候选结束后的下一位置设为新的可信边界,并为下一帧重新初始化解扰和CRC状态。达到搜索上限仍不能确认时,置位`sync_lost`、撤销`link_up`并按第26.2节复位当前协议会话和进入方向化重新训练。 ### 25.6 角色相关固定帧处理 @@ -1534,13 +1540,13 @@ CRC_ERROR_RETRAIN_THRESHOLD = 8 #### 26.2.1 协议层可见的链路状态 -`link_sync_up`是提供给传输协议层的聚合链路状态,只有同时满足以下条件时才允许为1: +`link_up`是提供给传输协议层的聚合链路状态,只有同时满足以下条件时才允许为1: ```text -link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete +link_up = ul_sync_up && dl_sync_up && run_entry_complete ``` -`ul_sync_up`和`dl_sync_up`可作为链路同步层内部状态或诊断输出;传输协议层不得因为其中一个方向仍可信而继续处理原会话业务。任一方向同步丢失时,检测端必须立即撤销`link_sync_up`。另一端通过仍可信方向上的链路层训练序列或同步状态变化获知异常后,也必须撤销`link_sync_up`。只有双方完成规定范围内的重新训练及运行入口过程后,才能重新置位`link_sync_up`。 +`ul_sync_up`和`dl_sync_up`可作为链路同步层内部状态或诊断输出;传输协议层不得因为其中一个方向仍可信而继续处理原会话业务。任一方向同步丢失时,检测端必须立即撤销`link_up`。另一端通过仍可信方向上的链路层训练序列或同步状态变化获知异常后,也必须撤销`link_up`。只有双方完成规定范围内的重新训练及运行入口过程后,才能重新置位`link_up`。 #### 26.2.2 重新训练方向 @@ -1557,7 +1563,7 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete #### 26.2.3 协议复位动作 -任意传输状态下,只要`link_sync_up`撤销、`sync_lost`有效或数据链路层进入`retrain_busy`,传输协议层必须立即撤销`transport_ready`,停止接受新的业务发送请求,并进入协议复位保持状态。必须执行以下动作: +任意传输状态下,只要`link_up`撤销,传输协议层必须立即撤销`transport_ready`,停止接受新的业务发送请求,并进入协议复位保持状态。必须执行以下动作: 1. 停止并清除`T_ACK_WAIT`、`T_POLL_INTERVAL`、`T_PROGRESS_LIMIT`以及连续失败计数; 2. 中止尚未完成线路发送的普通协议帧;不得把`tx_frame_abort`当作`tx_frame_done`; @@ -1571,7 +1577,7 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete #### 26.2.4 重新训练期间的行为 -传输协议层在`link_sync_up=0`期间保持复位,不得发送或接受普通`DATA`和`CTRL`,不得推进业务序号,也不得启动协议超时。数据链路层只允许发送重新训练和同步流程规定的固定帧、训练应答及运行入口序列。 +传输协议层在`link_up=0`期间保持复位,不得发送或接受普通`DATA`和`CTRL`,不得推进业务序号,也不得启动协议超时。数据链路层只允许发送重新训练和同步流程规定的固定帧、训练应答及运行入口序列。 `DL`异常且`UL`仍可信时,从端通过`UL`发送的`TRAIN`或规范规定的链路层状态,使主端得知`DL`异常并进入`DL`重新训练;该信息属于链路同步层,不得解释为传输协议业务。 @@ -1579,7 +1585,7 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete 规定范围内的重新训练和运行入口过程完成后,按照以下顺序建立新会话: -1. 双方链路同步层置位`link_sync_up`并产生`retrain_done`;双方传输协议状态仍保持第26.2.3节规定的初始值,`transport_ready`保持为0; +1. 双方数据链路层重新置位各自的`link_up`;双方传输协议状态仍保持第26.2.3节规定的初始值,`transport_ready`保持为0; 2. 主端进入`M_WAIT_STATUS`并置位`POLL_PENDING`; 3. 从端进入`S_EXPECT`。收到合法`POLL_REQ`后,以`ACK_NEXT=0`和当前实际`WIN_BYTES`形成状态`CTRL`; 4. 从端必须在该初始状态响应中发送`ACK_NEXT=0`。主端只要求响应帧的格式和CRC合法,不使用`ACK_NEXT`作为新会话准入条件;主端把收到的`ACK_NEXT`解释为新会话起始序号,原子设置`SND_UNA=ACK_NEXT`和`SND_NXT=ACK_NEXT`,保持`OUTSTANDING_BYTES=0`及重传缓存为空,并装载响应中的`WIN_BYTES`; @@ -1646,7 +1652,7 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete 计数器按包含终值设计时,50计数至少6位,200计数至少8位,300计数至少9位,10计数至少4位,20计数至少5位,10000和10500计数至少14位。所有连续计数器达到终值后应饱和或立即触发状态转换,不允许回卷。 -# 第五篇非对称可靠传输与重传机制 +# 第五篇 非对称可靠传输与重传机制 ## 28. 传输机制范围、目标与边界 @@ -1654,7 +1660,9 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete 本规范定义链路同步完成后的业务确认、接收窗口、超时查询、Go-Back-N重传和连续失败后的重新训练触发机制。 -本规范使用《数据协议标准》中定义的`DATA`、`CTRL`、`IDLE`和固定同步类帧,不重新定义帧格式、CRC、扰码或线路位序。同步训练、延迟校准和完整协议复位流程由链路同步规范定义。 +本篇使用第三篇“统一数据协议”(第8章至第17章)定义的`DATA`、`CTRL`、`IDLE`和固定同步类帧,不重复定义帧格式、CRC、扰码或线路位序。其中,公共编码和线路位序见第9章,帧类型与标识见第10章,固定同步类帧见第11章,`DATA`和`CTRL`格式分别见第12章和第14章,CRC与扰码规则分别见第15章和第16章,封装与解析规则见第17章。 + +同步训练、延迟校准、运行期同步监测和重新训练机制由第四篇(第18章至第27章)规定;同步丢失后的传输协议会话复位见第26.2节,传输状态机及层间恢复接口分别见第35章和第46章。 ### 28.2 设计目标 @@ -1665,23 +1673,6 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete 本文中的“业务帧”仅指带`SEQ`的`DATA`。重传层不解释`DATA`载荷。`CTRL`、`IDLE`及固定同步类帧不属于业务序号空间,不进入重传缓存,也不消耗`WIN_BYTES`。 -### 28.3 规范性用语 - -- **必须、不得**:实现兼容所需的强制行为。 -- **建议**:推荐行为,允许在不影响线路互操作和可靠性的前提下采用等效实现。 -- **可以**:可选实现方式。 - -### 28.4 术语边界 - -| 术语 | 本文中的固定含义 | -|---|---| -| 接收 | 线路数据进入帧解析器 | -| 校验通过 | CRC和数据协议格式全部正确 | -| 接受 | `SEQ`正确、资源充足,传输层决定保留该帧 | -| 提交 | 完整帧通过接收缓冲或提交接口交给上层 | -| 确认 | 从端通过`ACK_NEXT`累计确认业务序号 | -| 释放 | 主端删除已确认帧的重传缓存和描述符 | - ## 29. 机制总览 本章用于建立整体运行模型;第 30 章以后给出规范性实现细节。 @@ -1696,7 +1687,7 @@ link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete - 检查累计ACK的合理性并释放缓存; - 在ACK无进展时发送`POLL_REQ`; - 根据`RETRY_REQ`或超时执行Go-Back-N; -- 连续三轮重传无进展时触发重新训练。 +- 连续三轮重传无进展时报告可靠链路故障和会话中止,清空旧会话缓存并触发重新训练。 从端负责: @@ -1724,13 +1715,13 @@ Master释放重传缓存、更新窗口并继续发送 ↓ 发生错误:RETRY_REQ或超时触发Go-Back-N ↓ -连续三轮重传无进展:保留缓存并触发retrain +连续三轮重传无进展:报告可靠链路故障和会话中止,清空旧会话缓存并触发重新训练 ``` ### 29.3 总体数据流 ```mermaid -flowchart RL +flowchart LR subgraph MASTER["Master"] direction TB MU[Master上层发送] @@ -1838,7 +1829,7 @@ AVAILABLE_BYTES = max(PEER_WIN_BYTES - OUTSTANDING_BYTES, 0) 主端必须保存每个未确认`DATA`的不含CRC、未加扰逻辑帧: ```text -SOF + SEQ + LEN + PAYLOAD + CRC32 +SOF + SEQ + LEN + PAYLOAD ``` 推荐实现: @@ -1850,7 +1841,7 @@ SOF + SEQ + LEN + PAYLOAD + CRC32 重传不得重新分配`SEQ`。重传时,主端从`SOF`开始重新输出同一逻辑帧;数据链路层重新计算并追加CRC,再从规定初值重新执行逐帧扰码。 -只有合法累计ACK才能释放缓存。超时、完成重传、无效`CTRL`和物理重新训练均不得直接释放未确认帧。 +只有合法累计ACK才能将未确认帧作为成功传输而释放。超时、完成重传和无效`CTRL`不得释放未确认帧。进入重新训练时,必须按第26.2节中止当前会话并清空未确认帧、描述符和重传缓存,但不得将这些帧报告为成功。 ### 30.6 必须保持的不变量 @@ -1906,7 +1897,7 @@ Slave: RETRY_PENDING = 0 ``` -主端主动发送`POLL_REQ`。为使其字段确定,规定: +主端主动发送`POLL_REQ`。初始化和运行期的所有`POLL_REQ`均使用以下固定字段;从端只根据`FLAGS=POLL_REQ`执行状态查询,`ACK_NEXT`和`WIN_BYTES`仍参与格式与CRC检查,但不得被解释为主端对UL业务的确认或窗口公告: ```text FLAGS = POLL_REQ @@ -1920,7 +1911,7 @@ WIN_BYTES = 32'h00000000 ```text FLAGS = ACK/UPDATE ACK_NEXT = 0 -WIN_BYTES = 当前可用的协议层逻辑帧接收窗口 +WIN_BYTES = 以当前ACK_NEXT为锚点、当前能够承诺的协议层逻辑帧接收总额度 ``` 主端收到合法初始响应前不得发送`DATA`。若`WIN_BYTES`为0,主端保持等待并按T_POLL_INTERVAL间隔重新`POLL_REQ`。 @@ -1988,7 +1979,7 @@ ACK_PENDING = 1 ```text FLAGS = ACK/UPDATE ACK_NEXT = RCV_NEXT -WIN_BYTES = 当前可用的协议层逻辑帧接收窗口 +WIN_BYTES = 以当前ACK_NEXT为锚点、当前能够承诺的协议层逻辑帧接收总额度 ``` 开始发送状态`CTRL`时,从端锁存字段并清除本次快照已经覆盖的`ACK_PENDING`。随后发生的新事件具有更高时序优先级,必须重新置位`ACK_PENDING`。 @@ -2039,6 +2030,8 @@ WIN_BYTES <= 12 × free_frame_descriptor_count 最终公告值取上述约束的较小值并向下对齐到4字节。等效的、更保守的资源计算也可以使用,但不得出现主端按已公告`WIN_BYTES`合法发送后从端因描述符不足而拒绝帧的情况。 +为保证任意合法`DATA`均可取得发送进展,从端实现必须至少能够为一个最大`DATA`逻辑帧提供1040 B接收窗口,并至少提供一个能够描述该帧的接收描述符。该容量是实现能力下限;运行时仍可因缓存被占用而暂时公告较小窗口或零窗口。 + 一个帧被接受时按`FRAME_COST`占用资源;对应接收缓冲被上层释放时归还相同额度。从端必须保证已经公布的窗口不会被其他内部用途占用。 正常窗口变化随下一次累计ACK报告。为避免零窗口死锁,`WIN_BYTES`从0恢复为非0时,即使没有新业务帧被接受,从端也必须主动置位`ACK_PENDING`并发送`ACK/UPDATE`。 @@ -2089,7 +2082,7 @@ sequenceDiagram participant M as Master participant S as Slave - M->>S: DATA, SEQ=2,线路损坏 + M->>S: DATA, SEQ=2(CRC校验失败) S->>S: 丢弃,RCV_NEXT保持2 M->>S: DATA, SEQ=3 S->>S: SEQ不等于RCV_NEXT,丢弃 @@ -2134,7 +2127,7 @@ ACK_PENDING = 1 ```text FLAGS = RETRY_REQ ACK_NEXT = RCV_NEXT -WIN_BYTES = 当前实际可用的协议层逻辑帧接收窗口 +WIN_BYTES = 以当前ACK_NEXT为锚点、当前能够承诺的协议层逻辑帧接收总额度 ``` 只有正确接受`RCV_NEXT`对应帧才能清除`RETRY_PENDING`。发送一次`RETRY_REQ`不得清除`RETRY_PENDING`。 @@ -2154,11 +2147,12 @@ WIN_BYTES = 当前实际可用的协议层逻辑帧接收窗口 - 若`ACK_NEXT`相对原`SND_UNA`发生推进,按正常前进ACK清零连续失败计数;若未推进,则不得把它计作ACK进展; - 根据新窗口返回正常发送状态:有待发送帧且窗口足够时允许首次发送,否则等待窗口更新或上层业务。 -3. 如果 `ACK_NEXT != SND_NXT`,停止首次发送新业务帧。 -4. 设置 `RETX_PTR=ACK_NEXT`。 -5. 按原`SEQ`顺序重传未确认帧。 -6. 不增加`OUTSTANDING_BYTES`,不分配新`SEQ`,不建立新描述符。 -7. 重传结束后等待从端主动累计ACK;T_ACK_WAIT无进展时发送`POLL_REQ`。 +3. 如果 `ACK_NEXT != SND_NXT`,主端必须先验证区间`[ACK_NEXT, SND_NXT)`中的每个`SEQ`均恰好存在一个重传描述符及其对应缓存内容。若任一项缺失、重复或无法读取,主端必须将其判定为本地传输协议状态损坏;不得继续重传,也不得将任何未确认帧报告为成功。主端必须报告当前会话中止,撤销`transport_ready`,清空当前协议状态,置位`retrain_request`并进入`M_RETRAIN`,按第26.2节重新训练和建立新会话。 +4. 上述一致性检查通过后,停止首次发送新业务帧。 +5. 设置 `RETX_PTR=ACK_NEXT`。 +6. 按原`SEQ`顺序重传未确认帧。 +7. 不增加`OUTSTANDING_BYTES`,不分配新`SEQ`,不建立新描述符。 +8. 重传结束后等待从端主动累计ACK;T_ACK_WAIT无进展时发送`POLL_REQ`。 若重传期间收到更大的合法`ACK_NEXT`,主端立即释放已确认前缀,并从新的`SND_UNA`继续,不得重传已经累计确认的帧。 @@ -2188,7 +2182,7 @@ ACK使用累计确认。某个ACK丢失时,后续更大的`ACK_NEXT`覆盖它 否则: FLAGS=ACK/UPDATE ACK_NEXT = RCV_NEXT -WIN_BYTES = 当前实际可用的协议层逻辑帧接收窗口 +WIN_BYTES = 以当前ACK_NEXT为锚点、当前能够承诺的协议层逻辑帧接收总额度 ``` 主端无需判断是`POLL_REQ`丢失还是响应丢失;两者均按没有收到合法状态处理。 @@ -2199,48 +2193,103 @@ WIN_BYTES = 当前实际可用的协议层逻辑帧接收窗口 窗口不足不允许主端绕过限制发送新帧。`CTRL`不消耗窗口,因此任何窗口值下都可以发送`POLL_REQ`。 +#### 32.6.1 单纯窗口不足的确定性问询流程 + +“单纯窗口不足”必须同时满足: + +```text +存在等待首次发送的业务帧 +OUTSTANDING_BYTES == 0 +FRAME_COST > AVAILABLE_BYTES +link_up == 1 +transport_ready == 1 +``` + +该状态只表示当前窗口不能容纳队首待发送业务帧,不表示ACK丢失、业务帧传输失败或链路同步异常。主端必须执行以下流程: + +1. 保持在`M_RUN`,停止首次发送该业务帧;不得为其分配`SEQ`,不得写入重传缓存,也不得改变`SND_NXT`或`OUTSTANDING_BYTES`; +2. 进入单纯窗口等待的同周期清零并启动窗口问询计时器,计时间隔为`T_POLL_INTERVAL`; +3. 计时期间优先等待从端主动发送的`ACK/UPDATE`;从端在`WIN_BYTES`从0恢复为非0时仍必须按第31.7节主动报告; +4. 收到合法状态`CTRL`时,先装载最新`PEER_WIN_BYTES`并重新计算`AVAILABLE_BYTES`; +5. 若队首业务帧满足`FRAME_COST <= AVAILABLE_BYTES`,停止并清零窗口问询计时器,取消尚未开始发送的本次`POLL_REQ`,随后按第31.3节执行首次发送;已经开始发送的`POLL_REQ`必须完整结束; +6. 若收到合法状态后窗口仍不足,取消仅由本次窗口问询产生且尚未开始发送的`POLL_PENDING`,清零并重新启动完整的`T_POLL_INTERVAL`,不得在同一周期发送新的`POLL_REQ`; +7. 若计时达到`T_POLL_INTERVAL`且此前未取得足够窗口,置位一次`POLL_PENDING`并暂停该计时器;`POLL_PENDING`已经为1时不得重复累计新的请求; +8. `POLL_REQ`开始发送时清除本次已经覆盖的`POLL_PENDING`;该帧完整发送结束时清零、重新启动下一次`T_POLL_INTERVAL`。若请求或响应丢失,下一周期继续查询; +9. 如果等待首次发送的业务请求被业务应用层撤销或当前已经没有待发送业务帧,停止并清零窗口问询计时器,取消尚未开始发送的窗口查询; +10. `link_up`撤销或进入`M_RETRAIN`时,立即停止并清零窗口问询计时器,后续按第26.2节处理。 + +单纯窗口不足期间不得启动`T_ACK_WAIT`、`T_PROGRESS_LIMIT`、Go-Back-N或连续重传失败计数,也不得仅因等待时间较长而触发重新训练。`POLL_REQ`和从端返回的状态`CTRL`不消耗业务窗口。 + +若`OUTSTANDING_BYTES != 0`,则不适用本节的独立窗口问询流程。主端必须继续使用针对最早未确认帧的ACK进度计时器:`T_ACK_WAIT`到期后发送第一次`POLL_REQ`,其后按`T_POLL_INTERVAL`查询,并按`T_PROGRESS_LIMIT`决定是否启动或判定一轮Go-Back-N。 + +两种计时模式必须按以下条件原子切换:合法前进ACK清除最后一个未确认帧后,如果仍有队首待发送帧且窗口不足,必须在该次ACK处理完成时停止ACK进度计时并启动单纯窗口问询计时;单纯窗口等待结束并完成首个新业务帧发送后,必须停止窗口问询计时,并在该帧`tx_frame_done`时启动ACK进度计时。任何时刻不得同时启用两种计时解释。 + +采用第7.3节的750 Mbps典型配置时,`T_POLL_INTERVAL=20 μs`,即187.5 MHz时钟的3750个周期。其他物理配置按第33.1节计算。 + ### 32.7 主端估算窗口与从端本地窗口不一致 -主端的`AVAILABLE_BYTES`是最近状态快照基础上的保守估计,从端的`WIN_BYTES`是实时本地状态,两者不要求每个时刻数值相等。 +主端的`AVAILABLE_BYTES`由最近一次合法窗口公告及本地未确认帧记账计算;从端内部的瞬时空闲资源还会受到已保留额度和上层释放时机影响,两者不要求每个时刻数值相等,但从端必须始终兑现已经公告的窗口承诺。 #### 32.7.1 主端低估窗口 主端低估只降低吞吐率。主端停止新帧并等待`ACK/UPDATE`,或在T_POLL_INTERVAL后`POLL_REQ`。收到最新状态后重新计算。 -#### 32.7.2 主端高估窗口 +#### 32.7.2 主端高估窗口或窗口承诺不一致 -从端必须在接受每帧前独立检查本地资源。如果空间不足: +`WIN_BYTES`是以对应`ACK_NEXT`为锚点的接收能力承诺,不是可以撤销的瞬时空闲空间。从端发布窗口后,必须为主端依据该窗口合法发送的业务帧保留足够的帧缓存和描述符资源,直至相应业务帧被累计确认或当前协议会话终止。 -1. 丢弃该帧; -2. 不推进`RCV_NEXT`; -3. 发送 `RETRY_REQ + 当前ACK_NEXT + 实际WIN_BYTES`。 - -主端收到状态后从描述符FIFO重新求和,不得只相信增量计数: +主端收到合法`CTRL`后,必须先按`ACK_NEXT`释放已经累计确认的前缀,再从剩余描述符重新计算: ```text -OUTSTANDING_BYTES = 当前全部未确认描述符FRAME_COST之和 +OUTSTANDING_BYTES += [SND_UNA, SND_NXT)中全部未确认业务帧的FRAME_COST之和 + +PEER_WIN_BYTES += 本CTRL中与ACK_NEXT对应的WIN_BYTES + +AVAILABLE_BYTES += PEER_WIN_BYTES - OUTSTANDING_BYTES ``` -若: +对于符合本规范的窗口公告,必须满足: ```text OUTSTANDING_BYTES <= PEER_WIN_BYTES ``` -可以按正常Go-Back-N重传。若不满足,主端进入窗口重新同步状态: +`OUTSTANDING_BYTES`对应的接收能力已经由从端授予。同一`SEQ`的重传不产生新的窗口占用,因此即使`AVAILABLE_BYTES=0`,主端仍可以重传现有未确认帧;`AVAILABLE_BYTES=0`只禁止首次发送新的业务帧。 -1. 停止首次发送新帧; -2. 保留全部未确认缓存; -3. 从`SND_UNA`开始,只重传累计`FRAME_COST`不超过当前`WIN_BYTES`的最长连续前缀; -4. 若第一个未确认帧也无法容纳,则等待窗口更新并`POLL_REQ`; -5. 收到前进ACK后重新计算,再发送下一批。 +如果主端仅在: + +```text +FRAME_COST <= AVAILABLE_BYTES +``` + +时首次发送业务帧,则从端不得因为本地帧缓存或描述符不足而拒绝该帧或其后续重传。新的窗口公告不得撤销已经由旧窗口合法授予并被主端占用的接收能力。 + +出现以下任一情况时,表示窗口承诺或本地协议状态已经不一致: + +1. 主端处理合法`CTRL`并释放确认前缀后,得到`OUTSTANDING_BYTES > PEER_WIN_BYTES`; +2. 从端无法为主端依据已公告窗口合法首次发送的期望`SEQ`帧提供接收资源; +3. 从端无法接收已经占用窗口额度的未确认帧重传; +4. 主端的窗口记账、未确认描述符或重传缓存与`SND_UNA`、`SND_NXT`不一致。 + +上述情况不得通过缩小重传范围、等待窗口增大或重复发送`POLL_REQ`继续当前会话。检测端必须: + +1. 停止首次发送和重传业务帧; +2. 报告窗口承诺或本地协议状态一致性故障; +3. 将全部未完成业务请求报告为会话中止,不得报告为成功; +4. 撤销`transport_ready`并清空当前传输协议状态; +5. 触发重新训练,并按第26.2节建立新会话。 + +主端估算值与从端内部瞬时空闲资源可以在数值上不同,但只要双方仍满足已经公告的窗口承诺,这种差异不构成错误,也不需要专门的“窗口重新同步状态”。 ### 32.8 Go-Back-N轮次 一次Go-Back-N轮次定义为: 1. 冻结 `RETX_END=SND_NXT`。 -2. 从`SND_UNA`开始按`SEQ`顺序重传到 `RETX_END-1`;窗口重新同步状态下按第32.7节分批。 +2. 从`SND_UNA`开始按`SEQ`顺序重传到`RETX_END-1`;重传不重复占用窗口额度,也不按当前`AVAILABLE_BYTES`缩小范围。 3. 重传期间不首次发送新业务帧。 4. 重传完成后重新开始T_PROGRESS_LIMIT进度计时。 5. T_ACK_WAIT和T_ACK_WAIT+T_POLL_INTERVAL到期时发送`POLL_REQ`。 @@ -2300,7 +2349,7 @@ T_MAX_FRAME + T_CTRL + Slave处理延迟 + CDC/传播/抖动裕量 其中: - `T_ACK_WAIT`:最早未确认帧开始计时后,允许等待累计ACK自然到达的时间;到期时发送第一次`POLL_REQ`; -- `T_POLL_INTERVAL`:第一次`POLL_REQ`之后,相邻`POLL_REQ`之间的间隔; +- `T_POLL_INTERVAL`:状态查询间隔;单纯窗口等待时,从进入等待或收到仍不足的合法状态开始计至第一次`POLL_REQ`,后续从每个`POLL_REQ`完整发送结束时重新计时;存在未确认帧时,用作第一次`POLL_REQ`之后的重复查询间隔; - `T_PROGRESS_LIMIT`:自最近一次ACK推进以来允许无进展的总时间;达到该值时启动Go-Back-N或判定当前重传轮失败; - `MAX_GBN_FAILURE_ROUNDS`:连续无ACK推进的完整重传失败轮数门限。 @@ -2332,6 +2381,8 @@ T_PROGRESS_LIMIT: ACK仍未推进,启动或判定一轮Go-Back-N | 同确认点ACK | `ACK_NEXT`等于`SND_UNA` | 不释放缓存;可以更新同锚点`WIN_BYTES` | | 旧或越界ACK | 不满足合理性检查 | 丢弃整个`CTRL`并记录错误 | | `RETRY_REQ` | `ACK_NEXT`合法且存在未确认帧 | 暂停新帧,从`ACK_NEXT`开始Go-Back-N | +| 重传缓存一致性检查失败 | 合法未确认区间内存在描述符或缓存缺失、重复或不可读 | 报告本地传输协议状态损坏和会话中止;撤销`transport_ready`;清空当前协议状态;置位`retrain_request`并进入`M_RETRAIN` | +| 窗口承诺一致性检查失败 | `OUTSTANDING_BYTES > PEER_WIN_BYTES`,或对端无法兑现已公告窗口 | 报告窗口承诺一致性故障和会话中止;撤销`transport_ready`;清空当前协议状态;置位`retrain_request`并进入`M_RETRAIN` | | T_ACK_WAIT无进展 | 存在未确认帧 | 发送第一次`POLL_REQ` | | T_ACK_WAIT+T_POLL_INTERVAL无进展 | 仍无进展 | 再次发送`POLL_REQ` | | T_PROGRESS_LIMIT无进展 | 存在未确认帧 | 开始重传或判定当前轮失败 | @@ -2387,26 +2438,21 @@ T_PROGRESS_LIMIT: ACK仍未推进,启动或判定一轮Go-Back-N |---|---|---| | `M_WAIT_STATUS` | 等待从端合法状态报告 | 发送或重发`POLL_REQ`;禁止首次发送新业务帧 | | `M_RUN` | 正常可靠传输 | 在窗口内连续提交新业务帧;并行处理ACK、窗口和超时 | -| `M_RETX_PREP` | 准备一个Go-Back-N重传批次 | 等待当前在途帧结束,再锁存范围、设置RETX_PTR并确定本批终点 | +| `M_RETX_PREP` | 准备一轮Go-Back-N重传 | 等待当前在途帧结束,再锁存重传范围并设置`RETX_PTR` | | `M_RETX_SEND` | 顺序提交重传帧 | 禁止首次发送新业务帧;按描述符顺序推进RETX_PTR | -| `M_RETX_WAIT` | 本批重传结束后等待ACK进展 | 在T_ACK_WAIT及随后一个T_POLL_INTERVAL到期时请求状态;在T_PROGRESS_LIMIT判定本轮成功或失败 | -| `M_RETRAIN` | 链路失步、数据链路层正在重训练,或已达到连续失败门限 | 清除当前协议会话状态和缓存,停止协议帧请求;由连续失败门限进入时置位`retrain_request`;等待链路重新同步 | +| `M_RETX_WAIT` | 本轮冻结范围重传结束后等待ACK进展 | 在T_ACK_WAIT及随后一个T_POLL_INTERVAL到期时请求状态;在T_PROGRESS_LIMIT判定本轮成功或失败 | +| `M_RETRAIN` | 链路失步、数据链路层正在重训练、达到连续失败门限,或检测到缓存/窗口承诺一致性故障 | 清除当前协议会话状态和缓存,停止协议帧请求;由协议层故障进入时置位`retrain_request`;等待链路重新同步 | -`M_RUN`同时覆盖有未确认帧、等待窗口和暂时没有上层发送请求的情况。这些情况由`OUTSTANDING_BYTES`、窗口比较和请求有效信号区分,不需要建立互斥的等待状态。主端可对业务层宣告的就绪条件为`master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN)`。 +`M_RUN`同时覆盖有未确认帧、等待窗口和暂时没有上层发送请求的情况。这些情况由`OUTSTANDING_BYTES`、窗口比较和请求有效信号区分,不需要建立互斥的等待状态。主端可对业务层宣告的就绪条件为`master_transport_ready = link_up && (MASTER_STATE == M_RUN)`。 -`M_RETX_PREP`按以下规则确定重传批次: +`M_RETX_PREP`按以下规则冻结本轮重传范围: ```text RETX_END = 当前SND_NXT RETX_PTR = 当前SND_UNA - -若 OUTSTANDING_BYTES <= PEER_WIN_BYTES: - RETX_BATCH_END = RETX_END -若 OUTSTANDING_BYTES > PEER_WIN_BYTES: - RETX_BATCH_END = 从SND_UNA开始,累计FRAME_COST不超过PEER_WIN_BYTES的最长连续前缀终点 ``` -第一种情况属于正常Go-Back-N,重传已经占用过窗口的帧,不再次扣减窗口。第二种情况只用于第32.7节的窗口重新同步。如果第二种情况下第一个未确认帧也无法容纳,则本批为空,进入 `M_RETX_WAIT` 并通过`POLL_REQ`等待新状态。 +只要`RETX_PTR != RETX_END`,主端就从`RETX_PTR`开始依次重传,直至`RETX_END-1`。这些帧已经占用窗口额度,重传时不得再次扣减窗口,也不得根据当前`AVAILABLE_BYTES`缩小重传范围。进入本状态后若发现`OUTSTANDING_BYTES > PEER_WIN_BYTES`,必须按第32.7.2节作为窗口承诺一致性故障处理。 #### 35.2.2 状态图 @@ -2416,57 +2462,66 @@ stateDiagram-v2 M_WAIT_STATUS --> M_RUN: 收到格式和CRC合法的初始状态 M_WAIT_STATUS --> M_WAIT_STATUS: T_POLL_INTERVAL无合法状态 / 请求POLL - M_RUN --> M_RUN: 新帧完成、合法ACK或窗口更新 + M_RUN --> M_RUN: 新业务帧完成或合法ACK更新 + M_RUN --> M_RUN: OUTSTANDING_BYTES=0且窗口不足 / 启动T_POLL_INTERVAL + M_RUN --> M_RUN: T_POLL_INTERVAL到期 / POLL_PENDING=1 + M_RUN --> M_RUN: POLL_REQ发送完成且窗口仍不足 / 重启T_POLL_INTERVAL + M_RUN --> M_RUN: 合法状态但窗口仍不足 / 重启T_POLL_INTERVAL + M_RUN --> M_RUN: 合法状态且窗口足够 / 停止问询并恢复首次发送 M_RUN --> M_RETX_PREP: 合法RETRY_REQ且仍有未确认帧 M_RUN --> M_RETX_PREP: 未确认帧T_PROGRESS_LIMIT无进展 - M_RETX_PREP --> M_RETX_SEND: 已锁存非空重传批次 - M_RETX_PREP --> M_RETX_WAIT: 窗口重同步时第一个未确认帧也无法容纳 + M_RETX_PREP --> M_RETX_SEND: 已锁存非空重传范围 M_RETX_PREP --> M_RUN: ACK已确认全部发送帧 + M_RETX_PREP --> M_RETRAIN: 重传缓存一致性检查失败 - M_RETX_SEND --> M_RETX_SEND: 重传帧完成且本批仍有帧 - M_RETX_SEND --> M_RETX_WAIT: 本批最后一帧完成 + M_RETX_SEND --> M_RETX_SEND: 重传帧完成且冻结范围仍有帧 + M_RETX_SEND --> M_RETX_WAIT: 冻结范围最后一帧完成 M_RETX_SEND --> M_RUN: ACK已确认全部发送帧 + M_RETX_SEND --> M_RETRAIN: 重传缓存读取失败 - M_RETX_WAIT --> M_RETX_PREP: ACK推进且窗口重同步批次尚未完成 M_RETX_WAIT --> M_RUN: ACK推进且本轮已经完整发送 M_RETX_WAIT --> M_RETX_PREP: T_PROGRESS_LIMIT无进展且失败次数小于3 M_RETX_WAIT --> M_RETRAIN: T_PROGRESS_LIMIT无进展且形成第3次连续失败 - M_WAIT_STATUS --> M_RETRAIN: link_sync_up撤销或sync_lost - M_RUN --> M_RETRAIN: link_sync_up撤销或sync_lost - M_RETX_PREP --> M_RETRAIN: link_sync_up撤销或sync_lost - M_RETX_SEND --> M_RETRAIN: link_sync_up撤销或sync_lost - M_RETX_WAIT --> M_RETRAIN: link_sync_up撤销或sync_lost - M_RETRAIN --> M_WAIT_STATUS: retrain_done / 请求POLL + M_WAIT_STATUS --> M_RETRAIN: link_up撤销 + M_RUN --> M_RETRAIN: link_up撤销或窗口承诺故障 + M_RETX_PREP --> M_RETRAIN: link_up撤销或窗口承诺故障 + M_RETX_SEND --> M_RETRAIN: link_up撤销或窗口承诺故障 + M_RETX_WAIT --> M_RETRAIN: link_up撤销或窗口承诺故障 + M_RETRAIN --> M_WAIT_STATUS: link_up重新置位 / 请求POLL ``` +本状态图用于表示主要控制路径;窗口与ACK计时模式切换、同周期事件优先级及全部寄存器动作以第35.2.3节和第35.2.4节为准。 + #### 35.2.3 规范性转移与动作 | 当前状态 | 事件和条件 | 寄存器及控制动作 | 下一状态 | |---|---|---|---| -| 任意非`M_RETRAIN`状态 | `link_sync_up=0`、`sync_lost=1`或`retrain_busy=1` | 按第26.2节中止当前会话;清零序号、窗口和协议计时,清空描述符及重传缓存,撤销`transport_ready`,并报告未完成业务请求已中止 | `M_RETRAIN` | +| 任意非`M_RETRAIN`状态 | `link_up=0` | 按第26.2节中止当前会话;清零序号、窗口和协议计时,清空描述符及重传缓存,撤销`transport_ready`,并对每个已接受但未完成的业务请求报告一次中止 | `M_RETRAIN` | | 任意非`M_RETRAIN`状态 | 收到合法`CTRL` | 先按第31.6节处理`ACK_NEXT`和`WIN_BYTES`;无效`CTRL`不改变任何可靠传输状态 | 按下列事件继续判断 | | `M_WAIT_STATUS` | 收到格式和CRC合法的初始状态 | 绕过运行期ACK合理性检查;原子设置`SND_UNA=ACK_NEXT`和`SND_NXT=ACK_NEXT`,保持`OUTSTANDING_BYTES=0`及重传缓存为空;装载`PEER_WIN_BYTES`并清除本次`POLL_REQ`等待 | `M_RUN`,即使`WIN_BYTES`为0 | | `M_WAIT_STATUS` | T_POLL_INTERVAL无合法状态 | 置位`POLL_PENDING`;保持当前新会话初始状态不变 | `M_WAIT_STATUS` | +| `M_RUN` | `OUTSTANDING_BYTES==0`且队首待发送帧`FRAME_COST > AVAILABLE_BYTES` | 保持该请求未分配`SEQ`且不写重传缓存;按第32.6.1节启动单纯窗口问询计时 | `M_RUN` | +| `M_RUN` | 单纯窗口问询达到`T_POLL_INTERVAL`且窗口仍不足 | 置位一次`POLL_PENDING`并暂停窗口问询计时;不得启动重传相关计时或失败计数 | `M_RUN` | +| `M_RUN` | 单纯窗口等待中收到合法状态`CTRL` | 更新窗口并重新计算`AVAILABLE_BYTES`;足够时停止问询并恢复首次发送;不足时取消尚未上线的窗口查询并重新开始完整`T_POLL_INTERVAL` | `M_RUN` | | `M_RUN` | 新业务帧完成首次发送 | `OUTSTANDING_BYTES += FRAME_COST`;`SND_NXT++`;若未确认集合由空变为非空则启动进度计时 | `M_RUN` | | `M_RUN` | 合法前进ACK | 释放确认前缀,更新`SND_UNA`和窗口,清零失败计数并重新开始或停止进度计时 | `M_RUN` | | `M_RUN` | 同确认点`ACK/UPDATE` | 仅更新同一确认点的窗口;不得释放缓存或重置进度计时 | `M_RUN` | -| `M_RUN` | 合法`RETRY_REQ`且 `ACK_NEXT==SND_NXT` | 执行第32.3节的无重传目标分支,不建立重传批次 | `M_RUN` | +| `M_RUN` | 合法`RETRY_REQ`且 `ACK_NEXT==SND_NXT` | 执行第32.3节的无重传目标分支,不启动Go-Back-N | `M_RUN` | | `M_RUN` | 合法`RETRY_REQ`且仍有未确认帧 | 置位重传启动请求,停止接受新的首次发送请求;若有新业务帧正在发送,等待其完成 | `M_RETX_PREP` | | `M_RUN` | T_PROGRESS_LIMIT无ACK进展且存在未确认帧 | 置位重传启动请求,停止接受新的首次发送请求;若有新业务帧正在发送,等待其完成 | `M_RETX_PREP` | | `M_RETX_PREP` | `ACK_NEXT==SND_NXT` | 不建立重传请求,停止进度计时 | `M_RUN` | | `M_RETX_PREP` | 主端→从端帧仍在发送 | 等待该帧完整结束;若它是首次发送的新业务帧,先完成`SND_NXT`和`OUTSTANDING_BYTES`记账 | `M_RETX_PREP` | -| `M_RETX_PREP` | 发送器已到帧边界且仍有未确认帧 | 使用此时的`SND_UNA`、`SND_NXT`和描述符锁存RETX_END、RETX_PTR及RETX_BATCH_END | 批次非空则`M_RETX_SEND`,否则`M_RETX_WAIT` | -| `M_RETX_PREP` | 第一个未确认帧也无法容纳 | 置位`POLL_PENDING`,启动本轮进度等待 | `M_RETX_WAIT` | -| `M_RETX_SEND` | 一个重传帧发送完成 | `RETX_PTR++`;不得增加`OUTSTANDING_BYTES`或分配`SEQ` | 本批未结束则保持,否则转`M_RETX_WAIT` | -| `M_RETX_SEND` | 收到合法前进ACK | 立即释放确认前缀;若RETX_PTR落后于新`SND_UNA`则令 `RETX_PTR=SND_UNA`;清零失败计数 | 全部确认则`M_RUN`,否则继续当前批次 | +| 任意非`M_RETRAIN`状态 | 合法`CTRL`处理后得到`OUTSTANDING_BYTES > PEER_WIN_BYTES`,或检测到窗口承诺无法兑现 | 报告窗口承诺一致性故障和会话中止;撤销`transport_ready`;清空当前协议状态;置位`retrain_request` | `M_RETRAIN` | +| `M_RETX_PREP`或`M_RETX_SEND` | 合法未确认区间内存在描述符或缓存缺失、重复或不可读 | 报告本地传输协议状态损坏和会话中止;撤销`transport_ready`;清空当前协议状态;置位`retrain_request` | `M_RETRAIN` | +| `M_RETX_PREP` | 发送器已到帧边界且仍有未确认帧 | 使用此时的`SND_UNA`和`SND_NXT`锁存`RETX_PTR`和`RETX_END`;重传不再次检查或扣减窗口额度 | `M_RETX_SEND` | +| `M_RETX_SEND` | 一个重传帧发送完成 | `RETX_PTR++`;不得增加`OUTSTANDING_BYTES`或分配`SEQ` | 未到`RETX_END`则保持,否则转`M_RETX_WAIT` | +| `M_RETX_SEND` | 收到合法前进ACK | 立即释放确认前缀;若`RETX_PTR`落后于新`SND_UNA`则令`RETX_PTR=SND_UNA`;清零失败计数 | 全部确认则`M_RUN`,否则继续当前冻结范围 | | `M_RETX_WAIT` | T_ACK_WAIT及随后一个T_POLL_INTERVAL到期且无进展 | 置位`POLL_PENDING`;不增加失败计数 | `M_RETX_WAIT` | -| `M_RETX_WAIT` | ACK推进且 `RETX_PTR < RETX_END` | 清零失败计数,从新`SND_UNA`重新计算窗口允许的剩余前缀 | `M_RETX_PREP` | | `M_RETX_WAIT` | ACK推进且本轮冻结范围已经全部发送 | 清零失败计数;剩余未确认帧重新按正常计时处理 | `M_RUN` | | `M_RETX_WAIT` | T_PROGRESS_LIMIT无进展 | 当前轮失败计数加一;小于3时令`RETX_PTR=SND_UNA`开始下一轮;形成第3次连续失败时置位`retrain_request` | 小于3时进入`M_RETX_PREP`,否则进入`M_RETRAIN` | -| `M_RETRAIN` | `retrain_done=1`且`link_sync_up=1` | 保持第31.2节规定的初始协议状态;保持`transport_ready=0`;置位`POLL_PENDING` | `M_WAIT_STATUS` | -| 任意状态 | `link_sync_up=0`、`sync_lost=1`或`retrain_busy=1` | 清空可靠传输状态并按第31.2节初始化 | `M_RETRAIN` | +| `M_RETRAIN` | `link_up=1` | 保持第31.2节规定的初始协议状态;保持`transport_ready=0`;置位`POLL_PENDING` | `M_WAIT_STATUS` | 由协议事件触发普通状态转移时,当前完整帧必须发送结束后再切换调度请求。同步丢失或重新训练入口不适用该等待规则:未产生`tx_frame_done`的帧必须立即中止,相关描述符和记账状态随旧会话一起清除,并向业务应用层报告会话中止。 @@ -2476,7 +2531,7 @@ stateDiagram-v2 同一时钟周期出现多个事件时,必须按以下顺序处理: -1. `link_sync_up`撤销、`sync_lost`或`retrain_busy`引起的会话终止和协议复位;该事件抑制本周期所有较低优先级协议动作; +1. `link_up`撤销引起的会话终止和协议复位;该事件抑制本周期所有较低优先级协议动作; 2. 已经有效的`tx_frame_done`及其发送记账; 3. 合法接收`CTRL`:先做累计ACK和窗口更新,再解释`FLAGS`; 4. T_ACK_WAIT、后续T_POLL_INTERVAL及T_PROGRESS_LIMIT定时事件; @@ -2484,7 +2539,7 @@ stateDiagram-v2 前进ACK与T_PROGRESS_LIMIT超时同周期发生时,以前进ACK为准,重置进度计时并抑制本周期的失败判定。合法`RETRY_REQ`中的`ACK_NEXT`必须先释放确认前缀;仅当处理后仍有未确认帧时才进入重传。 -ACK进度计时独立于`M_RUN`的发送活动。只要存在未确认帧,即使主端仍在窗口内连续发送新帧,也必须继续统计最早未确认帧的无进展时间。初始化等待或没有未确认帧但窗口不足时,可以复用同一个计数器作为`T_POLL_INTERVAL`轮询间隔计时;两种模式不得同时解释同一个超时事件。进入`M_RETRAIN`时所有协议计时停止并清零,重训练期间不产生超时事件;恢复后的计时按照第26.2.4节重新启动。 +ACK进度计时独立于`M_RUN`的发送活动。只要存在未确认帧,即使主端仍在窗口内连续发送新帧,也必须继续统计最早未确认帧的无进展时间。初始化等待、没有未确认帧但窗口不足以及ACK进度等待可以复用同一个物理计数器,但必须按第32.6.1节和第33章分别产生事件;不同模式不得同时解释同一个超时事件。进入`M_RETRAIN`时所有协议计时停止并清零,重训练期间不产生超时事件;恢复后的计时按照第26.2.4节重新启动。 ### 35.3 主端发送调度器 @@ -2504,7 +2559,7 @@ stateDiagram-v2 2. `M_RETX_SEND`提供的下一帧重传请求; 3. `M_RUN`提供且满足窗口条件的新业务帧请求。 -`POLL_PENDING`允许合并,不能因为同一请求等待多个周期而排队多个`POLL_REQ`。开始发送`POLL_REQ`时清除本次已经覆盖的`POLL_PENDING`;同周期产生的新`POLL_REQ`事件必须继续保留。下层没有收到本层完整帧请求时如何发送`IDLE`,不属于本状态机。 +`POLL_PENDING`允许合并,不能因为同一请求等待多个周期而排队多个`POLL_REQ`。开始发送`POLL_REQ`时清除本次已经覆盖的`POLL_PENDING`;同周期产生的新`POLL_REQ`事件必须继续保留。单纯窗口等待时,窗口问询计时器在该`POLL_REQ`完整发送结束后按第32.6.1节重新启动。下层没有收到本层完整帧请求时如何发送`IDLE`,不属于本状态机。 ### 35.4 从端业务接收控制器 @@ -2525,9 +2580,11 @@ stateDiagram-v2 S_EXPECT --> S_RETRY_WAIT: 业务帧错误 / 丢弃、RETRY_PENDING=1、ACK_PENDING=1 S_RETRY_WAIT --> S_RETRY_WAIT: 非期望或错误帧 / 丢弃、ACK_PENDING=1 S_RETRY_WAIT --> S_EXPECT: 正确期望帧 / 提交、RCV_NEXT++、RETRY_PENDING=0、ACK_PENDING=1 - S_EXPECT --> S_LINK_HOLD: link_sync_up撤销或sync_lost - S_RETRY_WAIT --> S_LINK_HOLD: link_sync_up撤销或sync_lost - S_LINK_HOLD --> S_EXPECT: retrain_done / 等待POLL_REQ + S_EXPECT --> S_LINK_HOLD: 已公告窗口承诺无法兑现 / retrain_request + S_RETRY_WAIT --> S_LINK_HOLD: 已公告窗口承诺无法兑现 / retrain_request + S_EXPECT --> S_LINK_HOLD: link_up撤销 + S_RETRY_WAIT --> S_LINK_HOLD: link_up撤销 + S_LINK_HOLD --> S_EXPECT: link_up重新置位 / 等待POLL_REQ ``` `S_LINK_HOLD`期间不得接受普通`DATA`或`CTRL`。重训练完成后,保持`RCV_NEXT=0`进入`S_EXPECT`,但在收到合法`POLL_REQ`前不恢复普通业务传输。收到合法`POLL_REQ`只置位`ACK_PENDING`,不改变上述接收状态。`WIN_BYTES`从0恢复为非0时同样只置位`ACK_PENDING`。无效`CTRL`直接丢弃,不改变`RCV_NEXT`、`ACK_PENDING`或`RETRY_PENDING`。 @@ -2536,8 +2593,9 @@ stateDiagram-v2 | 当前状态 | 事件和条件 | 必须动作 | 下一状态 | |---|---|---|---| -| 任意非`S_LINK_HOLD`接收状态 | `link_sync_up=0`、`sync_lost=1`或`retrain_busy=1` | 回滚未完成候选帧;清零`RCV_NEXT`、`ACK_PENDING`和`RETRY_PENDING`,释放未提交接收资源并重新计算`WIN_BYTES`;撤销`transport_ready` | `S_LINK_HOLD` | -| `S_LINK_HOLD` | `retrain_done=1`且`link_sync_up=1` | 保持`RCV_NEXT=0`,根据真实资源重新计算`WIN_BYTES`,等待`POLL_REQ` | `S_EXPECT` | +| 任意非`S_LINK_HOLD`接收状态 | `link_up=0` | 回滚未完成候选帧;清零`RCV_NEXT`、`ACK_PENDING`和`RETRY_PENDING`,释放未提交接收资源并重新计算`WIN_BYTES`;撤销`transport_ready` | `S_LINK_HOLD` | +| 任意非`S_LINK_HOLD`接收状态 | 无法为依据已公告窗口合法发送的期望`SEQ`帧或其重传提供已承诺资源 | 报告窗口承诺一致性故障和会话中止;回滚当前候选帧;撤销`transport_ready`;复位当前协议状态并置位`retrain_request` | `S_LINK_HOLD` | +| `S_LINK_HOLD` | `link_up=1` | 保持`RCV_NEXT=0`,根据真实资源重新计算`WIN_BYTES`,等待`POLL_REQ` | `S_EXPECT` | | `S_EXPECT` | `DATA`的CRC和格式正确、`SEQ==RCV_NEXT`且资源足够 | 提交一次;`RCV_NEXT++`;`ACK_PENDING=1` | `S_EXPECT` | | `S_EXPECT` | `DATA`发生第32.2节任一错误 | 丢弃;`RCV_NEXT`不变;`RETRY_PENDING=1`;`ACK_PENDING=1` | `S_RETRY_WAIT` | | `S_RETRY_WAIT` | 正确收到当前`RCV_NEXT`对应业务帧且资源足够 | 提交一次;`RCV_NEXT++`;`RETRY_PENDING=0`;`ACK_PENDING=1` | `S_EXPECT` | @@ -2569,8 +2627,8 @@ ACK_PENDING_next = NEW_STATUS_EVENT 同一时钟周期出现多个事件时,必须按以下顺序形成下一状态: -1. `link_sync_up`撤销、`sync_lost`或`retrain_busy`引起的会话终止和协议复位;该事件抑制本周期所有较低优先级协议动作; -2. `retrain_done`引起的保持状态退出; +1. `link_up`撤销引起的会话终止和协议复位;该事件抑制本周期所有较低优先级协议动作; +2. `link_up`重新置位引起的保持状态退出; 3. `DATA`候选帧完成事件,按成功接受或失败丢弃更新`RCV_NEXT`和`RETRY_PENDING`; 4. 合法`POLL_REQ`及`WIN_BYTES`从0恢复事件; 5. 状态`CTRL`开始发送产生的旧快照清除事件; @@ -2610,7 +2668,7 @@ stateDiagram-v2 | `frame_tx_done` | 发送器 | 完整帧最后一位已经发送,并同时报告帧类别及业务`SEQ` | | `ack_progress` | 主端`CTRL`处理器 | 合法`ACK_NEXT`使`SND_UNA`向前推进 | | `status_launch` | 从端发送调度器 | 最新状态快照已经锁存并开始发送 | -| `retrain_done` | 数据链路层 | 采样位置和帧边界已经恢复;传输协议层仍须执行状态查询后才能恢复业务 | +| `link_up_rise` | 数据链路层接口 | `link_up`从0变为1;传输协议层进入新会话状态查询,但尚不得恢复业务 | 解析器不得在CRC和格式检查完成前产生 `business_candidate_valid` 或 `ctrl_valid`。状态机不得把仅识别到`SOF`当作有效帧事件。 @@ -2631,7 +2689,7 @@ stateDiagram-v2 3. `OUTSTANDING_BYTES`必须等于未确认描述符`FRAME_COST`之和。 4. 从端必须独立检查本地接收资源,不得因主端已发送就假定空间足够。 5. `WIN_BYTES`不得作为增量累加,旧确认点的窗口不得覆盖新确认点状态。 -6. 窗口不一致时不得丢弃主端重传缓存,必须按第32.7节重新同步。 +6. 合法`CTRL`处理后若`OUTSTANDING_BYTES > PEER_WIN_BYTES`,或者任一端无法兑现已经公告的窗口承诺,必须按第32.7.2节中止当前会话并触发重新训练。 ### 36.3 `CTRL`与超时 @@ -2644,11 +2702,13 @@ stateDiagram-v2 ### 36.4 失败与方向差异 1. 连续3轮重传无进展时必须报告可靠链路故障及会话中止,并触发重新训练;旧会话缓存按第26.2节清除,不得把未确认帧报告为成功。 -2. 从端→主端业务不得进入链路重传或窗口控制状态机。 -3. 主端业务缓存满时可以丢弃从端业务帧,但必须继续解析线路并保证`CTRL`接收。 -4. 任一方向同步丢失都必须使双方复位传输协议状态;重新训练完成后从`SEQ=0`建立新会话。 +2. `RETRY_REQ`的`ACK_NEXT`位于合法未确认区间但对应描述符或缓存缺失、重复或不可读时,必须报告本地传输协议状态损坏和会话中止,并进入`M_RETRAIN`;不得尝试跳过缺失项继续重传。 +3. 合法`CTRL`处理后若`OUTSTANDING_BYTES > PEER_WIN_BYTES`,或者任一端无法兑现已经公告的窗口承诺,必须报告一致性故障和会话中止并进入重新训练;不得通过分批重传或等待窗口增大继续旧会话。 +4. 从端→主端业务不得进入链路重传或窗口控制状态机。 +5. 主端业务缓存满时可以丢弃从端业务帧,但必须继续解析线路并保证`CTRL`接收。 +6. 任一方向同步丢失都必须使双方复位传输协议状态;重新训练完成后从`SEQ=0`建立新会话。 -# 第六篇分层架构与层间接口 +# 第六篇 分层架构与层间接口 ## 37. 数据链路层 @@ -3356,6 +3416,8 @@ app_tx_tag 业务应用层只提供`DATA`及其有效载荷,不提供`SOF`、`SEQ`、CRC或扰码数据。传输协议层负责分配`SEQ`、缓存可靠方向帧并生成发送逻辑帧。 +`transport_ready`只表示新会话已经建立,不等同于单个业务请求的`app_tx_ready`。可靠`DL`方向只有在协议层能够接收并保存完整载荷及其请求信息时才允许完成请求握手;完整载荷保存完成后产生一次`app_tx_accepted`。实现可以在窗口不足时先缓存已接受请求,也可以将`app_tx_ready`保持为0并要求业务应用层保持请求,但必须保证:已经产生`app_tx_accepted`的请求由协议层持续保存,直至产生且只产生一次`app_tx_completed`或`app_tx_aborted`。尚未产生`app_tx_accepted`的请求不得分配`SEQ`、不得写入重传描述符,也不得在会话终止时报告`app_tx_aborted`。 + ### 45.2 业务发送结果 建议区分: @@ -3396,29 +3458,25 @@ app_rx_data_last ### 46.1 数据链路层向传输协议层 +协议控制只依赖以下功能信号: + ```text -link_sync_up -sync_lost -retrain_busy -retrain_done +link_up tx_frame_abort ``` | 信号 | 含义 | |---|---| -| `link_sync_up` | `UL`、`DL`及运行入口过程均已完成,数据链路层可以承载新会话的普通协议帧 | -| `sync_lost` | 任一方向同步不再可信;当前传输协议会话立即失效 | -| `retrain_busy` | 数据链路层正在执行规定范围内的重新训练和同步恢复 | -| `retrain_done` | 规定范围内的重新训练及运行入口过程已经完成;不表示初始`POLL_REQ/ACK`已经完成 | +| `link_up` | 电平为1表示`UL`、`DL`及运行入口过程均已完成,数据链路层能够正常收发普通协议帧;电平为0表示数据链路层未就绪,传输协议层必须保持会话复位状态 | | `tx_frame_abort` | 此前接受的逻辑帧未完成线路发送;不得将其视为`tx_frame_done` | -`link_sync_up`必须是协议层可见的聚合状态: +`link_up`必须是协议层可见的聚合电平: ```text -link_sync_up = ul_sync_up && dl_sync_up && run_entry_complete +link_up = ul_sync_up && dl_sync_up && run_entry_complete ``` -`ul_sync_up`和`dl_sync_up`可以作为诊断信号输出,但不能替代`link_sync_up`控制传输协议层。`link_sync_up`撤销后,传输协议层必须执行第26.2.3节的复位动作;数据链路层只报告状态,不直接修改传输协议寄存器。 +`link_up`从1变为0时,传输协议层必须立即按第26.2.3节终止并复位当前会话;`link_up=0`期间不得发送或接受普通`DATA`和`CTRL`,不得运行协议定时器。`link_up`重新变为1后,主端进入`M_WAIT_STATUS`并发起初始`POLL_REQ`,从端进入`S_EXPECT`并等待该请求。`ul_sync_up`、`dl_sync_up`、`sync_lost`、`retrain_busy`和`retrain_done`可以作为数据链路层内部状态或诊断输出,但不得作为传输协议状态机的独立控制输入。 ### 46.2 传输协议层向数据链路层 @@ -3436,19 +3494,19 @@ sync_reset_request 进入重新训练时,传输协议层必须停止业务收发并执行第26.2.3节的协议复位。只重新训练`DL`时,仍可信的`UL`只能承载链路层训练和状态信息,不能承载原会话普通协议帧。 -`retrain_done`之后,主端进入`M_WAIT_STATUS`并发送`POLL_REQ`;从端必须以`ACK_NEXT=0`和当前真实接收容量返回初始状态。主端只检查响应帧的格式和CRC,不以`ACK_NEXT`的具体取值决定是否进入`M_RUN`;主端把收到的值作为新会话起始序号,同时设置`SND_UNA`和`SND_NXT`,不得把它按运行期累计ACK处理。 +`link_up`重新置位后,主端进入`M_WAIT_STATUS`并发送`POLL_REQ`;从端必须以`ACK_NEXT=0`和当前真实接收容量返回初始状态。主端只检查响应帧的格式和CRC,不以`ACK_NEXT`的具体取值决定是否进入`M_RUN`;主端把收到的值作为新会话起始序号,同时设置`SND_UNA`和`SND_NXT`,不得把它按运行期累计ACK处理。 主端的确定性就绪条件为: ```text -master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN) +master_transport_ready = link_up && (MASTER_STATE == M_RUN) ``` -从端在初始状态`CTRL`产生`tx_frame_done`后置位`slave_transport_ready`。任一端的`link_sync_up`撤销、`sync_lost`有效或`retrain_busy`有效时,必须立即撤销相应的`transport_ready`。 +从端在初始状态`CTRL`产生`tx_frame_done`后置位`slave_transport_ready`。任一端的`link_up`撤销时,必须立即撤销相应的`transport_ready`。 从端发送非零初始`ACK_NEXT`属于不符合本规范的行为,主端可以记录诊断信息;但为避免序号冲突,只要响应帧本身合法,主端仍必须把该值作为新会话起始序号,并使用其中的`WIN_BYTES`完成初始化。这一赋值不恢复任何旧会话状态。 -# 第七篇实现、诊断与验证 +# 第七篇 实现、诊断与验证 ## 47. RTL 实现输出与诊断契约 @@ -3456,7 +3514,7 @@ master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN) | 输出 | 含义 | |---|---| -| `link_sync_up` | `UL`、`DL`及本端运行入口条件均已完成;不表示初始`POLL_REQ/ACK`已经完成 | +| `link_up` | `UL`、`DL`及本端运行入口条件均已完成;不表示初始`POLL_REQ/ACK`已经完成 | | `transport_ready` | 传输状态已对齐,可以接受新的可靠`DL`业务请求 | | `link_retraining` | 当前处于训练/重训 | | `master_state / slave_state` | 顶层状态 | @@ -3501,23 +3559,37 @@ master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN) 17. 恢复成功和搜索超时重训; 18. `DL`单向重训和`UL`、`DL`完整重训都会复位双方传输协议状态,并在恢复后从`SEQ=0`建立新会话; 19. 主端单独复位时,DL退出合法运行流并使从端确定进入`S_TRAIN`; -20. 从端仅在完整发送20个运行入口`UL IDLE`后置位`link_sync_up`,期间的普通协议帧不提交; +20. 从端仅在完整发送20个运行入口`UL IDLE`后置位`link_up`,期间的普通协议帧不提交; 21. 所有训练通过条件与超时同周期发生时通过优先; 22. 可信方向从普通帧切换到训练固定帧时保持完整帧边界; 23. `M_DL_CONFIRM`、`M_UL_CONFIRM`和`M_RUN_ENTRY`收到完整`TRAIN`时按UL仍可信处理并返回`M_TX_TRAIN`; 24. `M_RUN_ENTRY`超时时分别验证UL仍持续收到`SYNC`和UL不再可靠两个分支; -25. `MON_RECOVERY`期间保持当前会话但丢弃全部候选普通帧;一个合法`IDLE`即可恢复,搜索失败才撤销`link_sync_up`; +25. `MON_RECOVERY`期间保持当前会话但丢弃全部候选普通帧;一个合法`IDLE`即可恢复,搜索失败才撤销`link_up`; 26. 运行期出现意外完整固定帧时立即进入规定训练路径; 27. 连续4个CRC错误或最近256个CRC承载帧中8个错误时触发方向化重训; -19. 多从端处于不同状态且互不影响; -20. power_on初始化、PLL失锁和延迟就绪丢失发生在各主要状态时的行为。 -21. `DATA`和`CTRL`无`IDLE`背靠背发送时,下一`SOF`只在计算得到的边界被识别; -22. 帧长可确定但CRC错误、下一边界为合法`IDLE`或`SOF`时,丢弃当前帧但保持同步; -23. 帧长可确定但CRC错误、下一边界也非法时,进入边界恢复; -24. `LEN`越界或未按4字节对齐时,不使用该`LEN`继续计数并立即进入恢复; -25. `LEN`误码后仍为合法值时,接收等待不超过对应最大帧长度,随后由CRC或下一边界发现异常; -26. 依次测试实现支持的全部接收对齐候选位置,验证边界搜索和重新锁定; -27. 恢复期间出现仅`SOF`匹配但完整固定帧、长度或CRC失败时,不得错误恢复边界。 +28. 多从端处于不同状态且互不影响; +29. power_on初始化、PLL失锁和延迟就绪丢失发生在各主要状态时的行为。 +30. `DATA`和`CTRL`无`IDLE`背靠背发送时,下一`SOF`只在计算得到的边界被识别; +31. 帧长可确定但CRC错误、下一边界为合法`IDLE`或`SOF`时,丢弃当前帧但保持同步; +32. 帧长可确定但CRC错误、下一边界也非法时,进入边界恢复; +33. `LEN`越界或未按4字节对齐时,不使用该`LEN`继续计数并立即进入恢复; +34. `LEN`误码后仍为合法值时,接收等待不超过对应最大帧长度,随后由CRC或下一边界发现异常; +35. 依次测试实现支持的全部接收对齐候选位置,验证边界搜索和重新锁定; +36. 恢复期间出现仅`SOF`匹配但完整固定帧、长度或CRC失败时,不得错误恢复边界。 + +37. 连续发送多个`DATA`并由一个累计ACK释放多个重传项,验证`OUTSTANDING_BYTES`始终等于未确认描述符`FRAME_COST`之和; +38. 同确认点ACK只更新同锚点窗口,旧ACK和越界ACK不改变任何可靠传输状态; +39. `SEQ`跨越`16'hFFFF`回绕时,累计ACK合理性判断、缓存释放和Go-Back-N范围均正确; +40. 分别丢弃或破坏ACK、`RETRY_REQ`、`POLL_REQ`及其响应,验证后续累计ACK、周期查询和超时重传能够恢复; +41. 验证零窗口、非零但不足以容纳队首帧、窗口恢复以及单纯窗口长期不足;单纯窗口等待不得启动Go-Back-N或重训练; +42. 验证ACK进度计时与单纯窗口问询计时在最后一个未确认帧被确认和首个新帧完成发送时原子切换,任一时刻只有一种计时解释有效; +43. 重传期间收到部分前进ACK时立即释放确认前缀并跳过已经确认的重传项; +44. 连续三轮完整重传无进展时只产生一次会话中止,所有已接受但未完成请求各产生一次`app_tx_aborted`; +45. 注入重传描述符缺失、重复、缓存不可读及`OUTSTANDING_BYTES > PEER_WIN_BYTES`,验证当前会话中止且不得跳过错误继续传输; +46. 模拟从端无法兑现已公告窗口,验证双方终止旧会话并进入重新训练; +47. `link_up`撤销与`tx_frame_done`、合法ACK或定时器到期同周期发生时,以会话终止为最高优先级,且不得同时报告完成与中止; +48. `link_up`重新置位后,协议层只通过初始`POLL_REQ/ACK`建立新会话,旧会话的序号、窗口、控制快照和重传缓存均不得恢复; +49. 最大载荷`LEN=1032`的`DATA`能够在从端最小合规资源配置下获得1040 B窗口和一个帧描述符并完成传输。 ### 48.2 门级、时序与板级验证 @@ -3538,10 +3610,10 @@ master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN) - 从端连续正确检测10000个`DL` `SYNC`,主端连续正确检测10个`SYNC_ACK`; - 从端精确发送20个`SYNC_ACK`后持续发送`SYNC`,主端连续正确检测10000个`UL` `SYNC`; - 从端识别首个完整`DL IDLE`后精确发送20个`UL IDLE`,主端识别首个完整`UL IDLE`后进入`M_RUN`; -- `link_sync_up` 稳定; +- `link_up` 稳定; - 初始协议`POLL_REQ`/ACK 完成后,传输协议层声明 `transport_ready`。 -`link_sync_up`表示`UL`、`DL`及运行入口过程均已就绪;`transport_ready`表示新会话的初始`POLL_REQ/ACK`已经完成。业务应用层只能在`transport_ready`后启动需要可靠`DL`的业务。 +`link_up`表示`UL`、`DL`及运行入口过程均已就绪;`transport_ready`表示新会话的初始`POLL_REQ/ACK`已经完成。业务应用层只能在`transport_ready`后启动需要可靠`DL`的业务。 ## 49. 实现基线结论 @@ -3553,13 +3625,13 @@ master_transport_ready = link_sync_up && (MASTER_STATE == M_RUN) 每个符合本规范的设备或IP至少应提供以下声明: -1. 本规范版本:V0.7; +1. 本规范版本:V0.8; 2. 主端或从端角色; 3. 采用的物理承载、时钟与链路实现配置及第7章全部参数; 4. 最大`DATA`载荷; -5. 接收窗口容量及重传缓存容量; +5. 接收窗口容量、帧描述符数量、重传缓存容量及`MAX_INFLIGHT_FRAMES`; 6. 延迟范围、步进和最小通过窗口; -7. 第27章规定的训练计数、超时和间隔参数; +7. 第27章规定的训练计数、超时和间隔参数,以及第33章的`T_ACK_WAIT`、`T_POLL_INTERVAL`、`T_PROGRESS_LIMIT`和`MAX_GBN_FAILURE_ROUNDS`; 8. `SYNC_RESET`、方向化重新训练及同步丢失后协议复位的实现方式; 9. 对外层间接口的位宽和时钟域映射; 10. 第48章验证项目的完成情况。