gosha 0 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба На входе - сигнал с постоянной состовляющей. Необходимо получить усредненное значение сигнала (постоянную составляющую). Потеря точности НЕ допускается. Частота дискретизации 30МГц. Период сигнала - от 1Гц до 200КГц Как экономичнее на verilog реализовать фильтр скользящего среднего ? Усредняем за время более периода младшей гармоники ? `include "timescale.v" /*===========================================================*/ module mean_filter( input clk_i, /* 30.72MHz */ input rst_i, input [23:0] dat_i, input srst_i, input valid_i, output signed [23:0] dat_o, output reg valid_o ); /*===========================================================*/ reg [14:0] addr_wr, addr_rd; reg signed [38:0] S; reg wr; wire signed [23:0] dat_m; reg signed [23:0] dat_average; /*===========================================================*/ assign dat_o= dat_average; mem_24x65536 mem (.clk(clk_i), .a(addr_wr), .d(dat_i), .dpra(addr_rd), .we(wr), .dpo(dat_m)); /*===========================================================*/ always @(posedge clk_i or posedge rst_i) begin if(rst_i) {addr_wr, addr_rd, S, wr, dat_average, valid_o, decimate}<= 0; else begin if(srst_i) {addr_wr, addr_rd, S, wr, dat_average, valid_o}<= 0; else begin if(&addr_wr) valid_o<= 1'b1; wr <= valid_i ; addr_rd<= addr_rd+ 1'b1; if(valid_i) addr_wr<= addr_wr+ 1'b1; if(!addr_rd) begin S<= dat_m; dat_average<= S[38:15]; end else S<= S + dat_m; end end end /*===========================================================*/ endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба 36 minutes ago, gosha said: Усредняем за время более периода младшей гармоники ? у вас не скользящее среднее 37 minutes ago, gosha said: Как экономичнее на verilog реализовать фильтр скользящего среднего ? CIC фильтр, одно звено, реализция без преобразования частоты Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость vitzap 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба Если задача позволяет, очень просто сделать экспоненциально взвешенное скользящее среднее. https://ru.wikipedia.org/wiki/Скользящая_средняя Если a брать 1/2, 1/4, 1/8 и т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha 0 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба 35 minutes ago, des00 said: у вас не скользящее среднее CIC фильтр, одно звено, реализция без преобразования частоты Спасибо ! А точность не потеряется ? По Т.З. погрешность измерения дальности дальномером : 5 метров Задача фильтра- усреднить разность фаз фазомера. Нужен децимирующий фильтр на 30000. (30 МГц -> 1 KГц) IP Xilinx не генерит CIC с дещимацией 30_000. Только децимирующий на 8192 максимум. Еще разрядность повышается: А тама арктангенс после фильтра. Скользящее среднее не будет ли точнее ? tone_20KHz.slx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба 29 minutes ago, gosha said: А точность не потеряется ? По Т.З. погрешность измерения дальности дальномером : 5 метров Задача фильтра- усреднить разность фаз фазомера. Нужен децимирующий фильтр на 30000. (30 МГц -> 1 KГц) IP Xilinx не генерит CIC с дещимацией 30_000. Только децимирующий на 8192 максимум. Еще разрядность повышается: А тама арктангенс после фильтра. Скользящее среднее не будет ли точнее ? вы хоть немного в ответ погрузитесь, до того как задавать вопросы и рисовать схемы в симулинке. по указанной выше ссылке в википедии, в разделе "Простое скользящее среднее, или арифметическое скользящее среднее" указана формула вот этого самого фильтра "CIC фильтр, одно звено, реализция без преобразования частоты". А децимировать можно на выходе. Но, если вам априори нужна децимация, то ваша реализация пойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tanya 4 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба Автор! Вам нужно экспериментально найти подходящий метод усреднения, которых существует бесконечно много. Отбрасывая измерения, повысить точность? Трудно поверить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrGalaxy 9 19 декабря, 2020 Опубликовано 19 декабря, 2020 · Жалоба 16.12.2020 в 08:12, gosha сказал: Необходимо получить усредненное значение сигнала Недавно решал подобную задачу. Сделал используя мегафункцию FIFO. Прибавляется текущее значение, которое пишется в память и вычитается самое старое значение, которое в этот момент вылезает из памяти. 16.12.2020 в 08:12, gosha сказал: Усредняем за время более периода младшей гармоники ? Периодов лучше взять побольше, хотя бы 10. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha 0 24 декабря, 2020 Опубликовано 24 декабря, 2020 · Жалоба Спасибо !! Хорошее решение. Тогда уж кольцевой буфер на основе двухпортовой RAM: в голову пишется, суммируется, хвост вычитается? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 25 декабря, 2020 Опубликовано 25 декабря, 2020 · Жалоба On 12/19/2020 at 8:36 PM, MrGalaxy said: Прибавляется текущее значение, которое пишется в память и вычитается самое старое значение, которое в этот момент вылезает из памяти. это и есть формула из википедии, по приведенной ссылке) раздел статьи: Простое скользящее среднее, или арифметическое скользящее среднее Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrGalaxy 9 25 декабря, 2020 Опубликовано 25 декабря, 2020 · Жалоба 12 часов назад, des00 сказал: это и есть формула из википедии, по приведенной ссылке) раздел статьи: Простое скользящее среднее, или арифметическое скользящее среднее Ради формулы простейшего интегрирования в скользящем окне в Википедию лазить... Вопрос был про реализацию. 23 часа назад, gosha сказал: Тогда уж кольцевой буфер на основе двухпортовой RAM: в голову пишется, суммируется, хвост вычитается? Я про это и написал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 26 декабря, 2020 Опубликовано 26 декабря, 2020 · Жалоба 15 hours ago, MrGalaxy said: Ради формулы простейшего интегрирования в скользящем окне в Википедию лазить... Вопрос был про реализацию. Ну это же не вам совет был, вы в этой теме гуру, а ТС изначально не был. Но прочитав все материалы по теме, в том числе y(t) = y(t-1) - x(t-N) + x(t), ТС не узнал в описании вашего устройства вот эту простую формулу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 26 декабря, 2020 Опубликовано 26 декабря, 2020 · Жалоба library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity delay_line is generic( W : integer := 8; -- data width L : integer := 1200); -- delay length, shall be > 3 port( i_clk : in std_logic; i_sync_reset : in std_logic; i_data : in std_logic_vector(W-1 downto 0); o_data : out std_logic_vector(W-1 downto 0)); end delay_line; architecture rtl of delay_line is type t_ram is array (L-2 downto 0) of std_logic_vector(W-1 downto 0); signal m_ram : t_ram; signal r_addr_wr : integer range 0 to L-2; signal r_addr_rd : integer range 0 to L-2; signal r_enable_read : std_logic; begin p_write : process (i_clk) begin if rising_edge(i_clk) then if(i_sync_reset='1') then r_addr_wr <= 0; r_enable_read <= '0'; else m_ram(r_addr_wr) <= i_data; if(r_addr_wr<L-2) then r_addr_wr <= r_addr_wr + 1; else r_addr_wr <= 0; r_enable_read <= '1'; -- enable reading section end if; end if; end if; end process p_write; p_read : process (i_clk) begin if rising_edge(i_clk) then if(i_sync_reset='1') then r_addr_rd <= 0; else if(r_enable_read='1') then o_data <= m_ram(r_addr_rd) ; -- additional delay if(r_addr_rd<L-2) then r_addr_rd <= r_addr_rd + 1; else r_addr_rd <= 0; end if; end if; end if; end if; end process p_read; end rtl; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity moving_average is generic ( G_NBIT : integer := 8; G_AVG_LEN_LOG : integer := 2 ); port ( i_clk : in std_logic; i_rstb : in std_logic; i_sync_reset : in std_logic; -- input i_data_ena : in std_logic; i_data : in std_logic_vector(G_NBIT-1 downto 0); -- output o_data_valid : out std_logic; o_data : out std_logic_vector(G_NBIT-1 downto 0)); end moving_average; architecture rtl of moving_average is type t_moving_average is array (0 to 2**G_AVG_LEN_LOG-1) of signed(G_NBIT-1 downto 0); signal p_moving_average : t_moving_average; signal r_acc : signed(G_NBIT+G_AVG_LEN_LOG-1 downto 0); -- average accumulator signal r_data_valid : std_logic; begin p_average : process(i_clk,i_rstb) begin if(i_rstb='0') then r_acc <= (others=>'0'); p_moving_average <= (others=>(others=>'0')); r_data_valid <= '0'; o_data_valid <= '0'; o_data <= (others=>'0'); elsif(rising_edge(i_clk)) then r_data_valid <= i_data_ena; o_data_valid <= r_data_valid; if(i_sync_reset='1') then r_acc <= (others=>'0'); p_moving_average <= (others=>(others=>'0')); elsif(i_data_ena='1') then p_moving_average <= signed(i_data)&p_moving_average(0 to p_moving_average'length-2); r_acc <= r_acc + signed(i_data)-p_moving_average(p_moving_average'length-1); end if; o_data <= std_logic_vector(r_acc(G_NBIT+G_AVG_LEN_LOG-1 downto G_AVG_LEN_LOG)); -- divide by 2^G_AVG_LEN_LOG end if; end process p_average; end rtl; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrGalaxy 9 26 декабря, 2020 Опубликовано 26 декабря, 2020 (изменено) · Жалоба 9 часов назад, des00 сказал: гуру, Сами Вы это слово. Изменено 26 декабря, 2020 пользователем MrGalaxy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha 0 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба `include "timescale.v" /*===========================================================*/ module mean_filter( input clk_i, /* 30.72MHz */ input rst_i, input signed [21:0] dat_i, input srst_i, input valid_i, output signed [21:0] dat_o ); /*===========================================================*/ reg [3:0] addr_wr; reg [3:0] addr_rd; reg signed [25:0] S; wire signed [25:0] S0; wire signed [21:0] dat_m; reg init_done; /*===========================================================*/ assign dat_o= S[25:4]; assign S0= S- dat_m; mem_x22 mem (.clk(clk_i), .a(addr_wr), .d(dat_i), .dpra(addr_rd), .we(valid_i), .qdpo(dat_m)); /*===========================================================*/ always @(posedge clk_i or posedge rst_i) begin if(rst_i) S<= 0; else begin if(srst_i) S<= 0; else begin if(valid_i) begin if(init_done) S<= S0 + dat_i; else S<= S+ dat_i; end end end end /*===========================================================*/ always @(posedge clk_i or posedge rst_i) begin if(rst_i) {addr_wr, addr_rd, init_done}<= 0; else begin if(srst_i) {addr_wr, addr_rd, init_done}<= 0; else begin if(&addr_wr) init_done<= 1'b1; if(valid_i) begin addr_rd<= addr_wr+ 2'd2; addr_wr<= addr_wr+ 1'b1; end end end end /*===========================================================*/ endmodule On 12/26/2020 at 11:09 AM, des00 said: Ну это же не вам совет был, вы в этой теме гуру, а ТС изначально не был. Но прочитав все материалы по теме, в том числе y(t) = y(t-1) - x(t-N) + x(t), ТС не узнал в описании вашего устройства вот эту простую формулу. Если с двух- портовой RAM, так оптимально ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба 4 hours ago, gosha said: Если с двух- портовой RAM, так оптимально ? на ней и делают. но как-то у вас все сложно и для фильтра избыточно. хотя у вас может быть спец.применение и вам нужен результат на первом цикле, поэтому и делаете принудительную инициализацю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться