CoaXPress 协议的CRC及其具体实现

CoaXPress CRC

在CXP协议中,CRC用在stream packet和control packet中,用于指示数据是否错误,如果是control packet, device发现CRC错误后应该给出CRC错误的回应。
下表是回应的packet格式,在高速数据链路downconnection中。

其中CXP使用的CRC定义如下:

CRC多项式: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
初始值: 0xFFFFFFFF
REFIN: true
REFOUT: true
XorOut: 0x00000000

进行CRC校验时,LSB FIRST,P0 FIRST

CRC校验哪些数据呢?

以Control packet为例说明:
下表是没有tag标签的control command 包,其中明确说明了,参与CRC校验的数据是从0到N+1,不包含K27.7和0x02,且如果是read command packet,实际就只有word 0,1 参与校验;

同样,协议给出了一个示例:
下面是一个完整的read control packet,其中0x56 0x86 0x5D 0x6F 是CRC校验结果,对应的word 为0x6F5D8656

K27.7 K27.7 K27.7 K27.7 0x02 0x02 0x02 0x02 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x00 0x56 0x86 0x5D 0x6F K29.7 K29.7 K29.7 K29.7

CRC校验HDL代码

有了协议给出的示例,我们可以选择正确的CRC32 代码,CRC一般分为串行和并行2种,我们的应用选择串行计算即可。

代码参考: http://outputlogic.com/?page_id=321

//-----------------------------------------------------------------------------
// Copyright (C) 2009 OutputLogic.com
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
// CRC module for data[0:0] ,   crc[31:0]=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
//-----------------------------------------------------------------------------
module crc(
  input [0:0] data_in,
  input crc_en,
  output [31:0] crc_out,
  input rst,
  input clk);

  reg [31:0] lfsr_q,lfsr_c;

  assign crc_out = lfsr_q;

  always @(*) begin
    lfsr_c[0] = lfsr_q[31] ^ data_in[0];
    lfsr_c[1] = lfsr_q[0] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[2] = lfsr_q[1] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[3] = lfsr_q[2];
    lfsr_c[4] = lfsr_q[3] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[5] = lfsr_q[4] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[6] = lfsr_q[5];
    lfsr_c[7] = lfsr_q[6] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[8] = lfsr_q[7] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[9] = lfsr_q[8];
    lfsr_c[10] = lfsr_q[9] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[11] = lfsr_q[10] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[12] = lfsr_q[11] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[13] = lfsr_q[12];
    lfsr_c[14] = lfsr_q[13];
    lfsr_c[15] = lfsr_q[14];
    lfsr_c[16] = lfsr_q[15] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[17] = lfsr_q[16];
    lfsr_c[18] = lfsr_q[17];
    lfsr_c[19] = lfsr_q[18];
    lfsr_c[20] = lfsr_q[19];
    lfsr_c[21] = lfsr_q[20];
    lfsr_c[22] = lfsr_q[21] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[23] = lfsr_q[22] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[24] = lfsr_q[23];
    lfsr_c[25] = lfsr_q[24];
    lfsr_c[26] = lfsr_q[25] ^ lfsr_q[31] ^ data_in[0];
    lfsr_c[27] = lfsr_q[26];
    lfsr_c[28] = lfsr_q[27];
    lfsr_c[29] = lfsr_q[28];
    lfsr_c[30] = lfsr_q[29];
    lfsr_c[31] = lfsr_q[30];

  end // always

  always @(posedge clk, posedge rst) begin
    if(rst) begin
      lfsr_q <= {32{1'b1}};
    end
    else begin
      lfsr_q <= crc_en ? lfsr_c : lfsr_q;
    end
  end // always
endmodule // crc

Copyright © 2009-2013 OutputLogic.com | 
posted @ 2023-05-23 09:59  Hello-FPGA  阅读(640)  评论(0编辑  收藏  举报