Радиотехнический сайт RADIOTRACT

Радиотехника и электроника для разработчиков и радиолюбителей

Информация

 

 

Справочные данные на радиоэлектронные компоненты, приборы, средства связи и измерений. Радиотехническая литература.

Общая

Микроконтроллеры

ПЛИС

Измерения

Радиостанции

Библиотека

Справочники

Доска объявлений

Объявления о покупке и продаже радиокомпонентов. Спрос и предложение на различные радиодетали и приборы.

Куплю

Продам

Магазин

Программы

Полезные программы для радиолюбителей и разработчиков радиоэлектроники.

Радиотехника

Интернет

Калькуляторы

Другие

Мы в соцсетях

  

Мегафункции ПЛИС

Вычисление контрольной суммы по алгоритму 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 100000111

INCLUDE "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
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 (MODE == "TX_MODE") GENERATE

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.d = crc_reg[7].q;
ELSE
out_ff.d = del_in_ff.q;
END IF;

out_ff.clk = clk;
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 обязательна.


Комментарии

comments powered by Disqus