← Девятая частьВ предыдущих постах мы подробно разбирали каждый слой: CPU, арифметику, скриптовый интерпретатор, оборудование. Вот, что окончательный отчёт о синтезе Quartus сообщает обо всех них: в готовой архитектуре используется 1593 логические ячейки из доступных в EP2C5 4608 (35% чипа) с 594 выделенными логическими регистрами и 17 блоками памяти M4K. Сам модуль CPU занимает 1173 из этих логических ячеек и 400 регистров. Остальная логика отдана периферии: драйверу ЖК‑дисплея (154 логические ячейки), сканеру клавиатуры (97), интерфейсу термопринтера (64), таймеру CTC (49) и аппаратному PRNG (20). 12 блоков памяти M4K занимает ROM микрокода (49152 бит: это полная программа калькулятора), 2 блока — ROM скриптинга (8192 бита), 1 — ROM BCD‑констант, 1 — таблица поиска для BCD‑умножения внутри CPU и 1 блок — ОЗУ. Меня это очень радует: полнофункциональный научный калькулятор уместился в 35% небольшой дешёвой FPGA. Читать далее

В предыдущих постах мы подробно разбирали каждый слой: CPU, арифметику, скриптовый интерпретатор, оборудование. Вот, что окончательный отчёт о синтезе Quartus сообщает обо всех них: в готовой архитектуре используется 1593 логические ячейки из доступных в EP2C5 4608 (35% чипа) с 594 выделенными логическими регистрами и 17 блоками памяти M4K. Сам модуль CPU занимает 1173 из этих логических ячеек и 400 регистров. Остальная логика отдана периферии: драйверу ЖК‑дисплея (154 логические ячейки), сканеру клавиатуры (97), интерфейсу термопринтера (64), таймеру CTC (49) и аппаратному PRNG (20). 12 блоков памяти M4K занимает ROM микрокода (49152 бит: это полная программа калькулятора), 2 блока — ROM скриптинга (8192 бита), 1 — ROM BCD‑констант, 1 — таблица поиска для BCD‑умножения внутри CPU и 1 блок — ОЗУ. Меня это очень радует: полнофункциональный научный калькулятор уместился в 35% небольшой дешёвой FPGA.
Технологический стекВ проекте использовался непривычно широкий спектр технологий: SystemVerilog для CPU и периферии, ModelSim и Verilator для симуляции, Quartus для синтеза FPGA, Qt для десктопного симулятора и браузерного WebAssembly‑демо, Python для ассемблера и компилятора скриптинга, C++ для эталонной реализации Proto и Autodesk Fusion для проектирования корпуса. Каждый инструмент нашёл своё место. Удивило меня то, насколько естественно они сочетались: одни и те же исходники Verilog работали во всех окружениях, одни и те же тестовые векторы верифицировали и эталон на C++, и оборудование, одно и то же Qt‑приложение компилировалось для десктопа и браузера без внесения изменений.
Чему я научилсяПроектирование собственного CPU — на удивление легко решаемая задача. EP2C5 состоит из 4608 логических элементов. Модуль CPU использует 1173 из них. Поначалу кривая обучения довольно сложна (Verilog не прощает двусмысленности), но после настройки тестового стенда и запуска просмотрщика временных диаграмм отладка оборудования больше похожа на отладку ПО, чем можно было бы ожидать. Verilator был самым подходящим инструментом: быстрым, свободным и способным выполнять тот же RTL, который позже реализуется в FPGA.
BCD‑арифметика имеет больше тонкостей, чем двоичная. История с защитным разрядом и битом фиксации потребовала дважды переписать код прототипа. Во второй раз я переписывал его, потому что при тестировании микрокода я нашёл баги в предыдущей версии. Именно поэтому сначала нужно писать эталонную реализацию, а уже потом ассемблерный код. Наличие золотого эталона, генерирующего тестовые векторы — это не какое‑то дополнительное требование, если вам важен последний разряд.
Составление собственной архитектуры набора команд CPU — настоящее приключение. Ты понимаешь, чего не может выразить твой набор команд, в тот самый момент, когда начинаешь писать на нём реальный код. Команда CALLI возникла благодаря тому, что я изучал гистограмму частотности команд и понял, что 28% кода представляют собой двухкомандные преамбулы к вызовам функций. Архитектура, которую проектируешь теоретически, и архитектура, получающаяся после написания ПО, редко оказывается одинаковой. И это хорошо.
Слой скриптинга — самая изящная деталь архитектуры; с точки зрения проектирования, она доставляет настоящее удовольствие своей компактностью. То же самое реализовали в 1982 году в Sinclair ZX Spectrum. Принцип всегда одинаков: как только реализуешь правильную работу небольшого множества примитивов, большая доля оставшейся функциональности как будто пишет себя сама.
Физическая сборка сложна. Припаивание TQFP-144 с шагом ножек в 0,5 мм поначалу давит на нервы (возможно, приступая к этой задаче, я немного переоценил свои силы). Соединение двух плат гибким кабелем ненадёжно. Переход от состояния «работает на стенде» до состояния «работает в корпусе, который можно засунуть в рюкзак» дольше, чем можно было бы предполагать, и в основном проблемы механические, а не электрические.
Что можно было бы улучшитьМеньше всего в этом проекте мне нравится клавиатура. Все, кто пользовался старыми калькуляторами HP, знают, как ощущаются их клавиши: чёткий тактильный щелчок, никакой разболтанности, никогда не стираемые легенды, потому что они проделаны в пластике насквозь. Воссоздание всего этого в домашних условиях, даже с 3D‑принтером потребительского уровня и лазерным гравировщиком, оказалось по‑настоящему трудной задачей. Я пробовал тактильные и купольные переключатели, нажимные кнопки и различные виды печати на них, а также некоторые другие решения. Ни одно из них не удовлетворило меня полностью, поэтому я продолжаю экспериментировать.

Aluminum faceplate
Ограничением остаётся и точность CORDIC для больших значений радиан. tanRad(1000) даст нам пятнадцать корректных разрядов. Эту проблему решают алгоритмы Коди‑Уэйта и Пэйна‑Ханека, но за них приходится расплачиваться увеличением размера кода, на которое я решил не идти. Однако в большинстве практических применений вполне подходит калькулятор, обеспечивающий высокую точность для нескольких сотен радиан.
И меня всё ещё не устраивает полностью внешний вид калькулятора: он слишком большой и неуклюжий, а клавиши, как уже говорилось, далеки от идеала. Впрочем, для любительского проекта этого вполне достаточно.
Кроме того, он просто обязан быть программируемым. Для этого ему нужно хранилище с постоянной памятью. Надеюсь в будущем заказать у JLCPCB следующую версию платы.
В заключениеЯ начал с такого вопроса: как вообще работает научный калькулятор? Теперь я могу дать на него ответ, не абстрактно, а вполне в конкретном смысле. Этот проект показал, как работают BCD на уровне разрядов. Он показал, что CORDIC делает с углами, и в целом продемонстрировал, как создавать точные калькуляторы.
Микрокод HP-35 умещается в 768 10-битных слов. Вся архитектура моего калькулятора умещается в 4 тысячи 12-битных слов. По сравнению с HP-35, моя архитектура огромна! С другой стороны, флагманский калькулятор того времени HP-41CX занимал 24 тысячи слов, упорядоченные в страницы.
Весь исходный код выложен на GitHub. Ниже представлены разные ролики, записанные в процессе работы над проектом. Я планирую со временем выложить на YouTube качественное видео (с монтажом и закадровыми комментариями), но на это понадобится какое‑то время. Возможно, очень долгое.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | [Перевод] wake up: демо в 16 байтах | 0 | 10.72 | 12-08-2026 |
| 2 | Мой код терял бы 230 байт из 231. Чтобы это увидеть, пришлось патчить QEMU | -1 | 10.63 | 02-08-2026 |
| 3 | Проект eMMC-emu | 0 | 8.99 | 06-08-2026 |
| 4 | Из обучения школьников цифре на макетке нужно выкинуть все резисторы и вставить микросхемы с FIFO | 0 | 5 | 11-07-2026 |
| 5 | Пишем мобильную ОС на Rust. Часть 3. Путь от bare-metal эксперимента к capability-based микроядру | 0 | 11.73 | 06-07-2026 |
| 6 | История создания самодельной видеокарты на 8 192 ядра RISC-V из тысяч дешевых микроконтроллеров | 5 | 7 | 20-07-2026 |
| 7 | const fn в 2026: ваш компилятор втихаря исполняет Rust | 0 | 9.58 | 20-07-2026 |
| 8 | Как я запустил перцептрон на обычном непрограммируемом калькуляторе Casio | 2 | 7 | 03-07-2026 |
| 9 | [Перевод] Паттерны доступа к данным, которые выбесят ваш процессор | 0 | 7 | 03-07-2026 |
| 10 | [Перевод] Доверьтесь компилятору: C++23 против трюков из 90-х | 0 | 10.4 | 27-07-2026 |