diff --git a/非对称可靠串行传输技术规范.md b/非对称可靠串行传输技术规范.md index 85f2716..bad6da7 100644 --- a/非对称可靠串行传输技术规范.md +++ b/非对称可靠串行传输技术规范.md @@ -12,7 +12,7 @@ | 版本 | 日期 | 说明 | |---|---|---| -| V1.0 | 2026-10-02 | 统一重新训练为UL校准、DL校准、双向同步确认及新会话建立的完整流程;取消DL单向重训和人为UL异常通知;明确训练失败与单点失败的区别;加入等价的1-bit及32-bit自定义CRC参考函数,完善关键要求和验证索引。 | +| V1.0 | 2026-10-02 | 统一重新训练为UL校准、DL校准、双向同步确认及新会话建立的完整流程;取消DL单向重训和人为UL异常通知;明确训练失败与单点失败的区别;加入独立等价的1-bit串行CRC模块及32-bit自定义CRC参考函数,完善关键要求和验证索引。 | | V0.9 | 2026-10-01 | 完善分层接口的确定性语义;补充诊断可观察性、接口时序、重新训练握手、验证验收与互操作声明要求。 | | V0.8 | 2026-10-01 | 完善重传协议的确定性实现规则;统一协议层`link_up`接口,明确最大接收能力、窗口计时切换、`POLL_REQ`、业务接口契约、状态图说明及重传验证要求。 | | V0.7 | 2026-10-01 | 完善链路训练和运行期监测的异常闭环;明确主端重启可见性、运行入口就绪时机、连续计数与超时优先级、可信方向帧边界切换、方向化重训、恢复候选帧丢弃、单个IDLE恢复、意外固定帧处理及运行期CRC错误门限。 | @@ -855,54 +855,115 @@ CRC按逻辑帧字节顺序处理:先处理`SOF`的第一个线路字节,再 ### 15.3 CRC计算参考代码 -以下两种Verilog函数均实现第15.2节定义,不包含帧初始化、封装或扰码。`calc_crc32_bit`每次处理1个输入位;`calc_crc32`每次处理1个32位逻辑字。32-bit函数按位0至位31依次调用1-bit函数,因此两者对相同输入位序和初始状态产生完全相同的结果。两个函数应定义在同一调用作用域,1-bit函数位于32-bit函数之前。 +以下两段Verilog代码均实现第15.2节定义,独立使用且互不调用。1-bit版本为串行输入、串行CRC输出模块,内部仍保存32-bit CRC状态;32-bit版本为输入32-bit逻辑字、返回32-bit更新状态的函数。1-bit/32-bit描述数据处理及输出宽度,不改变本规范CRC字段固定为32 bit的要求。 -#### 15.3.1 1-bit参考函数 +#### 15.3.1 1-bit输入与1-bit输出参考模块 + +该模块每次输入握手只计算1个数据位。最后一个被覆盖位计算完成后,下一周期开始串行输出最终CRC,共32个位,按位0至位31输出。输出CRC期间不接受下一帧数据;本模块不输出原始数据、不执行扰码,也不代表完整线路发送器。 ```verilog -function [31:0] calc_crc32_bit; - input data_bit; - input [31:0] crc; - reg feedback; - reg [31:0] shifted_crc; +module crc32_serial ( + input wire clk, + input wire rst_n, + input wire data_bit, + input wire data_valid, + input wire frame_start, + input wire data_last, + output wire data_ready, + output wire crc_bit, + output wire crc_valid, + output wire crc_last +); localparam [31:0] POLY = 32'h04C11DB7; - begin - feedback = crc[31] ^ data_bit; - shifted_crc = crc << 1; - if (feedback) - calc_crc32_bit = shifted_crc ^ POLY; - else - calc_crc32_bit = shifted_crc; + reg [31:0] crc_state; + reg [31:0] crc_output; + reg [4:0] output_index; + reg output_active; + wire [31:0] crc_base; + wire feedback; + wire [31:0] crc_next; + + assign data_ready = !output_active; + assign crc_base = frame_start ? 32'hFFFFFFFF : crc_state; + assign feedback = crc_base[31] ^ data_bit; + assign crc_next = {crc_base[30:0], 1'b0} + ^ (feedback ? POLY : 32'h00000000); + assign crc_bit = crc_output[0]; + assign crc_valid = output_active; + assign crc_last = output_active && (output_index == 5'd31); + + always @(posedge clk) begin + if (!rst_n) begin + crc_state <= 32'hFFFFFFFF; + crc_output <= 32'h00000000; + output_index <= 5'd0; + output_active <= 1'b0; + end else if (output_active) begin + crc_output <= {1'b0, crc_output[31:1]}; + if (output_index == 5'd31) begin + output_active <= 1'b0; + output_index <= 5'd0; + end else begin + output_index <= output_index + 5'd1; + end + end else if (data_valid && data_ready) begin + crc_state <= crc_next; + if (data_last) begin + crc_output <= crc_next; + output_index <= 5'd0; + output_active <= 1'b1; + end + end end -endfunction +endmodule ``` -每次调用只消耗一个被CRC覆盖的数据位;返回值作为下一位的CRC状态。逐字节处理时,每个字节依次输入位0至位7;逐32位逻辑字处理时,依次输入位0至位31。没有有效输入位时必须保持状态,不得额外输入0。 +接口与调用规则: -#### 15.3.2 32-bit参考函数 +- `rst_n`为同步低有效复位,复位用于初始化本参考模块;复位期间不得使用输出。 +- 每帧第一个被覆盖位在`data_valid && data_ready`时输入,并同时置`frame_start=1`;其他位`frame_start=0`。模块先选取FFFFFFFF初值,再计算首位,不会丢弃首位。不得在帧中途重新置位frame_start。 +- 最后一个被覆盖位在输入握手时置`data_last=1`。模块将包含该末位计算结果的`crc_next`装入输出寄存器,不能装入尚未处理末位的旧状态。 +- `data_valid=0`时不更新CRC;`data_ready=0`时不接受输入,调用方须保持未被接受的数据及帧标记,直到完成握手。 +- 输出没有反压:`crc_valid=1`期间每周期输出1 bit,共连续32周期;`crc_last=1`仅对应最后的位31。输出接收者必须逐周期接收,crc_valid=0时crc_bit无意义。 +- 输出第31位的周期data_ready仍为0;该位被采样后的下一周期data_ready恢复为1,新帧首位可带frame_start立即输入。 +- 输入是被CRC覆盖的原始逻辑比特,包括SOF及全部协议字段和载荷,字节内位0先行。CRC字段和IDLE不作为输入;串行CRC输出是加扰前的字段位,线路封装器仍须执行本规范的扰码。 + +该模块采用串行计算和串行输出分阶段方式,供计算规则及位序参考。产品实现的缓存、并行化和流水线须另行满足连续线路吞吐要求,不得把本示例的data_ready直接当作串行物理线路可以停顿的许可。 + +#### 15.3.2 独立32-bit参考函数 ```verilog function [31:0] calc_crc32; input [31:0] data; input [31:0] crc; reg [31:0] new_crc; + reg feedback; integer i; + localparam [31:0] POLY = 32'h04C11DB7; begin new_crc = crc; - for (i = 0; i < 32; i = i + 1) - new_crc = calc_crc32_bit(data[i], new_crc); + for (i = 0; i < 32; i = i + 1) begin + feedback = new_crc[31] ^ data[i]; + new_crc = new_crc << 1; + if (feedback) + new_crc = new_crc ^ POLY; + end calc_crc32 = new_crc; end endfunction ``` -每次调用消耗一个完整32位逻辑字,下一字必须继承本次返回的状态。设`C0=crc`,依次执行`C(i+1)=calc_crc32_bit(data[i], C(i))`,其中`i=0…31`,则`calc_crc32(data, crc)=C32`。此等式适用于任意32位数据及任意32位CRC输入状态,而不仅适用于固定初值。 +每次调用计算一个完整32-bit逻辑字,输入数据按位0至位31进入计算;返回值作为下一字的CRC状态。本函数不调用1-bit模块或其他CRC函数。每帧首字使用FFFFFFFF初值,末字处理完成后的32-bit返回值直接作为最终CRC字段。 -#### 15.3.3 逐帧调用规则 +#### 15.3.3 两种实现的一致性与逐帧使用 -每帧开始前将调用方保存的CRC状态置为`32'hFFFFFFFF`;按逻辑帧字序依次调用,首字为原始SOF。最后一个被覆盖位或字处理完成后的返回值直接作为CRC字段,不再反转、异或或追加零位。CRC字段自身不得输入上述函数。输入是加扰前的逻辑数据,接收端使用原始SOF及解扰后的逻辑数据;帧间IDLE不参与计算。 +对同一帧,以FFFFFFFF为初始状态,将逻辑数据按字序输入32-bit函数,或按相同字序、每字位0至位31输入1-bit模块,得到的最终CRC数值必须完全一致。串行模块输出的第k个位等于32-bit计算结果的位k,k=0…31。 -本规范普通逻辑帧长度均为4字节整数倍,因此逐32位字调用不会引入补零。第15.1节9字节ASCII检查值可使用1-bit函数按实际72位计算,不得为调用32-bit函数而填充额外字节。并行优化实现必须与此逐位递推及两个参考函数等价。 +一致性也适用于任意相同中间状态:一个32-bit字更新等价于按第15.2节执行32次逐位递推。串行模块的公开接口固定逐帧初始化,任意中间状态等价性可在验证环境内检查内部递推,不要求增加产品端口。 + +两个版本均不追加零位、不反转输出、不执行最终异或。发送计算使用加扰前逻辑数据;接收计算使用实际收到的原始SOF及解扰后的协议字段和载荷,最终与解扰后的CRC字段比较。帧间IDLE及CRC字段本身不参与计算。 + +普通逻辑帧长度均为4字节整数倍,因此32-bit函数无须补零。第15.1节9字节ASCII检查值可用1-bit模块输入实际72个位后取32位串行结果,不得填充额外字节。两段代码的参考端口仅说明计算方法,不替代第43~46章层间接口定义。 ## 16. 扰码与解扰 @@ -3957,7 +4018,7 @@ M_TRANSPORT_RUN、M_RETX_PREP、M_RETX_SEND、M_RETX_WAIT: 必须验证:重复且ACK不推进的RETRY_REQ持续到来时,本轮观察期仍在原截止时间到期,连续三轮无进展最终终止会话;ACK推进与超时同周期时按进展处理。正常路径通过不能替代该异常活性验证。 -CRC验证必须分别检查位序、初值、逐位反馈、逐字状态继承及结果封装,并对并行更新逻辑与第15.2节递推做等价比较。第15.3节32-bit函数必须与按同一初始状态依次调用32次1-bit函数等价;验证应覆盖任意初始状态、全0/全1输入、每个位置的单独置位、连续多字及最大长度逻辑帧。接口验证必须覆盖第43~45章时序图,包括候选末字与CRC同周期、中途abort、累计ACK期间读取占用、会话终止排空、结果排队和已提交接收数据的反压保留。 +CRC验证必须分别检查位序、初值、逐位反馈、逐字状态继承及结果封装,并对并行更新逻辑与第15.2节递推做等价比较。第15.3节32-bit函数必须与1-bit模块的逐位计算等价,串行输出按位0至位31重组后必须等于逐字计算的最终CRC;还须验证末位结果装载、32周期输出、输出末位标记、输入间隙及输出期间的输入保持;验证应覆盖任意初始状态、全0/全1输入、每个位置的单独置位、连续多字及最大长度逻辑帧。接口验证必须覆盖第43~45章时序图,包括候选末字与CRC同周期、中途abort、累计ACK期间读取占用、会话终止排空、结果排队和已提交接收数据的反压保留。 ### 48.5 关键要求与验证索引