Vhdl'de Birden Fazla Process Kullanımı

Başlatan vitruvius, 03 Mayıs 2012, 10:47:24

vitruvius

Merhaba, birden fazla process kullanırken nelere dikkat etmek gerekir? Mesela ayrı bir projede güzel çalışan bir devrem vardı. Butona her bastığımda bir değişkeni arttırıp bu değişkenin değerine göre o sıradaki ledi yakan.. Başka bir projede de "turkplc" hocamın forumda verdiği lcd devresi vardı. Ben bu ikisini alt alta getirip birleştirmek istedim. Bunu denediğimde lcd'de yazı yazıyor fakat butona her bastığımda ledler genelde 2'şer 2'şer artıyor. Bunu önlemek için nelere dikkat etmek gerekir? Teşekkürler.

Birleştirdiğim projenin kodunu veriyorum. Comment'lerle lcd ve diğer devreyi belirttim.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tplcdvebuton is
port (
		 buton : in std_logic;
		 led : out std_logic_vector(7 downto 0);
		 clk : in std_logic;		 
		 DB : out  STD_LOGIC_VECTOR (7 downto 4); 
       LCD_E :out STD_LOGIC;
       LCD_RS :out STD_LOGIC;
       LCD_RW :out STD_LOGIC
);
end tplcdvebuton;

architecture Behavioral of tplcdvebuton is
--------------- Buton ve Debounce için Kullanılan Signal'ler ----------------
signal counter : integer range 0 to 15000000;
signal buton_b : std_logic;
signal buton_g : std_logic;
signal sayac : integer range 0 to 8;
signal ledg : std_logic_vector(7 downto 0);
-----------------------------------------------------------------------------

--------------- Lcd için Kullanılan Signal'ler ------------------------------
Signal StopTimer:std_logic;
Signal DATA : STD_LOGIC_VECTOR (7 downto 0);
-----------------------------------------------------------------------------

begin
	led <= ledg;

	process(buton,clk) -- Debounce
    begin
        if(clk'event and clk='1') then
            if(buton_b <= '1') then
            counter<=counter+1;
            buton_g<='0';
            elsif(buton='1') then
            buton_b<='1';
            end if;
                if(counter=15000000) then --300ms
                counter<=0;
                buton_b<='0';
                    if(buton='1') then
                    buton_g<='1';
                    end if;
                end if;
        end if;
    end process;
    
    process(buton_g) --Sayaç
    begin
        if(buton_g='1') then
        sayac<=sayac+1;
            if(sayac=8) then
            sayac<=0;
            end if;
        end if;
    end process;
    
    process(sayac)
    begin
        case sayac is
            when 0 => ledg <= "00000000";
            when 1 => ledg <= "00000001";
            when 2 => ledg <= "00000010";
            when 3 => ledg <= "00000100";
            when 4 => ledg <= "00001000";
            when 5 => ledg <= "00010000";
            when 6 => ledg <= "00100000";
            when 7 => ledg <= "01000000";				
            when others => ledg <= "10000000";
        end case;
   end process;
	
	------------------------------------- LCD ------------------------------------
	process (clk,buton)
    variable say1:integer;
    variable say2:integer;
    begin
    if (clk'EVENT and clk='1') then
    if (StopTimer='0') then 
    say1:=say1+1;
    end if;				
        if (say1>50000) then	--1 KHZ
        say1:=0;
        say2:=say2+1;
            case say2 is
            when 90=>
                LCD_RW<='0';
                LCD_RS<='0'; --CMD
                DB<="0011";
            when 99=>LCD_E<='1';
            when 100=>LCD_E<='0';
            when 115=>LCD_E<='1';
            when 116=>LCD_E<='0';
            when 121=>LCD_E<='1';
            when 122=>LCD_E<='0';
            when 127=>DB<="0010";
            when 128=>LCD_E<='1';
            when 129=>LCD_E<='0';

            
            when 149=>DATA<=X"28";
            when 150=>DB<=DATA(7 downto 4);
            when 151=>LCD_E<='1';			
            when 152=>LCD_E<='0';
            when 153=>DB<=DATA(3 downto 0);
            when 154=>LCD_E<='1';
            when 155=>LCD_E<='0';			
            DATA<=X"08";

            when 156=>DB<=DATA(7 downto 4);
            when 157=>LCD_E<='1';			
            when 158=>LCD_E<='0';
            when 159=>DB<=DATA(3 downto 0);
            when 160=>LCD_E<='1';
            when 161=>LCD_E<='0';				
                DATA<=X"01"; 
            when 162=>
                DB<=DATA(7 downto 4);
            when 163=>LCD_E<='1';			
            when 164=>LCD_E<='0';
            when 165=>DB<=DATA(3 downto 0);
            when 166=>LCD_E<='1';
            when 167=>LCD_E<='0';	
                DATA<=X"06";
            when 168=>
                DB<=DATA(7 downto 4);
            when 169=>LCD_E<='1';			
            when 170=>LCD_E<='0';
            when 171=>DB<=DATA(3 downto 0);
            when 172=>LCD_E<='1';
            when 173=>LCD_E<='0';
                DATA<=X"0C";
            when 174=>
                DB<=DATA(7 downto 4);
            when 175=>LCD_E<='1';			
            when 176=>LCD_E<='0';
            when 177=>DB<=DATA(3 downto 0);
            when 178=>LCD_E<='1';
            when 179=>LCD_E<='0';			
            
            when 180=>LCD_RS<='1'; --Chr
                DATA<=X"54"; --T
            when 181=>
                DB<=DATA(7 downto 4);
            when 182=>LCD_E<='1';			
            when 183=>LCD_E<='0';
            when 184=>DB<=DATA(3 downto 0);
            when 185=>LCD_E<='1';
            when 186=>LCD_E<='0';	
                DATA<=X"55"; --U
            when 187=>
                DB<=DATA(7 downto 4);
            when 188=>LCD_E<='1';			
            when 189=>LCD_E<='0';
            when 190=>DB<=DATA(3 downto 0);
            when 191=>LCD_E<='1';
            when 192=>LCD_E<='0';	
                DATA<=X"52"; --R
            when 193=>
                DB<=DATA(7 downto 4);
            when 194=>LCD_E<='1';			
            when 195=>LCD_E<='0';
            when 196=>DB<=DATA(3 downto 0);
            when 197=>LCD_E<='1';
            when 198=>LCD_E<='0';
                DATA<=X"4B"; --K
            when 199=>
                DB<=DATA(7 downto 4);
            when 200=>LCD_E<='1';			
            when 201=>LCD_E<='0';
            when 202=>DB<=DATA(3 downto 0);
            when 203=>LCD_E<='1';
            when 204=>LCD_E<='0';
                DATA<=X"50"; --P
            when 205=>
                DB<=DATA(7 downto 4);
            when 206=>LCD_E<='1';			
            when 207=>LCD_E<='0';
            when 208=>DB<=DATA(3 downto 0);
            when 209=>LCD_E<='1';
            when 210=>LCD_E<='0';
                DATA<=X"4C"; --L
            when 211=>
                DB<=DATA(7 downto 4);
            when 212=>LCD_E<='1';			
            when 213=>LCD_E<='0';
            when 214=>DB<=DATA(3 downto 0);
            when 215=>LCD_E<='1';
            when 216=>LCD_E<='0';
                DATA<=X"43"; --C
            when 217=>
                DB<=DATA(7 downto 4);
            when 218=>LCD_E<='1';			
            when 219=>LCD_E<='0';
            when 220=>DB<=DATA(3 downto 0);
            when 221=>LCD_E<='1';
            when 222=>LCD_E<='0';            
            
            when 3000=>--StopTimer<='1';
            when others=>
            end case;
        
        end if;
    end if;
    end process;

end Behavioral;

yamak

Kodunda gözüme çarpanlar:
clk lı process lerde, duyarlılık listesinde sadece,clk ve asenkron reset kullanmaya dikkat et. Kodunda bir de buton diye bir sinyal kullanmış onu sil bence.Bir de sayaçları variable olarak tanımlamanı öneririm.

vitruvius

Lcd'nin process'indeki "buton" denemelerimden kalmış onu siliyorum. Debounce'takini de silerim. Sayacı birden fazla process'te kullanmak için signal olarak tanımlamıştım. O iki process'i birleştirmeyi de denerim.

pic365

Aşağıdaki process clock'lu olmadığı için sayac'ın düzgün çalışması pek mümkün değil gibi.

    process(buton_g) --Sayaç
    begin
        if(buton_g='1') then
        sayac<=sayac+1;
            if(sayac=8) then
            sayac<=0;
            end if;
        end if;
    end process;


vitruvius

Şöyle bir değişiklikle düzeltilebilir mi hocam? Evde olmadığımdan deneyemiyorum.

    process(clk) --Sayaç
    begin
        if(clk'event and clk='1') then
            if(buton_g='1') then
            sayac<=sayac+1;
                if(sayac=8) then
                sayac<=0;
                end if;
            end if;
        end if;
    end process;

speak48

her bir değişken için bir prosess açılabilineceği gibi tüm işlemleride tek bir prosesde yapılabilinir.

pic365

Alıntı yapılan: vitruvius - 03 Mayıs 2012, 15:43:58
Şöyle bir değişiklikle düzeltilebilir mi hocam? Evde olmadığımdan deneyemiyorum.

    process(clk) --Sayaç
    begin
        if(clk'event and clk='1') then
            if(buton_g='1') then
            sayac<=sayac+1;
                if(sayac=8) then
                sayac<=0;
                end if;
            end if;
        end if;
    end process;


Evet bu şekilde çalışması lazım.

vitruvius

Hocam evet düzeldi teşekkür ederim. Tam olarak niye öyle bir değişiklik yaptık?

teknikelektronikci

Alıntı yapılan: yamak - 03 Mayıs 2012, 11:41:52
Kodunda gözüme çarpanlar:
clk lı process lerde, duyarlılık listesinde sadece,clk ve asenkron reset kullanmaya dikkat et. Kodunda bir de buton diye bir sinyal kullanmış onu sil bence.Bir de sayaçları variable olarak tanımlamanı öneririm.

hocam vhdl de variable nasil tanimlanir acaba ?
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

vitruvius

Sadece process, function yada procedure yapısı içinde;

process(clk)
     variable sayac: integer range 0 to 8;
begin


şeklinde tanımlayabilirsiniz. Değer atamak için de <= yerine := kullanılır.

teknikelektronikci

Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

pic365

Alıntı yapılan: vitruvius - 04 Mayıs 2012, 10:54:08
Hocam evet düzeldi teşekkür ederim. Tam olarak niye öyle bir değişiklik yaptık?
Rica ederim.

buton_g bir cycle boyunca 1 oluyor ve biz sayac'ın bu bir cycle boyunca sadece bir kez artmasını istiyoruz. Process'i clock'suz yaparsak "sayac<=sayac+1" ifadesi sonsuz bir döngü oluşturur ve sayac bir cycle boyunca defalarca 1 ile toplanır. Process clock'lu olunca toplama işleminin sonuna bir flip-flop eklenmiş oluyor ve sayac 1 ile toplandıktan sonra değerini bir cycle boyunca koruyor.

yamak

Hocam "sayac<=sayac+1" ifadesinin neden sonsuz döngü oluşturduğunu açıklayabilr misiniz?

speak48

clock tanımlanmazsa değişkenler register yerine latch de saklanır. latch de sonraki durum için clock beklenmez girişlerin değişmesi beklenir yani toplama biter bitmez yeniden toplanır bu aralıksız çalışması sonsuz döngüye benzetilebilinir.

yamak

Tamam da her buton_g nin değişimnde çalışmayacak mı kod niye defalarca toplansın ki?