August 26, 2011

LUT-мультиплексор

   Задача: реализовать в ПЛИС мультиплексор, описав его структурную модель, использующую только LUT. В мультиплексоре 8 входов данных. 


    Вроде, задача, как задача. Ничего особенного. В распоряжении LUT с количеством входов о 6-ти. Чтобы не расточать ресурсы ПЛИС, воспользуемся 2-мя LUT с 6-ю входами и 1-й LUT с 3-мя входами. В 1-ю LUT6 идут младшие 2 линии адреса и младшие 4 линии данных. Во вторую - те же линии адреса и старшие 4 линии данных. Конечный результат определяем с помощью LUT3, на которую подаются выводы LUT6 и старшая линия адреса.


    Самое сложное - это задать "маску" для 6-ти входовой LUT.  Необходимо учесть 2^6=64 всевозвожных комбинаций - дело нудное, пахнущее мелкими ошибками и кучей расплывающихся в глазах цифр. Не зря сразу хочется плюнуть и описать поведенческую модель вместо структурной. Намного проще ведь. Но это не наш метод. Да и производитель ПЛИС советует использовать одну большую LUT вместо нескольких меньших. Склепав таблицу истинности для LUT6, запишем её маску:
# HEX:
0xFEDCBA9876543210
# BIN:
1111111011011100101110101001100001110110010101000011001000010000
    Маска для LUT3 несколько короче:
# HEX:
0xE4
# BIN:
11100100

   И теперь проведем тест:
  1. устанавливаем адрес
  2. подаём сигнал только на вход по этому адресу
  3. подаём сигнал на все входы, кроме этого адреса
  4. подаём сигнал на все входы
  5. убираем все сигналы
  6. повторяем п 1-5 для каждого адреса (всего 8 раз)
    Смотрим диаграмму результата:


    Вуаля, "It works!", а значит, маска для LUT6 определена верно и ею можно дальше смело пользоваться.

    Если в распоряжении есть LUT с количеством входов только до 4, то можно использовать 7 LUT3:


    Видно 3 вертикальных каскада. Каждый каскад работает с одним битом адреса. 1-й - с младшим, 2-й - со вторым, 3-й - со старшим. Тесты проходятся аналогично.

    Исходники мультиплексора и теста в архиве. В файле с описанием первого приведены 2 описания архитектуры.

GameDev: 47 механик

   На inwebwetrust наткнулся на перевод англоязычной статьи по разработке игр. Описаны техники, уловки, которые часто применяются в социальных играх. Довольно занятно. Больше осознаёшь, как и что давит на моск и отупляет его во всяких социалках. Перевод читается лучше. Ну хотя бы из-за картинок :).
   Вдобавок там рядом мельтешит ссылка на другую статью. "Психология – это весело, или...". Тоже занятно и опять-таки картинки клевые. Котэ :). Да и пирамида Маслоу воспринимается почти без слов.
   Конечно, читать статьи только из-за картинок - не повод, но только не в этом случае. Они там и вправду классные :).

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.