movsum

Şekil 1’de gösterilen N adet örneğe sahip bir örneklem penceresinin toplam değerinin hesaplanma işlemleri Denklem (1) ve Denklem (2)’de gösterildiği gibi yapılmaktadır.

orneklem_1-300x53

Şekil 1 . N adet örneğe sahip örneklem penceresi

denklem_1-300x24

denklem_2-300x80

Daha az toplama işlemi yapabilmek amacıyla, yeni toplam değerini bulmak için bir önceki toplam değerini kullanarak elde etmek için N+1 adet örneğe sahip bir örneklem penceresi kullanmak gerekmektedir (Şekil 2). Matematiksel hesaplama da Denklem (3)’deki gibi yapılmaktadır.

orneklem_2-300x53

Şekil 2 . N +1 adet örneğe sahip örneklem penceresi

denklem_3-300x35

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.

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.STD_LOGIC_SIGNED.ALL;
  4. use IEEE.STD_LOGIC_ARITH.ALL;
  5. entity moving_sum is
  6. Generic(
  7. DATA_WIDTH : integer := 12;
  8. SUM_SIZE : integer := 10
  9. );
  10. Port (
  11. in_clk : in std_logic;
  12. in_rst : in std_logic;
  13. in_data : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  14. in_data_vld : in std_logic;
  15. out_sum_value : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  16. out_sum_value_vld : out std_logic
  17. );
  18. end moving_sum;
  19. architecture Behavioral of moving_sum is
  20. type t_SUM_BUFFER is array (0 to SUM_SIZE)
  21. of std_logic_vector(DATA_WIDTH - 1 downto 0);
  22. signal r_SUM_BUFFER : t_SUM_BUFFER :=
  23. (others => (others => '0'));
  24. function f_shift_data_left
  25. (in_BUFFER : t_SUM_BUFFER;
  26. in_data : std_logic_vector(DATA_WIDTH - 1 downto 0))
  27. return t_SUM_BUFFER is
  28. variable v_SUM_BUFFER : t_SUM_BUFFER;
  29. begin
  30. v_SUM_BUFFER := in_BUFFER;
  31. for n_i in 0 to SUM_SIZE - 1 loop
  32. v_SUM_BUFFER(n_i) := v_SUM_BUFFER(n_i + 1);
  33. end loop;
  34. v_SUM_BUFFER(SUM_SIZE) := in_data;
  35. return v_SUM_BUFFER;
  36. end function;
  37. signal r_strt_calc : std_logic := '0';
  38. signal r_sum_value :
  39. std_logic_vector(DATA_WIDTH - 1 downto 0)
  40. := (others => '0');
  41. signal r_sum_value_vld : std_logic;
  42. begin
  43. out_sum_value <= r_sum_value;
  44. out_sum_value_vld <= r_sum_value_vld;
  45. process(in_clk)
  46. begin
  47. if in_rst = '1' then
  48. r_sum_value <= (others => '0');
  49. r_sum_value_vld <= '0';
  50. elsif rising_edge(in_clk) then
  51. r_sum_value_vld <= '0';
  52. if r_strt_calc = '1' then
  53. r_sum_value_vld <= '1';
  54. r_sum_value <= r_sum_value
  55. + r_SUM_BUFFER(SUM_SIZE) - r_SUM_BUFFER(0);
  56. end if;
  57. end if;
  58. end process;
  59. process(in_clk)
  60. begin
  61. if in_rst = '1' then
  62. r_SUM_BUFFER <= (others => (others => '0'));
  63. r_strt_calc <= '0';
  64. elsif rising_edge (in_clk) then
  65. r_strt_calc <= '0';
  66. if in_data_vld = '1' then
  67. r_SUM_BUFFER <= f_shift_data_left(r_SUM_BUFFER, in_data);
  68. r_strt_calc <= '1';
  69. end if;
  70. end if;
  71. end process;
  72. 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. Benzetim elde edilen sonuçlar aşağıdaki şekilde gösterilmektedir.

mov_sum-300x74

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.STD_LOGIC_SIGNED.ALL;
  4. use IEEE.STD_LOGIC_ARITH.ALL;
  5.  
  6. entity tb_moving_sum is
  7. end tb_moving_sum;
  8.  
  9. architecture Behavioral of tb_moving_sum is
  10.  
  11. component moving_sum
  12. Generic(
  13.   DATA_WIDTH : integer := 12;
  14.   SUM_SIZE : integer := 10
  15. );
  16. Port (
  17.   in_clk : in std_logic;
  18.   in_rst : in std_logic;
  19.   in_data : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  20.   in_data_vld : in std_logic;
  21.   out_sum_value : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  22.   out_sum_value_vld : out std_logic
  23. );     
  24. end component;
  25.  
  26. constant DATA_WIDTH : integer := 12;
  27. constant SUM_SIZE : integer := 10;
  28. constant CLK_PERIOD : time := 10 us;
  29.  
  30. signal in_clk : std_logic;
  31. signal in_data : std_logic_vector(DATA_WIDTH - 1 downto 0)
  32. := others => '0');
  33. signal in_data_vld : std_logic;
  34. signal out_sum_value : std_logic_vector(DATA_WIDTH - 1 downto 0);
  35. signal out_sum_value_vld : std_logic;
  36.    
  37. begin
  38.    
  39. process
  40. begin
  41.   in_clk <= '1';
  42.   wait for CLK_PERIOD / 2;
  43.   in_clk <= '0';
  44.   wait for CLK_PERIOD / 2;
  45. end process;
  46.    
  47. process
  48. begin
  49.   in_data_vld <= '0';
  50.   wait for  9 * CLK_PERIOD;
  51.   if in_data = 20 then
  52.     in_data <= conv_std_logic_vector(1, DATA_WIDTH);
  53.   else
  54.     in_data <= in_data + 1;
  55.   end if;
  56.   in_data_vld <= '1';
  57.   wait for  CLK_PERIOD;
  58. end process;
  59.    
  60. moving_sum_map : moving_sum
  61. Generic map(
  62.   DATA_WIDTH => DATA_WIDTH,
  63.   SUM_SIZE => SUM_SIZE
  64. )
  65. Port map (
  66.   in_clk => in_clk,
  67.   in_rst => '0',
  68.   in_data => in_data,
  69.   in_data_vld => in_data_vld,
  70.   out_sum_value => out_sum_value,
  71.   out_sum_value_vld => out_sum_value_vld
  72. ); 
  73.    
  74. end Behavioral;