Оптимизации АЛУ
Apr. 8th, 2019 12:37 pmПосле переписывания дорогих команд сборки, разборки и сдвига в многотактный вид и исправления нормализации вправо инвертированных мантисс (прибавлять младший бит инверсии можно по ходу нормализации, и в окончательном суммировании РМРу участвовать больше не нужно) всё стало гораздо компактнее:
Коммит будет сегодня вечером.
There are 31 levels of combinational cells
2-input LUTs: 309
3-input LUTs: 231
4-input LUTs: 228
5-input LUTs: 375
6-input LUTs: 726
Total LUT area: 1869
State : 204
(FF) : 204
CARRY4 : 132
DSP : 6
Коммит будет сегодня вечером.
no subject
Date: 2019-04-08 07:54 pm (UTC)Вот твои старые оценки для микро-БЭСМ, для сравнения:
с микрокодом в логике: 15771 LUT, 5166 FF;
с микрокодом в блочной памяти: 9904 LUT, 10 BRAM.
Но это всё вместе, не только АУ.
no subject
Date: 2019-04-08 08:27 pm (UTC)А если реализовать сложение, умножение и деление с помощью двухрядного кода (желательно, предварительно поняв, как именно работало деление без сравнения абсолютных значений мантисс),
то CARRY4 и DSP пропадут, и останутся считаные сотни LUTs.
no subject
Date: 2019-04-08 11:47 pm (UTC)Механизм прерываний может быть, например, такой: при возбуждении любого прерывания формируется слово: 15-1рр: М20, 30-16рр - адрес возврата, 47-42рр - режимы, 48р - признак правой команды, остальное - для маски прерываний. С этим словом выполняется как бы ЗП (М17).
ВЫПР, соответственно, будет работать как бы как МОД + РЖ + еще кое-что. Магазинность аналогична МОД.
no subject
Date: 2019-04-09 05:16 am (UTC)Но куча тестов сломалась:
И тест АУ не проходит.
no subject
Я когда увидел конструции в pack/unpack и умножение как $signed * $signed только и изумился: "А что так можно было?!! 😂 😂". Но для RTL модели ведь можно, верно?
А дальше уже когда к железу "как в БЭСМ6" ближе спускаться, можно и убрать.
Я потому скрипт для сложения и сделал, пытаясь разобраться с тем как это было в самой БЭСМ реализовано (хотя и не точно).
Но вот с умножением получился пока затык, читаю книги с теорией и практикой реализации 2's compl умножителей в железе, вижу что в БЭСМ6 алгоритм Бута, но он какой-то модифицированный. Сам алгоритм придумали в 1951 году, поэтому "наши" о нём 100% знали, но улучшили.
Вот нашел, что есть еще один интересный вариант реализации умножения когда пропускаются повторяющиеся биты в множителе.
Постараюсь сделать python скрипт.
no subject
Date: 2019-04-09 05:25 am (UTC)Времянка-то удлинилась.
Я сделаю.
no subject
Date: 2019-04-09 05:41 am (UTC)Не хотелось бы при прерывании трогать стек пользователя, и вообще ходить в память. Мы как-то уже обсуждали на Гитхабе: https://github.com/besm6/mesm6/issues/3#issuecomment-475087151
Есть идея ввести для режима прерываний/экстракодов отдельный набор регистров K[1]...K[15]. В режиме пользователя (после ВЫПР) возможны обращения только к M[1]...M[15]. При переключении в режим прерываний обращения идут к регистрам K[1]...K[15]. Из режима прерываний можно читать-писать регистры пользователя командами ITA/ATI, обращаясь к ним как к регистрам K[17]...K[31].
Преимущества:
Обработчики прерывания имеют отдельный стек, задаваемый регистром K[15].
Не надо упрятывать регистры в стеке. Ускоряется обработка прерываний. Достаточно упрятать сумматор и РМР.
Не нужны дополнительные регистры для сохранения информации о прерывании. Например, прерванный счётчик команд PC прячется в K[1], регистр режимов пользователя - в K[2], исполнительный адрес экстракода - в K[3].
no subject
Date: 2019-04-09 06:11 am (UTC)no subject
Date: 2019-04-09 06:16 am (UTC)Что делать с текущим К1 при вызове вложенного экстракода?
Можно сделать Экстракоды так чтобы они всегда выталкивали полный текущий PC_next по адресу [K15--], а команда ВЫПР возвращалась на [++K15]. При необходимости, программное выталкивание К2, К3 прописать в "соглашении о программных вызовах".
no subject
Date: 2019-04-09 06:23 am (UTC)В БЭСМ-6 хитрость: умножение на 2 разряда делается за полтакта благодаря тому, что есть защелки по обоим фронтам тактового сигнала, поэтому произведение двигается вправо на 4 разряда за такт (в формулах АУ это видно). Но нам спешить особо некуда, можно и по 2 разряда за такт.
Кстати, сейчас флаг sticky правильно отражает необходимость округления для сложения, и сравнение rmr с нулем в STATE_ROUND нужно только для умножения. Когда умножение будет делаться пошагово, можно будет устанавливать sticky по ходу дела.
В скрипте для сложения есть ошибка: округление нужно делать, если в процессе нормализации вправо РМР когда-либо был ненулевым, даже если в конце концов все единицы из него уехали.
no subject
Date: 2019-04-09 06:55 am (UTC)no subject
Date: 2019-04-09 07:05 am (UTC)Напомню, что стек в БЭСМ-6 растёт в сторону увеличения адресов, и 15-й регистр указывает на первую свободную ячейку стека. Поэтому push - это присваивание mem[M15++], а pop - это чтение из mem[--M15].
no subject
Date: 2019-04-09 06:54 pm (UTC)no subject
Date: 2019-04-09 07:08 pm (UTC)no subject
Date: 2019-04-09 07:28 pm (UTC)no subject
Date: 2019-04-09 07:50 pm (UTC)There are 10 levels of combinational cells
Total LUT area: 52
no subject
Date: 2019-04-09 07:59 pm (UTC)На маленькой платке 7680 лутов с флипфлопами. Вроде мы укладываемся.
no subject
Date: 2019-04-09 08:01 pm (UTC)no subject
Date: 2019-04-09 08:06 pm (UTC)no subject
Date: 2019-04-09 08:28 pm (UTC)Вот наличие и цена Max10 (25 штук) в корпусе QFT144 на mouser.com в зависимости от количества логических элементов:
10M08 - $13.97
10M16 - $27.29
10M25 - $31.61
10M40 - $43.39
10M50 - $48.46
no subject
Date: 2019-04-10 04:55 am (UTC)no subject
Date: 2019-04-10 04:57 am (UTC)no subject
Date: 2019-04-10 04:58 am (UTC)no subject
Date: 2019-04-10 06:33 am (UTC)Но это в режиме, когда оптимизируется площадь. При оптимизации по критическому пути, то выходит 24 уровня, как ни крути.
В делении 10 уровней для сумматора мантисс, да те же 10 уровней в компараторе абсолютных значений мантисс, и еще чуть-чуть в мультиплексорах набегает.
no subject
Date: 2019-04-10 07:01 am (UTC)Скажем, четыре разряда на такт.
no subject
Date: 2019-04-10 08:12 am (UTC)no subject
Date: 2019-04-10 01:45 pm (UTC)Есть мысль, чтобы процессор ходил в память через арбитр как в БЭСМ6, что позволит реализовать подсистемы блочного ввода/вывода с SD-карты, Ethernet (через шилд от ардуины), UART (протокол похожий на SLIP). Обращение к регистрам ввода/вывода сделать через команду УВВ (033), запрет/разрешение прерываний по маске через РЕГ 002.
no subject
Date: 2019-04-10 01:48 pm (UTC)no subject
Date: 2019-04-10 04:21 pm (UTC)no subject
Date: 2019-04-10 06:43 pm (UTC)Либо общая теория без привязки к FPGA или ASIC есть на примете.
no subject
Date: 2019-04-10 08:36 pm (UTC)Кстати, Altera не умеет синтезировать $countones().
no subject
Date: 2019-04-10 08:40 pm (UTC)Ещё вот это могу посоветовать, но она для более серьёзных случаев: https://www.amazon.com/Digital-Arithmetic-Kaufmann-Computer-Architecture/dp/1558607986/
no subject
Date: 2019-04-10 09:46 pm (UTC)wire [47:0] a_mux = (state == STATE_IDLE) ? a : acc;
Мой вариант - 2307 LUTs, 23 levels; твой - 2302 LUTs, 24 levels. Если твой вариант так исправить, становится 23 уровня, но 2319 LUTs. Разница - в нумерации состояний и их последовательности в операторе case; видимо, это артефакты синтеза для эмуляции, потому что он ради эквивалентности с софтверной симуляцией не переводит регистр состояния в 1-hot вид.
Synplicity для Spartan7 с максимумом оптимизации за разумное время (72 секунды) делает
Register bits not including I/Os: 312 of 14600 (2%)
Block Multipliers: 9 of 80 (11%)
Total LUTs: 2897 (19%)
И обещает частоту 121.6 MHz.
$countones в нашем случае пишется как
и с ней синтезируется в те же зайцы.
no subject
Date: 2019-04-10 10:25 pm (UTC)no subject
Date: 2019-04-10 11:41 pm (UTC)120 мегагерц это неплохо. Я надеялся получить в районе сотни.
Я поправлю a_mux как у тебя, и добавлю функцию countones().
no subject
Date: 2019-04-11 12:15 am (UTC)Не так глаз режет.
no subject
Date: 2019-04-11 01:47 am (UTC)Согласно Synplify, количество уровней CARRY4 практически не играет роли, потому что задержка по переносу чуть не на порядок меньше, чем задержка в лутах, особенно если они большие, и между лутами.
Текущий вариант (со ещё чуть-чуть оптимизированной арифметикой)
default (2781 LUTs):
SLOW_SHIFT (2310 LUTs):
Так что логика для 8 вариантов быстрого сдвига оказывается на критическом пути, который Synplify пытался раздербанить, потратил 470 лутов, но так успеха и не достиг.
no subject
Date: 2019-04-11 02:44 am (UTC)Мне кажется, ускорение сдвигов того стоит.
no subject
Date: 2019-04-11 04:25 am (UTC)Когда релизнем, вот будет детишкам развлечение анализировать производительность и оптимизировать! Можно даже какую-нибудь сумму денег в качестве призов не пожалеть за максимальную производительность на Whetstone, Dhrystone и пр. Жаль, что мы до 50-летия БЭСМ-6 это не придумали.
no subject
Date: 2019-04-11 05:52 pm (UTC)Теперь к 60-летию. :)
no subject
Date: 2019-04-11 06:50 pm (UTC)достигается при количестве тактов на (быстрые) сдвиги около 1%, что на невычислительной задаче вполне реально.
no subject
Date: 2019-04-11 06:56 pm (UTC)Глянем тест АУ, благо имеется файл трассировки. Всего выполнено 1178071 машинных команд, из них 78169 сдвигов. Это 6.6%, немало. Сдвиг вообще довольно популярная операция была, насколько мне подсказывает память и интуиция.
no subject
Date: 2019-04-11 07:00 pm (UTC)no subject
Date: 2019-04-11 07:49 pm (UTC)В каком-нибудь перемножении матриц на фортране сдвигов, считай, почти не было, но это не наш профиль. :)
С еще некоторыми оптимизациями в АУ, Synplify смог сделать, при запрошенных 140 МГц, 135.5 для быстрых сдвигов, и 139.8 для медленных.
no subject
Date: 2019-04-11 09:06 pm (UTC)https://www.intel.com/content/www/us/en/products/programmable/fpga/max-10.html
У Max10конфигурационная память прямо на основном кристалле, поэтому он несколько удобнее по жизни.
no subject
Date: 2019-04-12 01:42 am (UTC)no subject
Date: 2019-04-12 06:29 am (UTC)Размер логики:
Total combinational functions: 3290
Dedicated logic registers: 211
no subject
Date: 2019-04-12 08:19 am (UTC)