2015-12-29 2 views
0

Я работаю с последовательным протоколом. Сообщения имеют переменную длину, которая известна заранее. На обеих сторонах передачи и приема у меня есть сообщение, сохраненное в сдвиговом регистре, до тех пор, пока это самое длинное сообщение. Мне нужно вычислить CRC32 этих регистров, так же как и для Ethernet, как можно быстрее. Поскольку сообщения являются переменной длиной (что-то от 12 до 64 бит), я выбрал последовательную реализацию, которая должна работать уже параллельно с получением/передачей сообщения.Сообщения переменной длины в Verilog (серийный CRC-32)

У меня возникла проблема с организацией данных перед вычислением. Как указано here, данные должны быть восстановлены по битам, дополнены 32 нулями и дополнены перед вычислением.

Даже если я забуду часть про параллельную работу с получением или передачей данных, как я могу эффективно получить только мое релевантное сообщение из регистра максимальной длины, чтобы я мог выполнить его до вычисления? Я знаю, что такие идеи, как

newregister[31:0] <= oldregister[X:0] // X is my variable length 

не работает. Также невозможно иметь предложение generate for loop, которое я использую для бит-инвертирования старого вектора run variable количество раз. Я мог бы использовать счетчик для последовательного перемещения данных на желаемую длину, но я не могу позволить себе потерять это много времени.

В качестве альтернативы, существует ли операция, которая непосредственно даст мне дополненный и дополненный результат? У меня даже нет идеи, как начать разработку такой идеи.

Заранее благодарим за понимание.

ответ

0

Вы неправильно поняли, как сделать серийный CRC; вопрос Python, который вы цитируете, не имеет отношения к делу. Вам нужен только 32-разрядный регистр сдвига с соответствующими метками обратной связи. Вы получите миллион хитов, если вы выполните поиск Google для «serial crc» или «ethernet crc». Есть хотя бы одна заметка приложения Xilinx, которая делает все для вас. Вам нужно быть осторожным, чтобы предварительно загрузить 32-разрядный регистр с правильным значением и вне зависимости от того, переверните 32-битные данные при завершении.

EDIT

Первый удар по «Xilinx серийный стс» является xapp209, которая имеет основной ответ на рис 1. На вершине этого, вам нужны краны, значение предварительной нагрузки, следует ли инвертировать ответ и значение, которое нужно проверить при приеме. Я уверен, что они все это делали в другой заметке о приложении, но я не могу найти ее в данный момент. Основными ссылками являются спецификация Ethernet 802.3 (3.2.8 Frame Check Sequence, которая была p27 в оригинальной книге) и спецификацию V42 (8.1.1.6.2 32-битная последовательность проверки кадров, стр. 311 в старом CCITT Blue Книга). Оба дают краны. V42 требует предварительной загрузки для всех 1, инвертирования завершения и дает тестовое значение при приеме. Уоррен имеет (новую) главу в «Удовольствии Хакер», которая графически отображает краны; см. его сайт.

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

+0

Ухаживайте за подробностями или дайте мне пример этих «миллионов хитов»? Я нашел примечание к приложению Xilinx, но оно устарело для нашего оборудования, и мои начальники решили не использовать его. Я также нашел ряд калькуляторов и генераторов кода, но, насколько я понял последний, они выполнили только расчеты CRC, в то время как мне все еще нужно было организовать данные до и после него. Это правда, что я только опробовал их на другом расчете CRC, а не на упомянутом CRC-32, и поскольку мне там нужна дополнительная работа, я ожидал, что он будет таким же. – FlyinGazebo

0

С X является видоизмененным, вам нужно выполнить бит назначения с помощью цикла. Цикл for должен находиться внутри всегда блока, и for-loop должен статически разворачиваться (т.е. начальный индекс, конечный индекс и значение шага должны быть константами).

for(i=0; i<32; i=i+1) begin 
    if (i<X) 
    newregister[i] <= oldregister[i]; 
    else 
    newregister[i] <= 1'b0; // pad zeros 
end 
+0

И все должно быть завернуто в блок всегда для работы? – FlyinGazebo

+0

Также, я попробовал это сейчас на другом примере, и он не работает.Похоже, что только исполняемая часть if, но не другая. – FlyinGazebo

+0

(A) Да, он должен быть всегда в блоке. (B) Он должен работать, можете ли вы показать больше своего кода. Если 'X' также является регистром, то я бы рекомендовал переместить логические вычисления из синхронной логики (например,' always @ (posedge clk) ') в комбинационную логику (например,' always @ * '), сохранить назначение регистров в синхронный логический блок. – Greg

 Смежные вопросы

  • Нет связанных вопросов^_^