CRC_8_ATM并行CRC实现:异或位逻辑解析与适配咨询
并行CRC代码适配CRC_8_ATM多项式的问题
我想为CRC_8_ATM多项式编写并行CRC代码,找到了针对多项式0x1021的代码,但看不懂其中异或操作的位置设置及原因,没法改成适配目标多项式的代码。
原代码如下:
assign crc_out = crc_reg; // CRC控制逻辑 always @ (posedge clk) if (reset) begin crc_reg <= 16'hFFFF; end else if (enable) begin if (init) begin crc_reg <= 16'hFFFF; end else begin crc_reg <= next_crc; end end // 我不理解这部分 assign next_crc[0] = data_in[7] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[11]; assign next_crc[1] = data_in[1] ^ crc_reg[5]; assign next_crc[2] = data_in[2] ^ crc_reg[6]; assign next_crc[3] = data_in[3] ^ crc_reg[7]; assign next_crc[4] = data_in[4] ^ crc_reg[8]; assign next_crc[5] = data_in[7] ^ data_in[5] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[9] ^ crc_reg[11]; assign next_crc[6] = data_in[6] ^ data_in[1] ^ crc_reg[5] ^ crc_reg[10]; assign next_crc[7] = data_in[7] ^ data_in[2] ^ crc_reg[6] ^ crc_reg[11]; assign next_crc[8] = data_in[3] ^ crc_reg[0] ^ crc_reg[7]; assign next_crc[9] = data_in[4] ^ crc_reg[1] ^ crc_reg[8]; assign next_crc[10] = data_in[5] ^ crc_reg[2] ^ crc_reg[9]; assign next_crc[11] = data_in[6] ^ crc_reg[3] ^ crc_reg[10];
原代码异或逻辑的原理
原代码是**CRC-16-CCITT(多项式0x1021)**的8位并行计算实现。并行CRC的核心是把串行的"移位+异或"操作展开为一次计算:
- 串行CRC每次仅输入1位,新CRC位由当前CRC位、输入位与多项式系数(对应位为1则参与异或)共同决定。
- 并行计算8位输入时,相当于把8次串行操作合并,通过线性推导得到每个新CRC位的表达式——
next_crc[n]的异或项,是当前crc_reg的特定位和data_in的特定位的组合,组合位置完全由多项式的结构决定。
适配CRC_8_ATM的并行代码实现
CRC_8_ATM的标准参数:
- 多项式:
x⁸ + x² + x + 1(通常简写为0x07,最高位x⁸隐含) - 初始值:0xFF
- 输入/输出数据:不反转
- 最终异或值:0x00
以下是8位并行输入的CRC_8_ATM代码:
module crc_8_atm_parallel( input clk, input reset, input enable, input init, input [7:0] data_in, output reg [7:0] crc_out ); reg [7:0] crc_reg; always @(posedge clk) begin if (reset) begin crc_reg <= 8'hFF; end else if (enable) begin if (init) begin crc_reg <= 8'hFF; end else begin crc_reg <= next_crc; end end end assign crc_out = crc_reg; // 8位并行CRC计算逻辑,推导自CRC_8_ATM多项式 wire [7:0] next_crc; assign next_crc[7] = crc_reg[6] ^ data_in[7] ^ data_in[0] ^ crc_reg[7]; assign next_crc[6] = crc_reg[5] ^ data_in[6] ^ data_in[7] ^ data_in[0] ^ crc_reg[7]; assign next_crc[5] = crc_reg[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[0] ^ crc_reg[7]; assign next_crc[4] = crc_reg[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[0] ^ crc_reg[7]; assign next_crc[3] = crc_reg[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[0] ^ crc_reg[7]; assign next_crc[2] = crc_reg[1] ^ crc_reg[7] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[0]; assign next_crc[1] = crc_reg[0] ^ crc_reg[7] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[0]; assign next_crc[0] = crc_reg[7] ^ data_in[0] ^ data_in[7]; endmodule
推导说明
上述next_crc的表达式是通过将8次串行CRC操作展开得到的:
- 先写出单比特输入时的CRC更新规则,再代入8位输入的每一位。
- 每个新CRC位的异或项,包含当前CRC的关联位、输入数据的关联位,这些关联位由多项式的非零系数位置决定。
你也可以用CRC并行计算工具来验证或直接生成表达式,避免手动推导出错。
内容的提问来源于stack exchange,提问作者ghazalia
相关产品推荐
相关产品推荐

