|
|
|
"Схемотехнические трюки для ПЛИСоводов", создание аналога "Алгоритмические трюки для программистов" |
|
|
|
Dec 30 2017, 12:39
|
Профессионал
Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757
|
Цитата(Александр77 @ Dec 30 2017, 14:17) В VHDL нет разницы между UP, Up, uP или up. Про Down можно сказать тоже самое. Тащемта там строка, а не перечислимый тип. Цитата(Flip-fl0p @ Dec 30 2017, 13:31) Можете сказать навскидку где вообще такой счетчик мог бы пригодится ? Дело в принципе. Если вы пишете модуль, претендующий на универсальность, пишите его на самом деле универсальным, с минимальным количеством ограничений.
|
|
|
|
|
Dec 30 2017, 12:58
|
В поисках себя...
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140
|
Цитата(andrew_b @ Dec 30 2017, 15:39) Тащемта там строка, а не перечислимый тип.
Дело в принципе. Если вы пишете модуль, претендующий на универсальность, пишите его на самом деле универсальным, с минимальным количеством ограничений. Понял. Учтем ! А вообще в VHDL сделать модуль полностью универсальным очень сложно. Например я как-то хотел сделать модуль полностью настраиваемым. Т.е в области generic настраивать все возможные комбинации входных и выходных портов. Например если нужен сигнал синхронного сброса, сигнал переноса, разрешения работы, и пр то их можно включить просто настройкой параметров модуля. Но столкнулся с проблемой отсутствием возможности генерировать по условию входные\выходные порты. Вернее не так, возможность есть, но она очень кривая и модуль выдает кучу предупреждений. Хотя синтезируется нормально. Иногда даже жалко что у VHDL нет предпроцессора.
|
|
|
|
|
Jan 22 2018, 14:36
|
Частый гость
Группа: Участник
Сообщений: 90
Регистрация: 16-11-10
Пользователь №: 60 920
|
Цитата(ViKo @ Nov 13 2017, 14:27) Вот. Последние варианты (4 и 5, одинаковые). Остальные показывают процесс разработки. :-) CODE `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 меньше от желаемого значения счета.
|
|
|
|
|
Apr 16 2018, 08:40
|
Знающий
Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847
|
Простенький ФНЧ Uout = Uout-1 + (Utek - Uout-1)>> K Выручал неоднократно... Делюсь Все-таки добавлю к нему TestBanch...
Прикрепленные файлы
IQ_filtr.vhd ( 1.93 килобайт )
Кол-во скачиваний: 34
IQ_tb.vhd ( 2.49 килобайт )
Кол-во скачиваний: 13
RND.vhd ( 9.17 килобайт )
Кол-во скачиваний: 21
|
|
|
|
|
Apr 23 2018, 11:01
|
я только учусь...
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839
|
Цитата(Nerevarine @ Apr 20 2018, 16:25) Ребят... Тут скорее не трюк нужен, а какое-то схемное решение / конфигурация ПЛИС.
Проблема следующая: при подаче питания на FPGA (Cyclone 4 E) на выводах I/O банков появляется единица (подтяжка к Vcc) на время инициализации (загрузки прошивки из EPCS16). Длится это безобразие ~100-200 us, что ни в какие ворота... Банки питаются от 3.3В. Где-то читал, что выводы якобы должны быть в третьем состоянии и что порядок установки напряжений не важен для современных ПЛИС Altera или Intel, как Вам угодно)).
Вторая проблема, пока менее важная, это выбросы на I/O выходах во время сброса питания. Кто сталкивался с подобным? Куда тут копнуть? Напряжение ядра надо подать раньше, чем напряжение банок?
P.S. ПЛИС находится на отладочной плате, схема питания (и всего остального) прилагается в PDF [attachment=112179:Developm...ram_V2.1.pdf] переместить в ветку https://electronix.ru/forum/index.php?showforum=15
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
|
May 14 2018, 06:53
|
В поисках себя...
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140
|
Поскольку в последнее время часто возникает вопрос про детекторы фронта, то выложу сюда свой модуль детектора. Собственно сам текст: CODE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | File name | KAA_edge_dtct | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Properties | Tab type = space | HDL type = VHDL2008 | Languege - Russian | Syntesis tool = Quartus 13.1 | Sim = Modelsim ASE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Author | Клементьев Алексей Александрович | Email = KJIEMEHTbEB@gmail.com -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | 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 ( 18.61 килобайт )
Кол-во скачиваний: 61Критикуйте, если есть ляпы .
|
|
|
|
|
Jun 22 2018, 04:22
|
В поисках себя...
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140
|
Тоже в связи с частыми вопросами про дребезг я решил выложить сюда свой модуль антидребезга. Параметрами модуля можно ностроить: 1. Разрядность счетчика - определяющее время интегрирования. 2. Количество регистров-синхронизаторов для синхронизации с клоковым доменом. 3. Какой лог. уровень соответствует нажатой кнопке. Как всегда приветствуются все замечания и предложения. CODE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | File name | KAA_button_debouncer | -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Properties | Tab type = space | HDL type = VHDL2008 | Languege - Russian | Syntesis tool = Quartus 13.1 | Sim = Modelsim ASE -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | Author | Клементьев Алексей Александрович | Email = KJIEMEHTbEB@gmail.com -- ————————————————— ———————————————————————————————————————————————————————————————————————————————— ———————————————————————————————— -- | 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 ( 12.56 килобайт )
Кол-во скачиваний: 11
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|