Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Тактирование UART-передатчика (CYCLONE III)
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
mongol
Имеется проект небольшой, на Циклон поступают данные извне, а затем эти данные передаются по UART на микроконтроллер STM. Циклон тактируется от кварца на 100 MHz. На стороне микроконтроллера я примерно разобрался, почему там скорость тактирования должна быть в 16 раз выше битрейта, для лучшего сэмплирования. Но вот как тактировать передатчик, т.е. Циклон, я не могу понять. Во многих примерах тактирование ставят в 2 раза больше битрейта. Но почему так я и не выяснил. Как быть? Бодрейт для проекта выбран 9600. Делить с помощью PLL частоту кварца до 19200 и с такой же частотой обрабатывать приходящие на ПЛИС данные? Просветите пожалуйста новичка
Flip-fl0p
Цитата(mongol @ Aug 22 2017, 18:24) *
Имеется проект небольшой, на Циклон поступают данные извне, а затем эти данные передаются по UART на микроконтроллер STM. Циклон тактируется от кварца на 100 MHz. На стороне микроконтроллера я примерно разобрался, почему там скорость тактирования должна быть в 16 раз выше битрейта, для лучшего сэмплирования. Но вот как тактировать передатчик, т.е. Циклон, я не могу понять. Во многих примерах тактирование ставят в 2 раза больше битрейта. Но почему так я и не выяснил. Как быть? Бодрейт для проекта выбран 9600. Делить с помощью PLL частоту кварца до 19200 и с такой же частотой обрабатывать приходящие на ПЛИС данные? Просветите пожалуйста новичка

Тактируйте передатчик той частотой, какой вам удобно. Главное чтобы данные выводились наружу (в микроконтроллер) с частотой бодрейта.
dimka76
Передатчик UART это просто сдвиговый регистр. Соответственно, тактировать его надо с частотой битрейта. Т.е. в вашем случае 9600 Гц.
Александр77
Цитата(dimka76 @ Aug 22 2017, 20:46) *
Передатчик UART это просто сдвиговый регистр. Соответственно, тактировать его надо с частотой битрейта. Т.е. в вашем случае 9600 Гц.

Более высокая частота позволяет точнее определять начало приема данных. А сдвиг данных на скорости передачи может обернуться неприятным сбоем.
Maverick
в 16 раз тактовая частота выше должна быть.
Причины Вам Александр77 Вам рассказал.
Для ПЛИС это не есть проблема.
Посмотрите xapp341 там реализация как раз есть

Для новичка может SPI лучше выбрать? Проще....
krux
все серийные UART используют на приеме 8х или 16х оверсемплинг с решением принятого бита по мажоритару.

обычно берут максимальную скорость, с которой должен работать UART, например 115200, умножают на коэф. оверсемплинга, например 8х, получают 921600 и используют это значение в качестве тактовой частоты.
Всё, что должно работать медленнее - делают стробированием, с определенными делителями.
Ну и поскольку работать со скоростью 115200 с использованием прерываний без FIFO невозможно - ставят FIFO внутрь этого UART, байт так на 64 как минимум.
AVR
Цитата(mongol @ Aug 22 2017, 18:24) *
Циклон тактируется от кварца на 100 MHz.
Как быть? Бодрейт для проекта выбран 9600. Делить с помощью PLL частоту кварца до 19200 и с такой же частотой обрабатывать приходящие на ПЛИС данные? Просветите пожалуйста новичка

А зачем тут PLL? Элементарный делитель на 10417...
100*10^6 / 10417 = 9599,69280983 ~ 9600
Ошибка тысячные процента, считаем идеал, stm32 прекрасно такое скушает.
Вот каждый 10417-й цикл выдвигаем бит наружу.

P.S. Обратите внимание: из ПЛИС только передача в сторону STM32, приема нет, как я понял.
mongol
Нашёл пост
https://m.habrahabr.ru/post/278005/
Вот здесь по другому принципу высчитывается частота. Причем полученное значение непонятно как коррелирует с желаемым.
iosifk
Цитата(mongol @ Aug 23 2017, 16:04) *
Нашёл пост
https://m.habrahabr.ru/post/278005/
Вот здесь по другому принципу высчитывается частота. Причем полученное значение непонятно как коррелирует с желаемым.

Хороший пример того, как НЕ НАДО делать проекты...
Flip-fl0p
Цитата(mongol @ Aug 23 2017, 16:04) *
Нашёл пост
https://m.habrahabr.ru/post/278005/
Вот здесь по другому принципу высчитывается частота. Причем полученное значение непонятно как коррелирует с желаемым.

Так а Вы сами в сути UART разберитесь. На форуме достаточно много тем про UART. Тем более Вы же не делаете полноценный приемо-передатчик 16С550. А на хабре действительно не самый лучший пример реализации UART.
mongol
Цитата(iosifk @ Aug 23 2017, 14:21) *
Хороший пример того, как НЕ НАДО делать проекты...

Стало очень интересно, в чем минусы вышеприведенного проекта?
iosifk
Цитата(mongol @ Aug 23 2017, 17:09) *
Стало очень интересно, в чем минусы вышеприведенного проекта?

много есть о чем надо рассказать...
Если хотите, то голосом по скайпу. Мой адрес в личной карточке форума...
Maverick
понимаю, что делаю медвежью помощь...
см. вложение - altera
Цитата
For example, a basic UART implementing the 115200 baud N81 protocol costs only 62 ALUTs.
The example design uart_hw_test implements a simple demo for use with a terminal
app. It takes input characters on the receive side and sends the following character
(for example, ”a” –> ”b”) out the transmitter.


Inanity
Цитата(Maverick @ Aug 23 2017, 20:59) *
понимаю, что делаю медвежью помощь...
см. вложение - altera


Мне очень не нравится этот код.

Смеха ради посмотрел код приёмника и не увидел синхронизаторов там, где по моему мнению они обязаны быть.
Модуль uart_rx. Асинхронные данные приходят по проводу rxd. В этом процессе они защёлкиваются в триггер last_rxd:

Код
reg last_rxd;
always @(posedge clk) begin
    last_rxd <= rxd;
end


Триггер last_rxd может находиться в метастабильном состоянии, т.к. по rxd пакеты приходят асинхронно.
Провод slew тоже метастабилен, т.к. комбинационно зависит от last_rxd:

Код
wire slew = rxd ^ last_rxd;


Далее по коду и slew, и last_rxd используются в различных процессах, if-ах и в автомате состояний.

Код
WAITING : begin
    // wait for a start bit (0)
    if (!slew & sample_now && !last_rxd) begin   // тут ещё нравится использование & и && одновременно.
        state <= READING;
        held_bits <= 0;
    end
end


Оно, может и работает, но по-моему это жесть. Да ещё и копирайт от альтеры)
x736C
Inanity, правильные наблюдения.
Только добавлю то, к чему пришел не сразу и что использую во всех своих проектах.
Правилом хорошего тона является асинхронный сигнал пометить суффиксом.
Например, bus_16_or_68_async.
Обычно, это закладывается в стандарт кодирования. Если посмотреть стандарты известных производителей (из тех, что есть в открытом доступе), это правило или требование присутствует.
В Altera используют префикс a, который пишется слитно с наименованием сигнала. Например, adata.

То есть не очень понятно, с чего Вы взяли, что сигнал в данном примере (а это не более, чем пример от Altera) может быть асинхронным.
В тестбенче rxd = txd; То есть пример представлен в синхронном виде.
Ваше утверждение «Асинхронные данные приходят по проводу rxd» в данном случае все-таки неверно.
andrew_b
Цитата(Inanity @ Aug 24 2017, 00:53) *
Да ещё и копирайт от альтеры)
Не надо думать, что в корпорациях пишут идеальный код. Говнокода там тоже достаточно.
AVR
Цитата(Inanity @ Aug 24 2017, 00:53) *
Оно, может и работает, но по-моему это жесть. Да ещё и копирайт от альтеры)

И что тут такого? У Xilinx их модули для UART хоть и весьма компактные, но лично меня как пользователя тошнит от того как там организовано в этих модулях, я просто проклинаю автора и его матушку поминаю, хотя как-то удалось это заставить работать, сейчас правда своя нормальная реализация уже сделана. А еще копирайт от Xilinx... sm.gif
Maverick
Я смотрю здесь покритиковать все мастаки, а поделиться с человеком готовым описанием нет, зачем.
Может быть так и надо, просто критиковать?
Так же проще.



AVR
Цитата(Maverick @ Aug 24 2017, 11:05) *
Я смотрю здесь покритиковать все мастаки, а поделиться с человеком готовым описанием нет, зачем.

Вечером сегодня либо завтра попробую выложить свой простенький UART-передатчик с комментариями, как раз от 100 МГц тактироваться будет. Человек просил совета - советы ему отгрузили в полном объеме wink.gif
mongol
Мне понравилась вот эта реализация:
https://sites.google.com/site/vanyambausesl...art-transmitter
И здесь, как я понял, тактирование увеличено в 2 раза для переключения между состояниями автомата
AVR
Цитата(AVR @ Aug 23 2017, 11:45) *
А зачем тут PLL? Элементарный делитель на 10417...
100*10^6 / 10417 = 9599,69280983 ~ 9600
Ошибка тысячные процента, считаем идеал, stm32 прекрасно такое скушает.
Вот каждый 10417-й цикл выдвигаем бит наружу.

Реализация идеи: Нажмите для просмотра прикрепленного файлаТестбенч: Нажмите для просмотра прикрепленного файла
Тактовая 100 МГц, на выходе почти 9600, но достаточно точно.
Данные кушаются по valid, следующая порция - когда busy снимется в 0.
Недостаток реализации: если неудачно совпадет - будем на каждый байт дополнительно терять один бит пропускной способности, но зато всё очень просто сделано - просто делитель на 10417.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.