Просмотр полной версии : Реверс-инжиниринг Z80
Начало темы примерно здесь (https://zx-pk.ru/threads/725-spravochnik-po-z80.html?p=1146592&viewfull=1#post1146592).
Кратко, если я правильно понимаю суть источников:
Компания, занимающаяся реверсом 6502, в том числе засняла кристалл Z80, нарисовала слои, раставила транзисторы.
После чего список транзисторов попал в проект Z80 Explorer (https://baltazarstudios.com/z80explorer/), откуда я его благополучно вытащил вместе с названиями некоторых шин и линий.
После чего наш многоуважаемый Vslav сконвертировал список транзисторов в схему .sch для PCAD2006 (получилось около 6800 транзисторов, не считая верхних подтягивающих транзисторов, которых в списке вовсе не было за ненадобностью для тех, кто список делал). И из этой огромной матрицы транзисторов я начал прям очень неспешно собирать что-то осмысленное.
Пока что собираю то, что оносится к ALU. Наброски можно посмотреть в прилагаемом .pdf.
Для общего развития.
https://www.cl.cam.ac.uk/~sps32/Z80proj/Z80_traps.pdf
Я так понимаю, это про те самые "лишние" транзисторы. Команда 6502 нашла таких 4, разработчики упоминали про 6
Повторю
https://baltazarstudios.com/z80explorer/
здесь можно в "картинках" смотреть дорожки и где находится транзистор. там есть поиск - вроде работает.
пс:
1) "схема на транзисторах - это хорошо, а на логических элементах лучше". Если будет описание на verilog-е замечательно, но я "предпочитаю" systemverilog.
2) не обещаю (но по мере наличия времени)
- могу по тестить на плисах xilinx (artix-7 & zync) vivado.
- править исходники.
- преобразовать verilog в systemverilog.
- частично тесты писать (но в этом я "новичёк").
Для общего развития.
я так понимаю это Сергей Скоробогатов известный спектрумистам.
https://www.cl.cam.ac.uk/~sps32/
Я так понимаю, это про те самые "лишние" транзисторы. Команда 6502 нашла таких 4, разработчики упоминали про 6
Наверное, это для нас пока не актуально, т.к. они, как я понимаю, для защиты от 'тупого' копирования кристалла один в один.
- - - Добавлено - - -
1) "схема на транзисторах - это хорошо, а на логических элементах лучше".
Я сам сторонник логической схемы, но без транзисторной ее не сделаешь.
Я сам сторонник логической схемы, но без транзисторной ее не сделаешь.
Как успехи? Не исключаю, что с чем-то смогу помочь недели через 2 ;)
mastermind
21.03.2022, 01:18
Еще вот это есть: https://floooh.github.io/visualz80remix/
Не знаю про источники, возможно на основе тех же данных сделано.
Как успехи? Не исключаю, что с чем-то смогу помочь недели через 2
Рисую по мере свободного времени.
Регистровый файл уже нарисовал.
Частично АЛУ.
Кроме того, там интересный быстрый инкремент для PC.
- - - Добавлено - - -
Еще вот это есть: https://floooh.github.io/visualz80remix/
Не знаю про источники, возможно на основе тех же данных сделано.
Да, я думаю, это на основе того же.
Прогресс по теме такой.
Все ~7000 транзисторов собрал в блоки, частично причесал, надписал.
Теперь надо дальше причесывать, подписывать цепи, выяснять функциональность. Но так все в общем понятно, интересно.
Вот, например, как выглядит центральная часть 4-х битного АЛУ.
Вот такие интересные штуки встречаются (если не накосячил, перепроверю).
https://pic.maxiol.com/images2/1650368671.39616193.dontwork.png
В общем, перепроверил по оригинальному несортированному списку транзисторов, да есть ошибка.
Как видно из схемы, на стоке T5919 всегда будет 0, т.к. либо при CLK = 1, транзистор T5919 будет открыт, и на стоке будет 0. Либо при CLK = 0, будет отключена цепочка M1/T2/CLK, затвор T5957 окажется подтянут к плюсу (все затворы подтянуты к плюсу, т.к. подтягивающие транзисторы опущены за ненадобностью), и на стоке T5919 опять будет 0. А раз эта цепь не работает, то и триггер, который она тактирует, тоже не будет функционировать правильно.
Принимая во внимание, что у авторов модели все тесты проходили прекрасно, значит эта ошибка на оригинальном Z80, и на работоспособность она не влияет. Буду проверять дальше.
- - - Добавлено - - -
В общем, похоже, что-то я не так понимаю с этими CLK. Надо смотреть рисунок кристалла.
В общем, стал смотреть сам кристалл (благо, слои хорошо документированы в том же Z80 Explorer), и оказалось, что прав был уважаемый наш товарищ Vslav. А именно в том, что нельзя просто опускать в схеме подтягивающие транзисторы на плюс. Наглядным примером может служить этот фрагмент:
Слева схема составленная по списку транзисторов.
А справа реальная схема.
https://pic.maxiol.com/images2/1650486187.630248180.compare.png
Как видно из рисунков, если слева схема бессмыслена, то справа появляется смысл, если при CLK = 1, открытом T8887 заряд накапливается на затворе Т8886, а при CLK = 0 на стоке T8886 имеем нужное значение.
Отсюда два вопрос:
1. Получается, что Z80 не может работать в статике, т.к. заряд не будет храниться на затворе вечно при CLK = 0.
2. Где, блин, взять список подтягивающих транзисторов, и почему их нет в Z80 Explorer, базу транзисторов которого я брал для составления схемы? И как сам автор Z80 Explorer симулирует работу Z80 по этому списку, если там нет подтягивающих транзисторов?
Ну что же, раз ни у кого нет идей, то придется ползать по слоям кристалла, и собирать все подтягивающие транзисторы. Работа на 100500 лет вперед)
Работа на 100500 лет вперед
Не на-адо-о-о!
Наверняка есть какой-то выход.
Либо информация где нет подтяжек как-то спрятана.
Либо нет подтяжек на стоке, только если на затворе клок а на истоке не ноль. То есть какие-то правила которые казались "очевидными".
В конце концов, если ничего не помогает, а симуляция чисто случайно прошла все тесты, то надо снова идти по пути получения списка транзисторов и узлов от снимков. Автоматизировано, а не вручную.
Serg6845
22.04.2022, 13:46
1. Получается, что Z80 не может работать в статике, т.к. заряд не будет храниться на затворе вечно при CLK = 0.
известный факт, для NMOS версии. подтверждается данными из http://www.bitsavers.org/components/zilog/z80/Z80_Family_Product_Specifications_Handbook_Feb84.p df, стр.22, TwCl
Не на-адо-о-о!
Наверняка есть какой-то выход.
Либо информация где нет подтяжек как-то спрятана.
Либо нет подтяжек на стоке, только если на затворе клок а на истоке не ноль. То есть какие-то правила которые казались "очевидными".
В конце концов, если ничего не помогает, а симуляция чисто случайно прошла все тесты, то надо снова идти по пути получения списка транзисторов и узлов от снимков. Автоматизировано, а не вручную.
Я пересмотрел все файлы в Z80 Explorer, и не нашел ничего, что хотя бы отдаленно напоминало бы список подтягивающих транзисторов.
Возможно, где-то это хранится, но непонятно где.
Либо же, такие цепи используются только на линиях тактируемых CLK, и автор симулятора сделал коррекцию.
Возможно, полный список есть у товарищей с сайта 6502, откуда автор и взял список транзисторов. Но я на них выхода не имею.
В общем, стал потихоньку дорисовывать подтягивающие транзисторы сам, смотря на рисунок кристалла в Z80 Explorer. В принципе, все видно хорошо, только муторно все это рисовать)
попробую залезьть в Си-шник, но не скоро.
попробую залезьть в Си-шник, но не скоро.
Похоже, я быстрее сам нарисую)
Нарисовал уже подтягивающие транзисторы из обведенного фрагмента кристалла:
https://pic.maxiol.com/images2/1650659258.39616200.01.png
На самом деле, это не так сложно. Кроме того, если что-то пропущу, это сразу станет понятно после причесывания, ибо любой отсутствующий подтягивающий транзистор, который вызывает вопросы, тут же легко проверяется по кристаллу.
А ведь Z80 Explorer откуда-то все таки подкачивает PullUp'ы!
Это видно из лога загрузки:
2022-04-23 13:23:06 | I | Loading "Z80Explorer/resource/transdefs.js"
2022-04-23 13:23:06 | I | Loaded 6813 transistor definitions
2022-04-23 13:23:06 | I | Max net index 3592
2022-04-23 13:23:06 | I | Number of nets 3544
2022-04-23 13:23:06 | I | Number of transistors 6813
2022-04-23 13:23:06 | I | Loading "Z80Explorer/resource/segdefs.js"
2022-04-23 13:23:07 | I | Number of pullups 2059
2022-04-23 13:23:07 | I | Completed loading netlist resources
Похоже, они в segdefs.js. Буду разбираться.
- - - Добавлено - - -
В общем, все понятно.
Каждая цепь, которая помечена '-' - не имеет подтяжки. А которая помечена '+' - имеет.
Все просто)
- - - Добавлено - - -
Все, написал конвертер, и получил номера соединений, на которых висит подтяжка. Получилось ровно 2059. Значит все точно.
Теперь еще 10000 ведер воды (поставить на все 2059 линий подтяжки) и схема будет готова!
Плюс в том, что не надо по фотографии кристалла лазить.
Titus, У меня не хватает цензурных слов чтобы высказать восхищение проводимой работой.
:v2_dizzy_botan:
Titus, У меня не хватает цензурных слов чтобы высказать восхищение проводимой работой.
Ты дождись сперва, может я забью не доделав)
Прогресс: 30% из 2000 подтягивающих транзисторов.
Все, расставил все 2000 подтягивающих транзисторов.
Надо было сразу послушать уважаемого товарища Vslav'а и не забивать на подтяжки. Когда я переводил потранзисторный реверс ВМ2 (от того же Vslav'а) в логическую схему, там не было ни одной динамической защелки. И я решил, что и в Z80 ничего такого не будет. Но динамических защелок оказалось множество, и при таком раскладе без точного знания, где есть подтяжка, а где нет, понять функционал схемы невозможно.
Теперь предстоит заново причесывать схему, т.к. после расстановки подтяжек все красивое форматирование испортилось.
Разбираю логику потихоньку.
Встречаются интересные вещи.
Например, в одной из цепей сброса явная избыточность.
Фрагмент схемы:
https://pic.maxiol.com/images2/1652617769.39616254.1.png
Логический эквивалент:
https://pic.maxiol.com/images2/1652617839.39616254..png
Как видно из схемы, элементы U240 и U241 совершенно избыточны, если я правильно все понимаю)
1) Где сигнал РЕС на верхнем ?
2) и почему внизу у У239 тактовая инверсной подрисовано
3) У238 - это по сути защёлка наверно получается , или что ?
1) Где сигнал РЕС на верхнем ?
Приходит сверху на T7641.
2) и почему внизу у У239 тактовая инверсной подрисовано
Потому что этот триггер тактируется отрицательным уровнем сигнала CLK.
3) У238 - это по сути защёлка наверно получается , или что ?
Да.
Оффтоп малость. у процессора существует два вида внутреннего сброса (при одном внешнем сбросе), зависит оное от того когда снимается "сброс" со входа. Поэтому есть патент.
смотреть на
https://baltazarstudios.com/z80-gratitude/
Special reset
https://baltazarstudios.com/webshare/A-Z80/US4486827.pdf
instruction overlap; switches on the internal data bus
https://baltazarstudios.com/webshare/A-Z80/US4332008.pdf
нечто про входные пины.
https://baltazarstudios.com/webshare/A-Z80/US4605980.pdf
- - - Добавлено - - -
Потому что этот триггер тактируется отрицательным уровнем сигнала CLK.
Я малость слеповат. Схему внимательно не анализировал, однако на верхнем все тактовые в одной полярности. Может инверсия "гдетовнутриобразуется" ?
пс: Я только что домой дополз...
- - - Добавлено - - -
T7641 Открыт когда тактовая 1 или 0 ?
T7641 Открыт когда тактовая 1 или 0 ?
Транзисторы открыты, когда на затворе 1)
- - - Добавлено - - -
Оффтоп малость. у процессора существует два вида внутреннего сброса (при одном внешнем сбросе), зависит оное от того когда снимается "сброс" со входа. Поэтому есть патент.
Спасибо, полезная информация, не знал)
А то я думаю, зачем такой ресет) А он вот зачем)
Как раз схема из патента примерно в реале такая и есть.
Набросал логическую схему триггеров прерываний.
Как видно из схемы, команды RETI и RETN абсолютно идентичны. Хотя в документации указано, что только RETN приводит к копированию IFF2 в IFF1.
И еще замечание. В описании сказано, что при выполнении команды EI поступивший в это время запрос на прерывание будет блокирован, пока не выполнится следующая за EI команда.
Но судя по схеме, EI (равно как и DI) просто блокирует разрешение записанное в IFF1. А следовательно, если будет выполнятся цепочка из команд EI, то прерывание не сработает, пока все EI не выполнятся.
И еще, IFF2 нигде не используется, кроме как для команды LD A,I/R, либо же для копирования в IFF1 по команде RETN/RETI. Что, впрочем, совпадает с описанием.
Добавка:
NET00188 - это INT_ACK (подтверждение INT)
NET00135 - это NMI_ACK (подтверждение NMI)
NET00114 - это INT_REQ (запрос INT)
https://pic.maxiol.com/images2/1652655004.763926842.iii.png
Lethargeek
18.05.2022, 06:39
И еще замечание. В описании сказано, что при выполнении команды EI поступивший в это время запрос на прерывание будет блокирован, пока не выполнится следующая за EI команда.
Но судя по схеме, EI (равно как и DI) просто блокирует разрешение записанное в IFF1. А следовательно, если будет выполнятся цепочка из команд EI, то прерывание не сработает, пока все EI не выполнятся.
а retn/reti как блокируют только после первой в цепочке?
https://spectrumcomputing.co.uk/forums/viewtopic.php?t=7086
В описании сказано, что при выполнении команды EI поступивший в это время запрос на прерывание будет блокирован, пока не выполнится следующая за EI команда.
Но судя по схеме, EI (равно как и DI) просто блокирует разрешение записанное в IFF1. А следовательно, если будет выполнятся цепочка из команд EI, то прерывание не сработает, пока все EI не выполнятся.
Не вижу противоречия, просто каждый следующий EI в свою очередь откладывает реакцию на прерывание, 8080 работает аналогично.
а retn/reti как блокируют только после первой в цепочке?
https://spectrumcomputing.co.uk/foru...pic.php?t=7086
Не совсем понял вопрос.
Если отвечать на вопрос по твоей ссылке, то я не увидел на схеме ничего особенного. По команде RETN IFF2 копируется в IFF1. Просто реакция на это новое значение IFF1 скорее всего задерживается на одну команду, т.к. есть конвейер. Но я до него еще не дошел.
Lethargeek
18.05.2022, 16:03
Не совсем понял вопрос.
Если отвечать на вопрос по твоей ссылке,
там вопроса нету, там утверждение, что первая retn/reti в цепочке ведёт себя как ei...
"as in EI, all forms of the RETI and RETN instructions defer the acceptance of the maskable interrupt for one instruction,"
...а вторая и последующие почему-то нет
"unlike EI, a sequence of RETI/RETN instructions will not prevent an INT request from being accepted"
или это из-за префикса происходит? :v2_confu: интересно, как тогда сработает цепочка ei-reti-ei-reti- :v2_wacko:
как тогда сработает цепочка ei-reti-ei-reti-
Там есть ответ на этот вопрос. После ei-reti/retn прерывание будет принято. Чтобы оно не было принято после reti/retn, надо ei-...-nmi-...-reti/retn
Lethargeek
18.05.2022, 16:49
Там есть ответ на этот вопрос. После ei-reti/retn прерывание будет принято. Чтобы оно не было принято после reti/retn, надо ei-...-nmi-...-reti/retn
а кто сказал, что NMI не может долбить морзянкой? :D
а кто сказал, что NMI не может долбить морзянкой?
на поведение
ei-reti-ei-reti-
это не повлияет
Не смотря на огород и всякие другие дела, периодически причесываю реверс Z80 и перевожу попутно в логическую схему.
Для затравочки - логическая схема быстрого инкрементора/декрементора, который используется не только для инкремента PC, но и для инкремента регистра R, а также для декремента счетчика в групповых командах (еще не разбирался с этим, но явно просматривается). Тут же есть схема быстрой проверки на 0x0001 и всякое такое прочее.
Замечу, что PCR - это условное название теневого регистра над которым производится инкремент/декремент, доставшееся в наследство от автора Z80Explorer.
О некоторых сигналах:
INC_PCR - если 1, то инкрементировать PCR
HIGH_INC_PCR - если 0, то инкрементируются только младшие 7 бит PCR (очевидно, это используется для инкремента регистра R).
INV_PCR - если 1, то декремент вместо инкремента.
Alex Rider
06.09.2022, 22:10
Titus, есть прогресс?
Titus, есть прогресс?
Как огородик кончится, можно будет продолжить)
Alex Rider
12.09.2022, 13:21
Славно! Спасибо! Жду интересных решений инженеров Zilog )
Привет, ну как там огород? :)
Привет, ну как там огород? :)
Огород кончился, но еще не со всеми делами разобрался. Реалии этого года заставляют заниматься тем, чем раньше не озадачивался.
CodeMaster
01.11.2022, 08:57
Реалии этого года заставляют заниматься тем, чем раньше не озадачивался.
Неужели решил бункер выкопать?
Неужели решил бункер выкопать?
Метафизически это можно назвать у так)
Вряд ли работа может быть доведена до конца на энтузиазме? Каков необходимый объем финансовой поддержки или проблема заключается в том, что все должно свершаться именно нынешним способом без привлечения внимания?
Вряд ли работа может быть доведена до конца на энтузиазме? Каков необходимый объем финансовой поддержки или проблема заключается в том, что все должно свершаться именно нынешним способом без привлечения внимания?
Это не связано с финансами. Это связано со временем.
А какие цели проекта?, преобразовать маски в транзисторную схему, где трансы расставлены руками в редакторе? Из первого сообщения данного топика так и не понял :O) Но всё равно ждём завершения проекта!
А какие цели проекта?, преобразовать маски в транзисторную схему, где трансы расставлены руками в редакторе? Из первого сообщения данного топика так и не понял :O) Но всё равно ждём завершения проекта!
Цели такие:
1. Преобразование сехмы в транзисторную, где все собрано в понятные и подписанные блоки (нарисована вся, но подписаны и сформированы блоки еще не все).
2. Преобразование транзисторной схемы в логическую (частично тоже делается параллельно с пониманием работы отдельных блоков).
3. Точное понимание, как работает Z80 и бинго!
3. Точное понимание, как работает Z80 и бинго!
Будет web симуляция как 6502?
http://www.visual6502.org/JSSim/index.html
Такое уже есть...
1) тамже
2) и ещё у балтазара
ссылки уже постил гдето... щаз искать "лень"
пс: кажется 6502 (или другой проц ?) спаяли на транзисторах на 50*50см платы (примерно) с "лампочками"
Будет web симуляция как 6502?
Симуляция уже есть.
Мне интересно понять принцип работы.
Тогда и эмулятор можно потактово правильный написать.
Alex Rider
26.08.2023, 01:41
Titus, присоединяюсь к предыдущему оратору.
Я тут как раз погружаюсь во всякие ламповые и 1-битыне компы, было бы интересно заглянуть под капот к Z80.
присоединяюсь к предыдущему оратору.
А чего хочет предыдущий? )
У меня обычно летний сезон без проектов, т.к. дача) Поэтому и с Диззи перерыв и тем более со всем остальным.
Получается, что Z80 не может работать в статике, т.к. заряд не будет храниться на затворе вечно при CLK = 0.
Кстати, вспомнилось, что в документации на Atmel AT89Cx специально оговорено,
что MCU может работать на сколь угодно низкой тактовой частоте. А вот оригинальный
8051 не может - я на этом как-то обломался. Минимально где-то около 100KHz.
PS. За работу - большой респект!!
PS. За работу - большой респект!!
Работа не закончена, лишь приостановлена ввиду появления более интересных проектов)
Alex Rider
14.01.2024, 21:01
Titus, Есть ли какой прогресс в последнее время?
Titus, Есть ли какой прогресс в последнее время?
Пока что еще не брался, много других задач)
Вот вам реверс Sega Genesis и Z80 в ней.
https://github.com/nukeykt/Nuked-MD-FPGA/blob/main/z80.v
И тактово верный эмулятор
https://github.com/nukeykt/Nuked-MD-FPGA/blob/main/z80.v
Сей проект в принципе ( из тех исходников что выложено) не собирается.
FPGA точно собирается.
https://github.com/MiSTer-devel/MegaDrive_MiSTer/tree/main/rtl/nuked-md
а это совсем другой проект - и он возможно собирается (не смотрел)
z80.v сам по себе несколько хитёр - выглядит как "по транзисторная копия" - но насколь верно хз.
а это совсем другой проект - и он возможно собирается (не смотрел)
z80.v сам по себе несколько хитёр - выглядит как "по транзисторная копия" - но насколь верно хз.
Это просто порт этого проекта на MiSTer
ОФФТОП: в первом не хватает файлов (в принципе) для целостности "именно этого проекта", а во втором оные файлы добавлены.
По Теме: в z80.v зачем-то присутствуют две тактовые CLK и MCLK. Их соотношение между собой мне неизвестно. Для этого надо копать либо первый проект, либо второй (заточен под альтеру, а у меня "нет" квартуса).
Всё это несколько ОФФТОП для ТС.
Фух!
Наконец-то перевел транзисторную схему Z80 NMOS в логическую, попутно причесывая и транзисторную.
Чем дальше понимаешь логику работы, тем лучше причесывается схема, группируется по функциональным блокам и т.д.
Логическая схема полу-причесана, поэтому это только первый этап.
Кстати, уже нашел всякие интересности. Например, странную избыточность в цепи выборки команд CB.
Наверняка, при анализе какие-нибудь тайны Z80 все-таки всплывут)
Для затравочки кусочек с ALU:
https://pic.maxiol.com/images2/1723023933.2997897247.alu.png
- - - Добавлено - - -
Из интересностей:
Всего в процессоре 14 16-битных регистров. 12 регистров (IX, IY, HL, DE, BC, HL', DE', BC', AF, AF', WZ) сидят на основной шине, а два регистра PC и IR расположены на отдельной шине, причем при необходимости между этими двумя шинами может выстраиваться мост, чтобы получался доступ к PC и IR с основной шины.
Впрочем, оно и понятно, т.к. PC и IR имеют свои блоки инкремента/декремента, сравнения и т.д., т.к. используются параллельно с основным вычислительным блоком.
- - - Добавлено - - -
И похоже, что всякие блок-схемы Z80, в фирменно документации и не только - не имеют никакого отношения к реальной структуре процессора. Может просто я не все их видел.
parallelno
08.08.2024, 01:36
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
Lethargeek
21.08.2024, 19:46
SCF (на все 48Кб)
~56 миллисекунд - сильно сомневаюсь, что утечёт
помнится, раздельную память на фирме тестировали, ждали долго
~56 миллисекунд - сильно сомневаюсь, что утечёт
помнится, раздельную память на фирме тестировали, ждали долго
Попробовать надо. Совершенно не могу предположить, какая емкость затворов в данном процессоре.
Если не получится изловить на 48кб, надо посмотреть, можно ли соорудить цикл, который не перекеширует флаги, и тогда в цикле уж точно выловится.
Похоже, реальщиков желающих пока не нашлось)
- - - Добавлено - - -
Хм... думаю, что цикл устроить не получится, т.к. любая команда перехода перекеширует флаги :(
Однако, время работы непрерывной последовательности можно увеличить, заменив SCF, например, на ADD HL,dd.
Похоже, реальщиков желающих пока не нашлось)
ну почему же.
есть тесты CCF\SCF, причем в зависимости от производителя\мануфактуры - аж три различных варианта поведения этих самых недокументированных флагов. Вернее есть и 4 вариант("синдром"), что-то похожее на утечку, но пока это малоповторимо и точно никто из причастных не может сказать, с чем связано 4-е поведение, говорят - невоспроизводимый глюк :) Тесты от Патрика же, с картинками...
https://github.com/raxoft/z80test/tree/master/img
это результаты, других вариантов по паттернам не бывает.
Но бывает, что картинка "дрожит", как буд-то флаги произвольно меняются, что в принципе не должно быть. Может это та самая утечка?))
https://github.com/raxoft/z80test/blob/master/src/z80ccfscr.asm
как бы сам тест, десяток строк
ну почему же.
есть тесты CCF\SCF
Не видел такого теста. Впрочем, он о другом, позже его рассмотрю.
Меня интересует поведение именно документированных флагов.
Боюсь, реальщика долго придется искать) Все ленятся)
Barmaley_m
21.08.2024, 22:16
А можно, пользуясь случаем, задать тебе пару уточняющих вопросов:
Многие блоки в процессоре конвейеризированы, из-за чего команды выполняются быстрее, чем без конвейера. Например, простейшая команда вида LD r1,r2 в реальности выполняется за 6 тактов, а с конвейером за 4 такта. А команды работы с АЛУ вида ALU A,r в реальности выполняются за 7 тактов, а с конвейером за 4 такта.
А тут можно подробнее? Если конвейер на уровне команд - то значит, пока одна команда выполняется, следующая одновременно с этим считывается из памяти и подготовляется к исполнению. Но если бы в Z80 был такой конвейер - то были бы либо дополнительные задержки, когда одна команда нуждается в результатах исполнения предыдущей, и тогда приходится "сбрасывать" конвейер; либо неожиданные логические эффекты от отсутствия сброса конвейера там, где он нужен. Всякие глюки при исполнении самомодифицирующегося кода и т.д. Но, посколько подобных эффектов на Z80 нет, его исполнение детерминировано - значит ли это, что конвейеры, которые там имеются - они не на уровне команд, а на уровне операций, составляющих команды?
Ну, например, для команды ALU A,r требуется 7 тактов работы соответствующих блоков; но за счет дублирования некоторых из них и конвейеризации удалось сократить время исполнения до 4 тактов? Я правильно понял? А какие блоки дублируются, если не секрет?
читает его с шины HBUS/LBUS одновременно с записью предыдущей командой регистра F в регистровый файл.
А что это за шины там такие HBUS, LBUS? Как происходит обмен данными по ним? Откуда именно берется информация для записи F в регистровый файл? Это выходы АЛУ или других блоков?
Абсолютно любая команда в начале своего выполнения читает в 3-м такте регистр AF из регистрового файла, не зависимо от того, понадобится этот регистр или нет.
Ок, а куда она его считывает, где он хранится потом после считывания? На другом, временном, регистре?
Дополнительный блок быстрого инкремента/декремента 16-битного числа, позволяет делать инкремент/декремент всего за один такт. Во время выполнения самой короткой однобайтовой команды (4 такта) этот блок используется два раза - первый раз для инкремента регистра PC, второй для инкремента регистра IR (младшие 7 бит). Следует заметить, что было бы совсем не сложно используя этот блок, добавить дополнительные команды адресации с автоинкрементом типа (HL)+. Но авторы почему-то этого не сделали.
Вообще печально, что такой хороший блок транжирится на никому не нужную "регенерацию". Там ведь и 16 бит не надо, 7 достаточно. И вообще, регистр R можно было реализовать на 7-разрядном двоичном счетчике. По затратам ресурсов вышло бы, скорее всего, не больше, чем сам регистр, в котором оно хранится, и схемы коммутации этого регистра на 16-разрядный реверсивный счетчик и обратно.
Процессор построен как конечный автомат без каких-либо микропрограмм.
Строго говоря, наличие упоминаемых тобою ниже "динамических кэшей" и использование прочих аналоговых эффектов выводит процессор из категории конечных автоматов.
Процессор спроектирован достаточно оптимизировано. Говоря языком программирования, хорошо скомпилирован. Однако, в некоторых местах встречаются избыточные цепи, а в некоторых местах видно, как обьединялись несколько модулей, каждый из которых оптимизирован, но суммарная оптимизация после обьединения не производилась.
Как всегда, практические факторы. Спешка, начальство подгоняет. Отсутствие автоматизации проектирования. Страх, что все сломается, если переделывать слишком сильно.
И, конечно, внутренняя структура мало соответствуют тем блок-схемам, которые описывают Z80 в различных документациях.
[/LIST]
Ну да, искусство документации: как сказать много, но при этом ничего не сказать! Должно быть, была специальная стратегия, как написать документацию, чтобы раскрыть минимум информации о фактической структуре процессора.
Ну, например, для команды ALU A,r требуется 7 тактов работы соответствующих блоков; но за счет дублирования некоторых из них и конвейеризации удалось сократить время исполнения до 4 тактов? Я правильно понял? А какие блоки дублируются, если не секрет?
Нет, никакие блоки не дублируются) Откуда такая роскошь? )
Просто пока выбирается код следующей команды (это 2 такта), выполняется завершение предыдущей команды.
Таким образом, перекрытие может составлять до 2-х тактов. А учитывая то, что AF читается из регистрового файла независимо от того, какой код команды, а так же регистр AF от предыдущей команды может сохраняться в регистровом файле одновременно с чтением AF следующей командой, то перекрытие составляет до 3-х тактов.
Вообще, проще всего это изобразить на диаграммах, когда они будут.
- - - Добавлено - - -
А что это за шины там такие HBUS, LBUS? Как происходит обмен данными по ним? Откуда именно берется информация для записи F в регистровый файл? Это выходы АЛУ или других блоков?
Это одна из внутренних шин, коих дофига. Для понимания назначения шин нужно большое описание, схема и диаграммы работы.
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, и т.д.
Это нет смысла описывать текстом, надо смотреть на схеме и графиках.
- - - Добавлено - - -
Вообще печально, что такой хороший блок транжирится на никому не нужную "регенерацию". Там ведь и 16 бит не надо, 7 достаточно. И вообще, регистр R можно было реализовать на 7-разрядном двоичном счетчике. По затратам ресурсов вышло бы, скорее всего, не больше, чем сам регистр, в котором оно хранится, и схемы коммутации этого регистра на 16-разрядный реверсивный счетчик и обратно.
С этим абсолютно согласен. Тоже так подумал - зачем такие ценные ресурсы процессора тратить на схему регенерации.
- - - Добавлено - - -
Строго говоря, наличие упоминаемых тобою ниже "динамических кэшей" и использование прочих аналоговых эффектов выводит процессор из категории конечных автоматов.
Ну это я не совсем точно употребил. Тут скорее имеется в виду, что никаких микропрограмм нет, все работает тупо по условиям)
- - - Добавлено - - -
Ну да, искусство документации: как сказать много, но при этом ничего не сказать! Должно быть, была специальная стратегия, как написать документацию, чтобы раскрыть минимум информации о фактической структуре процессора.
Вряд ли была цель скрыть структуру процессора. Скорее просто хотели более упрощенно описать, выкидывая то, что для конечного пользователя практически не имеет значения.
Barmaley_m
22.08.2024, 11:56
Спасибо за разъяснения, Titus! Проект начинает выглядеть очень интересно. Постоянно возникает зуд - на основе изученного, добавить собственные знания и опыт и запилить на той же технологии (NMOS сколько-то мкм) более хороший и эффективный Z80 :) Но это так, конечно, чисто полет мысли. Вряд ли сегодня это кому-нибудь так нужно, чтобы имели желание заплатить. Да и технологии производства Z80 - есть ли сегодня в России хотя бы такие?
А учитывая то, что AF читается из регистрового файла...
А что, там читается именно AF, не просто F? А при записи - тоже? Там 16-битная шина считывания из регистрового файла? А по записи - тоже 16 бит?
регистр AF от предыдущей команды может сохраняться в регистровом файле одновременно с чтением AF следующей командой
А там возможно одновременное чтение и запись в регистровый файл? Или только по очереди, чтение либо запись?
А еще есть шины 8-битные шины ALUA, ALUB, ALUBUS, ALUOUT, DBUS.
И 16-битные REGBIT, PCBIT.
А кто присвоил шинам эти названия, это ты сам в ходе анализа? Или есть где-то отсылка к "оригинальным" названиям?
затем на ARGA, затем в два захода на 4-х битное ALU - 4-битную шину OP_A, и т.д.
Кстати, вот еще интересный вопрос. АЛУ 4-битное, значит, не может принять весь операнд за один заход. Где хранится та часть операнда, которая ждет обработки в следующем такте? Она держится на шине, которая все это время прокоммутирована к источнику информации (регистровому файлу и т.д.)? Или там есть промежуточные регистры хранения?
Аналогично по результатам АЛУ. Вот вычислились 4 бит от 8-битного результата. Где они хранятся во время того, как вычисляется второй полубайт? Временный регистр хранения есть?
С этим абсолютно согласен. Тоже так подумал - зачем такие ценные ресурсы процессора тратить на схему регенерации.
Учитывая реалии бизнеса, могу предположить, что у Zilog был какой-то крупный клиент на эти процессоры, которому нужна была регенерация ОЗУ. И процессор разрабатывался изначально под этого клиента.
Спектрумы - это, конечно, хорошо, но разработка и производство такого процессора в те времена требовали очень немалых инвестиций, которые должны были окупаться более крупным заказчиком, чем кто-то из тогдашних производителей микро-компьютеров. Возможно, было что-то военное?
Скажи, а ты что, сам занимаешься анализом Z80? Это же какая охренительная должна быть квалификация! Ты что заканчивал? ;)
А что, там читается именно AF, не просто F? А при записи - тоже? Там 16-битная шина считывания из регистрового файла? А по записи - тоже 16 бит?
AF читается всегда целиком 16 бит. А записываться может по частям..
Там две 8-битных шины, каждая из которых может работать отдельно друг от друга. Кроме того, обе эти шины могут обьединяться (пробрасывается мост с HBUS на LBUS). Причем, практически все операции как раз и проходят в режиме обьедененных шин, т.к. работа идет с 8 битами.
- - - Добавлено - - -
А там возможно одновременное чтение и запись в регистровый файл? Или только по очереди, чтение либо запись?
Есть возможность одновременного чтения/записи в старшую/младшую часть регистров. Единственное ограничение, это должен быть один и тот же регистр. Допустим, A читаем, F пишем. Другой вопрос, используется ли это, я еще не проверял.
Что касается всего регистрового файла, то, как я уже писал выше, он состоит из двух матриц. В одной из них почти все регистры, в другой PC и IR. И между ними тоже может образовываться мост. Вот в эти две части регистрового файла можно писать и читать одновременно разные регистры. Например, PC читается, и в это же время какой-то другой регистр тоже читается или записывается.
- - - Добавлено - - -
А кто присвоил шинам эти названия, это ты сам в ходе анализа? Или есть где-то отсылка к "оригинальным" названиям?
Несколько названий сохранились от проекта Z80 Explorer, другие же я обозвал сам по их назначению. Впрочем, пришлось переименовать шины, названные в Z80 Explorer VBUS и UBUS в LBUS и HBUS, т.к. это лучше соответствовало их назначению.
- - - Добавлено - - -
Кстати, вот еще интересный вопрос. АЛУ 4-битное, значит, не может принять весь операнд за один заход. Где хранится та часть операнда, которая ждет обработки в следующем такте? Она держится на шине, которая все это время прокоммутирована к источнику информации (регистровому файлу и т.д.)? Или там есть промежуточные регистры хранения?
Там много промежуточных защелок, в которых все это хранится. Как на входе АЛУ, так и на выходе.
Вот кусочки схемы:
Выход
https://pic.maxiol.com/images2/1724319505.2997897765.011.png
Вход
https://pic.maxiol.com/images2/1724319523.2997897765.023.png
- - - Добавлено - - -
Скажи, а ты что, сам занимаешься анализом Z80? Это же какая охренительная должна быть квалификация! Ты что заканчивал?
Я занимаюсь для того, чтобы понять нюансы его работы) Без этого точный эмулятор не напишешь. А я же эмуляторщик)
Ничего не заканчивал связанного с электроникой. Я программист.
Но я уже столько отреверсил чипов (для УКНЦ), что для меня это уже не особо сложная задача, просто кропотливая. Что делать, если никто не сделал, а хочется)
Многие реверсят до транзисторного вида, иногда даже не причесывая, и либо засовывают в FPGA, либо симулируют, как в Z80 Explorer. Но это не дает информации о нюансах работы. Да и плавающие состояния тут можно упустить. Единственный вариант, на мой взгляд, познать всю суть работы процессора - это построение причесанной и понятой транзисторной схемы, а по ней логической.
- - - Добавлено - - -
Вот чего мне менее всего интересно, это сидеть перерисовывать слои с кристалла.
Идеально, если уже есть потранзисторная схема, пусть даже просто в виде списка транзисторов и соединений. С чего я и начал реверс Z80, собственно.
- - - Добавлено - - -
ну почему же.
есть тесты CCF\SCF, причем в зависимости от производителя\мануфактуры - аж три различных варианта поведения этих самых недокументированных флагов.
На счет этого теста.
Думаю, что причина в том же - обилие динамических защелок в блоке формирования флагов.
Впрочем, их много в принципе в этом микропроцессоре. Но большинство из них тактируются CLK, и на частоте работы процессора работают как статические. А вот в блоке формирования флагов много наворотов, в том числе и с динамическими защелками, тактируемыми как придется. Так что вполне возможно, что утечки можно добиться. Надо проанализировать их работу на досуге, просто пока до них не дошел, только до флага S, о котором рассказывал выше.
Замечу, никто еще не вызвался проверить мое предположение на NMOS реале.:v2_unsur:
- - - Добавлено - - -
Немного о блоке формирования флагов:
S - флаг знака самый простой, в него просто копируется 7-бит результата работы АЛУ.
Z - флаг нуля почти такой же простой, формируется, если результат работы АЛУ равен 0. Однако там есть дополнительная цепь установки, сброса, обратной связи. Зачем она нужна, еще не разбирался.
N - флаг сложения/вычитания. Именно по этому флагу АЛУ знает, что нужно делать, складывать или вычитать (то же сложение, но второй аргумент инвертируется). Крайне интересно, что команды относительного условного перехода (и не только), использующие АЛУ для получения эффективного адреса, кешируют во нутренний кеш этого флага предыдущее состояние флага S(!). С чего бы это? Еще не разбирался. Должно быть, чтобы понять, вычитать смещение или прибавлять, в зависимости от знака смещения.
C - флаг переноса. Работает в целом весьма документированно, за исключением того, что для команд AND, CCF, SCF в него копируется инвертированное значение флага H(!) (полупереноса). Видимо, таким образом команда CCF инвертирует флаг C, пропуская его через полуперенос.
H - флаг полупереноса один из самых навороченных. Единственное, что пока могу сказать, он всегда изменяется для всех команд, которые влиют хотя бы на какие-то флаги. Т.е. у него нет кеша предыдущего его значения.
PV - флаг четности/переполнения - пока не разбирался.
Причем, практически все операции как раз и проходят в режиме обьедененных шин, т.к. работа идет с 8 битами.
И вот этот момент не воспроизвести в FPGA, как и висящее на зарядах затвора значения.
У меня есть подключенный к DE1 z80, могу провести разного рода эксперименты, при условии понятного мне условия теста и тестового кода
Lethargeek
22.08.2024, 19:50
N - флаг сложения/вычитания. Именно по этому флагу АЛУ знает, что нужно делать, складывать или вычитать (то же сложение, но второй аргумент инвертируется)
шта? по всем докам ровно наоборот - по сложению или вычитанию значение флага определяется
И вот этот момент не воспроизвести в FPGA, как и висящее на зарядах затвора значения.
У меня есть подключенный к DE1 z80, могу провести разного рода эксперименты, при условии понятного мне условия теста и тестового кода
Да, в таком виде не воспроизвести. Но если перевести в логическую схему, и выявить именно проблемные места, то можно их в той или иной мере и на FPGA повторить. Счетчик ввести специальный о потери заряда, и т.д.)
Если процессор NMOS, то обязательно надо сделать тест. На других архитектурах не надо, т.к. от них нет реверса.
- - - Добавлено - - -
шта? по всем докам ровно наоборот - по сложению или вычитанию значение флага определяется
Доки врут)
Я смотрю на схему и она гласит об обратном) Сначала выставляется флаг, потом АЛУ смотрит на флаг и говорит - о, флаг вычитания стоит, значит инвертирую второй аргумент.
Lethargeek
23.08.2024, 04:55
Доки врут)
Я смотрю на схему и она гласит об обратном) Сначала выставляется флаг,
а теперь внимание, вопрос: выставляется на основании чего? ;)
потом АЛУ смотрит на флаг
лишним выглядит, операция уже после декодирования известна
и говорит - о, флаг вычитания стоит, значит инвертирую второй аргумент.
инверсия - НЕ унарный минус! (в дополнительном коде)
Если процессор NMOS, то обязательно надо сделать тест. На других архитектурах не надо, т.к. от них нет реверса.
Нужен конкретно zilog или nmos от других производителей тоже подойдут?
Barmaley_m
23.08.2024, 11:39
У меня есть подключенный к DE1 z80, могу провести разного рода эксперименты, при условии понятного мне условия теста и тестового кода
Это дает огромные возможности. Скажем, если снизить тактовую частоту Z80 и подставлять ему команду SCF (или какая там нужна) в циклах M1 по всем адресам памяти - то можно выдержать достаточно времени до гарантированного разряда емкостей затворов, если от них что-нибудь зависит.
Игрался с z80 и МК. Могу задавать любую частоту, могу анализировать всё что хош. Выставляйте условия.
Нужен конкретно zilog или nmos от других производителей тоже подойдут?
А вот этого я не знаю. Я даже не знаю, с какой конкретно модели в проекте Z80 Explorer снимали схему.
Но, думаю, стоит попробовать на любом NMOS.
- - - Добавлено - - -
Игрался с z80 и МК. Могу задавать любую частоту, могу анализировать всё что хош. Выставляйте условия.
Задача такая. Если на спектруме, то по адресу $4000 разместить примерно такой код:
DI
LD A,0 (или $FF для второго теста)
OR A
NOP (загрузка кеша текущими значениями флагов)
ADD HL,DE (или SCF) (на все 48Кб)
В конце выполнения смотрим регистр флагов
- - - Добавлено - - -
а теперь внимание, вопрос: выставляется на основании чего?
На основании кода команды. А именно:
https://pic.maxiol.com/images2/1724406113.531452495.01.png
- - - Добавлено - - -
лишним выглядит, операция уже после декодирования известна
Кому известна? Блоку декодирования команд и флагов) А АЛУ неизвестна. АЛУ как раз ориентируется на флаг, чтобы инвертировать аргумент.
- - - Добавлено - - -
инверсия - НЕ унарный минус! (в дополнительном коде)
Разумеется. Но по скольку АЛУ всегда делает ADC, а не ADD, то как раз инвертируя входящий перенос и получается вычитание. Вообще, т.к. блок АЛУ 4-битный, он не ориентируется на флаг C, он ориентируется на флаг H. Думаю, поэтому флаг полупереноса вообще и был сделан в процессоре в том числе, т.к. он фактически является связующим переносом между двумя отдельными действиями 4-битного АЛУ.
- - - Добавлено - - -
Кстати, еще из интересного.
Регистр WZ, выбирается всегда, когда на том или ином этапе выполнения команды не выбран другой регистр. Там так и стоит широкое условие, что если не AF, если не HL, DE и т.д., то тогда выбираем WZ.
Пока с WZ тоже не разбирался, но думаю, он участвует во всех промежуточных операциях типа вычисления индекса, эффективного адреса относительных переходов и т.д.
- - - Добавлено - - -
И еще кстати - я думаю, что то, что имеется в виду под регистром MEMPTR, от которого в 3 и 5 битах в регистре флагов остаются следы, на самом деле не существует. Это просто остаточный заряд на шинах HBUS/LBUS. А так как LBUS используется для формирования флагов, и во время формирования флагов 3 и 5 биты просто не презаряжаются, а остаются, как есть, то и получается соответствующий результат.
- - - Добавлено - - -
Есть, конечно регистр PCR (так его назвали авторы Z80 Explorer). Может его и можно считать MEMPTR, т.к. через него инкрементируются 16-битные регистры типа PC, IR (7 бит).
- - - Добавлено - - -
Если кому интересно, текущий набросок выглядит так:
NMOS Z80 - sketch rev.14.pdf (https://dropmefiles.com/F7vYL)
Lethargeek
23.08.2024, 15:32
Кому известна? Блоку декодирования команд и флагов) А АЛУ неизвестна. АЛУ как раз ориентируется на флаг, чтобы инвертировать аргумент.
казалось бы, почему декодеру не сообщить тип операции в АЛУ напрямую
а так выходит, что многие команды флаг по сути портят (для единственного штатного применения)
ну, и под значениями флагов в доках понимается значение перед выполнением команды, а не в процессе
ADD HL,DE (или SCF) (на все 48Кб)
при сложении наверно надо еще записать #0000 в DE.
проверил на сером +2
add hl,de ; a=#00 ; ............... ; F=#44
a=#FF ; ................; F=#84
SCF ; a=#00 ; ............... ; F=#45
a=#FF ; ................; F=#AD
отличия с эмулем есть !!!
SpecEmu выдаёт #6C
https://pic.maxiol.com/thumbs2/1724417448.3645248216.clipboard01.png (https://pic.maxiol.com/?v=1724417448.3645248216.clipboard01.png&dp=2)
а так выходит, что многие команды флаг по сути портят (для единственного штатного применения)
Выходит, что так. Особенно с флагом полу-переноса.
- - - Добавлено - - -
при сложении наверно надо еще записать #0000 в DE.
Это не обязательно, т.к. мы смотрим флаг S, а на него ADD HL,DE не влияет не зависимо от аргументов.
- - - Добавлено - - -
проверил на сером +2
По твоему тесту сбоя не видать. У тебя NMOS процессор?
по-маркировке ( Z8400APS) - да
по-маркировке ( Z8400APS) - да
Надо попробовать еще на других. Но может действительно не успевает заряд разрядиться.
Если ничего не выйдет, то может кто-то смоделирует на какой-нить железке ситуацию, когда процессору скармливается несколько секунд один и тот же опкод, и потом уже смотреть флаги. Потому что реально интересно, за сколько времени разрядится ячейка.
- - - Добавлено - - -
Так с данным тестом отбой.
Почему? Потому что я поленился посмотреть потранзисторную версию этого фрагмента, и там все хорошо сделано. Постоянно регенерируется с помощью CLK.
Буду в следующий раз внимательнее проверять подобные подозрения.:v2_dizzy_facepalm:
- - - Добавлено - - -
https://pic.maxiol.com/images2/1724418253.531453748.01.png
отличия с эмулем есть !!!
SpecEmu выдаёт #6C
Ну это из-за другой особенности, из-за CCF, я думаю.
- - - Добавлено - - -
Погулял по транзисторной версии схемы, никакой утечки во всем блоке формирования флагов не нашел :(
Значит недокументированное поведение CCF не связано именно с утечкой в блоке флагов.
Надо будет посмотреть последовательно алгоритм выполнения CCF.
- - - Добавлено - - -
Проследил всю цепочку выполнения CCF.
Отличия от обычного NOP:
1. В такте T5 (T4 + 1) копируется кешированный ранее флаг C во флаг H
2. В такте T6 ничего не происходит
3. В такте T7 (T4 + 3) копируется инверсная копия H во флаг C.
4. В такте T8 (Т4 + 4) флаги выставляются на шину LBUS (кроме 3 и 5).
Поэтому если какой-то глюк и есть в CCF, то его надо искать только в 3 и 5 флагах, т.е. в состоянии LBUS во время выполнения CCF.
Но на LBUS я тоже не вижу никакого мусора. Туда копировался флаг F перед началом команды, значит флаги 3 и 5 должны были сохраниться.
Словом, пока не вижу по схеме потенциальных глюков, откуда они взялись в тестах иностранных товарищей.
А что касается команды SCF, то она работает абсолютно также, как CCF, за единственным исключением - в такте T5 флаг H очищается. Поэтому флаг H=0 при инверсии становится 1, и C становится равной 1.
Попричесывал блок формирования флагов, переделав все двунаправленные ключи обьеденив их многопортовые триггеры. Теперь все выглядит намного нагляднее.
Накину
1) https://github.com/hoglet67/Z80Decoder
тут чтото про ccf/scf test
2) на сайте visual6502 упоминались фотки Zilog CMOS Z80 - Z84C00
http://blog.visual6502.org/2011/08/zilog-cmos-z80-z84c00.html
на сайте visual6502 упоминались фотки Zilog CMOS Z80 - Z84C00
Ну наша-то точно NMOS.
1) https://github.com/hoglet67/Z80Decoder
тут чтото про ccf/scf test
Походив по ссылкам, нашел хорошую статью (без VPN может не открыться).
Статья все правильно описывает, все так и есть.
Down to the silicon: how the Z80's registers are implemented (http://www.righto.com/2014/10/how-z80s-registers-are-implemented-down.html)
- - - Добавлено - - -
А вот тут прекрасно рассказано про инкрементер/декрементер, упоминается конвейер и 4-битное АЛУ.
The Z-80's 16-bit increment/decrement circuit reverse engineered (http://www.righto.com/2013/11/the-z-80s-16-bit-incrementdecrement.html)
и ранее упоминалось здесь
https://github.com/MiSTer-devel/MegaDrive_MiSTer/tree/main/rtl/nuked-md
я кажется смог его "запустить" (z80.v) в симуляторе. там используется одна "основная" тактовая и вторая "вспомогательная". реализовано на "эмуляции защёлок" (это на поверхностный взгляд).
и ранее упоминалось здесь
Я не понимаю верилог, и не могу сравнить его со схемой, на сколько он ей соответствует.
ок. а схема вашего реверса доступна на просмтр ?
ок. а схема вашего реверса доступна на просмтр ?
Так в этом (https://zx-pk.ru/threads/34173-revers-inzhiniring-z80.html?p=1202822&viewfull=1#post1202822) посте выкладывал. Только она недопричесанная, и могут встречаться ошибки, но она постоянно совершенствуется. Это как бы промежуточный, но полноценный вариант.
ааа ... а слона то и не заметил.
1) к сожалению это пдф в графике - отсутствует поиск по наименованию цепей.
2) сходу не заметил таблички-прошивки для PLM (пока не понял смысл mask/value) - кажется уже догадался...
3) что подразумевает вход ОЕ (хотябы для PLM) ? EZ это понятно управление третьим состоянием.
4) на память с трудом вспоминаю (УГО, что обозначают символы в среднем поле) к примеру u231 ?
5) U179 и U178 как всё вместе работает применительно к выходу (out ports) ?
6) гипотетически, если спаять из этих микросхем - оно должно же работать ? или в схеме "используются" микросхемы, которые невозможны в реальном мире?
7) кругляш на входе - это инвертирование входного сигнала ? те активный уровень "лог 0" ?
2) сходу не заметил таблички-прошивки для PLM (пока не понял смысл mask/value)
Маска - это какие биты надо оставить для сравнения. Например, FF - это все биты сравниваются. 0F - это только младшие 4.
VALUE - это с каким значением сравнивается. Иными словами if (Input & Mask) = Value, то выход матрицы активен.
- - - Добавлено - - -
3) что подразумевает вход ОЕ (хотябы для PLM) ? EZ это понятно управление третьим состоянием.
OE - разрешение выхода. Если выход комплиментарный, то при OE = 0, на выходе ноль.
Если выход с открытым коллектором, то при OE = 0, на выходе Z.
Если выход с двумя треугольничками в виде ромбика, то выход комплиментарный, но при OE = 0 тоже Z.
- - - Добавлено - - -
4) на память с трудом вспоминаю (УГО, что обозначают символы в среднем поле) к примеру u231 ?
Это усиленный буфер. Он может быть с инверсией или без инверсии.
- - - Добавлено - - -
5) U179 и U178 как всё вместе работает применительно к выходу (out ports) ?
U179 с открытым эмиттером, U178 с открытым коллектором.
По-другому никак нельзя было изобразить это в виде логических микросхем. Такой вот нестандартный порт.
При BUSACK_C = 1, порты работают, как с открытым коллектором, при BUSACK_C = 0, они работают как обычные комплиментарные.
- - - Добавлено - - -
6) гипотетически, если спаять из этих микросхем - оно должно же работать ? или в схеме "используются" микросхемы, которые невозможны в реальном мире?
Имеется в виду, есть ли конкретно такие микросхемы в номенклатуре какого-либо производителя? Или же реальны ли они в принципе? )
- - - Добавлено - - -
7) кругляш на входе - это инвертирование входного сигнала ? те активный уровень "лог 0" ?
Да.
на первый взгляд - можно превратить в verilog по модулям аля U641, U837.... - по идее получится аля схема из квадратиков...
что-то типо такого
на первый взгляд - можно превратить в verilog по модулям аля U641, U837.... - по идее получится аля схема из квадратиков...
Ну, я с ним вообще не работал никогда, поэтому не знаю, какие есть утилиты, конвертеры, симуляторы)
ну это не страшно... systemVerilog очень простой. навороты языка необязательно использовать. НО есть нюансы (для любого языка HDL): RS-триггер идентичный ТМ2 невозможно изобразить (к примеру сложно описать выходы при запрещённой комбинации на входе) u190 R=1 S=1 что должно быть на выходе ?.
Другая сложность - это крайне не рекомендуется использовать тактовый сигнал как логический сигнал. U475+u192
ну это не страшно... systemVerilog очень простой. навороты языка необязательно использовать. НО есть нюансы (для любого языка HDL): RS-триггер идентичный ТМ2 невозможно изобразить (к примеру сложно описать выходы при запрещённой комбинации на входе) u190 R=1 S=1 что должно быть на выходе ?.
Мне, в принципе, верилог и не нужен, т.к. никогда не занимаюсь разработкой для FPGA, а мне интересны только программные эмуляторы.
Про RS-триггеры проще простого. В топологии Z80 они работают так. Если R = 1, и S = 1, то на обоих выходах простом и инверсном будут нули. Кроме того, я при реверсе специально проверяю, может ли такой триггер встать в третье состояние (может ли на него в данном включение быть подано R и S одновременно), и если может под ним подписываю.
- - - Добавлено - - -
Другая сложность - это крайне не рекомендуется использовать тактовый сигнал как логический сигнал. U475+u192
А тут в чем сложность? Весь Z80 наполнен такими цепями. Чаще всего это используется чтобы сдвинуть сигнал на пол-такта, а потом выделить из него вторую половину, т.к. Z80 внутренне работает с дискретностью пол-такта.
- - - Добавлено - - -
Правильно ли я понимаю, что FPGA вообще не любит триггеры, которые тактируются уровнем, а не фронтом?
1) ну я и не предлагаю (не заставляю) вписываться в hdl
2) про RS - вот такие нюансы и важны для плисоводов
3) clk - если делать дословно как по схеме - будет бред в плисе (вплоть до непонятных глюков в работе), а если использовать сдвиг по фазе - то придётся адаптировать исходную схему. Компромисия - она такая ;-)
4) ну как бы в плисах (ксалинкс/алтера) нет тригеров по уровню, только по фронту. но есть защёлки аля ир22 (IN74ACT373N). но и они крайне не рекомендуются к использованию.
Другими словами схема в плисе должна описываться D-триггерами с логикой (аля ла3) между оными.
Если отступать от этого правила - падает максимальная рабочая частота.
ПС: для плис: либо пожертвовать частотой (если использовать "две тактовые 0гр/180гр"), либо адаптировать схему принципиальную под одну тактовую. Разница в рабочей частоте примерно в раза будет отличаться (куча нюансов).
ну как бы в плисах (ксалинкс/алтера) нет тригеров по уровню, только по фронту. но есть защёлки аля ир22 (IN74ACT373N). но и они крайне не рекомендуются к использованию.
Ну я так примерно и представлял.
Конечно, тот, кто собирается реализовывать в FPGA может адаптировать всю схему под триггеры по фронту.
- - - Добавлено - - -
но есть защёлки аля ир22 (IN74ACT373N). но и они крайне не рекомендуются к использованию.
Зачем же они есть, если не рекомендуются к использованию?
Конечно, тот, кто собирается реализовывать в FPGA может адаптировать всю схему под триггеры по фронту.
Только это будет уже очередной симулятор, нужно смириться что нельзя воспроизвести структуру процессора 1в1 в FPGA, нужно на транзисторах собирать
Только это будет уже очередной симулятор, нужно смириться что нельзя воспроизвести структуру процессора 1в1 в FPGA, нужно на транзисторах собирать
Не согласен. События и так происходят фактически по фронту. Но для упрощения во многих местах можно было поставить триггеры по уровню. Так что такая переделка никак не повлияла бы на аутентичность реализации.
Другая сложность - это крайне не рекомендуется использовать тактовый сигнал как логический сигнал. U475+u192
Я думаю, что для FPGA во многих местах эта комбинация вполне может быть заменена на триггер с защелкиванием по спаду. Правда, нельзя это тупо все менять, надо смотреть, где можно так, а где немного иначе.
https://pic.maxiol.com/images2/1724666188.531452473.01cc.png
А в плис одновременно используются триггеры по фронту и спаду? Или чтобы реализовать и такие, и такие, надо иметь две CLK, одна сдвинутая на 180 градусов? Или как-то еще.
- - - Добавлено - - -
И еще вопросы:
1. Я так понимаю, что в ФПГА нет внутренних шин с Z-состоянием и открытым коллектором?
2. Как можно реализовать обьединение двух шин, когда они в какой-то такт процессора запараллеливаются (LBUS и HBUS)? Т.е. получается так, что в режиме обьединения шин все, что выводится на шину LBUS, например, появляется и на HBUS, и наоборот.
А в плис одновременно используются триггеры по фронту и спаду?
Одновременно нельзя, таких триггеров нет. Два противофазных тактовых сигнала( и два отдельных процесса, не один и тот же триггер ), либо удвоенная частота и счетчик.
Одновременно нельзя, таких триггеров нет. Два противофазных тактовых сигнала( и два отдельных процесса, не один и тот же триггер ), либо удвоенная частота и счетчик.
Я может не так выразился) Не один тот же триггер чтобы работал по фронту и спаду, а чтобы на кристалле были триггеры, одни из которых по фронту, другие по спаду.
Вообще, я думаю, что может быть зря обходил стороной сферу эмуляции в FPGA. Ведь гораздо проще перенести логическую схему в FPGA с небольшими адаптациями, чем программно эмулировать тоже самое на компьютере (с адекватной скоростью, на на уровне симуляции работы транзисторов, как в Z80 Explorer). Хотя, программная эмуляция мне наиболее интересна, т.к. привычнее.
Отсюда пара оффтопных вопросов:
1. Какие сейчас самые хорошие и ходовые вместительные FPGA? Производитель, серия? (китайцев лучше не предлагать). И чтобы отладочная плата продавалась готовая с HDMI, VGA, даже может композитом.
2. В каких средах и на каких языках сейчас пишут под FPGA? Какой есть нормальный симулятор, чтобы загрузил проект, и мог посмотреть симуляцию работы в виде диаграмм?
3. Какие есть учебники/ролики и т.д. чтобы ознакомиться с темой?
4. Есть ли пример проекта какого-то простенького спектрума, чтобы посмотреть, как вообще это делают.
4. Есть ли пример проекта какого-то простенького спектрума, чтобы посмотреть, как вообще это делают.
https://github.com/AtlasFPGA/zx?tab=readme-ov-file
Я может не так выразился) Не один тот же триггер чтобы работал по фронту и спаду, а чтобы на кристалле были триггеры, одни из которых по фронту, другие по спаду.
Вообще, я думаю, что может быть зря обходил стороной сферу эмуляции в FPGA. Ведь гораздо проще перенести логическую схему в FPGA с небольшими адаптациями, чем программно эмулировать тоже самое на компьютере (с адекватной скоростью, на на уровне симуляции работы транзисторов, как в Z80 Explorer). Хотя, программная эмуляция мне наиболее интересна, т.к. привычнее.
Отсюда пара оффтопных вопросов:
1. Какие сейчас самые хорошие и ходовые вместительные FPGA? Производитель, серия? (китайцев лучше не предлагать). И чтобы отладочная плата продавалась готовая с HDMI, VGA, даже может композитом.
2. В каких средах и на каких языках сейчас пишут под FPGA? Какой есть нормальный симулятор, чтобы загрузил проект, и мог посмотреть симуляцию работы в виде диаграмм?
3. Какие есть учебники/ролики и т.д. чтобы ознакомиться с темой?
4. Есть ли пример проекта какого-то простенького спектрума, чтобы посмотреть, как вообще это делают.
Буду дома - попробую с картинками ответить.
1) если не смотреть на китайцев - только два варианта Альтера и Ксалинкс. Лично я за Ксалинкс (это мой "хлеб") . Инструментарий Ксалинкс на порядок лучше чем Альтера ("сравнивал" на одном проекте). Единственный минус - это его медлительность в "синтезе/компиляции".
По платам: нынче одинаково фигово. Лично у меня есть ZedBoard (vga hdmi audio), + ещё парочка плат (заводская и самопал).
2) пишут нынче на vhdl verilog systemverilog - остальные экзотика. Лично я за systemverilog - современный, лаконичный, практичен и море возможностей (помесь Си и Паскаля). vhdl - много лишнего "текста", местами сложен (аля язык АДА).
Симулятор входит в комплект инструментария (Альтера и Ксалинкс).
3) для начала можно посмотреть https://marsohod.org (не фонтан, но для беглого ознакомления норм, к сожалению заточен на альтеру)
4) народ подскажет.
- - - Добавлено - - -
81178 81179
исходно есть:
- два 4-х канальных буфера с Z-выходом
- первый триггер работает по фронту 0/1
- второй триггер работает по фронту 1/0
всё это превращается в три слоя логики ( первый LUT, остальные триггера)
В реальных плисах нет Z-логики в железе. В железе всегда либо 0 либо 1. Z-значение в реальности тоже 0 или 1 (на усмотрение синтезатора). В этой схеме когда оба EN_A EN_B в нулях или в единице на выходе будет значение, которое "удобно" синтезатору. Если это не устраивает - то для этой ситуации надо модернизировать исходную схему.
ПС: LUT это по факту комбинаторная логика от 1 до 6 входов
Barmaley_m
28.08.2024, 00:40
Не один тот же триггер чтобы работал по фронту и спаду, а чтобы на кристалле были триггеры, одни из которых по фронту, другие по спаду.
Так можно. Но не рекомендуется. На кристалле обычно есть несколько (на порядки меньше по отношению к кол-ву триггеров) буферов тактовой частоты, через которые можно подавать на тактовый вход большой группы триггеров произвольный сигнал. Но чем меньше разных частот используется в проекте - тем лучше. Потому, что у триггеров есть такие явления, как метастабильность. Которая будет обязательно возникать, если источник сигнала (триггер) работает на одной тактовой частоте, а приемник - на другой. Поэтому переход сигналов между системами триггеров, работающих на разных тактовых частотах - это тот еще гемор, требующий для правильной работы использования специальных узлов - синхронизаторов.
Когда все триггеры работают на одной тактовой частоте - то становится возможным предсказать и оптимизировать быстродействие схемы. Нужно лишь гарантировать, что выходы одних триггеров, пройдя через комбинационную логику, попадают на входы последующих триггеров - грубо говоря - не позднее следующего фронта тактовой частоты. Время прохождения сигналов через комбинационную логику зависит от сложности этой логики и разводки схемы на ПЛИС. Контролем и оптимизацией сложности и разводки занимается среда разработки для соответствующего типа ПЛИС.
1. Какие сейчас самые хорошие и ходовые вместительные FPGA? Производитель, серия? (китайцев лучше не предлагать).
Производители: Xilinx (некоторое время назад перекуплено AMD) и Altera (некоторое время назад перекуплено Intel).
"Самые хорошие и вместительные" - из последних серий, они обычно настолько дорогие (тысячи и десятки тысяч $ за чип), что для большинства проектов себя не оправдывают. Для больших проектов за более-менее вменяемую цену следует использовать FPGA ценовой категории 50-60$/чип. Как правило, это бюджетные либо устаревшие серии FPGA. Для Xilinx это будет, на сегодняшний день, что-то из серии Spartan-7, Artix-7. Но Спектрум полностью (включая процессор) можно с большим запасом реализовать и на Spartan-6. Для Altera это будет что-то из серии Cyclone (какие у них там актуальные), с ними я не работал.
2. В каких средах и на каких языках сейчас пишут под FPGA?
Среды разработки поставляются производителем FPGA. Для Xilinx Spartan-6 и более ранних серий это ISE (для проектов со встроенными процессорами еще нужны платные пакеты XPS/SDK). Для более новых Artix-7, Spartan-7 это Vivado Design Studio. Для Altera не знаю - надо смотреть соответствующие серии FPGA, какие у них там инструменты разработки. Сторонних пакетов для разработки на FPGA не существует, так как внутренняя архитектура и формат данных конфигурации до конца не документированы. А без этого невозможно создать конкурирующую среду разработки.
Языки разработки - VHDL, Verilog. "System Verilog", о котором тут шла речь - не знаю, в чем его отличия от обычного Verilog.
Какой есть нормальный симулятор, чтобы загрузил проект, и мог посмотреть симуляцию работы в виде диаграмм?
В среде разработки обычно есть и симулятор. Программу для симуляции нужно создавать на том же языке, на котором разрабатывается проект (VHDL или Verilog). Дело в том, что оба упомянутых языка - это фактически языки симуляции, они так задумывались. На них задается поведение симулируемой схемы, а также входные сигналы для нее. Это уже потом появился софт, который описание поведения схемы на языке симуляции преобразует в собственно схему. А еще позже задание схемы на языке симуляции стало стандартом. Лишь небольшое подмножество возможностей языков (Verilog/VHDL) разрешается использовать для описания схем, которые подлежат "синтезу" (т.е. преобразованию в схемотехнический формат). Поэтому для схемотехника, для разработки на FPGA на упомянутых языках, нужно существенно перестроить мозги. Но ничего лучшего на сегодняшний день нет.
Также симуляции обычно подлежит не весь проект целиком, а отдельные его блоки. Лишь после отладки и симуляции блоков можно приступать к отладке проекта целиком в железе. Обычно допускаешь в проекте много ошибок, и без предварительной симуляции и отладки запускать проект на железе практически безнадежно.
0. Не один тот же триггер чтобы работал по фронту и спаду, а чтобы на кристалле были триггеры, одни из которых по фронту, другие по спаду.
1. Какие сейчас самые хорошие и ходовые вместительные FPGA? Производитель, серия? (китайцев лучше не предлагать). И чтобы отладочная плата продавалась готовая с HDMI, VGA, даже может композитом.
2. В каких средах и на каких языках сейчас пишут под FPGA? Какой есть нормальный симулятор, чтобы загрузил проект, и мог посмотреть симуляцию работы в виде диаграмм?
3. Какие есть учебники/ролики и т.д. чтобы ознакомиться с темой?
4. Есть ли пример проекта какого-то простенького спектрума, чтобы посмотреть, как вообще это делают.
0. Так можно, но лучше сделать удвоенную частоту и 1-битный счетчик. Тогда все триггеры будут переключаться по фронту, но одни при значении счетчика 0, другие при 1.
1. Я бы смотрел в сторону Cyclone4 (Intel). По другим сказать не могу
2. Я рекомендую Verilog. Симуляторы: iverilog (бесплатный, рекомендую), ModelSim(Questa Sim) - бесплатный StarterEdition, Aldec Active-HDL
3. https://iosifk.narod.ru/hdl_coding/verilog.htm https://marsohod.org/verilog
Референсный справочник по Verilog есть в Сети, еще советую почитать Gotcha's - типичные ошибки
4. Думаю, тут, в конференции есть. Opencores.org, GitHub - там можно поискать
Barmaley_m
Согласен на 99.9%
Уточню что "System Verilog" это "работа над ошибками" языка "Verilog" (+ у него более продвинутая возможность по тестированию)
IanPo
Согласен на 25% (пункт 3 и 4)
"0. Так можно, но лучше сделать удвоенную частоту и 1-битный счетчик. Тогда все триггеры будут переключаться по фронту, но одни при значении счетчика 0, другие при 1."
Можно - но не нужно так делать. Будут дополнительные заморочки по быстродействию схемы.
Если писать на Verilog, то для симуляции есть Icarus Verilog (https://ru.wikipedia.org/wiki/Icarus_Verilog). Просмотр результата в GTKWave (https://steveicarus.github.io/iverilog/usage/gtkwave.html).
Если писать на Verilog, то для симуляции есть Icarus Verilog (https://ru.wikipedia.org/wiki/Icarus_Verilog). Просмотр результата в GTKWave (https://steveicarus.github.io/iverilog/usage/gtkwave.html).
Смысл делать симуляцию в стороннем ПО, когда есть "штатный" симулятор ? при том достаточно плотно (доп. удобства для отладки) интегрирован в среду разработки...
Смысл делать симуляцию в стороннем ПО, когда есть "штатный" симулятор ?
iverilog быстрый и не требует штатного ПО вообще. Достаточно написать текст модуля, прогнать его в икарусе и посмотреть результат в gtkwave. Потом уже собирать в Квартусе или еще где
Смысл делать симуляцию в стороннем ПО, когда есть "штатный" симулятор ?
Ну давай ещё подискутируем, что лучше: Altera или Xilinx (или Lattice).
штатное ПО по любому потребуется, если нужен результат в "железе", так что "iverilog" лишняя заморочка.
Но если "результат в железе не нужен совсем" - то да "iverilog" (возможно) норм вариант (я не использовал ни разу, судя по описанию только для verilog с рядом ограничений).
- - - Добавлено - - -
Ну давай ещё подискутируем, что лучше: Altera или Xilinx (или Lattice).
А это уже ОФФТОП. У всех "любимые карандаши разные". Повторю: среда разработки у Xilinx более технологична, последовательна, понятнее ... (по результатам работы с обеими средами).
"iverilog" (возможно) норм вариант (я не использовал ни разу
Смысл засорять тему ненужными аргументами "против"?
Итак, уточню еще несколько вопросов:
1. VHDL все же или Verilog? Мне все равно, какой изучать, мне важно, какой сейчас в ходу, и, самое главное, на каком пишется большинство наших ретропроектов? На каком написаны симуляторы спектрума, симуляторы 1801ВМ2?
2. Пока что я не услышал конкретного решения, как именно мне тактировать схему, у которой на входе CLK, а внутри часть триггеров работает по спаду, а часть по фронту этого CLK? Мне приходит в голову только инверсия CLK (/CLK), и уже на часть триггеров подавать тактовый CLK, а на часть /CLK. Это же будет нормально синхронно и без подводных камней? Или как?
1) Товарищ Vslav пишет на verilog. Автор реверсов с кристалла процессоров vm80a 1801ВМ1/2/3
https://github.com/1801BM1
2) однозначного ответа не будет , пока не попробуешь реализовать схему. Как вариант можно воспользоваться синтезатором частот в плисе и сгенерировать две частоты со сдвигом фаз в 180гр. Будет минимум телодвижений. (боже упаси использовать инвертор для этих целей...). И НЕ использовать тактовый сигнал как обычный логический сигнал. CLK (и CLK_n) подавать только на тактовые входы триггеров.
Ну или использовать одну CLK а "там" указывать по какому фронту конкретный триггер будет работать. см PDF ранее выложенные.
ПС: я бы рекомендовал обвести пунктиром каждый кусок исходной схемы, обозвать его и реализовывать его как отдельный модуль. потом соединить их в одном топовом модуле. каждый отдельный модуль проще тестировать и отслеживать исправления исходной схемы. и по возможности не использовать русские буквы в комментариях (я не помню в какой кодировке у Алтеры, у Ксайлинкс под виндами cp1251. а что с кодировками под линуксов вообще не знаю).
пспс: verilog несколько более универсален: можно использовать для любых сред разработок и различных плис (в том числе и для китайцев). Проще чем vhdl (особенно если полжизни писал программы на Си). Элементарно стыкуется с (переводится на ) SystemVerilog.
пспспс: для особых "извращенцев" - в одном проекте можно использовать хоть все три языка одновременно (проверено в xilinx), главное чтоб среда разработки (синтезатор) понимал их. :v2_dizzy_facepalm:
VHDL все же или Verilog? Мне все равно, какой изучать, мне важно, какой сейчас в ходу, и, самое главное, на каком пишется большинство наших ретропроектов? На каком написаны симуляторы спектрума, симуляторы 1801ВМ2?
vhdl забыть как страшный сон, если забыть нельзя то терпеть и страдать
2) однозначного ответа не будет , пока не попробуешь реализовать схему. Как вариант можно воспользоваться синтезатором частот в плисе и сгенерировать две частоты со сдвигом фаз в 180гр.
Ни в коем случае. Частота CLK не константа, может продаваться на процессор произвольно меняясь на ходу.
- - - Добавлено - - -
Ну или использовать одну CLK а "там" указывать по какому фронту конкретный триггер будет работать. см PDF ранее выложенные.
А, ну если это возможно, то прекрасно. Мне именно и надо, чтобы одни триггеры работали по спаду, другие по фронту же.
Уточнение: Частота CLK плавно или дискретно (несколько значений) меняясь на ходу ? это типо "академический вопрос".
пс: на алишке есть ebaz4205 (не самый лучший вариант платы). но тут тоже есть нюансы - есть шанс что "изделие" одноразовое, те залить свою прошивку не выйдет. хотя если продают... то наверно всё норм.
Уточнение: Частота CLK плавно или дискретно (несколько значений) меняясь на ходу ? это типо "академический вопрос".
Входная частота CLK может меняться как угодно в Z80. Допустим, внешняя схема тормозит процессор не по сигналу WAIT, а затормаживанием CLK. В общем, смысл в том, что нельзя рассматривать CLK, как что-то со стабильной частотой и скважностью. Это просто события по фронту и спаду которых надо тактировать триггеры.
Ок. такой вариант возможен. Параметры скважности будет зависеть от максимальной частоты всей модели. те если Fmax ==5 МГц, то мин значение полупериода будет 10нС, а второй полупериод от 10 до бесконечности. Тк плиса вещь статическая то нижняя частота от 0 до Fmax.
ПС: 1) если использовать PLL то там есть порог минимальной опорной (входной) частоты -- чтото в районе нескольких МГц (точно не помню).
2) есть вариант использовать Fmax всегда, но управлять скважностью. что тоже будет равносильно от 0 до Fmax.
Несколько "мутно" пишу - но надеюсь что понятно будет.
Несколько "мутно" пишу - но надеюсь что понятно будет.
Мне еще пока не понятно главное - как при произвольной CLK, но не превышающей определенную частоту, сделать, чтобы часть триггеров работала по спаду, часть по фронту?
примерно так для триггера по нарастанию фронта
always_ff @ ( posedge clk)
bus_d <= bus_c;
а так для триггера по спаду фронта
always_ff @ ( negedge clk)
bus_e <= bus_d;
тут есть статейка в картинках про "плисоварение" от истории до конечного продукта.
https://fpga-systems.ru/fs_fsm/state_0/fsm_state_0.pdf
тут есть статейка в картинках про "плисоварение" от истории до конечного продукта.
Вот соблазните меня ПЛИСами, и перестану писать эмуляторы и буду писать FPGAторы, т.к. это проще и ближе к оригиналу)
CityAceE
30.08.2024, 15:26
Одну из разновидностей Tang Nano за копейки можно купить, чтобы понять нужно оно вообще или нет. Спектрум там есть.
Одну из разновидностей Tang Nano за копейки можно купить, чтобы понять нужно оно вообще или нет. Спектрум там есть.
Мне тут посоветовали пока что с китайскими ПЛИСами не связываться, поэтому лучше Xilinx.
С китайцами есть нюансы - не всегда предсказуемы (по документации, сами плисы, среды разработки...).
И покупать сразу платы вовсе не обязательно - для начала можно порезвиться в симуляторе. Цена вопроса - цена интернета за время скачивания среды разработки.
ПС: Рабочую модель с veriloga можно переписать на Си.
ПСПС: ну а для совсем "продвинутых" можно писать на Си (в среде VivadoHLS) и получать работающий проект в железе (я до этого ещё не дорос - потребности такой ещё не возникало).
ПС: Рабочую модель с veriloga можно переписать на Си.
В смысле переписать на си?
Ну как бы программу на паскале можно переписать на фортран и обратное тоже верно. Так и здесь. взять тот же сега мегадрайв. там есть верилог модель и есть си реализация...
Barmaley_m
30.08.2024, 22:48
Мне еще пока не понятно главное - как при произвольной CLK, но не превышающей определенную частоту, сделать, чтобы часть триггеров работала по спаду, часть по фронту?
Могу точно пояснить по Spartan-6.
Там в каждом блоке SLICE (в котором имеется 4-8 триггеров, 4 6-входовых комбинационных LUT6 и кое-что еще) можно конфигурировать полярность сигнала CLK на триггеры.
Поэтому можно взять тактовый сигнал, описать на языке (VHDL/Verilog) инвертор для него, и подавать прямой или инверсный CLK на тактовый вход всех триггеров. Та часть из них, на которую подается прямой CLK, будет срабатывать по его нарастанию, а другая часть (с инверсным CLK) - по спаду. При синтезе схемы этот инвертор не займет никаких ресурсов кристалла. Ни буферов тактовой частоты (BUFG), ни комбинационной логики (LUT), ничего. И даже задержки сигнала от инверсии не будет.
Как на Spartan-7 или Artix-7 - не знаю. У Xilinx была тенденция уменьшения гибкости логических ресурсов от поколения к поколению, чтобы упаковать их больше на один кристалл. Например, в Spartan-3 были триггеры с входами R и S, а в Spartan-6 - только один из двух (R или S). Также у Spartan-6 были асинхронные R- или S-входы у триггеров, а у Artix-7 - только синхронные (по фронту тактовой частоты). На самом деле эти ограничения даже полезные, они повышают культуру разработки и ни в коей мере не ограничивают свободу разработчика, если только он немного по-другому решит задачу, которую ранее решал асинхронными входами. В общем, по Artix-7 или Spartan-7 надо смотреть по докам, есть ли там тоже возможность инверсии тактового входа триггеров. В Spartan-6 точно есть.
Я не рекомендую подавать внешний тактовый сигнал с неизвестной скважностью на схему, часть триггеров которой срабатывает по нарастанию, а другая часть - по спаду. Почему?
Потому, что скважность тактового сигнала неизвестна. А размещение/разводка схемы требуют конкретных чисел. Например: что частота сигнала не более стольки-то МГц, и скважность не менее x % и не более y%. Тогда оптимизатор, исходя из наихудших условий (экстремально короткие тактовые импульсы и т.д.), раскидает и разведет схему по ресурсам ПЛИС, гарантируя ее работоспособность.
Но широкие допуски на входной тактовый сигнал приведут к тому, что максимальная тактовая частота, при которой синтез проекта пройзойдет успешно, окажется весьма низкой. В самом деле, а вдруг пользователь подаст на тактовый вход сигнал самой неприятной для схемы скважности? Очень короткие положительные или отрицательные импульсы на тактовом входе приведут к трудностям при генерации работоспособной конфигурации ПЛИС.
Что я предлагаю взамен? Гарантировать скважность 50% для тактовой частоты. Это можно сделать при условии, что входной тактовый сигнал периодический (без выпадений импульсов и т.п.). Подать входной тактовый сигнал на ФАПЧ, умножить его в n раз, и наслаждаться. На практике, у меня в железе на Spartan-6 работал 32-битный Softcore-процессор на частоте 80МГц, а некоторые модули схемы (напр. Gigabit MAC) - на 125МГц. Еще были приемники данных, работавшие на битовой частоте 960МГц и байтовой - 120МГц. Более современные поколения ПЛИС могут дать и более высокие рабочие частоты.
Если внешней схеме требуется задержать работу процессора - то это следует делать не путем манипуляций с тактовой частотой, а другим способом. Сделать какой-нибудь сигнал типа WAIT, возможно - с более высоким приоритетом, который безусловно заставляет процессор в любом состоянии пропустить тактовый импульс.
По языкам программирования (Verilog или VHDL) - наверное, это спор о вкусах. Когда учился, я пробовал освоить их оба, легче зашел VHDL, на нем и работал далее. Как профессиональный программист на Си, скажу, что "сходство" Verilog и C - кажущееся. Это совершенно разные языки, для совершенно разных задач, и способ мышления для них различается коренным образом. Между VHDL и Verilog больше сходств, чем между Verilog и C.
Оба языка, повторюсь, задумывались для описания симуляции. Самые главные их концепции:
1) описание узла схемы состоит из "параллельных" и "последовательных" инструкций.
2) Параллельные инструкции выполняются (в абстрактной среде исполнения) все параллельно, непрерывно и одновременно. Как правило, они описывают комбинационные схемы.
3) Последовательные инструкции исполняются как в обычном языке программирования, одна за другой. Они объединяются в "процессы" (Process в VHDL, Always-блоки в Verilog). Основная идея: "процесс" запускается по какому-либо событию (как правило - фронту тактовой частоты) и всякий раз мгновенно (в абстрактной среде исполнения) исполняется до конца. Отсюда конструкции VHDL типа: proc1: process(CLK) begin if CLK='1' and CLK'Event then ......... end if; end process;. В Verilog используется конструкция always @posedge(CLK). Хотя языки VHDL/Verilog допускают запуск "процесса" по изменению произвольных сигналов или их комбинаций, для синтезируемых схем следует запускать процессы только по фронту CLK. Ведь "процессы" синтезируются инструментами разработки в триггеры и комбинационную логику на их входах. Тело "процесса" может содержать разные команды, в том числе циклы, сложные конструкции if/else. Но опять же, для синтезируемых в приемлемых размерах схем следует ограничиться записью в какие-либо сигналы (это будут выходы триггеров) некоторой логической функции от каких-то других сигналов. "Процессов" в узле схемы может быть произвольное количество. По одному и тому же событию может запускаться много разных процессов, и все они (в абстрактной среде исполнения) исполняются одновременно и мгновенно.
Ну как бы программу на паскале можно переписать на фортран и обратное тоже верно. Так и здесь. взять тот же сега мегадрайв. там есть верилог модель и есть си реализация...
Я не сторонник в лоб переписывать с параллельного языка на последовательный. Понятно, что так можно получить наибольшую идентичность исходному коду, с меньшими шансами накосячить при оптимизации. Однако, на мой взгляд, это крайне расточительно в плане ресурсов.
Согласен на 98%
Я не рекомендую подавать внешний тактовый сигнал с неизвестной скважностью на схему, часть триггеров которой срабатывает по нарастанию, а другая часть - по спаду. Почему?
"здесь" - не стремятся добиться космических скоростей. Посему допустимо "подавать внешний тактовый сигнал с неизвестной скважностью". Главное обеспечить длительность любого полупериода больше чем минимальное время от Максимальной допустимой частоты модели. Это если не требуется использовать PLL (но я не помню требований к входной частоте для оного).
Про похожесть ("сходство" Verilog и C - кажущееся) имеется ввиду сложность написание. Verilog и C одного уровня, а VHDL это уровень языка ADA (более строгое соответствие типов, постоянные преобразования типов, знаков итд).
Для 7-семейства в systemveriloge (да и в vhdl) не требуется использовать инвертор (достаточно указывать по какому фронту "мы" работаем).
И да, в клонах ZX есть режим турбо, который переключает на ходу тактовый сигнал.
- - - Добавлено - - -
Я не сторонник в лоб переписывать с параллельного языка на последовательный. Понятно, что так можно получить наибольшую идентичность исходному коду, с меньшими шансами накосячить при оптимизации. Однако, на мой взгляд, это крайне расточительно в плане ресурсов.
Я подразумевал о возможности. а так - да, временами может потребоваться много вспомогательной работы по созданию "рунтайма".
ПС: к слову в виваде симулятор преобразуется *.v (любой hdl) в *.exe исполняемый файл , выводом является результат симуляции.
Barmaley_m
30.08.2024, 23:38
По поводу железа. Я рекомендую покупать готовые платы с FPGA и какой-то дополнительной периферией, и вести разработку на них, вплоть до интеграции таких плат в конечные продукты. Почему? Частоты, на которых работают FPGA (сотни МГц) требуют особых навыков разводки печатных плат. Также большинство актуальных чипов FPGA имеют BGA-корпус с несколькими сотнями выводов. Платы FPGA с какой-нибудь быстрой периферией (SDRAM- или DDR-память, HDMI, Gigabit Ethernet) используют 6 или 10 слоев с малыми допусками и контролем импеданса. Разводка "быстрых" связей требует размещения "змеек" для уравнивания задержки прохождения сигналов и других трюков. Дорого как производство таких плат, так и их монтаж. И с первого раза обычно не получается. Вручную припаять BGA-корпус с сеткой 0,5мм между выводами - тоже с первого раза не у всех получится. Поэтому покупка готовых плат за 250-500$ - вполне оправданное решение. Я, к примеру, использовал плату Digilent Atlys. К настоящему времени она уже устарела, но Спектрум (включая процессор) с HDMI- и звуковыми выходами на ней можно сделать аж на ура.
По поводу железа.
И это то же достаточно актуально. Но блин, здесь много "любителей старины", которые крайне рачительны и 200-500$ это не хилая сумма. Посему "народ" "перебивается" тем что по проще и подешевле. Не в обиду будет сказано для ТС и других посетителей форума.
Barmaley_m
30.08.2024, 23:59
Но блин, здесь много "любителей старины", которые крайне рачительны и 200-500$ это не хилая сумма.
Дешевле не получится. Если делать самому и даже не брать во внимание трудозатраты на разработку своей платы FPGA - то производство 10-слойки и ее монтаж на паре-тройке плат-прототипов вряд ли станут меньше. А если еще учесть риск, что с первого раза не заработает - то вообще ой. И еще, там не все выводы равноправные. Чтобы сразу угадать, какие внешние устройства на какие выводы лучше разводить - это надо вкурить тонны документации и учесть множество вариантов, в идеале - сначала разработать большой проект на готовой плате и на этой основе понять, что нужно для своей платы. Поэтому 250-500$ для плат FPGA, по моему мнению - это дешевле, чем делать самому. Снижение цены достигается эффектом масштаба, величиной серии.
Посему "народ" "перебивается" тем что по проще и подешевле.
А какие тебе известны более дешевые варианты?
ПС: к слову в виваде симулятор преобразуется *.v (любой hdl) в *.exe исполняемый файл , выводом является результат симуляции.
Вивада - это что? Лучше пояснять термины, которые известны вериложцам)
Barmaley_m
31.08.2024, 00:19
Вивада - это что?
Наверно, имеется в виду Vivado Design Studio от Xilinx - среда разработки.
Симуляторы Xilinx действительно переводят проект, состоящий из симуляционного скрипта (который подает на входы испытуемой схемы сигналы) и собственно схемы, в язык Си. Потом компилируют его компилятором GCC в .exe и исполняют. Тем самым достигается высокая производительность симуляции. Но я смотрел этот Си-код, он явно не предназначен для чтения человеком. Это просто код программы расчета результатов симуляции. Она всякий раз генерируется заново. Также я тихо подозреваю, что Си-код там не очень эффективный генерируется. Но за счет компиляции в нативный машинный код все равно достигается некоторая оптимизация.
Также у Spartan-6 были асинхронные R- или S-входы у триггеров, а у Artix-7 - только синхронные (по фронту тактовой частоты). На самом деле эти ограничения даже полезные, они повышают культуру разработки и ни в коей мере не ограничивают свободу разработчика, если только он немного по-другому решит задачу, которую ранее решал асинхронными входами.
Т.е. я еще и должен подумать о том, чтобы избавиться от асинхронных R/S-триггеров, чтобы все было адаптировано под современные ПЛИС? Это жестко, т.к. процессор Z80 изобилует ими.
Как схематически обозначаются синхронные R/S-триггеры и синхроные R/S входы на D-триггерах?
- - - Добавлено - - -
Если внешней схеме требуется задержать работу процессора - то это следует делать не путем манипуляций с тактовой частотой, а другим способом. Сделать какой-нибудь сигнал типа WAIT, возможно - с более высоким приоритетом, который безусловно заставляет процессор в любом состоянии пропустить тактовый импульс.
Это все хорошо, но никак не подходит к проекту Z80, который может быть вставлен в любую схему с CLK произвольной скважности. Поэтому даже и обсуждать нет смысла.
- - - Добавлено - - -
Да, и как реализуются схемы с многопортовыми D-триггерами на ПЛИСах?
По поводу железа.
Однако "мы" потихоньку скатываемся в оффтоп. да простит нас ТС.
По теме плат - если честно, то современные отладки (особенно фирменные и современные и не важно кто алтера/ксайлинкс) все сплошь заточены под высокоскоростные интерфейсы (10/100/400Гбит) и память ДДР4 (а то и под ИИ). А "обвязка" оных не делается "на коленке в домашних условиях". Плат по типу Digilent Atlys надо ещё поискать (она кстати кажется на спартане6). А плат со статической памятью вообще фиг найдёшь (конечно есть альтернативные решения).
Да и вообще ТС делает реверс Z80 в схему электрическую принципиальную - далее насколь я понимаю - делать 99,99% программную модель на Си (С++, алгол, бейсик, лисп ???).
Можно посмотреть здесь https://shop.trenz-electronic.de/en/Products/Programmable-Logic/AMD-Artix-7/
Особенно меня впечатлил
https://shop.trenz-electronic.de/en/TE0765-06-T001CK-MEGA65-highly-advanced-C64-and-C65-compatible-8-bit-computer
и совсем по теме так это
https://wiki.specnext.dev/Circuit_Diagrams
есть ещё алишка-
НО нынешняя ситуация в мире не сильно располагает к покупкам "там", да и финансы "поют романсы". Посему обхожусь тем чем богат (zedboard и ещё парочка других (промышленных) плат)
ПС: Мои извинения для ТС - "скатился" до сленга. Vivado как было сказано выше - это среда разработки.
По сути это огромный комплекс позволяющий делать с плисами что угодно (очень упрощённое описание):
- реализовывать на hdl схемы
- заниматься видео/аудио обработкой (цифровая обработка сигналов) в реалтайме.
- цифровые радиоприёмники
- в матлабе (устанавливается дополнительно) можно из функциональных квадратиков собирать выше упомянутые вещи
- так же на Си (с небольшими нюансами) описывать схемы (Си -> VHDL/Verilog -> прошивка плисы)
- тк в плисах (та да дам - есть софт и хард процессоры) - то можно писать программы для них (как бареметал, так и для линукса, который тоже крутится внутри плисы)
- отдельные версии плис позволяют ИИ
- симулятор того что написал на компе
- отладка в реал тайме в плисе
- онлайн менеджер документации
- и ещё то что уже не помню.
ПСПС: Справедливости ради у Альтеры есть аналогичное - но , я ранее говорил уже - крайне не удобное (не технологичное).
Barmaley_m
31.08.2024, 01:19
Т.е. я еще и должен подумать о том, чтобы избавиться от асинхронных R/S-триггеров, чтобы все было адаптировано под современные ПЛИС? Это жестко, т.к. процессор Z80 изобилует ими.
Жестко только на первый взгляд. Надо просто почесать голову и придумать решение без асинхронных RS-триггеров. На самом деле, асинхронные RS-триггеры - зло. Почему?
При переходе сигнала R (для S рассуждения аналогичны) из неактивного в активный уровень проблем не возникает. Триггер просто сбрасывается, независимо от входов CLK и D. Однако переход R из активного в неактивный уровень должен быть обязательно согласован с тактовой частотой. В противном случае может возникнуть метастабильность. Если снятие R и фронт CLK приходят на триггер почти одновременно - то неизвестно, какой (из-за задержек разводки связей на чипе и т.п. эффектов) придет раньше. И если вход D=1, то R может быть снят как раз в тот короткий промежуток времени, когда информация с входа D проходит на выход триггера. И тогда триггер может остаться в промежуточном состоянии между 0 и 1 на длительное время (один-два такта, изредка более). При этом, до перехода триггера в какое-нибудь (заранее неизвестное!) стабильное состояние, схема, которая смотрит на его выход, может увидеть несколько переключений.
Как лучше всего перевести схему с асинхронных на синхронные RS-триггеры - этот вопрос решается индивидуально в каждом конкретном случае. Если столкнешься с практическим примером, который трудно самому решить - приведи схему, попробуем покумекать вместе.
Как схематически обозначаются синхронные R/S-триггеры и синхроные R/S входы на D-триггерах?
Это зависит от ГОСТов той страны, в которой ведется разработка. Иногда еще от "стандартов" фирмы-производителя FPGA. Конкретно у Xilinx приняты следующие обозначения:
триггер с асинхронным сбросом - FDC, вход сброса - CLR
триггер с синхронным сбросом - FDR, вход сброса - R
триггер с асинхронной установкой - FDP, вход установки - PRE (от слова Preset)
триггер с синхронной установкой - FDS, вход установки - S
По ГОСТ 2.743-91, триггеры обозначаются символами T или TT. Вход установки - SET или S, сброс - RES или R (синхронность или асинхронность задается не буквами, а графическим "указателем свойства выводов").
Да, и как реализуются схемы с многопортовыми D-триггерами на ПЛИСах?
Что значит "многопортовыми"? Параллельные регистры с несколькими триггерами? Просто задаешь входные и выходные шины данных для этих регистров в виде "векторных" сигналов на языке (Verilog/VHDL). Задаешь один "процесс", запускающийся по фронту тактовой частоты. Внутри процесса (и, возможно, блока if) одна команда - запись выходных сигналов регистра на его выход. Еще можно сделать регистру вход разрешения записи (CE) путем помещения в "процесс" команды IF, которая позволяет запись на выходы регистра только если CE='1'. Триггеры внутри FPGA имеют вход разрешения записи, им можно и нужно пользоваться.
Для более подробной информации рекомендую документ Xilinx UG626 "Synthesis and Simulation Design Guide". Там глава 5 "Coding for FPGA Device Flow", подраздел "Registers in FPGA Design".
Т.е. я еще и должен подумать о том, чтобы избавиться от асинхронных R/S-триггеров, чтобы все было адаптировано под современные ПЛИС? Это жестко, т.к. процессор Z80 изобилует ими.
Как схематически обозначаются синхронные R/S-триггеры и синхроные R/S входы на D-триггерах?
Это все хорошо, но никак не подходит к проекту Z80, который может быть вставлен в любую схему с CLK произвольной скважности. Поэтому даже и обсуждать нет смысла.
Да, и как реализуются схемы с многопортовыми D-триггерами на ПЛИСах?
1)В современных плиса (я за ксайлинкс говорю/ у конкурента аналогично на 95% ) нет в чистом виде R/S-триггеров. НО D-триггер с R или S входом (асинхронные и синхронные относительно тактовой) есть и реализуемы. За другие виды триггеров вот так сходу не скажу - тк "по жизни" они в таком виде не требуются.
2) Про скважность я уже говорил - что можно, в плоть до отсутствия тактовой (статический уровень), есть ограничение на минимальное время полупериодов.
3) про " многопортовыми D-триггерами" я не понял... Это когда 8 бит шина "стробируется" одним сигналом тактовым ? ну дык хоть 512 бит можно сделать, да ещё и сброс на них завести при желании.
- - - Добавлено - - -
Насколь мне видится R и S сигналы в данной схеме формируются полюбому с привязкой к CLK, а посему здесь говорить о метастабильности неуместно. и в общем случае без разницы асинхр или синх будет триггер.
ПС: блин щаз запугаем ТС и он сорвётся с крючка ;-)
ТС - я не настаиваю на то чтоб вы вписывались в плисы, однако этот мир (плис) по своему прекрасен. и вовсе не обязательно всё знать - достаточно и 5% всего функционала (языка) использовать, чтоб творить "маленькие шедевры".
Barmaley_m
31.08.2024, 02:38
1)В современных плиса (я за ксайлинкс говорю/ у конкурента аналогично на 95% ) нет в чистом виде R/S-триггеров. НО D-триггер с R или S входом (асинхронные и синхронные относительно тактовой) есть и реализуемы. За другие виды триггеров вот так сходу не скажу - тк "по жизни" они в таком виде не требуются.
В целом согласен. Но опять же, для триггеров в Spartan-6 можно использовать либо только R, либо только S, но не оба одновременно. В 7-й и более старших сериях Xilinx входы R и S только синхронные, асинхронных нет. Если сильно нужен именно асинхронный RS-триггер - то его можно реализовать на комбинационной логике и другими трюками. Но обычно есть другие, более красивые решения. Лучше искать их.
Насколь мне видится R и S сигналы в данной схеме формируются полюбому с привязкой к CLK, а посему здесь говорить о метастабильности неуместно.
Не факт. Если сигнал R снимается по нарастающему фронту CLK - то как раз и реализуются благоприятные условия для метастабильности. Быть может, лишь задержка комбинационной логики позволит избежать риска.
ПС: блин щаз запугаем ТС и он сорвётся с крючка ;-)
Пускай учится сразу делать эффективные и надежные схемы! Предупреждение о типичных ловушках сэкономит ему много времени на отладку. Другие люди набивали эти шишки на своем, а не чужом, опыте.
ТС - я не настаиваю на то чтоб вы вписывались в плисы, однако этот мир (плис) по своему прекрасен
Я скажу более. "Вписаться" в плисы - это значит развить у себя навыки создания эффективных и надежных цифровых схем. Те ограничения, которые вводятся последними поколениями ПЛИС - это результат опыта предыдущих десятилетий. Что, например, асинхронные RS-входы нужны только в плохо спроектированных схемах, а хорошие схемы используют другие, синхронные, решения. И ограничения на асинхронность позволяют не только улучшить проект, но и получить более емкую ПЛИС, на которой этот проект будет работать. А когда проект отлажен и хорошо работает на ПЛИС - то можно (если за это кто-то готов заплатить) задуматься о синтезе собственной заказной микросхемы на основе тех же исходников на Verilog или VHDL.
- - - Добавлено - - -
Плат по типу Digilent Atlys надо ещё поискать (она кстати кажется на спартане6).
Да, она на Spartan-6. Но для целей эмуляции Спектрума хорошо пойдут и актуальные платы от Digilent:
- Basys 3. Там довольно большая Artix 7 FPGA, есть VGA-выход. Есть USB-интерфейс, но ему, скорее всего, потребуется современный 32-битный Softcore-процессор (не Z80). Но ресурсов там дофига, хватит и на 3 процессора. Цена 165$
- Arty Z7. Чип Zynq 7000, встроенный двухъядерный процессор ARM, 650Мгц. Хорошо пойдет для обслуживания периферии типа USB-клавиатур, мышей и флешек. 512Мб динамической памяти. Есть HDMI- вход и выход. Через HDMI можно, наверно, и выход звука реализовать. Или PWM. Цена $249
А плат со статической памятью вообще фиг найдёшь (конечно есть альтернативные решения).
Статической памяти в самой ПЛИС наберется около мегабайта. Вполне достаточно для эмуляции Спектрума на частоте процессора в 50-100 МГц.
- - - Добавлено - - -
Вот еще нашел плату: Alinx AX7035B. На борту Artix-7, HDMI In/Out, USB, Ethernet, 256Мб памяти. Цена - $132.
Что значит "многопортовыми"? Параллельные регистры с несколькими триггерами?
Нет, многопортовые - это вот:
https://pic.maxiol.com/images2/1725064551.2997899230.01z.png
- - - Добавлено - - -
Пускай учится сразу делать эффективные и надежные схемы! Предупреждение о типичных ловушках сэкономит ему много времени на отладку. Другие люди набивали эти шишки на своем, а не чужом, опыте.
Совершенно согласен.
Лучше уже нацелиться на самые-самые ограничения для всех ПЛИС, но зато сделать хорошо компилируемую и стабильную схему. Но для этого эти комплексные ограничения надо все знать.
- - - Добавлено - - -
Обозначение синхронного RS-триггера я нашел:
https://pic.maxiol.com/images2/1725064988.2997899230.imgjap1cw.png
А вот D-триггера, у которого есть еще синхронные RS-входы - нет.
- - - Добавлено - - -
Кстати, можно сказать, что большинство RS-триггеров в Z80 фактически синхронные. Просто я рисовал - отдельно базовый RS-триггер, и отдельно 2И элементы на входе со входами CLK для синхронного переключения. Можно было это сразу упаковать в синхронный RS-триггер.
Нет, многопортовые - это вот: https://pic.maxiol.com/images2/1725064551.2997899230.01z.png
А какова логика работы такого триггера?
Barmaley_m
31.08.2024, 10:21
А какова логика работы такого триггера?
Присоединяюсь. Мне из графического изображения непонятно, как он работает. Там по два входа D и C, но только один выход. Каким образом комбинируется информация в этом элементе схемы? Два триггера и логическая функция на их выходе? Или один триггер и логическая функция на его входе?
Логика очень проста.
При активном уровне на C0, данные с D0 защелкиваются на выходе.
При активном уровне на C1, данные с D1 защелкиваются на выходе.
И т.д. В схеме 4-х портовые триггеры даже есть.
Barmaley_m
31.08.2024, 11:06
При активном уровне на C0, данные с D0 защелкиваются на выходе.
При активном уровне на C1, данные с D1 защелкиваются на выходе.
А, так это еще и "прозрачный" триггер-защелка, у которого при активном уровне на C0 или C1 данные со входа на выход проходят постоянно?
Регистры-защелки в FPGA имеются (в Spartan-6 - точно), но их использовать не рекомендуется, по тем же причинам, что асинхронные входы R/S.
По твоему описанию логики работы, такой элемент реализуется в FPGA с помощью мультиплексора, логики и одного триггера. Мультиплексор пропускает на свой выход сигнал D0 или D1 в зависимости от состояния C0. Логический элемент "ИЛИ" объединяет C0 и C1 в сигнал разрешения записи в триггер. И, наконец, сам триггер (лучше всего D-типа, работающий от основной тактовой частоты). Получается синхронный элемент памяти, работающий близко к тому, что ты описал. Как его вписать в остальную схему, пойдет ли он там со своей синхронностью - это уже надо разбираться глубже.
А, так это еще и "прозрачный" триггер-защелка, у которого при активном уровне на C0 или C1 данные со входа на выход проходят постоянно?
Да
- - - Добавлено - - -
Регистры-защелки в FPGA имеются (в Spartan-6 - точно), но их использовать не рекомендуется, по тем же причинам, что асинхронные входы R/S.
Да, я уже отметил, что все триггеры работающие по уровню в для FPGA надо будет сначала переделать в работающие по фронту.
- - - Добавлено - - -
По твоему описанию логики работы, такой элемент реализуется в FPGA с помощью мультиплексора, логики и одного триггера.
Да, я так примерно и представлял.
- - - Добавлено - - -
Пробежался по текущей схеме, заменил RS-триггеры, у которых входы тактировались одинаковой полярностью (CLK или /CLK) на RCS-триггеры. А триггеры, у которых входы тактировались разными полярностями пока оставил как есть. Я думаю, самое главное, что в данной схеме все RS-входы в триггерах так или иначе синхронны с CLK или /CLK, поэтому проблем с синтезом у FPGA не будет.
В силу смены работы писал на Verilog очень давно, но вставлю свои "5 копеек". Для обучения мне очень помогло отвлечься от абстракций в виде электрических принципиальных схем на "рассыпухе", а вернуться к математическо-программистским корням, к дискретной математике и теории вычислительных процессов. А именно - к комбинаторике, графам, автоматам различных типов и их оптимизации. И вот это всё на Verilog перекладывается просто превосходно. То есть, не надо заниматься "синтезом" из логических и прочих элементов, надо заниматься математическим описанием (и оптимизацией) того, что надо сделать. А синтезом займётся сама среда типа Quartus (в конторе были Альтеры в почёте). Например, не надо рисовать схему какого-либо узла Z80 из логических элементов, надо рисовать её в виде графа, описывающего автомат. Со входом, выходом, состояниями, памятью и т.п. И его математическо-текстового представления, если надо. И оптимизация тут будет - вычислительная, в первую очередь. А оптимизацией синтезируемой логической схемы займётся софт.
Андрей, моё почтение! Реверс-инжиниринг процессора это титанические усилия. Пройти весь путь в обратном порядке: транзисторы -> логика -> математика...
Например, не надо рисовать схему какого-либо узла Z80 из логических элементов, надо рисовать её в виде графа, описывающего автомат.
Мне наиболее удобно привести схему сперва в классический логический вариант. Именно такую схему я могу быстро читать и понимать, когда она такая глобальная, как Z80. Ведь перевести на FPGA - это лишь попутная идея. Основная моя идея - это привести в наиболее понятный вид (логический), описать, найти нюансы, ошибки, особенности, понять принцип работы. А уже из этой точки можно и эмулятор потактовый делать, и FPGA, и т.д. Конечно я могу читать и понимать потранзисторную схему. Но уровень ориентирования в ней для меня гораздо ниже, чем в логической. Это все равно как сравнить си и ассемблер. Я вообще удивляюсь, как Vslav переводил в Verilog транзисторные схемы сразу, минуя логический этап. Мне такое неудобно. Поэтому все делаю последовательно, как мне понятнее. Сперва транзисторная, потом логическая, потом причесывания и понимание. А потом уже куда угодно можно двигаться. Да и другим понятнее она.
Логика очень проста.
При активном уровне на C0, данные с D0 защелкиваются на выходе.
При активном уровне на C1, данные с D1 защелкиваются на выходе.
И т.д. В схеме 4-х портовые триггеры даже есть.
Для RS/вот этих триггеров и ещё что там по схеме.
И отслеживать "запрещённые входные комбинации":
- либо гарантировать их отсутствие
- либо отслеживать доп. логикой с выводом на "лампочка авария"
- тд пт
ПС:соглашусь: latch крайне не рекомендуется к употреблению, но в плисе он реализуем физически.
Поэтому все делаю последовательно, как мне понятнее. Сперва транзисторная, потом логическая, потом причесывания и понимание. А потом уже куда угодно можно двигаться. Да и другим понятнее она.
А после причёсывания схемы из логических элементов напрашивается этап математико-логической модели. А уж из неё потом можно и эмулятор на любом языке. И синтезированная для FPGA выглядеть будет совсем не так, как реверс-схема процессора, но результат будет выдавать такой же.
По поводу защёлок - надо смотреть каждый случай. Как уже сказали, она реализуема физически. Но! Может быть, что в математический и verilog-модели этот элемент будет вообще лишним. Либо же будет являться элементом памяти конечного автомата, а многие FPGA имеют для этих целей скоростную внутреннюю память.
Почитал про Verilog. В общих чертах все понятно, и что такое always-блоки.
Правда, пока не понял, как задавать такой блок И для спада CLK, и для фронта.
И при этом, чтобы в блоке для фронта и спада делались разные действия.
Если мне память не изменяет, то в списке событий блока можно просто указать сигнал, и тогда блок будет "выполняться" при каждом изменении сигнала. Но если надо для фронта и для спада делать разные действия, то должно быть два always-блока с posedge и negedge. Но как сейчас это согласуется с современными ПЛИС - надо поинтересоваться у знающих людей. На "циклоне" синтезировалось без проблем, и каких либо ухудшений по тактовым частотам или по неопределённым состояниям не видел.
- - - Добавлено - - -
Опять же, FPGA - это синхронный дизайн. И идеальный путь, чтобы всё синхронизировалось по общему тактовому сигналу. Тогда минимум проблем будет.
Почитал про Verilog. В общих чертах все понятно, и что такое always-блоки.
Правда, пока не понял, как задавать такой блок И для спада CLK, и для фронта.
И при этом, чтобы в блоке для фронта и спада делались разные действия.
always-блок не может работать по фронту и спаду от одного и того же сигнала (в данном случае CLK). Только либо по фронту либо только по спаду.
https://www.asic-world.com/examples/verilog/flip_flop.html
always-блок не может работать по фронту и спаду от одного и того же сигнала (в данном случае CLK). Только либо по фронту либо только по спаду.
И реализовать мою задачу можно с помощью?..
И реализовать мою задачу можно с помощью?..
Несколько не понял вопроса.
155ТМ2 ни разу не работает по двум фронтам тактового сигнала и вроде на них собрано до фига и больше различных устройств. Я не вижу причин , которые однозначно не позволят реализовать "этот проект"
Несколько не понял вопроса.
155ТМ2 ни разу не работает по двум фронтам тактового сигнала и вроде на них собрано до фига и больше различных устройств. Я не вижу причин , которые однозначно не позволят реализовать "этот проект"
Разные действия, грубо говоря, означают разные логические функции. Следовательно должно быть два always блока.
always @(posedge clk) begin ... end
always @(negedge clk) begin ... end
Опять же, как оно синтезируется в соверменных FPGA, с учётом упрощения логических блоков, о котором вы упоминали...
Несколько не понял вопроса.
155ТМ2 ни разу не работает по двум фронтам тактового сигнала и вроде на них собрано до фига и больше различных устройств. Я не вижу причин , которые однозначно не позволят реализовать "этот проект"
Да все позволяет. Просто в одном блоке есть TM2, на которые заведен CLK, и есть TM2, на которые заведен /CLK. Удваивать частоту нельзя. Надо так и работать, чтобы часть триггеров по фронту переключалась, часть по спаду.
- - - Добавлено - - -
учётом упрощения логических блоков, о котором вы упоминали...
Что за упрощение?
Что за упрощение?
Вот тут (https://zx-pk.ru/threads/34173-revers-inzhiniring-z80.html?p=1203096&viewfull=1#post1203096) говорилось про отличия между поколениями Xilinx. Это уже мимо меня прошло.
Barmaley_m
31.08.2024, 21:06
... отвлечься от абстракций в виде электрических принципиальных схем на "рассыпухе", а вернуться к математическо-программистским корням, к дискретной математике и теории вычислительных процессов. А именно - к комбинаторике, графам, автоматам различных типов и их оптимизации. И вот это всё на Verilog перекладывается просто превосходно.... А оптимизацией синтезируемой логической схемы займётся софт.
Полностью абстрагироваться от железа и полностью полагаться на оптимизацию софтом - большая ошибка. С таким подходом получаются огромные и тормозные реализации в FPGA. Я видел множество примеров функциональных блоков от той же фирмы Xilinx, где такое вот абстрактное программирование раздувало потребление ресурсов кристалла сверх всякой меры.
Конечно, мышление в терминах логических схем плохо ложится на VHDL/Verilog. Но это объясняется тем, что VHDL/Verilog - это языки симуляции, а не описания логических схем. Их под роль описания приспособили насильно.
Из своего опыта могу сказать, что наилучшие результаты дает нахождение некоторого компромисса. Мыслить по-прежнему в логике, регистрах и мультиплексорах. Лишь некоторые сложные узлы, вроде конечных автоматов со сложной диаграммой переходов, можно оставить на синтез и оптимизацию софту, а самому придумывать их именно в виде конечных автоматов, а не логических схем, и напрямую описывать как автоматы на Verilog/VHDL.
Всегда нужно иметь в виду, какие у целевой ПЛИС есть ресурсы, как устроены логические блоки, как их можно настраивать, какие схемы хорошо на них лягут, а какие - плохо. И тогда получаются реализации, которые потом можно после синтеза проверить на уровне логической схемы и узнать в диаграмме свои задумки. И эти реализации получаются с малой затратой ресурсов и высоким быстродействием.
Я в начале, как учился разработке на FPGA, пытался все делать в виде логических элементов, регистров и т.п., полностью на уровне схемы. Сделал себе VHDL-блоки для регистров, счетчиков и т.п. с настраиваемыми параметрами, а далее вставлял их в "схему", т.е. VHDL-элемент более высокого уровня. Такой подход работал, но позже я понял, что он неэффективный в плане удобства разработки. И стал уже напрямую не вставлять в схему счетчики, а писать для них "процессы" или даже вставлять реализацию счетчиков в другие процессы, которые еще чем-то занимались. Получал на выходе синтеза те же самые схемы, но более лаконично описанные.
Да, перестройка мозгов нужна большая. Быстро она не происходит. Нужно просто браться за дело, от простого к сложному. Почаще контролировать результаты синтеза - какая получается логическая схема. И тогда со временем придет легкость и эффективность разработки.
- - - Добавлено - - -
Правда, пока не понял, как задавать такой блок И для спада CLK, и для фронта.
И при этом, чтобы в блоке для фронта и спада делались разные действия.
В твоем случае лучше всего иметь как минимум два разных always-блока, один для фронта, второй для спада. И выполнять в каждом из них соответствующие действия.
В Verilog или VHDL можно создать always-блок (или процесс), запускающийся и по фронту, и по спаду, и вообще по произвольным событиям. Но такой блок может быть затруднителен для синтеза схемы. Одно маленькое отличие логики внутри блока - и потребление ресурсов кристалла возрастет десятикратно. И триггеры будут реализовываться не на встроенных в кристалл триггерах, а на комбинационных схемах с обратной связью. И тому подобные аномалии. Лучше всего иметь только always-блоки по фронту или спаду, и никаких других.
Почитал про Verilog. В общих чертах все понятно, и что такое always-блоки.
Правда, пока не понял, как задавать такой блок И для спада CLK, и для фронта.
И при этом, чтобы в блоке для фронта и спада делались разные действия.
лучше так не делать, т.к. тактирование по фронту и по спаду - это два разных клока, поэтому схемы которые от них тактируются нельзя напрямую соединять - нужно синхронизировать.
Сама идея что Вы это хотите сделать подсказывает, что Вы чтото делаете неправильно. Вся схема должна тактироватьс от одного клока иначе не избежать проблем с асинхронностью и метастабильностью. Асинхронность по началу кажется ерундой, а не проблемой, но потом, когда сталкиваешься с проблемами из-за нее и пытаешься их решить приходит осознание почему дизайн должен быть синхронный...
тактирование по фронт и спаду от одного клока - это ОДИН клок. остальные рассуждения неверны для данной ситуации...
Сама идея что Вы это хотите сделать подсказывает, что Вы чтото делаете неправильно. Вся схема должна тактироватьс от одного клока иначе не избежать проблем с асинхронностью и метастабильностью.
Асинхронность - это когда возможны биения разных источников клока. А в данном случае это один и тот же клок, только разные его фазы, поэтому никакой асинхронности нет. Все строго синхронно.
Вообще, если нужно несколько синхросигналов разной частоты (а это частая ситуация), то для этого есть встроенный PLL. Фаза таких клоков всегда одинакова, кроме того, внутри плисины ещё и применяются специальные меры, чтобы, на этапе синтеза, можно было рассчитать задержку распространения синхросигналов по шинам.
Несколько раз переделывал схемы с малой интеграции и сталкивался с тем, что разработчики использовали трюки с асинхронностью и собственными задержками переключения логических элементов. Главным образом для экономии, или ещё какие спецэффекты хотели получить. А в FPGA это всё повторять смысла не имело, так как синтез по совсем другим правилам.
Асинхронность - это когда возможны биения разных источников клока. А в данном случае это один и тот же клок, только разные его фазы, поэтому никакой асинхронности нет. Все строго синхронно.
не совсем так. Я наблюдал типичные проблемы асинхронности при тактировании в двух always блоках от одного клока, но от разных фронтов. Это происходило для клока 100 МГц. Я не знаю точной причины почему это происходит, но подозреваю из-за того, что любой клок имеет джиттер и время между posedge и negedge плавает. Поэтому собственно говоря клок нужно на PLL генерировать, чтобы как можно точнее выдерживать 50% duty cycle, иначе из-за плавающего фронта может не хватить времени для переключения каких-то частей схемы. А за счет задержек клока от одной части кристалла до другой, вполне можно получить плавающие race conditions, несмотря на то, что оба always тактируются от одного клока, но от разных фронтов.
Если клок генерировать не на PLL, а каким-то счетчиком, как это делалось в наших ZX Spectrum клонах, то у такого клока будет заметный джиттер и это очень быстро приводит к проблемам, особенно если от клока тактируется большая схема занимающая почти весь кристалл FPGA.
Проявляются такие проблемы с клоком неприятно - всё может прекрасно работать до поры до времени, но в какой-то момент при внесении малейшего изменения (вплоть до изменения значения кода в табличке для FSM) приводящего к переразводке схемы, схема начинает сбоить.
И кстати, я большинство этих проблем наблюдал именно в ситуации использования двух always блоков от одного клока но по разным фронтам.
В FPGA есть еще проблема с тем, что если клок не сгенерирован на PLL блоке, то такой клок разводится как обычные сигналы, а для них в FPGA не предусмотрены меры по минимизации задержек. Clock сигналы имеют имеют отдельную шину, которая позволяет доставить клок в любую часть кристалла с минимальной задержкой или даже задать нужную задержку. Для минимизации задержек PLL блоки расположены с 4 сторон кристалла, что позволяет сократить путь clock сигнала от PLL к любой точке кристалла. Обычный сигнал превратить в клок невозможно, по крайней мере на Altera/Intel.
Использовать обычный сигнал в качестве клока технически можно, но это выливается в массу проблем - невозможно использовтаь такой клок для тактирования блоков предназначенных для клока, например таким клоком невозможно тактировать PLL блок. Это связано с тем, что клоки и обычные сигналы разводятся на разных шинах и у них нет прямой связи между собой. Ну и масса проблем с нестабильностью схемы будет вылазить.
Я наблюдал типичные проблемы асинхронности при тактировании в двух always блоках от одного клока, но от разных фронтов. Это происходило для клока 100 МГц. Я не знаю точной причины почему это происходит, но подозреваю из-за того, что любой клок имеет джиттер и время между posedge и negedge плавает. Поэтому собственно говоря клок нужно на PLL генерировать, чтобы как можно точнее выдерживать 50% duty cycle, иначе из-за плавающего фронта может не хватить времени для переключения каких-то частей схемы.
На таких частотах Z80 гонять особо-то не планирую.
Чтобы перейти на однополярное тактирование, надо сперва сделать двухполярное синхронное, и посмотреть, возможна ли переделка на однополярное БЕЗ ущерба полной идентичности оригинальному NMOS Z80. Если это окажется возможным, то я только за однополярное тактирование. Но если нет, то я по любому сделаю выбор в пользу полной идентичности оригиналу, чем погоне за возможностью запускать спек на 100МГц.
- - - Добавлено - - -
В FPGA есть еще проблема с тем, что если клок не сгенерирован на PLL блоке, то такой клок разводится как обычные сигналы, а для них в FPGA не предусмотрены меры по минимизации задержек. Clock сигналы имеют имеют отдельную шину, которая позволяет доставить клок в любую часть кристалла с минимальной задержкой или даже задать нужную задержку.
Полезная информация. Учту на будущее.
Но пока что, если не гоняться за предельными частотами, думаю, что проблем не должно быть.
- - - Добавлено - - -
Плюс, на сколько я понимаю, некоторым линиям (тому же CLK) можно задать параметр, что они должны трассироваться для самого короткого (быстрого) пути прохождения сигнала.
ZMAX местами не прав от слова совсем...
клок можно делать из чего угодно, но требуется выполнить ряд условий:
- оный клок должен быть описан в "временных ограничениях" (частота, скважность, фаза)
- должен использоваться только как "клок", но ни как обычный сигнал
- временами требуется явно указать что этот сигнал надо "разводить правильно"
ПС: отсутствие оных и других constrains - это основная ошибка "начинающих/любителей", а потом порождаются вот такие легенды
ПСПС: использование PLL приводит к не явному созданию "нужных ограничений" и посему совет использовать PLL приводит к желаемому результату.
- оный клок должен быть описан в "временных ограничениях" (частота, скважность, фаза)
Кстати, где это описывается и как?
Barmaley_m
01.09.2024, 13:41
Если клок генерировать не на PLL, а каким-то счетчиком, как это делалось в наших ZX Spectrum клонах, то у такого клока будет заметный джиттер
Вот не знаю. Я не вижу причин появления дрожания (джиттера) на выходе счетчика, если исходный тактовый сигнал не имел такого дрожания. Более того, даже делитель на 2 уже гарантирует 50% скважность, даже если исходный тактовый сигнал имел иную, или даже переменную, скважность. Опять же, при условии, что там не было дрожания нарастающего фронта.
Если же качество исходного тактового сигнала (в плане дрожания и скважности) вызывает сомнения - тогда да, тогда ФАПЧ (PLL) может в некоторой степени "очистить" тактовую частоту. Но у всего есть пределы. Если исходный сигнал совсем плохого качества - то не поможет и ФАПЧ.
Проявляются такие проблемы с клоком неприятно - всё может прекрасно работать до поры до времени, но в какой-то момент при внесении малейшего изменения (вплоть до изменения значения кода в табличке для FSM) приводящего к переразводке схемы, схема начинает сбоить.
Тут подписываюсь. Поскольку качество исходного тактового сигнала зачастую достоверно неизвестно - то инструменты синтеза не позволяют учесть все возможные отклонения. Также точность моделирования инструментов синтеза не 100%. Поэтому иногда появляются плавающие сбои даже в таких конфигурациях, синтез которых прошел без ошибок Timing Constraints.
В FPGA есть еще проблема с тем, что если клок не сгенерирован на PLL блоке, то такой клок разводится как обычные сигналы, а для них в FPGA не предусмотрены меры по минимизации задержек. Clock сигналы имеют имеют отдельную шину, которая позволяет доставить клок в любую часть кристалла с минимальной задержкой или даже задать нужную задержку.
На Xilinx таких проблем нет. Если какой-либо внешний или внутренний сигнал подается на тактовый вход триггера - то синтезатор автоматически пропускает его через глобальный тактовый буфер (BUFG), который рассчитан на большое количество нагрузок (много тактовых входов триггеров) и разводку с минимальной задержкой по всему кристаллу. Еще там есть локальные тактовые буфера (BUFH и т.д.), которые распределяют сигнал от BUFG на триггеры в локальной области чипа (напр. северозападный квадрант), но включение этих буферов полностью автоматизировано софтом для синтеза, в это лучше не вмешиваться.
Количество BUFG на кристалле очень ограничено. В моем чипе Spartan-6 их было 16 - это при десятках тысяч общего кол-ва триггеров.
Обычный сигнал превратить в клок невозможно, по крайней мере на Altera/Intel.
На Xilinx без проблем. Но на это расходуется ограниченный ресурс BUFG.
например таким клоком невозможно тактировать PLL блок. Это связано с тем, что клоки и обычные сигналы разводятся на разных шинах и у них нет прямой связи между собой. Ну и масса проблем с нестабильностью схемы будет вылазить.
Для сигнала на входе ФАПЧ важно обеспечить, чтобы этот сигнал был периодическим, с одним импульсом за период. Не допускать выпадений тактовых импульсов и тому подобной грязи. В противном случае ФАПЧ не сможет синхронизироваться с таким сигналом и достичь стабильной работы. Некоторое дрожание входного сигнала ФАПЧ сглаживает, но есть предел.
- - - Добавлено - - -
Кстати, где это описывается и как?
Для Xilinx - UG612 "Xilinx Timing Constraints User Guide"
Пробиться сквозь дебри этого документа непросто. Даю небольшой лайфхак.
Достаточно только задать в Timing Constraints параметры входного тактового сигнала. Синтезатор прослеживает распространение тактовой частоты по всей схеме, в том числе случаи умножения и деления этой частоты на блоках ФАПЧ (PLL) и DCM). Также синтезатор контролирует время прохождения обычных (не тактовых) сигналов через комбинационную логику и разводку связей и автоматически обеспечивает, чтобы это время не превышало периода тактовой частоты для всех сигналов. Поэтому, особенно для простых схем, лишь указание параметров входной тактовой частоты достаточно.
Дополнительные Timing Constraints нужно указывать только в следующих случаях:
1) Обеспечение гарантий на внешних интерфейсах ввода-вывода;
2) Прохождение сигналов между разными тактовыми зонами (между системами триггеров с разной тактовой частотой);
3) Деление тактовой частоты "вручную" с помощью счетчиков - тогда нужно указать, какое соотношение с входной тактовой частотой имеет выходная.
- - - Добавлено - - -
Плюс, на сколько я понимаю, некоторым линиям (тому же CLK) можно задать параметр, что они должны трассироваться для самого короткого (быстрого) пути прохождения сигнала.
Не совсем так. Трассировщик схемы по кристаллу FPGA может, конечно, дать наиболее короткие задержки каким-то сигналам. Но всем сигналам сразу самые короткие задержки дать нельзя: ведь они конкурируют друг с другом. Поэтому трассировщик пытается гарантировать максимально допустимое время задержки для всех сигналов. Для одних сигналов, где мало комбинационной логики, он при этом будет использовать менее быструю разводку и расположение, а для других сигналов, где заданную задержку обеспечить трудно - он будет использовать наиболее оптимальные расположения и разводку.
В конце своей работы (т.е. раскидывания логики по физическим ресурсам FPGA и разводки связей между ними) трассировщик либо сообщает, что он смог обеспечить заданные требования (напр. не более 10нс задержки для всех сигналов), либо не смог. В последнем случае приходится либо оптимизировать схему, либо снижать тактовую частоту.
Уточню. тов Barmaley_m даёт ссылки на документацию для среды ISE 14.7
Сиё достаточно подробно описывает про ограничения, но в более современной среде Vivado используется другой формат описания ограничений (*.UCF заменяется *.SDC). Но суть временных ограничений от этого не меняется.
На таких частотах Z80 гонять особо-то не планирую.
я такое поведение наблюдал и на 2 МГц. На меньших частотах вероятность поймать сбой ниже, на высоких частотах обычно сбой сразу видно, а на низких он может вылезти со временем. Это делает эту проблему еще более неприятной, т.к. прячет её до поры до времени.
Это самая неприятная вещь по сравнению с обычным программированием в котором состояние всегда детерминировано. На FPGA при использовании асинхронных конструкций начинаются приколы не токько с race conditions но и с метастабильностью.
ZMAX местами не прав от слова совсем...
клок можно делать из чего угодно, но требуется выполнить ряд условий:
Возможно на Xilinx это и так, но на Altera/Cyclone (например IV или 10) это точно не так. В них клок можно либо завести через специальный GPIO поддерживающий CLK (а таких GPIO немного), либо сгенерировав на PLL. Других вариантов сгенерировать клок на Altera/Cyclone нет, никакие хаки не не помогут - в чипе физически нет возможности пробросить обычный сигнал на шину клоков. А блоки которые имеют выход на шину клоков (типа PLL) невозможно затактировать от обычного сигнала, они тактируются только от клоков. При синтезе будет просто ошибка, даже если с синтаксисом все будет в порядке.
- временами требуется явно указать что этот сигнал надо "разводить правильно"
ПС: отсутствие оных и других constrains - это основная ошибка "начинающих/любителей", а потом порождаются вот такие легенды
я знаю про constraints и в описываемом случае они были подробно заданы. И как-раз меняя их я и игрался пытаясь обойти эти баги. Но в итоге пришел к тому, что использование подобных асинхронных конструкций приводит только к практически неустраняемым плавающим сбоям и от их использования лучше просто отказаться. Самое неприятное, что использование подобных конструкций может создать первое впечатление что всё работает, но проблемы обязательно вылезут позже...
Вместо того, чтобы вешать логику на разные фронты клока, я думаю более надежный и простой вариант - сгенерировать в два раза более высокочастотный клок на PLL и тактировать всё по одному фронту от одного клока.
ПСПС: использование PLL приводит к не явному созданию "нужных ограничений" и посему совет использовать PLL приводит к желаемому результату.
Нет, что касается Altera/Inter Cyclone IV и 10, там физическое ограничение - невозможно пробросить обычный сигнал на шину клоков. Физически нет таких соединений на кристалле. Отсюда и требование использовать либо клоковый пин либо PLL. Можно нагуглить статьи и app notes про это и именно там сказано что это невозможно физически. На форумах можно найти хаки как это якобы можно обойти, но они позволяют только обойти ошибки начального анализа. При синтезе всеравно вылезет ошибка.
Можете попробовать поиграться в Quartus - завести обычный сигнал в качестве клока на PLL. Гарантирую, для Cyclone IV и 10 у Вас это точно не получится, у них физически невозможно завести обычный сигнал на клоковый вход.
Вот не знаю. Я не вижу причин появления дрожания (джиттера) на выходе счетчика, если исходный тактовый сигнал не имел такого дрожания.
Клоковые сигналы и обычные разводятся физически на разных шинах и у обычных сигналов джиттер больше из-за особенностей FPGA. Кроме того невозможно обеспечить точные задержки для сброса и установки обычного сигнала, поэтому на выходе счетчика не будет 50% duty cycle. Поэтому если Вы используете оба фронта, то у Вас уже возникает проблема, т.к. длительность одного из полупериодов будет меньше и соответственно выше требование к максимальной частоте схемы которая тактируется одним из фронтов...
Более того, даже делитель на 2 уже гарантирует 50% скважность, даже если исходный тактовый сигнал имел иную, или даже переменную, скважность. Опять же, при условии, что там не было дрожания нарастающего фронта.
к сожалению не гарантирует. Более того, предсказать какой получится скважность нереально - это будет зависеть от разводки, поэтому малейшее изменение в коде может привести к изменению скважности и то что до этого работало перестаент работать и наоборот...
Скважность точно задать можно только на PLL. Более того, на PLL можно еще и точную задержку фазы указать.
На всякий случай кидаю сюда текущую версию потранзисторной схемы Z80. Она также, как и логическая, причесана частично, т.к. причесываются они одновременно. Но это очень близко к финальной версии. Скажем, на 90%. Схема полностью соответствует оригиналу NMOS Z80 без каких-либо изменений. Все причесывание заключается лишь в группировке блоков в понятном виде и подписывании линий.
NMOS Z80 - Transistor sketch rev 2.25.pdf (https://dropmefiles.com/ku0ED)
Я устал "бороться с ветрянными мельницами".
Titus - будут практические вопросы - спрашивайте (если надумаете связаться с плисами. Xilinx - максимальный ответ. Altera - по среднему отвечу (я у коллег консультируюсь)).
Не надумаете - то выложите схему, где работает текстовый поиск, а функциональные блоки обведены и подписаны + комментарий как работает тот или иной логический компонент (его логика поведения)
Я устал "бороться с ветрянными мельницами".
Много тут было полезной информации для меня по ПЛИСам, так что это не борьба, а интересная дискуссия)
Да, я сам ориентируюсь, если что, под Xilinx по советам разных людей.
В догонку... много интересного
https://www.chipverify.com/
Тадам! Выявил уже одну ошибку в логической схеме) И это неправильная полярность сигнала GRP_BRANCH. Продолжил рисовать теоретические диаграммы работы, и PC никак не загружается. Так и обнаружил ошибку. Не та полярность - это вообще самая ходовая ошибка при переписывании из транзисторной схемы в логическую. В транзисторной схеме, разумеется, этой ошибки нет. В ней накосячить можно только забыв нарисовать какой-то транзистор. Но полярность перепутать там нереально.
Кстати, ошибка полярности чаще всего не такая опасная, т.к. вылезает сразу же при практической или теоретической попытки моделировать схему.
Стандартный цикл выборки однобайтовой 4-х тактовой команды (без торможения памяти по WAIT):
https://pic.maxiol.com/images2/1725281593.531452783.z80commandfetchdiag.png
Замечу, что даже основные циклы не совсем совпадают с фирменной документацией по Z80. А именно - циклы T1-T4 смещены на пол-такта:
https://pic.maxiol.com/images2/1725282317.531452783.z80commandfetchbrie.png
Обозначения:
Если в ноере такта присутствует точка (T1.1 или T1.2), это означает, что имеется в виду 1-й или 2-й полутакт.
Номер полутакта может быть больше 2 вследствие прохождения сигналом промежуточных триггеров. Например, T1.3 обозначает третий полутакт от начала такта T1. Не смотря на то, что по времени он может совпадать с T2.1, правильнее обозначать его именно T1.3, т.к. он инициирован тактом T1.
В первом цикле любой команды в такте Т1.1 активны сигналы READ_PCR и SEL_PC, по которым регистр PC читается из регистрового файла и записывается в регистр PCR.
В такте T1.2 регистр PCR записывается в регистр адреса REG_ADR, содержимое которого выставляется на шину адреса AB0..15.
В этом же такте инкрементированное значение PCR записывается в регистр PCR2.
По переднему фронту такта T1.3 (T2.1) устанавливаются сигналы MREQ и RD, выдавая внешней схеме запрос чтения памяти.
Также в такте T1.3 (T2.1) происходит запись регистра PCR2 обратно в регистр PC.
По переднему фронту такта T2.2 устанавливается сигнал DP_DL, по которому данные с DB0..7 через шину DLATCH0..7 записываются в регистр REG_DATA.
По переднему фронту такта Т2.3 (Т3.1) устанавливается сигнал LOAD_IR, по которому данные с шины DBUS0.7 записываются в регистр команды REG_COMMAND. При этом в течение такта T2.3 (T3.1) на шине DBUS0..7 удерживается ноль.
Также в этом такте активны сигналы READ_PCR и SEL_IR, по которым регистр IR читается из регистрового файла и записывается в регистр PCR.
По переднему фронту такта Т3.2 снимается сигнал DP_DL, прекращая запись внешних данных в регистр REG_DATA.
В такте Т3.2 на шине DBUS0..7 появляется значение регистра REG_DATA и остается там до следующего такта T2.2.
Так же в этом такте данные с шины DBUS0..7 продолжают записываться в регистр REG_COMMAND.
Фактически фронт T3.2 - это момент защелкивания данных с шины DB0..7 в регистре REG_COMMAND.
Таким образом, с момента выставления сигнала RD и до момента защелкивания данных в REG_COMMAND отводится чуть менее 1.5 тактов.
В этом же такте регистр PCR записывается в регистр адреса REG_ADR, содержимое которого выставляется на шину адреса AB0..15.
В этом же такте инкрементированное значение PCR (инкрементируются младшие 7 бит) записывается в регистр PCR2.
В этом же такте сбрасывается сигнал MREQ.
По переднему фронту такта T3.3 (T4.1) сбрасывается сигнал LOAD_IR, прекращая запись регистра REG_DATA в REG_COMMAND.
В этом же такте происходит запись регистра PCR2 обратно в регистр IR.
В этом же такте устанавливается сигнал MREQ,
По переднему фронту такта T4.3 (T5.1) сбрасывается сигнал MREQ.
Таким образом, длительность цикла чтения - 1.5 такта (и более, если активен WAIT), длительность цикла регенерации памяти - 1 такт.
Похоже, подобные разборы не заходят) Буду иметь в виду)
Они полезны для понимания логики работы. но фанатов этого знания бесконечно мало...
:)
Они полезны для понимания логики работы. но фанатов этого знания бесконечно мало...
:)
Да, пожалуй, это интересно единицам)
Основному пользователю нужен или готовый эмулятор/симулятор, или хотя бы модель на верилоге)
Или интересные споры о методах разработки)
Когда я "смотрел" как работает oberon-cpu (oberonproject2013) - то конспектировал "мысли", нашёл несколько недокументированных вещей (хотя возможно, я где то не всё прочитал в оригинальной документации). Так что файлик с описанием "результата реверса" как оно работает - будет полезен по многим причинам...
ПС: сей "проект" заморожен в виду отсутствия времени...
конспектировал "мысли", нашёл несколько недокументированных вещей
Безусловно, какие-то еще никем не изведанные тайны в Z80 имеются. И чтобы их понять, недостаточно схему просто повторить. Ее надо изучить вдоль и поперек, понять все нюансы работы. Подвергнуть теоретическому стресс-тесту, не может ли в каких-то блоках найти коса на камень.
- - - Добавлено - - -
Обнаружилась очень интересная штука с константами.
В блоке констант не оказалось константы вектора прерывания 0x66. Только 0x00, 0x38 и 0x7F.
Оказывается, вектор с таким странным адресом 0x66 (как я думаю) появился потому, что 0x66 - это составная константа блока двоично-десятичной коррекции DAA. Там как раз имеется две половинки константы 0x60 и 0x06, которые корректируют старшую и младшую часть числа соответственно. И вот как раз они и используются в качестве вектора для NMI. Вот такая интересная экономия)
В блоке констант не оказалось константы вектора прерывания 0x66. Только 0x00, 0x38 и 0x7F.
Оказывается, вектор с таким странным адресом 0x66 (как я думаю) появился потому, что 0x66 - это составная константа блока двоично-десятичной коррекции DAA. Там как раз имеется две половинки константы 0x60 и 0x06, которые корректируют старшую и младшую часть числа соответственно. И вот как раз они и используются в качестве вектора для NMI. Вот такая интересная экономия)
а как инструкция DAA связана с обработкой NMI сигнала?
а как инструкция DAA связана с обработкой NMI сигнала?
Никак.
Но обе они используют константу 0x66. NMI для адреса обработчика прерываний, а DAA для коррекции результата.
Вот такая интересная экономия)
Всегда удивлялся, почему именно 0x66, а тут вон оно чё! :)
Всегда удивлялся, почему именно 0x66, а тут вон оно чё! :)
Я думаю, это далеко не последние интересности)
Стал разбираться, зачем же в блоке констант константа 0x7F, и оказалось, что она никогда не используется!
А точнее, скорее всего является рудиментом от лишнего транзистора в схеме выборки констант.
- - - Добавлено - - -
И еще из интересненького.
Блок быстрого 16-битмого инкремента/декремента, который в основном используется для инкремента PC и IR, также во всю используется многими другими командами.
Этот блок может считать +1, -1, а может вообще отменять инкремент, т.е. прибавлять 0. Где же это используется? Например, в команде LD SP,HL. А вы думали, почему она так быстро работает? Потому что пересылка осуществляется не двумя шагами по 8 бит каждый, а сразу 16 бит. А такую пересылку может осуществить только 16-битный блок инкремента/декремента. Кроме того, отмена инкремента используется в навороченной команде EX (SP),HL. Ну и в команде HALT и обработчиках прерываний, чтобы PC топтался на месте.
Ну, а декремент понятно, где используется. Это работа с записью в стек, это групповые команды LDD/CPD/IND/OUTD(R). Ну и всякие LDI/CPI.
- - - Добавлено - - -
Кстати, инкремент/декремент регистровых пар типа INC/DEC dd - этим тоже занимается данный блок. Поэтому инкремент такой быстрый, и поэтому он не влияет на флаги, т.к. блок АЛУ не задействован.
Barmaley_m
04.09.2024, 21:19
Похоже, подобные разборы не заходят) Буду иметь в виду)
Мне очень зашло! Жду следующих разборов, очень интересно!
Кстати, для построения временных диаграмм (в документе про анализ схемы "Орель БК-08") мне удалось удачно использовать симулятор VHDL. Я реализовал часть анализируемой схемы на VHDL, а потом просимулировал ее и включил результаты симуляции в документ. Тем самым решается сразу 2 задачи: защита от ошибок симуляции схемы "вручную"; получение VHDL-реализации этой же схемы, которая бы, в случае необходимости, заработала на FPGA.
защита от ошибок симуляции схемы "вручную"
Симуляция схемы вручную интересна тем, что позволяет лучше понять логику работы того или иного узла.
Ещё забавно будет для регистровой пары IR...
Ещё забавно будет для регистровой пары IR...
Что именно будет забавно для IR? )
Например, интересно, чем инкрементируется R (раз на флаги не влияет, то наверное не с помощью АЛУ), и почему именно 7 бит.
или я что то пропустил или IR инкрементируется той же схемой что и PC ?
Например, интересно, чем инкрементируется R (раз на флаги не влияет, то наверное не с помощью АЛУ), и почему именно 7 бит.
или я что то пропустил или IR инкрементируется той же схемой что и PC ?
Для тех, кто не прочитал мой обзор - говорю кратко)
Конечно тем же самым методом, что и PC)
Первые два такта команды - это выдача PC на шину и инкремент,
Следующие два такта команды - это выдача IR на шину и инкремент с ограничением до 7 бит.
Причем, даже описал, как происходит этот инкремент.
Сперва регистровая пара пересылается в регистр PCR, а затем уже инкрементированная пересылается в PCR2, а уже из него обратно в регистровый файл.
интересно было бы посмотреть циклограмму выполнения команд из DD/FD префикса
Поработаю оракулом: оные префиксы работают как однобайтные команды аля NOP
ПС: вот только как они взаимодествуют с INT NMI - надо "смотреть"
Поработаю оракулом: оные префиксы работают как однобайтные команды аля NOP
Я думаю, ZXMAK интересуют не префиксы, а циклы доступа к памяти по индексам)
- - - Добавлено - - -
ПС: вот только как они взаимодествуют с INT NMI - надо "смотреть"
Никак не взаимодействуют. Прерывания могут быть только после окончания выполнения команды.
- - - Добавлено - - -
Кстати, если кто-нибудь сидит на иностранных форумах, на которых обсуждают недокументированные особенности Z80 и всякие другие нюансы работы, киньте им ссылочку сюда.
- - - Добавлено - - -
Похоже, вот тут (https://stardot.org.uk/forums/viewtopic.php?t=15464) активно обсуждают баги Z80. Киньте им ссылку, если кто-то там зареган.
Стандартный цикл выполнения однобайтовой 4-х тактовой команды (без торможения памяти по WAIT):
Диаграммы (огромная простыня):
https://pic.maxiol.com/images2/1725706694.531453190.z80basediagram.png
Для сравнения взяты две команды: LD D,L и ALU A,L
В такте T3 всегда активен SEL_ACC.
В такте T3.2.3 (Т3.2/Т4.1) разрывается связь между шинами HBUS и LBUS
В этом же такте активен R_H, обьединяя шины REG.H и HBUS (для чтения регистра A).
(Для LD) В этом же такте активен R_L (т.к. REQ_FLAGS = 0), обьединяя шины REG.L и LBUS (для чтения регистра F).
(REQ_FLAGS = 0 означает, что предыдущая команда не меняла флаги, и надо загрузить флаги из регистра F).
По переднему фронту такта T3.3 (Т4.1) сбрасывается REQ_FLAGS.
В такте Т3.3 (Т4.1) активен SEL_AF (выбор регистра AF).
(Для ALU) В этом же такте активны сигналы RL_WR и WRITE_REG (т.к. REQ_FLAGS = 1), по которым содержимое флагов с линии LBUS записывается в регистр F.
В такте T4 активен SEL_REG_SRC, инициируя выбор регистра источника.
В такте T4.2.3 (T4.2/T5.1) активны сигналы R_L (работа с младшей половиной регистровой пары) и READ_REG.
В такте T4.3 (T5.1) активен сигнал SEL_HL по которому читается значение HL на шину REGBIT0..15, но на обе шины LBUS и HBUS попадает только младшее значение регистра - L, т.к. команда работает с младшей половиной регистровой пары (активен R_L, а не R_H).
Работа с АЛУ:
В такте T3 активен REQ_ALUB1, по которому в такте T3.2.3 (T3.2/T4.1) активен HBUS_TO_ALUBUS, по которому содержимое регистра A поступает на ALUBUS. А в такте T3.3 (T4.1) содержимое ALUBUS (регистр A) поступает на ALUB.
(Для ALU) В такте Т3 по SEL_ACC активен сигнал REQ_ALUA, по которому в такте T3.3 (T4.1) активен ALUBUS_TO_ALUA, по которому содержимое ALUBUS (регистр A) поступает на ALUA.
В такте T4 активен REQ_ALUB2, по которому в такте T4.2.3 (T4.2/T5.1) активен HBUS_TO_ALUBUS, по которому содержимое регистра L поступает на ALUBUS. А в такте T4.3 (T5.1) содержимое ALUBUS поступает на ALUB.
(Для LD) В такте T4.3 (T5.1) на шину ALUA принудительно выставляется 0.
В такте T4.3.4 (Т5) активен ALU_SEL_LOW. Таким образом на ALU подаются младшие 4 бита аргументов.
В такте T4.5.6 (Т6) не активен ALU_SEL_LOW. Таким образом на ALU подаются старшие 4 бита аргументов,
По спаду ALU_SEL_LOW (Т6.1) в регистре REG_ALU_LOW защелкиваются младшие 4 бита результата.
(Для ALU) По переднему фронту T1 (T5) устанавливается флаг REQ_FLAGS.
(Для LD) В такте T2 (T6) активны SEL_REG_DST и SEL_REG_DST_R, по которым в такте T6.3 (Т7.1) выбирается регистровая пара приемник DE (активен SEL_DE), а также активен RH_WR (запись в старший байт D) и WRITE_REG, по которым содержимое D записывается в регистровый файл.
(Для ALU) В такте Т2.3 (Т7.1) активны RH_WR, WRITE_REG и SEL_AF, по которым содержимое AF записывается в регистровый файл.
(Для ALU) В такте Т2.3 (Т7.1) устанавливается SET_PV_Z_S, по которому формируются флаги и защелкиваются в буферном регистре флагов.
(Для ALU) В такте Т3.2.3 (Т7.2/Т8.1) активен SEL_FLAGS по которому данные из буферного регистра флагов записываются на шину LBUS (биты 5 и 3 шины LBUS не меняются, на них остается предыдущее содержимое - значение регистра A).
(Для ALU) В такте Т3.3 (Т8.1) активны сигналы RL_WR и WRITE_REG (т.к. REQ_FLAGS = 1), по которым содержимое флагов с линии LBUS записывается в регистр F.
- - - Добавлено - - -
Описание работы ADD A,L и LD D,L простыми словами:
Пояснение: ALUA и ALUB - это два аргумента ALU.
В такте T4 регистровая пара AF всегда читается на шину HBUS/LBUS, независимо от кода команды, а содержимое регистра A на всякий случай загружается в ALUB.
Для ADD A,L в этом же такте регистр A загружается в ALUA.
В такте T5 регистр L загружается в ALUB (перезаписывая ранее загруженное значение A). А для команды LD D,L обнуляется значение ALUA.
В такте T6 на шине HBUS и LBUS (они в этом такте запараллелены) появляется значение результата работы ALU. Для ADD A,L - это A + L; для LD D,L - это 0 + L.
В такте T7 результат операции записывается с шины HBUS в регистр A (для ADD A,L), или в регистр D (для LD D,L). В этом же такте формируются флаги для ADD A,L в буферном регистре флагов.
Для ADD A,L в такте T8 флаги из буферного регистра флагов через LBUS записываются в регистр F (кроме битов 5 и 3, в которых сохраняется предыдущее содержимое, а имено значение регистра A). Надо заметить, что запись флагов в регистр F совпадает с чтением регистра AF следующей команды, и делается это одновременно.
Тадам! И по традиции, тема с подробным разбором не заходит)
- - - Добавлено - - -
Особенности работы команды NOP:
Не смотря на внешнее бездействие данной команды, внутренне проводится некоторая работа.
Как и во всех командах, вначале регистр флагов F кешируется, а регистр A засылается в оба аргумента АЛУ.
Далее, т.к. команда не использует аргументы, результатом работы АЛУ является A + A, но результат никуда не попадает.
Вот и все.
Команды LD I/R,A:
Не смотря на то, что большинство команд пересылок проходят через АЛУ (посредством сложения с нулем), есть группа команд, для которых сделаны специальные патчи, позволяющие модифицировать этот маршрут. Одна из таких команд LD I/R,A.
Команда выполняется (не считая префикса) за 5 тактов вместо 4. Это необходимо для того, чтобы приостановить конвейер выборки следующей команды и регенерацию памяти, освободив тем самым в 5-м такте доступ к дополнительному регистровому файлу, в котором расположен регистр IR.
В такте T4.2 содержимое ARGB (аргумент B), в котором находится только что загруженное значение регистра A выдается на HBUS в обход АЛУ.
В такте T4.3 (T5.1) активен SEL_IR, по которому в регистр I или R записывается значение регистра A с шины HBUS.
Интересно то, что 5..3 биты кода команды кодируют регистр, в который происходит запись точно таким же способом, как это делают команды, работающие с регистрами общего назначения. 010 - это регистр I, 011 - это регистр R. При этом сама информация о коде регистра используется лишь частично, а различие между I и R происходит по биту 3, как происходит выбор младшей и старшей части любого другого регистра общего назначения.
Также интересно, что на самом деле команда LD I/R,A работает даже быстрее (5 тактов), чем простая пересылка типа LD r1,r2 (7 тактов). Оставшиеся 3 такта АЛУ дорабатывает вхолостую.
Команда LD A,I/R:
Работа команды значительно отличается от ее антагониста LD I/R,A.
Прежде всего она заставляет АЛУ работать так, как если бы это была команда вида ADD A,r. За одним исключением, обнуляется аргумент A, как в командах LD r1,r2. Плюс, в 5-м такте конвейер приостанавливается на 1 такт, чтобы выбрать в качестве аргумента-источника регистр I или R из дополнительного регистрового файла.
Флаг P устанавливается как логическое ИЛИ флага V и IFF2. Но, благодаря тому, что арифметического переноса при прибавлении нуля к любому числу быть не может, мы получаем только значение IFF2. Все остальные флаги устанавливаются так же, как и при ADD, за исключением того, что не меняется флаг C.
Команда LD A,I/R:
вспоминается что " если прерывание произойдет во время выполнения этих команд, то в P/V будет 0 вместо 1"
вспоминается что " если прерывание произойдет во время выполнения этих команд, то в P/V будет 0 вместо 1"
Я думаю, что сама команда в этом не виновата, т.к. 'тупо' считывает состояние IFF2. Это надо смотреть блок прерываний.
Обновленная текущая версия черновика реверса.
* Исправлено несколько ошибок (как и ожидалось, все связанные с полярностями сигналов).
* Полностью избавился от проходных ключей (проходные регистры на шинах пока остались).
* Много оптимизаций, переработок, перегруппировок блоков.
* Много новых распознанных и подписанных линий и функций.
* Повышена четкость надписей увеличением DPI в два раза)
p.s.: Замечу - это полный реверс. Вся текущая работа над ним связана лишь с распознаванием, подписыванием, пониманием, причесыванием. Так что сохраните себе на всякий случай, на файлообменнике он лежит 14 дней.
NMOS Z80 - sketch rev.20.pdf (https://dropmefiles.com/D6uxZ)
Команды сдвигов:
С ними все просто.
В такте T4 запрещается стандартная передача значения регистра с HBUS на ALUBUS, но включается специальная передача с HBUS на ALUBUS через сдвиговый регистр либо BUF_SHIFT_LEFT, либо BUF_SHIFT_RIGHT. Т.е. значение регистра попадает в аргументы АЛУ уже сдвинутое. Далее происходит все тоже самое, что и при команде LD. К значению регистра прибавляется ноль, и заносится обратно в регистр, только с влиянием на флаги.
Еще одна интересная находка.
Стал разбирать простые команды вида LD (HL/DE/BC),r, и сперва попал в ступор. В цикле M2, который следует после цикла M1 нет записи в память! Я уж и так, и сяк ищу. Нет и все. Но ведь всем известно, что за девятым вагоном сразу идет десятый циклом M1 сразу идет цикл M2. Оказалось, что нет. Для некоторых команд (и в том числе для вышеописанных) за циклом M1 сразу идет цикл M4. А потом M5, если понадобится. А вот в цикле M4 запись в память как раз и есть.
Скажем еще раз 'пока' фирменным документациям)
Lethargeek
10.09.2024, 14:27
Скажем еще раз 'пока' фирменным документациям)
каким именно? например, в юзермануале официальном вообще нету буквосочетаний M3 и M4 (а M2 только в составе IM2)
каким именно? например, в юзермануале официальном вообще нету буквосочетаний M3 и M4 (а M2 только в составе IM2)
Наша русская: 'Z80 Central Processor Unt" - справочное пособие.
Я считал ее переводом с чего-то иностранного. Не с потолка же они все написали)
HardWareMan
10.09.2024, 15:43
Еще одна интересная находка.
Стал разбирать простые команды вида LD (HL/DE/BC),r, и сперва попал в ступор. В цикле M2, который следует после цикла M1 нет записи в память! Я уж и так, и сяк ищу. Нет и все. Но ведь всем известно, что за девятым вагоном сразу идет десятый циклом M1 сразу идет цикл M2. Оказалось, что нет. Для некоторых команд (и в том числе для вышеописанных) за циклом M1 сразу идет цикл M4. А потом M5, если понадобится. А вот в цикле M4 запись в память как раз и есть.
Скажем еще раз 'пока' фирменным документациям)
Как именно считать циклы это всего-лишь вопрос перспективы. У ВМ80 номера циклов исходят от безусловности счётчика. Как это сделано в Z80?
Как именно считать циклы это всего-лишь вопрос перспективы. У ВМ80 номера циклов исходят от безусловности счётчика. Как это сделано в Z80?
И тут стоит 'безусловный счетчик', который шагает от цикла M1 до M5. Но при определенных условиях может перескакивать сразу с M1 на M4, как оказалось. (кому я выкладываю схему реверса в PDF'ах? Все же там как на ладони, и счетчик M-циклов тоже)
Lethargeek
10.09.2024, 17:51
Я считал ее переводом с чего-то иностранного. Не с потолка же они все написали)
почему бы нет, отсебятиной многие грешат
И тут стоит 'безусловный счетчик', который шагает от цикла M1 до M5. Но при определенных условиях может перескакивать сразу с M1 на M4, как оказалось. (кому я выкладываю схему реверса в PDF'ах? Все же там как на ладони, и счетчик M-циклов тоже)
а с чего ты взял, что условные обозначения чего бы то ни было в описаниях снаружи видимой логики обязательно соответствуют каким бы то ни было внутренним значениям и процессам
почему бы нет, отсебятиной многие грешат
Этого нельзя придумать самим. Они действительно описывают пять M-циклов, и их в реальности в процессоре действительно 5.
Я думаю, что писали по какому-то иностранному описанию. Иначе и быть не могло.
А в описании наверное что-то упрощенно было описано. Без перескоков с M1 на M4. Потому что для всех остальных команд циклы действительно идут последовательно.
HardWareMan
10.09.2024, 19:58
И тут стоит 'безусловный счетчик', который шагает от цикла M1 до M5. Но при определенных условиях может перескакивать сразу с M1 на M4, как оказалось. (кому я выкладываю схему реверса в PDF'ах? Все же там как на ладони, и счетчик M-циклов тоже)
Я не горю желанием нырять в этот нужник. Мне достаточно краткого суммари от "человека в теме". Спасибо.
Lethargeek
10.09.2024, 20:43
Этого нельзя придумать самим.
чего "этого"? тупо нумерацию продолжить после единицы нельзя самим?
Они действительно описывают пять M-циклов, и их в реальности в процессоре действительно 5.
а байтов на инструкцию максимум 4 - ичо?
- - - Добавлено - - -
это я к тому, что доки пишутся на внешние сигналы, а внутри могло же быть что угодно, хоть обратный счётчик или код Грэя))
HardWareMan
10.09.2024, 20:52
это я к тому, что доки пишутся на внешние сигналы, а внутри могло же быть что угодно, хоть обратный счётчик или код Грэя))
Соглашусь. Условному пользователю не нужно знать, как работает чёрный ящик внутри. Достаточно описать как он будет себя вести снаружи. Что в доках и делают. Тем более, что внутренние методы могут быть объектом авторского права и/или секрета.
чего "этого"? тупо нумерацию продолжить после единицы нельзя самим?
Куда-то у нас не туда зашел спор)
Я придерживаюсь мнения, что наша русскоязычная книжка была основана на каком-то иностранном мануале. Но на каком, не знаю, не изучал.
Стандартный цикл выполнения однобайтовой 4-х тактовой команды (без торможения памяти по WAIT):
Диаграммы (огромная простыня):
https://i.imgur.com/o8PgEEs.png
Для сравнения взяты две команды: LD D,L и ALU A,L
а где тут сигнал M1? чтото не нахожу...
а где тут сигнал M1? чтото не нахожу...
PORT_M1, это если ты про внешний пин.
А если про цикл M1, то он постоянно активен в данном примере, т.к. команда занимает 4 такта.
Вот интересно было бы посмотреь как M1 устанавливается сбрасыватеся для длинных инструкций.
Вот интересно было бы посмотреь как M1 устанавливается сбрасыватеся для длинных инструкций.
Очень просто. Устанавливается всегда в такте M1.T1.2, а сбрасывается в T3.2 или же по BUSRQ.
Длинная инструкция - это с префиксом? В каждом байте выборки префикса устанавливается, т.к. это циклы M1.
Опять лирическое отступление на тему ПЛИС.
Как устроены у современных ПЛИС RS-входы у D-триггеров? Эти входы тоже синхронны с CLK, либо же вход D работает синхронно, а входы RS асинхронно?
Xilinx 7 семейство Физическая реализация
Триггеры:
FDCE Primitive: D Flip-Flop with Clock Enable and Asynchronous Clear
FDPE Primitive: D Flip-Flop with Clock Enable and Asynchronous Preset
FDRE Primitive: D Flip-Flop with Clock Enable and Synchronous Reset
FDSE Primitive: D Flip-Flop with Clock Enable and Synchronous Set
Защёлки (не рекомендуется использовать, но они есть в наличии).
LDCE Primitive: Transparent Data Latch with Asynchronous Clear and Gate Enable
LDPE Primitive: Transparent Data Latch with Asynchronous Preset and Gate Enable
Сиё взято из документа: UG768 "Xilinx 7 Series FPGA and Zynq-7000 All Programmable SoC Libraries Guide for HDL Designs UG768 (v14.7) October 2, 2013"
FDCE Primitive: D Flip-Flop with Clock Enable and Asynchronous Clear
FDPE Primitive: D Flip-Flop with Clock Enable and Asynchronous Preset
FDRE Primitive: D Flip-Flop with Clock Enable and Synchronous Reset
FDSE Primitive: D Flip-Flop with Clock Enable and Synchronous Set
А каких больше триггеров, с асинхронным или синхронным R/S?
есть универсальный приметив ТРИГГЕР. в зависимости от того как он сконфигурён (при загрузке плисы) тем он и будет.Пример: есть 100 триггеров всего из них одновременно можно сделать
1 FDCE и 99 FDRE
а можно
по 25 штук каждого.
Интересно, как мне обозначать в схеме триггеры, у которых не только D синхронный, но и RS.
Потому что сейчас триггеры с асинхронным RS обозначаются так:
https://pic.maxiol.com/images2/1726047326.531452988.01xxx.png
ХЗ. Наверно для синхронного : D C R входы объединять в одном прямоугольнике, а если асинхронный R вход - то примерно как в 155ТМ2 (в отдельном прямоугольнике).
ПС: к сожалению (для нас) и к радости (инженеров) в плисах нет триггеров с R и S входами одновременно. и всегда есть D и C.
ПС: к сожалению (для нас) и к радости (инженеров) в плисах нет триггеров с R и S входами одновременно. и всегда есть D и C.
А как же синхронные RS-триггеры? Их тоже нет?
Выше перечислен базис примитивов. На основе оных и доп. логики формируются все остальные "интимные фантазии" инженера... с той или иной точностью поведения
ПС: на практике в 99,9999% случаях ни кто не заморачивается с использованием примитивов напрямую (за исключением специализированных примитивов). Просто пишется описание требуемого поведения схемы на языке HDL - если написано реализуемая схема - то получаем прошивку, а если нет - то упрощаем описание...
Применение примитивов это как Асм вставки в СИ языке.
Ок. Значит буду писать на Verilog с расчетом, что все триггеры синхронные, и RS входы тоже синхронные. А трассировщик сам уже разберется. Естественно, прослежу, чтобы R и S не могли устанавливаться одновременно.
HardWareMan
11.09.2024, 14:55
Titus, а почему Z80 опкод защёлкивает по спаду такта, а данные (аргументы и прочее) по фронту (так же, как и ВМ80)? С чем связано такие различие в циклах внешней шины?
Titus, а почему Z80 опкод защёлкивает по спаду такта, а данные (аргументы и прочее) по фронту (так же, как и ВМ80)? С чем связано такие различие в циклах внешней шины?
До чтения аргументов из памяти еще не дошел. Как дойду, расскажу.
А вот до записи в память дошел уже на примере базовых команд типа LD (dd),r.
Интересно, что все 3 последних такта команды (цикл M4) посвящены записи байта в память.
Причем, цикл записи длится значительно дольше (2.5 такта после выставления адреса), чем цикл чтения (1.5 такта после выставления адреса).
Не знаю, с чем это связано. Может считалось, что на заре компьютеров запись в память происходила медленнее, чем чтение?
Думаю, если бы на запись отвели не 2.5 такта, а 1.5, как и на чтение, то такие команды, как LD (dd),r занимали бы 6 тактов, а не 7.
Titus, а почему Z80 опкод защёлкивает по спаду такта, а данные (аргументы и прочее) по фронту (так же, как и ВМ80)? С чем связано такие различие в циклах внешней шины?
Это связано с тем, что цикл чтения кода операции короче (1.5 такта), чем цикл чтения данных (2 такта). Поэтому и завершаются они в разных полутактах. А цикл чтения кода операции короче, как я думаю, из-за того, что в 4 такта надо было упихнуть и цикл чтения кода операции, и цикл регенерации памяти. На каждый из них пол-такта на установку адреса, и 1.5 такта на чтение. А в цикле чтения данных такого ограничения нет, поэтому, цикл и длиннее. Он мог бы быть 2.5 такта, но еще нужно пол-такта, чтобы сохранить результат, поэтому он длится 2 такта.
- - - Добавлено - - -
Кстати, вот еще одна веская причина при реализации на ПЛИС, по которой нельзя отказаться от тактирования внутренних блоков по фронту CLK, и по спаду. Раз даже внешние события могут происходить и по фронту, и по спаду CLK.
Не сходиться с ld a, (hl)
Не сходиться с ld a, (hl)
Поточнее, что именно и с чем не сходится?
Твои слова с 6 тактами
- - - Добавлено - - -
Ты пишешь что чтение 1.5 тактов, а запись 2.5. и если бы запись была бы как чтение то команда ЛД (хл),а исполнялась 6 тактов, мб если ЛД а, (хл) исполнялась за 6, но нет она тоже исполняется за 7
Похоже, вот тут активно обсуждают баги Z80. Киньте им ссылку, если кто-то там зареган.
https://stardot.org.uk/forums/viewtopic.php?p=433901#p433901
HardWareMan
12.09.2024, 10:24
Ты пишешь что чтение 1.5 тактов, а запись 2.5. и если бы запись была бы как чтение то команда ЛД (хл),а исполнялась 6 тактов, мб если ЛД а, (хл) исполнялась за 6, но нет она тоже исполняется за 7
Верно, Z80 данные данные пишет и читает одинаково, в итоге 3 такта. Разница лишь в чтении опкода. Вот без учёта тактов ожидания:
https://i.postimg.cc/mk5rqb8V/image.png
PS Извините, запамятовал и перепутал фазы. Чтение опкода по фронту, чтение/запись данных по спаду. Инверсия от F2 ВМ80.
Твои слова с 6 тактами
Ты пишешь что чтение 1.5 тактов, а запись 2.5. и если бы запись была бы как чтение то команда ЛД (хл),а исполнялась 6 тактов, мб если ЛД а, (хл) исполнялась за 6, но нет она тоже исполняется за 7
Это цикл чтения кода команды 1.5 такта. А цикл чтения данных 2 такта. Плюс пол-такта на запись результата в регистр. Цикл записи 2.5 такта, но эти последние пол-такта - это удержание данных на шине уже после снятия MREQ, чтобы сперва снимался MREQ, а потом данные. Итого, и LD A,(HL), и LD (HL),A выполняются за одинаковое время, за 7 тактов, с учетом дополнительных расходов.
Я все прекрасно понимаю, я лишь указал что в твоей логике прикол. Но ты его не увидел, по этому ладушки поехали дальше
Полистал книжечку по Verilog'у.
Чета вообще все просто, если не использовать ненужные навороты.
Соедени все линии assign'ом, поставь always-блоки на фронты тактирования, все.
Язык выглядит абсолютно простым.
Главное перевести всю схему с полностью синхронный формат сперва, что я попутно и делаю,
пока что на 100% сохраняя логическое соответствие оригиналу.
Но все равно в итоге придется уходить от Z-шин и проходных регистров, обьединяющих несколько шин.
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot