VHDL'de Variable Nerede Tanımlanıyor? Fpga

Başlatan vitruvius, 24 Şubat 2012, 16:01:07

yamak

#15
Alıntı yapılan: kakalive - 27 Şubat 2012, 13:14:56
Konu açıklığa kavuşmuş ama ben de variable ile ilgili birkaç ekleme yapayım. Process içinde variable tanımlandığı zaman sadece o process içinde kullanılabiliyor. Eğer birden fazla process'te kullanacaksanız, tanım process'in dışında (signal'ların tanımlandığı yerde) shared variable şeklinde yapılıyor. Diğer yandan RTL'de variable kullanmak benim pek tercih ettiğim bir şey değil, sadece testbench'te kullanıyorum. Çünkü yazımı kolaylaştırsa da hata olasılığını artırıyor.
Hocam neden tercih etmiyosunuz. Mesela gecikme yapmak için 5000000 a kadar saydırma yapılacak bu durumda variable kullanmak mantıklı değil mi?Signal kullansak bu boş yere gecikmeye sebep olamayacak mı?Yani amacacım sorgulamak değil yanlış anlamayın. Eğer yararlı birşeyse ben de bundan sonra o şekilde kullanayım

pic365

Sayaç olarak kullanılan variable'lar fazla sorun çıkarmıyor ama sinyallerle birlikte kullanıldığında sıkıntı çıkarabiliyor. Örneğin bir çıkarma işleminin sonucu variable'a atanıyor olsun. Normalde biz sonucu negatif yapacak hiçbir input vermesek bile simülatör sıfır anında bazı sinyalleri sıfır olarak alıp variable'a negatif sayı atamaya çalışıyor, sonucunda hata veriyor. Bu durum integer olarak tanımlanan sinyallerde de geçerli.

Bir de ben yine bu forumda mı yazmıştım tam hatırlamıyorum ama Xilinx variable kullanılmasını tavsiye etmiyor. Xilinx'in tavsiyesine uymayan kodların sentezinde de performans düşebiliyor. Performans derken timing, area, power gibi şeyleri kastediyorum.

vitruvius

Bu en son oluşturduğum kodu değiştirip switch ile 8 led için uyarlamak istedim ama şu hatayı alıyorum: Syntax error near "signal". Neyi gözden kaçırıyorum acaba, eskiden bu hatayı almıyordum.

Kodum şu şekilde:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity sw_state is
    Port ( sw : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           led : out  STD_LOGIC_VECTOR (7 downto 0));
end sw_state;

architecture Behavioral of sw_state is

type state_type is (s0,s1,s2,s3,s4,s5,s6,s7,s8)
signal state : state_type;

begin

process (clk,rst)
	begin
		if (rst='1') then
		state <= s0;
			elsif (clk'event and clk='1') then
				case state is
					when s0 =>
						if sw='1' then
						state <= s1;
						else
						state <= s0;
						end if;
					when s1 =>
						if sw='1' then
						state <= s2;
						else
						state <= s1;
						end if;
					when s2 =>
						if sw='1' then
						state <= s3;
						else
						state <= s2;
						end if;
					when s3 =>
						if sw='1' then
						state <= s4;
						else
						state <= s3;
						end if;
					when s4 =>
						if sw='1' then
						state <= s5;
						else
						state <= s4;
						end if;
					when s5 =>
						if sw='1' then
						state <= s6;
						else
						state <= s5;
						end if;
					when s6 =>
						if sw='1' then
						state <= s7;
						else
						state <= s6;
						end if;
					when s7 =>
						if sw='1' then
						state <= s8;
						else
						state <= s7;
						end if;
					when s8 =>
						if sw='1' then
						state <= s0;
						else
						state <= s8;
						end if;
				end case;
		end if;
	end process;
	
	process (state)
		begin
			case state is
				when s0 =>led<="00000000";
				when s1 =>led<="10000000";
				when s2 =>led<="01000000";
				when s3 =>led<="00100000";
				when s4 =>led<="00010000";
				when s5 =>led<="00001000";
				when s6 =>led<="00000100";
				when s7 =>led<="00000010";
				when s8 =>led<="00000001";
			end case;
		end process;
		


end Behavioral;


Teşekkürler.

yamak

type state_type is (s0,s1,s2,s3,s4,s5,s6,s7,s8)
Bu satırın sonuna ; koymayı unuttunuz.

vitruvius

 :-[ Hocam peki sizin başlığınızda verilen örnek debounce uygulamasını kullandınız mı? Sadece o uygulamayı içeren bir proje yaptığımda çıkışta herhangi bir şey göremedim ben.

Alıntı yapılan: muuzoo - 01 Ekim 2011, 00:32:42
@kakalive önemli bir noktaya değinmiş. Tasarladığınız yapıda buton kullanıyorsanız "debounce" şartına da dikkat etmek gerekiyor.

NOT: "Debounce" ne diyenler için geliyor. Bir mikrodenetleyici ya da mikroişlemciye bağladığınız butona bakarak yazılımda bir koşul çalıştırdığınızı varsayın. Butona bastığınızda üreteceğiniz parazitler yüzünden programınız sapıtabilir. Çünkü size göre butona bir kez basılmıştır fakat oluşan "zıplamalar" yüzünden sisteminiz bunu birden fazla kez basılmış olarak algılayabilir. Bu ve bunun gibi durumları  engellemek için "debounce" denen önlem alınır. Butonun uçlarına paralel kapasitör bağlamak, yazılımda gecikme ya da v.b şekilde önlemler almak gibi.

Örnek bir istenmeyen durum :

(Resim gizlendi görmek için tıklayın.)

Örnek bir debounce uygulaması :

LIBRARY ieee;
USE ieee.STD_LOGIC_1164.all;
USE ieee.STD_LOGIC_UNSIGNED.all;

-- Title "Key debounce circuit";
-- Prepared by: D. N. Warren-Smith
-- Updated: 7 February 2001

ENTITY DEBOUNCE IS
PORT (
  Clk       : IN STD_LOGIC;
  Key       : IN STD_LOGIC;  -- active low input
  pulse     : OUT STD_LOGIC);
END DEBOUNCE;

ARCHITECTURE clean_pulse OF DEBOUNCE IS
  SIGNAL cnt       : STD_LOGIC_VECTOR (1 DOWNTO 0);
BEGIN
  PROCESS (Clk)
  BEGIN
    IF Key = '1' THEN
      cnt <= "00";
    ELSIF (clk'EVENT AND Clk = '1') THEN
      IF (cnt /= "11") THEN cnt <= cnt + 1; END IF;
    END IF;
    IF (cnt = "10") AND (Key = '0') THEN pulse <= '1'; ELSE pulse <= '0'; END IF;
  END PROCESS;
END clean_pulse;


Kaynak : http://users.senet.com.au/~dwsmith/vhdl.htm#Key

@teknikelektronikci FPGA ile ilgili bir yazı dizisi yayınlamak uzun zamandır aklımda. Fakat fırsat bulup da zaman ayırmak her zaman mümkün olmuyor. Bu yakınlarda muhtemelen bir başlangıç yapacağım bu iş için. Şu an yüksek lisans tezimle uğraşıyorum arada yazmaktan sıkıldığımda :) yazı dizisi üzerinde çalışırım.

yamak


speak48

bende hiç debounce devresi kullanmadım zaten fpga setlerinde buton switch girişlerinde alçak geçiren filitre var.
bi tavsiyede hdlde bulunayım bende ilk vhdl le başlamıştım ama sorun çıkarmasından başka hiç bir artısı olmadı için veriloğa  geçtim.
seninde yol yakınken veriloğa geçmeni taavsiye ederim.
veriloğun artıları; sentaxı yabancı değil c ye benziyor, daha pratik okuması anlaşılır, tamamen donanıma yönelik örn:2 tane değişkenin var kullanılan biri reg biri wire olay biter. yok integer yok std_logic yok signal .....
vhdl in artısının var  olduğunu idda eden varsa yazsın bizde öğrenelim.

vitruvius

Hocam filtre varsa da ya o yetersiz yada benim tasarımım yetersiz. Verilog'a başlasam da muhtemelen aynı sıkıntıyı yaşarım. Benim bu konuda hiçbir eğitimim olmadı. İnternetten, kitaplardan okuduklarımla bir şeyler yapmaya çalışıyorum ama o zaman da temeli sağlam tutmak zor oluyor. Soru sorarken çok utanıyorum bazen yani  :)  :-[ Çizgi tagem'in 10 gün sonra 3 günlük bir eğitimi var, ona katılacağım. Şüphesiz benim için faydalı olacaktır  :)

İlgilenenler için: http://www.cizgi-tagem.org/education/detail.aspx?id=27

Bu debounce için de şöyle bir algoritma düşündüm. Bir sayaç oluşturayım, yürüyen ışık mantığındaki gibi. Butona bastıktan 20ms sonra led yansın mantığıyla bir şeyler deneyeceğim. Bu gibi durumlarda say:=say+1'i         if(buton='1) then    satırının altında mı tanımlamak gerekir yoksa    elsif (clk'EVENT AND Clk = '1') then     satırının altında mı?

speak48

Öğrenci & Öğretmen (DE0 FPGA Kiti + Eğitim): 230,00 TL KDV Dahil
Diğer (DE0 FPGA Kiti + Eğitim): 280,00 TL KDV Dahil
Öğrenci & Öğretmen (Sadece Eğitim): 50,00 TL KDV Dahil
Diğer (Sadece Eğitim): 100,00 TL KDV Dahil

sadece eğitim 50 lira fiyatı uygun olmasına rağmen içerik ve eğitmenler ne kadar dolgun nu bilemicem.anlatacak olanlarda senin benim gibi adamlar işin uzmanı değil.ama yardımcı olabilir.bizede böyle bir eğitim verilmedi , utanmaya gerek yok bizi konuları anlatmayan üniversiteler utanmalı  ama üniversite lojik temelini verdiyse her konuda olduğu gibi gerisi sana kalmış.

kodlamalar  en önemli kısım ilk başta yazılır veya şöyle ifade edersek veri akışında verinin ilk geçeceği durum en sona son geçeceği durum en başa yazılır ama hepsi clk sinyalinin altındadır çünkü fpga senkron tasarımları gerçeklemek için üretilmiştir aynı işlemin cloğu aynı olmak zorundadır.

pic365

Alıntı yapılan: speak48 - 05 Nisan 2012, 16:02:32
bizede böyle bir eğitim verilmedi , utanmaya gerek yok bizi konuları anlatmayan üniversiteler utanmalı  ama üniversite lojik temelini verdiyse her konuda olduğu gibi gerisi sana kalmış.
Türkiye'de sayısal tasarım konusunda ders veren çok fazla hoca yok. İstanbul'da benim bildiğim Sabancı, Özyeğin, Yeditepe ve Boğaziçi Üniversitesi'nde var.

vitruvius

Arkadaşlar yapmak istediğim devreyi iki şekilde gerçekleştirdim. İlkinde led'i kaydırmak amaçlı yaptım. İkinci tasarımda ise bir değişkeni değiştirip onun değerine göre kontrol etmek istedim. İkisinin de kodunu veriyorum, kolay gelsin.

Kaydırma ile:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity istek is
port(
		buton: in std_logic;
		ledg: out std_logic_vector(7 downto 0);
		clk: in std_logic
);
end istek;

architecture arch of istek is
signal counter: std_logic_vector(23 downto 0);
signal ara: std_logic_vector(15 downto 0);
signal enable: std_logic;
signal ledgs: std_logic_vector(7 downto 0):=x"01";

begin

	ledg<=ledgs;
	
process(clk)
begin
if (clk'event and clk='1') then
	if(enable='1') then
	counter<=counter+1;
	elsif(buton='0') then
	enable <='1';
	end if;
	if(counter=x"A00000") then
	enable<='0';
	counter<= (others=>'0');
		if(buton='0') then
		ledgs<=ledgs(0)&ledgs(7 downto 1);
		end if;
	end if;
end if;
end process;
end arch;


Değişken ile:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity deneme is
port (
		 buton: in std_logic;
		 ledg: out std_logic_vector(7 downto 0);
		 clk: in std_logic
);
end deneme;

architecture arch of deneme is

signal counter: std_logic_vector(23 downto 0);
signal enable: std_logic;
signal ledgs: std_logic_vector(7 downto 0);
signal buton_s: std_logic;
signal say: integer range 0 to 8;

begin
	ledg<=ledgs;
	
	process(clk,buton) -- Debounce
	begin
		if(clk'event and clk='1') then
			if(enable='1') then
			counter<=counter+1;
			buton_s<='0';
			elsif(buton='0') then
			enable<='1';
			end if;
			if(counter=x"A00000") then
			enable<='0';
			counter<=(others=>'0');
				if(buton='0') then
				buton_s<='1';
				end if;
			end if;
		end if;
	end process;
	
	process(buton_s) -- Sayaç	
	begin
		if(buton_s='1') then
		say<=say+1;		
			if(say=8) then
			say<=0;
			end if;
		end if;
	end process;

	process(say)
	begin
		case say is
			when 0 => ledgs <= "00000000";
			when 1 => ledgs <= "00000001";
			when 2 => ledgs <= "00000010";
			when 3 => ledgs <= "00000100";
			when 4 => ledgs <= "00001000";
			when 5 => ledgs <= "00010000";
			when 6 => ledgs <= "00100000";
			when 7 => ledgs <= "01000000";			
			when others => ledgs <= "10000000";
		end case;
	end process;
			
	
end arch;