AFON // радиотехник affonya@mail.ru
← Проекты на VHDL

Проект 43. Генератор CRC-8

Контрольная сумма считается по одному биту за такт: сдвиг регистра и, при необходимости, сложение с образующим полиномом по модулю два. Тот же метод, что применяется в протоколах связи.

Задача

Вычислить контрольную сумму CRC-8 по потоку входных бит.

Тип схемы: Синхронный сдвиговый регистр с обратной связью по полиному.
Модуль: crc8. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования. Теорию по языку смотрите в статье VHDL — язык описания аппаратуры, по самим микросхемам — на странице ПЛИС.

Алгоритм

  1. Объявить образующий полином параметром модуля.
  2. На каждый входной бит вычислять бит обратной связи как XOR старшего разряда и входа.
  3. Сдвигать регистр CRC влево, вдвигая ноль.
  4. Если бит обратной связи равен единице, наложить на результат полином операцией XOR.

Код на VHDL

Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v43.vhd

--=====================================================
-- Проект 43. Генератор CRC-8
-- Последовательно принимает биты и вычисляет
-- контрольную сумму по образующему полиному.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;

entity crc8 is
    generic (
        POLY : std_logic_vector(7 downto 0) := x"07"     -- полином CRC-8-CCITT
    );
    port (
        clk      : in  std_logic;
        rst      : in  std_logic;
        data_in  : in  std_logic;                         -- входной бит
        bit_valid: in  std_logic;                          -- строб приёма бита
        crc_out  : out std_logic_vector(7 downto 0)
    );
end entity crc8;

architecture rtl of crc8 is
    signal crc : std_logic_vector(7 downto 0) := (others => '0');
begin
    process (clk, rst)
        variable fb : std_logic;
    begin
        if rst = '1' then
            crc <= (others => '0');
        elsif rising_edge(clk) then
            if bit_valid = '1' then
                fb  := crc(7) xor data_in;                -- бит обратной связи
                crc <= crc(6 downto 0) & '0';
                if fb = '1' then
                    crc <= (crc(6 downto 0) & '0') xor POLY;
                end if;
            end if;
        end if;
    end process;

    crc_out <= crc;
end architecture rtl;

Пояснения

  • Такой расчёт CRC полностью эквивалентен делению многочлена на образующий полином по модулю два — именно так CRC определяется в стандартах.
  • Полином задан параметром generic: для другого стандарта CRC достаточно подставить другое шестнадцатеричное значение.
  • Расчёт по одному биту за такт прост, но медленный; для быстрых линий строят параллельные схемы CRC, обрабатывающие сразу байт за такт.

Что дальше

Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.