Реализация модуля CRC32 с verilog для FPGA

Я вроде новичок в FPGA. Этим летом у меня есть проект в этой области, который реализует Ethernet-коммутатор с 4 портами. Я закодировал все части для проверки преамбулы, MAC-адреса и т. д., и они работают правильно, но у меня серьезные проблемы с реализацией CRC32.

  • Я знаю алгоритм CRC32 из IEEE 802.3
  • затем создал кадр с 18 байтами данных
  • затем сгенерировал CRC моего кадра с помощью этого апплета (вот ссылка!

но с любым кадром, который я делаю, результат проверки CRC для этого конкретного кадра неверен (это означает, что с моим модулем каждый кадр имеет ошибку)

Я был бы более чем счастлив узнать ваше мнение

Вот мой код модуля CRC32:

module CRC( clk10x, clk, rst, SFD, length, lengthReady, dataIn, hasError//, MACready
);
   .
   .
// input and outputs and registers are here
   .
   .
   . 
initial
begin
    CRC <= 32'h04C11DB7;
    zeros <= 32'h00000000;
end

always @ ( posedge clk10x )
begin
    if ( rst )
    begin
        counter32bit <= 0;
        shiftFlag <= 1;
        shift <= 0;
        shift2 <= 0;
        first32bit <= 0;
        state <= 0;
        index <= 0;
        calcEnd <= 0;
    end

    else if ( clk )
    begin
        if ( SFD )
        begin

            case ( state )
                'b00 : begin
                            first32bit <= ( counter32bit == 32 ) ? 1 : 0;
                            state <= ( first32bit ) ? 'b01 : 'b00;
                            {MSB, window} <= {window, ~dataIn};     // shift Register;
                            counter32bit <= counter32bit + 1;
                        end
                'b01 : begin
                            {MSB, window} <= ( MSB ) ? ( {window, dataIn} ^ CRC ) : {window, dataIn};
                            shift <= ( lengthReady && shiftFlag ) ? ( length * 8 ) : shift - 1;
                            shiftFlag <= ( lengthReady ) ? 0 : shiftFlag;
                            shift2 <= ( shift == 0 && lengthReady ) ? 32 : shift2 -1;
                            //shift2 <= ( !shift2 ) ? shift2 - 1 : shift2;
                            state <= ( shift2 == 2 && lengthReady ) ? 'b10 : 'b01;
                         end
                'b10 : begin
                            {MSB, window} <= ( MSB && !calcEnd ) ? ( {window, zeros[index]} ^ CRC ) : {window, zeros[index]};
                            index <= ( index == 32 && !calcEnd ) ? 40 : index + 1;
                            calcEnd <= ( index == 40 ) ? 1 : 0;
                            state <= ( calcEnd ) ? 'b11 : state;

                         end

                'b11 : begin
                            window <= window ^ 32'b11111111_11111111_11111111_11111111;
                            hasError <= ( window == 0 ) ? 0 : 1;
                         end
                default : begin
                                //state <= 0;
                                first32bit <= 0;
                                //shift <= 0;
                             end
            endcase

            // have to assign index 0 again
        end

person user2295408    schedule 16.08.2014    source источник
comment
Как инициализируется окно? Сдвигаемый регистр должен начинаться со всех единиц.   -  person Mark Adler    schedule 17.08.2014
comment
Почему это ? не могли бы вы помочь мне проверить кадр с помощью алгоритма CRC32?   -  person user2295408    schedule 17.08.2014
comment
Это прямо там, на веб-сайте, на который вы ссылаетесь. Начальное значение FFFFFFFF. Похоже, вы реализуете окончательное значение xor, FFFFFFFF.   -  person Mark Adler    schedule 17.08.2014


Ответы (1)


Вычисления CRC выполняются побитно. поэтому каждое слово входных данных — скажем, один байт за такт при частоте 125 МГц для гигабитного Ethernet — приводит к 8 вычислениям CRC за такт. Таким образом, вашему коду нужен дополнительный цикл для выполнения этих 8 вычислений подцикла.

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

Как заметил Марк Адлер, начальное значение внутреннего LFSR CRC должно быть инициализировано 0xFFFFFFFF. Я вижу это в вашем коде.

Почему вы используете 2 разных часов в своем процессе?

Редактировать 1:

Я не очень хорошо разбираюсь в кодировании Verilog, поэтому скопирую некоторый код VHDL из нашей библиотеки VHDL. Я думаю, вы сможете перевести утверждения в соответствующий код Verilog. Я избавился от отдельного процесса регистрации со сбросом и включением часов :)

-- Compute next combinational Value
process(lfsr, din)
  variable v : std_logic_vector(lfsr'range);
begin
  v := lfsr;
  for i in BITS-1 downto 0 loop
    v := (v(v'left-1 downto 0) & '0') xor
         (GN and (GN'range => (din(i) xor v(v'left))));
  end loop;
  lfsn <= v;
end process;
  • BITS является общим и установлен на 32
  • lfsr (регистр сдвига с линейной обратной связью) имеет ширину 32 бита и хранит текущую «контрольную сумму».
  • темп. переменная v инициализируется текущим значением регистра (lfsr)
  • цикл for просматривает каждый бит din (входящие данные) и выполняет вычисление crc (shift + xor)
  • => поэтому за такт выполняется 32 вычисления CRC
  • GN — нормализованный порождающий полином CRC32.
  • результат сохраняется в lfsn (следующее значение lfsr), который подключен к 32-битному D-FF со сбросом и включением часов.
person Paebbels    schedule 18.08.2014
comment
Спасибо за совет. Я использовал два тактовых генератора из-за модуля декодирования Manchester. clk моей платы будет clk10x, и clk работает как флаг включения, а другие модули работают с этим clk. Моя главная просьба — помочь мне реализовать CRC32 для Ethernet, пожалуйста. заранее спасибо - person user2295408; 19.08.2014
comment
@user2295408 user2295408 Я добавил основной цикл вычислений для CRC в VHDL, потому что я не очень хорошо разбираюсь в Verilog. - person Paebbels; 19.08.2014
comment
Извините за поздний ответ. Спасибо, мне помогло. Теперь я завершил свой код. есть ли какая-либо программа или надежный апплет, который я могу использовать для создания кадра Ethernet? Я уже использовал несколько апплетов генераторов CRC32 в сети. но они не могут быть на 100% точными, так как они самодельные. Большое спасибо за Вашу помощь - person user2295408; 30.08.2014
comment
Например, для таких данных, как: 0010A47BEA800012345678900012000102030405060708090A0B0C0D0E0F1011 в шестнадцатеричном формате, каким будет CRC32? - person user2295408; 30.08.2014
comment
Так что, если мой ответ был достаточно хорош, вы можете проголосовать за него ;) Итак, вы ищете тестовые данные ... Я использовал wireshark, чтобы захватить несколько кадров и скопировал их в тестовый стенд VHDL. Просто создайте вектор 8-битного вектора для хранения нескольких байтов. Теперь вы можете использовать процесс, который считывает из этого вектора один байт за цикл, чтобы управлять вводом ваших модулей. - person Paebbels; 31.08.2014
comment
Я не могу проголосовать за него, потому что я недавно зарегистрировался здесь и у меня все еще недостаточно репутации (для голосования необходимо не менее 15 репутации). сделаю, когда наберется достаточно кредита ;) Спасибо, я попробую с Wireshark. - person user2295408; 31.08.2014