VHDL ile Kayan Toplayıcı (Moving Sum) Tasarımı

Ş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

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

denklem_1

denklem_2

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

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

denklem_3

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. var quads_screen_width = document.body.clientWidth;
  2. if ( quads_screen_width >= 1140 ) {
  3. /* desktop monitors */
  4. document.write('');
  5. (adsbygoogle = window.adsbygoogle || []).push({});
  6. }if ( quads_screen_width >= 1024 && quads_screen_width < 1140 ) {
  7. /* tablet landscape */
  8. document.write('');
  9. (adsbygoogle = window.adsbygoogle || []).push({});
  10. }if ( quads_screen_width >= 768 && quads_screen_width < 1024 ) {
  11. /* tablet portrait */
  12. document.write('');
  13. (adsbygoogle = window.adsbygoogle || []).push({});
  14. }if ( quads_screen_width < 768 ) {
  15. /* phone */
  16. document.write('');
  17. (adsbygoogle = window.adsbygoogle || []).push({});
  18. }
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25. library IEEE;
  26. use IEEE.STD_LOGIC_1164.ALL;
  27. use IEEE.STD_LOGIC_SIGNED.ALL;
  28. use IEEE.STD_LOGIC_ARITH.ALL;
  29.  
  30. entity moving_sum is
  31. Generic(
  32. DATA_WIDTH : integer := 12;
  33. SUM_SIZE : integer := 10
  34. );
  35. Port (
  36. in_clk : in std_logic;
  37. in_rst : in std_logic;
  38. in_data : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  39. in_data_vld : in std_logic;
  40. out_sum_value : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  41. out_sum_value_vld : out std_logic
  42. );
  43. end moving_sum;
  44.  
  45. architecture Behavioral of moving_sum is
  46.  
  47. type t_SUM_BUFFER is array (0 to SUM_SIZE) of std_logic_vector(DATA_WIDTH - 1 downto 0);
  48. signal r_SUM_BUFFER : t_SUM_BUFFER := (others => (others => '0'));
  49.  
  50. 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
  51. variable v_SUM_BUFFER : t_SUM_BUFFER;
  52. begin
  53. v_SUM_BUFFER := in_BUFFER;
  54. for n_i in 0 to SUM_SIZE - 1 loop
  55. v_SUM_BUFFER(n_i) := v_SUM_BUFFER(n_i + 1);
  56. end loop;
  57. v_SUM_BUFFER(SUM_SIZE) := in_data;
  58. return v_SUM_BUFFER;
  59. end function;
  60.  
  61. signal r_strt_calc : std_logic := '0';
  62. signal r_sum_value : std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0');
  63. signal r_sum_value_vld : std_logic;
  64.  
  65. begin
  66.  
  67. out_sum_value <= r_sum_value;
  68. out_sum_value_vld <= r_sum_value_vld;
  69.  
  70. process(in_clk)
  71. begin
  72. if in_rst = '1' then
  73. r_sum_value <= (others => '0');
  74. r_sum_value_vld <= '0';
  75.  
  76. elsif rising_edge(in_clk) then
  77. r_sum_value_vld <= '0';
  78. if r_strt_calc = '1' then
  79. r_sum_value_vld <= '1';
  80. r_sum_value <= r_sum_value + r_SUM_BUFFER(SUM_SIZE) - r_SUM_BUFFER(0);
  81. end if;
  82. end if;
  83.  
  84. end process;
  85.  
  86. process(in_clk)
  87. begin
  88. if in_rst = '1' then
  89. r_SUM_BUFFER <= (others => (others => '0'));
  90. r_strt_calc <= '0';
  91.  
  92. elsif rising_edge (in_clk) then
  93. r_strt_calc <= '0';
  94. if in_data_vld = '1' then
  95. r_SUM_BUFFER <= f_shift_data_left(r_SUM_BUFFER, in_data);
  96. r_strt_calc <= '1';
  97. end if;
  98. end if;
  99. end process;
  100.  
  101. 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

  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) := (others => '0');
  32. signal in_data_vld : std_logic;
  33. signal out_sum_value : std_logic_vector(DATA_WIDTH - 1 downto 0);
  34. signal out_sum_value_vld : std_logic;
  35.  
  36. begin
  37.  
  38. process
  39. begin
  40. in_clk <= '1';
  41. wait for CLK_PERIOD / 2;
  42. in_clk <= '0';
  43. wait for CLK_PERIOD / 2;
  44. end process;
  45.  
  46. process
  47. begin
  48. in_data_vld <= '0';
  49. wait for 9 * CLK_PERIOD;
  50. if in_data = 20 then
  51. in_data <= conv_std_logic_vector(1, DATA_WIDTH);
  52. else
  53. in_data <= in_data + 1;
  54. end if;
  55. in_data_vld <= '1';
  56. wait for CLK_PERIOD;
  57. end process;
  58.  
  59. moving_sum_map : moving_sum
  60. Generic map(
  61. DATA_WIDTH => DATA_WIDTH,
  62. SUM_SIZE => SUM_SIZE
  63. )
  64. Port map (
  65. in_clk => in_clk,
  66. in_rst => '0',
  67. in_data => in_data,
  68. in_data_vld => in_data_vld,
  69. out_sum_value => out_sum_value,
  70. out_sum_value_vld => out_sum_value_vld
  71. );
  72.  
  73. end Behavioral;

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir