Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> VHDL

VHDL контроллер двух 7-сегментных дисплеев для Pmod SSD — простое FPGA-интегрирование

В этой статье я представлю VHDL-модуль, который может отображать двузначное число на Pmod SSD: семисегментном дисплее от Digilent. Двойной 7-сегментный дисплей совместим с интерфейсом Pmod, что означает, что вы можете использовать его без какой-либо пайки. Он вставляется в Pmod-разъем, который стандарт на многих платах разработки FPGA.

Для тестирования VHDL-реализации я использую Lattice iCEstick — низкобюджетную плату разработки FPGA с Pmod-разъемом. Помимо iCEstick, вам нужен кабель-сплиттер 2×6-pin в Dual 6-pin Pmod для преобразования от параллельного Pmod-разъема на iCEstick к последовательной версии штекера, которую ожидает 7-сегментный дисплей. Наконец, я рекомендую взять USB type-A удлинительный кабель, потому что вставка iCEstick прямо в USB-порт компьютера неудобна.

Как работают 7-сегментные дисплеи

Существует много разных 7-сегментных дисплеев на рынке. Количество цифр варьируется между ними, так же как физический интерфейс и распиновка. Общее решение, покрывающее все возможные 7-сегментные дисплеи, с которыми вы можете столкнуться, вероятно, не было бы очень удобным для пользователя. Однако вы можете использовать код, представленный в этой статье, как основу и модифицировать его под свои нужды.

Изображение выше из даташита на Pmod-модуль Digilent. Оно показывает, как 7-сегментный дисплей подключается к Pmod-пинам. Эти пины напрямую доступны для FPGA на iCEstick.

Семь пинов управляют по одному сегменту каждый на дисплее. Подавая логическую единицу на такой пин, соответствующий сегмент загорается на дисплее. Но на этом дисплее две цифры, и мы можем управлять только одной за раз. Пин P4/C на разъеме J2 выбирает одну или другую цифру. Когда логическое напряжение на этом пине '0', загорается правая цифра, если '1' — активируется левая цифра.

Десятичная точка "DP" не подключена и не может быть доступна.

Сущность (Entity)

Код ниже показывает сущность нашего VHDL-модуля seg7. Сущность имеет generic-порт с константой clk_cnt_bits. Она определяет длину внутреннего счетчика, контролирующего частоту обновления дисплея, частоту чередования между левой и правой цифрами.

Точная частота не критична. Выберите длину счетчика в диапазоне от 50 до нескольких сотен Герц. Формула, определяющая частоту обновления: refresh_hz = 2^clk_cnt_bits / clk_hz.

entity seg7 is
  generic (
    -- refresh_hz = (2 ** clk_cnt_bits) / clk_hz
    clk_cnt_bits : integer
  );
  port (
    clk       : in  std_logic;
    rst       : in  std_logic;
    value     : in  integer range 0 to 99;
    segments  : out std_logic_vector(6 downto 0);
    digit_sel : out std_logic
  );
end seg7;

Помимо тактового сигнала и сброса, сущность имеет один входной сигнал: значение для отображения на 7-сегментном дисплее. Сигнал value — целочисленный тип, ограниченный диапазоном 0 до 99, потому что это единственные числовые значения, которые можно показать, используя только две цифры.

Выходные сигналы — семь сегментов как вектор и сигнал выбора цифры для выбора либо левой, либо правой цифры для освещения.

Представление двоично-десятичного кода

Для представления цифр, показываемых на дисплее, мы будем использовать формат, известный как двоично-десятичный код (BCD). Хотя двоичное представление — самый эффективный способ хранить десятичное число, мы сталкиваемся с проблемами при попытке разделить его на левую и правую цифру для отображения на дисплее. Мы не можем различить десятичные цифры просто путем нарезки вектора, используемого для хранения числа.

subtype digit_type is integer range 0 to 9;
type digits_type is array (1 downto 0) of digit_type;
signal digit  : digit_type;
signal digits : digits_type;

Как показано в коде выше, мы объявляем подтип integer в диапазоне 0 до 9 для описания значения, которое может быть представлено одной десятичной цифрой. Затем мы объявляем новый массив типа, который может содержать два таких BCD-значения. Сигнал digit хранит число, в данный момент показываемое либо на левой, либо на правой стороне дисплея. С другой стороны, сигнал digits содержит отдельные десятичные символы для двух цифр, как они будут появляться человеку, смотрящему на экран.

Преобразование десятичного в BCD

Вход этого модуля, value — целое число в диапазоне 0 до 99, двоичное представление числа. Нам нужно преобразовать это единственное целое число в два целых в диапазоне 0 до 9, BCD.

Стандартный алгоритм для этого — Double Dabble, также известный как алгоритм shift-and-add-3. Хотя это хорошо для использования, я выберу более короткое решение в нашем случае, потому что у нас только две цифры для разделения.

digits(1) <= value / 10;
digits(0) <= value - ((value / 10) * 10);

Используя целочисленное деление, как показано в коде выше, мы можем изолировать старшую десятичную цифру и присвоить ее сигналу digits(1). Чтобы получить младшую цифру, мы можем вычесть старшую цифру из сигнала value, оставляя нам только число для присвоения сигналу digits(0).

Подсчет тактовых циклов

Задержка времени в FPGA — просто вопрос подсчета тактовых циклов. Период тактового сигнала — единственный предсказуемый временной интервал, на который вы можете положиться в вашем VHDL-коде. Код ниже показывает сигнал clk_cnt, который мы используем для подсчета тактовых циклов. Generic clk_cnt_bits определяет, сколько бит зарезервировать для этого беззнакового сигнала.

signal clk_cnt : unsigned(clk_cnt_bits - 1 downto 0);

Точная частота обновления дисплея менее важна, поэтому я выбрал беззнаковый тип здесь. Это позволяет нам использовать поведение самозаворачивания беззнакового сигнала. Все, что нам нужно сделать — инкрементировать счетчик на каждом фронте тактового сигнала. Код ниже показывает синхронный процесс с сбросом, который заботится об этом.

COUNT_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      clk_cnt <= (others => '0');
    else
      clk_cnt <= clk_cnt + 1;
    end if;
  end if;
end process;

Чередование между цифрами

Теперь, когда у нас работает свободно-бегущий счетчик, мы можем использовать старший бит (MSB) беззнакового сигнала счетчика для переключения между двумя цифрами. MSB чередуется между '0' и '1' с коэффициентом заполнения 50%. Первая строка кода ниже устанавливает сигнал digit_sel на основе значения MSB. Вторая строка реализует мультиплексор с MSB, используемым как селектор. Он передаст значение активной цифры из массива digits в сигнал digit.

digit_sel <= clk_cnt(clk_cnt'high);
digit     <= digits(0) when clk_cnt(clk_cnt'high) = '0' else digits(1);

BCD в 7-сегментный энкодер


Финальный шаг модуля seg7 — преобразовать BCD, хранимый в сигнале digit, в визуальное представление на 7-сегментном дисплее. Код ниже показывает процесс, достигающий этого с использованием case-оператора.

Позиция в векторе каждого битового литерала соответствует одному сегменту на дисплее. Индекс 0 равен сегменту A, индекс 1 — B, и так далее, до индекса 6, который управляет сегментом G. Отображение сегментов на индексы вектора получено из даташита на 7-сегментный дисплей Digilent.

ENCODER_PROC : process(digit)
begin
  case digit is
    when 0 => segments <= "0111111";
    when 1 => segments <= "0000110";
    when 2 => segments <= "1011011";
    when 3 => segments <= "1001111";
    when 4 => segments <= "1100110";
    when 5 => segments <= "1101101";
    when 6 => segments <= "1111101";
    when 7 => segments <= "0000111";
    when 8 => segments <= "1111111";
    when 9 => segments <= "1101111";
  end case;
end process;

Выход

VHDL-модуль seg7 будет рендерить на дисплее все, что вы присвоите входному сигналу value. В тестбенче мы инкрементируем сигнал value раз в секунду. Затем мы симулируем немного более 100 секунд, чтобы мы могли наблюдать точку завершения цикла счетчика value.

Волновой форму выше из ModelSim. Она показывает первую часть симуляции, где значение отсчитало от 0 до 15. Мы видим, что числа в массиве digits тоже считают. Единицы (0) считают каждый раз, когда меняется сигнал value, в то время как десятки (1) инкрементируются на каждом десятом числе.

Вы можете скачать проект ModelSim, включая тестбенч, используя форму ниже.

Если вы реализуете модуль seg7 как верхний модуль на FPGA, дисплей, скорее всего, покажет стабильное "00". Это потому, что '0' — самое распространенное значение по умолчанию, даваемое неинициализированным сигналам в FPGA. Когда сигнал value получает все нули, дисплей покажет именно это.

Чтобы пройти через все возможные входные числа, я создал обертку VHDL-модуль, который инкрементирует сигнал value десять раз в секунду. Затем я инстанцировал модуль seg7 в обертке перед реализацией дизайна на Lattice iCEstick. Циклическое GIF-видео ниже показывает, как реализованный дизайн выглядит на 7-сегментном дисплее.

Покупка Pmod SSD: Семисегментный дисплей

7-сегментный дисплей, использованный в этом блог-посте, от Digilent. Вы можете приобрести Pmod-модуль в веб-магазине Digilent, или получить его у одного из множества перепродавцов. В списке ниже я привел ссылки на страницу продукта дисплея в нескольких онлайн-магазинах электроники, которые имеют этот товар в наличии.

Обратите внимание, что если вы хотите использовать Digilent 7-сегментный дисплей с Lattice iCEstick, или любой другой платой разработки FPGA, имеющей 6×2-pin Pmod-разъем, вам также нужен кабель-сплиттер. Кабель доступен в Digilent, Digi-key, Mouser и RS Electronics.

Дополнительно, все компоненты доступны у различных продавцов на Amazon и eBay.

VHDL-курс с использованием Digilent 7-сегментного дисплея

Я запустил новый VHDL и FPGA курс для абсолютных новичков. В курсе я использую 7-сегментный дисплей от Digilent и плату разработки FPGA Lattice iCEstick для обучения VHDL. Нажмите на ссылку ниже, чтобы прочитать больше о курсе!

FPGA and VHDL Fast-Track:
Hands-On for Absolute Beginners

Вы знакомы с программированием, но новичок в VHDL?
Вам нужно короткое введение в эту незнакомую тему?
Ваш расписание полно, без времени на учебу?
Поймите основы FPGA-разработки с использованием VHDL за несколько вечеров! Этот курс для IT-профессионалов и студентов, которым нужен быстрый обзор предмета. С этим курсом и низкобюджетной платой разработки Lattice iCEstick, вы будете разрабатывать настоящее железо за часы.

Нажмите здесь, чтобы прочитать больше и записаться:
FPGA and VHDL Fast-Track: Hands-On for Absolute Beginners

VHDL

  1. Освоение параллельных операторов в VHDL: практическое руководство
  2. Создание Tcl-управляемого тестбенча для VHDL-модуля кодового замка
  3. Освоение функций VHDL: практическое руководство по эффективному дизайну
  4. Использование списков чувствительности в процессах VHDL для надежного RTL-проектирования
  5. Освоение формальной верификации модулей VHDL с помощью PSL
  6. Переменные в VHDL: практические примеры и правила для надежного дизайна
  7. Различия между сигналами и переменными в VHDL
  8. Курс FPGA и VHDL — создание контроллера точечно-матричного LED-дисплея с нуля
  9. Управление VHDL-тестбенчами из внешних файлов стимулов с TEXTIO
  10. Чтение BMP-изображений в VHDL-тестбенчах с помощью TEXTIO