Sunteți pe pagina 1din 93

UNIVERSITATEA TEHNICA„Gh Asachi” IASI

FACULTATEA DE INGINERIE ELECTRICA


ENERGETICA SI INFORMATICA APLICATA
SPECIALIZAREA: INSTRUMENTATIE SI ACHIZITII
DE DATE

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

1.1. CIRCUITE LOGICE PROGRAMABILE

Circuitele logice programabile, cunoscute şi sub forma acronimului PLD


(Programmable Logic Device), sunt circuite integrate pe scară largă sau foarte largă,
conţinând un număr mare de structuri logice elementare, neconectate sau parţial conectate
între ele.
Acestea pot fi interconectate de către utilizator, în scopul realizării unei aplicaţii
specifice. Interconectarea se realizează prin intermediul unei reţele (matrice) de conductori, în
nodurile căreia sunt plasaţi conectori programabili.

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

Structura logică fundamentală ŞI – SAU este următoarea:

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)

1.1.1. Circuitele PLA (Programmable Logic 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.

1.1.2. Circuitele PAL (Programmable Array Logic)

O altă categorie de reţele logice programabile sunt circuitele PAL (Programmable


Array Logic), care conţin o reţea de porţi ŞI programabilă, dar reţeaua de porţi SAU are
conexiuni fixe (Figura 1.3.). Fiecare linie de ieşire este conectată la un set fix de linii ale
reţelei de porţi ŞI. O asemenea ieşire a circuitului PAL poate implementa o expresie pe două
nivele conţinând cel mult opt termeni. Avantajele circuitelor PAL sunt simplitatea utilizării
în anumite aplicaţii şi viteza mai ridicată. Aceste circuite sunt însă mai puţin flexibile decât
circuitele PLA.

Fig. 1.3.
Structura generală a unui circuit PAL

1.1.3. Circuitele CPLD (Complex Programmable Logic Device)

Circuitele logice programabile complexe CPLD (Complex Programmable


Logic Device) sunt circuite PLD având o densitate mai ridicată. Ele conţin un număr de
blocuri funcţionale, asemănătoare unor circuite PLD, fiecare bloc fiind compus din mai
multe macrocelule (Figura 1.4.). Există de asemenea o matrice de rutare pentru

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

Caracteristicile unor circuite CPLD (Cypress Semiconductor)

Nr. blocuri Nr. Nr. porţi Nr. pini f max Vcc


Tip circuit
logice macrocelule elementare I/O [MHz] [V]
CY39030V 32 512 30000 174 233 2,5/3,3
CY39050V 48 768 50000 218 233 2,5/3,3
CY39100V 96 1536 100000 136 222 2,5/3,3
CY39165V 166 2560 165000 386 181 2,5/3,3
CY39200V 192 3072 200000 428 181 2,5/3,3

1.1.4. Circuitele FPGA (Field Programmable Gate Array)

Un circuit FPGA constă dintr-o reţea bidimensională de celule sau blocuri


logice. De obicei, fiecare bloc logic poate fi programat pentru a implementa orice func ţie
logică a intrărilor sale. De aceea, aceste blocuri sunt numite de obicei blocuri logice
configurabile (Configurable Logic Block - CLB). Cele mai multe blocuri logice conţin
de asemenea unul sau două bistabile. Canalele şi blocurile de comutare dintre aceste blocuri
conţin resurse de interconectare, după cum se ilustrează în Figura 1.5. Aceste resurse conţin
de obicei segmente de interconectare de diferite lungimi. Interconexiunile conţin comutatoare
programabile cu rolul de a conecta blocurile logice la segmentele de interconectare, sau un
segment de interconectare la altul. În plus, există celule de I/E la periferia reţelei, care pot fi
programate ca intrări sau ieşiri.

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.

Proiectare independentă de circuitul-ţintă


mediu de dezvoltare mediu de dezvoltare mediu de dezvoltare compilare
A B C procesare

PAL CPLD 8 FPGA


-orice tip -orice tip -orice tip circuit-ţintă
-orice fabricant -orice fabricant -orice fabricant
Performanţă economică ridicată
- reducerea costurilor de proiectare-simulare-implementare;
- reducerea spectaculoasă a ciclului:

concepţie simulare implementare comercializare


Descrierea problemei în limbaj natural
(completarea caietului de sarcini).
Definirea intrărilor şi ieşirilor
implementare Definirea
(identificatori, tipuri de variabile). proiectului
Structura sistemului
Manual
(arhitectura - bloc).
Etapele proiectării în VHDL

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ă

Programarea circuitului Implementarea


9

Testarea fizică a circuitului Testarea finală


1.2.2. Fundamentele VHDL
Identificatori

VHDL admite ca identificatori secvenţe de caractere cu orice lungime.

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

Clase (obiecte) de date VHDL (data objects)

Clasă de date: orice obiect poate reţine o valoare.


O clasă de date are întotdeauna un tip asociat.

Clasa de date Tipul asociat

defineşte condiţiile în precizează ce fel de valori


care se reţin valorile pot fi reţinute

Clase de date VHDL (data objects)

CONSTANTE VARIABILE SEMNALE

CONSTANTE: valoare neschimbată pe tot parcursul programului.

constant identificator : tip := valoare ;

Exemplu: constant N : integer := 3 ;

VARIABILE:
- valoare neschimbată pe parcursul unei instrucţiuni;
facultativ
11
variable identificator : tip := valoare iniţială ;
- valoare variabilă pe parcursul programului.

Exemplu: variable REZULTAT : bit := ‘0’ ;

Observaţie: variabilele şi constantele se declară obligatoriu înainte de folosire (principiul:


„always – declare – before – using”).

SEMNALE: clasă de date specifică modelării structurilor hardware.


Modelează:
- porturile circuitelor (intrările şi ieşirile);
- conexiuni (conductori de legătură);
- elemente de memorare;

signal identificator : tip ;

Exemplu: signal A2 : std_logic;

Observaţie: semnalele pot fi declarate implicit, în momentul definirii portului de


intrare/ieşire al blocului numeric scris.

Tipuri de date

Tipuri predefinite:
- INTEGER
- CHARACTER
- STRING
- BOOLEAN
- BIT
- BIT_VECTOR specifice clasei
SIGNAL
- STD_LOGIC
- STD_LOGIC_VECTOR

INTEGER: numere întregi în intervalul   2 31  1    2 31  1


Intervalul poate fi restrâns între două limite predefinite.

12
Exemplu: variable A : integer range -255 to 255 ;

CHARACTER: unul din cele 128 caractere ASCII.

STRING: şir de caractere.


Exemplu: variable R : string(1 to 5) := ”RESET” ;
BOOLEAN: pot lua una din valorile TRUE sau FALSE.

BIT: pot lua două valori : ‘0’ sau ‘1’


Constantele de tip bit ‘0’ sau ‘1’ se scriu între apostrofuri.
Exemplu: signal x : bit ; --declara x ca semnal de tip bit
x<=’1’; --atribuie semnalului x valoarea ‘1’

BIT_VECTOR: şiruri de biţi de forma “10011011”


Constantele de tip bit_vector se scriu între ghilimele.
Exemplu: signal a : bit_vector(15 downto 0) ;
a<=”0011101001001101”

STD_LOGIC: acest tip modelează stările reale din sisteme numerice.


Semnalele de tip std_logic pot lua una din valorile:
‘0’
valori logice
‘1’
‘Z’ înaltă impedanţă (high Z)
valori meta-logice
‘-’ orice valoare (don’t care)

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.

STD_LOGIC_VECTOR: şiruri de valori de tip std_logic.

13
Constantele de tip std_logic_vector se scriu între ghilimele.
Exemplu: signal a : std_logic_vector(0 to 7) ;
a<=”0-1ZZ010” ;

Observaţie: cele mai frecvent utilizate tipuri sunt STD_LOGIC şi STD_LOGIC_VECTOR.


Pentru folosirea lor se cere apelată o bibliotecă specifică din mediul de dezvoltare a
aplicaţiilor VHDL.
Orice program VHDL va începe deci cu liniile:
library ieee;
use ieee.std_logic_1164.all;

Operatori uzuali

pentru variabile şi Ex: variabile a2 : bit ;


:=
constante a2 := ‘0’ ;
operatori de atribuire
Ex: signal X : std_logic ;
pentru semnale <=
X <= ‘1’ ;
NOT, AND, OR, NAND, Ex: signal a, b, c: std_logic ;
operatori logici
NOR, XOR, XNOR a <= b NAND c ;
operatorul de asociere => creează conexiuni între semnale
egalitate =
inegalitate /=
mai mare >
operatori relaţionali mai mic <
mai mare sau egal >=
a nu se confunda cu operatorul de
mai mic sau egal <=
atribuire
adunare + - aplicabili numai tipului
scădere -
INTEGER ;
înmulţire *
operatori aritmetici împărţire / - pot fi extinşi la tipurile BIT şi
ridicare la o putere STD_LOGIC prin apelarea
**
a lui 2 unor biblioteci specifice

14
1.2.3. Entităţi logice şi arhitecturi

Structura surselor VHDL


Entitate logică

Portul
I/O ARHITECTURA
(interfaţa)

Structura sursei VHDL

Declaraţia entităţii
entity

- defineşte portul de intrare/ieşire

Definiţia arhitecturii

architecture

- descrie relaţiile intrare - ieşire

Descrierea în VHDL a unei entităţi logice

15
Ex: comparator 2 x 1 bit

a
COMP - dacă a = b, EGAL = 1
EGAL
2x1 - dacă a  b, EGAL = 0
b

Structura sursei VHDL:


1 library ieee;
Apelarea bibliotecilor
2 use ieee.std_logic_1164.all

3 entity COMP is port


4 (a,b : in std_logic; Declaraţia entităţii (definirea
portului I/O)
5 EGAL : out std_logic);
6 end COMP;

7 architecture arch_COMP of COMP is


8 begin
9 COMP : process (a,b)
10 begin
Definiţia arhitecturii (relaţii
11 if a=b then EGAL<=’1’; intrare-ieşire)
12 else EGAL<=’0’;
13 end if;
14 end process COMP;
15 end arch_COMP;

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:

a entity poarta_SI is port


y (a : in std_logic ;
b
b: in std_logic ;
y: out std_logic);
end poarta_SI;
Modurile (sensurile) semnalelor
out - întotdeauna iese
in - întotdeauna intră
buffer - iese şi realizează reacţie internă (feed-back)
inout - uneori intră, uneori iese

Exemplu:

Definirea arhitecturii

Sintaxa generală:
numele_arhitecturii numele_entităţii
17
architecture of is

declaraţii de tip, declaraţii de semnale,


variabile, constante

begin
instrucţiuni care descriu arhitectura

end numele_arhitecturii ;

Declararea semnalelor în cadrul unei descrieri de arhitectură:


signal nume_semnal : tip ;

std_logic
orice std_logic_vector
identificator bit
legal bit_vector

Exemplu:

signal u, v, w : std_logic;

Tipuri de instrucţiuni în descrierea arhitecturilor

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’;

- Realizarea de conexiuni între semnale:

A<= B;
B <= C;

- Definirea de operatori logici:


u <= a XOR b ;
v <= a AND (NOT b);

- Condiţionarea unui semnal de alte semnale:


x <= ’1’ when (a=b)
else ‘0’;

- Condiţionarea conexiunilor dintre semnale de alte semnale:


z <= a when (x=’0’)
else b;

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 ;

RESET se defineşte ca o comandă independentă de CLK şi prioritară faţă de intrarea


D.
Secvenţa operaţiilor descrise este:

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;

Secvenţa operaţiilor descrise este:


1. se fixează ieşirea y la valoarea 0,
2. se testează condiţia a=b,
3. se decide asupra valorii y.

Modalităţi de descriere a arhitecturilor

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).

Sintaxa generală a unui PROCES: lista senzitivităţilor

nume_proces : process ( semnal 1 , semnal 2 , ... )


begin
instrucţiuni care definesc
algoritmul comportamental
al entităţii logice 20
end process nume_proces ;

Descrieri de tip flux de date


Descrierile de tip flux de date indică modul în care datele sunt transferate de la intrări
spre ieşiri (fluxul de date), fără a acorda importanţă ordinii în timp a acestor transferuri.
Folosesc numai instrucţiuni concurente (atribuire, funcţii logice, when-else, etc.)

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;

- Descrierea arhitecturii aceluiaşi comparator 2 x 2 biţi, folosind when-else:


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_2 of COMP is
begin
Y <= ‘1’ when (A=B) else ‘0’;
end arch_COMP_2;

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;

1.2.4. Descrierea structurilor combinaţionale

Se folosesc:
- descrieri: - comportamentale
- flux de date

22
- structurale
- instrucţiuni: - concurente
- secvenţiale

Descrierea structurilor combinaţionale


folosind instrucţiuni concurente

Există 3 instrucţiuni concurente:


- ecuaţii logice (booleene)
- instrucţiuni de selecţie with-select-when
- instrucţiuni condiţionale when-else
1. Descrierea prin ecuaţii logice (booleene)
Operatori logici predefiniţi: NOT, AND, OR, NAND, XOR, XNOR
Pot opera cu variabile de tip:
- bit
- bit_vector
- std_logic
- std_logic_vector

NU există priorităţi predefinite pentru operatorii logici!

Operaţiile se execută în ordinea scrierii operatorilor.

Exemplu: a OR b AND c se va evalua ca: (a+b)c


Priorităţile se definesc prin paranteze.

Exemplu: a  bc Reprezentare simplificată


se codează: NOT(a) OR (b AND NOT(c))

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;

2. Instrucţiunea de selecţie with-select-when


Atribuie valori unui semnal în funcţie de valorile unui selector.
Realizează o descriere de tip flux de date.
Sintaxa generală:
semnal_selecţie
with select
semnal_ieşire valoare_1 valoare_1_semnal_selecţie
<= when ,
valoare_2 valoare_2_semnal_selecţie

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;

Modul de operare al instrucţiunii with-select-when:

Ordinea de testare a valorilor


selectorului S nu are importanţă.

25
Cuvântul rezervat others desemnează toate valorile posibile ale selectorului, în afară
de cele specificate în instrucţiune.

Exemplu: MUX 5:1 de 1 bit, cu ieşirea 0 când nu e selectată nici o intrare

with s select Semnal selecţie s


y <= a when “000”, s2 s1 s0
0 0 0 y=a
b when “001”,
0 0 1 y=b
c when “010”, 0 1 0 y=c
d when “011”, 0 1 1 y=d
e when “100”, 1 0 0 y=e
alte valori y=0
‘0’ when others;

3. Instrucţiunea condiţională when-else


Atribuie valori unui semnal în funcţie de realizarea unei condiţii.
Realizează o descriere de tip flux de date.
Sintaxa generală:
nume_semnal <= valoare_1 when ( condiţie_1 ) else

valoare_2 when ( condiţie_1 ) else


...
valoare_n-1 when ( condiţie_n-1 ) else

valoare_n ;

Exemplu: MUX 4:1 de 4 biţi


library ieee;
use ieee.std_logic_1164.all

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!

Exemplu: multiplexor 3:1

architecture arch_MUX of MUX is


begin
y <= a when (s = ”00”) else
b when (s = ”01”) else
c;
end arch_MUX;

Sursa nu precizează valoarea cuvântului de selecţie pentru care y = c.


Multiplexorul conectează intrarea c la ieşire atât pentru combinaţia S1 S 0 =”10” cât şi
pentru combinaţia S1 S 0 =”11” a cuvântului de selecţie.

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;

Sursa precizează conexiunea y = c pentru combinaţia S1 S 0 =”10” şi starea de înaltă


impedanţă a ieşirii pentru S1 S 0 =”11”.
Pentru S1 S 0 =”11” ieşirea este în starea HZ (întreruptă).
Folosirea operatorilor relaţionali în instrucţiunea when-else
Descrierea condiţiilor în cadrul instrucţiunii se poate face sintetic folosind operatorii
relaţionali:
Relaţia între variabile operatorul relaţional
a egal cu b a=b
a diferit de b a /= b
a mai mic ca b a<b
a mai mic sau egal cu b a <= b
a mai mare ca b a>b
a mai mare sau egal cu b a >= b

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

Extinderea operatorilor (overloading)

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

library ieee; -- permite folosirea de semnale std_logic


use ieee.std_logic_1164.all
use work.std_arith.all; -- extinde operatorii relaţionali şi aritmetici la
-- variabile de tip std_logic şi std_logic_vector
entity DETECT9 is port
(a : in std_logic_vector(3 downto 0);
y : out std_logic);
end DETECT9;
architecture arch_DETECT9 of DETECT9 is
begin
y <= ‘1’ when (a = 9) else ‘0’;
end arch_DETECT9;

- Comparator relaţional de 2 x 4 biţi:


Relaţia a, b a EGAL b a INF b a SUP b
a=b 1 0 0
a<b 0 1 0
a>b 0 0 1

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;

Folosirea condiţiilor compuse în instrucţiunea when-else


Condiţie compusă: succesiune de condiţii simple concatenate prin operatori logici.
Exemplu: Comparator de egalitate 2 x 4 biţi, cu validarea ieşirii:

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;

Descrierea structurilor combinaţionale


folosind instrucţiuni secvenţiale

Instrucţiunile secvenţiale descriu un algoritm funcţional (PROCES) al entităţii logice.


Ordinea instrucţiunilor determină: - arhitectura schemei logice generate
- modul de operare al schemei în timp

1. Instrucţiunea secvenţială if-then-else


Instrucţiunea if-then-else simplă:
if condiţie then acţiune_1 ;

else acţiune_2 ;
end if ;

Instrucţiunea if-then-else compusă:


if condiţie_1 then acţiune_1 ;

elsif condiţie_2 then acţiune_2 ;

condiţie_3 acţiune_3
elsif then ;
acţiune_4
else ;
end if ;

Exemplu: MUX 8:1 de 4 biţi

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;

2. Instrucţiunea secvenţială case-when


Sintaxa generală:
case nume_selector is

when valoare_selector_1 => acţiune_1 ;

when valoare_selector_2 => acţiune_2 ;


.
.
when valoare_selector_n-1 => acţiune_n-1 ;

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.

Modul secvenţial de acţiune:


- condiţiile sunt testate în ordinea în care sunt scrise în sursă;
- schema logică sintetizată testează atât realizarea valorilor selectorului cât şi nerealizarea lor;
- instrucţiunea case-when descrie un algoritm comportamental al entităţii logice, deci se cere
încadrată într-un PROCES.

Exemplu: Codificator zecimal / binar de 2 biţi


intrare zecimală ieşire binară
Reprezentare simplificată Z0 Z1 Z2
B1 B0
Z3
1 0 0 0 0 0
0 1 0 0 0 1
0 0 1 0 1 0
library ieee; 0 0 0 1 1 1
use ieee.std_logic_1164.all
entity CODIF is port

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;

Observaţie: Instrucţiunile case-when şi if-then-else pot fi folosite în cadrul aceluiaşi proces.

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.

1.2.5. Descrierea structurilor secvenţiale


Descrierea structurilor secvenţiale sincrone

35
Structura generală a unui circuit secvenţial sincron

Semnalul de sincronizare CLK

clk = ‘0’ sau clk = ‘1’ - exprimă nivelul logic al semnalului clk
atributul ‘event - exprimă o schimbare de nivel logic a semnalului clk

Exprimarea fronturilor semnalului clk:


clk’event AND clk = ‘1’ - frontul pozitiv (crescător)
clk’event AND clk = ‘0’ - frontul negativ (descrescător)

Descrierea bistabilului D-sincron

Exemplu: bistabil D cu acţiune pe frontul pozitiv

36

Procesul este senzitiv numai la clk


library ieee;
use ieee.std_logic_1164.all
entity D_pozitiv is port
(d, clk : in std_logic;
q : out std_logic);
end D_pozitiv;
architecture arch_D_pozitiv of D_pozitiv is
begin
process (clk) -- proces senzitiv numai faţă de clk
begin
if (clk’event AND clk = ‘1’) then -- testează frontul pozitiv al clk
q <= d; -- transmite valoarea d la q
end if;
end process; -- închide procesul
end arch_D_pozitiv;

Arhitectura pentru un bistabil D cu acţiune pe frontul negativ:


architecture arch_D_negativ of D_negativ is
begin
process (clk) -- proces senzitiv numai faţă de clk
begin
if (clk’event AND clk = ‘0’) then -- testează frontul negativ al clk
q <= d; -- transmite valoarea d la q
end if;
end process; -- închide procesul
end arch_D_negativ;
Descrierea bistabilului D-latch

Exemplu: bistabil D-latch (cu zăvorâre):

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;

Observaţie: În exemplele precedente s-a tratat doar starea de transparenţă a bistabilului,


starea de memorare (zăvorâre) fiind realizată implicit. Procesul descris în exemplul anterior
este echivalent cu:
process (clk, d)
begin
if (clk = ‘1’) then -- testează valoarea clk = 1
q <= d; -- transmite valoarea d la q
else q <= q; -- memorează ultima valoare q
end if;
end process; -- închide procesul

38
Descrierea bistabilului T

Exemplu: bistabil T cu acţiune pe frontul pozitiv

Procesul este senzitiv numai la clk


library ieee;
use ieee.std_logic_1164.all
entity T is port
(t, clk : in std_logic;
q : out std_logic);
end T;
architecture arch_T of T is
begin
process (clk) -- proces senzitiv numai faţă de
clk
begin
if (clk’event AND clk = ‘1’) then -- testează frontul pozitiv al clk
if (t = ‘1’) then q <= NOT(q); -- schimbă starea dacă t = 1
else q <= q; -- păstrează starea dacă t = 0
end if;
end if;
end process; -- închide procesul
end arch_T;

Observaţie: Exemplul precedent are în vedere implementarea pe un circuit programabil care


are predefinită structura de bistabil T. Pentru circuitele care nu conţin bistabili T predefiniţi,
aceştia se cer sintetizaţi pe baza structurilor existente.
Instrucţiunea wait-until

39
Este o instrucţiune simplă, care se poate intercala direct într-un proces.
Sintaxa:
wait until ( condiţie );

Efect: blochează programul până la realizarea condiţiei.


Mod de acţiune:

Exemplu: bistabil D cu acţiune pe frontul pozitiv

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;

Observaţie: Cu wait-until nu e necesară precizarea listei de senzitivităţi în declaraţia de


proces (instrucţiunea defineşte implicit senzitivităţile). Lista de senzitivităţi se poate omite
numai când wait-until este prima instrucţiune din proces. În exemplul precedent instrucţiunea
wait-until (clk = ‘1’) este echivalentă cu: if (clk’event AND clk = ’1’) then ...

Funcţiile rising-edge şi falling-edge (front-crescător şi front descrescător)

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 )

Valoarea de ieşire: de tip boolean (true sau false).


Utilizare: condiţii în instrucţiuni de tip condiţional (when-else, if-then-else, wait-until)

Exemplu: bistabil D cu acţiune pe frontul negativ

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;

Observaţie: Moduri echivalente de sesizare (detectare) a fronturilor semnalelor:

if rising_edge (clk) then ... if falling_edge (clk) then ...


if (clk’event AND clk = ‘1’) then ... if (clk’event AND clk = ‘0’) then ...
wait until (clk = ‘1’); ... wait until (clk = ‘0’); ...

Intrări de iniţializare sincrone (RESET şi PRESET sincron)

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

Procesul este senzitiv numai


la clk

Priorităţi: 1. clk (front-)


2. reset
3. d
Reset: acţionează sincron cu clk şi prioritar faţă de d

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;

Intrări de iniţializare asincrone (RESET şi PRESET asincron)

Realizează iniţializarea cu ‘1’ (PRESET) sau cu ‘0’ (RESET) a bistabililor


independent de semnalul CLK (în orice moment).
Au acţiune prioritară faţă de CLK şi faţă de intrările de date.
Exemplu: bistabil D-latch cu RESET asincron

Procesul este senzitiv la clk,


d şi reset

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

Numără impulsurile clk şi afişează rezultatul


numărării în cod binar natural.
Capacitatea numărătorului: 2 n  1 ,
unde n = nr. biţi ieşire.

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ă

memorează aduc starea actuală generează


starea actuală la intrare starea următoare

Exemplu: numărător sincron de 3 biţi (0 ... 7) realizat cu bistabili D master-slave (numărător


sincron: toţi bistabilii sunt comandaţi simultan de clk).

Semnalul de ieşire se cere declarat cu


modul
buffer, pentru a realiza reacţia internă:

q : buffer std_logic_vector(2 downto 0)

44
Descrierea funcţionării prin diagramă de stări:

Descrierea în cod VHDL:


library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- admite adunarea semnalelor logice cu numere întregi
entity NUMARATOR is port
(clk : in std_logic;
q : buffer std_logic_vector(2 downto 0)); -- ieşirea în mod buffer
end NUMARATOR;
architecture arch_NUMARATOR of NUMARATOR 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
q <= q-1; -- incrementează cu 1
else q <= q; -- păstrează starea (instrucţiune redundantă)
end if;
end process NUMARARE;
end arch_NUMARATOR;

Observaţie: work.std_arith extinde domeniul de aplicare al operatorului „adunare” la operaţii


între semnale de tip std_logic_vector şi constante întregi. Rezultatul adunării are acelaşi
număr de biţi ca cel mai mare dintre operanzi (dacă suma are mai mulţi biţi, se suprimă bitul
cel mai semnificativ).

Exemplu: dacă q = ”101”, operaţia q <= q +1 are ca rezultat q = ”110”


dacă q = ”111”, operaţia q <= q +1 are ca rezultat q = ”000” (se suprimă MSB).

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ă.

Descrierea numărătoarelor cu intrări de iniţializare sincrone


Exemplu: numărător de 4 biţi cu RESET sincron

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;

Descrierea numărătorului cu intrare de validare a numărării (count-enable)


Exemplu: numărător de 8 biţi cu count_enable sincron

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;

Descrierea numărătoarelor cu intrare cu iniţializare sincronă


Exemplu: numărător de 16 biţi cu iniţializare şi validarea numărării – sincrone

Când ini = ‘1’, se încarcă numărătorul


cu o valoare fixă (ex: “1000000000000000”)

clk ini count_en q+

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;

Observaţie: others permite scrierea prescurtată a vectorilor logici cu lungimi mari.


Exemplu: dacă q <= ”000000000” se poate scrie q <= (others => ‘0’)
dacă q <= ”0100000000” se poate scrie q <= (‘0’, ‘1’, others => ‘0’)

Descrierea numărătoarelor cu intrare de încărcare sincronă (load)


Exemplu: numărător de 8 biţt cu intrare de încărcare şi validarea numărării – sincrone

Când load = ‘1’ încarcă numărătorul cu valorile


de pe intrarea “data”, apoi continuă numărarea
de la această valoare.

clk load count_en q+

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;

Descrierea numărătoarelor cu intrări de iniţializare asincrone


Exemplu: numărător de 16 biţi cu RESET şi PRESET – asincrone

RESET şi PRESET acţionează independent faţă de clk.


RESET : aduce numărătorul în starea ”0000...0”
PRESET : aduce numărătorul în starea ”1111...1”
RESET acţionează prioritar faţă de PRESET.
Proces senzitiv la
clk, reset, preset
reset preset clk q+
Priorităţi: 1. reset 0 0 q+1
2. preset
1 x x ”000...00”
3. clk
0 1 x ”111...11”

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;

Descrierea ieşirilor cu 3 stări (three-state) (TS)

Exemplu: receptor cu ieşire TS


- semnalul de validare oe - semnalul de validare oe
Se declară de tipul
(output enable) std_logic sau
std_logic_vector
- semnalul de ieşire y_out

Semnalele de tip std_logic şi std_logic_vector


pot lua valorile:
oe y_out
‘1’ valori logice
0 ‘Z’ ieşirea întreruptă ‘0’
1 y ieşirea validată ‘Z’ – înaltă impedanţă (high Z) (HZ)
(valoare “metalogică”)

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).

Exemplu: numărător de 4 biţi cu validarea numărării, reset asincron şi ieşiri TS

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

arhitecturi. 0 ‘Z’ ieşirea întreruptă


- q se declară ca semnal intern (nu aparţine
1 q ieşirea validată
portului)
(q_out este senzitiv la q şi oe)
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all; -- extinde operatorul +
entity NUM_TS is port
(reset, clk, count_en, oe : in std_logic;
Q_out :out std_logic_vector (3 downto 0)); -- ieşirea în mod
out
end NUM_TS;

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.

Exemplu: numărător presetabil de 4 biţi, folosind ieşirea şi ca intrare de iniţializare:

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.

1.2.6. Descrierea automatelor finite


Automate de tip Moore

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;

Se declară semnalele interne „prezenţă-coca” şi „prezenţă-pepsi”:


signal prezenta_coca, prezenta_pepsi: std_logic;

Descrierea cu „două procese”

Se defineşte un proces care va descrie evoluţia stării următoare în funcţie de starea


actuală, de intrări şi de semnale interne.
În această etapă descrierea automatului se face fără a lua în considerare caracterul
sincron al funcţionării (dependenţa de clk):

proc_AUTOMAT : process (stare_actuala, fisa, coca, pepsi,


prezenta_coca, prezenta_pepsi);
begin
case stare_actuala is
-- ...................................................................................................................................................
-- se descriu stările prin case-when şi tranziţiile prin if-then-else
-- exemplificare pentru cazul stării „decizie”
-- ...................................................................................................................................................
when decizie => iesire_coca <= ‘0’;

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;

Se defineşte un proces separat pentru descrierea funcţionării sincrone a automatului. În


acest caz ieşirea este senzitivă numai faţă de clk.
SINCRON : process (clk)
begin
if (clk’event and clk = ‘1’) then -- orice tranziţie este sincronă cu
stare_actuala <= stare_urmatoare; -- frontul crescător al clk
end if;
end process SINCRON;

Observaţii:
- primul proces descrie CUM au loc tranziţiile;
- al doilea proces arată CÂND au loc tranziţiile.

Acest tip de descriere se numeşte „descriere cu 2 procese”:


- primul proces descrie diagrama stărilor;
- al doilea proces impune sincronizarea tranziţiilor cu semnalul clk.

Sursa VHDL a automatului:


library ieee;
use ieee.std_logic_1164.all;
entity AUTOMAT is port
(fisa, coca, pepsi, clk : in std_logic;
iesire_coca, iesire_pepsi, iesire_fisa : out std_logic);
end AUTOMAT;
architecture arch_AUTOMAT of AUTOMAT is

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;

Exemplu: controler memorie

Controlerul generează semnalele re (read-enable) şi we (write-enable) pentru controlul


citirii sau scrierii în RAM, în funcţie de semnalele ready şi r_w furnizate de procesor.
Funcţionarea este sincronizată cu frontul crescător al clk.

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.

Funcţionarea controlerului este exemplificată în cronograma următoare:

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;

Descrierea de tip „proces unic”

Condiţia de sincronizare pe frontul clk poate fi înglobată în prinul proces:


- se declară clk în lista de senzitivităţi a procesului (lista nu va mai conţine alte semnale sau
variabile, cu excepţia eventualelor intrări asincrone);
- se pune condiţia de sincronizare pe clk înainte de descrierea diagramei stărilor (înainte de
instrucţiunea case-when).

proc_CONTROLER : process (clk) -- procesul este senzitiv numai faţă de clk


begin
if rising_edge (clk) then -- impune sincronizarea tranziţiilor cu frontul + al clk
case stare_actuala is -- descrie diagrama stărilor
when asteptare => re <= ‘0’; we <= ‘0’;
if ready = ‘1’ then -- ………....
-- …………………………………………………
end case;
end if;
end process proc_CONTROLER;

63
CAPITOLUL 2
PROIECTAREA UNUI AUTOMAT PENTRU
CONTROLUL ŞI MONITORIZAREA UNEI PARCĂRI

2.1. DESCRIEREA PROIECTULUI

AFIŞOR

card roşu
roşu ieşire verde
verde

x1 x2 P
250 locuri

m
card
sus
intrare
jos
obstacol

Am avut în vedere o parcare cu o capacitate de 250 locuri, prevăzută cu barieră şi câte


un semafor, atât la intrarea în parcare, cât şi la ieşire.
Pe străzile de acces sunt prevăzute afişoare care indică dacă sunt locuri libere în
parcare. În cazul în care sunt locuri libere iar semaforul indică culoarea verde (acest lucru
arată faptul că nu este nici o maşină lângă barieră), maşina poate înainta. Când automobilul

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

2.3.1. Descrierea şi simularea automatului


Portul automatului

sus ridică
jos coboară
obstacol
Automat barieră roşu
verde
card_intrare
card_ieşire

CLK INI

Descrierea automatului

Automatul are următoarele intrări de 1 bit:


- sus: senzor pentru poziţia „deschis” a barierei
- jos: senzor pentru poziţia „închis” a barierei
- x1, x2: senzori prezenţă vehicul
- card_intrare, card_iesire: senzori prezenţă card valid
- obstacol: senzor prezenţă obstacol sub barieră

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

INI ridică=’0’; coboară=’0’


roşu=’0’ ; verde=’1’
STOP JOS
card_ieşire=’1’ S0 card_intrare=’1’
jos=’1’ jos=’1’

ridică=’1’; coboară=’0’ RIDICĂ RIDICĂ ridică=’1’; coboară=’0’


roşu=’1’ ; verde=’0’ S4 S1 roşu=’1’ ; verde=’0’

sus=’1’ jos=’1’ sus=’1’

ridică=’0’; coboară=’0’ STOP SUS STOP SUS ridică=’0’; coboară=’0’


roşu=’1’ ; verde=’0’ S5 S2 roşu=’1’ ; verde=’0’

=’1’ =’1’

COBOARĂ ridică=’0’; coboară=’1’


S3 roşu=’1’ ; verde=’0’
obstacol=’1’

RIDICĂ ridică=’1’; coboară=’0’


S6 roşu=’1’ ; verde=’0’
=’1’
sau
sus=’1’
=’1’

STOP SUS ridică=’0’; coboară=’0’


S7 roşu=’1’ ; verde=’0’

Descrierea diagramei stărilor a automatului

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’;

Sursa VHDL a automatului

1. Folosind programul Galaxy din cadrul pachetului de programe WARP5.1 se descrie


în limbaj VHDL funcţionarea automatului. Se vor parcurge următoarele etape:

1.1. Start Programs => WARP5.1 => Galaxy


1.2. File => New => Project [Target – device]
-- sinteza automatului se va face cu un circuit CPLD precizat în etapa 2.5;
1.3. Project name: AUTOMAT -- se introduce numele aplicaţiei;
1.4. Project Path: c:\warp\student 

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

2. Se va simula funcţionarea automatului cu programul Active – HDL Sim din pachetul de


programe Warp5.1. Se vor parcurge următoarele etape:

2.1. Start Programs => Warp5.1 => Active – HDL Sim


2.2. File => New Waveform => Open VHDL=> c:\WARP\student\vhd\
\AUTOMAT.vhd  –­ se deschide fişierul care va fi simulat
2.3. Simulation => Initialize
2.4. Waveform => Add Signals => Name => INI, sus, jos, obstacol, x1, x2, card_intrare,
card_iesire, clk =>Add
2.5. Se configurează semnalele de intrare ca stimuli:
- sublu clic drepta pe semnalul clk => Stimulators type => clock => se completează rubrica
„Frequency” cu valoarea 1MHz;
- se selectează semnalul INI, efectuându-se dublu clic-stânga;
- se execută clic-dreapta după care se selectează opţiunea Stimulators;
- Stimulator type => formula => enter formula (…..) => Apply => Close
Se completează rubrica “enter formula” astfel: <value> <time>, <value> <time>,..etc.
“Value” poate fi 0 sau 1. “Time” reprezintă momentul de timp în care stimulul îşi schimbă
valoarea (unitatea de măsura este picosecunda).

Pentru scenariul în care autovehiculul intră în parcare:


Pentru semnalul INI se completeaza rubrica “enter formula” astfel:
1 0, 0 1000000 

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 

Se salvează apoi semnalele editate:


- File => Save as => AUTOMAT => Save => File => Close all waveforms (se salvează în
directorul SRC corespunzător)
2.6. Se simulează funcţionarea circuitului, vizualizând semnalul de ieşire:
- Waveform => Add Signals => Name => ridica, coboara, rosu, verde => Add
- Simulation => Run until => 15000 ns
2.7. Se va analiza semnalele ridica, coboara, rosu, verde, verificând funcţionarea corectă
a automatului.

La fel se procedează şi pentru scenariile: ieşire din parcare, prezenţă obstacol la


intrarea în parcare, prezenţă obstacol la ieşirea din parcare.

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

2.4.1. Sursa VHDL a 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;

2.4.2. Simularea proiectului

86
Scenariul 1

Scenariul 2

87
88
Scenariul 3

89
Scenariul 4

90
Scenariul 5

91
CONCLUZII

- Automatul a putut fi implementat pe un singur CIP CPLD, de


complexitate medie.

- Proiectul poate fi extins şi la realizarea unui sistem automat de


tarifare (bazat pe card cu microcip).

92
9.000.000

BIBLIOGRAFIE

1. WAKERLY, J.F. – Circuite digitale, Editura TEORA, Bucureşti 2002


2. AMAINI, A.I. – Electronic Logic Systems, McGraw-Hill, London, 1998
3. ŞTEFAN, Gh. – Circuite integrate digitale, Editura DENIX, Bucureşti, 1993
4. DIACONESCU, C-tin – Limbaje de descriere hardware, note de curs, Editura
ULBS, 2004
5. *** WARP HDL Development System – Language Reference Manual,
Cypress Semiconductor Ltd, San Jose – California 1998
6. *** XILINX – VHDL – Metamor User’s Guide, Metamor, 1997
7. http://bavaria.utcluj.ro/~baruch/ac/labor/AC06-2004.pdf

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

S-ar putea să vă placă și