Здравствуйте уважаемые!
Делаю в рамках самообразования проект на плате DE1-SoC от terasic
периодически появляются вопросы, с которыми не могу справится самостоятельно. Очень надеюсь что здесь подкинут свежих идей!
В частности назрело 2 вопроса.
1) Как просто и правильно поделить 24 бита на 3 куска по 8?
Я сейчас делаю это так, но может это не совсем удобно, и есть более прозрачные и удобные способы?
Спойлерmodule bytemode (enter_data,drop_data,clk,uartOK);
input uartOK; // сюда уарт сообщает о том что он все отправил
input clk; // тактирование
input [23:0] enter_data; // входящая 24битная шина
output [7:0] drop_data; // нужный результат 8бит
always @ (posedge clk)
if (automat!=3) begin
if (uartOK) begin // если счетчик и уарт готовы
automat=automat+1; // мотаем счетчик
if (automat==1) // можно было сделать и через case, но вот так пока. 1 этап разделки туши.
begin
if (enter_data!=0) // если ненулевые данные
temp1[0]=enter_data[7:0]; // отгрызаем кусок
end
else if (automat==2) // 2 этап
begin
if (enter_data!=0)
temp1[1]=enter_data[15:8]; // еще кусок
end
else if (automat==3) // 3 и последний этап
begin
if (enter_data!=0)
temp1[2]=enter_data[23:16]; // последний кусок
automat=0;
end
end
end
assign drop_data=temp1[automat]; // каждый этап формирует выходной сигнал в виде нашего 8битного куска
endmodule
2. У меня счетчик прибавляет к значению по единичке (своеобразный генератор пилы) и выплёвывает это в FIFO (в quartus'е LPM_FIFO в стандартной библиотеке), потом это идет в означенный выше разделитель, и дальше в UART. Но UART вместо нужных символов показывает погоду. Где почитать про то как подобные вещи синхронизируются между собой?
Для начала не хватает сигнала начальной установки счечика, без него Вы первую передачу начинаете с произвольного места во входных данных. Для выбора байтов ИМХО лучше использовать case т.к. он скомпилируется в многоканальный мультиплесор. кроме того я бы посмотрел в какой момент лучше инкрементировать счетчик. Изучение ПЛИС - задача интересная, но требует большого объема базовых знаний до получения первого результата. Смотрите в сторону изучения МodelSim с ним многое можно увидеть "по шагам"
Большое спасибо за ответ!
Появился еще такой вопрос
Бьюсь, бьюсь, а так и не получилось увязать между собой разделитель 24 битной шины на 3 по 8 и УАРТ
Получается что фифо выдает очередную порцию данных после того как уарт сообщает об отправке данных, этот же сигнал окончания отправки сообщает разделителю что можно делить. Но почему-то на выходе получается что сообщения разделены "00", т.е например мы передаем FFDE88 и DDE6E3 а приходит "FFDE8800DDE6E3" и так нулями между собой все разделяется. Поидее наверное нужно чтобы разделитель сообщал о наличии данных УАРТУ, и тот срабатывал после этого. Но получается что УАРТ ждет сигнала от разделителя, а разделитель ждёт сигнала от УАРТА. Как избавится от этого ожидания друг друга, чтобы они могли сообщать о состоянии друг друга и при этом работать по сигналу друг от друга?
Заранее спасибо за помощь
Gromph писал(а):Получается что фифо выдает очередную порцию данных после того как уарт сообщает об отправке данных, этот же сигнал окончания отправки сообщает разделителю что можно делить. Но почему-то на выходе получается что сообщения разделены "00", т.е например мы передаем FFDE88 и DDE6E3 а приходит "FFDE8800DDE6E3" и так нулями между собой все разделяется.
По всей видимости у Вас объявляется двухбитная переменная (счетчик, или еще что-то), которая имеет четыре возможных состояния: 00, 01, 10 и 11. В процессе работы, счетчик проходит все комбинации, а дешифратор рассчитан всего на три состояния (наверное 00, 01 и 10) вот и получается дополнительная вставка лишних нулей.
Gromph писал(а):Поидее наверное нужно чтобы разделитель сообщал о наличии данных УАРТУ, и тот срабатывал после этого. Но получается что УАРТ ждет сигнала от разделителя, а разделитель ждёт сигнала от УАРТА. Как избавится от этого ожидания друг друга, чтобы они могли сообщать о состоянии друг друга и при этом работать по сигналу друг от друга?
Сделайте конечный автомат (КА), на вход которого будете заводить сигналы и уарта и разделителя - пусть он разруливает очередность работы. Но есть подозрение, что исключив четвертое состояние у счетчика, Вы избавитесь от дополнительных нулей без привлечения КА.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Спасибо Meteor! Вы оказались правы не в бровь а в глаз просто. У делителя был лишний такт. Как только от него избавился пакеты полетели без пауз.
За ловлей этих нулей совсем забыл что у меня уарт по 4 раза отправляет одно и то же, т.е. 001 001 001 001 002 002 002 002 003 003 003 003 и т.д.
Теперь ловлю этот баг
Как выловлю, нарастающим итогом буду прикручивать синус CORDIC'ом.
Вопрос с повторной отправкой одного и того же пакета решился более ранним запросом на чтение из фифо. Правда теперь теряется 1 пакет. Допустим идет 0001 0002 0003 0005 0006 0007 009 и т.д.
Поиски продолжаются.
Что за ФИФО: одноклоковое или двуклоковое?
С фифо в свое время намучился, есть особенности их использования. Дело в том, что счетчики числа записанных байт (rdusedw и wrusedw) имеют задержку примерно от трех тактов (для двухтактового ФИФО определяется меньшей частотой).
Для надежного применения в проектах стараюсь разделять интервалы записи в фифо и чтения для корректного счета.
Не знаю насколько Вам это пригодится, но вполне возможно данная информация не станет лишней.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Meteor писал(а):А потом раз - и начинается вот то что идет до конца.
Количество "правильных" посылок, зависит от кол-ва строк в FIFO, чем больше ставлю, тем дольше правильно работает. Видимо косяк как-то связан с переполнением FIFO.
А как вообще такой момент эффективно контролировать? Бывали ли у кого нибудь такие проблемы? Или сталкивались может с какими-то типичными решениями в таких ситуациях?
Да были, куда без них то?!
Ситуация когда после определенного количества вычиток, данные зависают в одном состоянии связана с тем, что фифо опустело, а не переполнилось.
Для корректной работы, нужно смотреть на состояние сигнала rdempty (или подобный) как только этот сигнал принимает значение 1, это означает что в фифо остался последний байт (если ширина 8 бит) и нужно прекращать чтение.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже