Comments 34
Рад, что мои статьи как-то влияют на то, что делают другие люди)
Вы заморочились (в хорошем смысле этого слова) с игрой намного больше, чем я, когда делал тетрис)
Удачи в освоении разработки под FPGA!
Вы заморочились (в хорошем смысле этого слова) с игрой намного больше, чем я, когда делал тетрис)
Удачи в освоении разработки под FPGA!
Это круто. У меня тоже на плате есть VGA выход, но к сожалению больше нет мониторов, которые поддерживают VGA :)
За пару недель такое?
Завидую!
Завидую!
Спасибо за мотивацию :)
Нельзя просто взять и записать что-либо в регистр в разных местах кода, если компилятор не может четко обозначить условия: при таких — пишем это, при таких — это. Почему так происходит понятно — вход на запись у регистра один и нельзя подать 2 сигнала без какой-либо логики на один вход.
Я Вам больше скажу. Если Вы пишете на Verilog (просто я из статьи не понял — пишете Вы C с трансляцией в Verilog, или прямо на Verilog) — то нельзя присваивать один и тот же регистр в разных «Always» — потому что трансляторы разных производителей понимают такие вещи по разному.
Неправильно:
always @(posedge CLK) if (A) reg <= B;
always @(posedge CLK) if (A1) reg <= B1;
Правильно:
always @(posedge CKJ)
if (A) reg <= B;
else if (A1) reg <= B1;
Я использовал systemverilog из-за возможности использовать структуры и logic. Кстати, был еще один момент, когда я сумел в разных модулях изменить значения одних регистров, причем я не понял как это прокатило. Разбор этой ситуации отложил на потом
Ну глобально тут полезно понимать что происходит с логикой при тех или иных условиях. В частности если взять тот кусок кода, который я пометил как «правильный» то синтезатор сделает следующее.
1. Создаст D-триггер, на вход D которого придет некое значение — MUX.
2. Значение MUX будет получаться из мультиплексора, и будет выбираться из двух ( B или B1) в зависимости от входного сигнала SEL. Например SEL=0 выбирает B, а SEL=1 выбирает B1
3. SEL при этом будет определяться как: SEL = NOT(A).
4. На вход CE (clock enable) будет при этом приходить условие определяемое следующим образом:
CE = A | NOT(A) & A1.
Обратитет внимание что в пункте 4 для срабатывания по условию A1 важно выполнение условия NOT(A).
Если код построен так, что NOT(A) не проверяется при выборе A1 — то такое присваивание будет работать непредсказуемо.
1. Создаст D-триггер, на вход D которого придет некое значение — MUX.
2. Значение MUX будет получаться из мультиплексора, и будет выбираться из двух ( B или B1) в зависимости от входного сигнала SEL. Например SEL=0 выбирает B, а SEL=1 выбирает B1
3. SEL при этом будет определяться как: SEL = NOT(A).
4. На вход CE (clock enable) будет при этом приходить условие определяемое следующим образом:
CE = A | NOT(A) & A1.
Обратитет внимание что в пункте 4 для срабатывания по условию A1 важно выполнение условия NOT(A).
Если код построен так, что NOT(A) не проверяется при выборе A1 — то такое присваивание будет работать непредсказуемо.
У меня та же история, в 80-х я в глаза ни разу не видел компьютер, но умел что-то примитивное создавать на логических элементах. Помню даже случай, когда на триггер не хватало несколько копеек и я впервые в жизни у прохожего попросил их, тот чтобы убедиться, что я не попрошайка, пошел со мной в магазин и я при нем купил микросхему) Потом в приложении к Юному Технику появилась схема компьютера и в месте с ней у меня мечта его собрать. Ну в принципе, будет время — осуществлю мечту в FPGA)
И даже переключил свое сознание в этом направлении на синхронный дизайн: из-за особенности архитектуры ПЛИС в целом (не важно, CPLD это или FPGA), комбинаторика тут работает непредсказуемо из-за непредвиденных задержек сигнала, вносимых путями сигналов, которые образуются после принятия решения фиттером куда что положить в кристалле.
Эту непредсказуемость можно контролировать путем задания ограничений на Propagation Delay. Но мое мнение таково — если в дизайне есть ограничения на асинхронные пути (или полная крайность — задание правил LOC — координаты в ПЛИС, для LUT и регистров) — то этот дизайн плохой. Это из той же оперы что при проектировании схемы полагаться на характеристики транзисторов. Не в том смысле что их оценивать, а в том что шаг вправо, шаг влево — и схема отваливается.
В общем — больше регистров хороших и годных.
Ну живой пример из практики. У меня просто много знакомых которые чрезмерно увлекаются асинхронным дизайном, клоканьем регистров не штатным клоком и прочими такими делами.
Человек полгода писал ПЛИС. Код абсолютно дурной — чесслово, я бы писал совсем по другому. Констрейнов там на 1000 строк. Добрая половина их них — указание САПРу игнорить те или иные пути, и обконстренйенные в хлам ансихронные пути. Утилизация небольшая — менее 40% (к слову я набивал FPGA под 85% по LUT) Утрамбовалось, BIST прошло. Через полгода эксплуатации заказчик выявил баг. Простой — исправить, как два пальца — с логической точки зрения. Исправляют уже третий месяц — у них BIST не проходит теперь. Разъехалась логика где-то.
Хороший дизайн можно модифицировать с минимальными затратами времени. Идеальный (на мой взгляд) дизайн не требует констрейнов вообще (окромя задания пинов и частоты клока естсественно)
Человек полгода писал ПЛИС. Код абсолютно дурной — чесслово, я бы писал совсем по другому. Констрейнов там на 1000 строк. Добрая половина их них — указание САПРу игнорить те или иные пути, и обконстренйенные в хлам ансихронные пути. Утилизация небольшая — менее 40% (к слову я набивал FPGA под 85% по LUT) Утрамбовалось, BIST прошло. Через полгода эксплуатации заказчик выявил баг. Простой — исправить, как два пальца — с логической точки зрения. Исправляют уже третий месяц — у них BIST не проходит теперь. Разъехалась логика где-то.
Хороший дизайн можно модифицировать с минимальными затратами времени. Идеальный (на мой взгляд) дизайн не требует констрейнов вообще (окромя задания пинов и частоты клока естсественно)
Вот например у студентов часто встречаю такие конструкции:
Результатом будет полный треш
Объяснить почему?
Или такое
Тоже очень прикольные вещи происходят в такой конструкции
always @(posedge CLK1 or posedge CLK2)
reg <= value
Результатом будет полный треш
Объяснить почему?
Или такое
always @(posedge CLK1)
reg1 <= A
always @(posedge CLK2)
reg2 <= A
Тоже очень прикольные вещи происходят в такой конструкции
Меня просто периодически просят внести какие-то изменения в чей-то код. Поставщик таких задач — компания в которой много
— студентов
— представителей «старой школы»
типичный ВПК короче
И я каждый раз за голову хватаюсь — там такого добра валом.
Часто просто приходится заново переписывать куски кода.
— студентов
— представителей «старой школы»
типичный ВПК короче
И я каждый раз за голову хватаюсь — там такого добра валом.
Часто просто приходится заново переписывать куски кода.
И да, я задаю только клок и пины. А после пытаюсь избавиться от всех (ну или большинства) варнингов.
Единственно что я делаю в плане геолокации вентилей в ПЛИС — я задаю регионы. Потому что основная масса продуктов которые пишу — это законченные переносимые IP блоки. Поэтому как-то «красивее» что-ли когда IP занимает какой-то определенный кадратик в кристалле.
always @(posedge CLK1)
reg1 <= A
always @(posedge CLK2)
reg2 <= A
А что тут не так, объясните пожалуйста
Зависит от того что там дальше. Ну для определенности давайте возьмем ситуацию когда сигнал «A» синхронизирован с частотой CLK1 и асинхронен по отношению к частоте CLK2.
В этом случае reg1 отработает корректно, а вот на выходе reg2 возможно возникновение метастабильного состояния. Метастабильное состояние характеризуется тем, что фронт сигнала затянут — не просто завален/сглажен — а он буквально размазан во времени Причем даже возможно за период частоты сигнал так и не установится. Дальше представьте что значение reg2 у Вас участвует в логике в нескольких частях схемы и Вы предполагаете что на входе всех компонентов в отдельно взятый момент времени он имеет одно и то же значение. Однако в случае вознкновения метастабильного состояния — какие-то блоки увидят на входе 0, а какие-то 1. И вся логика работы Вашей схемы слетит. Причем слетать оно будет всегда по-разному. Печально здесь то — что никакие констрейны на тайминг эту ситуацию Вам не накроют. И САПР на тайминги ругаться не будет. Он проглотит.
В результате, когда к Вам попадает чужой дизайн, который почему-то дает плавающие отказы (причем всегда разные) — и Вы не ожидаете там таких конструкций — дебажить Вы его будете очень долго.
В этом случае reg1 отработает корректно, а вот на выходе reg2 возможно возникновение метастабильного состояния. Метастабильное состояние характеризуется тем, что фронт сигнала затянут — не просто завален/сглажен — а он буквально размазан во времени Причем даже возможно за период частоты сигнал так и не установится. Дальше представьте что значение reg2 у Вас участвует в логике в нескольких частях схемы и Вы предполагаете что на входе всех компонентов в отдельно взятый момент времени он имеет одно и то же значение. Однако в случае вознкновения метастабильного состояния — какие-то блоки увидят на входе 0, а какие-то 1. И вся логика работы Вашей схемы слетит. Причем слетать оно будет всегда по-разному. Печально здесь то — что никакие констрейны на тайминг эту ситуацию Вам не накроют. И САПР на тайминги ругаться не будет. Он проглотит.
В результате, когда к Вам попадает чужой дизайн, который почему-то дает плавающие отказы (причем всегда разные) — и Вы не ожидаете там таких конструкций — дебажить Вы его будете очень долго.
Ну, т/е конструкция сама по себе ок, только зависит от интеграции с другими частями системы, мне это важно знать ибо я испугался «может чего-то не понимаю». А так да, про метастабильное состояние я читал и сразу понял, что пример будет с ним)
Ну это самое адовое что может быть в ПЛИС — поэтому раз уж мы говорим о косяках — я не преминул привести этот пример.
Лечится переходом через 2-3 регистра.
Но лечить такое в уже готовом дизайне — треш. Потому что 2-3 регистровых стадии кардинально меняют всю логику. То есть переписывать приходится все.
Лечится переходом через 2-3 регистра.
Но лечить такое в уже готовом дизайне — треш. Потому что 2-3 регистровых стадии кардинально меняют всю логику. То есть переписывать приходится все.
А можно ссылку на используемую плату?
По поводу видеовыхода, а шим не?
Так шим предусматривает, что на выходе импульсы будут сглажены. Если предположить, что это сделает сам монитор, то в принципе можно на обратном фронте синхроимпульса убирать сигнал, получится примитивный шим на 3 значения, т.е. получу 27 цветов вместо 8. В принципе, попробовать можно. Более продвинутый шим программно получить только увеличением частоты — хз как китайская железяка к этому отнесется. Сейчас итак там 108Мгц
Ну дык, 4 циклон вещь очень хорошая, на 3м, на 3500ЛЕ делается спектрум 128, делали так же ПАЛ кодер, там вообще шим на шим умножается, http://zx-pk.ru/threads/9342-plis-i-vsjo-chto-s-nimi-svyazano.html куча полезного, простым языком по VHDL.
>Если предположить, что это сделает сам монитор
Ну емкость то у ВГА входа, какая-то, но должна быть, ну или в схеме на выходе, китайцы ж не думали, что ВГА это 8 цветов :-)
>Если предположить, что это сделает сам монитор
Ну емкость то у ВГА входа, какая-то, но должна быть, ну или в схеме на выходе, китайцы ж не думали, что ВГА это 8 цветов :-)
Так шим предусматривает, что на выходе импульсы будут сглажены
Я никогда не работал с Альтерой, но по аналогии с Xilinx могу предположить, что там можно регулировать slew-rate выводов. Если если можно — ставьте самый низкий. Вариация на тему — может называться Drive Strength. И будут Вам заваленные фронты.
Sign up to leave a comment.
River Raid на FPGA