Нет смысла делать двойную работу.
Вид для печати
Малость теории.
1) В плисах есть два типа сигналов: дата и тактовый. они разводятся каждый по своим дорожкам. Дата условно "абы кабы". Тактовый по своим "чтоб тактовый был там где надо вовремя" (очень условное описание). Дата - потому что длина цепей относительно мала, а тактовые по всей плисе на тысячи триггеров "одновременно".
2) К примеру асинхронный счётчик на Д-триггере
https://studfile.net/html/2706/245/h...img-7f5rW6.png
его быстродействие равно длительности распространения от первого C до последнего Q. Пока сигнал "бежит" - выход счётчика может принимать все фантастические значения. А если по этим выходам формируются "обратные связи" на эти же триггера - результат вообще не предсказуемый.
Посему делают только синхронные счётчики - это на С поступает только тактовый сигнал. на Д - через "внешнюю логику, описывающую поведение счётчика".
Другой случай когда на тысячу триггеров заводят "тактовый с выхода Q" - а так как он будет разводится абы кабы (однако есть способы как сделать более правильно - но это будет "грязно выглядеть") - то и поведение такой схемы будет "очень волшебным", а быстродействие упадёт на порядок другой...
Сиё максимально упрощённое описание...
ПС: Особый кайф, это когда берут выход условной К155ЛР3 и подают на С-вход. Пока логика устаканится - выход 100500 раз поменяет своё значение - а триггер (или даже синхронный счётчик) всё ЭТО посчитает... 8-0
AlexG, всё верно. И именно поэтому надо смотреть в условный TimeQuest на Clock Skew или хотя-бы Fmax чтобы понимать, что фиттер положил насинтезированное так, что задержки укладываются в твой такт. Тогда проект будет работать на всех указанных тобой чипах в любых условиях, а не глючить в зависимости от фазы луны и желанию твоей левой пятки.
https://i.postimg.cc/zfkj5k7Q/image.png
Побольше синих и отсутствие красных. И ещё, если попытаешься комбинаторику в такты зарулить без правильного преобразования оно тебе прокричит про ripple clock.
Есть несколько методов разного рода, когда действительно надо сформировать вторичный тактовый домен. Например, синхронизация через общую тактовую частоту. Но чаще проще просто оставаться в одном тактовом домене используя условия. Тогда при правильном описании синтезатор сам вместо муксов заюзает специальный сигнал ENA.
https://i.postimg.cc/CxPShJpQ/image.png
PS В самом примитивном варианте, такты должны выходить из триггера. Точка.
В общем, что касается правильного тактирования схемотехнически, мне все более-менее понятно.
В плане реализации этого на Verilo'е могут быть вопросы, но это спрошу, если понадобится.
п.с.: Никто так и не заметил, что я накосячил, и случайно обьединил все 8-битные половинки регистров в 16-битные, из-за чего нельзя записывать половинки) Ну да, кому нужны схемы-то) Всем нужна готовая модель или эмулятор) Или какие-то вскрытые тайны и особенности простым языком)
такие вещи взглядом не заметишь. Это как программа написанная, но ни разу не скомпилированная. Смотришь вроде все правильно, а начнешь компилировать и дебажить и вылезут ошибки.
Однозначно второй вариант. По возможности надо делать так, чтобы все триггеры схемы тактировались одной частотой. Если какие-то части схемы работают на половине или других долях от этой частоты - то следует использовать вход триггеров Clock Enable (CE), описав его на HDL в виде команды if, наподобие твоего второго варианта, для достижения поставленной цели.
Деление тактовой частоты триггером и использование результата для тактирования какой-то части схемы имеет следующие недостатки:
1) Расходуются глобальные тактовые буферы (в примере Spartan6 - BUFG)
2) Поделенная тактовая частота будет из-за задержек элементов схемы и разводки выхода триггера на тактовый буфер и обратно сдвинута по фазе относительно исходной. Эти сдвиги затронут также все сигналы от триггеров, работающих от половины тактовой частоты. Все эти задержки будут отниматься от "бюджета времени" при переходе сигналов данных от триггеров, тактируемых полной тактовой частотой, на триггеры, тактируемые ее половиной, и обратно. В результате будет труднее обеспечить выполнение Timing constraints, снизится максимальная тактовая частота проекта.
До того, как Hardwareman про это написал, я не знал, что у триггеров в ПЛИС есть входы разрешения тактирования. Так-то оно конечно, логичнее. Другой вопрос - на всех ли современных ПЛИС у триггеров есть входы CE?
- - - Добавлено - - -
Сколько их в среднем бывает?
И прям на каждый клок триггера расходуется свой буфер, если клок не совпадает с уже имеющимися?
- - - Добавлено - - -
Вот в этом примере что, на каждый следующий каскад расходуется глобальный тактовый буфер?
https://studfile.net/html/2706/245/h...img-7f5rW6.png
1) У всех xilinx ( упоминал ранее UG768 v14.7) есть CE у триггеров.
2) К примеру плиса о 200 выводов 53200 LUT (универсальная логика) + 106400 FF (триггера) имеют всего 32 BUFG (глобального буфера для распределения тактовой).
3) зависит от настроек "компилятора" (наверное - я такое не практикую от слова совсем. посмотрел один раз на результат - ужаснулся, перекрестился, сплюнул три раза и зарёкся ТАК делать).
ПС: не надо заморачиваться специально про СЕ. Достаточно писать
always @(posedge clk) begin
if (T1 == 1) begin
....
синтезатор "сам придумает" схему как сделать лучше (через СЕ или через комбинационную схему или ...). Конечно есть специальные "указания/прагмы/аттрибуты" которые указавают КАК хочется автору (но это надо иметь экспириенс от 58).
----------------------------------------
Триггеры:
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
"каждый следующий каскад расходуется глобальный тактовый буфер?" - наверно зависит от настроек "компилятора" .
НО Я ТАК НИКОГДА НЕ ДЕЛАЮ (как на рисунке) - за это пожизненный эцих с гвоздями.
В общем и целом я полностью согласен - один законченный IP блок должен быть запитан от одной тактовой частоты, чтобы однозначно уложить его в прогнозируемые тайминги. Но бывают случаи, когда просто необходимо разделять тактовые домены. Например, из самого редкого это вот такой, есть у меня в модуле работы с FT245R:
https://i.postimg.cc/TYKcwmTw/image.png
Он собирается вот так:
https://i.postimg.cc/DyRPbZzc/11.png
https://i.postimg.cc/jSNQ6bwY/22.png
Смысл: использование nRD как такты для регистра хранения данных на шине данных гарантирует наличие актуальных данных в самый последний момент, как того гласит датащит. То же самое касается и сэмплирования сигнала TDO у JTAG: его следует синхронизировать именно к результирующему TCK, который по факту выходит наружу.
Ну и в конце концов разные IP могут работать на разных тактовых частотах, чтобы сэкономить несколько регистров и PIA, например. Поэтому, нужно просто подходит с умом и осознанно. С учётом синхронизации сигналов при переходе в другой тактовый домен. Ну а что касается вышеупомянутого асинхронного счётчика то это не для ПЛИС. Забудьте про 555ИЕ5, 555ИЕ10 должен быть ваш выбор.
32 BUFG - это еще много. По-моему вся серия Spartan6 имеет только 16 BUFG. Но это не такое страшное ограничение, как может показаться. Даже в крупных проектах хватает за глаза. Не надо только без серьезной необходимости тактировать триггеры разной частотой.
В моем большом проекте использовались следующие крупные области с разной тактовой частотой:
1) Процессор и основная периферия, а также внутренние шины - 80 МГц
2) Спец интерфейс - 960МГц (самые внешние его блоки ISERDES2), а связанная с ними FPGA-логика - 120МГц
3) Ethernet MAC (та его часть, которая непосредственно связана с интерфейсом GMII) - 125МГц
Если бы я использовал интерфейс HDMI - то там бы была еще область 1080МГц (для ISERDES2/OSERDES2). и 135МГц для "нормальной" связанной с этим FPGA-логики.
В том чипе, с которым я работал, частоту выше 80МГц для основной схемы использовать не удавалось - ругался компилятор из-за расхождения Timing Constraints. На относительно высоких частотах в моем проекте (120 и 125МГц) работали только небольшие части всей схемы, где данные частоты были обусловлены требованиями к интерфейсам ввода-вывода.
Перепад ловится обычным синхронизатором:
https://i.postimg.cc/FHL81xsN/image.png
Понятное дело, что CLK должно быть как можно выше, скорости смены уровней на DAT. Фронт или спад ловится соответствующим заданием инверсии у логического И.
из интересного
- - - Добавлено - - -
форум это очень медленно, мне нужна оперативность общения, по теме но в большей степени, в любом случае печально это видеть
про "специальный RESET" лет 10 как известно, даже в эмуле есть. В специальном.
Вот кратенько по годам, что-когда раскопали:
* 2006 - [MEMPTR](https://zxpress.ru/zxnet/zxnet.pc/5909)
* 2012 - [Q: Zilog](https://worldofspectrum.org/forums/discussion/41704)
* 2014 - [Special Reset](https://github.com/redcode/Z80/wiki/Z80-Special-Reset)
* 2018 - [Additional flag changes of the block instructions](https://github.com/hoglet67/Z80Decod...cumented-Flags)
* 2018 - [Q: NEC / ST](https://github.com/hoglet67/Z80Decod...cumented-Flags)
* 2021 - [`reti` and `retn` reject INT when IFF1 != IFF2](https://floooh.github.io/2021/12/17/...n-instructions)
* 2022 - [MEMPTR during the additionaal flag changes of `otir` and `otdr`](https://github.com/hoglet67/Z80Decoder/issues/2)
* 2022 - [NMI rejection](https://spectrumcomputing.co.uk/foru...pic.php?t=7086)
* 2023 - [MEMPTR during the additional flag changes of all I/O block instructions](https://spectrumcomputing.co.uk/foru...ic.php?t=10555)
* 2024 - [Unstable flag behavior of `ccf` / `scf`](https://github.com/hoglet67/Z80Decod...-SCF-Behaviour)
Никуда я полезать не собираюсь)
- - - Добавлено - - -
Я выкладываю фрагменты диаграмм и описаний для привлечения внимания интересующихся лиц.
И для того, чтобы люди могли ознакомиться в ОБЩЕМ, как процессор работает.
А диаграммы работы всех команд я составлять не собираюсь)
Основная проблема подобных проектов - это то что автор зачем-то пытается "понять" как оно работает. Это является основным тормозом, в результате чего проект может длиться годами. Так и у нас было.
Но потом оказалось что достаточно получить netlist, а понимать вовсе не обязательно. Ведь полученные результаты рано или поздно захотят практического применения (программный эмулятор / HDL реализация), а если делать точно, то оно и будет работать как исходная схема и то что ты "понял" как оно работает никакой пользы не доставит. Главное понимать как в целом логика работает - основные приёмчики, подходы к реализации (регистры, счётчики, автоматы), а распутывать лапшу комбинаторно-последовательной логики это бессмысленно и беспощадно. Но не могу запретить автору продолжать, читаем с интересом.
Я люблю понимать суть процессов)
Без точного понимания невозможно с материалом ничего сделать интересного. Только клонировать, да и там можно ошибиться, именно из-за того, что не понимаешь нюансов.
Кроме того, представьте себе программный эмулятор, эмулирующий на уровне вентилей? Это сверхизбыточность.
Также, понимание сути позволяет найти скрытые нюансы, ошибки, неизвестные подводные камни. Это все очень интересно.
Видимо, тут говорит мой дух хакера и оптимизатора)
- - - Добавлено - - -
У нас - это у кого, и с каким проектом?
- - - Добавлено - - -
Тут могу согласиться)
Наши приключения с фамиком:Цитата:
У нас - это у кого, и с каким проектом?
https://github.com/emu-russia/breaks
https://github.com/emu-russia/breaknes
А вот пример чего можно добиться за месяц, без особого "понимания":
https://github.com/nukeykt/Nuked-MD
https://github.com/nukeykt/Nuked-MD-FPGA
Рекомендую таки сделать нетлист и проект сразу завершится. "Понимать" можно не вдумчиво вглядываясь в вентили, а анализируя вейвы при прогоне модели HDL в том же Icarus Verilog + GTKWave.
Это будет опять же наблюдение за последствиями извне, не понимая причин.
Как, например, преобразовать схему в синхронную, избавиться от проходных буферов (обьединяющих две шины) не понимая всех нюансов работы?
Да и чтобы найти какую-то хитрую ошибку во флагах, нужно начинать изнутри, а не 'тупо' перебирать все комбинации, наблюдая за последствиями снаружи, вдруг чего попадется интересного.
- - - Добавлено - - -
Думаю, что K-MOS-овская версия Z80 в этом плане попроще, т.к. посовершеннее.