VHDL ile tasasrım yapılırken sıklıkla kullanılan bileşenlerden biri de sayıcılardır. Sayıcılar gecikme yapmak, frekans bölmek v.b. pek çok amaçla kullanılabilen elemanlardandır. Bu uygulamalı örnekte ilk olarak 4 Bit uzunlukta basit bir sayıcı tasarımı yapılmış olup ardından aynı sayıcı generic hale getirilmiştir.
Sayıcı tasarlarken sayı aralığına bağlı olarak değişen bit uzunluğuna dikkat edilmelidir. Sayıcının alabileceği azami değer ve bit uzunluğu arasında aşağıda verilen matematiksel bağıntı mevcuttur, ‘n’toplam bit uzunluğu olmak üzere:
Sayının Azami Değeri = 2n-1
Örnek 1: Aşağıda 4 bitlik sayaç devresinin gerçekleştirildiği sayac_4_bit.vhd VHDL kodu verilmiştir. sayac_4_bit varlığımıza ilişkin port bildirimleri 6-10. satırlar arasında yapılmıştır. Sayaç tasarımında 1 bitlik saat darbesi giriş portu, 1 bitlik reset giriş portu ve 4 bitlik çıkış portu mevcuttur. 15. Satırda tanımlanan 4 bitlik r_sayac sinyali 19. satırda out_cikis çıkış portuna atanmaktadır. 21. satırda tanımlanan söz dizimi ile process’in in_clk ve in_rst giriş portlarında meydana gelen değişiklikler ile aktif olacağı belirtilmektedir.
process içerisinde yapılan tanımlamardan da görüleceği üzere saklayıcı tasarımında eş zamanlı olmaya reset kullanılmıştır. 23. satırda in_rst giriş portu ‘1’ değerini aldığında r_sayac sinyalinin tüm bitlerine ‘0’ değeri atanmaktadır. Bu durumda out_cikis çıkış portunun tüm bitleride ‘0’ olmaktadır. in_rst girişinin diğer durumlarında ise in_clk giriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır. in_clk giriş sinyalinin yükselen kenarının meydana gelmemesi durumunda ise r_sayac sinyali bir önceki değerini korumaktadır.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity sayac_4_bit is Port ( in_clk : in std_logic; in_rst : in std_logic; out_cikis : out std_logic_vector(3 downto 0) ); end sayac_4_bit; architecture Behavioral of sayac_4_bit is signal r_sayac : std_logic_vector(3 downto 0) := (others => '0'); begin out_cikis <= r_sayac; process(in_clk, in_rst) begin if in_rst = '1' then r_sayac <= (others => '0'); elsif rising_edge(in_clk) then r_sayac <= r_sayac + 1; end if; end process; end Behavioral;
Aşağıda ise sayac_4_bit varlığının benzetim yapılabilmesi için tb_sayac_4_bit.vhd sınama kodu verilmiştir ve benzetim çıktısı Şekil 1’de gösterilmiştir. Şekil 1’de gösterilen benzetim sonucunda:
1. adım :in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0001” olmaktadır. r_sayac sinyalinin değerinin “0001” olması ile out_cikis çıkış portuna “0001” değeri atanmaktadır.
2. adım : in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0010” olmaktadır. r_sayac sinyalinin değerinin “0010” olması ile out_cikis çıkış portuna “0010” değeri atanmaktadır.
3. adım : in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0011” olmaktadır. r_sayac sinyalinin değerinin “0011” olması ile out_cikis çıkış portuna “0011” değeri atanmaktadır.
4. adım :in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0100” olmaktadır. r_sayac sinyalinin değerinin “0100“ olması ile out_cikis çıkış portuna “0100“ değeri atanmaktadır.
5. adım :in_rstgiriş portunundeğeri ‘1’ olması nedeniyle r_sayac sinyalinin değerine “0000”atanmaktadır. r_sayac değerinin “0000” olması ile out_cikis değerine “0000” değeri atanmaktadır.
6. adım :in_rstgiriş portunundeğeri ‘0’ olmasına rağmen in_clk giriş portunda yükselen kenar meydan gelmediği için r_sayac sinyalinin değerinde değişiklik olmamıştır.
7. adım : in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0001” olmaktadır. r_sayac sinyalinin değerinin “0001” olması ile out_cikis çıkış portuna “0001” değeri atanmaktadır.
8. adım :in_rstgiriş portunundeğerinin ‘0’ olması ve in_clkgiriş portunun yükselen kenarı ile birlikte r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0010” olmaktadır. r_sayac sinyalinin değerinin “0010” olması ile out_cikis çıkış portuna “0010” değeri atanmaktadır.

Şekil 1 sayac_4_bit varlığı benzetim çıktısı
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity tb_sayac_4_bit is end tb_sayac_4_bit; architecture Behavioral of tb_sayac_4_bit is component sayac_4_bit Port ( in_clk : in std_logic; in_rst : in std_logic; out_cikis : out std_logic_vector(3 downto 0) ); end component; constant CLK_PERIOD : time := 150 ns; signal in_clk : std_logic := '0'; signal in_rst : std_logic := '0'; signal out_cikis : std_logic_vector(3 downto 0) := (others => '0'); begin process begin in_clk <= '1'; wait for CLK_PERIOD / 2; in_clk <= '0'; wait for CLK_PERIOD / 2; end process; process begin in_rst <= '0'; wait for 550 ns; in_rst <= '1'; wait for 150 ns; in_rst <= '0'; wait for 300 ns; end process; sayac_4_bit_map : sayac_4_bit port map( in_clk => in_clk, in_rst => in_rst, out_cikis => out_cikis ); end Behavioral;
Örnek 2: Aşağıda sayacın artan veya azalan durumunun tayin edilebildiği n_bit bitlik sayaç devresinin gerçekleştirildiği generic_sayac.vhd VHDL kodu verilmiştir. generic_sayac varlığımıza ilişkin generic bildirimleri 6-8. satırlarda, port bildirimleri 9-14. satırları arasında yapılmaktıdır.
Sayaç tasarımında 1 bitlik saat darbesi giriş portu, 1 bitlik reset giriş portu, 1 bitlik sayacın artması veya azalması durumunun tayin edildiği giriş portu ve n_bit bitlik çıkış portu mevcuttur. 25. satırda tanımlanan söz dizimi ile process’in in_clk ve in_rst giriş portlarında meydana gelen değişiklikler ile aktif olacağı belirtilmektedir.
process içerisinde yapılan tanımlamardan da görüleceği üzere saklayıcı tasarımında eş zamanlı olmaya reset kullanılmıştır. 27. satırda in_rst giriş portu ‘1’ değerini aldığında r_sayac sinyalinin tüm bitlerine ‘0’ değeri atanmaktadır. Bu durumda out_cikis çıkış portunun tüm bitleride ‘0’ olmaktadır. in_rst girişinin diğer durumlarında ise in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portu değerinin ‘0’ olması durumunda r_sayac sinyalinin değeri bir artırılmaktadır. in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portu değerinin ‘1’ olması durumunda r_sayac sinyalinin değeri bir azaltılmaktadır.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity generic_sayac is Generic( n_bit : integer := 4 ); Port ( in_clk : in std_logic; in_rst : in std_logic; in_say : in std_logic; out_cikis : out std_logic_vector(n_bit - 1 downto 0) ); end generic_sayac; architecture Behavioral of generic_sayac is signal r_sayac : std_logic_vector(n_bit - 1 downto 0) := (others => '0'); begin out_cikis <= r_sayac; process(in_clk, in_rst) begin if in_rst = '1' then r_sayac <= (others => '0'); elsif rising_edge(in_clk) then if in_say = '0' then r_sayac <= r_sayac + 1; elsif in_say = '1' then r_sayac <= r_sayac - 1; end if; end if; end process; end Behavioral;
Aşağıda ise generic_sayac varlığının benzetim yapılabilmesi için tb_generic_sayac.vhd sınama kodu verilmiştir ve benzetim çıktısı Şekil 2’de gösterilmiştir. Şekil 2’de gösterilen benzetim sonucunda:
1. adım :in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘0’ değerini alması ile r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0001” olmaktadır. r_sayac değerinin “0001“ olması ile out_cikis çıkış portuna “0001“ değeri atanmaktadır.
2. adım :in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘0’ değerini alması ile r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0010” olmaktadır. r_sayac değerinin “0010“ olması ile out_cikis çıkış portuna “0010“ değeri atanmaktadır.
3. adım : in_rst giriş portunundeğeri ‘1’ olması nedeniyle r_sayac değerine “0000” atanmaktadır. r_sayac değerinin “0000” olması ile out_cikis çıkış portuna “0000” değeri atanmaktadır.
4. adım : in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘0’ değerini alması ile r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0001” olmaktadır. r_sayac değerinin “0001“ olması ile out_cikis çıkış portuna “0001“ değeri atanmaktadır.
5. adım :in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘0’ değerini alması ile r_sayac sinyalinin değeri bir artırılmaktadır ve değeri “0010” olmaktadır. r_sayac değerinin “0010“ olması ile out_cikis çıkış portuna “0010“ değeri atanmaktadır.
6. adım :in_rst giriş portunundeğerinin ‘0’ve in_say girişinin ‘1’ olmasına rağmen in_clk giriş portunda yükselen kenar meydana gelmemsidnen dolayı r_sayac sinyalinin değeri değilmemiştir.
7. adım : in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘1’ değerini alması ile r_sayac sinyalinin değeri bir azaltılmaktadır ve değeri “0001” olmaktadır. r_sayac değerinin “0001“ olması ile out_cikis çıkış portuna “0001“ değeri atanmaktadır.
8. adım : in_rst giriş portunundeğerinin ‘0’ olması ve in_clk giriş portunun yükselen kenarı ile birlikte in_say giriş portunun ‘1’ değerini alması ile r_sayac sinyalinin değeri bir azaltılmaktadır ve değeri “0000” olmaktadır. r_sayac değerinin “0000“ olması ile out_cikis çıkış portuna “0000“ değeri atanmaktadır.

Şekil 2 sayac_generic varlığı benzetim çıktısı
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity tb_generic_sayac is end tb_generic_sayac; architecture Behavioral of tb_generic_sayac is component generic_sayac Generic( n_bit : integer := 4 ); Port ( in_clk : in std_logic; in_rst : in std_logic; in_say : in std_logic; out_cikis : out std_logic_vector(n_bit - 1 downto 0) ); end component; constant CLK_PERIOD : time := 150 ns; signal in_clk : std_logic := '0'; signal in_rst : std_logic := '0'; signal in_say : std_logic := '0'; signal out_cikis : std_logic_vector(3 downto 0) := (others => '0'); begin process begin in_clk <= '1'; wait for CLK_PERIOD / 2; in_clk <= '0'; wait for CLK_PERIOD / 2; end process; process begin in_rst <= '0'; wait for 300 ns; in_rst <= '1'; wait for 150 ns; in_rst <= '0'; wait for 550 ns; end process; process begin in_say <= '0'; wait for 700 ns; in_say <= '1'; wait for 300 ns; end process; generic_sayac_map : generic_sayac port map( in_clk => in_clk, in_rst => in_rst, in_say => in_say, out_cikis => out_cikis ); end Behavioral;