Московский Государственный Университет Приборостроения и Информатики
Кафедра ИТ-6 “Управление и моделирование систем”
“Реализация последовательного асинхронного интерфейса”
по курсу 1629 “Современные информационные технологии”
2012г.
Цель работы: реализация модуля UART на языке VHDL, тестирование в среде ModelSim, проверка работоспособности модуля с помощью отладочной платы Cyclone II FPGA Starter Development Kit.
Аппаратное обеспечение: отладочная плата Cyclone II FPGA Starter Development Kit.
Краткие теоретические сведения:
Универсальный асинхронный приемопередатчик (UART universal asynchronous receiver-transmitter) позволяет передавать данные между цифровыми устройствами по последовательному протоколу. Существует несколько стандартов, определяющих количество, характеристики и назначение сигналов, участвующих в обмене данными. До недавнего времени наиболее распространенным стандартом для ПК был RS-232. Этот последовательный интерфейс использует 9 физических проводников:
9-ти пиновый разъем | Обозначение | Название |
3 | TxD | Передача данных от компьютера |
2 | RxD | Прием данных компьютером |
7 | RTS | Запрос на передачу (request to send) |
8 | CTS | Готовность передачи (clear to send) |
6 | DSR | Готовность источника данных/ Data set ready |
4 | DTR | Готовность приемника данных/Data terminal ready |
1 | DCD | Наличие несущей / Carrier detect |
9 | RI | Сигнал вызова / RI |
5 | SG | Общий провод (земля) |
Сигналы RTS/CTS, DTR/DSR, DCD, RI относятся к так называемому аппаратному интерфейсу управления потоком и в общем случае являются необязательными. Сигналы TxD и RxD обеспечивают параллельную (одновременную) асинхронную передачу в обоих направлениях. Асинхронный режим означает, что передача происходит не постоянно, а по мере необходимости. В рамках интнрфейса RS-232 данные передаются группами длиной от 3 бит до одного байта (8 бит). В режиме когда передача отсутствует на линию (RxD или TxD) выставляется высокий уровень сигнала. Для индикации начала передачи на линию выставляется сигнал низкого уровня. Вслед за этим последовательно передаются биты данных. Далее передается необязательный бит четности, после чего высоким уровнем передается стоповый бит.
Рис. 1 Диаграмма сигнала (RxD или TxD) интерфейса RS-232.
В рамках лабораторной работы необходимо реализовать модуль передатчика RS-232 и обеспечить прием одного байта данных на компьютере от отладочной платы. Для этого необходимо реализовать следующую схему:
Рис.2 Схема эксперимента.
Классическая схема реализации последовательной передачи битов строится на основе сдвигового регистра.
Рис.3 Реализация модуля передатчика на основе сдвигового регистра.
По сигналу “старт” логика управления, находясь в режиме ожидания, записывает входные данные в соответствующие позиции сдвигового регистра, устанавливает стартовый бит S в 0, стоповый бит St в единицу, а бит четности заполняет с помощью операции XOR. После этого логическая схема управления переходит в режим “передача”, в котором на каждом такте в линию передачи выдается самый правый бит и весь регистр сдвигается вправо. После передачи стопового бита логика управления снова переходит в режим ожидания.
Возможная схема реализация логики управления представлена на рисунке 4.
Рис.4 Пример реализации логики управления последовательного порта.
Порядок выполнения
1. Реализуйте модуль передатчика в виде модуля на языке VHDL. Интерфейс передатчика должен, как минимум, содержать следующие сигналы:
entity uarttx is port ( reset : in std_logic ; clk : in std_logic ; data_in : in std_logic_vector (7 Downto 0) ; wr : in std_logic ; tx : out std_logic ) ; end uarttx ; |
2. Проверьте правильность функционирования разработанного вами передатчика в среде ModelSim. Для этого:
2.1. Создайте папку проекта на диске. Путь к папке не должен содержать русских символов, например c:\work\uarttx\. Поместите ваш файл uarttx.vhd, содержащий код передатчика в эту папку.
2.2. Запустите программу ModelSim. Выполните команду меню File->Change Directory. Укажите свою директорию.
2.3. Создайте файл test_uarttx.vhd в этой же папке. В этот файл поместите код для тестирования созданного вами передатчика. Вы можете написать этот код сами или воспользуйтесь готовым примером.
library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_signed.all ; use ieee.std_logic_arith.all ;
entity test_uarttx is end ;
architecture test_ar_uarttx of test_uarttx is component uarttx is port ( reset : in std_logic ; clk : in std_logic ; data_in : in std_logic_vector (7 Downto 0) ; wr : in std_logic ; tx : out std_logic ) ; end component ;
signal t_reset : std_logic ; signal t_clk : std_logic := '0' ; signal t_data_in : std_logic_vector(7 downto 0) ; signal t_wr : std_logic := '0' ; signal t_tx : std_logic := '0' ;
begin dut: uarttx port map ( reset => t_reset, clk => t_clk, data_in => t_data_in, wr => t_wr, tx => t_tx ) ;
-- ~300 bit/s t_clk <= not t_clk after 1500 us ;
stimulus: process begin wait for 3000 us ; t_reset <= '1' ; wait for 3000 us ; t_reset <= '0' ; t_data_in <= b"01101001" ; wait for 3000 us ; t_wr <= '1' ; wait for 3000 us ; t_wr <= '0' ; wait ; end process ; end architecture ; |
2.4. Теперь в вашей директории есть два исходных файла:
uarttx.vhd
test_uarttx.vhd
Создайте рабочую библиотеку. Выберите пункты меню File->New->Library. Вам будет предложено создать рабочую библиотеку с именем work. Соглашайтесь. В эту библиотеку будут помещены результаты компиляции.
2.5. Скомпилируйте ваши файлы, выбрав пункты меню Compile->Compile... Укажите файлы для компиляции и нажмите кнопку Compile. После успешной компиляции изучите содержание библиотеки work.
2.6. Перейдите в режим симуляции. Для этого щелкните правой кнопкой мыши на элементе test_uarttx в библиотеке work и выберите пункт Simulate.
Укажите время симуляции - 50 миллисекунд:
Выделите все сигналы в окне Objects и перетащите их мышью в окно Wave:
Запустите процесс моделирования:
Отмасштабируйте полученные графики:
В результате вы должны получить следующие диаграммы сигналов:
3. Создайте новый проект в среде Quartus, используйте имя проекта, отличное от uarttx.vhd.
3.1. Скопируйте файл uarttx.vhd в папку проекта и добавьте его в проект. Создайте новый файл Block Diagram/Schematic File. Сохраните его под тем же именем что и название проекта.
3.2. Откройте файл uarttx.vhd в среде Quartus, выберите пункты меню File->Create/Update->Create Symbol Files for Current File.
3.3. Вернитесь к документу txport.bdf. Выберите режим SymbolTool.
Кликните на пустом месте в окне документа txport.bdf. ВЫберите созданный символ для uarttx.vhd и поместите его в схему.
Пользуясь режимом PinTool,
добавьте входные порты reset, clk50, wr и выходной порт tx.
Отладочная плата предоставляет тактовый сигнал 50МГц, мы будем использовать соединение на скорости 300 бит/сек. Следовательно нам необходимо сформировать тактовый сигнал 300 Гц. Это в 166666.(6) раз медленнее чем 50МГц. Для реализации такого дробного делителя будем использовать схему PLL для получения промежуточной частоты частоты, кратной 300Гц, и после этого, поделим ее с помощью счетчика.
Мы будем использовать промежуточную частоту 19660800Гц = 300Гц * =300 * 65536Гц. На втором этапе частоту надо поделить на 65536 с помощью счетчика.
Для добавления PLL перейдите в режим SymbolTool и наберите в поле Name altpll.
Нажмите OK, Далее. Укажите в качестве частоты входного сигнала значение 50MHz:
Нажмите кнопку Далее 3 раза, укажите для выхода c0-Core/External Output Clock значение частоты 19.6608MHz.
Добавьте модуль PLL в схему
Создайте новый модуль на языке VHDL и поместите туда код делителя частоты (счетчика).
library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_signed.all ; use ieee.std_logic_arith.all ;
entity count is port ( clk: in std_logic ; out1: out std_logic ; out2: out std_logic ) ; end count ;
architecture a_count of count is signal counter: std_logic_vector(15 downto 0) := b"0000_0000_0000_0000" ; begin out1 <= counter(14) ; out2 <= counter(15) ; process(clk) begin if rising_edge(clk) then counter <= counter + 1 ; end if ; end process ; end a_count ; |
Сгенерируйте для этого файла символ (File->Create/Update->Create Symbol Files for current file) и разместите этот символ в схеме после PLL.
Соберите схему полностью
Соедините внешние контакты микросхемы с логическими сигналами в схеме. Воспользуйтесь таблицами из предыдущей лабораторной, для присоединения сигналов reset и wr к кнопкам, воспользуйтесь таблицей:
Для соединения логического выхода tx воспользуйтесь таблицей:
Скомпилируйте проект, после чего перейдите к пункту меню Tools->SignalTap II Logic Analyzer (при этом у вас должна быть включена опция Enable sending TalkBack data to Altera)
Укажите в качестве тактового сигнала для записи данных выход out1 модуля count. В список сигналов для анализа добавьте входные сигналы от кнопок reset, wr, сигнал out2 модуля count и выходной сигнал tx.
Скомпилируйте проект еще раз, загрузите прошивку в плату. Перейдите в окно LogicAnalyzer нажмите кнопку Run Analysis:
Нажмите на плате на кнопку, которую вы присоединили к сигналу wr. Вы должны увидеть результаты измерения реальных сигналов в плате:
Выключите плату!
Соедините ком-порт на плате к ком-порту на компьютере. Включите плату и загрузите вашу прошивку. На компьютере запустите программу HyperTerminal или аналогичную ей. Задайте параметры соединения:
Нажмите Ok, при каждом нажатии клавиши, соответствующей сигналу wr вы должны наблюдать прием символа (одного байта) в окне терминала.
Для устранения эффекта многократного срабатывания можно использовать следующий код.
library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_signed.all ; use ieee.std_logic_arith.all ;
entity starter is port ( reset : in std_logic ; clk : in std_logic ; raw_start : in std_logic ; strobe : out std_logic ) ; end starter ;
architecture a_starter of starter is signal counter: std_logic_vector(7 downto 0) := b"0000_0000" ; signal out_strobe : std_logic := '0' ; signal ena : std_logic := '0' ; signal res : std_logic := '0' ; begin strobe <= out_strobe ; ena <= not counter(7) ; res <= raw_start and counter(7) ; process(clk) variable count_ena : std_logic := '0' ; begin if reset='1' then counter <= b"0000_0000" ; elsif rising_edge(clk) then if res='1' then counter <= b"0000_0000" ; elsif ena='1' then counter <= counter + 1 ; end if ; out_strobe <= res ; end if ; end process ; end a_starter ;
|
Заключение и выводы
Ссылки
1. http://ru.wikipedia.org/wiki/RS-232
2. http://www.fpga4fun.com/SerialInterface.html
3. Pedroni, Volnei A. Circuit design with VHDL. Massachusetts Institute of Technology. 2004.