Tomasz Dumała

Transkrypt

Tomasz Dumała
Tomasz DUMAŁA – IV rok
Koło Naukowe Techniki Cyfrowej
Dr inŜ. Wojciech Mysiński – opiekun naukowy
ELECTRIC IMPULSE DURATION MEASUREMENT USING VHDL
LANGUAGE
ZASTOSOWANIE JĘZYKA VHDL DO POMIARU CZASU TRWANIA
IMPULSU ELEKTRYCZNEGO.
Keywords: VHDL, measurement, electric impulse, programmable device, duration
Słowa kluczowe: VHDL, pomiar, impuls elektryczny, układ programowalny, czas trwania
1. KONCEPCJA UKŁADU POMIAROWEGO.
Pomiar czasu trwania impulsu prostokątnego moŜna przeprowadzić między innymi
wykorzystując liczniki, układy mikroprocesorowe, mikrokontrolery lub stosując układy
programowalne. W mojej pracy postaram się przedstawić, w jaki sposób korzystając z
układów programowalnych(FPGA) skonstruować układ spełniający załoŜenia tematu.
Na początek postaram się przedstawić algorytm, którym będę się kierował projektując
układ. W tym celu sporządziłem schemat blokowy przedstawiony na poniŜszym rysunku.
Rys. 1.1 Schemat blokowy układu pomiarowego.
1.1. ZASADA DZIAŁANIA
1. Podanie mierzonego impulsu:
a. na blok sterujący
b. na bramkę elektroniczną
2. Podanie sygnału z generatora wzorcowego na bramkę elektroniczną.
3. Bramka elektroniczna porównuje sygnały na nią podane.
a. gdy impuls mierzony jest w stanie wysokim to bramka przepuszcza sygnały z
generatora wzorcowego
b. gdy impuls mierzony jest w stanie niskim to bramka na wyjściu przyjmuje stan
niski (czyli nie przepuszcza sygnału z generatora)
4. Gdy bramka przepuszcza sygnał z generatora to zaczyna swą prace układ zaliczający.
5. Blok sterowania(umoŜliwia pomiar wielu impulsów występujących po sobie):
a. kontrola zerowania licznika
b. kontrola zatrzasku
6. Wyświetlenie wyniku pomiaru na wyświetlaczu.
1.2. ALGORYTM UKŁADU ZLICZAJĄCEGO IMPULSY.
Rys. 1.2. Algorytm układu.
Wynikiem działania kolejnych bloków powyŜszego schematu jest układ wykresów
przedstawiający role i funkcje podanych segmentów.
Rys. 1.3. Wykresy zaleŜności między blokami układu pomiarowego.
Działanie układu polega na zliczaniu impulsów podawanych z generatora wzorcowego.
Znając okres generatora moŜemy obliczyć czas trwania impulsu według następującej
zaleŜności.
T
I
= nT W
gdzie:
T
T
I
W
- czas trwania impulsu mierzonego
- okres impulsu z generatora wzorcowego
1.3. OGRANICZENIA ZWIĄZANE Z BŁĘDAMI POMIAROWYMI.
W danym czasie układ zlicza n ± 1 impulsów, zatem błąd z tym związany będzie wynosił
1
. Wynika stąd, iŜ im krótszy pomiar czasu tym jest on obarczony większym błędem.
n
Całkowity błąd jakim jest obarczony układ będzie sumą poszczególnych błędów w nim
występujących. W rzeczywistości na kaŜdym elemencie występuje opóźnienie związane z
czasem propagacji. Dlatego teŜ stosuje się generatory wzorcowe, których błąd waha się w
granicach 10-5 – 10-8.
Przyjmując za błąd techniczny wartość 1% moŜna oszacować jaki minimalny czas, który
moŜemy zmierzyć uŜywając generatora o określonej częstotliwości.
f – częstotliwość generatora
T- okres impulsu generatora
t- minimalny czas, który moŜemy zmierzyć, przy danej częstotliwości nie przekraczając
błędu technicznego
Długość okresu obliczamy ze wzoru:
T=
1
f
Jak wspomniałem wyŜej błąd pomiaru obliczamy ze wzoru:
δ=
1
n
gdzie n- liczba zliczonych impulsów.
Zatem
δ ≤ 0,01 = 1%
dla n ≥ 100
Czyli
t = nT
Układ, który dla przykładu skonstruowałem jest taktowany częstotliwością f=1MHz,
więc T= 0,1µs z czego wynika, Ŝe moŜemy nim wykonać pomiar impulsu nie krótszego niŜ
t=1ms, aby błąd nie przekroczył 1%.
2. PODSTAWY JĘZYKA VHDL I IMPLEMENTACJA PROJEKTU.
2.1. PODSTAWY PROGRAMOWANIA W VHDL’u.
2.1.1. WPROWADZENIE.
Nazwa pochodzi od Very High Speed Integrated Circuit i Hardware Description
Language. Sięga on 1983 roku. Początkowo był językiem stworzonym dla amerykańskiego
Departamentu Obrony, do opisu sprzętu elektronicznego. W 1987 roku doczekał się
standaryzacji. Następne poprawki były w 1993 roku.
Dziś jest to powszechnie stosowany język do opisu, syntezy i symulacji sprzętu
elektronicznego. Dzięki niemu moŜemy łatwo tworzyć i symulować roŜnego rodzaju
urządzenia cyfrowe bez większych nakładów finansowych. Przy prostych projektach
uŜytkownik nie musi się martwić o optymalizację wykonywanych funkcji gdyŜ robi to za
niego system projektowy. Dzięki stałej pracy programistów powyŜsze systemy są ciągle
ulepszane i staja się mniej zawodne, mogą równieŜ zastępować inŜyniera na niektórych
etapach projektowania. Jak widać takie podejście znacznie skraca czas od zaprojektowania do
wykonania danego elementu, co przy dzisiejszej konkurencji jest istotną sprawą.
Technika ta w ostatnich latach znacznie poszła do przodu dzięki czemu w dzisiejszych
czasach produkowane są juŜ układy zbudowane z setek tysięcy, a nawet milionów bramek, co
daje nam niezmiernie duŜe moŜliwości.
Dla przykładu podam kilka układów FPGA firmy Xilinx z rodziny Spartan-3.
Układ XC3S50, gdzie ostatnia liczba „50” oznacza liczbę bramek systemowych, które
zawiera układ. Inne układy z tej rodziny to XC3S200, XC3S400, XC3S1000, XC3S1500,
XC3S2000, XC3S4000 oraz XC3S5000. Jak widać pierwszy z nich zawiera 50000 bramek,
natomiast ostatni, aŜ 5000000 bramek.
Przygotowując przykłady do powyŜszego referatu korzystam z oprogramowania
WebPACK w wersji 6.3.03i firmy Xilinx. Obecnie jest juŜ na rynku wersja 8.1 jednak Ŝe
wersja 6.3 jest juŜ sprawdzoną i niezawodną wersją, w przeciwieństwie do nowo
wychodzących wersji.
Do symulacji polecam ModelSim XE III 6.0a. Programy te, po uprzednim zarejestrowaniu
się moŜna ściągnąć ze strony producenta www.xilinx.com .
2.1.2. PODSTAWOWE ZAGADNIENIA JĘZYKA.
KaŜdy projekt w języku VHDL składa się z jednostki projektowej (opis tzw. czarnej
skrzynki, z wyszczególnionymi tylko wejściami i wyjściami) i architektury, która opisuje
zaleŜności pomiędzy wejściami i wyjściami danej „czarnej skrzynki”.
Podstawowe części programu w języku VHDL.
Opis jednostki
Opis architektury
entity bramka_and is
Port ( nazwy i typu portów wejść
i wyjść );
end bramka_and;
architecture arch_and of bramka_and is
begin
opis zaleŜności między wejściami i
wyjściami
end arch_and;
A oto przykładowy prosty program w VHDL’u opisujący dwu wejściową bramkę AND:
(znak „--” oznacza przejście do opisu)
Przykładowy projekt.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
deklaracja
wykorzystywanych
bibliotek
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity bramka_and is
Port ( a : in std_logic;
b : in std_logic;
y : out std_logic);
end bramka_and;
deklaracja jednostki
projektowej, wraz z
opisem wejść-wyjść
in-wejście , out-wyjście
koniec deklaracji jednostki
architecture arch_and of bramka_and is
deklaracja architektury
zawierającej opis
zaleŜności pomiędzy
wejściami i wyjściami
(y <= a and b;)
begin
y <= a and b;
end arch_and;
koniec deklaracji
architektury
2.1.3. OBIEKTY W VHDL’u
Podstawowym obiektem jest sygnał. MoŜe on być zewnętrzny (pobierany z portów układu)
lub wewnętrzny (deklarowany w ciele architektury, przed słowem kluczowym begin ).
Deklaracja sygnału wewnętrznego wygląda następująco:
signal nazwa_sygnału : typ_sygnału
Na końcu moŜemy dodać ograniczenie lub wartość domyślną sygnału, jak to jest pokazane
poniŜej.
signal calkowita : intiger range 0 to 10; -- ograniczenie od 0 do 10
signal a : bit :=’1’; -- wartość domyślna
W procedurach i podprogramach moŜemy równieŜ korzystać ze zmiennych, które są
pomocnicze do zapamiętywania wyników naszych obliczeń. Deklaracja wygląda tak:
variable nazwa_zmiennej : typ_zmiennej
Wartość domyślną oraz ograniczenie tworzymy tak samo jak w przypadku sygnałów.
MoŜemy równieŜ stosować wartości stałe, a ich deklaracja wygląda następująco:
constant nazwa_stałej : typ_stałej :=wyraŜenie
Do przechowywania danych mogą słuŜyć pliki, ich deklaracja to:
file nazwa_pliku : typ_danych [open tryb] is „nazwa_pliku”;
2.1.4. TYPY W VHDL’u
Spis typów języka VHDL.
TYP
bit
boolean
integer
natural
positive
real
std_ulogic
i std_logic
character
time
string
OPIS
Wartość logiczna ‘0’ lub ‘1’
Logiczna prawda lub fałsz
Liczby całkowite
Liczby naturalne
Liczby naturalne z wyjątkiem zera
Liczby rzeczywiste
Typy wielowartościowe dzięki którym moŜemy np. opisać stan wysokiej
impedancji, stan niezainicjowany czy tez dowolny
Znaki ze zbioru ASCII
Czas, zakres od 0 do 2147483647 i jednostki: fs, ps, ns, us, ms, sec, min, hr
Deklaruje ciągi znaków
UŜytkownik moŜe deklarować własne typy:
•
Wyliczeniowe (wypisanie kolejno elementów) np. type wyliczeniowy is (1,3,5,7,9);
•
ZłoŜone (odpowiednik tablicy w innych językach)
np. type złoŜony is array(0 to 7) of bit; signal a : bit_vector(0 to 3);
•
Podtypy (ograniczenie zakresu typów) np. subtype liczby is integer range 0 to 12;
2.1.5. OPERATORY W VHDL’u
Lista operatorów stosowanych w języku.
OPERATOR
not
and
nand
or
nor
xor
Xnor
+
*
/
&
mod
rem
=
/=
<
>
<=
>=
sll
srl
sla
sra
rol
ror
abs
**
+
-
OPIS
Operatory logiczne
Negacja wartości logicznej
Iloczyn logiczny
Zanegowany iloczyn logiczny
Suma logiczna
Zanegowana suma logiczna
Prawda gdy sygnały róŜnych wartości
Negacja xor
Operatory arytmetyczne
Arytmetyczne dodawanie
Arytmetyczne odejmowanie
MnoŜenie
Dzielenie
Sklejanie
Obliczanie modułu
Reszta z dzielenia
Operatory relacji
Rowność
Nierówność
Mniejszy
Większy
Mniejszy bądź równy
Większy bądź równy
Operatory przesunięcia
Przesuwa słowo logiczne w lewo, puste miejsca wypełniają się zerami
Przesuwa słowo logiczne w prawo, puste miejsca wypełniają się zerami
Przesuwa słowo logiczne w lewo, puste miejsca wypełniają się jedynkami
Przesuwa słowo logiczne w prawo, puste miejsca wypełniają się jedynkami
Przesuwa słowo logiczne w lewo do okoła, ostatni bit staje się pierwszym
Przesuwa słowo logiczne w prawo do okoła, pierwszy bit staje się ostatnim
RoŜne
Liczy wartość bezwzględną
Potęgowanie
Określenie znaku wartości
Określenie znaku wartości
2.2. IMPLEMENTACJA PROJEKTU.
Schemat projektu moŜemy przedstawić następująco:
Rys. 2.1 Schemat blokowy układu do pomiaru czasu trwania impulsu elektrycznego.
Układ umoŜliwia da sposoby pomiaru:
1) pomiar tylko jednego impulsu
2) pomiar czasu impulsów następujących po sobie
Jak widać układ składa się pojedynczych bloków, które najpierw oddzielnie opisze w
języku VHDL, a następnie połączę wykorzystując moŜliwości tego języka. Jest to tzw.
programowanie strukturalne.
Pierwszym blokiem, który opisze będzie układ wejściowy odpowiadający za kierowanie
zliczaniem impulsów zegarowych. Dzięki niemu moŜemy wybrać rodzaj pracy dla naszego
urządzenia. W programie jest to zrobione w ten sposób, Ŝe jeŜeli sygnał zewnętrzny: „sposób”
jest równy „1” to mierzymy czas wszystkich następujących po sobie impulsów i wyświetlamy
zmierzone czasy na na wyświetlaczu(po kaŜdym zboczu opadającym). A jeŜeli „sposob”
równa się „0” to układ zlicza czas tylko jednego impulsu a jego zbocze opadające powoduje
jego wyświetlenie na wyświetlaczu i zablokowanie dalszego zliczania. PoniŜej przedstawiam
kod opisywanego bloku.
entity poczatek is
Port ( C : in std_logic;
sygnal : in std_logic;
sposob : in std_logic;
wyjs : out std_logic);
end poczatek;
architecture Behavioral of poczatek is
signal a : std_logic := '1';
begin
process(sposob,sygnal)
begin
if sposob = '1' then
a <= '1';
elsif sposob = '0' then
if falling_edge(sygnal) then
a <= '0';
end if;
end if;
end process;
wyjs <= C when (a and sygnal) = '1' else
'0';
end Behavioral;
W kolejnym kroku omówię „serce” całego projektu to znaczy licznik. Składa się on z 6
liczników liczących w kodzie BCD. Dzięki tej jednostce pokaŜe sposób łączenia małych
programów (komponentów) w większe bardziej złoŜone projekty.
W tym celu zaimplementowałem pojedynczy licznik:
entity licznikBCD is
Port ( zegar : in std_logic;
reset : in std_logic;
przen : out std_logic;
wyjscie : out std_logic_vector(3 downto 0) );
end licznikBCD;
architecture Behavioral of licznikBCD is
begin
process(zegar,reset)
variable zmien_pom : unsigned(3 downto 0);
begin
if reset = '1' then
zmien_pom := "0000";
elsif rising_edge(zegar) then
if zmien_pom < 9 then
zmien_pom := zmien_pom + 1;
przen <= '0';
else
zmien_pom := "0000";
przen <= '1';
end if;
end if;
wyjscie <= std_logic_vector(zmien_pom);
end process;
end Behavioral;
Liczni ten posiada 2 wejścia : zegar i reset oraz 2 wyjścia : przen i wyjscie, które jest
wektorem 4-ro bitowym. W procesie wykorzystujemy zmienną pomocniczą : zmien_pom.
Układ reaguje na zbocze rosnące zegara(funkcja rising_edge(zegar)), gdy je wykryje to
zwiększa nasza zmienną pomocniczą o 1 i tak do 9. Jeśli licznik zliczy 9 impulsów to
następne pojawia się na nim „0” i równocześnie jest podawany sygnał przeniesienia.
Sygnał przeniesienia generowany w danym liczniku jest podawany na następny jako
sygnał zegarowy i tak oto uzyskujemy kolejną liczbę do wyświetlenia na naszym
wyświetlaczu. Aby to jednak połączyć musimy napisać poniŜszy program:
entity licz_zlozony is
Port ( zeg : in std_logic;
res : in std_logic;
wyj1 : out std_logic_vector(3 downto 0);
wyj2 : out std_logic_vector(3 downto 0);
wyj3 : out std_logic_vector(3 downto 0);
wyj4 : out std_logic_vector(3 downto 0);
wyj5 : out std_logic_vector(3 downto 0);
wyj6 : out std_logic_vector(3 downto 0));
end licz_zlozony;
architecture gotowe of licz_zlozony is
COMPONENT licznikbcd
PORT(
zegar : IN std_logic;
reset : IN std_logic;
przen : OUT std_logic;
wyjscie : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
signal a,b,c,d,e,f : std_logic;
begin
g1: licznikbcd port map (zeg,res,a,wyj1);
g2: licznikbcd port map (a,res,b,wyj2);
g3: licznikbcd port map (b,res,c,wyj3);
g4: licznikbcd port map (c,res,d,wyj4);
g5: licznikbcd port map (d,res,e,wyj5);
g6: licznikbcd port map (e,res,f,wyj6);
end gotowe;
Program ten przy pomocy komponentów odwołuje się do programu licznikBCD i łączy ze
sobą 6 takich pojedynczych liczników, w sposób pokazany na poniŜszym rysunku.
zegar
reset
przen
wyj1
zegar
przen
wyj2
zegar
przen
wyj3
zegar
przen
wyj4
zegar
przen
wyj5
zegar
wyj6
Rys. 2.2 Sposób połączenia licznika.
KaŜdy komponent to jakby jeden wewnętrzny bloczek. Do ich połączenia uŜywamy
pomocniczych sygnałów wewnętrznych: a, b, c, d, e, f, oraz specjalnej procedury :
G1: licznikbcd port map (zeg,res,a,wyj1);
Dzięki temu poleceniu moŜemy łatwo przypisać sygnały wejściowe i wyjściowe do
odpowiednich komponentów, co daje nam połączenie ich w jeden większy program
Mógłbym opisać tu wszystkie bloki, jakie znajdują się w głównym rysunku, takie jak:
zatrzask, dekoder, dzielnik czy wyświetlanie,
jednakŜe zajęłoby wiele czasu, a nie oto tu chodzi. Myślę, Ŝe w przedstawionym przeze mnie
materiale ukazałem podstawową architekturę i sposób projektowania.
Na zakończenie podam tylko kod do głównego programu, który scala wszystkie bloki z
Rys.2.1 w jedną całość. Korzystałem tu równieŜ z komponentów.
entity pomiar_czasu is
Port ( zegar : in std_logic;
sygnal : in std_logic;
sposob : in std_logic;
reset : in std_logic;
led : out std_logic_vector(6 downto 0);
wyswietlacz : out std_logic_vector(5 downto 0));
end pomiar_czasu;
architecture gotowa of pomiar_czasu is
COMPONENT poczatek
PORT(
C : IN std_logic;
sygnal : IN std_logic;
sposob : IN std_logic;
wyjs : OUT std_logic
);
END COMPONENT;
COMPONENT licz_zlozony
PORT(
zeg : IN std_logic;
res : IN std_logic;
wyj1 : OUT std_logic_vector(3 downto 0);
wyj2 : OUT std_logic_vector(3 downto 0);
wyj3 : OUT std_logic_vector(3 downto 0);
wyj4 : OUT std_logic_vector(3 downto 0);
wyj5 : OUT std_logic_vector(3 downto 0);
wyj6 : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
COMPONENT zatrzask
PORT(
syg : IN std_logic;
we1 : IN std_logic_vector(3 downto 0);
we2 : IN std_logic_vector(3 downto 0);
we3 : IN std_logic_vector(3 downto 0);
we4 : IN std_logic_vector(3 downto 0);
we5 : IN std_logic_vector(3 downto 0);
we6 : IN std_logic_vector(3 downto 0);
wy1 : OUT std_logic_vector(3 downto 0);
wy2 : OUT std_logic_vector(3 downto 0);
wy3 : OUT std_logic_vector(3 downto 0);
wy4 : OUT std_logic_vector(3 downto 0);
wy5 : OUT std_logic_vector(3 downto 0);
wy6 : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
COMPONENT dekoder_zlozony
PORT(
we1 : IN std_logic_vector(3 downto 0);
we2 : IN std_logic_vector(3 downto 0);
we3 : IN std_logic_vector(3 downto 0);
we4 : IN std_logic_vector(3 downto 0);
we5 : IN std_logic_vector(3 downto 0);
we6 : IN std_logic_vector(3 downto 0);
seg1 : OUT std_logic_vector(6 downto 0);
seg2 : OUT std_logic_vector(6 downto 0);
seg3 : OUT std_logic_vector(6 downto 0);
seg4 : OUT std_logic_vector(6 downto 0);
seg5 : OUT std_logic_vector(6 downto 0);
seg6 : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;
COMPONENT wyswietlanie
PORT(
zegar : IN std_logic;
we1 : IN std_logic_vector(6 downto 0);
we2 : IN std_logic_vector(6 downto 0);
we3 : IN std_logic_vector(6 downto 0);
we4 : IN std_logic_vector(6 downto 0);
we5 : IN std_logic_vector(6 downto 0);
we6 : IN std_logic_vector(6 downto 0);
wyjs : OUT std_logic_vector(6 downto 0);
wy : OUT std_logic_vector(5 downto 0)
);
END COMPONENT;
COMPONENT dzielnik
PORT(
zegar : IN std_logic;
podzielony : OUT std_logic
);
END COMPONENT;
signal a,multip : std_logic;
signal b1,b2,b3,b4,b5,b6 : std_logic_vector(3 downto 0);
signal c1,c2,c3,c4,c5,c6 : std_logic_vector(3 downto 0);
signal d1,d2,d3,d4,d5,d6 : std_logic_vector(6 downto 0);
begin
g1: poczatek port map (zegar,sygnal,sposob,a);
g2: licz_zlozony port map (a,reset,b1,b2,b3,b4,b5,b6);
g3: zatrzask port map (sygnal,b1,b2,b3,b4,b5,b6,c1,c2,c3,c4,c5,c6);
g4: dekoder_zlozony port map (c1,c2,c3,c4,c5,c6,d1,d2,d3,d4,d5,d6);
g5: dzielnik port map (zegar,multip);
g6: wyswietlanie port map (multip,d1,d2,d3,d4,d5,d6,led,wyswietlacz);
end gotowa;
Dla zainteresowanych polecam ksiąŜkę umieszczoną pod pozycją numer [3] w literaturze,
gdyŜ zawiera ona wiele ciekawych przykładów.
LITERATURA
[1] Karkowski Zdzisław, „Miernictwo elektroniczne”, WSiP, Warszawa 1982.
[2] Pieńkoś Jan, Turczyński Janusz, „Układy scalone TTL w systemach cyfrowych”, WKŁ,
Warszawa 1986.
[3] Mark Zwoliński, z jęz. ang. przeł. Marian Adamski, Marek Węgrzyn, Zbigniew
Skowroński „Projektowanie układów cyfrowych z wykorzystaniem języka VHDL”.WKŁ,
Warszawa 2002.

Podobne dokumenty