Şekil 1’de gösterilen N adet örneğe sahip bir örneklem penceresinin toplam değerinin hesaplanma işlemleri aşağıdaki gibi yapılmaktadır.
Şekil 1 . N adet örneğe sahip örneklem penceresi
N sayısı arttıkça her seferinde bu işlemin yapılması maliyeti artıracaktır. Bu nedenle saklayıcı biriminin uzunluğu bir artıralarak ve yeni oluşturulan hafıza biriminin ilk ve son değerleri kullanılarak yine mevcut toplam değeri elde edilebilir.
Aşağıda kayan toplayıcı VHDL kodu verilmiştir. Generic parametreler olarak 8. satırda veri uzunluğu tanımlanmaktadır. 9. satırda ise kaç adet verinin toplanacağına ait tanımlama yapılmaktadır. 23. satırda buffer tanımlaması yapılmaktadır. Tanımlamadan da görüleceği üzere Generic olarak tanımlanan parametreler kullanılarak SUM_SIZE + 1 uzunluğunda DATA_WIDTH genişliğinde buffer tanımlanmıştır. 26-35 satırları arasında ise buffer içerisinde ki dataların kaydırılması işleminin gerçekleştirildiği fonksiyon tanımlanmaktadır. 46-60 satırları arasında yukarıda (2) nolu denklemde tanımlanan işlemler gerçekleştirilmektedir. 62-75 satırları arasında ise giriş datasının hafızaya yazılma işlemi gerçekleştirilmektedir.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity moving_sum is Generic( DATA_WIDTH : integer := 12; SUM_SIZE : integer := 10 ); Port ( in_clk : in std_logic; in_rst : in std_logic; in_data : in std_logic_vector(DATA_WIDTH - 1 downto 0); in_data_vld : in std_logic; out_sum_value : out std_logic_vector(DATA_WIDTH - 1 downto 0); out_sum_value_vld : out std_logic ); end moving_sum; architecture Behavioral of moving_sum is type t_SUM_BUFFER is array (0 to SUM_SIZE) of std_logic_vector(DATA_WIDTH - 1 downto 0); signal r_SUM_BUFFER : t_SUM_BUFFER := (others => (others => '0')); function f_shift_data_left (in_BUFFER : t_SUM_BUFFER; in_data : std_logic_vector(DATA_WIDTH - 1 downto 0)) return t_SUM_BUFFER is variable v_SUM_BUFFER : t_SUM_BUFFER; begin v_SUM_BUFFER := in_BUFFER; for n_i in 0 to SUM_SIZE - 1 loop v_SUM_BUFFER(n_i) := v_SUM_BUFFER(n_i + 1); end loop; v_SUM_BUFFER(SUM_SIZE) := in_data; return v_SUM_BUFFER; end function; signal r_strt_calc : std_logic := '0'; signal r_sum_value : std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0'); signal r_sum_value_vld : std_logic; begin out_sum_value <= r_sum_value; out_sum_value_vld <= r_sum_value_vld; process(in_clk) begin if in_rst = '1' then r_sum_value <= (others => '0'); r_sum_value_vld <= '0'; elsif rising_edge(in_clk) then r_sum_value_vld <= '0'; if r_strt_calc = '1' then r_sum_value_vld <= '1'; r_sum_value <= r_sum_value + r_SUM_BUFFER(SUM_SIZE) - r_SUM_BUFFER(0); end if; end if; end process; process(in_clk) begin if in_rst = '1' then r_SUM_BUFFER <= (others => (others => '0')); r_strt_calc <= '0'; elsif rising_edge (in_clk) then r_strt_calc <= '0'; if in_data_vld = '1' then r_SUM_BUFFER <= f_shift_data_left(r_SUM_BUFFER, in_data); r_strt_calc <= '1'; end if; end if; end process; end Behavioral;
Aşağıda moving_sum varlığının test işlemlerinin yapılabilmesi için sınama kodu verilmiştir. Sınama kodunda girişe 1’den 20’ye kadar sıralı olarak veriler verilmektedir.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity tb_moving_sum is end tb_moving_sum; architecture Behavioral of tb_moving_sum is component moving_sum Generic( DATA_WIDTH : integer := 12; SUM_SIZE : integer := 10 ); Port ( in_clk : in std_logic; in_rst : in std_logic; in_data : in std_logic_vector(DATA_WIDTH - 1 downto 0); in_data_vld : in std_logic; out_sum_value : out std_logic_vector(DATA_WIDTH - 1 downto 0); out_sum_value_vld : out std_logic ); end component; constant DATA_WIDTH : integer := 12; constant SUM_SIZE : integer := 10; constant CLK_PERIOD : time := 10 us; signal in_clk : std_logic; signal in_data : std_logic_vector(DATA_WIDTH - 1 downto 0) := others => '0'); signal in_data_vld : std_logic; signal out_sum_value : std_logic_vector(DATA_WIDTH - 1 downto 0); signal out_sum_value_vld : std_logic; begin process begin in_clk <= '1'; wait for CLK_PERIOD / 2; in_clk <= '0'; wait for CLK_PERIOD / 2; end process; process begin in_data_vld <= '0'; wait for 9 * CLK_PERIOD; if in_data = 20 then in_data <= conv_std_logic_vector(1, DATA_WIDTH); else in_data <= in_data + 1; end if; in_data_vld <= '1'; wait for CLK_PERIOD; end process; moving_sum_map : moving_sum Generic map( DATA_WIDTH => DATA_WIDTH, SUM_SIZE => SUM_SIZE ) Port map ( in_clk => in_clk, in_rst => '0', in_data => in_data, in_data_vld => in_data_vld, out_sum_value => out_sum_value, out_sum_value_vld => out_sum_value_vld ); end Behavioral;