georgy31 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Подскажите малограмотному, как в Верилоге вывести среднее значение переменного сигнала. Компаратор сравнивает 50 сигналов, синхронизированные по переднему фронту, но отличающиеся по длительности на заднем фронте. Разница выводится на индикацию, но сигналы меняются так быстро, что на выходе каша. Как можно вывести среднее значение? Заранее благодарен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Приветствую! Подскажите малограмотному, как в Верилоге вывести среднее значение переменного сигнала. Компаратор сравнивает 50 сигналов, синхронизированные по переднему фронту, но отличающиеся по длительности на заднем фронте. Разница выводится на индикацию, но сигналы меняются так быстро, что на выходе каша. Как можно вывести среднее значение? Заранее благодарен. В Verilog, как это не странно, значение среднего считается так же как и в математике - просуммировали N значений - поделили на N (ни какой оригинальности :) ) А вот реализация зависит от того что Вы хотите получить ОДНО средне за каждые N осчетов или скользящее среднее за ПОСЛЕДНИЕ N осчетов. Ну и если не критично усреднять проще на степень 2- тогда вместо деления можно использовать простой сдвиг. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=SSN= 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба (ни какой оригинальности :) ) И тем не менее, написав "ни какой" раздельно, вы умудрились таки эту оригинальность проявить.. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
georgy31 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Спасибо за ответ. Значит я все 50 складываю, потом делю на 50, потом вывожу на индикацию полученное значение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=SSN= 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Значит я все 50 складываю, потом делю на 50.. Прежде, чем что-то делить, хорошо бы научиться умножать: SUM/50 = SUM*(0.02*2**N)>>>N; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Спасибо за ответ. Значит я все 50 складываю, потом делю на 50, потом вывожу на индикацию полученное значение? деление на 50 придется делать в виде модуля целочисленного деления или описать: int divs100(int n) { int q, r; n = n + (n>>31 & 99); q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) + (n >> 12) + (n >> 13) - (n >> 16); q = q + (q >> 20); q = q >> 6; r = n - q*100; return q + ((r + 28) >> 7); // return q + (r > 99); } в конце сделать еще умножение на 2 (сдвигом) ЗЫ для деления лучще степень двойки 32 или 64 - операция сдвига на нужное количество разрядов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Приветствую! Спасибо за ответ. Значит я все 50 складываю, потом делю на 50, потом вывожу на индикацию полученное значение? Да, но деление (не на степень 2) в железе дорогое "удовольствие", если уж сильно критично усреднять 50 значений то проще нормировать умножением на обратную величину. Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
georgy31 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Мне нужно усреднить значение выхода S1. Я его прописываю как регистр и складываю. Потом по приходу тактирующего импульса CM делю на число импульсов и вывожу результат? Это надо конечный автомат писать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Мне нужно усреднить значение выхода S1. Я его прописываю как регистр и складываю. Потом по приходу тактирующего импульса CM делю на число импульсов и вывожу результат? Это надо конечный автомат писать? лучше, pipeline архитектура складываете все, потом например используете это или это Выбор зависит от "как часто будет приходить" импульс CM, успеет ли конечный автомат посчитать до прихода следующего импульса подсчет импульсов, примерно такой можно использовать: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pulse_len_measure is generic ( N : integer:=8); port ( i_clk : in std_logic; i_rstb : in std_logic; i_input : in std_logic; o_pulse_len_hi : out std_logic_vector(N-1 downto 0); o_pulse_len_lo : out std_logic_vector(N-1 downto 0)); end pulse_len_measure; architecture rtl of pulse_len_measure is constant C_MAX_COUNT : unsigned(N-1 downto 0):=(others=>'1'); signal r_count_hi_ena : std_logic; signal r_count_hi : unsigned(N-1 downto 0); signal r_count_lo : unsigned(N-1 downto 0); signal r_count_lo_ena : std_logic; signal r_rise : std_logic; signal r_fall : std_logic; signal p_input : std_logic_vector(0 to 2); -- input pipe begin p_edge_detector : process(i_clk,i_rstb) begin if(i_rstb='0') then r_rise <= '0'; r_fall <= '0'; p_input <= (others=>'0'); elsif(rising_edge(i_clk)) then r_rise <= not p_input(2) and p_input(1); r_fall <= not p_input(1) and p_input(2); p_input <= i_input&p_input(0 to p_input'length-2); end if; end process p_edge_detector; p_count_hi : process(i_clk,i_rstb) begin if(i_rstb='0') then r_count_hi_ena <= '0'; r_count_hi <= to_unsigned(1,N); o_pulse_len_hi <= (others=>'0'); elsif(rising_edge(i_clk)) then if(r_rise='1') then r_count_hi_ena <= '1'; elsif(r_fall='1') then r_count_hi_ena <= '0'; o_pulse_len_hi <= std_logic_vector(r_count_hi); end if; if(r_count_hi_ena='1') then if(r_count_hi<C_MAX_COUNT)then r_count_hi <= r_count_hi + 1; end if; else r_count_hi <= to_unsigned(1,N); end if; end if; end process p_count_hi; p_count_lo : process(i_clk,i_rstb) begin if(i_rstb='0') then r_count_lo_ena <= '0'; r_count_lo <= to_unsigned(1,N); o_pulse_len_lo <= (others=>'0'); elsif(rising_edge(i_clk)) then if(r_fall='1') then r_count_lo_ena <= '1'; elsif(r_rise='1') then r_count_lo_ena <= '0'; o_pulse_len_lo <= std_logic_vector(r_count_lo); end if; if(r_count_lo_ena='1') then if(r_count_lo<C_MAX_COUNT) then r_count_lo <= r_count_lo + 1; end if; else r_count_lo <= to_unsigned(1,N); end if; end if; end process p_count_lo; end rtl;library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pulse_len_measure is generic ( N : integer:=8); port ( i_clk : in std_logic; i_rstb : in std_logic; i_input : in std_logic; o_pulse_len_hi : out std_logic_vector(N-1 downto 0); o_pulse_len_lo : out std_logic_vector(N-1 downto 0)); end pulse_len_measure; architecture rtl of pulse_len_measure is constant C_MAX_COUNT : unsigned(N-1 downto 0):=(others=>'1'); signal r_count_hi_ena : std_logic; signal r_count_hi : unsigned(N-1 downto 0); signal r_count_lo : unsigned(N-1 downto 0); signal r_count_lo_ena : std_logic; signal r_rise : std_logic; signal r_fall : std_logic; signal p_input : std_logic_vector(0 to 2); -- input pipe begin p_edge_detector : process(i_clk,i_rstb) begin if(i_rstb='0') then r_rise <= '0'; r_fall <= '0'; p_input <= (others=>'0'); elsif(rising_edge(i_clk)) then r_rise <= not p_input(2) and p_input(1); r_fall <= not p_input(1) and p_input(2); p_input <= i_input&p_input(0 to p_input'length-2); end if; end process p_edge_detector; p_count_hi : process(i_clk,i_rstb) begin if(i_rstb='0') then r_count_hi_ena <= '0'; r_count_hi <= to_unsigned(1,N); o_pulse_len_hi <= (others=>'0'); elsif(rising_edge(i_clk)) then if(r_rise='1') then r_count_hi_ena <= '1'; elsif(r_fall='1') then r_count_hi_ena <= '0'; o_pulse_len_hi <= std_logic_vector(r_count_hi); end if; if(r_count_hi_ena='1') then if(r_count_hi<C_MAX_COUNT)then r_count_hi <= r_count_hi + 1; end if; else r_count_hi <= to_unsigned(1,N); end if; end if; end process p_count_hi; p_count_lo : process(i_clk,i_rstb) begin if(i_rstb='0') then r_count_lo_ena <= '0'; r_count_lo <= to_unsigned(1,N); o_pulse_len_lo <= (others=>'0'); elsif(rising_edge(i_clk)) then if(r_fall='1') then r_count_lo_ena <= '1'; elsif(r_rise='1') then r_count_lo_ena <= '0'; o_pulse_len_lo <= std_logic_vector(r_count_lo); end if; if(r_count_lo_ena='1') then if(r_count_lo<C_MAX_COUNT) then r_count_lo <= r_count_lo + 1; end if; else r_count_lo <= to_unsigned(1,N); end if; end if; end process p_count_lo; end rtl; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
georgy31 0 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Тактовая частота 36 мГц. Время для подсчёта среднего почти 4мС. Думает не хватит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Тактовая частота 36 мГц. Время для подсчёта среднего почти 4мС. Думает не хватит? Вам решать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 19 декабря, 2016 Опубликовано 19 декабря, 2016 · Жалоба Тактовая частота 36 мГц.Да, 36 миллигерц, прямо скажем, немного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
georgy31 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Может я велосипед изобретаю? Мне нужно подсчитать среднее изменение фазы Р1, за период CM, это изменение равно S1. Сейчас там стоит аналоговый фазовый детектор. Можно ли его в ПЛИС всунуть? Есть всего лишь 500 свободных ЛУТов. Может не стоит и завязываться? Тем более, что я не сильно в программировании разбираюсь, в основном работаю в графическом редакторе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Приветствую! Может я велосипед изобретаю? Мне нужно подсчитать среднее изменение фазы Р1, за период CM, это изменение равно S1. Сейчас там стоит аналоговый фазовый детектор. Можно ли его в ПЛИС всунуть? Есть всего лишь 500 свободных ЛУТов. К тому же Вы и нас к этому велосипеду привлекаете да еще и угадывать приходится сколько колес должно быт :) Неточность постановки задачи влечет ошибки в ее решении. Насколько мои телепатические способности (а также зрение) позволяют понят - Вы хотите усреднить разность фаз между импульсными сигналами P1 и QtrS за 50 циклов. Единицей измерения является такт Clk, Если еще поработать провидцем и предположить что разность фаз может быть знаковая то Все что Вам нужно это ВСЕГО 3 счетчика - 1 реверсивный счетчик считает по МОДУЛЮ 50 разность фаз в цикле, второй реверсивный считает число модулей первого - это и будет усредненное значение разности фаз ДЕЛЕННОЕ на 50 :laughing: ну а 3 считает 50 циклов измерения в конце которого результат измерения будет в счетчике 2. И да - подбирая модуль деления 1 счетчика (а может и величину приращения 1и 2) можно при необходимости сразу получить на выходе нормировку в нужных физических величинах. И ни делителей ни умножителей ни CPU c DSP - скукота ;) Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
georgy31 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Разность фаз не знаковая, а всегда положительная, причём только по заднему фронту. По переднему обе фазы одинаковы. Да, похоже я не правильно сформулировал задачу. На рассыпухе вся схема измерения ухода фазы состоит из двух корпусов операционников и двух десятков деталей, думал здесь будет ещё проще, так и было бы если бы фаза не скакала, и не надо было вычислять среднее значения её изменения за цикл. В любом случае спасибо за помощь, буду что то пытаться сваять на счётчиках. Язык мои старые мозги не осилят в совершенстве, а по другому не получится. Мне кажется достаточно и одного счётчика. Просто тупо сосчитать число клоков в разностном сигнале и вывести его на дисплей, это и будет разница в условных единицах за цикл. Видимо всё гениальное всё таки очень просто. А ежали всю кучу разделить на 47(50 это я округлил), то будет и сказка и песня в одном флаконе. Спасибо братья по разуму!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться