Речь пойдёт всё так-же о асинхронной логике. Похоже, что тут никто и никого не ждал... к такому выводу можно прийти, если посмотреть на сравнения, в сети и материалах, по части синхронной и асинхронной логики, и на фактические цифры, ну и на традиционную забагованность (в частности Gowin EDA) в таких нужных местах как массивы, впрочем эта забагованность вполне победима посредством небольшого «шаманства», об этом будет тоже. Приходится делать «двухшаговые » публикации, потому что если свалить всё в прошлую — то это вряд ли станет всё читабельным, а одного шага явно мало для полноценной публикации, особенно на фоне борьбы с чужими багами. Если не лень читать новые «приключения» васинхронном, и не только, мире — то пожалуйста.
В прошлой публикации мной были выложены асинхронные триггеры — синтезированный средой и свой, полученный после некоторого анализа ситуации в процессе его разработки и анализа схемы синтезированного средой. Тот что получен самостоятельно показал себя на тестбенчах как более стабильный. Удовлетворившись результатом работы, поделав некоторые другие дела, я задумался — «а что же там за цифры, и может их посчитать...». Как задумал — так и сделал. Правда долго не решался выкладывать расчёты, потому что не знал куда — отдельной публикацией было мало материала, а в старую — сделать в ней больше чем нужно для «формата». Размышления подтолкнули на новые действия: сгенерировать асинхронный счётчик в блоке генерации, а заодно попробовать победить баг, возникающий при создании массива проводов. Почему называю его не шиной? Потому что не параллельное подключение — 1, потому, что шину в Gowin Eda можно создавать достаточно небольшого размера, и если превысить лимит — то начнёт выдавать ошибку при компиляции. А смысл имеет, если браться за что‑то серьёзное, возможность работы только с большими массивами. Итак баг был побеждён, и далее в порядке названия публикации.
Насколько же это может быть быстрым...
имеется ввиду асинхронная логика. Я как-то не придал значения сразу полученным (в тестбенчах из прошлой публикации) цифрам, но потом всё-же задумался и о них. Новые тестбенчи, но уже с асинхронным счётчиком, полученным в блоке генерации.
Код под спойлером
Скрытый текст
module Trs
(input S, R,
output Q);
not n1(R1,R);
and a1(G,S,R1);
DLC dlc1 (Q,G,G,R);
endmodule
module pprobe1 ( output out); // 6 LEDS pin);
genvar i;
wire [30:0] w;
wire restT;
generate
not (w[0],w[29]);
for (i=0; i<29; i=i+1 ) begin:pprobe1_generation
Trs tr(w[i],w[29],w[i+1]);
end
endgenerate
assign out= w[29];
Gowin_OSC GwOsc(oscout);
endmodule
.
Изображён тут счётчик из 30 асинхронных триггеров, который сбрасывается как только в тридцатый записывается единица, а получаемый с его выхода сигнал ноля проходит через элемент NOT , и вновь запускает последовательное заполнение асинхронного счётчика. То-есть полный цикл срабатываний - это 30 счётчиков, но чтобы на диаграмме визуализировать более удобно разделение циклов - отслеживается сигнал с выхода 15-го триггера (проиндексирован блоком генерации как 14), а быть точнее сигнал с провода w[14].
Немного помощи тем, кто не смог разобраться с осцилятором и тестбенчами в Gowin Eda под спойлером
Скрытый текст
Осцилятор.
В меню с выпадающим списком нужно выбрать следующее
Откроется окно и выбрать
Далее будет создан файл, а в появляющемся окне появится коэффициент, на котороый мы хотим поделить 1 такт частоты предоставляемой платой. Я делил на 100. В проекта модуль оцилятора лежит отдельным файлом, экспериментов я пока на этот счёт не делал, потому что подозреваю, что при его создании что-то прописывается ещё и в настройки проекта.
Тестбенчи.
Во вкладке Capture Options я отслеживаю всего два сигнала, один из которых взят за сигнал захвата
В Trigger Options всего один сигнал
, без каких либо условий.
Настройки триггера
Надеюсь, так новичкам будет проще.
Итак тестбенч выше приведённого кода, с отслеживанием сигнала на середине асинхронного счётчика.
Границы сигналов тут смещаются немного, но сложно сказать результат каких допусков это. Здесь у нас имеется на 125 тактов, полученных с осцилятора, 41 полный цикл заполнения асинхронного счётчика. Посчитаем - тактовая частота платы 27 МГц, она увеличивается осцилятором в 100 раз, получается 2700 МГц или 2.7ГГц. За 125 тактов этой частоты, 30 последовательных асинхронных триггеров заполнили 41 раз, умножаем 30*41 = 1230 за 125 тактов. Если посчитаем сколько триггеров заполнилось за один такт, то получим 9,84. Умножим 9,84 на 2.7 и получим 26,568 ГГц для эквивалентной системы, где время срабатывания одного асинхронного триггера эквивалентно одному её такту. То-есть это предполагаемая асинхронная система на базе FPGA ( c встроенной тактовой частотой 27МГц). То-есть если строить чисто асинхронную логику - то она значительно превзойдёт синхронную, даже если той давать тактовую частоту с осцилятора. Тут всё как и мною ожидалось, но не на таких, правда, ранних этапах - я думал, что получу выход на мощности только когда сделаю уже свой рабочий процессор. С одной стороны это радует, но с другой стороны даёт повод задуматься - а так ли бескорыстны были заявления тех, кто заявлял о невозможности что-либо сделать на асинхронной логике. Но то ладно - ещё тогда я решил не вспоминать о людях распространивших тот материал. Поэтому не стоит и тут.
Тут можно добавить ещё то, что никакого такого ПЛИС на заказ я не приобретал, начиная с пошлой публикации и вот с этим материалом из википедии
Синхронные схемы практически любого уровня сложности могут быть реализованы на относительно дешевых ПЛИС. Напротив, строго-самосинхронные схемы предъявляют очень жесткие требования к внутренней структуре ПЛИС[6][7] и практически единственным решением является изготовление ПЛИС на заказ[8][9][10][11].
абсолютно не согласен - всё сопрягается и работает, как мной и было в общем-то ожидаемо, правда не на таких ранних этапах. Ну так - значит так. Может материал просто утарел.
Маленькая победа над багом Gowin EDA...
, собственно эта победа и есть второй повод для печали, так как была вынужденной на фоне рапортов о успешном импортозамещении, так как в её ракурсе немного теряются успехи заявлявших о таковом. С этим багом я столкнулся ещё давно, как-бы не пол-года назад. Если закомментировать в выше приведённом коде строку номер 19
, а она ровным счётом ни за что не отвечает, так как и выход нам этот совсем не нужен, то получим во вьювере такую аброказябру (ничего не нужно отключать или подключать - просто комментируем строку 19, в которой следующее : assign out= w[29];):
. Это и есть тот самый баг. И да - и это будет работать, на удивиление, но со скоростью в два раза меньшей, хотя согласно визуализации вообще работать не должно как асинхронный счётчик, так как все провода замкнуты то даже третьего триггера сигнал записи единицы вообще никогда не должен достигнуть, а сигнал отслеживается аж с 15-го триггера. То-есть визуализация полностью не соответсвует подключение проводов. И этот баг прослеживается и с осцилятором, и без него, даже в более простых схемах. Как решение - предпринял попытку дать компилятору "увидеть" схему в новой абстракции - подключить ненужный выход (строка 19), который вообще никак не задействован, а служит только для того, чтобы придать схеме новый абстрактный уровень для компилятора.
. Поразительно. Полгода назад меня этот казус, тогда я не знал что это работает, поставил в тупик — в книгах вроде одно, а во вьювере — другое. Ясное дело — баг. То‑есть его можно обойти, нужно дать компилятору «понять» что‑же тут происходит, для этого я и решил сделать в топмодуле выход (может как‑то компилятор увидит это в плане другой астракции) и подключить к нему сигнал последнего триггера, хотя для решения задачи выполняемой модулем — это абсолютно не нужно. Причём баг этот наблюдается что в Windows, что в Linux, и побеждается одним и тем‑же способом, надеемся, что разработчики победят его тоже.
На этом почти всё. Следующая публикация будет по готовности асинхронного АЛУ для асинхронного процессора, наработки есть, и как было показано из расчётов выше — перспективы асинхронной логики огромны, даже на такой дешёвой и простой плате. Единственное что — АЛУ будет полностью своей архитектуры, как и сам процессор, начиная от кэша команд (его схему я отлаживал до каких‑либо расчётов, и отлаженная схема есть в прошлой публикации, анимированная). Следом за АЛУ уже планируется небольшой процессор, для запуска уже программированной игры «Жизнь» (клеточный автомат, правда думаю серьёзно поработать над правилами поведения клеток) на машинном коде под него. Пока так вот. Планы серьёзные, но вроде и наработки неплохие — хардварная база протестирована и вроде как ничему не препятствует. В случае успеха вероятно будет начато, как OpenHardWare проект.
Если Вы увидите несоответствие в терминологии — прошу поставить в известность, я постараюсь исправить недочёты.
Комментарии (8)
Brak0del
10.11.2024 18:08хотя согласно визуализации вообще работать не должно как асинхронный счётчик, так как все провода замкнуты
Они не замкнуты, а объединены в шину. Рассматривайте их как пучок проводов.
engin
10.11.2024 18:08По части отладки, или я пропустил или это как то было отмечено? На сколько мне известно, не настаиваю, это лишь личные наблюдения, стандартные инструменты FPGA больше ориентированы на синхронные системы. Отладка асинхронных схем это непредсказуемые грабли из-за отсутствия центрального тактового сигнала, нужно детализировать тайминги, когда сигналы достигают различных элементов схемы в непредсказуемое время, что влечет полный рассинхрон.
Thealik
10.11.2024 18:08Счётчик - это, конечно, хорошо, но что говорит Gowin о режимах работы триггера? Почему это важно? Потому что вход сброса у этого триггера есть, а входа установки, наверняка, нет. А жаль, на двух RS-триггерах можно было бы собрать С-элемент (схема Murphy)
Brak0del
А в чём состоит баг? Вы подключили отладчик (analyzer oscilloscope), из-за которого вашу схему не сносит синтезатор. К нему же подключен и ваш осциллятор, поэтому его тоже не сносит и он там отдельным квадратиком стоит, тактируя отладчик. А analyzer oscilloscope на схематике не отображается. Схема верна.
А скорости различаются, потому что как и написано в цитате с вики:
физически на плисине ваши два эксперимента раскладываются на разные LUT-ы, длины путей между которыми отличаются и вносят существенную разницу в скорость осцилляции вашей штуки.
Чтобы немножко контролировать процесс, прибейте констрейнтами ваши триггеры к конкретным LUT-ам внутри ПЛИС.
Thealik
Выход LUT, конечно, можно подключить к триггеру в другом CLB, но зачем тянуть провод, если есть "местный" триггер? Может быть оптимизатор иногда так делает. Если цель - поизучать что вытворяет оптимизатор - это одно, а если цель - настроить всё вручную, то для этого служит instantiation.
Brak0del
Да, действительно, пардон, не посмотрел, что там у человека Latch, а не LUTы используются. Но сути замечания сильно не меняет: для хоть сколько-нибудь контролируемого тайминга в подобных экспериментах ресурсы лучше прибить констрейнтами, иначе результаты будут очень существенно отличаться в зависимости от того, как P&R всё разложило в этот конкретный раз на кристалле.
Thealik
Кстати, про P&R, может быть Вы знаете, кто-то сравнивал open-source разводчики? В частности тот, который внутри Verilog to Routing с тем, который внутри Yosys?
Brak0del
Про open-source к сожалению не знаю; но слышал, что раньше были соревнования по алгоритмам P&R и победители попадали в современные тулы, проприетарные и не очень.