← Седьмая часть

В предыдущем посте я писал о микрокоде и слое скриптинга. На этом этапе калькулятор почти полностью существовал только в ПО: в виде десктопного Qt-приложения, выполняющего симуляцию, или в виде страницы с WebAssembly в браузере. Это удобная среда для разработки и демонстрации, но это не калькулятор. Калькулятор должен лежать на столе, его можно взять и постучать по кнопкам.

Сегодня мы поговорим об этом этапе (за исключением издевательств над кнопками).

С чего мы начинаем: плата разработчика EP2C5

Первое оборудование, на котором мы будем запускать код калькулятора, не разработано специально под эту задачу. Это маленькая стандартная плата Altera EP2C5 Mini Dev Board (на момент написания статьи продаётся на eBay примерно за $5) — модуль размером с банковскую карту, на котором установлены Cyclone II EP2C5T144C8 FPGA, генератор на 50 МГц, несколько светодиодов, кнопка и четыре набора по 2x14 контактов GPIO, позволяющие получить доступ к большинству из 144 контактов FPGA. Отсутствие на плате периферии — это преимущество: ничто не сравнится с контактами GPIO и нам не придётся обходить проблему использования фиксированных ресурсов.

The Altera EP2C5 Mini Dev Board: around $5 on eBay, and the first piece of hardware the calculator ever ran on.

Я уже много лет использую эту плату для экспериментов с FPGA, она неприхотливая и дешёвая. По современным стандартам, сама FPGA здесь довольно скромная (4608 логических элементов, 26 встроенных множителей, 89 пользовательских контактов ввода-вывода), но её было более чем достаточно для всех моих проектов. Для Cyclone II также требуется ПО Quartus 13.0 SP1, оно бесплатное и хорошо работает с этим семейством устройств.

Чтобы использовать эту плату под первую версию калькулятора, я внёс небольшие аппаратные модификации: пришлось удалить пару SMD-резисторов и конденсаторов, направлявших контакты GPIO на неподходящие для моей разводки выводы. Эти компоненты были необходимы только для поддержки разных моделей устройств одной платой (EP2C8), поэтому можно было вполне безопасно убрать их в версии EP2C5. В документации платы на веб-сайте чётко говорится, что они «требуются только для EPC28».

После внесения этих изменений плата EP2C5 превратилась в CPU. Для настоящего калькулятора мне нужны были ещё клавиатура и дисплей. Они были расположены на отдельной печатной плате.

The two removed SMD components left empty pads — visible here between the GPIO headers. Safe to remove on the EP2C5 variant; required only for the EP2C8 SKU.
Пустые контактные площадки двух удалённых SMD-компонентов

Rev A: две платы, соединённые гибким кабелем

Конфигурация Rev A представляла собой систему из двух плат, описанную в части 5: модуль EP2C5 занимался FPGA, а к нему 40-контактным гибким кабелем была подключена специально спроектированная печатная плата с дисплеем и матрицей клавиш 7×5. В этой части я расскажу о сканировании матрицы клавиш, OLED-совместимом интерфейсе HD44780 и о процессе работы с EasyEDA/JLCPCB.

Rev A: the EP2C5 dev board (left) and the keypad/LCD board (right), connected by a 40-pin ribbon cable.

Чему меня научила Rev A

Rev A работала.

Мой изначальный код разрабатывался на ней, и он работал. Калькулятор запускался, отображал вывод, принимал нажатия на клавиши и правильно выполнял вычисления. Наличие физических клавиш существенно повлияло на процесс разработки: баги, невидимые в Qt-симуляторе, мгновенно проявлялись, когда в дело вступал человеческий палец (в основном это были пограничные случаи сканера клавиатуры). Изменились и ощущения от работы: это уже было не просто ПО, работающее в Qt-приложении, а реальное оборудование!

Однако Rev A обладала очевидными недостатками: две отдельные платы, соединённые кабелем, неудобно (и небезопасно) носить с собой на совещания и демонстрации. Кабель был ненадёжным, а само устройство хрупким. У него не было ни аккумулятора, ни кнопки включения питания, ни корпуса. Оно жило на столе и получало питание по USB-кабелю.

Оно подходило для разработки, но не для повседневного применения калькулятора.

Rev B: одна плата

В Rev B систему из двух плат заменили две специально разработанные платы. В одной был интегрирован голый FPGA-чип EP2C5T144C8 (в корпусе TQFP-144), дисплей, программные интерфейсы и схема питания. Вторая представляла собой плату клавиатуры. Я намеренно разделил конструкцию на основную плату и на клавиатуру: у меня был план поэкспериментировать с разными конфигурациями клавиатуры, используя при этом одну и ту же основную плату.

Схема питания
Схема питания
Схема основной платы
Схема основной платы
Схема FPGA
Схема FPGA
Схема конфигурирования
Схема конфигурирования
Основная плата в 3D
Основная плата в 3D

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

Rev B: everything on one board. The FPGA is the large TQFP in the center; the OLED sits at the top.

FPGA

Хоть я в этом и не мастер, с припаиванием корпуса TQFP-144 в домашних условиях я вполне справился: достаточно приличного паяльника, припоя, оплётки для удаления припоя и терпения. Расстояние между контактами равно 0,5 мм. Я использовал технику протяжки: щедро наносил флюс, вёл паяльник с припоем по контактам, а потом избавлялся от перемычек при помощи оплётки. Лупой с десятикратным увеличением я проверял наличие перемычек и непропаянных соединений. На один чип требовалось около получаса, и редко нужно было больше двух проходов. В результате у меня осталось несколько перемычек, но они соединяли неиспользуемые GPIO и могли вызвать ужас только у тех, кто хорошо паяет и может разглядеть мелкие детали.

FPGA — единственный по-настоящему сложный компонент платы. Всё остальное или устанавливается в отверстия, или представляет собой SMD бо́льших размеров.

Soldering FPGA main board under microscope
Altera Cyclone II
Altera Cyclone II

Два разъёма для программирования

Одно из принятых на этапе проектирования решений, которое многократно оправдало себя — это монтаж на плату двух разъёмов для программирования, каждый из которых соединён под отдельный режим прошивки.

Правый разъём соединён для режима JTAG. В нём подключение USB Blaster напрямую программирует внутреннюю SRAM FPGA: код сразу становится рабочим, но пропадает при отключении питания. Этот режим использовался при разработке, потому что он быстр (программирование занимает несколько секунд) и позволяет выполнять итерации без снижения ресурса флэш-памяти.

Стоит упомянуть, для чего изначально проектировался JTAG: Joint Test Action Group была сформирована в 1985 году для решения производственной проблемы: как тестировать соединения на уровне плат в корпусах с постоянно уменьшающимся шагом контактов, не используя при этом физические щупы. В 1990 году решение этой группы, реализованную в кремнии стандартизованную последовательную цепь опроса периферии, утвердили в качестве IEEE 1149.1. Использовать JTAG для программирования и отладки FPGA стали позже, но тот же четырёхконтактный доступ, позволяющий проверять контакты — это именно то, что нужно для программирования, поэтому такое перепрофилирование интерфейса было вполне логичным.

Левый разъём соединён для режима Active Serial (AS). Подключение к нему USB Blaster программирует внешний флэш-чип EPCS, на котором хранится конфигурация FPGA. При включении питания платы FPGA читает свой битовый поток с чипа EPCS и менее чем за секунду конфигурирует себя. Это режим «продакшена»: достаточно запрограммировать чип один раз, и калькулятор будет запускаться всегда.

Active Serial (left) for persistent flash programming

Для обоих разъёмов используется одинаковый стандартный 10-контактный держатель USB Blaster. Один клон USB Blaster (примерно $10 на eBay) работает с обоими режимами; достаточно лишь подключить его к нужному разъёму.

Корпус и колпачки клавиш

Корпус проектировался в Autodesk Fusion и печатался на Prusa MK4S филаментом PLA.

Calculator keyboard layout

Жёлтый SHIFT — отсылка к стандарту HP, имевшему интересное происхождение. У HP-35 1972 года вообще не было клавиши SHIFT: у неё была только клавиша ARC, переключавшая режим тригонометрических функций между обычными и обратными. Когда HP выпустила в 1973 году HP-45, она добавила жёлтую клавишу SHIFT, дающую каждой клавише вторую функцию; её рекламировали, как «почти удваивающую вычислительную мощь» калькулятора. Эта жёлтая клавиша использовалась во всех научных калькуляторах HP в течение следующих пяти десятков лет. HP никогда её не меняла: любой, кто пользовался хотя бы одним калькулятором HP, знает, что означает жёлтый цвет.

На что похоже программирование

После синтеза в Quartus программирование платы Rev B занимает примерно тридцать секунд:

  1. Подключаем кабель USB-C.

  2. Вставляем коннектор USB Blaster в левый разъём (AS).

  3. Открываем Programmer в Quartus, выбираем Active Serial mode, добавляем файл .pof.

  4. Нажимаем Start.

  5. Отключаем и включаем питание платы.

FPGA считывает битовый поток из EPCS, конфигурирует себя, инициализируется OLED, и калькулятор готов к работе. От пустого экрана до работающего научного калькулятора за несколько секунд.

Во время разработки этапы 2 и 3 меняются: используем правый разъём (JTAG), выбираем режим JTAG, добавляем файл .sof. Результат готов примерно за три секунды и не требует отключения питания, благодаря чем цикл «изменение-синтез-тестирование», оказывается вполне быстрым и приятным.

Что было перенесено из Rev A в Rev B

Можно было бы считать Rev A одноразовым прототипом, но это явно оказалось бы недооценкой её роли. Именно на Rev A писался и отлаживался сканер клавиатуры. Тайминги подавления дребезга, частота сканирования, значения подтягивающих резисторов, выбор конкретной модели тактильных переключателей, порядок инициализации OLED — всё это было реализовано на Rev A ещё до разработки специализированной платы.

Кроме того, Rev A стандартизировала назначение контактов. У FPGA есть 89 пользовательских контактов ввода-вывода, а сканер клавиатуры плюс интерфейс дисплея задействуют примерно 22 из них. Выбор связи контактов с сигналами и документирование этого в файле .qsf может оказаться очень дорогостоящим решением, если что-то понадобится поменять в процессе производства платы. Реализовав всё правильно в Rev A, я мог перенести все назначения контактов в RevB.

Что дальше

Физический калькулятор теперь работает, а его микрокод завершён. В версии 2025 года я решил проблему численной точности: переписал базовые арифметические алгоритмы на основании усовершенствованного прототипа на C++, улучшил обработку защитного разряда и повысил оптимизацию команд CPU, что позволило уменьшить размер кода, чтобы добавить ещё несколько функций. Это будет темой следующего поста.


Файлы проекта Quartus (в том числе и назначения контактов RevA и RevB в файле .qsf) находятся в папке quartus/. EP2C5 Mini Dev Board задокументирована на land-boards.com.

Комментарии (1)


  1. aabzel
    23.07.2026 07:14

    Зачем Вам именно FPGA для разработки калькулятора?
    Ведь в калькуляторах обычно не нужна высокая производительность.
    Почему бы не выбрать микроконтроллер?