]> git.the-white-hart.net Git - vhdl/commitdiff
Add window sum filter
authorrs <>
Sat, 13 Dec 2025 04:42:34 +0000 (22:42 -0600)
committerrs <>
Sat, 13 Dec 2025 04:42:34 +0000 (22:42 -0600)
libraries/dsp/filter_windowsum.vhd [new file with mode: 0644]
libraries/dsp/tests/test_filter_windowsum.vhd [new file with mode: 0644]

diff --git a/libraries/dsp/filter_windowsum.vhd b/libraries/dsp/filter_windowsum.vhd
new file mode 100644 (file)
index 0000000..901c9fc
--- /dev/null
@@ -0,0 +1,75 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+library work;
+
+
+entity filter_windowsum is
+       generic (
+               WIDTH:  positive := 16;
+               WINDOW: positive := 16
+       );
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+
+               stb_i: in  std_logic;
+               rdy_o: out std_logic;
+               dat_i: in  std_logic_vector(WIDTH-1 downto 0);
+
+               stb_o: out std_logic;
+               rdy_i: in  std_logic;
+               dat_o: out std_logic_vector(WIDTH+integer(ceil(log2(real(WINDOW))))-1 downto 0)
+       );
+end filter_windowsum;
+
+
+architecture behavioral of filter_windowsum is
+
+       constant ACC_WIDTH: positive := WIDTH+integer(ceil(log2(real(WINDOW))));
+
+       signal enable:      std_logic;
+
+       signal value_head:  std_logic_vector(WIDTH-1 downto 0);
+       signal value_tail:  std_logic_vector(WIDTH-1 downto 0);
+
+       signal accumulator: std_logic_vector(ACC_WIDTH-1 downto 0);
+       signal value_sum:   signed(ACC_WIDTH-1 downto 0);
+
+begin
+
+       value_head <= dat_i;
+       value_sum <= signed(accumulator) + signed(value_head) - signed(value_tail);
+
+       e_ctrl: entity work.pipectrl
+               generic map (WIDTH => ACC_WIDTH)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_o  => enable,
+                       stb_i => stb_i,
+                       rdy_o => rdy_o,
+                       dat_i => std_logic_vector(value_sum),
+                       stb_o => stb_o,
+                       rdy_i => rdy_i,
+                       dat_o => accumulator
+               );
+
+       dat_o <= accumulator;
+
+       e_delay: entity work.delay_srl
+               generic map (
+                       WIDTH => WIDTH,
+                       DELAY => WINDOW
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => enable,
+                       dat_i => value_head,
+                       dat_o => value_tail
+               );
+
+end behavioral;
diff --git a/libraries/dsp/tests/test_filter_windowsum.vhd b/libraries/dsp/tests/test_filter_windowsum.vhd
new file mode 100644 (file)
index 0000000..58bbedc
--- /dev/null
@@ -0,0 +1,79 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_filter_windowsum is
+end test_filter_windowsum;
+
+
+architecture behavior of test_filter_windowsum is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal rst_i:   std_logic;
+       signal clk_i:   std_logic;
+
+       signal src_stb: std_logic;
+       signal src_rdy: std_logic;
+       signal src_dat: std_logic_vector(7 downto 0);
+
+       signal sum_stb: std_logic;
+       signal sum_rdy: std_logic;
+       signal sum_dat: std_logic_vector(7+2 downto 0);
+
+begin
+
+       p_test: process
+       begin
+               -- Initial values
+               sum_rdy <= '1';
+               --src_dat <= x"80";
+               --src_dat <= x"7f";
+               src_dat <= x"ff";
+
+               -- Reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD*17;
+               rst_i <= '0';
+
+               -- Done
+               wait;
+       end process;
+
+       e_src: entity work.src_counter
+               generic map (WIDTH => 8)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       stb_o => src_stb,
+                       rdy_i => src_rdy,
+                       dat_o => open--src_dat
+               );
+
+       e_windsum: entity work.filter_windowsum
+               generic map (
+                       WIDTH  => 8,
+                       WINDOW => 4
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       stb_i => src_stb,
+                       rdy_o => src_rdy,
+                       dat_i => src_dat,
+                       stb_o => sum_stb,
+                       rdy_i => sum_rdy,
+                       dat_o => sum_dat
+               );
+
+       p_clk: process
+       begin
+               clk_i <= '0';
+               wait for CLK_I_PERIOD/2;
+               clk_i <= '1';
+               wait for CLK_I_PERIOD/2;
+       end process;
+
+end;