VHDL ile Hareketli Ortalama Filtre (Moving Average Filter)
FPGA'de Statik Timing Analizi
- 12 min read

Hareketli Ortalama Filtre (Moving Average Filter)
Hareketli ortalama filtre (moving average filter) girdilerin sıralı şekilde ortalamasını alıp çıkartan bir filtredir. Ani ve rastgele değişen girdilere karşılık stabil bir çıktı üretir. Matematiksel olarak genişliği sabit olan bir Finite Impulse Response (FIR) fonksiyonu ile konvolüsyon işlemidir. Low pass karakteristiğine sahiptir. Zaman domaininde iyi çalışan bir filtre olmasına karşın frekans domaininde iyi sonuçlar vermez.
Elektronik alanında analog dijital dönüştürücülerde (ADC) ve gürültülü girdi sinyallerinin filtrelenmesinde sıklıkla kullanılır. Finans alanında ise kıymetli varlıkların değerlerinin anlamlandırılmasında da kullanılmaktadır. Oldukça başarılı, anlaşılabilir ve algoritmik açıdan kolay implemente edilebilir yapıdadır.
En önemli parametresi pencere genişliğidir (window length). Pencere genişliği kaç tane girdinin ortalamasının alınacağını belirleyen parametredir. Matematiksel olarak ifadesi Şekil 1’de verilmiştir.
Şekil 1 - Hareketli ortalama filtrenin matematiksel ifadesi
Şekil 2’de verilen GIF görselinde hareket eden pencerenin girdileri ve oluşturduğu çıktılar incelendiğinde algoritma daha iyi bir şekilde anlaşılabilir.
Şekil 2 - Hareketli ortalama filtrenin matematiksel ifadesi
Yukarıdaki işlemde kırmızı renkli çıktı ve mavi renkli girdi indeksleri incelendiğinde ortalamanın sağlıklı alınabilmesi için pencerenin tamamen girdilerle dolması gerektiği anlaşılmaktadır. Tamamen girdiler ile dolan pencerenin ortanca elemanına ait indeksten itibaren verilen çıktılar anlamlı ve doğrudur. Filtreye uygulanan sinyalin giriş ve çıkış anında ortalamaya dahil edilecek katsayı miktarı pencere genişliğinden az olacağı için üretilen çıktılar yanıltıcı olabilmektedir.
Filtrenin özellikle gürültülü girdilere karşılık gösterdiği performans başarılıdır. Şekil 3’te görsel incelendiğinde soldaki ham veriye uygulanmış pencere genişliği 11 ve 51 örnek olan filtrelerin performansları görülebilir.
Şekil 3 - Hareketli ortalama filtrenin çeşitli pencere genişliklerine göre çıktı örneği
Mikrodenetleyici veya FPGA gibi aygıtlar üzerinde çalıştırılacak olan hareketli ortalama filtrede aynı çıktı sonuçlarını verecek sürekli hareketli ortalama filtre (continuous moving average filter) algoritması kullanılır. Bu algoritmanın yalnızca bir aşamasında toplama ve çıkarma, bir tane de bölme işlemi yapılarak yazılım ve donanımda yalınlık amaçlanır. Bahsedilen algoritma Şekil 4’te verilmiştir.
Şekil 4 - İmplemente edilen algoritma
Giriş verisi pencere uzunluğu kadar aşamadan oluşan bir pipeline yapısına sokulur. Sum adındaki bir sinyal ile ardışık girdiler sürekli olarak toplanırken pipeline yapısının son elemanı bu toplamdan sürekli olarak çıkarılır. Bu yapı sayesinde pencere uzunluğu kadar olan verilerin toplamı elde edilebilir. Girdinin sürekli gelmesi durumunda dahi toplama ve çıkarma işlemleri sayesinde yalnızca son gelen pencere genişliği tane verinin toplamı saklanır. Pencere genişliği parametresine göre verilerin toplamları elde edildikten sonra toplam pencere uzunluğu parametresine bölünerek ortalama değeri elde edilir.
Şekil 5 - İmplemente edilen algoritmanın işleyişi
Şekil 5’te pencere genişliği 5 olan; sırasıyla 1,2,3,4,5,6,7,8 ve 9 değerindeki veri girişine karşılık algoritmanın işleyişi gösterilmiştir.
Bu yapı sayesinde pencere genişliğinden bağımsız olarak yalnızca bir toplama-çıkarma işlemi ve bir de bölme işlemi ile hareketli ortalama filtresi uygulanabilmektedir.
VHDL ile hareketli ortalama filtre uygulaması:
Yukarıda algoritması ifade edilen hareketli ortalama filtrenin VHDL ile yazılmış uygulaması aşağıda verilmiştir.
--VHDLVerilog.com (VerilogVHDL.com) - 2025
--Hareketli ortalama filtresi (Moving average filter)
--Aşağıdaki yapı pencere boyutu tane (WINDOW_LENGTH_c) girdiyi aldıktan sonra çıktı üretmeye başlar.
--Girdi sinyali geçerli olduğu sürece çıktı verisini eşit ağırlıkta ortalama alarak günceller.
--Girdi sinyalinin geçersiz olduğu durumda ise ortalama alınacak penceredeki verileri ve çıktıyı güncellemeden bekler.
--Bu beklemeden sonra yeni veri gelmesi durumunda hali hazırda kuyrukta(pipeline'da) bulunan veriler ile gelen verilerin ortalaması alınarak başlanır.
--Active low senkron reset ile hafızadaki pencere değerleri temizlenebilir.
--ROUND_TYPE_c generic parametresi "FLOOR" olarak ayarlandığında ortalama alınırken yapılan yuvarlama bir küçük tam sayıya;
--ROUND_TYPE_c generic parametresi "CEIL" olarak ayarlandığında ortalama alınırken yapılan yuvarlama bir büyük tam sayıya yuvarlanır.
--Girdi std_logic_vector olarak BITDEPTH_c generic parametresine bağlı uzunlukta ve unsigned olarak yapılmalıdır.
--Çıktı std_logic_vector olarak BITDEPTH_c generic parametresine bağlı uzunlukta ve unsigned olarak yapılmaktadır.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;
entity moving_average_filter is
generic
(
BITDEPTH_c : integer;--girdi ve çıktının bit derinliği
WINDOW_LENGTH_c : integer;--ortalama alınacak pencerenin boyutu(2'nin kuvveti olması kuvvetle önerilir)
ROUND_TYPE_c : string--"FLOOR" veya "CEIL" olarak ayarlanmalıdır. Başka parametre seçilmemedilir.
);
port
(
CLK_i : in std_logic;
RESET_n_i : in std_logic;--active low reset
DATA_i : in std_logic_vector(BITDEPTH_c-1 downto 0);
DATA_VALID_i : in std_logic;
DATA_o : out std_logic_vector(BITDEPTH_c-1 downto 0);
DATA_VALID_o : out std_logic
);
end entity;
architecture moving_average_filter_beh of moving_average_filter is
--Girdileri toplayıp bir signale yazarken signal'in boyutu ceil(log2(WINDOW_LENGTH_c)) kadar büyür.
--Bu fonksiyon da log2 değerini küsüratlı ise bir üste yuvarlayarak hesaplar
function ceil_log2( depth : natural) return integer is
variable temp : integer := 1;
variable ret_val : integer := 0;
begin
if depth <= 1 then--depth 1'den kucuk esit ise pencerenin bit derinliginin artmasina ihtiyac yoktur.
return 0;
else--depth 1'den buyuk ise
while temp < depth loop--bit derinliginin alabilecegi deger giris degerini gecene kadar
ret_val := ret_val + 1;--her carpim islemi sonucunda return edilecek degeri bir arttir
temp := temp * 2;--bit derinligi degerini 1den baslayarak her defasinda 2 ile carparak arttir.
end loop;
return ret_val;
end if;
end function;
type data_pipeline_type is array (0 to WINDOW_LENGTH_c-1) of std_logic_vector(BITDEPTH_c-1 downto 0);--gelen verinin pipeline type'ı
signal data_p : data_pipeline_type := (others=>(others=>'0'));--gelen verinin pipeline'ı
signal data_valid_p : std_logic_vector(WINDOW_LENGTH_c-1 downto 0) := (others=>'0');--gelen verinin geçerli olup olmadığının pipeline'ı
signal en : std_logic := '0';--cikisin hesaplamasinin yapilip yapilmayacaginin saklandigi signal
--gelen verilerin girdilerinin toplanacağı signal
--Gelen verilerin boyutu her toplam işleminde(her seferinde en buyuk girdi geldiği senaryoda (en kotu senaryo)) kendi miktarınca artar.
--orneğin pencere genisligi 3, bit derinliği 8 olsun. Üç adet 8 bitlik verinin toplamı en fazla 255*3=765 olur. 765 değeri ise 10 bit ile ifade edilir.
--bu matematiksel olarak ifade edilmek istenirse BITDEPTH_c + ceil_log2(WINDOW_LENGTH_c) olarak ifade edilir.
signal sum : integer range 0 to ((2**(BITDEPTH_c+ceil_log2(WINDOW_LENGTH_c)))-1) := 0;
begin
process(CLK_i)
begin
if rising_edge(CLK_i) then
if RESET_n_i = '0' then--sync reset
--signal sıfırlama
data_p <= (others=>(others=>'0'));
data_valid_p<= (others=>'0');
sum <= 0;
--output sıfırlama
DATA_o <= (others=>'0');
DATA_VALID_o<= '0';
else
--pipeline 0
if DATA_VALID_i = '1' then--girdi geçerli ise
data_p(0) <= DATA_i;--pipeline kuyruğuna ekleniyor.
data_valid_p(0) <= '1';--pencerenin dolmasi icin valid sinyali '1' yapiliyor.
sum <= sum + to_integer(unsigned(DATA_i)) - to_integer(unsigned(data_p(WINDOW_LENGTH_c-1)));
--pipeline loop
--generic şekilde WINDOW_LENGTH_c girdisine bağlı olarak bir önceki pipeline elemanlarını bir sonrakine aktarıyor
for pipeline_index in 1 to WINDOW_LENGTH_c-1 loop
data_p(pipeline_index) <= data_p(pipeline_index-1);
data_valid_p(pipeline_index) <= data_valid_p(pipeline_index-1);
end loop;
en <= '1';--çıkış hesaplamasını yap. Bu sinyal DATA_VALID_i sinyalini registerlar yani DATA_VALID_i sinyali kesildikten sonra
--cerceve icerisindeki sinyaller 1 clk daha bosaltilmaya devam edilir.
else
en <= '0';--çıkış hesaplamasını yapma
end if;
--last pipeline
--pipeline'ların tamamı veri ile doluysa(pencere genişliği WINDOW_LENGTH_c'den az ise çıktı vermez) ve cikis hesaplamasi yapiliyor ise
if data_valid_p(WINDOW_LENGTH_c-1) = '1' and en = '1' then
--generic parametre oldugundan sentez araci tarafindan asagidakilerden birisi secilerek disari aktarilir.
if ROUND_TYPE_c = "CEIL" then
DATA_o <= std_logic_vector(to_unsigned(((sum+(WINDOW_LENGTH_c-1))/WINDOW_LENGTH_c),BITDEPTH_c));--çıkış veriliyor.
else--"FLOOR"
DATA_o <= std_logic_vector(to_unsigned((sum/WINDOW_LENGTH_c),BITDEPTH_c));--çıkış veriliyor.
end if;
DATA_VALID_o <= '1';--çıkış değeri gecerli.
else
DATA_VALID_o <= '0';--çıkış değeri geçerli degil.
end if;
end if;--RESET_n_i
end if;--rising_edge
end process;
end architecture;
VHDL konunun generic parametre bölümünde her bir girdinin bit derinliği BITDEPTH_c ile, pencere genişliği WINDOW_LENGTH_c ile ayarlanmalı, girdiler std_logic_vector olarak ve unsigned şekilde verilmelidir. Ayrıca aşağıda daha detaylı anlatılan bölme işleminin yuvarlama yönü de ROUND_TYPE_c generic parametresi ile ayarlanmalıdır.
Şekil 4’te verilen algoritma yapısına bağlı kalınarak WINDOW_LENGTH_c parametresine bağlı bir pipeline yapısı oluşturulmuş ve bu pipeline yapısına gelen veriler geçerli olduğunda (DATA_VALID_i = ‘1’) veri eklenmiştir. WINDOW_LENGTH_c tane elemanı bulunan pipeline’ın elemanlarının geçerli olup olmadığı saklamak için WINDOW_LENGTH_c tane elemandan oluşan std_logic_vector dizisi (data_valid_p(index)) tanımlanmıştır. Bu std_logic_vector signali yeni veri geldiğinde veri ile senkron şekilde yeni indexe kaydırılmıştır.
Her clockta (DATA_VALID_i = ‘1’ iken) yeni veri geldiğinde, sum adlı signal’e gelen veri yazılmış, pipeline’daki son veri ise bu signalden çıkartılmıştır. Böylece pencerenin genişliği artmadan verinin toplamı hesaplanmıştır.
Sum adlı sinyal WINDOW_LENGTH_c tane girdinin toplamından oluşur. Her bir girdi BITDEPTH_c tane bit ile ifade edilmektedir. Dolayısıyla sum adlı signalin sınırları WINDOW_LENGTH_c tane BITDEPTH_c girdisinin alabileceği en büyük toplam değeri kadar olmalıdır. Bunun matematiksel karşılığı BITDEPTH_c + ceil_log2(WINDOW_LENGTH_c) ifadesidir. Bu ifadede WINDOW_LENGTH_c tane toplamın BITDEPTH_c’yi kaç bit büyüteceği hesaplanıp BITDEPTH_c değeri ile toplanmaktadır.
ceil_log2 fonksiyonu girdi değerinin 2 tabanında logaritmasını alır ve küsüratlı olması halinde üste yuvarlar. Bu da girdinin kaç bit ile ifade edilebileceğini hesaplar. Pencere genişliği girdi olarak verildiğinde toplama işleminin değer aralığını kaç bit büyütmesi gerektiğini hesaplar. Örnek olarak:
- WINDOW_LENGTH_c = 5 ve BITDEPTH_c = 8 olsun.
- Girdinin alabileceği değer aralığı 0-255 olur.
- 5 tane girdinin toplamı ise en az 50 = 0, en fazla 5255 = 1275 olur.
- 1275 değerini ifade etmek için ceil_log2(1275) = 11 bite (unsigned) ihtiyaç duyulur.
Bu işlem yukarıda ifade edilen fonksiyon ile yapılmak istenirse:
- bit derinliği + ceil_log2(toplamdaki eleman sayısı)
- BITDEPTH_c + ceil_log2(WINDOW_LENGTH_c) = 8 + ceil_log2(5) = 11 elde edilir.
Pipeline dolduğunda (pipeline’ın son verisi geçerli ise) ve DATA_VALID_i’nin registerlandığı en sinyali 1 ise toplam değeri WINDOW_LENGTH_c parametresine bölünerek çıktı elde edilmiş ve çıktının geçerli olduğu bilgisi dışarıya aktarılmıştır. Registerlama işlemi, data_p ve data_valid_p sinyali hesaplanırken 1 clock gecikme olacağı için bir sonraki aşama olan çıkış hesaplamasının da 1 clock gecikme ile yapılması için gereklidir.
ROUND_TYPE_c adlı generic parametre ile bölme işlemi yapılırken sonucun küsüratlı çıkması halinde yukarı (CEIL) veya aşağı (FLOOR) yönde yapılıp yapılmaması seçilebilecek şekilde generic yazılmıştır. ROUND_TYPE_c, generic bir parametre, yani instantiation esnasında belirtilen sabit bir parametre olarak belirtilmiştir. Bundan dolayı seçilen parametre dışındaki diğer seçenekler asla çalışmayacağından dolayı sentez araçları tarafından sentezlenmez ve donanımda gereksiz yer işgal etmez. Buna karşılık çalışma esnasında çıkış bölmesinin floor mu ceil olacağı değiştirilemez.
Ayrıca sentez aşamasında daha az kaynak kullanılması ve çalışma frekansının daha yüksek olabilmesi için WINDOW_LENGTH_C’nin 2’nin kuvveti olan bir değer seçilmelidir. 2’nin kuvveti olarak seçilen WINDOW_LENGTH_C kullanıldığında algoritmadaki bölme işlemi bit kaydırma ile yüksek performans ve düşük kaynak tüketimi ile yapılırken 2’nin kuvveti olmayan bir değer seçildiğinde bölme devresi senteze eklenmektedir.
Testbench:
Aşağıda verilen VHDL dilinde yazılmış testbench ile modüle çeşitli girdiler verilerek doğru çalışıp çalışmadığı test edilmiştir.
--VHDLVerilog.com (VerilogVHDL.com) - 2025
--Hareketli ortalama filtresi (Moving average filter) testbench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity moving_average_filter_tb is
generic
(
BITDEPTH_c : integer := 8;--testbench'te kullanılacak olan girdi özellikleri buradan değiştirilmedilir.
WINDOW_LENGTH_c : integer := 5;
ROUND_TYPE_c : string := "CEIL"--"CEIL" veya "FLOOR" dışında girdi yapılmamalıdır.
);
end entity;
architecture DUT of moving_average_filter_tb is
---------------------------------------------------------------------------------------------------
--components
---------------------------------------------------------------------------------------------------
component moving_average_filter is
generic
(
BITDEPTH_c : integer;
WINDOW_LENGTH_c : integer;
ROUND_TYPE_c : string
);
port
(
CLK_i : in std_logic;
RESET_n_i : in std_logic;
DATA_i : in std_logic_vector(BITDEPTH_c-1 downto 0);
DATA_VALID_i : in std_logic;
DATA_o : out std_logic_vector(BITDEPTH_c-1 downto 0);
DATA_VALID_o : out std_logic
);
end component;
---------------------------------------------------------------------------------------------------
--signals
---------------------------------------------------------------------------------------------------
constant clock_period : time := 10ns;--100MHz
signal clk : std_logic := '1';
signal reset_n : std_logic := '1';--active low reset
signal data : std_logic_vector(BITDEPTH_c-1 downto 0) := (others=>'0');--test girdisi
signal data_valid : std_logic := '0';--test girdisinin geçerli olup olmadığını gösteren sinyal
begin
--clock generator
clock_process :
process
begin
clk <= '1';
wait for clock_period/2;
clk <= '0';
wait for clock_period/2;
end process;
MOVING_AVERAGE_FILTER_TEST :
process
begin
wait for clock_period/2;--falling edge'de degisim olusturmak icin gecikme
reset_n <= '0';--reset aktif
wait for clock_period;
reset_n <= '1';--reset pasif
data <= x"01";
data_valid <= '1';
wait for clock_period;
data <= x"02";
wait for clock_period;
data <= x"03";
wait for clock_period;
data <= x"04";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"06";
wait for clock_period;
data <= x"07";
wait for clock_period;
data <= x"08";
wait for clock_period;
data <= x"09";
wait for clock_period;
data <= x"0a";
wait for clock_period;
data <= x"0b";
wait for clock_period;
data <= x"0c";
wait for clock_period;
data <= x"0d";
wait for clock_period;
data <= x"0e";
wait for clock_period;
data <= x"0f";
wait for clock_period;
data <= x"10";
wait for clock_period;
data <= x"11";
wait for clock_period;
data <= x"12";
wait for clock_period;
data <= x"13";
wait for clock_period;
data <= x"14";
wait for clock_period;
data <= x"15";
wait for clock_period;
data <= x"16";
wait for clock_period;
data <= x"17";
wait for clock_period;
data <= x"18";
wait for clock_period;
data_valid <= '0';--girdi geçersiz ise nasıl davrandığı incelemek için eklendi.
data <= x"19";
wait for clock_period;
data <= x"1a";
wait for clock_period;
data <= x"1b";
wait for clock_period;
data <= x"1c";
wait for clock_period;
data <= x"1d";
wait for clock_period;
data <= x"1e";
wait for clock_period;
data <= x"20";
wait for clock_period;
data <= x"21";
wait for clock_period;
data_valid <= '1';--girdi tekrar geçerli olduğunda pencerede kalan eski değerleri gözlemlemek için eklendi.
data <= x"22";
wait for clock_period;
data <= x"23";
wait for clock_period;
data <= x"24";
wait for clock_period;
data <= x"25";
wait for clock_period;
data <= x"26";
wait for clock_period;
data <= x"27";
wait for clock_period;
data <= x"28";
wait for clock_period;
data <= x"29";
wait for clock_period;
reset_n <= '0';--reset aktif!
wait for clock_period;
reset_n <= '1';--reset pasif!(data_valid hala aktif!)
--Girdi bit sınırına yakın girdiler verilerek Owerflow durumunun incelenmesi için eklendi.
--Ayrıca aşağıdaki girdiler ile ceil ve floor özellikleri de incelenebiliyor.
data <= x"f9";
wait for clock_period;
data <= x"fa";
wait for clock_period;
data <= x"fb";
wait for clock_period;
data <= x"fc";
wait for clock_period;
data <= x"fd";
wait for clock_period;
data <= x"fe";
wait for clock_period;
data <= x"ff";
wait for clock_period;
data <= x"fe";
wait for clock_period;
data <= x"fd";
wait for clock_period;
data <= x"fc";
wait for clock_period;
data <= x"fb";
wait for clock_period;
data <= x"fa";
wait for clock_period;
data <= x"f9";
wait for clock_period;
----------------------
wait for clock_period;
reset_n <= '0';--reset aktif!
wait for clock_period;
reset_n <= '1';--reset pasif!(data_valid hala aktif!)
----------------------
--FLOOR ve CEIL çıktılarının doğru olup olmadığını gözlemek için eklendi.
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";--ortalama 5 olur ve çıktı elde edilir.(WINDOW_LENGHT_c=5 ise)
wait for clock_period;
data <= x"06";--ortalama (WINDOW_LENGHT_c=5 ise) 5,2 oluyor. CEIL'de çıkış = 6, FLOOR'da çıkış = 5 olur.
wait for clock_period;
----------------------
wait for clock_period;
reset_n <= '0';--reset aktif!
wait for clock_period;
reset_n <= '1';--reset pasif!(data_valid hala aktif!)
----------------------
--FLOOR ve CEIL çıktılarının doğru olup olmadığını gözlemek için eklendi.
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";
wait for clock_period;
data <= x"05";--ortalama 5 olur ve çıktı elde edilir.(WINDOW_LENGHT_c=5 ise)
wait for clock_period;
data <= x"04";--ortalama (WINDOW_LENGHT_c=5 ise) 4,8 oluyor. CEIL'de çıkış = 5, FLOOR'da çıkış = 4 olur.
wait for clock_period;
data_valid <= '0';--SON
wait;
end process;
---------------------------------------------------------------------------------------------------
--instantiations
---------------------------------------------------------------------------------------------------
DUT : moving_average_filter
generic map
(
BITDEPTH_c => BITDEPTH_c,
WINDOW_LENGTH_c => WINDOW_LENGTH_c,
ROUND_TYPE_c => ROUND_TYPE_c
)
port map
(
CLK_i => clk,
RESET_n_i => reset_n,
DATA_i => data,
DATA_VALID_i => data_valid,
DATA_o => open,
DATA_VALID_o => open
);
end architecture;
Sıralı girişlere karşılık filtrenin çıktılarının incelendiği senaryo Şekil 6’da verilmiştir.
Şekil 6 - Sıralı girişlere karşılık filtrenin çıktıları
DATA_VALID_i = ‘0’ olduğu durumda girdilere karşılık filtrenin çıktılarının incelendiği senaryo Şekil 7’de verilmiştir.
Şekil 7 - DATA_VALID_i = '0' olduğu durumda girdilere karşılık filtrenin çıktıları
DATA_VALID_i = ‘0’ değerinden sonra tekrar ‘1’ olduğu durumda girdilere karşılık filtrenin çıktılarının incelendiği senaryo Şekil 8’de verilmiştir. Burada pipeline’daki eski değerlerin korunduğu görülmektedir.
Şekil 8 - DATA_VALID_i = '0' değerinden sonra tekrar '1' olduğu durumda girdilere karşılık filtrenin çıktıları
Girdi olarak girdinin alabileceği en büyük sınıra yakın değerler verilerek overflow durumunun incelendiği senaryo Şekil 9’da verilmiştir.
Şekil 9 - Overflow durumunun incelenmesi
ROUND_TYPE_c parametresi FLOOR ve CEIL yapılarak çıktıların incelendiği senaryo Şekil 10’da verilmiştir. Görselin sol tarafında floor, sağ tarafında ise ceil yuvarlama yapısı kullanılmıştır.
Şekil 10 - ROUND_TYPE_c parametresinin çıktıya etkisinin incelenmesi
Not: 21.12.2025 tarihinde kod içerisindeki ceil_log2 fonksiyonuna ve pipeline valid yapısına hata düzeltmesi yapılmıştır.
Bu yazı hazırlanırken Wikipedia - Moving Average, Analog Devices DSP Book ve Surf-VHDL - How to Implement Moving Average in VHDL kaynaklarından faydalanılmıştır.