VHDL ile 7-Segment Display Üzerine Birden Fazla Sayı Yazdırmak

Paylaşacağım şey bizim geçen dönem EE – 102 dersinde yaptığımız lablardan sadece bir tanesi. Olay şu, on-off butonlarını kullanarak 8-bitlik bir input elde ediyoruz ve çıkan toplamı da 4 tane 7-segment displayimizin üzerine yazdırıyoruz. 7-segment display çalışması ile ilgili olarak da, pratik aslında sadece bir tane displayi aktifleştirebiliyoruz, ancak bir frekans’u baya büyük, mesala 2kHz gibi bir clock ile hangi displayin değişmeli olarak yanacağını kontrol ediyoruz. Bu sayede yine aynı anda en fazla bir tanesi yanmış oluyor ancak o kadar hızlı değişiyorlar ki gözle fark edemiyoruz ve sanki hepsi birlikte yanıyormuş gibi görüyoruz. Bu da böyle işte. Gelelim kodlara, kodları satır satır anlatmayacağım çünkü bu benim için baya sıkıcı olur ancak yine de bir şeyler anlayabilirsiniz umarım yazdıklarımdan. Öncelikle top modulümüzden başlayalım.

hex2LedTop.vhd


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

entity hex2LedTop is
	Port (clk: in STD_LOGIC;
	nCheck: in std_logic;
	DATA : in STD_LOGIC_VECTOR(7 downto 0);
	SelectDisplay : out STD_LOGIC_VECTOR(3 downto 0);--segment selct
	SEGMENTS : out STD_LOGIC_VECTOR(6 downto 0)
	);
end hex2LedTop;

architecture Top_arch of hex2LedTop is
--components
component clkdivide is
	Port (clkin: in std_logic;
	clkout:out std_logic );
end component;

component conv_bcd is
	Port ( DATA : in STD_LOGIC_VECTOR(7 downto 0);
	D3 : out std_logic_vector(3 downto 0);
	D2 : out std_logic_vector(3 downto 0);
	D1 : out std_logic_vector(3 downto 0);
	D0 : out std_logic_vector(3 downto 0));
end component;

component hex2led is
	port (clock : in STD_LOGIC;
	nCheck2: in std_logic;
	D3,D2,D1,D0 : in STD_LOGIC_VECTOR(3 downto 0);
	SEGMENTS : out STD_LOGIC_VECTOR(6 downto 0);
	SelectDisplay : out STD_LOGIC_VECTOR(3 downto 0));
end component;

--signals
signal wire: std_logic;
signal A1,B1,C1,D11: std_logic_vector (3 downto 0);

begin
	L1: hex2led port map (
		nCheck2=>nCheck,
		SEGMENTS=>SEGMENTS,
		clock=>wire,
		SelectDisplay=>SelectDisplay,
		D3=>D11,
		D2=>C1,
		D1=>B1,
		D0=>A1
	);
	L2:clkdivide port map (clkin=>clk , clkout=>wire);
	L3:conv_bcd port map (DATA=>DATA,D3=>D11,D2=>C1,D1=>B1,D0=>A1);
end Top_arch;

hex2Led.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_ARITH.all;
use IEEE.std_logic_UNSIGNED.all;

entity hex2led is
	port (clock : in STD_LOGIC;
	nCheck2: in std_logic;
	D3,D2,D1,D0 : in STD_LOGIC_VECTOR(3 downto 0);
	SEGMENTS : out STD_LOGIC_VECTOR(6 downto 0);
	SelectDisplay : out STD_LOGIC_VECTOR(3 downto 0));
end hex2led;

architecture arch of hex2led is

signal counter:bit_vector(1 downto 0) :="00";

begin
	L1:process(D3,D2,D1,D0,clock, nCheck2)

	variable Z: std_logic_vector(3 downto 0);
	variable A: integer;

	begin
		if clock'event and clock='1' then
			if counter="00" then counter<="01"; Z:=D0; SelectDisplay <= "1110"; end if;
			if counter="01" then counter<="10"; Z:=D1; SelectDisplay <= "1101"; end if;
			if counter="10" then counter<="11"; Z:=D2; SelectDisplay <= "1011"; end if;
			if counter="11" then counter<="00"; Z:=D3; SelectDisplay <= "0111"; end if;
			A := 1000*conv_integer(D3) + 100*conv_integer(D2) +  10*conv_integer(D1) + conv_integer(D0);
			if(nCheck2='1') then
				if(A<50) then
					--write LO to the display
					if(counter="11") then
						SEGMENTS <= "1000111"; --writes L
					elsif(counter="10") then
						SEGMENTS <= "1000000"; --writes O
					else
						SEGMENTS <= "1111111";
					end if;
				elsif(A>200) then
					--write HI to the display
					if(counter="11") then
						SEGMENTS <= "0001001";--writes H
					elsif(counter="10") then
						SEGMENTS <= "1001111"; --writes I
					else
						SEGMENTS <= "1111111";
					end if;
				else
					if(counter="00") then
						case CONV_INTEGER(Z) is
							when 0 => SEGMENTS <= "1000000";
							when 1 => SEGMENTS <= "1111001";
							when 2 => SEGMENTS <= "0100100";
							when 3 => SEGMENTS <= "0110000";
							when 4 => SEGMENTS <= "0011001";
							when 5 => SEGMENTS <= "0010010";
							when 6 => SEGMENTS <= "0000010";
							when 7 => SEGMENTS <= "1111000";
							when 8 => SEGMENTS <= "0000000";
							when 9 => SEGMENTS <= "0010000";
							when others => SEGMENTS <="0001001";
						end case;
					elsif(counter="01") then
						case CONV_INTEGER(Z) is
							when 0 => SEGMENTS <= "1000000";
							when 1 => SEGMENTS <= "1111001";
							when 2 => SEGMENTS <= "0100100";
							when 3 => SEGMENTS <= "0110000";
							when 4 => SEGMENTS <= "0011001";
							when 5 => SEGMENTS <= "0010010";
							when 6 => SEGMENTS <= "0000010";
							when 7 => SEGMENTS <= "1111000";
							when 8 => SEGMENTS <= "0000000";
							when 9 => SEGMENTS <= "0010000";
							when others => SEGMENTS <="0001001";
						end case;
					elsif(counter="10") then
						case CONV_INTEGER(Z) is
							when 0 => SEGMENTS <= "1000000";
							when 1 => SEGMENTS <= "1111001";
							when 2 => SEGMENTS <= "0100100";
							when 3 => SEGMENTS <= "0110000";
							when 4 => SEGMENTS <= "0011001";
							when 5 => SEGMENTS <= "0010010";
							when 6 => SEGMENTS <= "0000010";
							when 7 => SEGMENTS <= "1111000";
							when 8 => SEGMENTS <= "0000000";
							when 9 => SEGMENTS <= "0010000";
							when others => SEGMENTS <="0001001";
						end case;
					elsif(counter="11") then
						case CONV_INTEGER(Z) is
							when 0 => SEGMENTS <= "1000000";
							when 1 => SEGMENTS <= "1111001";
							when 2 => SEGMENTS <= "0100100";
							when 3 => SEGMENTS <= "0110000";
							when 4 => SEGMENTS <= "0011001";
							when 5 => SEGMENTS <= "0010010";
							when 6 => SEGMENTS <= "0000010";
							when 7 => SEGMENTS <= "1111000";
							when 8 => SEGMENTS <= "0000000";
							when 9 => SEGMENTS <= "0010000";
							when others => SEGMENTS <="0001001";
						end case;
					end if;
				end if;
			elsif(nCheck2='0') then
					if(counter="00") then
					case CONV_INTEGER(Z) is
						when 0 => SEGMENTS <= "1000000";
						when 1 => SEGMENTS <= "1111001";
						when 2 => SEGMENTS <= "0100100";
						when 3 => SEGMENTS <= "0110000";
						when 4 => SEGMENTS <= "0011001";
						when 5 => SEGMENTS <= "0010010";
						when 6 => SEGMENTS <= "0000010";
						when 7 => SEGMENTS <= "1111000";
						when 8 => SEGMENTS <= "0000000";
						when 9 => SEGMENTS <= "0010000";
						when others => SEGMENTS <="0001001";
					end case;
				elsif(counter="01") then
					case CONV_INTEGER(Z) is
						when 0 => SEGMENTS <= "1000000";
						when 1 => SEGMENTS <= "1111001";
						when 2 => SEGMENTS <= "0100100";
						when 3 => SEGMENTS <= "0110000";
						when 4 => SEGMENTS <= "0011001";
						when 5 => SEGMENTS <= "0010010";
						when 6 => SEGMENTS <= "0000010";
						when 7 => SEGMENTS <= "1111000";
						when 8 => SEGMENTS <= "0000000";
						when 9 => SEGMENTS <= "0010000";
						when others => SEGMENTS <="0001001";
					end case;
				elsif(counter="10") then
					case CONV_INTEGER(Z) is
						when 0 => SEGMENTS <= "1000000";
						when 1 => SEGMENTS <= "1111001";
						when 2 => SEGMENTS <= "0100100";
						when 3 => SEGMENTS <= "0110000";
						when 4 => SEGMENTS <= "0011001";
						when 5 => SEGMENTS <= "0010010";
						when 6 => SEGMENTS <= "0000010";
						when 7 => SEGMENTS <= "1111000";
						when 8 => SEGMENTS <= "0000000";
						when 9 => SEGMENTS <= "0010000";
						when others => SEGMENTS <="0001001";
					end case;
				elsif(counter="11") then
					case CONV_INTEGER(Z) is
						when 0 => SEGMENTS <= "1000000";
						when 1 => SEGMENTS <= "1111001";
						when 2 => SEGMENTS <= "0100100";
						when 3 => SEGMENTS <= "0110000";
						when 4 => SEGMENTS <= "0011001";
						when 5 => SEGMENTS <= "0010010";
						when 6 => SEGMENTS <= "0000010";
						when 7 => SEGMENTS <= "1111000";
						when 8 => SEGMENTS <= "0000000";
						when 9 => SEGMENTS <= "0010000";
						when others => SEGMENTS <="0001001";
					end case;
				end if;
			end if;
		end if;
	end process;
end arch;

clkdivide.vhd

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

entity clkdivide is
	Port (clkin: in std_logic;
	clkout:out std_logic );
end clkdivide;

architecture Behavioral of clkdivide is

signal int_clock:std_logic;

begin
	clkout<=int_clock;
	process(clkin)
	variable var:integer range 0 to 12500 :=0;
	begin
	if (clkin'event and clkin = '1') then
		if var = 12500 then
			int_clock <= not int_clock; var:=0;
		else
			var:=var+1;
		end if;
	end if;
end process;

end Behavioral;

conv_bcd.vhd

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

entity conv_bcd is

	Port ( DATA : in STD_LOGIC_VECTOR(7 downto 0);
	D3 : out std_logic_vector(3 downto 0);
	D2 : out std_logic_vector(3 downto 0);
	D1 : out std_logic_vector(3 downto 0);
	D0 : out std_logic_vector(3 downto 0));
end conv_bcd;

architecture Behavioral of conv_bcd is
begin
	process(DATA)
	variable AA,BB,CC,DD,i: integer;
	begin
		AA:= CONV_INTEGER(DATA);
		BB:=0;
		CC:=0;
		DD:=0;
		for i in 1 to 2 loop
			if AA > 99 then AA:=AA-100;CC:=CC+1;end if;
		end loop;
		for i in 1 to 9 loop
			if AA > 9 then AA:=AA-10;BB:=BB+1;end if;
		end loop;
		D0<=CONV_STD_LOGIC_VECTOR(AA,4);
		D1<=CONV_STD_LOGIC_VECTOR(BB,4);
		D2<=CONV_STD_LOGIC_VECTOR(CC,4);
		D3<=CONV_STD_LOGIC_VECTOR(DD,4);
	end process;
end Behavioral;

Ve eğer Basys2 Board üzerinde deneme yapmak isterseniz işte port atamalarıda aşağıdaki gibi.

pin.ucf

NET "DATA<7>" LOC = "n3" ;
NET "DATA<6>" LOC = "e2" ;
NET "DATA<5>" LOC = "f3" ;
NET "DATA<4>" LOC = "g3" ;
NET "DATA<3>" LOC = "b4" ;
NET "DATA<2>" LOC = "k3" ;
NET "DATA<1>" LOC = "l3" ;
NET "DATA<0>" LOC = "p11" ;
NET "SEGMENTS<0>" LOC = "l14" ;
NET "SEGMENTS<1>" LOC = "h12" ;
NET "SEGMENTS<2>" LOC = "n14" ;
NET "SEGMENTS<3>" LOC = "n11" ;
NET "SEGMENTS<4>" LOC = "p12" ;
NET "SEGMENTS<5>" LOC = "l13" ;
NET "SEGMENTS<6>" LOC = "m12" ;
NET "SelectDisplay<3>" LOC = "k14" ;
NET "SelectDisplay<2>" LOC = "m13" ;
NET "SelectDisplay<1>" LOC = "j12" ;
NET "SelectDisplay<0>" LOC = "f12" ;
NET "clk" LOC = "b8";
net "nCheck" loc= "a7";


Bu ve buna benzer yazılardan haberdar olmak için kaydol:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>