2013-07-15 4 views
0

Все, Я ищу класс или модуль, который реализует генератор CRC (или контролер). Я мог бы создать его с нуля, но если есть готовый вариант, то может быть заставка в реальном времени :-)ищет реализацию CRC в Systemverilog

Спасибо! Ран

+3

вы проверили opencores.org? – guga

ответ

0
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 
+0

Спасибо, Чейгстер! brilliant :-) –

+0

@Tudor, что, если данные, на которых я должен вычислить свой CRC, не кратно байту, а 9 бит? , т. Е. 'Байт функции calc_crc (бит [8: 0] cmd []);' – Alessandro

+0

@Alessandro Я не ответил на этот вопрос :) Я только что отредактировал ответ. –

0

Example of Ethercat POLYNOM

Вот еще один пример для вычисления CRC. В следующих примерах вычисляется последовательность CRC. Поэтому они медленнее по сравнению с другими решениями, которые вычисляют каждый бит CRC параллельно с помощью XOR. Тем не менее, я нахожу это решение более «настраиваемым», если вам нужен другой ПОЛИНОМ.

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 

Вы можете иметь автоматическую генерацию вашего CRC со следующего сайта http://www.easics.com/services/freesics/crctool.html

Похожая реализации на языке C с использованием TOPBIT и не LSB немного. из примеров Altera: 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

От: https://www.altera.com/support/support-resources/design-examples/intellectual-property/embedded/nios-ii/exm-crc-acceleration.html

#define WIDTH (8 * sizeof(crc)) 
#define TOPBIT (1 << (WIDTH - 1)) 
#define POLYNOMIAL   0x04C11DB7 
#define INITIAL_REMAINDER 0xFFFFFFFF 
#define FINAL_XOR_VALUE  0xFFFFFFFF 

Вызов

crc crcSlow(unsigned char const message[], int nBytes); 

Функция

crcSlow(unsigned char const message[], int nBytes) 
{ 
crc   remainder = INITIAL_REMAINDER; 
int   byte; 
unsigned char bit; 
/* Perform modulo-2 division, a byte at a time. */ 
for (byte = 0; byte < nBytes; ++byte) 
{ 
    /* Bring the next byte into the remainder. */ 
    remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8)); 
    /* Perform modulo-2 division, a bit at a time. */ 
    for (bit = 8; bit > 0; --bit) 
    { 
     /*Try to divide the current data bit. */ 
     if (remainder & TOPBIT) 
     { 
      remainder = (remainder << 1)^POLYNOMIAL; 
     } 
     else 
     { 
      remainder = (remainder << 1); 
     } 
    } 
} 

/* The final remainder is the CRC result. */ 
return (REFLECT_REMAINDER(remainder)^FINAL_XOR_VALUE); 

}