jenya7 0 10 января, 2019 Опубликовано 10 января, 2019 (изменено) · Жалоба 8 minutes ago, Zig said: Уточню замечание У вас f_count считается на частоте FREQ_IN, а защелкивается в регистр COUNTER на частоте CLK. И что за хитровывернутость с сигналом reset? да. криво. понимаю. но я не нашел другого способа защелкнуть и обнулить f_count. есть другой способ? Изменено 10 января, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 10 января, 2019 Опубликовано 10 января, 2019 · Жалоба 8 минут назад, jenya7 сказал: Так нет опоры. Задача померять асинхронно. Пины взял посто которые было удобно использовать. --in entity FREQ_IN : in std_logic; --AB3 FREQ_OUT1 : out std_logic; --Y3 FREQ_OUT2 : out std_logic; --Y4 FREQ_OUT3 : out std_logic; --Y5 --in architecture FREQ_OUT1 <= clk_120M; FREQ_OUT2 <= clk_100M; FREQ_OUT3 <= clk_60M; U_PLL : pll port map ( inclk0 => MAX10_CLK2_50, c0 => clk_100M, c1 => clk_120M, c2 => clk_150M, c3 => clk_60M ); А вы не подумали, что я могу не знать какую fpga вы применяемое ? Более того у меня может не быть соответствующего софта, чтобы глянуть за вас распиновку. .. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 10 января, 2019 Опубликовано 10 января, 2019 · Жалоба 7 minutes ago, Flip-fl0p said: А вы не подумали, что я могу не знать какую fpga вы применяемое ? Более того у меня может не быть соответствующего софта, чтобы глянуть за вас распиновку. .. я меряю на пинах соответствующую частоту. у меня нет такого осцилографа который померял бы точно. но значения близкие к тем что должен выдать PLL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 10 января, 2019 Опубликовано 10 января, 2019 · Жалоба Цитата да. криво. понимаю. но я не нашел другого способа защелкнуть и обнулить f_count. есть другой способ? Так есть пару простых способов: Первый: пишите фиговину который выдает сигнал пока у вас считается период, относительно которого вы меряете ваши "пульсы". Естественно Формируется этот сигнал в домене clk (100 Mhz). Посредством простенького синхронизатора вы переносите этот длинный сигнал в домен FREQ_IN. В домене FREQ_IN Вы выделяете передний фронт этого длинного сигнала, посредством простейшего детектора фронтов. Этот детектированный передний фронт - сигнал начала подсчета Ваших "пульсов". Так-же Вы выделяете задний фронт этого длинного сигнала, посредством простейшего детектора фронтов. Этот детектированный фронт - счигнал окончания подсчета количества Ваших "пульсов". Через несколько тактов (частоты FREQ_IN ) можете спокойно без всяких синхронизаторов переписать количество ваших "пульсов" в домен clk. Ибо данные у Вас стабильны и больше не меняются. Не забыть написать соответствующие констрейны что у вас доменыFREQ_IN и CLK асинхронные. К итоговой ppm добавится погрешность в пару тактов. Но тут ничего не сделать поскольку метастабильность никто не отменял. Второй способ: можно попробовать увеличить частоту клока, которым Вы периоды считаете. С частотой FREQ_IN работать не как с клоком, а как с данными. Тогда вам достаточно просто синхронизировать частоту FREQ_IN с доменом (clk), поставить детектор фронта и считать фронты. Точность будет повыше. Но и требования к частоте clk есть, т.к она должна быть как минимум в 2 раза выше чем частота FREQ_IN (вспоминаем теорему Котельникова, часто называют критерий Накйвиста). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reanimatorr 1 25 января, 2019 Опубликовано 25 января, 2019 · Жалоба Вам нужен счетчик импульсов или частотомер? Работать должен непрерывно или измеряет иногда? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 27 января, 2019 Опубликовано 27 января, 2019 · Жалоба On 1/26/2019 at 12:03 AM, Reanimator++ said: Вам нужен счетчик импульсов или частотомер? Работать должен непрерывно или измеряет иногда? счетчик импульсов за период это по сути частотометр. непрерывно или нет? даже не знаю. пока никакого синхронизирующего флага у меня нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 27 января, 2019 Опубликовано 27 января, 2019 · Жалоба 4 часа назад, jenya7 сказал: счетчик импульсов за период это по сути частотометр. непрерывно или нет? даже не знаю. пока никакого синхронизирующего флага у меня нет. Он хоть заработал ? Как в итоге Вы сделали ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 27 января, 2019 Опубликовано 27 января, 2019 (изменено) · Жалоба 3 hours ago, Flip-fl0p said: Он хоть заработал ? Как в итоге Вы сделали ? Последняя версия library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity FCOUNTER is port( RST :in std_logic; CLK :in std_logic; FREQ_IN :in std_logic; PERIOD :in Std_logic_vector(15 downto 0) := X"0064"; COUNTER :out Std_logic_vector(31 downto 0) ); end FCOUNTER; architecture STRUCTURE of FCOUNTER is signal ms_clock :std_logic := '0'; signal reset :std_logic := '0'; signal f_count : std_logic_vector(31 downto 0) := (others=>'0'); signal ms_count : std_logic_vector(15 downto 0) := (others=>'0'); signal count : std_logic_vector(31 downto 0) := (others=>'0'); begin process(FREQ_IN, reset) begin if (FREQ_IN'event and FREQ_IN = '1') then f_count <= count + '1'; end if; if (reset = '1') then COUNTER <= f_count; --ticks per period f_count <= (others=>'0'); end if; end process; process(ms_clock) begin if (rising_edge(ms_clock)) then ms_count <= ms_count + '1'; if ( ms_count = PERIOD) then --milliseconds ms_count <= (others=>'0'); reset <= '1'; end if; if (reset = '1') then reset <= '0'; end if; end if; end process; process(CLK) --100 Mhz begin if (rising_edge(CLK)) then count <= count + '1'; --49999 if (count = X"0000C34F") then --50000 - 500us count <= (others=>'0'); ms_clock <= not ms_clock; --tick 500us end if; end if; end process; end STRUCTURE; На периоде 1 сек. погрешность +/- 2ppm. Изменено 27 января, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 27 января, 2019 Опубликовано 27 января, 2019 · Жалоба 1 час назад, jenya7 сказал: Последняя версия На периоде 1 сек. погрешность +/- 2ppm. А Вы упертый товарищ... Какая-то у Вас странная забава. Задать вопрос, получить ответы. Но в итоге сделать по-своему и при этом неправильно... Да Ваш код может даже почти всегда считает правильно. Однако у него есть один серьезнейший недостаток: В момент совпадения фронта FREQ_IN и сигнала reset Вы на выходе иногда будете получать очень "странный" результат. Ну что же. Ждем от Вас новой темы с вопросом, почему Ваш "идеальный" код сбоит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 27 января, 2019 Опубликовано 27 января, 2019 · Жалоба 2 jenya7 Ну и если уж все равно наплевали на метастабильность, то зачем было делать ms_clock? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 27 января, 2019 Опубликовано 27 января, 2019 (изменено) · Жалоба 9 minutes ago, Flip-fl0p said: А Вы упертый товарищ... Какая-то у Вас странная забава. Задать вопрос, получить ответы. Но в итоге сделать по-своему и при этом неправильно... Да Ваш код может даже почти всегда считает правильно. Однако у него есть один серьезнейший недостаток: В момент совпадения фронта FREQ_IN и сигнала reset Вы на выходе иногда будете получать очень "странный" результат. Ну что же. Ждем от Вас новой темы с вопросом, почему Ваш "идеальный" код сбоит. я понял. следующий шаг добавить еще один флаг синхронизирующий FREQ_IN и период. 5 minutes ago, dvladim said: 2 jenya7 Ну и если уж все равно наплевали на метастабильность, то зачем было делать ms_clock? считать период? ой. извиняюсь. моя ошибка. вот последняя версия. library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity FCOUNTER is port( RST :in std_logic; CLK :in std_logic; FREQ_IN :in std_logic; PERIOD :in Std_logic_vector(15 downto 0) := X"03E8"; COUNTER :out Std_logic_vector(31 downto 0) ); end FCOUNTER; architecture STRUCTURE of FCOUNTER is signal ms_clock :std_logic := '0'; signal reset :std_logic := '0'; signal f_count : std_logic_vector(31 downto 0) := (others=>'0'); signal ms_count : std_logic_vector(15 downto 0) := (others=>'0'); signal count : std_logic_vector(31 downto 0) := (others=>'0'); signal clk1 : std_logic := '0'; signal clk2 : std_logic := '0'; signal clk3 : std_logic := '0'; signal clk4 : std_logic := '0'; begin clk3 <= not clk1 and clk2; process(FREQ_IN, reset) begin if (FREQ_IN'event and FREQ_IN = '1') then f_count <= f_count + '1'; end if; if (reset = '1') then --COUNTER <= f_count; --ticks per period f_count <= (others=>'0'); end if; end process; process(CLK) --100 Mhz begin if (rising_edge(CLK)) then count <= count + '1'; --99999 if (count = X"0001869F") then --100000 - 1ms count <= (others=>'0'); ms_count <= ms_count + '1'; end if; if (ms_count = PERIOD) then --milliseconds ms_count <= (others=>'0'); COUNTER <= f_count; --ticks per period reset <= '1'; end if; if (reset = '1') then --do it one clock reset <= '0'; end if; end if; end process; end STRUCTURE; Изменено 27 января, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 27 января, 2019 Опубликовано 27 января, 2019 · Жалоба Вот один из вариантов решения задачи. Из готовых модулей его можно собрать минут за 5. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity freq_meter is port ( clk : in std_ulogic; -- Частота основной логики измерения start : in std_ulogic; -- Запуск измерения meas_time : in std_ulogic_vector(31 downto 0); -- measurement_time meas_freq : in std_ulogic; -- Measured frequency result : out std_ulogic_vector(31 downto 0); -- measurement result result_valid : out std_ulogic -- Сигнал валидности result (сформируйте его уже сами) ); end entity; architecture RTL of freq_meter is signal prd_counter : unsigned(31 downto 0) := (others => '0'); -- Наш счетчик периода --===================================================================== -- Наш JK-триггер, можно без него, написав простенький автомат -- Но лично мне с триггером понятнее. --===================================================================== signal J : std_ulogic; -- Сигнал установки триггера signal K : std_ulogic; -- Сигнал сброса триггера signal Q : std_ulogic := '0'; -- Выход триггера signal syncronizer : std_ulogic_vector(2 downto 0) := (others => '0'); -- Синхронизатор с клоковым доменом meas_freq signal edge_detector : std_ulogic := '0'; -- DFF Для детектирования фронтов signal Redge : std_ulogic; -- Сигнал-флаг детектированного переднего фронта signal Fedge : std_ulogic; -- Сигнал-флаг детектированного заднего фронта signal meas_counter : unsigned(31 downto 0) := (others => '0'); -- Счетчик, который считает "пульсы" за период begin -- Алгоритм такой: пришла команда запуска - мы загружаем в вычитающий счетчик период измерения -- Одновременно с загрузкой данных в счетчик, мы усанавливаем наш JK триггер в единичку. -- Когда счетчик отсчитает наш период (от значения meas_time до 0) у нас сбросится JK триггер. -- Таким несложным способом мы формируем длинный сигнал пока у нас счетчик отсчитывает период --=============================================================================================== -- Счетчик с синхронной загрузкой. У меня это всегда отдельный модуль с параметрами --=============================================================================================== counter_sload : process(clk) begin if (rising_edge(clk)) then prd_counter <= prd_counter - "1"; -- Вычитающий счетчик if (start = '1') then -- Когда пришла команда начать измерения prd_counter <= unsigned(meas_time); -- Загружаем в счетчик период измерения end if; end if; end process; --=========================================================== -- JK триггер. У меня это отдельный модуль с параметарми --=========================================================== JKFF : process(clk) variable JplusK : unsigned(1 downto 0) := (others => '0'); begin if (rising_edge(clk)) then JplusK := J & K; case JplusK is when "00" => Q <= Q; when "01" => Q <= '0'; when "10" => Q <= '1'; when "11" => Q <= not Q; when others => null; end case; end if; end process; J <= start; -- Пришла команда запуска устанавливаем JK в единицу K <= '1' when (prd_counter = (31 downto 0 => '0')) else '0'; -- Счетчик отсчитал период - сбрасываем наш JK тригер --================================================================================== -- Сдвиговый регистр синхронизатор -- У меня это тоже отдельный модуль, с правильными атрибутами синтеза -- Этим регистром мы переносим наш длинный сигнал c JK триггера в домен meas_freq --================================================================================== process(meas_freq) begin if (rising_edge(meas_freq)) then syncronizer <= syncronizer(syncronizer'left - 1 downto 0) & q; end if; end process; --========================================================================= -- DFF Триггер для детектирования фронтов -- У меня это тоже отдельный модуль... --========================================================================= process(meas_freq) begin if (rising_edge(meas_freq)) then edge_detector <= syncronizer(syncronizer'left); end if; end process; Redge <= not edge_detector and syncronizer(syncronizer'left); -- Детектируем передний фронт Fedge <= not syncronizer(syncronizer'left) and edge_detector; -- Детектируем задний фронт --====================================================================== -- Считаем количество "пульсов" за период -- И опять, же у меня это всегда отдельный модуль с параметрами. --====================================================================== process(meas_freq) begin if (rising_edge(meas_freq)) then meas_counter <= meas_counter + "1"; if (Redge = '1') then -- Передним фронтом нашего длинного сигнала meas_counter <= (others => '0'); -- Сбрасываем счетчик (подготсвливаем для счета) end if; end if; end process; process(meas_freq) begin if (rising_edge(meas_freq)) then if (Fedge = '1') then -- Задним фронтом result <= std_ulogic_vector(meas_counter); -- Мы переписываем результат в отдельный триггер end if; end if; end process; -- Чтобы было совсем правильно, надо сформировать сигнал result_valid, который сообщает, что данные result правильные, и их можно забрать. -- Естественно, что result_valid должен быть синхронен домену CLK. -- А сам result можно не синхронизировать.... если будет result_valid. -- Но это уже сами. -- Вообще, есть много вариантов измерителя "пульсов" за период. Можно вообще попробовать применить счетчик Грея. -- Всё в Ваших руках end architecture; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 января, 2019 Опубликовано 28 января, 2019 · Жалоба спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reanimatorr 1 1 февраля, 2019 Опубликовано 1 февраля, 2019 · Жалоба On 1/27/2019 at 10:36 AM, jenya7 said: счетчик импульсов за период это по сути частотометр. непрерывно или нет? даже не знаю. пока никакого синхронизирующего флага у меня нет. Еще раз. Частотомеров разных видов очень много. Вам таки надо измерять частоту или считать импульсы за период? Если измерять частоту то с какой точностью и за какое время? Если это таки частотомер то он может измерить частоту, затем подождать немного, а затем снова измерять? Или нельзя пропустить ни одного импульса? Что является источником опорного сигнала? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 августа, 2019 Опубликовано 22 августа, 2019 (изменено) · Жалоба интересно а это должно работать если частота больше тактирующей частоты? process(meas_freq) begin if (rising_edge(meas_freq)) then meas_counter <= meas_counter + "1"; if (Redge = '1') then -- Передним фронтом нашего длинного сигнала meas_counter <= (others => '0'); -- Сбрасываем счетчик (подготсвливаем для счета) end if; end if; end process; у меня FPGA клокируется от осцилятора 30 мега а на ножку приходит 100 мега. Изменено 22 августа, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться