Układy cyfrowe i systemy wbudowane 1 SPRAWOZDANIE 8

Układy cyfrowe i systemy wbudowane 1 – laboratorium mgr inż. Antoni Sterna Pt 1245 - 1500

SPRAWOZDANIE

Tym razem, w odróżnieniu od wszystkich poprzednich zajęć, nasze projekty mieliśmy zrealizować na układzie Spartan. Jest to o wiele bardziej rozbudowany i dający o większe możliwości układ, niż wcześniejszy XC9572XL. Na zajęciach mieliśmy za zadanie zbudować układ realizujący funkcję „echa” na porcie szeregowym dla wybranego zakresu znaków (znaki odebrane z komputera mieszczące się w zadanym przedziale miały zostać odesłane przez układ, inne pominięte). Drugie zadanie polegało na skonstruowaniu układu konwertującego wartości heksadecymalne przesyłane portem szeregowym z komputera na kod BCD i wyświetlić na wbudowanym wyświetlaczu LCD. Ćwiczenia zrealizowaliśmy w programie Xilnix ISE Project Navigator.

  1. Układ realizujący funkcję „echa” na porcie szeregowym

Układ zbudowaliśmy wykorzystując gotowy moduł do obsługi portu szeregowego wbudowanego w Spartana. Do tego modułu podłączyliśmy napisany przez nas moduł filtrujący znaki odebrane z portu szeregowego, którego kod znajduje się poniżej. Po utworzeniu symbolu z napisanego modułu mogliśmy przystąpić do podłączenia wszystkiego w całość. Ostatecznie układ przedstawiał się następująco:

A oto kod filtra:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx primitives in this code.

--library UNISIM;

--use UNISIM.VComponents.all;

entity filter is

port(

start_in : in std_logic;

filter_input : in std_logic_vector(7 downto 0);

start_out : out std_logic;

filter_output : out std_logic_vector(7 downto 0));

end filter;

architecture filter_arch of filter is

subtype byte is integer range 0 to 255;

constant zero : byte := character'pos('0');

constant nine : byte := character'pos('9');

constant lower_a : byte := character'pos('a');

constant lower_z : byte := character'pos('z');

constant upper_a : byte := character'pos('A');

constant upper_z : byte := character'pos('Z');

signal filter_input_value : byte;

begin

filter_input_value <= to_integer(unsigned(filter_input));

process(filter_input_value)

begin

if filter_input_value >= zero and filter_input_value <= nine then

filter_output <= std_logic_vector(to_unsigned(filter_input_value, filter_output'length));

elsif filter_input_value >= lower_a and filter_input_value <= lower_z then

filter_output <= std_logic_vector(to_unsigned(filter_input_value - 16#20#, filter_output'length));

elsif filter_input_value >= upper_a and filter_input_value <= upper_z then

filter_output <= std_logic_vector(to_unsigned(filter_input_value + 16#20#, filter_output'length));

else

filter_output <= (others => '0');

end if;

end process;

start_out <= start_in when ((filter_input_value >= zero and filter_input_value <= nine)

or (filter_input_value >= lower_a and filter_input_value <= lower_z)

or (filter_input_value >= upper_a and filter_input_value <= upper_z)) else '0';

end filter_arch;

  1. Układ konwertujący wartości heksadecymalne przesyłane portem szeregowym z komputera na kod BCD i wyświetlający na wbudowanym wyświetlaczu LCD

Do realizacji układu, podobnie jak w poprzednim punkcie, skorzystaliśmy z gotowego modułu obsługi portu szeregowego, ponadto skorzystaliśmy jeszcze z modułu obsługującego wyświetlacz LCD. Do całości potrzebny był nam jeszcze moduł konwertera, który napisaliśmy w VHDL i którego kod znajduje się poniżej. Po podłączeniu wszystkiego razem układ prezentował się następująco:

A tak wygląda kod modułu konwertera, który na schemacie znajduje się w postaci symbolu bcd_impl:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx primitives in this code.

--library UNISIM;

--use UNISIM.VComponents.all;

entity bcd_impl is

port(

hex_in : in std_logic_vector(7 downto 0);

bcd_out : out std_logic_vector(11 downto 0));

end bcd_impl;

architecture bcd_impl_arch of bcd_impl is

begin

process(hex_in)

variable temporary : unsigned(11 downto 0);

variable input_value : unsigned(7 downto 0);

begin

temporary := to_unsigned(0, bcd_out'length);

input_value := unsigned(hex_in);

for i in 0 to 7 loop

if temporary(3 downto 0) > 4 then

temporary(3 downto 0) := temporary(3 downto 0) + 3;

end if;

if temporary(7 downto 4) > 4 then

temporary(7 downto 4) := temporary(7 downto 4) + 3;

end if;

if temporary(11 downto 8) > 4 then

temporary(11 downto 8) := temporary(11 downto 8) + 3;

end if;

temporary := temporary sll 1;

temporary(0) := input_value(7);

input_value := input_value sll 1;

end loop;

bcd_out <= std_logic_vector(temporary);

end process;

end bcd_impl_arch;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx primitives in this code.

--library UNISIM;

--use UNISIM.VComponents.all;

entity counter is

port(

CLR : in std_logic;

Clk_LF : in std_logic;

modulo : in std_logic_vector(1 downto 0);

count : out std_logic_vector(3 downto 0);

terminal_count : out std_logic);

end counter;

architecture counter_arch of counter is

signal count_internal : unsigned(3 downto 0);

signal modulo_value : unsigned(3 downto 0);

begin

process (modulo) is

begin

case modulo is

when "00" => modulo_value <= to_unsigned(3, 4);

when "01" => modulo_value <= to_unsigned(2, 4);

when "10" => modulo_value <= to_unsigned(8, 4);

when "11" => modulo_value <= to_unsigned(2, 4);

when others => modulo_value <= to_unsigned(0, 4);

end case;

end process;

process (CLR, Clk_LF) is

begin

if CLR = '1' then

count_internal <= to_unsigned(0, count_internal'length);

elsif rising_edge(Clk_LF) then

if count_internal < (modulo_value - to_unsigned(1, count_internal'length)) then

count_internal <= (count_internal + to_unsigned(1, count_internal'length));

else

count_internal <= to_unsigned(0, count_internal'length);

end if;

end if;

end process;

count <= not std_logic_vector(count_internal);

terminal_count <= '1' when (count_internal + to_unsigned(1, 3) = modulo_value) else '0';

end counter_arch;

Wnioski:

Dzięki tym zajęciom mieliśmy okazję doskonalić nasze umiejętności w zakresie programowania w języku VHDL. Podobnie jak na poprzednich zajęciach, korzystaliśmy zarówno z opisu modułów w języku VHDL, jak i budowy schematu układu za pomocą symboli. Pozwoliło to maksymalnie uprościć budowę układu przy wykorzystaniu wszystkich korzyści, jakie daje nam stosowanie języka VHDL. Ponadto zajęcia te pozwoliły nam zapoznać się z kolejnym produktem firmy Xilinx – układem Spartan. Zrobił on na nas duże wrażenie, bo w porównaniu z poprzednim układem oferuje o wiele więcej różnych przycisków i interfejsów, które z pewnością będziemy wykorzystywać w czasie kolejnych zajęć.


Wyszukiwarka