В этом апноуте приведено функциональное описание исходного кода VHDL и Verilog для создания UART. Код может использоваться для микросхем CPLD XC95144, XCR3128XL или XC2C128. Получить исходный код VHDL или Verilog можно на сайте Xilinx, или по ссылке [2].
Универсальный асинхронный приемопередатчик (Universal Asynchronous Receiver Transmitter, UART) всегда максимально широко использовался для последовательного обмена данными в электронной аппаратуре. UART позволяет создать полнодуплексное соединение через физические линки наподобие RS232. Порты UART доступны в большинстве недорогих стандартных изделиях большинство производителей микроконтроллеров. Описанный здесь демонстрационный код VHDL и Verilog показывает реализацию UART на чипах Xilinx CPLD начального уровня, что само по себе довольно полезно для практического применения как на младших моделях CPLD, так и на более старших микросхемах логики FPGA.
Базовые функции аппаратуры UART как микропроцессорного интерфейса - двойная буферизация данных передатчика, генерация фрейма, битов четности, преобразование последовательных данных в параллельные и наоборот. Используемый формат фрейма UART: стартовый бит лог. 0, 5..8 бит данных, генерируемый по выбору бит четности и 1 или 2 стоп-бита. Некоторые порты UART включают дополнительные сигналы для интерфейса модема. В этом дизайне дополнительные сигналы не реализованы.
Формат фрейма для передаваемых/принимаемых данных UART показан на рис. 1. Фрейм обрамлен состоянием ожидания, когда уровень сигнала достаточно долгое время равен лог. 1. Передаваемый символ в фрейме состоит из 5 - 8 бит данных. Стартовый бит имеет значение лог. 0, и одиночный стоповый бит имеет значение лог. 1.
Рис. 1. Формат фрейма UART (показан самый популярный фрейм из 8 бит данных).
[Приемник]
Сигналы, используемые в приемнике, показаны в таблице 1. Приемник выдает данные через параллельную шину dout[7:0] с сигналом rdn. Контроллер может генерировать строб rdn, если data_ready равен true. Приемник снабжен двойной буферизацией, что позволяет удерживать данные в буферном регистре rbr[7:0], пока данные последовательно вдвигаются в регистр сдвига приемника rsr[7:0]. Это дает контроллеру гибкость при операциях чтения шины.
Приемник детектирует фрейм символа по битам старта и стопа, выделяя из фрейма биты данных. Переменная no_bits_rcvd управляет размером слова.
Регистр clkdiv[3:0] используется для управления временем, за которое декодируются данные. Приемник использует 16x локальных тактовых импульсов и декодирует значение значение бит старта, данных и стоп-бита посередине их интервалов. Для этой цели стартовый бит инициализирует работу счетчика с помощью clkdiv[3:0]. После детектирования перепада в лог. 0 стартового бита приемник считает 16x такты до 8 и декодирует уровень, или делает выборки значения уровня сигнала. Затем регистр clkdiv[3:0] сбрасывается в 0, и далее считает 16x такты до 16. Это обеспечивает центрирование выборки для бит данных и стоп-бита.
Рис. 2. Принцип оцифровки бит принимаемых данных.
Обычно в UART используется три сигнала детектирования ошибки. Ошибка четности (Parity Error) показывает, четное или нечетное количество единичек присутствовало в обработанных данных. Ошибка переполнения (Overrun Error) показывает, были ли данные в буферном регистре приема перезаписаны данными из регистра сдвига до того, как контроллер прочитал их. Обработка этого вида ошибки не реализована в исходном коде VHDL/Verilog. Ошибка фрейма (Framing Error) показывает, что стоп-бит не был равен лог. 1.
Таблица 1. Логические сигналы приемника.
Сигнал |
Направление |
Функция |
rst |
I |
Сброс. |
clk16x |
I |
Вход тактов 16x. |
rdn |
I |
Строб чтения. |
dout[7:0] |
O |
Шина выходных данных. |
framing_error |
O |
Сигнал ошибки фрейма. |
parity_error |
O |
Сигнал ошибки четности. |
rbr[7:0] |
Внутренний сигнал |
Буферный регистр приемника - получает данные из rsr[7:0] и передает на шину data[7:0]. |
rsr[7:0] |
Регистр сдвига приемника - получает данные со входа и передает их в rbr[7:0]. |
no_bits_rcvd |
Управляет количеством бит фрейма и работой приемника. |
clk1x_enable |
Разрешает тактирование от clk1x. |
clk1x |
Тактовый сигнал 1x, используемый для внутренних операций. |
[Передатчик]
Сигналы, используемые передатчиком, показаны в таблице 2. Передатчик подключается к шине данных с сигналом опустошения буфера передатчика (transmitter buffer register empty, tbre) и сигналом wrn. Контроллер может генерировать строб wrn, если tbre равен лог. 1. Передатчик снабжен двойной буферизацией, что позволяет данным din[7:0] быть записанными в регистр буфера tbr[7:0], когда данные выдвигаются из регистра сдвига tsr[7:0]. Передатчик генерирует фрейм, состоящий из состояния ожидания (idle state, лог. 1 на sdo), лог. 0 на старт-бите, восьми бит данных и стоп-бита.
Значение no_bits_sent управляет размером слова и последовательностью операций передатчика. Чтобы поменять размер слова, измените значение no_bits_sent в исходном коде.
Таблица 2. Логические сигналы передатчика.
Сигнал |
Направление |
Функция |
rst |
I |
Сброс, который инициализирует исходные значения wrn1, wrn2, no_bits_sent, clkdiv[3:0], tbr[7:0], tsr[7:0]. |
clk16x |
I |
Вход тактов 16x, определяющий скорость передачи. |
wrn |
I |
Управляющий сигнал, который защелкивает данные из din[7:0] в регистр tbr[7:0]. |
sdo |
O |
Последовательный выход данных. |
tbre |
O |
Сигнал опустошения буфера передатчика. |
no_bits_sent |
Внутренний сигнал
|
Управляет размером слова и последовательностью работы передатчика. |
clk1x_enable |
Разрешает тактирование от clk1x. |
tbr[7:0] |
Принимает данные с шины din[7:0] и передает их в регистр tsr[7:0]. |
tsr[7:0] |
Принимает параллельные данные их tbr[7:0], и выдвигает их в sdo. |
clkdiv[3:0] |
Используется для генерации внутренних тактов. |
[Ссылки]
1. XAPP341 UARTs in Xilinx CPLDs site:xilinx.com. 2. 181226Xilinx-CPLD-UART.zip - исходный код, документация. |