aBoomest 0 18 июня, 2018 Опубликовано 18 июня, 2018 (изменено) · Жалоба Всем доброго дня. Привожу нижеследующий код: OnButtonLeft_Down: process(OnBtnLeft_DownEvent) begin if rising_edge(OnBtnLeft_DownEvent) then if (PulsePerPeriod_VAR > 0) then PulsePerPeriod_VAR := PulsePerPeriod_VAR - 1; --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end if; end if; end process OnButtonLeft_Down; OnButtonRight_Down: process(OnBtnRight_DownEvent) begin if rising_edge(OnBtnRight_DownEvent) then if (PulsePerPeriod_VAR < PulsePerPeriod_VAR_MAX) then PulsePerPeriod_VAR := PulsePerPeriod_VAR + 1; --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end if; end if; end process OnButtonRight_Down; (PulsePerPeriod_VAR объявлена как shared variable) Это обработка нажатия двух кнопок (вправо, влево) Само нажатие работает нормально, по которому я формирую "событие-сигнал" нажатия кнопки (либо правой, либо левой - по названиям процессов все понятно) при этом обращаю внимание на выделенные две строки. Если их закоментировать - все компилируется. Если оставить одну из них - тоже компилируется. А вот обе - сразу дает ошибку. Я чую конечно что так писать нельзя. (Переменная PulsePerPeriod_VAR в обоих процессах одна и таже) Но почему? Не могу понять и найти объяснение. Уже неделю копаю и в инете и в книгах Бибило. 1. Может кто-нибудь популярно объяснить почему так нельзя? 2. Как реализовать нажатие нескольких кнопок, когда по нажатию надо изменять значение одного и того же параметра (в данном случае увеличить или уменьшить значение переменной PulsePerPeriod_VAR) 3. Может кто посоветовать литературу такого плана - дается к.л. конструкция кода и далее какую структуру она порождает и описание это (примеры). Не готовые схемы счетчиков и т.п. а наоборот, с т.з. языка vhdl. Код -> структура -> описание. Изменено 18 июня, 2018 пользователем aBoomest Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 220 18 июня, 2018 Опубликовано 18 июня, 2018 · Жалоба Да потому что кнопки сейчас мифические. Перейдите в реальность и сделайте сперва синхронный подавитель дребезга для обеих, после него не останется никаких неоднозначностей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба А может корректнее завести все в один процесс и там увеличивать/уменьшать содержимое переменной? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба Предлагаю все объединить в одном процессе. Заменить переменную на сигнал и таким образом описать суммирующие-вычитающий счетчик. Ну а далее все просто: Когда кнопка нажата счетчик считает "вверх". Когда кнопка отпущена счетчик считает "вниз". Если счетчик досчитал до конца (все разряды счетчика единички) - значит сигнал-флаг нажатой кнопки становится активным. Если счетчик досчитал до конца (все разряды счетчика нолики) - значит сигнал-флаг нажатой кнопки становится не активным. Задавая разрядность счетчика Вы задаете время фильтрации дребезга. Не забыть поставить регистр-синхронизатор для подавления метастабильности. В итоге Вы получите классический вариант антидребезга кнопки :1111493779: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 19 июня, 2018 Опубликовано 19 июня, 2018 (изменено) · Жалоба Да потому что кнопки сейчас мифические. Перейдите в реальность и сделайте сперва синхронный подавитель дребезга для обеих, после него не останется никаких неоднозначностей.Ни в коем случае. Ничего мифического нет. :) Key_01 и Key_02 - контролируют длительность нажатия. Первый заход в процесс - устанавливается Key_01. В конце устанавливается Key_02. Второй заход в процесс (через 10 мс) - проверяется Key_01 = Key_02. Т.е. антидребезг на 10 мс. UCF Net "Btn_Left" Loc = "D18" | IOStandard = LVTTL | PullDown; Net "Btn_Right" Loc = "H13" | IOStandard = LVTTL | PullDown; VHD shared variable PulsePerPeriod_VAR: integer range 0 to PulsePerPeriod_VAR_MAX := 624; . . . . . ButtonsPolling: process(Clock_100Hz) begin if rising_edge(Clock_100Hz) then if Btn_Left = '1' then Key_01 := '1'; if Key_01 = Key_02 then OnBtnLeft_DownEvent <= '1'; end if; else OnBtnLeft_DownEvent <= '0'; end if; if Btn_Right = '1' then Key_01 := '1'; if Key_01 = Key_02 then OnBtnRight_DownEvent <= '1'; end if; else OnBtnRight_DownEvent <= '0'; end if; Key_02 := Key_01; end process ButtonsPolling; OnButtonLeft_Down: process(OnBtnLeft_DownEvent) begin if rising_edge(OnBtnLeft_DownEvent) then if (PulsePerPeriod_VAR > 0) then PulsePerPeriod_VAR := PulsePerPeriod_VAR - 1; end if; end if; end process OnButtonLeft_Down; OnButtonRight_Down: process(OnBtnRight_DownEvent) begin if rising_edge(OnBtnRight_DownEvent) then if (PulsePerPeriod_VAR < PulsePerPeriod_VAR_MAX) then PulsePerPeriod_VAR := PulsePerPeriod_VAR + 1; end if; end if; end process OnButtonRight_Down; 1. Если есть знатоки как красиво делать антидребезг - буду только благодарен узнать/послушать. 2. На счет того синхронный подавитель это или НЕ синхронный - таких подробностей пока не знаю. Спасибо за ответы. На счет объединения в один процесс . . . обязательно подумаю, тока пока не понимаю как это вообще возможно. :) А как вообще в мире делается опрос клавиатуры (если например 10 кнопок)? Ведь например функция вверх-вниз хождения по меню - это явно уменьшение/увеличение одной и той же переменной описывающей текущее положение в меню. Так? К слову - философский вопрос о концепции того, что возможно построить на ПЛИС и нужно ли это делать? У меня есть набор Спартан 3Е. На нем есть какая-то память, ЖКИ и тд и тп. А вот такой вопрос вобще на ПЛИС "возможно" реализовать устройство например которое принимает сигнал с ацп и рассчитывает его спектр. Плюс вывод какой-то дополнительной информации на экран. Под словом "возможно", я подразумеваю не то возможно ли это вообще сделать, а то - целесообразно ли это, или надо делать применять другие микросхемы. Изменено 19 июня, 2018 пользователем aBoomest Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба Если есть знатоки как красиво делать антидребезг - буду только благодарен узнать/послушать. Не претендую на роль знатока, но совсем чуть-чуть про дребезг знаю. И один из вариантов подавителя дребезга был предложен мною выше. Вообще советую ознакомиться с темой: https://electronix.ru/forum/index.php?showtopic=147150 Удивительно что Вы её не нашли. На счет объединения в один процесс . . . обязательно подумаю, тока пока не понимаю как это вообще возможно. :) Ну так работая с FPGA Вы не программу пишете а схему. Придется отказаться от "программисткого способа мышления" Представьте объединение процессов как обычный счетчик с сигналом управления. Если на него подается единичка - счетчик считает вверх. Если нолик - счетчик считает вниз. И по условию у вас формируется сигнал управления этим счетчиком. А как вообще в мире делается опрос клавиатуры (если например 10 кнопок)? Вертикальные счетчики (ссылка на статью дана в теме про антидребезг). К слову - философский вопрос о концепции того, что возможно построить на ПЛИС и нужно ли это делать? Построить на ПЛИС можно почти все, что можно сделать на микроконтроллерах и даже чуточку больше :rolleyes: И даже сам микроконтроллер. Вопрос в том, что сколько это займет времени, денег, и когда нужен результат. И вообще актуальность решения задачи на FPGA - это действительно философский вопрос. реализовать устройство например которое принимает сигнал с ацп и рассчитывает его спектр. Плюс вывод какой-то дополнительной информации на экран. Под словом " Сделать можно. Но очень долго, если самому с нуля проектировать. Связка МК+ куча микросхем скорее всего будет быстрее в несколько раз. Альтернатива - собрать на FPGA из готовых IP блоков, со всеми граблями, велосипедами, и глюками и прочими негативными факторами. Но за то быстро. Возможно быстрее чем на МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба debounce.vhd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба Не претендую на роль знатока, но совсем чуть-чуть про дребезг знаю. И один из вариантов подавителя дребезга был предложен мною выше. Вообще советую ознакомиться с темой: https://electronix.ru/forum/index.php?showtopic=147150 Удивительно что Вы её не нашли. Спасибо! Ну так работая с FPGA Вы не программу пишете а схему. Придется отказаться от "программисткого способа мышления" Представьте объединение процессов как обычный счетчик с сигналом управления. Если на него подается единичка - счетчик считает вверх. Если нолик - счетчик считает вниз. И по условию у вас формируется сигнал управления этим счетчиком. Да, борюсь с этим. Учусь переключаться с того на это. На счет счетчиков - спасибо. По больше бы таких фраз. Очень популярно многое объясняет. Построить на ПЛИС можно почти все, что можно сделать на микроконтроллерах и даже чуточку больше :rolleyes: И даже сам микроконтроллер. Вопрос в том, что сколько это займет времени, денег, и когда нужен результат. И вообще актуальность решения задачи на FPGA - это действительно философский вопрос. Примерно год, полтора в лучшем случае. Сделать можно. Но очень долго, если самому с нуля проектировать. Связка МК+ куча микросхем скорее всего будет быстрее в несколько раз. Альтернатива - собрать на FPGA из готовых IP блоков, со всеми граблями, велосипедами, и глюками и прочими негативными факторами. Но за то быстро. Возможно быстрее чем на МК. На счет АЛЬТЕРНАТИВЫ - честно сказать вообще пока не понимаю о чем это? Погуглил. Идея понятна. Но это чтото видится пока еще более долгим вариантом. (учитывая что только что первый раз услышал) Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба На счет АЛЬТЕРНАТИВЫ - честно сказать вообще пока не понимаю о чем это? Погуглил. Идея понятна. Но это чтото видится пока еще более долгим вариантом. (учитывая что только что первый раз услышал) У многих производителей FPGA в составе их САПР есть готовые функциональные блоки, SDRAM контроллеры, MAC контроллеры, PCI, всякие DSP блоки, и многое другое. Зачастую пользуясь этими блоками, можно собирать необходимую схему, как из конструктора. Но очень часто в таких блоках может не хватать нужного функционала, или блок может содержать ошибки, или вообще быть "платным" где для пользования блоком надо приобретать отдельную лицензию, а пользователю доступен блок в демо-режиме, в котором ограничен функционал. Да и что скрывать, зачастую на эти блоки документация очень убогая, и приходиться тратить кучу времени на его изучение. Да и применяя все готовое самому не научиться делать правильно, что самое неприятное в этом подходе. Но собрать из таких блоков нужную схему будет, как правило проще и быстрее, чем самому во всем разобраться. И может даже все это будет работать. P.S. Но если система требует особой надежности - я бы не стал применять такой код, ибо непонятно как и кем он написан, посему доверия он не внушает. Но это уже мое личное мнение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 220 19 июня, 2018 Опубликовано 19 июня, 2018 (изменено) · Жалоба синхронный подавитель это или НЕ синхронный - таких подробностей пока не знаю В этом-то и проблема. Он в наличии и синхронный, а вот его результат зачем-то выведен из-под данного такта — создайте в нём же условие "обе кнопки нажаты или отпущены" и не по нему меняйте счётчик. Изменено 19 июня, 2018 пользователем Plain Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба В этом-то и проблема. Он в наличии и синхронный, а вот его результат зачем-то выведен из-под данного такта — создайте в нём же условие "обе кнопки нажаты или отпущены" и не по нему меняйте счётчик.Простите мне мою глупость, но я не совсем понял о чем Вы. Сделать все в одном процессе, как писали коллеги выше по тексту? а вот его результат зачем-то выведен из-под данного тактаКонкретно вот эта фраза не понятна. Не могли бы вы мне ее растолковать как детсадовскому ребенку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба [quote name='aBoomest' date='Jun 19 2018, 13:47' post='156 Не могли бы вы мне ее растолковать как детсадовскому ребенку? У Вас личная почта работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 19 июня, 2018 Опубликовано 19 июня, 2018 · Жалоба Так точно, работает! PS: На счет того как засунуть в один процесс - ясно, это я тупанул жутко. Спасибо за советы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 21 июня, 2018 Опубликовано 21 июня, 2018 · Жалоба Предлагаю все объединить в одном процессе. Заменить переменную на сигнал и таким образом описать суммирующие-вычитающий счетчик. На счет того как засунуть в один процесс - ясно, это я тупанул жутко.Не, чего-то и где-то я не допонимаю. :( Запихал все в один процесс, как советовали выше. И, как я понимаю, ошибка в том, что нельзя в двух местах изменять переменную PulsePerPeriod_VAR. Как из ситуации-то выходить? Если по нажатию одной кнопки мне нужно увеличить значение на 1цу, по нажатию другой, соответственно уменьшить. Существует какое-то классическое/общепринятое решение в данном случае? МОжет в этот процесс надо как-то Clock какой-нибудь добавить. OnButtonLeftRight_Down: process(OnBtnLeft_DownEvent,OnBtnRight_DownEvent) -- изменение длительности импульса begin if rising_edge(OnBtnLeft_DownEvent) then if (PulsePerPeriod_VAR > 0) then PulsePerPeriod_VAR := PulsePerPeriod_VAR - 1; end if; elsif rising_edge(OnBtnRight_DownEvent) then if (PulsePerPeriod_VAR < PulsePerPeriod_VAR_MAX) then PulsePerPeriod_VAR := PulsePerPeriod_VAR + 1; end if; end if; end process OnButtonLeftRight_Down; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 21 июня, 2018 Опубликовано 21 июня, 2018 · Жалоба Первое и основное правило синхронных проектов - на тактовый вход триггера должен приходить только синхросигнал*. Т.е при вызове функции rising_edge\faling_edge использовать только синхросигнал. Если нужно детектировать передний или задний фронт какого-либо сигнала, не являющегося тактовым - применяйте схемы, называемые детекторы фронта. Вот кстати я недавно выкладывал свой модуль детектора фронта: https://electronix.ru/forum/index.php?showt...5&start=195 А вот кусок счетчика, который считает вверх, или вниз в зависимости от того, какие кнопки нажаты: --================================================ -- 0 разряд сигнала buttons соответствует кнопке 0 -- 1 разряд сигнала buttons соответствует кнопке 1 --================================================ OnButtonLeftRight_Down : process(clk) begin if rising_edge(clk) then case buttons is when "10" => PulsePerPeriod_VAR := PulsePerPeriod_VAR - 1; when "01" => PulsePerPeriod_VAR := PulsePerPeriod_VAR + 1; when others => null; end case; end if; end process; Но я бы так не делал :rolleyes: Я бы для начала сделал обычный антидребезг и подключил его кнопкам. А реакцию схемы на нажатие кнопок обрабатывал бы простой FSM. PS * Исключением из этого правила является специально сгенерированная на логике частота, например поделенная в 2 раза на триггере. Но даже в этом случае я предпочитаю применить PLL. Ибо частота сгенерированная на PLL имеет меньший джиттер, чем та-же частота сгенерированная на логике. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться