すべて、CRC ジェネレーター (またはチェッカー) を実装するクラスまたはモジュールを探しています。ゼロから作成することもできますが、既製のものがある場合は、リアルタイムの節約になるかもしれません:-)
ありがとう!ラン
すべて、CRC ジェネレーター (またはチェッカー) を実装するクラスまたはモジュールを探しています。ゼロから作成することもできますが、既製のものがある場合は、リアルタイムの節約になるかもしれません:-)
ありがとう!ラン
CRC 計算の別の例を次に示します。次の例では、CRC を順次計算します。そのため、XOR を使用して各 CRC ビットを並列に計算する他のソリューションと比較して遅くなります。ただし、別のPOLYNOMが必要な場合に備えて、このソリューションはより「カスタマイズ可能」だと思います。
localparam CRC32POL = 32'hEDB88320; /* Ethernet CRC-32 Polynom, reverse Bits */
function automatic bit[31:0] genCRC32(input bit [7:0] databyte_stream[]);
int unsigned i, j;
bit [31:0] crc32_val = 32'hffffffff; // shiftregister,startvalue
bit [7:0] data;
//The result of the loop generate 32-Bit-mirrowed CRC
for (i = 0; i < databyte_stream.size; i++) // Byte-Stream
begin
data = databyte_stream[i];
for (j=0; j < 8; j++) // Bitwise from LSB to MSB
begin
if ((crc32_val[0]) != (data[0])) begin
crc32_val = (crc32_val >> 1) ^ CRC32POL;
end else begin
crc32_val >>= 1;
end
data >>= 1;
end
end
crc32_val ^= 32'hffffffff; //invert results
return crc32_val;
endfunction : genCRC32
次の Web サイトhttp://www.easics.com/services/freesics/crctool.htmlから CRC を自動生成できます 。
LSB ビットではなく TOPBIT を使用した C 言語での同様の実装。アルテラの例から: https://www.altera.com/content/dam/altera-www/global/en_US/others/support/examples/download/crc_accelerator.zip
ドイツ語で、ウィキペディア。これを計算する方法の例があります。 https://de.wikipedia.org/wiki/Zyklische_Redundanzprüfung
完全に構成された CRC 計算機の systemverilog の例は次のようになります。
localparam CRC_BW = 8;
localparam CRCXPOLYREV = 'hE0; /* CRC-8 Polynom, umgekehrte Bitfolge */
localparam CRCXPOLY = 'h07; /* CRC-8 Polynom, Bitfolge */
function automatic logic[CRC_BW-1:0] generateCRC_X(
logic [7:0] databyte_stream[],
input logic reversed_poly=0,
input logic[CRC_BW-1:0] start_crc_value='1,
input logic[CRC_BW-1:0] final_crc_xor_value='0,
input logic do_end_crc_reversebits=0);
int unsigned i, j;
bit [CRC_BW-1:0] crcx_tmp,crcx_val = start_crc_value; /* Schieberegister, Startwert (111...) */
bit [7:0] data;
//Ergebnis der Schleife gibt 8-Bit-gespiegelte CRC
for (i = 0; i < databyte_stream.size; i++) // Byte-Stream
begin
if (reversed_poly==1) begin
data = databyte_stream[i];
for (j=0; j < 8; j++) // from LSB to MSB in one byte!
begin
if ((crcx_val[0]) != (data[0]))
crcx_val = (crcx_val >> 1) ^ CRCXPOLYREV;
else
crcx_val >>= 1;
data >>= 1;
end
end else begin
data = databyte_stream[i];
for (j=0; j < 8; j++) // from LSB to MSB in one byte
begin
if ((crcx_val[CRC_BW-1]) != (data[7]))
crcx_val = (crcx_val << 1) ^ CRCXPOLY;
else
crcx_val <<= 1;
data <<= 1;
end
end
end
crcx_val ^= final_crc_xor_value; //Ergebnis invertieren
if (do_end_crc_reversebits==1) begin
for (j=0; j < CRC_BW; j++) // from LSB to MSB in the CRC bitwidth
begin
crcx_tmp[CRC_BW-1-j]=crcx_val[j];//reversed
end
crcx_val=crcx_tmp;
end
return crcx_val;
endfunction : generateCRC_X
CRC をテストするには、 http: //www.zorc.breitbandkatze.de/crc.html をお勧めします
function byte calc_crc(byte unsigned cmd[]);
bit [7:0] crc, d, c;
int i;
crc = 0;
for (i=0; i<cmd.size(); i++) begin
d = cmd[i];
c = crc;
crc[0] = d[7] ^ d[6] ^ d[0] ^ c[0] ^ c[6] ^ c[7];
crc[1] = d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[6];
crc[2] = d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[6];
crc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[7];
crc[4] = d[4] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[4];
crc[5] = d[5] ^ d[4] ^ d[3] ^ c[3] ^ c[4] ^ c[5];
crc[6] = d[6] ^ d[5] ^ d[4] ^ c[4] ^ c[5] ^ c[6];
crc[7] = d[7] ^ d[6] ^ d[5] ^ c[5] ^ c[6] ^ c[7];
//$display("crc result: %h",crc);
end
return crc;
endfunction