Documente Academic
Documente Profesional
Documente Cultură
LUCRARE DE DIPLOMĂ
„Automat pentru controlul şi monitorizarea unei parcări”
Coordonator ştiinţific:
Prof. Dr. Ing. EMIL VREMERA
Absolvent: GAVRILA MARIUS GABRIEL
IASI
- 2010 -
AUTOMAT PENTRU CONTROLUL ŞI
MONITORIZAREA UNEI PARCĂRI
CUPRINS
CAPITOLUL 1
CONSIDERAŢII TEORETICE ......................................... pag. 4
1.1. CIRCUITE LOGICE PROGRAMABILE ........................... pag. 4
1.1.1. CIRCUITE PLA .......................................................................... pag. 5
1.1.2. CIRCUITE PAL .......................................................................... pag. 6
1.1.3. CIRCUITE CPLD ....................................................................... pag. 6
1.1.4. CIRCUITE FPGA ....................................................................... pag. 7
1.2. VHDL .................................................................................. pag. 8
1.2.1. INTRODUCERE ÎN VHDL .......................................................
pag. 8
1.2.2. FUNDAMENTELE VHDL ....................................................... pag.
10
1.2.3. ENTITĂŢI LOGICE ŞI ARHITECTURI .................................. pag.
15
1.2.4. DESCRIEREA STRUCTURILOR COMBINAŢIONALE ....... pag.
22
1.2.5. DESCRIEREA STRUCTURILOR SECVENŢIALE ................ pag.
35
2
1.2.6. DESCRIEREA AUTOMATELOR FINITE .............................. pag.
54
CAPITOLUL 2
PROIECTAREA UNUI AUTOMAT PENTRU CONTROLUL
ŞI MONITORIZAREA UNEI PARCĂRI ............................ pag. 63
2.1. DESCRIEREA PROIECTULUI ........................................ pag. 63
2.2. PROIECTAREA SCHEMEI-BLOC .................................. pag. 65
2.3. DESCRIEREA ŞI SIMULAREA BLOCURILOR
FUNCŢIONALE ................................................................ pag. 66
2.3.1. DESCRIEREA ŞI SIMULAREA AUTOMATULUI ................ pag. 66
2.3.2. DESCRIEREA ŞI SIMULAREA DISPOZITIVULUI
DE MONITORIZARE ............................................................... pag. 78
2.4. SURSA VHDL ŞI SIMULAREA PROIECTULUI ........... pag. 82
2.4.1. SURSA VHDL A PROIECTULUI ............................................ pag. 82
2.4.2. SIMULAREA PROIECTULUI .................................................. pag. 85
CONCLUZII ............................................................................ pag. 90
BIBLIOGRAFIE ..................................................................... pag. 91
3
CAPITOLUL 1
CONSIDERAŢII TEORETICE
fuzibili
cu programare
definitivă
antifuzibili
Conectori
programabili
tranzistori
MOS
reprogramabili
tranzistori
FLOTOX
Porţile logice programabile ale unui circuit PLD pot fi reprezentate în mod simplificat
ca în figura 1.1(b). În locul unor linii de intrare multiple la fiecare dintre aceste porţi, ca în
figura 1.1(a), în reprezentarea simplificată s-a figurat o singură linie. Semnul x indică o
conexiune programabilă a unei linii de intrare la o poartă logică. Absenţa semnului x indică
faptul că respectiva conexiune a fost programată în starea deconectată.
4
(a)
reprezentare
obişnuită
Fig 1.1.
Porţi ŞI, respectiv SAU
(b)
reprezentare simplificată
pentru circuitele PLD
Fig 1.1.
Porţi ŞI, respectiv SAU
Există mai multe tipuri de circuite care sunt denumite în mod generic circuite logice
programabile (PLD). Principalele tipuri sunt:
- PLA (Programmable Logic Array)
- PAL (Programmable Array Logic)
- CPLD (Complex Programmable Logic Device)
- FPGA (Field Programmable Gate Array)
Un circuit PLA (Programmable Logic Array) poate implementa în mod direct un set
de funcţii logice exprimate printr-un tabel de adevăr. Fiecare intrare pentru care valoarea
funcţiei este adevărată necesită un termen produs, şi acestuia îi corespunde o linie de por ţi
ŞI din primul etaj al circuitului PLA. Fiecare ieşire corespunde la o linie de por ţi SAU din al
doilea etaj al circuitului. Numărul de porţi SAU corespunde cu numărul de intrări din tabela
Fig. 1.2.
Structura generală a unui circuit
PLA
5
de adevăr pentru care ieşirea este adevărată. Dimensiunea totală a circuitului PLA este
egală cu suma dintre dimensiunea reţelei de porţi ŞI şi dimensiunea reţelei de porţi SAU.
Din Figura 1.2 se observă că dimensiunea reţelei de porţi ŞI este egală cu numărul
de intrări multiplicat cu numărul diferiţilor termeni produs, iar dimensiunea reţelei de porţi
SAU este egală cu numărul de ieşiri multiplicat cu numărul termenilor produs.
Fig. 1.3.
Structura generală a unui circuit PAL
6
interconectarea blocurilor. Funcţiile logice simple pot fi implementate în cadrul uni singur
bloc. Funcţiile mai complexe pot necesita mai multe blocuri, care vor fi interconectate prin
matricea de rutare.
Fig. 1.4.
Structura generală a unui circuit CPLD
Fig. 1.5.
Structura unui circuit FPGA tipic
7
Caracteristicile unor circuite FPGA (Xilinx)
Matricea Nr. total Nr. porţi Nr. Pini Nr. f max Vcc
Tip circuit bistabili
CLB CLB elementare I/O [MHz] [V]
XC4002XL 8x8 64 3000 64 256 220 2,5/3,3
XC406E 16 x 16 256 12000 128 768 200 2,5/3,3
XC425E 32 x 32 1024 45000 256 2560 200 2,5/3,3
XC4044XL 40 x 40 1600 80000 320 3840 180 2,5/3,3
XC408XL 56 x 56 3136 180000 448 7168 145 2,5/3,3
1.2. VHDL
(Very High Speed Integrated Circuits Hardware Description Language)
1.2.1. Introducere în VHDL
Caracterizare generală
Putere şi flexibilitate
- descrierea structurilor logice de dimensiuni mari prin cod succint;
- descriere ierarhizată a structurilor complexe;
- număr mare de biblioteci predefinite;
- posibilitatea definirii de noi articole de bibliotecă sau de noi biblioteci;
- posibilitatea simulării complexe înainte de implementare.
Portabilitate mare
- limbaj standardizat la nivel mondial (IEEE-1164 şi IEEE-1076)
- consecinţă: sursele VHDL potcod
fi compilate
VHDL şi procesate folosind o mare diversitate de medii
sursă
de dezvoltare.
Codarea Descrierea în
VHDL
Compilarea sursei.
Sinteza şi optimizarea matematică a
schemei logice. Sinteza
Optimizarea schemei în raport cu schemei
structura şi resursele circuitului-ţintă.
Generarea fişierului executabil.
Generarea documentaţiei.
Simularea logică
Automat Simularea
schemei
Simularea electronică
Caractere legale:
- litere mari (A ... Z)
- litere mici (a ... z)
- cifre (0 ... 9)
- linia de subliniere (underscore)
Reguli de respectat:
- primul caracter să fie o literă
- ultimul caracter să nu fie linia de subliniere
- să nu conţină două linii de subliniere consecutive
- să nu conţină spaţii goale (blank-uri)
- să nu fie cuvinte rezervate
Exemple:
Identificatori legali Identificatori ilegali
10
IntrareA23 Semnal A
iesire_Q14 Validare__iesire
Reset_asincron intrare-date
cip_select_2 _clk_
COUNT_enable 12A&B
Comentarii
Comentariile încep cu două linii (--) şi se termină la capătul rândului.
Exemplu:
-- Acesta este un comentariu
-- scris pe două rânduri
VARIABILE:
- valoare neschimbată pe parcursul unei instrucţiuni;
facultativ
11
variable identificator : tip := valoare iniţială ;
- valoare variabilă pe parcursul programului.
Tipuri de date
Tipuri predefinite:
- INTEGER
- CHARACTER
- STRING
- BOOLEAN
- BIT
- BIT_VECTOR specifice clasei
SIGNAL
- STD_LOGIC
- STD_LOGIC_VECTOR
12
Exemplu: variable A : integer range -255 to 255 ;
Constantele de tip std_logic ‘0’, ‘1’, ‘Z’ şi ‘-’ se scriu între apostrofuri.
Observaţie:
- valorile ‘1’ şi ‘0’ se pot folosi oriunde în program;
- valoarea ‘Z’ se poate atribui doar unui port de ieşire de nivel înalt (ieşire din sistem asociată
unui pin fizic al circuitului integrat);
- valoarea ‘-’ nu se poate folosi în instrucţiuni de tip condiţional (if … then … else) sau cu
operatori relaţionali.
13
Constantele de tip std_logic_vector se scriu între ghilimele.
Exemplu: signal a : std_logic_vector(0 to 7) ;
a<=”0-1ZZ010” ;
Operatori uzuali
14
1.2.3. Entităţi logice şi arhitecturi
Portul
I/O ARHITECTURA
(interfaţa)
Declaraţia entităţii
entity
Definiţia arhitecturii
architecture
15
Ex: comparator 2 x 1 bit
a
COMP - dacă a = b, EGAL = 1
EGAL
2x1 - dacă a b, EGAL = 0
b
Declaraţia entităţii
Sintaxa generală:
entity numele_entităţii is port
(
declararea semnalelor
de intrare/ieşire
care definesc portul
);
end numele_entităţii ;
16
Forma generală a declaraţiei de semnal:
nume_semnal : sens (mod) tip ;
in std_logic
orice out std_logic_vector
identificator inout bit
legal buffer bit_vector
Exemplu:
Exemplu:
Definirea arhitecturii
Sintaxa generală:
numele_arhitecturii numele_entităţii
17
architecture of is
begin
instrucţiuni care descriu arhitectura
end numele_arhitecturii ;
std_logic
orice std_logic_vector
identificator bit
legal bit_vector
Exemplu:
signal u, v, w : std_logic;
Instrucţiuni:
- concurente
- secvenţiale
Instrucţiuni concurente
Aceste instrucţiuni definesc structuri logice elementare şi conexiunile dintre ele
(scheme logice). Nu sunt legate de funcţionarea în timp a entităţii logice.
Este indiferent în ce ordine se scriu în descrierea arhitecturii.
Exemple:
18
- Atribuirea de valori logice semnalelor:
a<=’1’;
A<= B;
B <= C;
Instrucţiuni secvenţiale
Instrucţiunile secvenţiale definesc un algoritm comportamental al entităţii logice. Ele
descriu succesiunea în timp a operaţiilor logice elementare.
Este foarte importantă ordinea în care se scriu instrucţiunile în descrierea arhitecturii.
Exemple:
- Bistabil D cu acţiune pe frontul pozitiv al CLK, cu resetare asincronă:
if RESET <= ’1’ then Q <= ‘0’ ;
elsif rising_edge(CLK) then Q<=D ;
end if ;
19
1. întâi se testează RESET,
2. apoi se testează frontul crescător al CLK,
3. în final se testează intrarea de date D.
- Comparator de 2 x 1 bit:
y <= ‘0’;
if a=b then y <= ‘1’;
end if;
Tipuri de descriere:
- comportamentală
- flux de date
- structurală
Descrierea comportamentală
Descrierea comportamentală este o modalitate de descriere de nivel înalt. Aceasta
defineşte un algoritm comportamental al entităţii logice.
Unitatea de program care defineşte un algoritm se numeşte proces. O arhitectură
conţine unul sau mai multe procese.
Descrierea procesului se face în special cu instrucţiuni de tip secvenţial (pot să existe
însă şi instrucţiuni concurente).
Exemple:
- Descrierea arhitecturii unui comparator 2 x 2 biţi, folosind funcţii logice:
library ieee;
use ieee.std_logic_1164.all;
entity COMP is port
(A, B: in std_logic_vector(1 downto 0);
Y: out std_logic);
end COMP;
architecture arch_COMP_1 of COMP is
begin
Y <= NOT(A(1) XOR B(1)) AND NOT(A(0) XOR B(0));
end arch_COMP_1;
21
Descrieri de tip structural
Descrierile de tip structural indică explicit structura (schema) internă a entităţii logice
descrise.
Acestea folosesc blocuri funcţionale predefinite, pe care le extrag din bibliotecă şi
descriu modul de interconectare a acestora.
Dacă blocurile funcţionale nu există în bibliotecă, ele pot fi creeate, compilate şi
salvate ca articole de bibliotecă.
Exemplu:
- Descrierea structurală a arhitecturii unui comparator 2 x 2 biţi:
library ieee;
use ieee.std_logic_1164.all;
entity COMP is port
(A, B: in std_logic_vector(0 to 1);
Y: out std_logic);
end COMP;
use work.gatespkg.all -- biblioteca ce conţine porţile
-- logice xnor2 şi and2
architecture arch_COMP of COMP is
signal X: std_logic_vector(0 to 1); -- se definesc semnalele interne X
begin
u0: xnor2 port map (A(0), B(0), X(0)); -- se definesc conexiunile
între
u1: xnor2 port map (A(1), B(1), X(1)); -- porţile logice din schemă
u2: and2 port map (X(0), X(1), Y);
end arch_COMP;
Se folosesc:
- descrieri: - comportamentale
- flux de date
22
- structurale
- instrucţiuni: - concurente
- secvenţiale
Exemplu:
23
library ieee;
use ieee.std_logic_1164.all
entity MUX is port
(a, b, c, d: in std_logic_vector(3 downto 0);
s: in std_logic_vector(1 downto 0);
y: out std_logic_vector(3 downto 0));
end MUX;
architecture arch_MUX of MUX is
begin
y(3) <= (a(3) and not (s(1)) and not (s(0))) or (b(3) and not (s(1)) and not (s(0)))
or (c(3) and not (s(1)) and not (s(0))) or (d(3) and not (s(1)) and not (s(0)));
y(2) <= (a(2) and not (s(1)) and s(0)) or (b(2) and not (s(1)) and s(0))
or (c(2) and not (s(1)) and s(0)) or (d(2) and not (s(1)) and s(0));
y(1) <= (a(1) and s(1) and not (s(0))) or (b(1) and s(1) and not (s(0)))
or (c(1) and s(1) and not (s(0))) or (d(1) and s(1) and not (s(0)));
y(0) <= (a(0) and s(1) and s(0)) or (b(0) and s(1) and s(0))
or (c(0) and s(1) and s(0)) or (d(0) and s(1) and s(0));
end arch_MUX;
valoare_n-1 24 valoare_n-1_semnal_selecţie
valoare_n
when ,
...
when ,
when others ;
Exemplu: MUX 4:1 de 4 biţi
library ieee;
use ieee.std_logic_1164.all
entity MUX is port
(a, b, c, d: in std_logic_vector(3 downto 0);
s: in std_logic_vector(1 downto 0);
y: out std_logic_vector(3 downto 0));
end MUX;
architecture arch_MUX of MUX is
begin
with S select
y <= a when ”00”,
b when ”01”,
c when ”10”,
d when others; -- others desemnează aici valoarea s=11,
-- dar şi toate combinaţiile conţinând Z
end arch_MUX;
25
Cuvântul rezervat others desemnează toate valorile posibile ale selectorului, în afară
de cele specificate în instrucţiune.
valoare_n ;
26
entity MUX is port
(a, b, c, d: in std_logic_vector(3 downto 0);
s: in std_logic_vector(1 downto 0);
y: out std_logic_vector(3 downto 0));
end MUX;
architecture arch_MUX of MUX is
begin
y <= a when (s = ”00”) else
b when (s = ”01”) else
c when (s = ”10”) else
d; -- y = d pentru s = 11
end arch_MUX;
Modul de operare al instrucţiunii when-else este asemănător cu al instrucţiunii with-
select-when.
NU are importanţă ordinea în care se testează condiţiile!
27
architecture arch_MUX of MUX is
begin
y <= a when (s = ”00”) else
b when (s = ”01”) else
c when (s = ”10”) else
‘Z’;
end arch_MUX;
Rezultatul operaţiei relaţionale este de tip boolean (true / false). Operanzii trebuie să
fie însă de acelaşi tip.
Exemplu:
signal a : std_logic_vector(3 downto 0);
signal y : std_logic;
...
y <= ‘1’ when (a = 9) else ‘0’; -- operaţia va genera o eroare, întrucât a
-- este de tip SIGNAL, iar 9 este de tip INTEGER
28
Prin overloading operatorii relaţionali pot fi aplicaţi între variabile de tipuri diferite.
Extinderea se face prin apelarea unor biblioteci specializate.
Exemplu:
biblioteca work.std_arith extinde utilizarea operatorilor relaţionali şi aritmetici la
semnalele de tip std_logic şi std_logic_vector.
Exemple:
- Detector de 9:
a3 a2 a1 a 0 y
1 0 0 1 1
alte valori 0
29
library ieee;
use ieee.std_logic_1164.all
use work.std_arith.all; -- extinde operatorii „<” şi „>” la semnale logice
entity COMP is port
(a, b : in std_logic_vector(3 downto 0);
aEGALb, aINFb, aSUPb : out std_logic);
end COMP;
architecture arch_COMP of COMP is
begin
aEGALb <= ‘1’ when (a = b) else ‘0’;
aINFb <= ‘1’ when (a < b) else ‘0’;
aSUPb <= ‘1’ when (a > b) else ‘0’;
end arch_COMP;
oe relaţia a, b y
a b
0 0
a=b
a b 0
1
a=b 1
library ieee;
use ieee.std_logic_1164.all
entity COMP is port
(a, b : in std_logic_vector(3 downto 0);
oe : in std_logic;
y : out std_logic);
end COMP;
architecture arch_COMP of COMP is
begin
30
y <= ‘1’ when (a = b AND oe = ‘1’) else ‘0’; -- condiţie compusă
end arch_COMP;
else acţiune_2 ;
end if ;
condiţie_3 acţiune_3
elsif then ;
acţiune_4
else ;
end if ;
31
library ieee;
use ieee.std_logic_1164.all
entity MUX is port
(a, b, c, d, e, f, g, h : in std_logic_vector(3 downto 0);
s : in std_logic_vector(2 downto 0);
y : out std_logic_vector(3 downto 0));
end MUX;
architecture arch_MUX of MUX is
begin
MUX_8_1 : process (a, b, c, d, e, f, g, h, s)
begin
if s = ”000” then y <= a;
elsif s = ”001” then y <= b;
elsif s = ”010” then y <= c;
elsif s = ”011” then y <= d;
elsif s = ”100” then y <= e;
elsif s = ”101” then y <= f;
elsif s = ”110” then y <= g;
else y <= h ;
end if ;
end process MUX_8_1;
end arch_MUX;
acţiune_n
32
when others => ;
end case;
Observaţii:
a) => este operatorul de asociere (asociază valoarea selectorului cu acţiunea specificată);
b) Pentru o valoare a selectorului pot fi specificate acţiuni multiple:
when valoare_selector => acţiune_1, acţiune_2, acţiune_3 ...;
c) Ultima specificare a selectorului este obligatoriu others.
33
(z : in std_logic_vector(0 to 3);
b : out std_logic_vector(1 downto 0));
end CODIF;
architecture arch_CODIF of CODIF is
begin
process (z) -- deschide un proces şi indică lista
senzitivităţilor
case z is -- deschide case-when şi indică
selectorul
when ”1000” => b <= ”00”;
when ”0100” => b <= ”01”;
when ”0010” => b <= ”10”;
when others => b <= ”11”; -- others reprezintă z=0001
-- şi toate celelalte combinaţii
nespecificate
end case; -- închide case-when
end process; -- închide procesul
end arch_CODIF;
34
Instrucţiuni de selecţie şi instrucţiuni condiţionale
Instrucţiuni de Instrucţiuni
selecţie condiţionale
- Descriu structuri logice prin relaţii de
tip intrare – ieşire
Instrucţiuni with-select- - Ordinea în care se scriu instrucţiunile
when-else
concurente when este indiferentă.
- Recomandate în descrierea
structurilor combinaţionale
- Definesc un algoritm comportamental
al entităţii logice.
if-then-else - Se folosesc în cadrul unui PROCES.
Instrucţiuni
case-when şi - Ordinea în care se scriu instrucţiunile
secvenţiale
if-elsif-else este foarte importantă.
- Obligatorii în descrierea structurilor
secvenţiale.
Execută acţiuni Execută acţiuni
în funcţie de în funcţie de
valoarea unui realizarea unei
selector. condiţii.
35
Structura generală a unui circuit secvenţial sincron
clk = ‘0’ sau clk = ‘1’ - exprimă nivelul logic al semnalului clk
atributul ‘event - exprimă o schimbare de nivel logic a semnalului clk
36
37
Procesul este senzitiv atât la clk
cât şi la d. Intervale de transparenţă
library ieee;
use ieee.std_logic_1164.all
entity D_latch is port
(d, clk : in std_logic;
q : out std_logic);
end D_latch;
architecture arch_D_latch of D_latch is
begin
process (clk, d) -- proces senzitiv faţă de clk şi d
begin
if (clk = ‘1’) then -- testează valoarea clk=1
q <= d; -- transmite valoarea d la q
end if;
end process; -- închide procesul
end arch_D_latch;
38
Descrierea bistabilului T
39
Este o instrucţiune simplă, care se poate intercala direct într-un proces.
Sintaxa:
wait until ( condiţie );
architecture arch_D of D is
begin
process -- nu este necesară lista de
senzitivităţi
begin
wait until (clk = ‘1’); -- sesizează frontul crescător al clk
q <= d; -- transmite valoarea d la q
end process;
end arch_D;
40
Sunt definite în biblioteca ieee.std_logic_1164.
Detectează fronturile crescătoare şi descrescătoare ale semnalelor.
Sintaxa:
rising_edge ( nume_semnal )
falling_edge ( nume_semnal )
architecture arch_D of D is
begin
process (clk) -- proces senzitiv numai faţă de clk
begin
if falling_edge (clk) then -- sesizează frontul descrescător al clk
q <= d;
end process;
end arch_D;
41
Realizează iniţializarea cu ‘1’ (PRESET) sau cu ‘0’ (RESET) a bistabililor, în
sincronism cu semnalul CLK.
Au acţiune prioritară faţă de intrările de date.
Exemplu: bistabil D cu acţiune pe frontul crescător, cu RESET sincron
library ieee;
use ieee.std_logic_1164.all;
entity D is port
(d, clk, reset : in std_logic;
q : out std_logic);
end D;
architecture arch_D of D is
begin
process (clk) -- proces senzitiv numai faţă de clk
begin
if rising_edge (clk) then -- testează frontul pozitiv al clk
if (reset = ‘1’) then -- testează intrarea reset
q <= ‘0’; -- iniţializează bistabilul cu ‘0’
else q <= d; -- transmite valoarea d la q
end if;
end if;
42
end process;
end arch_D;
Priorităţi: 1. reset
2. clk
3. d
library ieee;
use ieee.std_logic_1164.all;
entity D_latch is port
(d, clk, reset : in std_logic;
q : out std_logic);
end D_latch;
architecture arch_D_latch of D_latch is
begin
process (clk, d, reset) -- proces senzitiv numai faţă de clk, d şi reset
begin
if (reset = ‘1’) then -- testează intrarea reset
43
q <= ‘0’; -- iniţializează bistabilul cu ‘0’
elsif (clk = ‘1’) then -- testează prezenţa semnalului clk
q <= d; -- transmite valoarea d la q
end if;
end process; -- închide procesul
end arch_D_latch;
Numărătoare
Sunt automate simple: starea următoare a ieşirii depinde numai de starea actuală.
Se realizează din: bistabili + legături de reacţie + logică combinaţională
44
Descrierea funcţionării prin diagramă de stări:
45
Acest mod de funcţionare al operandului „+” extins permite descrierea foarte simplă a
numărătoarelor: la atingerea capacităţii numărătorului, acesta trece în stare iniţială.
clk reset q+
0 q+1
1 ”0000”
x q
Priorităţi: 1. clk
2. reset
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinderea operatorului +
entity NUM is port
(clk, reset : in std_logic;
q : buffer std_logic_vector(3 downto 0)); -- ieşirea în mod buffer
end NUM;
architecture arch_NUM of NUM is
begin
NUMARARE : process (clk) -- ieşirea este senzitivă numai la clk
begin
if rising_edge(clk) then -- testează frontul crescător al clk
if reset = ‘1’ then
q <= ”0000”; -- iniţializează cu zero
else q <= q+1; -- incrementează cu 1
end if;
end if;
46
end process NUMARARE;
end arch_NUM;
clk count_en q+
0 q
1 q+1
x q
Priorităţi: 1. clk
2. count_en
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinderea operatorului +
entity NUM is port
(clk, count_en : in std_logic;
q : buffer std_logic_vector(7 downto 0)); -- ieşirea în mod buffer
end NUM;
architecture arch_NUM of NUM is
begin
NUMARARE : process (clk) -- ieşirea este senzitivă numai la clk
begin
if rising_edge(clk) then -- testează frontul crescător al clk
if count_en = ‘1’ then
q <= q+1; -- incrementează cu 1
else q <= q; -- păstrează valoarea (redundant)
end if;
47
end if;
end process NUMARARE;
end arch_NUM;
Priorităţi: 1. clk 0 q
0
2. ini 1 q+1
3. count_en
1 x ”100..00”
x x q
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinderea operatorului +
entity NUM is port
(clk, count_en : in std_logic;
q : buffer std_logic_vector(15 downto 0)); -- ieşirea în mod buffer
end NUM;
architecture arch_NUM of NUM is
begin
NUMARARE : process (clk) -- ieşirea este senzitivă numai la clk
begin
if (clk’event and clk = ‘1’) then -- testează frontul crescător al clk
if ini = ‘1’ then
q <= (‘1’, others => ‘0’); -- iniţializează cu
1000...00
elsif count_en = ‘1’ then q <= q+1; -- incrementează cu 1
end if;
end if;
48
end process NUMARARE;
end arch_NUM;
0 q
Priorităţi: 1. clk 0
1 q+1
2. load
3. count_en 1 x data
x x q
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinderea operatorului +
entity NUM is port
(clk, load, count_en : in std_logic;
data : in std_logic_vector(7 downto 0);
q : buffer std_logic_vector(7 downto 0)); -- ieşirea în mod buffer
end NUM;
architecture arch_NUM of NUM is
begin
NUMARARE : process (clk) -- ieşirea este senzitivă numai la clk
begin
if (clk’event and clk = ‘1’) then -- testează frontul crescător al clk
if load = ‘1’ then
49
q <= data; -- încarcă valoarea de pe intrarea ”data”
elsif count_en = ‘1’ then q <= q+1; -- incrementează cu 1
end if;
end if;
end process NUMARARE;
end arch_NUM;
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinderea operatorului +
entity NUM is port
(clk, reset, preset : in std_logic;
q : buffer std_logic_vector(15 downto 0)); -- ieşirea în mod buffer
end NUM;
architecture arch_NUM of NUM is
begin
NUMARARE : process(reset,preset,clk) -- ieşirea este senzitivă la reset,preset,clk
begin
if reset = ‘1’ then -- testează reset
q <= (others => ‘0’); -- iniţializează cu ”000...00”
elsif preset <= ‘1’ then -- testează preset
50
q <= (others => ‘1’); -- iniţializează cu ”111...11”
elsif (clk’event and clk = ‘1’) then -- testează frontul crescător al clk
q <= q+1; -- incrementează cu 1
end if;
end process NUMARARE;
end arch_NUM;
library ieee;
use ieee.std_logic_1164.all;
entity TS is port
(y : in std_logic; -- în cazul când nu a fost deja
declarată
-- ca ieşire din entitate logică
oe : in std_logic; -- intrarea de validare (output enable)
y_out : out std_logic); -- ieşirea 3-state
end TS;
architecture arch_TS of TS is
begin
proc_TS : process (y, oe) -- ieşirea este senzitivă atât la y cât şi la oe
begin
51
if oe = ‘0’ then -- testează intrarea de validare
y_out <= ‘Z’; -- fixează ieşirea în starea HZ
else y_out <= y; -- validează ieşirea
end if;
end process proc_TS;
end arch_TS;
Observaţie: Procesul proc_TS este senzitiv la y şi oe, întrucât schimbări de stare ale acestor
mărimi determină schimbări de stare simultane ale ieşirii y_out. Descrierea se poate face şi cu
instrucţiunea concurentă when-else: y_out <= ‘Z’ when oe = ‘0’ else y (în acest caz nu este
necesară definirea unui proces).
Descrierea numărătorului:
reset clk count_en q+
1 x x ”0000”
0 q
0
1 q+1
(q este senzitiv la reset şi clk)
Descrierea operatorului TS:
- Numărătorul şi repetorul TS sunt descrise
prin două procese distincte, în cadrul aceleiaşi oe q_out
52
architecture arch_NUM_TS of NUM_TS is
signal q : std_logic_vector(3 downto 0); -- declară q ca semnal intern
begin
NUMARARE: process (reset, clk) -- proces ce descrie numărătorul
begin -- senzitiv la reset şi clk
if reset = ‘1’ then -- testează reset
q <= ”0000”; -- fixează ieşirea la ”0000”
elsif (clk’event and clk = ‘1’) then -- testează frontul crescător al clk
if count_en = ‘1’ then -- testează count_enable
q <= q+1; -- incrementează cu 1
end if;
end if;
end process NUMARARE;
IESIRE_TS : process(q, oe) -- proces ce descrie ieşirea TS
begin -- senzitiv la q şi oe
if oe = ‘0’ then q_out <= ”ZZZZ”; -- ieşirea HZ
else q_out <= q; -- ieşirea validată
end if;
end process IESIRE_TS;
end arch_NUM_TS;
Semnal bidirecţional
În cazul ieşirilor TS, pinii de ieşire pot fi folosiţi şi ca intrări. Semnalele respective vor
fi declarate cu modul inout.
Pinii q folosiţi ca
ieşire din numărător
53
Pinii q folosiţi ca
intrare de iniţializare
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinde operatorul + pentru operaţii cu
semnale
entity NUM is port
(load, clk, oe : in std_logic;
q : inout std_logic_vector (3 downto 0)); -- semnalul q este declarat
-- cu modelul inout
end NUM;
architecture arch_NUM of NUM is
signal y, d : std_logic_vector(3 downto 0); -- declară semnale interne
begin
NUMARARE: process (clk) -- proces ce descrie acţiunea de numărare
begin
if rising_edge(clk) then -- testează frontul pozitiv al clk
if load = ‘1’ then y <= d; -- încarcă valorile q în numărător
else y <= y+1; -- incrementează numărătorul cu
1
end if;
end if;
end process NUMARARE;
54
TS : process(y, oe) -- proces ce descrie ieşirea TS
begin
if oe = ‘0’ then -- testează intrarea de validare
q <= ”ZZZZ”; --întrerupe ieşirea TS
else
q <= y; -- validează ieşirea TS
end if;
end process TS;
d <= q; -- conectează ieşirea q la intrarea de iniţializare d
end arch_NUM;
Observaţie: Instrucţiunea (d <= q;) poate fi omisă dacă în linia (if load = ‘1’ then y <= d; )
se foloseşte direct semnalul q în loc de d.
Ieşirile depind numai de starea actuală a automatului (nu depind direct de intrări).
Specificarea automatului:
- intrarea X
- ieşirea Y
- stările (variabilele de stare) Q
- funcţia stării următoare Q = f(X,Q)
- funcţia ieşirii Y = g(Q) (tip Moore)
Reprezentarea automatului prin diagrama stărilor:
55
Descrierea diagramei stărilor
Diagrama stărilor:
Descrierea:
Se transpune în cod VHDL diagrama stărilor, folosind instrucţiuni secvenţiale:
case-when – pentru definirea stărilor
if-then-else – pentru definirea tranziţiilor
Declararea entităţii:
56
entity AUTOMAT is port
(fisa, coca, pepsi, clk : in std_logic;
iesire_coca, iesire_pepsi, iesire_fisa : out std_logic);
end AUTOMAT;
Descrierea arhitecturii:
Stările se precizează prin nume (etichete) declarate în cadrul unui tip enumerat:
type STARE is (asteptare, decizie, control_coca, control_pepsi,
livrare_coca, livrare_pepsi, restituire_fisa);
Se declară două variabile de tipul STARE, care vor desemna starea actuală şi starea
următoare:
signal stare_actuala, stare_urmatoare : STARE;
57
iesire_pepsi <= ‘0’; -- se precizează ieşirile
iesire_fisa <= ‘0’;
if prezenta_coca = ‘1’ then -- se precizează tranziţiile
stare_urmatoare <= livrare_coca;
else stare_urmatoare <= restituire_fisa;
end if;
end case;
end process proc_AUTOMAT;
Observaţii:
- primul proces descrie CUM au loc tranziţiile;
- al doilea proces arată CÂND au loc tranziţiile.
58
type STARE is (asteptare, decizie, control_coca, control_pepsi, -- lista stărilor
livrare_coca, livrare_pepsi, restituire_fisa);
signal stare_actuala, stare_urmatoare : STARE;
signal prezenta_coca, prezenta_pepsi : std_logic; -- semnale
interne
begin
proc_AUTOMAT : process (stare_actuala, fisa, coca, pepsi,
prezenta_coca, prezenta_pepsi);
begin
case stare_actuala is
when asteptare => iesire_coca <= ‘0’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘0’;
if fisa = ‘1’ then stare_urmatoare <= decizie;
else stare_urmatoare <= asteptare; -- instrucţiune redundantă
end if;
when decizie => iesire_coca <= ‘0’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘0’;
if coca = ‘1’ then stare_urmatoare <= control_coca;
elsif pepsi = ‘1’ then stare_urmatoare <= control_pepsi;
else stare_urmatoare <= decizie; -- instrucţiune redundantă
end if;
when control_coca => iesire_coca <= ‘0’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘0’;
if prezenta_coca = ‘1’ then stare_urmatoare <= livrare_coca;
else stare_urmatoare <= restituire_fisa;
end if;
when control_pepsi => iesire_coca <= ‘0’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘0’;
if prezenta_pepsi = ‘1’ then stare_urmatoare <= livrare_pepsi;
else stare_urmatoare <= restituire_fisa;
59
end if;
when livrare_coca => iesire_coca <= ‘1’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘0’;
stare_urmatoare <= asteptare;
when livrare_pepsi => iesire_coca <= ‘0’;
iesire_pepsi <= ‘1’;
iesire_fisa <= ‘0’;
stare_urmatoare <= asteptare;
when restituire_fisa => iesire_coca <= ‘0’;
iesire_pepsi <= ‘0’;
iesire_fisa <= ‘1’;
stare_urmatoare <= asteptare;
end case;
end process proc_AUTOMAT;
SINCRON : process (clk) -- proces ce descrie sincronizarea cu semnalul clk
begin
if (clk’event and clk = ‘1’) then
stare_actuala <= stare_urmatoare;
end if;
end process SINCRON;
end architecture arch_AUTOMAT;
60
Descrierea ciclului de funcţionare:
- Iniţial controlerul este în starea de aşteptare (memoria nu este activată nici pentru citire,
nici pentru scriere) : re = 0, we = 0.
- Un impuls ready = 1 activează controlerul, pe primul front crescător al clk.
- Pe următorul front crescător al clk testează starea intrării r_w (decizie) :
- dacă r_w = 1 se activează citirea din RAM (re = 1, we = 1);
- dacă r_w = 0 se activează scrierea în RAM (re = 0, we = 1).
- Starea de citire sau scriere se menţine pe mai multe perioade clk, până când un nou impuls
ready = 1 aduce controlerul în starea de aşteptare.
Diagrama stărilor:
re=0
we=0
re=0
we=0
re=0 re=1
we=1 we=0
ready=0 ready=0
61
library ieee;
use ieee.std_logic_1164.all;
entity CONTROLER is port
(ready, r_w, clk : in std_logic;
re, we : out std_logic);
end CONTROLER;
architecture arch_CONTROLER of CONTROLER is
type STARE is (asteptare, decizie, scriere, citire);
signal stare_actuala, stare_urmatoare : STARE;
begin
proc_CONTROLER : process (stare_actuala, ready, r_w -- descrie
-- diagrama stărilor
begin
case stare_actuala is
when asteptare => re <= ‘0’; we <= ‘0’; -- ieşirea
if ready = ‘1’ then stare_urmatoare <= decizie; -- tranziţia
else stare_urmatoare <= asteptare;
end if;
when decizie => re <= ‘0’; we <= ‘0’;
if r_w = ‘1’ then stare_urmatoare <= citire;
else stare_urmatoare <= scriere;
end if;
when citire => re <= ‘1’; we <= ‘0’;
if ready = ‘1’ then stare_urmatoare <= asteptare;
else stare_urmatoare <= citire;
end if;
when scriere => re <= ‘0’; we <= ‘1’;
if ready = ‘1’ then stare_urmatoare <= asteptare;
else stare_urmatoare <= scriere;
end if;
end case;
end process proc_AUTOMAT;
SINCRO : process (clk) -- proces ce descrie sincronizarea cu semnalul clk
62
begin
if rising_edge (clk) then
stare_actuala <= stare_urmatoare;
end if;
end process SINCRO;
end architecture arch_CONTROLER;
63
CAPITOLUL 2
PROIECTAREA UNUI AUTOMAT PENTRU
CONTROLUL ŞI MONITORIZAREA UNEI PARCĂRI
AFIŞOR
card roşu
roşu ieşire verde
verde
x1 x2 P
250 locuri
m
card
sus
intrare
jos
obstacol
64
ajunge înaintea barierei, conducătorul auto trebuie să introducă în aparat cardul de intrare.
După ce a introdus cardul, se ridică bariera. Când bariera ajunge sus, şoferul poate înainta iar
în momentul în care acesta atinge senzorul x2, bariera începe să coboare.
Din momentul în care s-a introdus cardul şi până când bariera ajunge jos după ce
automobilul trece de senzorul x2, semaforul are culoarea roşie. După ce bariera ajunge jos,
semaforul îşi schimbă culoarea, din roşu în verde.
Când şoferul doreşte să iasă cu maşina din parcare, acesta trebuie să parcurcă aceleaşi
etape ca atunci cand intră în parcare. În primul rând, aşteaptă ca semaforul să indice culoarea
verde, după care înaintează spre barieră. Când ajunge lângă barieră, introduce cardul de ieşire.
Apoi bariera se ridică iar când aceasta ajunge sus, şoferul poate înainta. După ce atinge
senzorul x1, bariera coboară.
La fel ca şi în cazul anterior, când maşina intra în parcare, se întâmplă şi acum. Din
momentul în care şoferul introduce cardul şi până trece cu maşina de barieră, semaforul are
culoarea roşie, apoi se schimbă în verde.
În cazul în care sub barieră se află un obstacol, aceasta se ridică, iar când ajunge sus
rămâne acolo până când unul din senzorii x1, x2 confirmă dispariţia obstacolului.
Un dispozitiv de monitorizare ţine evidenţa gradului de ocupare a parcării. În cazul în
care parcarea este complet ocupată se transmite un mesaj spre mai multe dispozitive de afişare
plasate pe străzile de acces spre parcare.
Proiectarea automatului s-a făcut folosind limbajul descriptor VHDL, pentru
implementare pe un circuit programabil de tip CPLD. S-a folosit mediul de dezvoltare WARP
al firmei CYPRESS.
Verificarea funcţionării s-a făcut prin simulare cu programul ACTIVE HDL-SIM din
mediul de dezvoltare WARP.
65
2.2. PROIECTAREA SCHEMEI-BLOC
sus ridică
jos coboară
obstacol
Automat barieră
roşu
verde
card_intrare
card_ieşire
CLK INI
data 8
load
8
Numărător q
reversibil
q=q+1
q=q-1
CLK reset
Detector
250
z
66
Afişare
„ocupat”
2.3. DESCRIEREA ŞI SIMULAREA BLOCURILOR
FUNCŢIONALE
sus ridică
jos coboară
obstacol
Automat barieră roşu
verde
card_intrare
card_ieşire
CLK INI
Descrierea automatului
67
Iniţializarea acestuia se face în mod asincron cu semnalul INI. Pe frontul crescător al
semnalului CLK se face trecerea automatului dintr-o stare în alta.
Semnalele de ieşire ale automatului sunt tot de 1 bit. Acestea sunt:
- ridica: comanda motorului barierei pentru ridicare
- coboara: comanda motorului barierei pentru coborâre
- rosu, verde: comenzi pentru semafoare
Funcţionarea automatului este descrisă cu ajutorul diagramei de stări a acestuia
prezentate mai jos.
Diagrama stărilor automatului
=’1’ =’1’
68
Iniţializarea automatului la punerea în funcţiune se face în mod asincron cu semnalul
INI care determină trecerea automatului în starea S0.
Trecerea dintr-o stare în alta se face pe frontul crescător al semnalului de sincronizare
(CLK).
Când automatul se află în starea S0, dacă card_intrare = ‘1’ şi jos = ‘1’, atunci
automatul trece în starea S1, dacă card_iesire = ‘1’ şi jos = ‘1’, acesta trece în starea S4, iar
altfel el rămâne în starea S0.
Dacă automatul se află în starea S1 şi sus = ‘1’ acesta va trece în starea S2, altfel va
rămâne în starea S1. Când se află în starea S4, dacă sus = ‘1’ automatul trece în starea S5,
altfel rămâne în starea S4.
Când automatul se află în starea S2, dacă x2 = ‘1’, acesta va trece în starea S3, altfel
rămâne în starea S2. Dacă se află în starea S5 şi x1 = ‘1’, atunci automatul trece în starea S3,
altfel rămâne în S5.
În cazul în care automatul se află în starea S3, dacă obstacol = ‘1’ va trece în S6, dacă
jos = ‘1’ va trece în starea S0, altfel rămâne în starea S3. Dacă se află în starea S6 şi sus = ‘1’,
automatul trece în starea S7, altfel rămâne în S6. Când automatul se află în starea S7 dacă
sus = ‘1’, rămâne în S7, altfel trece în starea S3.
Automatul are 4 ieşiri: ridica, coboara, rosu, verde.
În funcţie de starea în care se află automatul, avem următoarele valori ale ieşirilor:
- când se află în S0: ridica = ‘0’, coboara = ‘0’, rosu = ‘0’, verde = ‘1’;
- când se află în S1, S4 sau S6: ridica = ‘1’, coboara = ‘0’, rosu = ‘1’, verde = ‘0’;
- când se află în S2, S5 sau S7: ridica = ‘0’, coboara = ‘0’, rosu = ‘1’, verde = ‘0’;
- când se află în S3: ridica = ‘0’, coboara = ‘1’, rosu = ‘1’, verde = ‘0’;
69
-- se introduce numele directorului unde va fi salvată aplicaţia;
1.5. Next => Next => Select Target Device => CPLD => Flash 370I => C372i –66JC
-- se selectează circuitul CPLD care va conţine automatul ;
1.6. Finish
1.7. File => New => Text files => => Save as: AUTOMAT.vhd
-- se deschide fişierul sursă în care se va descrie în limbaj VHDL automatul;
1.8. Project => Add Files To Project => AUTOMAT.vhd => Add => OK
-- se ataşează fisierul text AUTOMAT.vhd
1.9. Se deschide fisierul AUTOMAT.vhd în care se vor introduce următoarele instrucţiuni:
library ieee;
use ieee.std_logic_1164.all; -- se precizează bibliotecile necesare pentru
descrierea şi compilarea circuitului descris;
use work.std_arith.all; -- extinde operatorul “+” la operaţii între
semnale şi numere întregi;
entity AUTOMAT is port -- entitatea descrie interfaţa automatului, adică,
care sunt semnalele de intrare şi ieşire din
automat;
-- porturile corespund pinilor automatului;
(INI, sus, jos, obstacol, x1, x2, card_intrare, card_iesire, CLK: in std_logic;
-- semnale de intrare de tip logic;
ridica, coboara, rosu, verde: out std_logic);
-- semnale de ieşire de tip logic;
end AUTOMAT;
architecture arch_of_AUTOMAT of AUTOMAT is
-- arhitectura descrie transformările care au loc
în interiorul CPLD pentru a funcţiona ca
automat;
-- pentru o entitate pot exista mai multe
arhitecturi care reprezintă implementări
alternative;
type STARE is (S0, S1, S2, S3, S4, S5, S6, S7);
70
-- stările automatului;
signal S: STARE;
begin
AUT: process(INI, CLK) -- procesul reprezintă o descriere de tip
comportamental a entităţii care conţine
instrucţiuni de tip secvenţial. Instrucţiunile se
execută atunci când se modifică valorile
semnalelor de intrare INI şi CLK;
begin
if INI=’1’ then --testează semnalul de iniţializare (iniţializarea
automatului);
S<=S0; -- instrucţiune de atribuire a stării S0 stării S;
elsif rising_edge(CLK) then
-- testează frontul crescător al CLK;
S<=S0;
case S is -- descrie diagrama stărilor;
when S0 =>
if card_intrare=’1’ and jos=’1’ then S<=S1;
elsif card_iesire=’1’ and jos=’1’ then S<=S4;
else S<=S0;
end if;
when S1=>
if sus=’1’ then S<=S2;
else S<=S1;
end if;
when S2=>
if x2=’1’ then S<=S3;
else S<=S2;
end if;
when S3=>
if jos=’1’ then S<=S0;
elsif obstacol=’1’ then S<=S6;
else S<=S3;
end if;
71
when S4=>
if sus=’1’ then S<=S5;
else S<=S4;
end if;
when S5=>
if x1=’1’ then S<=S3;
else S<=S5;
end if;
when S6=>
if sus=’1’ then S<=S7;
else S<=S6;
end if;
when S7=>
if x1=’1’ or x2=’1’ then S<=S3;
else S<=S7;
end if;
end case;
end if;
end process AUT;
ridica<=’1’ when (S=S1 or S=S6 or S=S4) else -- generarea
ieşirilor
‘0’;
coboara<=’1’ when (S=S3) else
‘0’;
rosu<=’0’ when (S=S0) else
‘1’;
verde<=’1’ when (S=S0) else
‘0’;
end arch_of_AUTOMAT;
Compilarea sursei
1.10. Project => Compiler Options => Timing Model => 1164/VHDL => OK
-- se va selecta opţiunea de compilare pentru simulare funcţională
72
-- a automatului cu programul Active –HDL Sim;
1.11. Compile => Project -- se vor compila fişierele ataşate aplicaţiei AUTOMAT;
1.12. Analizând fişierul AUTOMAT.rep (View => Report File) determinaţi cum au fost
alocate semnalele de intrare şi ieşire din automat pinilor circuitului CPLD.
Simularea automatului
73
Pentru semnalul card_intrare se completeaza rubrica “enter formula” astfel:
0 0, 1 1000000, 0 3000000
Pentru semnalul card_iesire se completeaza rubrica “enter formula” astfel:
0 0
Pentru semnalul sus se completeaza rubrica “enter formula” astfel:
0 0, 1 6000000, 0 11000000
Pentru semnalul jos se completeaza rubrica “enter formula” astfel:
1 0, 0 4000000, 1 14000000
Pentru semnalul x1 se completeaza rubrica “enter formula” astfel:
0 0
Pentru semnalul x2 se completeaza rubrica “enter formula” astfel:
0 0, 1 8000000, 0 10000000
Pentru semnalul obstacol se completeaza rubrica “enter formula” astfel:
0 0
74
Simulare
Scenariul: Intrare în parcare
75
Scenariul: Ieşire din parcare
76
Scenariul: Prezenţă obstacol la intrarea în parcare
77
Scenariul: Prezenţă obstacol la ieşirea din parcare
78
2.3.2. Descrierea şi simularea dispozitivului de monitorizare
Portul dispozitivului de monitorizare
79
data 8
load
8
Numărător q
reversibil
card_intrare q=q+1
card_ieşire
q=q-1
CLK reset
Detector
250
Afişare
„ocupat”
Dispozitivul este compus din:
- un numărător reversibil
- un detector de „parcare ocupată”
- dispozitive de afişare a stării „ocupat”.
Numărătorul reversibil are ca intrări de tip std_logic: load, card_intrare, card_iesire,
reset şi clk. Intrarea data este de tip std_logic_vector, este o intrare pe 8 biţi.
La ieşire avem semnalul q de tip buffer std_logic_vector pe 8 biţi şi semnalul z de tip
std_logic.
Iniţializarea circuitului se face cu semnalul RESET, sincron cu CLK. Când load = ‘1’
se încarcă data . În cazul în care card_intrare = ‘1’, atunci se încarcă q+1, altfel, dacă
card_iesire = ‘1’, se încarcă q-1.
Când detectorul atinge valoarea de 250, adică q = “11111010”, pe afişor întâlnim
mesajul “ocupat”, adică z = ‘1’, altfel z = ‘0’.
Sursa VHDL a dispozitivului de monitorizare
library ieee;
80
use ieee.std_logic_1164.all;
use work.std_arith.all;
entity num_reversibil is port
(card_intrare, card_iesire, load, reset, clk : in std_logic;
-- semnale de intrare de tip logic;
data : in std_logic_vector (7 downto 0);
-- semnal de intrare de tip std_logic_vector;
q : buffer std_logic_vector (7 downto 0);
-- semnal de tip buffer (cu reacţie internă)
-- std_logic_vector;
z : out std_logic); -- semnal de ieşire de tip logic;
end num_reversibil;
architecture arch_of_num_reversibil of num_reversibil is
begin
NUM: process(CLK)
begin
if rising_edge(CLK) then -- testează frontul crescător al CLK;
if reset=’1’ then q<=”00000000”;
-- iniţializează cu zero numărătorul
elsif load=’1’ then q<=data;
-- încarcă numărătorul cu data
elsif card_intrare=’1’ then q<=q+1;
-- numără progresiv
elsif card_iesire=’1’ then q<=q-1;
-- numără regresiv
end if;
end if;
end process NUM;
z<=’1’ when q=”11111010” else
‘0’;
end arch_of_num_reversibil;
Simularea dispozitivului de monitorizare
Scenariul 1
81
Scenariul 2
82
2.4. SURSA VHDL ŞI SIMULAREA PROIECTULUI
83
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all;
entity proiect is port
(card_intrare, card_iesire, sus, jos, obstacol, x1, x2, load, reset, clk, ini : in std_logic;
data : in std_logic_vector(7 downto 0);
ridica, coboara, rosu, verde : out std_logic;
q : buffer std_logic_vector(7 downto 0);
z : out std_logic);
end proiect;
architecture arch_of_proiect of proiect is
type STARE is (S0, S1, S2, S3, S4, S5, S6, S7);
signal S: STARE;
begin
AUT: process(INI,CLK)
begin
if INI='1' then
S<=S0;
elsif rising_edge(CLK) then
S<=S0;
case S is
when S0=>
if card_intrare='1' and jos='1' then S<=S1;
elsif card_iesire='1' and jos='1' then S<=S4;
else S<=S0;
end if;
when S1=>
if sus='1' then S<=S2;
else S<=S1;
end if;
when S2=>
if x2='1' then S<=S3;
84
else S<=S2;
end if;
when S3=>
if jos='1' then S<=S0;
elsif obstacol='1' then S<=S6;
else S<=S3;
end if;
when S4=>
if sus='1' then S<=S5;
else S<=S4;
end if;
when S5=>
if x1='1' then S<=S3;
else S<=S5;
end if;
when S6=>
if sus='1' then S<=S7;
else S<=S6;
end if;
when S7=>
if x1='1' or x2='1' then S<=S3;
else S<=S7;
end if;
end case;
end if;
end process AUT;
ridica<='1' when (S=S1 or S=S6 or S=S4) else
'0';
coboara<='1' when (S=S3) else
'0';
rosu<='0' when (S=S0) else
'1';
verde<='1' when (S=S0) else
'0';
85
NUM: process(CLK)
begin
if rising_edge(CLK) then
if reset='1' then q<="00000000";
elsif load='1' then q<=data;
elsif card_intrare='1' then q<=q+1;
elsif card_iesire='1' then q<=q-1;
end if;
end if;
end process NUM;
z<='1' when q="11111010" else
'0';
end arch_of_proiect;
86
Scenariul 1
Scenariul 2
87
88
Scenariul 3
89
Scenariul 4
90
Scenariul 5
91
CONCLUZII
92
9.000.000
BIBLIOGRAFIE
8. http://bavaria.utcluj.ro/~baruch/ssc_proiect.html
9. http://vega.unitbv.ro/~nicula/general/reguli_vhd/reguli_vhd.html
10. http://en.wikipedia.org/wiki/VHDL
93