Огород кончился, но еще не со всеми делами разобрался. Реалии этого года заставляют заниматься тем, чем раньше не озадачивался.
Вид для печати
Вряд ли работа может быть доведена до конца на энтузиазме? Каков необходимый объем финансовой поддержки или проблема заключается в том, что все должно свершаться именно нынешним способом без привлечения внимания?
А какие цели проекта?, преобразовать маски в транзисторную схему, где трансы расставлены руками в редакторе? Из первого сообщения данного топика так и не понял :O) Но всё равно ждём завершения проекта!
Цели такие:
1. Преобразование сехмы в транзисторную, где все собрано в понятные и подписанные блоки (нарисована вся, но подписаны и сформированы блоки еще не все).
2. Преобразование транзисторной схемы в логическую (частично тоже делается параллельно с пониманием работы отдельных блоков).
3. Точное понимание, как работает Z80 и бинго!
Будет web симуляция как 6502?
http://www.visual6502.org/JSSim/index.html
Такое уже есть...
1) тамже
2) и ещё у балтазара
ссылки уже постил гдето... щаз искать "лень"
пс: кажется 6502 (или другой проц ?) спаяли на транзисторах на 50*50см платы (примерно) с "лампочками"
@Titus, присоединяюсь к предыдущему оратору.
Я тут как раз погружаюсь во всякие ламповые и 1-битыне компы, было бы интересно заглянуть под капот к Z80.
@Titus, Есть ли какой прогресс в последнее время?
Вот вам реверс Sega Genesis и Z80 в ней.
https://github.com/nukeykt/Nuked-MD-...lob/main/z80.v
И тактово верный эмулятор
https://github.com/nukeykt/Nuked-MD-...lob/main/z80.v
Сей проект в принципе ( из тех исходников что выложено) не собирается.
FPGA точно собирается.
https://github.com/MiSTer-devel/Mega...n/rtl/nuked-md
а это совсем другой проект - и он возможно собирается (не смотрел)
z80.v сам по себе несколько хитёр - выглядит как "по транзисторная копия" - но насколь верно хз.
ОФФТОП: в первом не хватает файлов (в принципе) для целостности "именно этого проекта", а во втором оные файлы добавлены.
По Теме: в z80.v зачем-то присутствуют две тактовые CLK и MCLK. Их соотношение между собой мне неизвестно. Для этого надо копать либо первый проект, либо второй (заточен под альтеру, а у меня "нет" квартуса).
Всё это несколько ОФФТОП для ТС.
Фух!
Наконец-то перевел транзисторную схему Z80 NMOS в логическую, попутно причесывая и транзисторную.
Чем дальше понимаешь логику работы, тем лучше причесывается схема, группируется по функциональным блокам и т.д.
Логическая схема полу-причесана, поэтому это только первый этап.
Кстати, уже нашел всякие интересности. Например, странную избыточность в цепи выборки команд CB.
Наверняка, при анализе какие-нибудь тайны Z80 все-таки всплывут)
Для затравочки кусочек с ALU:
https://pic.maxiol.com/images2/17230...897247.alu.png
- - - Добавлено - - -
Из интересностей:
Всего в процессоре 14 16-битных регистров. 12 регистров (IX, IY, HL, DE, BC, HL', DE', BC', AF, AF', WZ) сидят на основной шине, а два регистра PC и IR расположены на отдельной шине, причем при необходимости между этими двумя шинами может выстраиваться мост, чтобы получался доступ к PC и IR с основной шины.
Впрочем, оно и понятно, т.к. PC и IR имеют свои блоки инкремента/декремента, сравнения и т.д., т.к. используются параллельно с основным вычислительным блоком.
- - - Добавлено - - -
И похоже, что всякие блок-схемы Z80, в фирменно документации и не только - не имеют никакого отношения к реальной структуре процессора. Может просто я не все их видел.
Titus, очень крутая работа!
Несколько интересных фактов о Z80 для затравочки:
- Внутренняя частота работы процессора фактически в два раза выше, чем частота тактирования CLK. Это связано с тем, что часть действий процессор выполняет во время положительного полутакта CLK, а часть во время отрицательного полутакта CLK.
- Многие блоки в процессоре конвейеризированы, из-за чего команды выполняются быстрее, чем без конвейера. Например, простейшая команда вида LD r1,r2 в реальности выполняется за 6 тактов, а с конвейером за 4 такта. А команды работы с АЛУ вида ALU A,r в реальности выполняются за 7 тактов, а с конвейером за 4 такта.
- Команды вида ALU A,r модифицируют регистр флагов F в 7-м такте своего выполнения. В этом же такте следующая команда должна считать регистр AF из регистрового файла для своей работы. Чтобы не было накладок, предусмотрен специальный режим, когда следующая команда не читает AF из регистрового файла, а читает его с шины HBUS/LBUS одновременно с записью предыдущей командой регистра F в регистровый файл.
- Абсолютно любая команда в начале своего выполнения читает в 3-м такте регистр AF из регистрового файла, не зависимо от того, понадобится этот регистр или нет.
- Дополнительный блок быстрого инкремента/декремента 16-битного числа, позволяет делать инкремент/декремент всего за один такт. Во время выполнения самой короткой однобайтовой команды (4 такта) этот блок используется два раза - первый раз для инкремента регистра PC, второй для инкремента регистра IR (младшие 7 бит). Следует заметить, что было бы совсем не сложно используя этот блок, добавить дополнительные команды адресации с автоинкрементом типа (HL)+. Но авторы почему-то этого не сделали.
- Тактовый генератор формирует до 6 T-циклов, и до 5 М-циклов, в зависимости от команды. Линия WAIT влияет только на задержку между циклами Т2 и T3. Все остальные циклы приостанавливаться не могут.
- M-циклы могут быть различной длины. Например, цикл M1 длится 4 такта для всех команд, кроме LD SP,HL, PUSH, IND/DEC dd, DJNZ, RET cc, LD I/R,A, LD A,I/R, OUTI/OUTD/OTIR/OTDR, INI/IND/INIR/INDR, RST, а так же в прерываниях IM1 и IM2.
- Процессор построен как конечный автомат без каких-либо микропрограмм. Если переложить на язык программирования, то упрощенно говоря весь процессор - это огромный список команд IF, с множеством условий каждая. Например, IF (TAKT=T1 && CYCLE=M2 && REQ_FLAGS=0) THEN DO SOMETHING.
- Процессор спроектирован достаточно оптимизировано. Говоря языком программирования, хорошо скомпилирован. Однако, в некоторых местах встречаются избыточные цепи, а в некоторых местах видно, как обьединялись несколько модулей, каждый из которых оптимизирован, но суммарная оптимизация после обьединения не производилась.
- И, конечно, внутренняя структура мало соответствуют тем блок-схемам, которые описывают Z80 в различных документациях.
Оказывается, регистр флагов имеет некий промежуточный динамический кэш, который требует регенерации.
И получается очень интересное дело.
Кэш необходим для того, чтобы команда, влияющая на часть флагов, могла часть флагов считать из кеша, а часть модифицировать.
Команды, вообще не меняющие флаги, в конце своего выполнения кэшируют регистр F целиком (кроме флагов 3 и 5).
Команды, меняющие флаги, в конце своего выполнения кэшируют только те флаги, которые поменяли.
Если же выполняется длительная цепочка команд, влияющих не на все флаги, то часть флагов, закешированная ранее не регенерируется. А динамический кеш - это фактически заряженный затвор полевого транзистора, и заряд со временем утекает.
Кто-то может сказать - почему же не предусмотрели ситуацию, когда часть флагов надо кешировать из F, а часть изменять? Это усложнило бы схему. И так, 50 лет процессору почти, а никто на эти подводные грабли еще не наступил.
Смоделируем следующую ситуацию:
1. Выполняем NOP. Текущие флаги закеширповались в динамическом кэше F.
2. Выполняем последовательно много раз команду, которая влияет не на все флаги. Например, SCF.
Во время выполнения команды SCF предполагается, что, например, флаг Z не изменился, поэтому кэшированное значение не обновляется. Однако, ячейка хранящая состояние флага S динамическая, поэтому ей все время нужна регенерация. И через некоторое время она потеряет свое значение.
Предлагаю реальщикам провести тест на процессоре NMOS архитектуры, примерно вот такой:
LD A,0 (или $FF)
OR A
NOP (загрузка кеша текущими значениями флагов)
SCF (на все 48Кб)
тут смотрим флаг S
Попробовать надо. Совершенно не могу предположить, какая емкость затворов в данном процессоре.
Если не получится изловить на 48кб, надо посмотреть, можно ли соорудить цикл, который не перекеширует флаги, и тогда в цикле уж точно выловится.
Похоже, реальщиков желающих пока не нашлось)
- - - Добавлено - - -
Хм... думаю, что цикл устроить не получится, т.к. любая команда перехода перекеширует флаги :(
Однако, время работы непрерывной последовательности можно увеличить, заменив SCF, например, на ADD HL,dd.
ну почему же.
есть тесты CCF\SCF, причем в зависимости от производителя\мануфактуры - аж три различных варианта поведения этих самых недокументированных флагов. Вернее есть и 4 вариант("синдром"), что-то похожее на утечку, но пока это малоповторимо и точно никто из причастных не может сказать, с чем связано 4-е поведение, говорят - невоспроизводимый глюк :) Тесты от Патрика же, с картинками...
https://github.com/raxoft/z80test/tree/master/img
это результаты, других вариантов по паттернам не бывает.
Но бывает, что картинка "дрожит", как буд-то флаги произвольно меняются, что в принципе не должно быть. Может это та самая утечка?))
https://github.com/raxoft/z80test/bl.../z80ccfscr.asm
как бы сам тест, десяток строк
А можно, пользуясь случаем, задать тебе пару уточняющих вопросов:
А тут можно подробнее? Если конвейер на уровне команд - то значит, пока одна команда выполняется, следующая одновременно с этим считывается из памяти и подготовляется к исполнению. Но если бы в Z80 был такой конвейер - то были бы либо дополнительные задержки, когда одна команда нуждается в результатах исполнения предыдущей, и тогда приходится "сбрасывать" конвейер; либо неожиданные логические эффекты от отсутствия сброса конвейера там, где он нужен. Всякие глюки при исполнении самомодифицирующегося кода и т.д. Но, посколько подобных эффектов на Z80 нет, его исполнение детерминировано - значит ли это, что конвейеры, которые там имеются - они не на уровне команд, а на уровне операций, составляющих команды?
Ну, например, для команды ALU A,r требуется 7 тактов работы соответствующих блоков; но за счет дублирования некоторых из них и конвейеризации удалось сократить время исполнения до 4 тактов? Я правильно понял? А какие блоки дублируются, если не секрет?
А что это за шины там такие HBUS, LBUS? Как происходит обмен данными по ним? Откуда именно берется информация для записи F в регистровый файл? Это выходы АЛУ или других блоков?
Ок, а куда она его считывает, где он хранится потом после считывания? На другом, временном, регистре?
Вообще печально, что такой хороший блок транжирится на никому не нужную "регенерацию". Там ведь и 16 бит не надо, 7 достаточно. И вообще, регистр R можно было реализовать на 7-разрядном двоичном счетчике. По затратам ресурсов вышло бы, скорее всего, не больше, чем сам регистр, в котором оно хранится, и схемы коммутации этого регистра на 16-разрядный реверсивный счетчик и обратно.
Строго говоря, наличие упоминаемых тобою ниже "динамических кэшей" и использование прочих аналоговых эффектов выводит процессор из категории конечных автоматов.
Как всегда, практические факторы. Спешка, начальство подгоняет. Отсутствие автоматизации проектирования. Страх, что все сломается, если переделывать слишком сильно.
Ну да, искусство документации: как сказать много, но при этом ничего не сказать! Должно быть, была специальная стратегия, как написать документацию, чтобы раскрыть минимум информации о фактической структуре процессора.
Нет, никакие блоки не дублируются) Откуда такая роскошь? )
Просто пока выбирается код следующей команды (это 2 такта), выполняется завершение предыдущей команды.
Таким образом, перекрытие может составлять до 2-х тактов. А учитывая то, что AF читается из регистрового файла независимо от того, какой код команды, а так же регистр AF от предыдущей команды может сохраняться в регистровом файле одновременно с чтением AF следующей командой, то перекрытие составляет до 3-х тактов.
Вообще, проще всего это изобразить на диаграммах, когда они будут.
- - - Добавлено - - -
Это одна из внутренних шин, коих дофига. Для понимания назначения шин нужно большое описание, схема и диаграммы работы.
HBUS/LBUS используются как получатели-приемники данных из регистрового файла. На LBUS формируется новый регистр флагов, перед записью его в F. На LBUS выдаются данные с шины DBUS (которая является шиной данных для обмена с внешними устройствами). На LBUS формируется дополнительное число для двоично-десятичной коррекции. HBUS используется в сдвигах. HBUS является приемником значения ALU, и т.д.
А еще есть шины 8-битные шины ALUA, ALUB, ALUBUS, ALUOUT, DBUS.
И 16-битные REGBIT, PCBIT.
- - - Добавлено - - -
AF считывается из регистрового файла на шины REGBIT, затем HBUS/LBUS, затем с старшая часть (регистр A) с HBUS на ALUBUS, затем на ALUA, затем на ARGA, затем в два захода на 4-х битное ALU - 4-битную шину OP_A, и т.д.
Это нет смысла описывать текстом, надо смотреть на схеме и графиках.
- - - Добавлено - - -
С этим абсолютно согласен. Тоже так подумал - зачем такие ценные ресурсы процессора тратить на схему регенерации.
- - - Добавлено - - -
Ну это я не совсем точно употребил. Тут скорее имеется в виду, что никаких микропрограмм нет, все работает тупо по условиям)
- - - Добавлено - - -
Вряд ли была цель скрыть структуру процессора. Скорее просто хотели более упрощенно описать, выкидывая то, что для конечного пользователя практически не имеет значения.
Спасибо за разъяснения, Titus! Проект начинает выглядеть очень интересно. Постоянно возникает зуд - на основе изученного, добавить собственные знания и опыт и запилить на той же технологии (NMOS сколько-то мкм) более хороший и эффективный Z80 :) Но это так, конечно, чисто полет мысли. Вряд ли сегодня это кому-нибудь так нужно, чтобы имели желание заплатить. Да и технологии производства Z80 - есть ли сегодня в России хотя бы такие?
А что, там читается именно AF, не просто F? А при записи - тоже? Там 16-битная шина считывания из регистрового файла? А по записи - тоже 16 бит?
А там возможно одновременное чтение и запись в регистровый файл? Или только по очереди, чтение либо запись?
А кто присвоил шинам эти названия, это ты сам в ходе анализа? Или есть где-то отсылка к "оригинальным" названиям?
Кстати, вот еще интересный вопрос. АЛУ 4-битное, значит, не может принять весь операнд за один заход. Где хранится та часть операнда, которая ждет обработки в следующем такте? Она держится на шине, которая все это время прокоммутирована к источнику информации (регистровому файлу и т.д.)? Или там есть промежуточные регистры хранения?
Аналогично по результатам АЛУ. Вот вычислились 4 бит от 8-битного результата. Где они хранятся во время того, как вычисляется второй полубайт? Временный регистр хранения есть?
Учитывая реалии бизнеса, могу предположить, что у Zilog был какой-то крупный клиент на эти процессоры, которому нужна была регенерация ОЗУ. И процессор разрабатывался изначально под этого клиента.
Спектрумы - это, конечно, хорошо, но разработка и производство такого процессора в те времена требовали очень немалых инвестиций, которые должны были окупаться более крупным заказчиком, чем кто-то из тогдашних производителей микро-компьютеров. Возможно, было что-то военное?
Скажи, а ты что, сам занимаешься анализом Z80? Это же какая охренительная должна быть квалификация! Ты что заканчивал? ;)
AF читается всегда целиком 16 бит. А записываться может по частям..
Там две 8-битных шины, каждая из которых может работать отдельно друг от друга. Кроме того, обе эти шины могут обьединяться (пробрасывается мост с HBUS на LBUS). Причем, практически все операции как раз и проходят в режиме обьедененных шин, т.к. работа идет с 8 битами.
- - - Добавлено - - -
Есть возможность одновременного чтения/записи в старшую/младшую часть регистров. Единственное ограничение, это должен быть один и тот же регистр. Допустим, A читаем, F пишем. Другой вопрос, используется ли это, я еще не проверял.
Что касается всего регистрового файла, то, как я уже писал выше, он состоит из двух матриц. В одной из них почти все регистры, в другой PC и IR. И между ними тоже может образовываться мост. Вот в эти две части регистрового файла можно писать и читать одновременно разные регистры. Например, PC читается, и в это же время какой-то другой регистр тоже читается или записывается.
- - - Добавлено - - -
Несколько названий сохранились от проекта Z80 Explorer, другие же я обозвал сам по их назначению. Впрочем, пришлось переименовать шины, названные в Z80 Explorer VBUS и UBUS в LBUS и HBUS, т.к. это лучше соответствовало их назначению.
- - - Добавлено - - -
Там много промежуточных защелок, в которых все это хранится. Как на входе АЛУ, так и на выходе.
Вот кусочки схемы:
Выход
https://pic.maxiol.com/images2/17243...897765.011.png
Вход
https://pic.maxiol.com/images2/17243...897765.023.png
- - - Добавлено - - -
Я занимаюсь для того, чтобы понять нюансы его работы) Без этого точный эмулятор не напишешь. А я же эмуляторщик)
Ничего не заканчивал связанного с электроникой. Я программист.
Но я уже столько отреверсил чипов (для УКНЦ), что для меня это уже не особо сложная задача, просто кропотливая. Что делать, если никто не сделал, а хочется)
Многие реверсят до транзисторного вида, иногда даже не причесывая, и либо засовывают в FPGA, либо симулируют, как в Z80 Explorer. Но это не дает информации о нюансах работы. Да и плавающие состояния тут можно упустить. Единственный вариант, на мой взгляд, познать всю суть работы процессора - это построение причесанной и понятой транзисторной схемы, а по ней логической.
- - - Добавлено - - -
Вот чего мне менее всего интересно, это сидеть перерисовывать слои с кристалла.
Идеально, если уже есть потранзисторная схема, пусть даже просто в виде списка транзисторов и соединений. С чего я и начал реверс Z80, собственно.
- - - Добавлено - - -
На счет этого теста.
Думаю, что причина в том же - обилие динамических защелок в блоке формирования флагов.
Впрочем, их много в принципе в этом микропроцессоре. Но большинство из них тактируются CLK, и на частоте работы процессора работают как статические. А вот в блоке формирования флагов много наворотов, в том числе и с динамическими защелками, тактируемыми как придется. Так что вполне возможно, что утечки можно добиться. Надо проанализировать их работу на досуге, просто пока до них не дошел, только до флага S, о котором рассказывал выше.
Замечу, никто еще не вызвался проверить мое предположение на NMOS реале.:v2_unsur:
- - - Добавлено - - -
Немного о блоке формирования флагов:
S - флаг знака самый простой, в него просто копируется 7-бит результата работы АЛУ.
Z - флаг нуля почти такой же простой, формируется, если результат работы АЛУ равен 0. Однако там есть дополнительная цепь установки, сброса, обратной связи. Зачем она нужна, еще не разбирался.
N - флаг сложения/вычитания. Именно по этому флагу АЛУ знает, что нужно делать, складывать или вычитать (то же сложение, но второй аргумент инвертируется). Крайне интересно, что команды относительного условного перехода (и не только), использующие АЛУ для получения эффективного адреса, кешируют во нутренний кеш этого флага предыдущее состояние флага S(!). С чего бы это? Еще не разбирался. Должно быть, чтобы понять, вычитать смещение или прибавлять, в зависимости от знака смещения.
C - флаг переноса. Работает в целом весьма документированно, за исключением того, что для команд AND, CCF, SCF в него копируется инвертированное значение флага H(!) (полупереноса). Видимо, таким образом команда CCF инвертирует флаг C, пропуская его через полуперенос.
H - флаг полупереноса один из самых навороченных. Единственное, что пока могу сказать, он всегда изменяется для всех команд, которые влиют хотя бы на какие-то флаги. Т.е. у него нет кеша предыдущего его значения.
PV - флаг четности/переполнения - пока не разбирался.
Да, в таком виде не воспроизвести. Но если перевести в логическую схему, и выявить именно проблемные места, то можно их в той или иной мере и на FPGA повторить. Счетчик ввести специальный о потери заряда, и т.д.)
Если процессор NMOS, то обязательно надо сделать тест. На других архитектурах не надо, т.к. от них нет реверса.
- - - Добавлено - - -
Доки врут)
Я смотрю на схему и она гласит об обратном) Сначала выставляется флаг, потом АЛУ смотрит на флаг и говорит - о, флаг вычитания стоит, значит инвертирую второй аргумент.