Перейти к содержанию
    

Как написать среднее значение из 50 переменных?

Подскажите малограмотному, как в Верилоге вывести среднее значение переменного сигнала. Компаратор сравнивает 50 сигналов, синхронизированные по переднему фронту, но отличающиеся по длительности на заднем фронте. Разница выводится на индикацию, но сигналы меняются так быстро, что на выходе каша. Как можно вывести среднее значение? Заранее благодарен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Подскажите малограмотному, как в Верилоге вывести среднее значение переменного сигнала. Компаратор сравнивает 50 сигналов, синхронизированные по переднему фронту, но отличающиеся по длительности на заднем фронте. Разница выводится на индикацию, но сигналы меняются так быстро, что на выходе каша. Как можно вывести среднее значение? Заранее благодарен.

В Verilog, как это не странно, значение среднего считается так же как и в математике - просуммировали N значений - поделили на N (ни какой оригинальности :) )

А вот реализация зависит от того что Вы хотите получить ОДНО средне за каждые N осчетов или скользящее среднее за ПОСЛЕДНИЕ N осчетов.

Ну и если не критично усреднять проще на степень 2- тогда вместо деления можно использовать простой сдвиг.

 

Удачи! Rob.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(ни какой оригинальности :) )

И тем не менее, написав "ни какой" раздельно, вы умудрились таки эту оригинальность проявить.. :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответ. Значит я все 50 складываю, потом делю на 50, потом вывожу на индикацию полученное значение?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значит я все 50 складываю, потом делю на 50..

Прежде, чем что-то делить, хорошо бы научиться умножать:

 

SUM/50 = SUM*(0.02*2**N)>>>N;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответ. Значит я все 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 - операция сдвига на нужное количество разрядов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Спасибо за ответ. Значит я все 50 складываю, потом делю на 50, потом вывожу на индикацию полученное значение?

Да, но деление (не на степень 2) в железе дорогое "удовольствие", если уж сильно критично усреднять 50 значений то проще нормировать умножением на обратную величину.

 

Успехов! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне нужно усреднить значение выхода S1. Я его прописываю как регистр и складываю. Потом по приходу тактирующего импульса CM делю на число импульсов и вывожу результат? Это надо конечный автомат писать?

post-55305-1482161592_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне нужно усреднить значение выхода 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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тактовая частота 36 мГц. Время для подсчёта среднего почти 4мС. Думает не хватит?

Вам решать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я велосипед изобретаю? Мне нужно подсчитать среднее изменение фазы Р1, за период CM, это изменение равно S1. Сейчас там стоит аналоговый фазовый детектор. Можно ли его в ПЛИС всунуть? Есть всего лишь 500 свободных ЛУТов. Может не стоит и завязываться? Тем более, что я не сильно в программировании разбираюсь, в основном работаю в графическом редакторе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Может я велосипед изобретаю? Мне нужно подсчитать среднее изменение фазы Р1, за период CM, это изменение равно S1. Сейчас там стоит аналоговый фазовый детектор. Можно ли его в ПЛИС всунуть? Есть всего лишь 500 свободных ЛУТов.

К тому же Вы и нас к этому велосипеду привлекаете да еще и угадывать приходится сколько колес должно быт :)

Неточность постановки задачи влечет ошибки в ее решении.

 

Насколько мои телепатические способности (а также зрение) позволяют понят - Вы хотите усреднить разность фаз между импульсными сигналами P1 и QtrS за 50 циклов. Единицей измерения является такт Clk, Если еще поработать провидцем и предположить что разность фаз может быть знаковая то Все что Вам нужно это ВСЕГО 3 счетчика - 1 реверсивный счетчик считает по МОДУЛЮ 50 разность фаз в цикле, второй реверсивный считает число модулей первого - это и будет усредненное значение разности фаз ДЕЛЕННОЕ на 50 :laughing: ну а 3 считает 50 циклов измерения в конце которого результат измерения будет в счетчике 2. И да - подбирая модуль деления 1 счетчика (а может и величину приращения 1и 2) можно при необходимости сразу получить на выходе нормировку в нужных физических величинах.

И ни делителей ни умножителей ни CPU c DSP - скукота ;)

 

 

Успехов! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разность фаз не знаковая, а всегда положительная, причём только по заднему фронту. По переднему обе фазы одинаковы. Да, похоже я не правильно сформулировал задачу. На рассыпухе вся схема измерения ухода фазы состоит из двух корпусов операционников и двух десятков деталей, думал здесь будет ещё проще, так и было бы если бы фаза не скакала, и не надо было вычислять среднее значения её изменения за цикл. В любом случае спасибо за помощь, буду что то пытаться сваять на счётчиках. Язык мои старые мозги не осилят в совершенстве, а по другому не получится. Мне кажется достаточно и одного счётчика. Просто тупо сосчитать число клоков в разностном сигнале и вывести его на дисплей, это и будет разница в условных единицах за цикл. Видимо всё гениальное всё таки очень просто. А ежали всю кучу разделить на 47(50 это я округлил), то будет и сказка и песня в одном флаконе. Спасибо братья по разуму!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...