August 19, 2011

ПЛИС + LCD "Hello, world!"

   Пост устарел. Уровень знаний VHDL в момент написания поста был довольно низок. Вскоре появится ссылка на реализацию SoC, в которой будет более понятна реализация передатчика данных на LCD. [25.01.2012]
  Обновление  [06.04.2012]: вот обещанная реализация : [ссылка]. Пример подключенияя [здесь]. К сожалению, пока нет времени написать документацию, но главный принцип все равно описан ниже.

    Ура, первое работающее "что-нибудь" на ПЛИС готово! Это, конечно, не что-то гениальное из рода "железного мозга", но и не "2+2". Всего лишь вывод строчки на LCD.


     Сложного ничего нет. Если не учитывать, что это первый проект на VHDL да и первый опыт работы с ПЛИС вообще. По началу всё это кажется несколько специфическим. Особенно после J2EE. Особенно после чтения "Чистого кода". Хорошо, что после чтения русскоязычной литературы нашел англоязычный кратний учебник по VHDL. Написано коротко и ясно. Читается легко и быстро. Как-то вот в случае с аппараткой англоязычная литература, блоги и форумы заметно информативнее и понятнее русскоязычных.

    Средства:
  1. Xilinx Spartan-3E Starter Kit Board;
  2. User Guide к ней;
  3. Xilinx ISE 13.1;
  4. USB Cable type A/type B;
    Работа с исходным кодом в ISE после ставшено почти родным Netbeans - жесть ещё та. Возникает мысль, что если уже хардкор, то по полной. К счастью это не штаны через голову одевать - привыкнуть вполне можно, хотя и по началу без автодополнения кода ощущается определённый дискомфорт. А в остальном - штука довольно-таки удобная. Не тупит, всё под рукой, лечить как Active-HDL не надо (попробуй дождись от них бесплатной лицензии на триалку хотя бы), под линуксами работает - красота в общем.
   
    Вывод текста заключается в следующем:
  1. Инициализация LCD.
  2. Пересылка команд и данных к LCD:
    1. Пересылка пачки команд для подготовки вывода текста.
    2. Непосредственно вывод текста.
    Для инициализации и отправки данных были созданы 2 разных устройства (LCD_initializer и LCD_byte_transmitter соответственно). Управляются они с помощью 3-го устройства (LCD_writer). Возможно, создание 3-х устройств покажется глупым и нелогичным, но, по-моему, более нелогично создавать вещи, которые выполняют разные функции, никак не связанные между собой. Да и вообще сваливать всё в одну кучу - нехорошо. Если после синтеза одного большого устройства количество используемых ресурсов ПЛИС будет заметно меньше, чем после синтеза нескольких меньших устройств, в сумме выполняющих ту же задачу, то, конечно, это будет повод задуматься и принять меры. А вот в данном случае создается не устройство управления запуском шаттла, а всего лишь академический проект-микроб.

    Инициализация

    Процесс инициализации описан в руководстве пользователя на странице 53 (Initializing the Display -> Power-On Initialization). В проекте она производится устройством "LCD_initializer". Файл описания устройства - "lcd_initializer.vhd". Файл с тестом - "LCD_initializer_test.vhd". Схема автомата приведена ниже.


    0-состояние - состояние ожидания (простоя). В нём устройство находится сразу после включения. 
   Переход в 1-е состояние происходит при подче сигнала RESET. Так же при подаче этого сигнала происходит переход в 0-состояние из любого другого.
    Состояния 3, 6, 9, 12 полностью идентичны.
   Состояния 2, 5, 8 так же полностью идентичны. Состояние 11 очень похоже. Разница лишь в том, что в нем на выход SF_D подается 0х2, а не 0х3.
    Инициализация длится 19'280'960 нс (964048 циклов при частоте 50 МГц). Между сменами состояний проходит 1 цикл (20 нс).

  Передача данных в 8-ми битном режиме через 4-х битный интерфейс

    Временные диаграммы передачи данных приведены в руководстве пользователя на странице 52. В проекте осуществляется с помощью устройства "LCD_byte_transmitter". Файл описания  - "LCD_byte_writer.vhd". Файл теста - "LCD_byte_transmitter_test.vhd". Схема автомата приведена ниже.


   Как и в предыдущем случае 0-состояние - это состояние ожидания. Устройство находится в нем после включения. При подаче сигнала RESET происходит переход в него из любого другого состояния.
     Состояния 2, 6 полностью идентичны.
     Состояния 3, 7 так же полностью идентичны.
     Состояния 2-4 - передача старшего полубайта.
     Состояния 6-8 - передача младшего полубайта.
    Между передачами 2-х полубайт одного байта происходит задержка в 1 мкс (20 + 940 + 40 (нс)).
    Между передачами 2-х байт должна выполняться минимальная задержка в 40 мкс. Если данные идут последовательно, то это достигается задержкой 8-го, 9-го и 2-го состояний.
  Необходимость передачи байта сообщается уровнем "1" на сигнале TRANSMISSION_NEEDED. 
    При работе устройства значения сигналов LCD_E и LCD_RW изменяются. В состояниях, когда они не нужны, их значения приводятся в исходное состояние. (Во время пауз между передачами байт и полубайт).
   Передача байта длится 1'540 нс (77 циклов при частоте 50 МГц). После этого можно на вход подавать другое значение. Передача байта с минимальной задержкой длится 41'480 нс (2074 цикла при частоте 50 МГц). Между сменами состояний проходит 1 цикл (20 нс).

    Передача команд и данных

  Передача команд и данных контролируются с помощью устройства "LCD_writer".  Файл описания - "LCD_writer.vhd". Файл с тестом - "LCD_writer_test.vhd". Для выполнения передачи данных устройство обращается к LCD_byte_transmitter.

   Состояния:
   0 - ожидание инициализации. (работа устройства LCD_initializer);

   RS = 0
   1 - передача "00101000" - "Function Set";
   2 - передача "00000110" - "Entry Mode Set";
   3 - передача "00001100" - "Display On";
   4 - передача "00000001" - "Clear Display" (1.64 мс);
   5 - передача "10000000" - "Set DD RAM Address";

   RS = 1
   RW = 0
   6 - передача "01011001" - "Y"; 
   7 - передача "01100101" - "e";  
   8 - передача "01100001" - "a"; 
   9 - передача "01101000" - "h";  
   10 - передача "00100001" - "!"; 

   11 - простой. 

   Между сменами состояний проходит 1 цикл (20 нс). Диаграммы тестов не приводятся из-за слишком больших пауз между некоторыми операциями.
    
  В [архиве] хранятся указанные файлы + UCF. Подача сигнала RESET осуществляется с помощью кнопки BTN_East.

10 comments:

  1. Вы бы не могли перезалить архив http://dl.dropbox.com/u/76022516/proj/fpga/vhdl/fpga_lcd.zip ?

    ReplyDelete
    Replies
    1. готово. архив почему-то был размером в 4 байта.
      в этой статье из ценного осталось только описание. код я бы советовал смотреть уже в рабочем проекте, а тест для него здесь. правда, я не помню, что оно выводит в тесте, но сам код намного понятнее, чем в архиве

      Delete
  2. Спасибо за помощь. Буду разбираться...

    ReplyDelete
  3. Можно ещё вопрос:
    А ведь подключали через PLB в Xilinx EDK? Если есть возможность, то выложите и userlogic пожалуйста.

    ReplyDelete
  4. делалось все в XPS. отдельно UCF тут.

    Весь проект тут. Исходники можно скачать пачкой. Поскольку исходники в репозитории к статье не относятся, то можно просто смотреть директории "src/SoC/LCD" и "tests/SoC/LCD".

    Еще один пример подключения (живой) есть в тут. Как видно, интерфейс адаптирован под подобие общей шины.

    Я почти год проектом не занимался, и платы у меня при себе нет. Так что могу только словами помочь. Где-то была структурная схема, если надо, могу поискать.

    + это все на частоте 50 МГц работало. константы под нее брались.

    ReplyDelete
  5. Добрый день....скажите пожалуйста....можно ли всю эту систему что вы здесь описывали связать с протоколом can?

    ReplyDelete
    Replies
    1. наверно, можно. исходники-то есть :) периферия там нормально работает. чтоб сделать свой модуль, можно посмотреть, например, подключение линейки диодов или uart-а. ну а сам cpu можно рассматривать максимум в академических целях. гарантированно работает набор команд, достаточный для реализации калькулятора с операциями +-/*, вводом данных через uart и свичи, и выводом результатов на lcd. остальные возможности не гарантирую, там где-то при реализации блока управления задержки вылазили

      Delete
  6. А не подскажете какой ip core у этого дисплея? Я бы свой хотел реализовать

    ReplyDelete
  7. А не подскажете какой ip core у этого дисплея? Я бы свой хотел реализовать

    ReplyDelete
    Replies
    1. Что значит "какой ip core"? Внизу статьи ссылка на архив. Ещё есть вариант переиспользуемого модуля: https://github.com/oblalex/0xFFFFua/tree/master/src/SoC/LCD

      Delete