Мегафункции ПЛИС
Вычисление контрольной суммы по алгоритму CRC-8
Описание:
Алгоритм: CRC8
Полином: 100000111
Поток данных: последовательный поток данных старшим битом вперёд (MSB-first bit)
Версия модуля: 1.1
Временная диаграмма входных и выходных сигналов прилагается (в формате симулятора пакета Quartus II).
Параметры:
MODE - режим работы модуля ("RX_MODE" - для работы в приёмнике, "TX_MODE" - для работы в передатчике)
DATA_WIDTH - суммарное количество бит в пакете данных
Входные порты:
clk - вход тактовых импульсов
reset - асинхронный вход сброса
sclr - синхронный вход сброса
in - вход данных
valid_in - строб входных данных
strobe - строб тактового сигнала
Выходные порты:
out - выход данные+CRC в режиме "TX_MODE"
data_ok - флаг успешной проверки контрольной суммы
crc_complete - флаг завершения проверки контрольной суммы (строб для сигнала data_ok)
Характеристики для использования в ПЛИС EP1C6Q240C8:
Maximum Frequency: 275.03 MHz
Total logic elements: 41
Total memory bits: 0
Исходный текст
TITLE "CRC8";
--Version 1.1
--MSB-first bit
--Polinom 100000111INCLUDE "lpm_counter";
PARAMETERS
(
MODE = "RX_MODE", --TX_MODE/RX_MODE
DATA_WIDTH = 48 --DATA WIDTH
);CONSTANT DATA_CNT_DONE = DATA_WIDTH - 1;
CONSTANT INIT_CRC_DATA = B"00000000";--B"11110011";
CONSTANT DATA_CNT_WIDTH = CEIL(LOG2(DATA_WIDTH));SUBDESIGN crc8s
(
clk : INPUT; --SYSTEM CLOCK
reset : INPUT; --SYSTEM RESET
in : INPUT; --DATA INPUT
valid_in : INPUT; --VALID DATA INPUT
strobe : INPUT; --DATA STROBE
sclr : INPUT; --RESET MODULE (INDEPENDENT OF ALL OTHER SIGNALS)out : OUTPUT; --DATA OUTPUT
data_ok : OUTPUT; --RX DATA CRC OK
crc_complete : OUTPUT; --CRC CALCULATION IS COMPLETE)
VARIABLE
CRCSM : MACHINE WITH STATES (_CRC_WAIT,_CRC_INIT,_CRC_DATA,_CRC_CRC,_CRC_END);
data_cnt : lpm_counter WITH (LPM_WIDTH = DATA_CNT_WIDTH,LPM_DIRECTION = "UP");
crc_cnt : lpm_counter WITH (LPM_WIDTH = 3,LPM_DIRECTION = "UP");crc_reg[7..0] : DFFE; --CRC REGISTER
data_in_ff : DFFE; --DELAY INPUT DATA
del_in_ff : DFFE; --DELAY INPUT DATA
out_ff : DFFE; --OUTPUT DATA
data_ok_ff : DFFE; --"NO ERRORS"
crc_end_ff : DFFE; --"crc_complete"feedback : NODE;
fb : NODE;BEGIN
CRCSM.clk = clk;
CRCSM.reset = reset;
CRCSM.ena = strobe # sclr;CASE CRCSM IS
WHEN _CRC_WAIT => --wait
IF (valid_in & !sclr) THEN
CRCSM = _CRC_INIT;
ELSE
CRCSM = _CRC_WAIT;
END IF;WHEN _CRC_INIT => --initialize
IF sclr THEN
CRCSM = _CRC_WAIT;
ELSE
CRCSM = _CRC_DATA;
END IF;WHEN _CRC_DATA => --tx/rx data
IF sclr THEN
CRCSM = _CRC_WAIT;
ELSE
IF (data_cnt.q[] == DATA_CNT_DONE) THEN
CRCSM = _CRC_CRC;
ELSE
CRCSM = _CRC_DATA;
END IF;
END IF;WHEN _CRC_CRC => --crc calculation
IF sclr THEN
CRCSM = _CRC_WAIT;
ELSE
IF (crc_cnt.q[] == 7) THEN
CRCSM = _CRC_END;
ELSE
CRCSM = _CRC_CRC;
END IF;
END IF;WHEN _CRC_END => --end
CRCSM = _CRC_WAIT;END CASE;
data_cnt.clock = clk;
data_cnt.aclr = reset;
data_cnt.sclr = (CRCSM == _CRC_WAIT);
data_cnt.cnt_en = (CRCSM == _CRC_DATA) & strobe;crc_cnt.clock = clk;
crc_cnt.aclr = reset;
crc_cnt.sclr = (CRCSM == _CRC_WAIT);
crc_cnt.cnt_en = (CRCSM == _CRC_CRC) & strobe;data_in_ff.clk = clk;
data_in_ff.d = in;
data_in_ff.ena = strobe;del_in_ff.clk = clk;
del_in_ff.d = data_in_ff.q;
del_in_ff.ena = strobe;
--CRC CALCULATOR
crc_reg[].clk = clk;
crc_reg[].ena = ((CRCSM == _CRC_INIT) # (CRCSM == _CRC_CRC) # (CRCSM == _CRC_DATA)) & strobe;IF (CRCSM == _CRC_INIT) THEN
IF (MODE == "TX_MODE") GENERATE
crc_reg[].d = INIT_CRC_DATA;
feedback = GND;
ELSE
feedback = fb;
crc_reg[0].d = feedback;
crc_reg[1].d = crc_reg[0].q $ feedback;
crc_reg[2].d = crc_reg[1].q $ feedback;
crc_reg[3].d = crc_reg[2].q;
crc_reg[4].d = crc_reg[3].q;
crc_reg[5].d = crc_reg[4].q;
crc_reg[6].d = crc_reg[5].q;
crc_reg[7].d = crc_reg[6].q;
END IF;IF (CRCSM == _CRC_CRC) THEN
fb = GND;
ELSE
fb = crc_reg[7].q $ del_in_ff.q;
END IF;ELSE GENERATE
fb = crc_reg[7].q $ del_in_ff.q;
END GENERATE;IF (CRCSM == _CRC_CRC) THEN
out_ff.clk = clk;
out_ff.d = crc_reg[7].q;
ELSE
out_ff.d = del_in_ff.q;
END IF;
out_ff.ena = strobe;
out = out_ff.q;data_ok_ff.clk = clk;
data_ok_ff.d = (crc_reg[].q == 0);
data_ok_ff.ena = (CRCSM == _CRC_END);
data_ok = data_ok_ff.q;crc_end_ff.clk = clk;
crc_end_ff.d = (CRCSM == _CRC_END);
crc_complete = crc_end_ff.q;
END;
Скачать исходники можно здесь (архив RAR, 4Кб).
При любом полном или частичном воспроизведении, копировании и распространении материалов сайта - активная ссылка на ресурс www.radiotract.ru обязательна.
Комментарии