Александр77 1 30 декабря, 2017 Опубликовано 30 декабря, 2017 · Жалоба Нет проверки на то, что что в DIRECTION будет нечто, отличное от "UP" и "DOWN". Например, "Up" или "Down". Не всем нравится верхний регистр. Лучше заменить строку на boolean. В VHDL нет разницы между UP, Up, uP или up. Про Down можно сказать тоже самое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 30 декабря, 2017 Опубликовано 30 декабря, 2017 · Жалоба В VHDL нет разницы между UP, Up, uP или up. Про Down можно сказать тоже самое. Для типа string разница есть ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 30 декабря, 2017 Опубликовано 30 декабря, 2017 · Жалоба В VHDL нет разницы между UP, Up, uP или up. Про Down можно сказать тоже самое.Тащемта там строка, а не перечислимый тип. Можете сказать навскидку где вообще такой счетчик мог бы пригодится ?Дело в принципе. Если вы пишете модуль, претендующий на универсальность, пишите его на самом деле универсальным, с минимальным количеством ограничений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 30 декабря, 2017 Опубликовано 30 декабря, 2017 · Жалоба Тащемта там строка, а не перечислимый тип. Дело в принципе. Если вы пишете модуль, претендующий на универсальность, пишите его на самом деле универсальным, с минимальным количеством ограничений. Понял. Учтем ! А вообще в VHDL сделать модуль полностью универсальным очень сложно. Например я как-то хотел сделать модуль полностью настраиваемым. Т.е в области generic настраивать все возможные комбинации входных и выходных портов. Например если нужен сигнал синхронного сброса, сигнал переноса, разрешения работы, и пр то их можно включить просто настройкой параметров модуля. Но столкнулся с проблемой отсутствием возможности генерировать по условию входные\выходные порты. Вернее не так, возможность есть, но она очень кривая и модуль выдает кучу предупреждений. Хотя синтезируется нормально. Иногда даже жалко что у VHDL нет предпроцессора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alxkon 0 22 января, 2018 Опубликовано 22 января, 2018 · Жалоба Вот. Последние варианты (4 и 5, одинаковые). Остальные показывают процесс разработки. :-) `define LENTH 28 `define VAR5 `ifdef VAR1 `define TIM1 `elsif VAR2 `define TIM1 `elsif VAR3 `define TIM1 `else `define TIM2 `endif module Timer_m `ifdef TIM1 ( (* chip_pin = "91", altera_attribute = "-name global_signal on; -name io_standard lvds" *) input bit clk, // high-speed clock input bit [`LENTH-1:0] rld, // reload data output bit pls // timer overload pulse ); `endif `ifdef VAR1 bit [`LENTH:0] cnt; always_ff @(posedge clk) begin if (cnt[`LENTH]) cnt <= {1'b0, rld}; else cnt <= cnt - 1; end assign pls = cnt[`LENTH]; `elsif VAR2 bit [`LENTH-1:0] cnt; always_ff @(posedge clk) begin if (cnt[`LENTH-1]) cnt <= rld; else cnt <= cnt - 1; end assign pls = cnt[`LENTH-1]; `elsif VAR3 bit [`LENTH-1:0] cnt; always_ff @(posedge clk) begin if (cnt[`LENTH-1]) cnt <= rld; else cnt <= cnt[`LENTH-2:0] - 1; end assign pls = cnt[`LENTH-1]; `endif `ifdef TIM2 ( (* chip_pin = "91", altera_attribute = "-name global_signal on; -name io_standard lvds" *) input bit clk, // high-speed clock input bit [`LENTH-1:0] rld, // reload data input bit ldp, // load pulse output bit pls // timer overload pulse ); `endif `ifdef VAR4 bit [`LENTH:0] cnt; always_ff @(posedge clk) begin if (cnt[`LENTH]) cnt <= {ldp, rld}; else cnt <= cnt[`LENTH-1:0] - 1; end assign pls = cnt[`LENTH]; `endif `ifdef VAR5 bit [`LENTH-1:0] cnt; always_ff @(posedge clk) begin if (pls) {pls, cnt} <= {ldp, rld}; else {pls, cnt} <= cnt - 1; end `endif endmodule : Timer_m Извините, забыл совсем ответить. Если я не ошибаюсь в Вашем варианте загружаемое значение lpd должно быть на 1 меньше от желаемого значения счета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Мур 1 16 апреля, 2018 Опубликовано 16 апреля, 2018 · Жалоба Простенький ФНЧ Uout = Uout-1 + (Utek - Uout-1)>> K Выручал неоднократно... Делюсь Все-таки добавлю к нему TestBanch... IQ_filtr.vhd IQ_tb.vhd RND.vhd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 14 мая, 2018 Опубликовано 14 мая, 2018 · Жалоба Поскольку в последнее время часто возникает вопрос про детекторы фронта, то выложу сюда свой модуль детектора. Собственно сам текст: -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | File name | KAA_edge_dtct | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Properties | Tab type = space | HDL type = VHDL2008 | Languege - Russian | Syntesis tool = Quartus 13.1 | Sim = Modelsim ASE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Author | Клементьев Алексей Александрович | Email = [email protected] -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Description | Детектор фронтов. Встроенный CDC синхронизатор, который можно применить в качеств элемента задержки -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Notes | -- | | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Change history | (1) 19.02.2018 - исправлен закомментированный кусок для вставки -- | | (2) 02.03.2018 - Регистр синхронизатор - отдельный модуль с внутренними констрейнами -- | | (3) 14.03.2018 - Убран отдельный модуль CDC синхронизатора. Встроенные констрейны не работают. Да и неудобно. -- | | (3) 14.03.2018 - Убран параметр детектирования фронта посредством 2 регистров. Нет необходимости в парамтре -- | | (3) 14.03.2018 - Добавлен параметр регистрового выхода. Мало ли когда понадобится. -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- edge_dtct_comp : entity work.KAA_edge_dtct -- generic map -- ( -- clock_domain_sync => "Disable", -- Enable / Disable включение / выключение CDC- синхронизатора. Можно использовать как элемент задержки -- sync_stages => 3, -- Количество триггеров для синхронизации (или время задержки) -- edge_type => "Rising", -- Rising / Falling / All_edge тип детектированного фронта -- Individual_wire_for_edge => "Disable", -- edge(0) - rising edge(1) - faling -- Reg_output => "Enable" -- Enable / Disable включение/выключение регистрового выхода (создает дополнительную задержку в 1 такт) -- ) -- port map -- ( -- clk => -- input => -- edge(0) => -- ); -- ———————————————————————————————————————————————————————————————————————————————— —————————————————————————————————————————————————————— --================================================================================ ====================================================== -- Пакет для функции, которая нужна для определения разрядности выходной шины если включен режим Individual_wire_for_edge -- Пакет должен идти перед описанием модуля KAA_edge_dtct. Иначе Modelsim не поддецпит его и будет ругаться на отуствтие пакета. --================================================================================ ====================================================== library ieee; use ieee.std_logic_1164.all; package KAA_edge_dtct_pkg is function type_wire ( a : string; b : string ) return natural; end package; package body KAA_edge_dtct_pkg is function type_wire ( a : string; b : string ) return natural is begin if (a = "Enable" and b = "All_edge") then return 1; else return 0; end if; end type_wire; end package body; --================================================================================ ====================================================== -- Собственно модуля KAA_edge_dtct --================================================================================ ====================================================== library ieee; use ieee.std_logic_1164.all; use work.KAA_edge_dtct_pkg.all; entity KAA_edge_dtct is generic ( Clock_domain_sync : string := "Enable"; -- Enable / Disable включение / выключение CDC- синхронизатора. Можно использовать как элемент задержки Sync_stages : natural := 1; -- Количество триггеров для синхронизации (или время задержки) Edge_type : string := "Falling"; -- Rising / Falling / All_edge тип детектированного фронта Individual_wire_for_edge : string := "Disable"; -- Enable / Disable включение отдельного выхода для каждого типа стрба режиме если включен режим all_edge Reg_output : string := "Disable" -- Enable / Disable включение/выключение регистрового выхода (создает дополнительную задержку в 1 такт) ); port ( clk : in std_logic; input : in std_logic; edge : out std_logic_vector(type_wire(a => individual_wire_for_edge, b => Edge_type ) downto 0) -- Функция определена в KAA_edge_dtct_pkg (выше по тексту) ); end entity; architecture RTL of KAA_edge_dtct is signal CDC_sync : std_logic_vector(sync_stages - 1 downto 0) := (others => '0'); -- Сдвиговый регистр - синхронизатор (или линия задержки signal input_stable : std_logic := '0'; -- Промежуточный сигнал для возможности подключения синхронизатора signal edge_detector : std_logic := '0'; -- Регистр для детектирования фронта begin --================================================================================ =========== -- Если включён входной синхронизатор, пропустим данные через сдвиговый регистр -- (2) Добавил отдельный модуль синхронизатор. -- (3) Убрал отдельный модуль синхронизатор. Неудобно. И констрейны не работают... --================================================================================ =========== clock_domain_sync_enable_generating : if (clock_domain_sync = "Enable") generate CDC_sync_proc : process (clk) begin if (rising_edge(clk)) then if (Sync_stages = 1) then -- Если стадий синхронизации 1 - то записшем сразу в регистр (сделано чтобы не Quartus не ругался на null_rage) CDC_sync(CDC_sync'left) <= input; else CDC_sync <= CDC_sync(sync_stages - 2 downto 0) & input; end if; end if; end process; input_stable <= CDC_sync(CDC_sync'left); end generate; --================================================================================ ====================================== -- Если отключён входной синхронизатор, считается что данные стабильны т.к формируются в том-же клоковом домене. --================================================================================ ====================================== clock_domain_sync_disable_generating : if (clock_domain_sync = "Disable") generate input_stable <= input; end generate; --================================================================================ =========== -- Запишем входной сигнал в регистр для последующего детектирования фронтов --================================================================================ =========== signal_latch : process (clk) begin if (rising_edge(clk)) then edge_detector <= input_stable; end if; end process; --================================================================================ =========== -- Детектирование заднего фронта сигнала --================================================================================ =========== falling_edge_detection_generating : if (edge_type = "Falling") generate --================================================================================ =========== -- Если включен регистровый выход (3) --================================================================================ =========== Reg_output_enable_generate : if (Reg_output = "Enable") generate edge(0) <= not input_stable and edge_detector when rising_edge(clk); end generate; --================================================================================ =========== -- Если выключен регистровый выход --================================================================================ =========== Reg_output_disable_generate : if (Reg_output = "Disable") generate edge(0) <= not input_stable and edge_detector; end generate; end generate; --================================================================================ =========== -- Детектирование переднего фронта сигнала --================================================================================ =========== rising_edge_detection_generating : if (edge_type = "Rising") generate --================================================================================ =========== -- Если включен регистровый выход (3) --================================================================================ =========== Reg_output_enable_generate : if (Reg_output = "Enable") generate edge(0) <= not edge_detector and input_stable when rising_edge(clk); end generate; --================================================================================ =========== -- Если выключен регистровый выход --================================================================================ =========== Reg_output_disable_generate : if (Reg_output = "Disable") generate edge(0) <= not edge_detector and input_stable; end generate; end generate; --================================================================================ =========== -- Детектирование всех фронтов сигнала если нужен только один выход из модуля --================================================================================ =========== non_individual : if (individual_wire_for_edge = "Disable" and edge_type = "All_edge" ) generate --================================================================================ =========== -- Если включен регистровый выход (3) --================================================================================ =========== Reg_output_enable_generate : if (Reg_output = "Enable") generate edge(0) <= edge_detector xor input_stable when rising_edge(clk); end generate; --================================================================================ =========== -- Если выключен регистровый выход --================================================================================ =========== Reg_output_disable_generate : if (Reg_output = "Disable") generate edge(0) <= edge_detector xor input_stable; end generate; end generate; --================================================================================ =========== -- Детектирование всех фронтов сигнала. Каждый фронт имеет отдельный выход --================================================================================ =========== individual : if (individual_wire_for_edge = "Enable" and edge_type = "All_edge" ) generate --================================================================================ =========== -- Если включен регистровый выход (3) --================================================================================ =========== Reg_output_enable_generate : if (Reg_output = "Enable") generate edge(0) <= not edge_detector and input_stable when rising_edge(clk); -- Rising edge(1) <= not input_stable and edge_detector when rising_edge(clk); -- Faling end generate; --================================================================================ =========== -- Если выключен регистровый выход --================================================================================ =========== Reg_output_disable_generate : if (Reg_output = "Disable") generate edge(0) <= not edge_detector and input_stable; -- Rising edge(1) <= not input_stable and edge_detector; -- Faling end generate; end generate; --================================================================================ =========== -- Проверка правильности ввода парамтеров Clock_domain_sync --================================================================================ =========== assert (Clock_domain_sync = "Enable" or Clock_domain_sync = "Disable") report LF& "Incorrect parametr 'Clock_domain_sync'. Check the syntax !" &LF& "Note : parametr case-sensitive !"&LF severity error; --================================================================================ =========== -- Проверка правильности ввода парамтеров Edge_type --================================================================================ =========== assert (Edge_type = "Rising" or Edge_type = "Falling" or Edge_type = "All_edge") report LF& "Incorrect parametr 'Edge_type'. Check the syntax !" &LF& "Note : parametr case-sensitive !"&LF severity error; --================================================================================ =========== -- Проверка правильности ввода парамтеров Reg_output (3) --================================================================================ =========== assert (Reg_output = "Enable" or Reg_output = "Disable") report LF& "Incorrect parametr 'Reg_output'. Check the syntax !" &LF& "Note : parametr case-sensitive !"&LF severity error; end architecture; Ну и отдельным файлом для скачивания.: KAA_edge_dtct.vhd Критикуйте, если есть ляпы :rolleyes: . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 22 июня, 2018 Опубликовано 22 июня, 2018 · Жалоба Тоже в связи с частыми вопросами про дребезг я решил выложить сюда свой модуль антидребезга. Параметрами модуля можно ностроить: 1. Разрядность счетчика - определяющее время интегрирования. 2. Количество регистров-синхронизаторов для синхронизации с клоковым доменом. 3. Какой лог. уровень соответствует нажатой кнопке. Как всегда приветствуются все замечания и предложения. -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | File name | KAA_button_debouncer | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Properties | Tab type = space | HDL type = VHDL2008 | Languege - Russian | Syntesis tool = Quartus 13.1 | Sim = Modelsim ASE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Author | Клементьев Алексей Александрович | Email = [email protected] -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Description | Антидребезг кнопки с синхронизатором CDC и выбором активного уровня нажатой кнопки. -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Notes | 1. В модуле предусмотрена настройка какому лог. уровню соответствует нажатая кнопка. -- | | За счет этого у нас сигнал-флаг нажатой кнопки всегда имеет логический уровень "1" -- | | 2. Сдвиговый регистр-синхронизатор не может быть менше 2 разрядов. -- | | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Change history | -- | | -- | | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- KAA_button_debouncer_comp : entity work.KAA_button_debouncer -- generic map -- ( -- active_level => "Negative", --"Positive" / "Negative" Активный уровень нажатой кнопки -- sync_stages => 3, -- Количество стадий синхронизации с клоковым доменом -- debouncer_width => 7 -- Разрядность счетчика, который досчитав до конца выдаст фалг нажатой кнопки -- ) -- port map -- ( -- clk => -- debouncer_in => -- button_pressed => -- ); --———————————————————————————————————————————————————————————————————————————————— —————————————————————————————————————————————————————— library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity KAA_button_debouncer is generic ( active_level : string := "Positive"; -- "Positive" / "Negative" Активный уровень нажатой кнопки sync_stages : natural := 3; -- Количество стадий синхронизации с клоковым доменом debouncer_width : natural := 6 -- Разрядность счетчика, который досчитав до конца выдаст фалг нажатой кнопки ); port ( clk : in std_logic; debouncer_in : in std_logic; button_pressed : out std_logic ); end entity; architecture rtl of KAA_button_debouncer is --===================================================================== -- Константы для удобства --===================================================================== constant up : std_logic := '1'; -- Нажатая кнопка - счетчик считает вверх constant down : std_logic := '0'; -- Кнопка отпущна - счетчик считает вниз signal shreg : std_logic_vector(sync_stages - 1 downto 0) := (others => '0'); -- Регистр - синхронизатор signal up_dissable : std_logic -- Сигнал отключения счета вверх signal down_dissable : std_logic -- Сигнал отключения счета вниз signal counter_unsigned : unsigned(debouncer_width -1 Downto 0) := (others => '0'); -- Счетчик begin --===================================================================== -- Синхронизируем сигнал с клоковым доменом. -- Так-же автоматически переводим активный уровень сигнала в лог.1 -- Это позволит на выходе иметь сигнал-флаг нажатой кнопки лог.1 --===================================================================== meta_harden_reg : process(clk) begin if (rising_edge(clk)) then if (active_level = "Positive") then -- Если активный уровнь лог.1 shreg <= shreg(shreg'left - 1 downto 0) & debouncer_in; -- То записываем сигнал в регистр как есть. end if; if (active_level = "Negative") then -- Если активный уровнь лог.1 shreg <= shreg(shreg'left - 1 downto 0) & (not debouncer_in); -- То записываем в ренгистр инверсию сигнала end if; end if; end process; --===================================================================== -- Сигналы отключения счета счетчика --===================================================================== up_dissable <= '1' when (counter_unsigned = (counter_unsigned'left downto 0 => '1')) else '0'; -- Если все единички - запрети счетчику считать вверх down_dissable <= '1' when (counter_unsigned = (counter_unsigned'left downto 0 => '0')) else '0'; -- Если все нолики - запрети счетчику считать вниз --===================================================================== -- Собственно сам счетчтик --===================================================================== cnt_proc : process(clk) begin if (rising_edge(clk)) then case shreg(shreg'left) is -- Анализируем сигнал перенесенный в наш клоковый домен when up => -- Если кнопка нажата if (up_dissable = '0') then -- Если счетчику не запрещено считать вверх counter_unsigned <= counter_unsigned + "1"; -- Инкрементируем счетчтик end if; when down => -- Если кнопка отпущена if (down_dissable = '0') then -- Если счетчику не запрещено считать вниза counter_unsigned <= counter_unsigned - "1"; -- Декрементируем счетчтик end if; when others => null; end case; end if; end process; --===================================================================== -- Выходной триггер для формирования сигнала-флага нажатой кнопки --===================================================================== output_flip_flop : process(clk) begin if (rising_edge(clk)) then case counter_unsigned is when (counter_unsigned'left downto 0 => '1') => button_pressed <= '1'; -- Счетчик досчитал до конца(все единцы) - значит кнопка была нажата when (counter_unsigned'left downto 0 => '0') => button_pressed <= '0'; -- Счетчик досчитал до конца(все нули) - считаем что была отпущена when others => null; -- В оостальных случаях триггер хранит свое значение end case; end if; end process; --================================================================================ =========== -- Счетчик не может быть равен 0 !! --================================================================================ =========== assert (debouncer_width /= 0) report LF& "Incorrect parametr 'debouncer_width'. Check the syntax !" &LF& "Note : parametr Must be > 0 !"&LF severity error; --================================================================================ =========== -- Проверка правильности параметров active_level --================================================================================ =========== assert (active_level = "Negative" or active_level = "Positive") report LF& "Incorrect parametr 'active_level'. Check the syntax !" &LF& "Note : parametr case-sensitive !"&LF severity failure; -- ================================================================================ =========== -- Разрядность регистра-синхронизатора не может быть меньше 2 ! --================================================================================ =========== assert (sync_stages >= 2) report LF& "Incorrect parametr 'sync_stages'. Check the syntax !" &LF& "Note : parametr Must be > 2 !"&LF severity error; end architecture; KAA_button_debouncer.vhd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 31 мая, 2019 Опубликовано 31 мая, 2019 · Жалоба В 22.06.2018 в 07:22, Flip-fl0p сказал: KAA_button_debouncer.vhd Не слишком ли много букв? debounce.vhd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 31 мая, 2019 Опубликовано 31 мая, 2019 · Жалоба 2 часа назад, _sda сказал: Не слишком ли много букв? debounce.vhd Когда встречаю такое use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; возникают очень сильные сомния в квалификации автора. Ну и без utils_pak этот код бесполезен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 31 мая, 2019 Опубликовано 31 мая, 2019 · Жалоба 2 часа назад, andrew_b сказал: Когда встречаю такое use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; возникают очень сильные сомния в квалификации автора. Если сомния есть - сомнийтесь на здоровье. Мне за мою более чем двадцатилетнюю практику работы с FPGA эта сладкая парочка не преподнесла ни одного сюрприза. 2 часа назад, andrew_b сказал: Ну и без utils_pak этот код бесполезен. Это только Ваше уникальное мнение. В этом файле,в частности, просто описание типов sl и slv, которые и так понятны, но уменьшают количество букв(std_logic и std_logic_vector). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 31 мая, 2019 Опубликовано 31 мая, 2019 · Жалоба 12 часов назад, _sda сказал: Не слишком ли много букв? debounce.vhd Букв достаточно, чтобы компонент можно было применять для любого вида кнопок с любым активным уровнем. Алгоритм простой: Мы настраиваем порог, досчитав до которого делается вывод о том, что кнопка нажата. Т.е. если кнопка нажата - счетчик считает вверх. Кнопка отпущена - счетчик считает вниз. Соответственно если счетчик смог досчитать вверх - значит у нас формируется сигнал button_pressed равный лог.1, говорящая о том, что кнопка была нажата. Из преимуществ я вижу: 1. Возможность указания активного уровня сигнала, что позволит использовать любые кнопки. 2. Отсутствие привязки к активному уровню сигнала, за счет того, что нажатой кнопке всегда соответствует флаг button_pressed = '1' . 3. Максимальная простота работы модуля. 4. Хоть для современных FPGA уже не так актуально, однако мой модуль занимает минимальное количество ресурсов. 5. Контроль правильности вводимых параметров. 6. Защита от метастабильности. 7. Ну и самое главное, как я считаю - у меня достаточно подробно описано как, что и зачем в модуле сделано. В вашем модуле мне не нравится: 1. вот эта строчка: if (ireset = '1') then cnt <= (others => '0'); odata <= idata; Асинхронно установить триггер в то значение, которое на входе. И это значение выдать в качестве флага нажатой кнопки.... Ну не знаю, не знаю. А как-же борьба с метастабильностью ? Или Вы считаете, что асинхронная установка триггера лишена метастабильного состояния ? Да и по ресурсам как-то слишком много у Вас уходит на обработку банального дребезга. И идеологически я не считаю, что считывать состояния кнопки через какое-то время - это правильное решение. P.S. и я не экономлю строчки кода. Я экономлю время, которое затрачивается на разработку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба 11 часов назад, _sda сказал: Если сомния есть - сомнийтесь на здоровье. Ну посмейтесь над обычной опечаткой, если больше не над чем. Да и клавиатурка старенькая, иногда не срабатывает. 11 часов назад, _sda сказал: Мне за мою более чем двадцатилетнюю практику работы с FPGA эта сладкая парочка не преподнесла ни одного сюрприза. Это значит, что её нужно втыкать везде, где надо и где не надо? А кто это у нас тут строки считает? Неряшливый код означает неряшливость в мыслях. 11 часов назад, _sda сказал: Это только Ваше уникальное мнение. Разумеется, капитан Очевидность. Я где-то утверждал обратное? 11 часов назад, _sda сказал: В этом файле,в частности Я не телепат, чтобы знать, что там в коде, которого я не видел. Прошу извинить меня за этот маленький недостаток. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 17 января, 2020 Опубликовано 17 января, 2020 · Жалоба On 6/1/2019 at 2:40 AM, Flip-fl0p said: Т.е. если кнопка нажата - счетчик считает вверх. Кнопка отпущена - счетчик считает вниз. Соответственно Так это ж алгоритмически неверно. Нажата - увеличиваем. Ненажата - обнуляем. Иначе это не антидребезг совсем. Если счётчик достигнет порог-1 величины, то он же дальше будет этот самый дребезг пропускать на выход. Не так? Ну а если в обе стороны надо, то после достижения верхнего предела - наооборот. Декремент , если состояние изменилось, но если вернулось к прежнему - установка на максимум сразу. Иными словами - антидребезг срабатывает тогда, когда состояние кнопки противоположно изначальному N раз подряд без пропусков Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 18 января, 2020 Опубликовано 18 января, 2020 · Жалоба 15 часов назад, DASM сказал: Так это ж алгоритмически неверно. Нажата - увеличиваем. Ненажата - обнуляем. Иначе это не антидребезг совсем. Если счётчик достигнет порог-1 величины, то он же дальше будет этот самый дребезг пропускать на выход. Не так? Ну а если в обе стороны надо, то после достижения верхнего предела - наооборот. Декремент , если состояние изменилось, но если вернулось к прежнему - установка на максимум сразу. Иными словами - антидребезг срабатывает тогда, когда состояние кнопки противоположно изначальному N раз подряд без пропусков Почему алгоритмически неверно ? Изначально счетчик в нуле, что соответствует не нажатой кнопке. Флаг button_pressed = '0'. Затем мы нажали на кнопку. Счетчик начал считать вверх. Из-за дребезга у нас с выхода кнопки то нули то единицы. Соответственно счетчик считает то вверх, то вниз. Когда счетчик смог досчитать до значения 2**debouncer_width - 1 ( во всех разрядах счетчика единицы) - значит что нажатие кнопки действительно было, и она была нажата достаточное время. И мы выдаем флаг button_pressed = '1'. Ни о каком дребезге с кнопки речи быть не может. Флаг button_pressed станет снова нулем только тогда, когда счетчик досчитает до нуля ( во всех разрядах счетчика нули). Ежели у Вас такой сильный дребезг, что при нажатии кнопки счетчик прыгает от состояния "все единицы" <----> "все нули" - значит у вас сильно фиговая кнопка или неправильно настроен модуль - выбрана слишком маленькая разрядность счетчика, поэтому мы в настройках модуля выбираем бОльшую разрядность счетчика. Например debouncer_width => 7 меняем на debouncer_width => 15 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться