Перейти к содержанию
    

CRC код

CRC решил реализовать. Классический побитовый метод долгий. Наткнулся на статьи об матричных методах расчета данного кода (+онлайн генераторы готовых crc, но чужой модуль хорошо, а свой ближе к душе).

 

упорно пытался читать, пробовать....

В итоге взяв полином CRC8 Dallas/Maxim я получил методом тыка матрицу для расчета CRC.

Т.к. ее получение для меня оказалось трудным, я просто взял матрицу путем n-ых пребразований привел к нужному (вроде) виду

В матлабе для 8 битных чисел ответы сходятся с онлайн CRC подсчетом

Но....я не понимаю, а как в эту формулу включить начальное значение, которое потом будет иметь смысл Crc текущего для расчета последующего при длинных посылка (более байта)

 

Кидаю ссылку на статьи:

 

 

Мне желательно узнать

1) вычисление crc одним из матричных способов (мб есть где подробней)

2) как в моем случае учитывать текущее значение

3) или ссылки на более подробную литературу

 

ЗЫ. я решаю методом f матрицы, получив f матрицу(там легко) нужно ее возвести в степень полинома (CRC8 значит 8)

Возведение степень-не простое тут про это написано(http://apt.cs.manchester.ac.uk/ftp/pub/apt/papers/MGrymel_TVLSI10.pdf)

Я "грязно" получил искомую матрицу f^8.

Проблема в нахождении crc.....не могу я понять в статьях , как получить crc..там приводиться матричное выражение Xсл=F^8*Xтек*D (см статьи там корректней т к там использую операцию xor)

Xтек- это начальное значение crc, ноесли посылка более 8 бит, то результат каждой побайтовой операции нахождения crc заноситься в нее...

D-8бит входная последовательность..

вот тут я и не понимаю ничерта....если условиться, что x=00000000 и забыть про него, то для 1 байтовых чисел в матлабе у меня ответ сходится путем умножения f^8 на d...

И в голове каша....умножив массив f на X получу вектор.....а вектор на вектор не будет вектором(8 битным)

 

http://www.ijeat.org/attachments/File/v3i1/A2311103113.pdf

http://outputlogic.com/my-stuff/parallel_c..._whitepaper.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CRC же изначально был придуман для последовательного канала, затем чтобы побитово считать и к моменту принятия последнего разряда входного слова иметь значение контрольной суммы. Аппаратно это крайне компактная схема. Вы пытаетесь повесить код для последовательного канала на параллельный, а потом ищете способы это всё ускорить. Возникает вопрос, выбор данного вида контроля сообщения был осознанным или просто так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CRC же изначально был придуман для последовательного канала, затем чтобы побитово считать и к моменту принятия последнего разряда входного слова иметь значение контрольной суммы. Аппаратно это крайне компактная схема. Вы пытаетесь повесить код для последовательного канала на параллельный, а потом ищете способы это всё ускорить. Возникает вопрос, выбор данного вида контроля сообщения был осознанным или просто так?

Абсолютно верно. Я делал МАС, так там прием данных идут тетрадами. Вот в темпе приема тетрадами оно и считается. А вот в PCI - там прием словами, там приходится принимать словами, чтобы с задержкой в 1 такт было все сосчитано... А уж если канал битовый, то это минимальный расход ресурса...

А еще есть одна заноза. Если данные из канала принимаются в FIFO, то ведь у него нет входа СБРОС, а значит из него данные надо выдирать сразу же. А если Вы будете считать сумму ПОТОМ, то можете FIFO и переполнить...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен, полностью.

Я без конкретной задачи вопрос задаю, просто интересно, т.к. прочел, пока общие принципы crc изучал,(наткнулся на статьи), захотел посмотреть и понять

Слишком глубоко лезть не хочу(с доказательствами и т.п.), а в общих чертах иметь понимание откуда, как и т.п. да.

Изменено пользователем go2winner

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен, полностью.

Я без конкретной задачи вопрос задаю, просто интересно, т.к. прочел (наткнулся на статьи), захотел посмотреть и понять

Слишком глубоко лезть не хочу, а в общих чертах иметь понимание откуда, как и т.п. да.

В таком случае модуль CRC делается параметризируемым. Пара параметров: разрядность и инициализация...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В таком случае модуль CRC делается параметризируемым. Пара параметров: разрядность и инициализация...

 

 

Ну это понятно,я пока что стараюсь все модули параметрическими делать. Но мне не сам crc не понятен , а именно матричный алгоритм расчета

(по классическому crc и статей много и готовых программ на си и т.п. много)

Я из статей не понял, как реализовать его (матричный метод). Матрицу для полинома получил, а как ее использовать не очень понятно, пока что.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему бы просто не взять это? http://www.easics.com/webtools/crctool и сделать себе оптимальный CRC для Verilog/VHDL?

UPD: прошу прощения, не понял что нужно не сделать, а просто опробовать другой метод. А матричный способ он какие преимущества несет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Параметризованная функция на VHDL совершенно тривиальна, эффективность при синтезе будет не хуже, чем от web генераторов, можно использовать любые полином, длину crc, и ширину шины данных. На Верилог примерно также можно.

library ieee,work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package crc is
  constant eth_poly:std_logic_vector(31 downto 0):=X"04C11DB7";
  function crc_next(crc_poly, crc:std_logic_vector; data:std_logic_vector)return std_logic_vector;
end package;

package body crc is 
  function crc_next(crc_poly, crc:std_logic_vector; data:std_logic_vector)return std_logic_vector is
    variable l_crc, mask:std_logic_vector(crc'length - 1 downto 0);
    alias adata:std_logic_vector(data'LENGTH-1 downto 0) is data;
    alias acrc:std_logic_vector(crc'LENGTH-1 downto 0) is crc;
  begin
    l_crc :=  acrc;
    for i in adata'reverse_range loop  --from bit(0) to bit(length-1)
      mask := (others=>l_crc(l_crc'high) xor adata(i));
      l_crc := (l_crc(l_crc'HIGH-1 downto l_crc'LOW))&"0" xor (crc_poly and mask);
    end loop;
    return  l_crc;
  end function crc_next;  
end package body;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ладно.......я просто пробовал CRC разными методами(битовый, байтовый, матричный(хотя его тоже к побайтовым отнести))

Из них матричный малопонятен был и остается...

генераторы работают, как я понял по этому методу

ЗЫ. Оказывается я просто на просто несколько не понимал, как работает цикл (думал последовательно каждая иттерация-такт), поэтому полез в поле матричных решений,дабы "быстро" считать CRC , стыдно..каюсь(.....

 

 

Но вот я реализовал на вскидку побитовый метод

 

signal    polinom    :    std_logic_vector( 7 downto 0)    := "00110001";
signal    crc_new    :    std_logic_vector( 7 downto 0)    := (others => '0');

    srs: process (clk)
    variable    crc_temp    :    std_logic_vector( 7 downto 0)    := (others => '0');
    begin
        if (rst = '0') then 
            crc_new <= (others => '0');
        elsif rising_edge(clk) then
            if data_r = '1' then
                crc_temp(7 downto 0) := crc_temp (6 downto 0) & data_in;
                if (crc_new(7) = '1') then
                    crc_temp := crc_temp xor polinom;
                else
                    crc_temp := crc_temp;
                end if;
                crc_new<=crc_temp;                
            end if;                
        end if;
    end process srs;

 

crc_new поддаю на выход

 

Вот, что меня мучает

В классическом алгоритме, данные дополняются нулями (кол-во нулей равно степени полинома)

Так вот...вопрос

Вот пришла посылка/сообщение ПОБИТОВО, я побитово считаю CRC. Вырабатывали флаг готовности(приняли условное количество байт, равное пакету). Теперь в идеале после флага готовности CRC должен быть подсчитан ... для этого нужно в цикле прокрутить алгоритм CRC (см выше) N итераций , где N- степень полинома, при этом data_n принимается равным 0

 

Вот, как это красиво и с минимальными затратами обставить?

На ум громоздкие идеи приходят

Изменено пользователем go2winner

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ладно.......я просто пробовал CRC разными методами(битовый, байтовый, матричный(хотя его тоже к побайтовым отнести))

Зачем все усложнять? Для начала попробуйте автоматически сгенерировать crc, например, откуда советовал AVR в посте 8, промоделируйте, посмотрите схему на уровне RTL, потом придет понимание как это работает и, возможно, появятся конкретные вопросы.

Вот конкретный рабочий код crc24, правда на verilog, для стандарта ADSB, mode s.

module crc24 (
input ce,
input clk,
input rst,
input data_in,
output reg [23:0] data_out
);

wire inv;
   
assign inv = data_in ^ data_out[23];                   // XOR required?
   
always @(posedge clk or posedge rst) begin
      if (rst) data_out<=0;
      else if (ce) begin
         data_out[23] <= data_out[22] ^ inv;
         data_out[22] <= data_out[21] ^ inv;
         data_out[21] <= data_out[20] ^ inv;
         data_out[20] <= data_out[19] ^ inv;
         data_out[19] <= data_out[18] ^ inv;
         data_out[18] <= data_out[17] ^ inv;
         data_out[17] <= data_out[16] ^ inv;
         data_out[16] <= data_out[15] ^ inv;
         data_out[15] <= data_out[14] ^ inv;
         data_out[14] <= data_out[13] ^ inv;
         data_out[13] <= data_out[12] ^ inv;
         data_out[12] <= data_out[11] ^ inv;
         data_out[11] <= data_out[10];
         data_out[10] <= data_out[9] ^ inv;
         data_out[9] <= data_out[8];
         data_out[8] <= data_out[7];
         data_out[7] <= data_out[6];
         data_out[6] <= data_out[5];
         data_out[5] <= data_out[4];
         data_out[4] <= data_out[3];
         data_out[3] <= data_out[2] ^ inv;
         data_out[2] <= data_out[1];
         data_out[1] <= data_out[0];
         data_out[0] <= inv;
         end
      end
   
endmodule

 

Тут все просто - по сбросу происходит обнуление всех регистров, на 24 такт после сброса появляется валидный crc (24-разрядный). Схема до очевидности проста.

Ну а дальше, если интересно переходите на более сложные реализации - какой-нибудь FCS в UDP для ethernet и работой с тетрадами и реверсом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...