Sunteți pe pagina 1din 20

Structura sistemelor de calcul – Automate de stare în limbajul VHDL 1

7. AUTOMATE DE STARE ÎN LIMBAJUL VHDL

În această lucrare se descriu diferite tehnici pentru proiectarea automatelor de stare cu ajutorul
limbajului VHDL. Se prezintă mai întâi un exemplu simplu, arătându-se faptul că realizarea unei descrieri
funcŃionale a unui automat de stare constă din simpla translatare a unei diagrame de stare în instrucŃiuni case şi
if. În continuare se prezintă diferite tehnici care pot fi utilizate pentru sinteza automatelor de stare.

7.1. Exemplu de proiectare


Se va proiecta la început un automat de stare reprezentând un controler simplu de memorie, mai întâi
prin metoda tradiŃională, iar apoi cu ajutorul limbajului VHDL.
Controlerul de memorie activează şi dezactivează semnalele output enable (oe) şi write enable (we) ale
unui buffer de memorie în timpul tranzacŃiilor de citire şi de scriere. Intrările controlerului de memorie sunt
semnalele ready şi read_write, care provin de la un microprocesor, iar ieşirile controlerului sunt semnalele oe şi
we. O nouă tranzacŃie începe cu validarea semnalului ready după terminarea unei tranzacŃii precedente (sau, la
punerea sub tensiune, pentru tranzacŃia iniŃială). La un ciclu de ceas după începerea unei tranzacŃii, starea
semnalului read_write determină tipul tranzacŃiei: de citire, dacă semnalul read_write este activat, sau de scriere,
în caz contrar. O tranzacŃie este terminată prin activarea semnalului ready, după care poate începe o nouă
tranzacŃie. Semnalul oe este activat în timpul unei tranzacŃii de citire, iar semnalul we este activat în timpul unei
tranzacŃii de scriere.

7.1.1. Proiectarea tradiŃională


Conform metodologiei de proiectare tradiŃionale, se construieşte mai întâi o diagramă de stare, pe baza
căreia se poate întocmi apoi o tabelă a stărilor. Se pot determina şi elimina stările echivalente prin compararea
liniilor din tabela stărilor şi utilizarea unei tabele a implicaŃiilor, dacă este necesar. În continuare se asignează
stările şi se construieşte o tabelă de tranziŃie a stărilor, pe baza căreia se pot determina ecuaŃiile stării următoare
şi ecuaŃiile ieşirilor, Ńinând cont de tipul bistabilelor utilizate pentru implementare.
Pornind de la descrierea controlerului, se poate desena diagrama de stare din Figura 7.1.

Figura 7.1. Diagrama de stare a controlerului de memorie.


2 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

Pentru acest automat de stare, nu există stări echivalente; toate stările necesită intrări diferite pentru
tranziŃia în starea următoare, sau ieşirile sunt diferite. Pentru implementare se va utiliza numărul minim de
bistabile necesare. Se alege implementarea cu bistabile de tip D. Se întocmeşte tabela de tranziŃie a stărilor,
combinată cu tabela de asignare a stărilor (Tabelul 7.1). Asignarea stărilor este indicată în coloana stărilor
prezente (SP). Coloana stărilor următoare (SU) indică tranziŃiile din starea prezentă în starea următoare pe baza
valorii curente a celor două intrări, read_write şi ready. CombinaŃiile valorilor acestor intrări sunt indicate prin
00, 01, 11 şi 10. Deoarece implementarea se realizează cu bistabile D, nu este necesar să se prevadă o coloană
pentru intrările bistabilelor, deoarece aceasta coincide cu coloana stării următoare. Ieşirile se indică în ultima
coloană.

Tabelul 7.1. Tabela de tranziŃie a stărilor pentru controlerul de memorie.


SP (q0q1) SU (Q0Q1) Ieşiri
Nume Cod 00 01 11 10 oe we
idle 00 00 01 01 00 0 0
decision 01 11 11 10 10 0 0
write 11 11 00 00 11 0 1
read 10 10 00 00 10 1 0

În continuare, se determină ecuaŃiile stării următoare pentru cei doi biŃi de stare. Pentru aceasta, pe baza
tabelei de tranziŃie a stărilor se întocmesc diagramele Karnaugh ale biŃilor de stare Q0, Q1 şi ale ieşirilor oe, we în
funcŃie de biŃii stării prezente (q0, q1) şi intrări (read_write, ready). Aceste diagrame se utilizează pentru
determinarea ecuaŃiilor minime ale stării următoare şi ale ieşirilor. Deoarece implementarea se realizează cu
bistabile D, ecuaŃiile stării următoare reprezintă şi ecuaŃiile de intrare ale bistabilelor.
Se obŃin următoarele ecuaŃii:

Q0 = q 0 q1 + q0 ⋅ ready (7.1)
Q1 = q 0 q1 ⋅ ready + q 0 q1 ⋅ read _ write + q0 q1 ⋅ ready (7.2)
oe = q0 q1 (7.3)
we = q0 q1 (7.4)

Pe baza acestor ecuaŃii, se poate realiza implementarea, de exemplu într-un circuit PLD care dispune de
bistabile de tip D. Pentru implementarea cu alte bistabile, este necesară determinarea unui nou set de ecuaŃii, pe
baza tabelei de tranziŃie şi a tabelei de excitaŃie a bistabilului ales.

7.1.2. Proiectarea utilizând limbajul VHDL


Diagrama de stare din Figura 7.1 se poate translata în mod simplu într-o descriere VHDL de nivel înalt
fără a fi necesară asignarea stărilor, întocmirea tabelei de tranziŃie a stărilor şi determinarea ecuaŃiilor stării
următoare pe baza tipului de bistabile disponibile. În limbajul VHDL, fiecare stare se poate translata într-o
alternativă a unei instrucŃiuni case. TranziŃiile între stări pot fi specificate apoi prin instrucŃiuni if.
Pentru translatarea diagramei de stare în limbajul VHDL, se defineşte mai întâi un tip enumerat,
constând din numele stărilor, iar apoi se declară două semnale de acest tip:
type tip_stare is (idle, decision, read, write);
signal stare_prez, stare_urm: tip_stare;
În continuare, se crează un proces. Starea următoare este determinată ca o funcŃie de starea prezentă
(stare_prez) şi de intrări (read_write şi ready). Deci, lista de sensibilitate a procesului va fi formată din
aceste semnale:
proc_comb: process (stare_prez, read_write, ready)
begin
...
end process proc_comb;

În cadrul procesului se vor descrie tranziŃiile automatului de stare. Se va utiliza o instrucŃiune case şi
se vor specifica pentru fiecare caz (fiecare stare) starea ieşirilor şi tranziŃiile posibile.
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 3

Procesul construit astfel indică tranziŃiile executate pe baza stării prezente şi a intrărilor prezente, dar nu
indică momentul în care starea următoare devine stare prezentă. Aceasta are loc în mod sincron, pe frontul
crescător al semnalului de ceas, ceea ce se va descrie într-un al doilea proces, prezentat mai jos.
proc_secv: process (clk)
begin
if (clk'event and clk = '1') then
stare_prez <= stare_urm;
end if;
end process proc_secv;
Descrierea completă a controlerului de memorie este prezentată în continuare.

Exemplul 7.1
entity contr_mem is
port (read_write: in bit;
ready, clk: in bit;
oe, we: out bit);
end contr_mem;

architecture automat_stare of contr_mem is


type tip_stare is (idle, decision, read, write);
signal stare_prez, stare_urm: tip_stare;
begin
proc_comb: process (stare_prez, read_write, ready)
begin
case stare_prez is
when idle => oe <= '0'; we <= '0';
if (ready = '1') then
stare_urm <= decision;
else -- else nu este necesar
stare_urm <= idle;
end if;
when decision => oe <= '0'; we <= '0';
if (read_write = '1') then
stare_urm <= read;
else -- read_write = '0'
stare_urm <= write;
end if;
when read => oe <= '1'; we <= '0';
if (ready = '1') then
stare_urm <= idle;
else -- ready = '0'
stare_urm <= read;
end if;
when write => oe <= '0'; we <= '1';
if (ready = '1') then
stare_urm <= idle;
else -- ready = '0'
stare_urm <= write;
end if;
end case;
end process proc_comb;

proc_secv: process (clk)


begin
if (clk'event and clk = '1') then
stare_prez <= stare_urm;
end if;
end process proc_secv;

end automat_stare;

Descrierea funcŃională a maşinii de stare se realizează într-un mod mai simplu decât descrierea prin
specificarea ecuaŃiilor. În acelaşi timp, printr-o asemenea descriere se reduce posibilitatea apariŃiei erorilor. Prin
sinteza descrierii funcŃionale rezultă o structură similară cu cea obŃinută prin implementarea ecuaŃiilor (7.1)-
(7.4).
4 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

7.2. Proiectarea unui controler de memorie


Următorul exemplu de proiectare este de asemenea un controler de memorie, având însă funcŃii
suplimentare faŃă de controlerul de memorie anterior. Figura 7.2 prezintă schema bloc a unui sistem care
utilizează controlerul de memorie.

Figura 7.2. Schema bloc a sistemului care utilizează al doilea controler de memorie.

Dispozitivele de pe magistrală iniŃiază un acces la bufferul de memorie prin setarea identificatorului de


magistrală bus_id la valoarea F3h. În următorul ciclu de ceas, se activează semnalul read_write pentru a indica o
citire din bufferul de memorie, sau se dezactivează acest semnal pentru a indica o scriere în bufferul de memorie.
Dacă operaŃia executată este una de citire, se poate citi fie un singur cuvânt, fie un grup de patru cuvinte în mod
exploziv (“burst”). O citire în mod exploziv este indicată prin activarea semnalului burst în timpul primului ciclu
de citire, după care controlerul accesează patru locaŃii de memorie. LocaŃiile consecutive sunt accesate după
activarea succesivă a semnalului ready. Controlerul activează semnalul de ieşire oe (output enable) în timpul
unei operaŃii de citire şi incrementează cei doi biŃi mai puŃin semnificativi ai adresei în timpul unei citiri în mod
exploziv.
La o operaŃie de scriere în buffer se scrie întotdeauna un singur cuvânt. În timpul unei operaŃii de scriere
se activează semnalul we (write enable), permiŃând scrierea datelor în memorie la adresa specificată de adr. Un
acces de citire sau de scriere este terminat prin activarea semnalului ready.
Figura 7.3 prezintă diagrama de stare a acestui controler de memorie. Un semnal de resetare sincronă
plasează automatul în starea idle. Atunci când bufferul de memorie nu este accesat, controlerul rămâne în
starea idle. Dacă bus_id este setat la valoarea F3h în timp ce controlerul este în starea idle, automatul trece în
starea decision. În următorul ciclu de ceas, controlerul trece fie în starea read1, fie în starea write, în funcŃie
de valoarea semnalului read_write. Dacă accesul este pentru citire, citirea unui singur cuvânt este indicată prin
activarea semnalului ready în starea read1, fără activarea semnalului burst. În acest caz, controlerul revine în
starea idle. O citire în mod exploziv este indicată prin activarea ambelor semnale ready şi burst în starea
read1. În acest caz, automatul trece prin fiecare din stările de citire (read2, read3, read4). În timpul fiecărei
stări de citire este activat semnalul oe şi este incrementată adresa adr.
Dacă accesul este pentru scriere, ceea ce se indică prin dezactivarea semnalului read_write, controlerul
activează semnalul we, aşteaptă semnalul ready de la magistrală, iar apoi revine în starea idle.
Diagrama de stare se poate translata într-o instrucŃiune case, similar cu automatul de stare din
exemplul anterior. Fiecărei stări în corespunde o ramură a instrucŃiunii case.
Acest automat de stare necesită un semnal de resetare sincronă. În locul specificării tranziŃiei de resetare
în starea idle în fiecare ramură a instrucŃiunii case, se poate adăuga o instrucŃiune if la începutul procesului
pentru a aduce automatul în starea idle în cazul în care semnalul reset este activ. În această instrucŃiune if
trebuie să se specifice care va fi starea ieşirilor atunci când semnalul reset este activ. Dacă nu se specifică starea
ieşirilor pentru această condiŃie, vor fi generate bistabile pentru memorarea valorilor precedente ale ieşirilor.
Pentru a se evita generarea bistabilelor, se va specifica faptul că ieşirile au valori indiferente atunci când
semnalul reset este activ. Aceasta va permite efectuarea unor optimizări pentru a se minimiza ecuaŃiile
semnalelor de ieşire. Atunci când semnalul reset este activ, automatul de stare va trece în starea idle, iar ieşirile
vor fi decodificate din starea prezentă şi asignate conform cu definiŃia lor în starea idle. În cazul în care s-ar
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 5

asigna valori semnalelor de ieşire în această instrucŃiune if iniŃială, ieşirile ar deveni funcŃii de starea prezentă şi
de semnalul reset, şi nu numai de starea prezentă.

Figura 7.3. Diagrama de stare a celui de-al doilea controler de memorie.

SecvenŃa necesară pentru resetarea sincronă este următoarea:


proc_comb: process (reset, stare_prez, burst, read_write, ready)
begin
if (reset = '1') then
oe <= '-'; we <= '-'; adr <= "--";
stare_urm <= idle;
else
case stare_prez is
...
end case;
end if;
end process proc_comb;

O altă posibilitate este specificarea condiŃiei de resetare după instrucŃiunea case, ca ultima instrucŃiune
a procesului proc_comb. Definirea valorilor pentru semnalele de ieşire nu este necesară în acest caz, deoarece
instrucŃiunea case, în care se definesc valorile ieşirilor, nu este parte a ramurii else dintr-o instrucŃiune if.
SecvenŃa necesară în acest caz pentru resetarea sincronă este următoarea:
proc_comb: process (reset, stare_prez, burst, read_write, ready)
begin
case stare_prez is
...
end case;
if (reset = '1') then
stare_urm <= idle;
end if;
6 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

end process proc_comb;

Descrierea completă a controlerului de memorie este prezentată în Exemplul 7.2.

Exemplul 7.2
library ieee;
use ieee.std_logic_1164.all;
entity contr_mem is
port (reset, read_write,
ready, burst, clk: in std_logic;
bus_id: in std_logic_vector (7 downto 0);
oe, we: out std_logic;
adr: out std_logic_vector (1 downto 0));
end contr_mem;

architecture automat_stare of contr_mem is


type tip_stare is (idle, decision, read1, read2,
read3, read4, write);
signal stare_prez, stare_urm: tip_stare;
begin
proc_comb: process (reset, bus_id, stare_prez, burst,
read_write, ready)
begin
if (reset = '1') then
oe <= '-'; we <= '-'; adr <= "--";
stare_urm <= idle;
else
case stare_prez is
when idle => oe <= '0'; we <= '0'; adr <= "00";
if (bus_id = "11110011") then
stare_urm <= decision;
else
stare_urm <= idle; -- else nu este necesar
end if;
when decision => oe <= '0'; we <= '0';
adr <= "00";
if (read_write = '1') then
stare_urm <= read1;
else -- read_write = '0'
stare_urm <= write;
end if;
when read1 => oe <= '1'; we <= '0'; adr <= "00";
if (ready = '0') then
stare_urm <= read1;
elsif (burst = '0') then
stare_urm <= idle;
else
stare_urm <= read2;
end if;
when read2 => oe <= '1'; we <= '0'; adr <= "01";
if (ready = '1') then
stare_urm <= read3;
else
stare_urm <= read2; -- else nu este necesar
end if;
when read3 => oe <= '1'; we <= '0'; adr <= "10";
if (ready = '1') then
stare_urm <= read4;
else
stare_urm <= read3; -- else nu este necesar
end if;
when read4 => oe <= '1'; we <= '0'; adr <= "11";
if (ready = '1') then
stare_urm <= idle;
else
stare_urm <= read4; -- else nu este necesar
end if;
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 7

when write => oe <= '0'; we <= '1'; adr <= "00";
if (ready = '1') then
stare_urm <= idle;
else
stare_urm <= write; -- else nu este necesar
end if;
end case;
end if;
end process proc_comb;

proc_secv: process (clk)


begin
if rising_edge (clk) then
stare_prez <= stare_urm;
end if;
end process proc_secv;

end automat_stare;

Automatul de stare este descris prin două procese. Unul din procese descrie partea combinaŃională, iar
al doilea proces descrie sincronizarea tranziŃiilor de stare cu semnalul de ceas. Structura acestei descrieri este
similară cu arhitectura unui bloc logic al unui circuit CPLD. Decodificarea stării prezente şi a intrărilor se
realizează în partea combinaŃională (reŃeaua de termeni produs) a blocului logic, fiind descrisă în procesul
combinaŃional al codului sursă. Sincronizarea stării următoare este descrisă în procesul proc_secv, care descrie
un banc de registre cum sunt macrocelulele dintr-un bloc logic.
Dacă este necesar un semnal de resetare asincronă, trebuie să se modifice procesul secvenŃial
proc_secv. Dacă semnalul de resetare se utilizează numai în timpul iniŃializării sau la apariŃia unei erori, un
semnal de resetare asincronă poate fi mai avantajos decât un semnal de resetare sincronă, deoarece acesta din
urmă poate necesita resurse suplimentare ale circuitului.
Codul prezentat în Exemplul 7.3 este echivalent funcŃional cu cel din Exemplul 7.2, dacă acesta este
modificat pentru a utiliza un semnal de resetare asincronă. În Exemplul 7.3 se utilizează un singur proces pentru
a descrie tranziŃiile stărilor şi sincronizarea acestor tranziŃii cu semnalul de ceas. Se utilizează instrucŃiuni
suplimentare de asignare concurentă pentru a descrie comportarea semnalelor de ieşire.

Exemplul 7.3
architecture automat_stare of contr_mem is
type tip_stare is (idle, decision, read1, read2,
read3, read4, write);
signal stare: tip_stare;
begin
tranz_st: process (reset, clk)
begin
if (reset = '1') then -- resetare asincronă
stare <= idle;
elsif rising_edge (clk) then -- sincronizarea cu ceasul
case stare is
when idle =>
if (bus_id = "11110011") then
stare <= decision;
else
stare <= idle; -- else nu este necesar
end if;
when decision =>
if (read_write = '1') then
stare <= read1;
else -- read_write = '0'
stare <= write;
end if;
when read1 =>
if (ready = '0') then
stare <= read1;
elsif (burst = '0') then
stare <= idle;
else
stare <= read2;
8 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

end if;
when read2 =>
if (ready = '1') then
stare <= read3;
else
stare <= read2; -- else nu este necesar
end if;
when read3 =>
if (ready = '1') then
stare <= read4;
else
stare <= read3; -- else nu este necesar
end if;
when read4 =>
if (ready = '1') then
stare <= idle;
else
stare <= read4; -- else nu este necesar
end if;
when write =>
if (ready = '1') then
stare <= idle;
else
stare <= write; -- else nu este necesar
end if;
end case;
end if;
end process tranz_st;

-- Ieşiri decodificate în mod combinaŃional

with stare select


oe <= '1' when read1 | read2 | read3 | read4,
'0' when others;
we <= '1' when stare = write
else '0';
with stare select
adr <= "01" when read2,
"10" when read3,
"11" when read4,
"00" when others;

end automat_stare;

În descrierea din Exemplul 7.3, se utilizează un singur semnal de stare. Asignarea acestui semnal se
realizează în mod sincron cu ceasul. Pentru automatele de stare, se recomandă stilul de codificare cu două
procese, ca în Exemplul 7.2, deoarece ieşirile şi tranziŃiile stărilor se pot identifica în mod simplu. Aceste
descrieri cu două procese sunt mai uşor de creat şi de înŃeles, în special pentru automatele de stare de dimensiuni
mari, automatele cu un număr mare de tranziŃii sau automatele cu un număr mare de ieşiri.

7.3. Tehnici pentru generarea semnalelor de ieşire


În această secŃiune, pe baza aceluiaşi controler de memorie, se prezintă următoarele tehnici pentru
generarea semnalelor de ieşire ale automatelor de tip Moore:
• Ieşiri decodificate combinaŃional din biŃii de stare;
• Ieşiri decodificate în registre paralele de ieşire;
• Ieşiri codificate în cadrul biŃilor de stare;
• Codificarea cu un bistabil pe stare.
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 9

7.3.1. Ieşiri decodificate din biŃii de stare


Ieşirile automatului de stare din Exemplele 7.2 şi 7.3 trebuie decodificate din starea prezentă a biŃilor de
stare (Figura 7.4). Această decodificare combinaŃională poate necesita nivele logice suplimentare, rezultând un
timp de propagare mai ridicat de la biŃii de stare la pinii de ieşire ai circuitului.

Figura 7.4. Automat de stare cu ieşiri decodificate din registrele de stare.

7.3.2. Ieşiri decodificate în registre paralele de ieşire


O metodă prin care se poate asigura transmiterea mai rapidă a ieşirilor automatului de stare la pinii
circuitului constă în decodificarea ieşirilor din biŃii de stare înainte ca aceşti biŃi să fie înscrişi în registrele de
stare. Aceasta se poate realiza utilizând fie o descriere cu un singur proces, fie o descriere cu două procese.
Considerând acelaşi exemplu al controlerului de memorie şi presupunând că semnalele adr trebuie să fie
disponibile într-un timp mai scurt la pinii circuitului, în ambele cazuri asignările la semnalele adr trebuie
efectuate în afara procesului în care sunt definite tranziŃiile stărilor. În locul utilizării stării prezente pentru
determinarea biŃilor de adresă adr, se va utiliza valoarea stării următoare stare_urm. De exemplu, dacă în
starea următoare a automatului adr(1) va fi '1', se memorează valoarea '1' într-un bistabil pe frontul crescător al
semnalului de ceas, iar dacă adr(1) va fi '0', se memorează valoarea '0' în acelaşi bistabil. Se poate utiliza
aceeaşi tehnică şi pentru alte semnale. Conceptul memorării valorilor ieşirilor pe baza valorii semnalului
stare_urm este ilustrat în Figura 7.5.

Figura 7.5. Automat Moore cu ieşirile decodificate în registre paralele de ieşire.

Pentru ca în descrierea controlerului de memorie să se includă ieşiri decodificate în registre paralele de


ieşire, se modifică descrierea din Exemplul 7.2 în modul arătat în Exemplul 7.4.

Exemplul 7.4
library ieee;
use ieee.std_logic_1164.all;
entity contr_mem is
port (reset, read_write,
ready, burst, clk: in std_logic;
bus_id: in std_logic_vector (7 downto 0);
oe, we: out std_logic;
adr: out std_logic_vector (1 downto 0));
10 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

end contr_mem;

architecture automat_stare of contr_mem is


type tip_stare is (idle, decision, read1, read2,
read3, read4, write);
signal stare_prez, stare_urm: tip_stare;
signal adr_d: std_logic_vector (1 downto 0);
-- intrări D ale bistabilelor pentru adr
begin
proc_comb: process (bus_id, stare_prez, burst,
read_write, ready)
begin
case stare_prez is -- ieşirile adr nu sunt
-- definite aici
when idle => oe <= '0'; we <= '0';
if (bus_id = "11110011") then
stare_urm <= decision;
else
stare_urm <= idle;
end if;
when decision => oe <= '0'; we <= '0';
if (read_write = '1') then
stare_urm <= read1;
else -- read_write = '0'
stare_urm <= write;
end if;
when read1 => oe <= '1'; we <= '0';
if (ready = '0') then
stare_urm <= read1;
elsif (burst = '0') then
stare_urm <= idle;
else
stare_urm <= read2;
end if;
when read2 => oe <= '1'; we <= '0';
if (ready = '1') then
stare_urm <= read3;
else
stare_urm <= read2;
end if;
when read3 => oe <= '1'; we <= '0';
if (ready = '1') then
stare_urm <= read4;
else
stare_urm <= read3;
end if;
when read4 => oe <= '1'; we <= '0';
if (ready = '1') then
stare_urm <= idle;
else
stare_urm <= read4;
end if;
when write => oe <= '0'; we <= '1';
if (ready = '1') then
stare_urm <= idle;
else
stare_urm <= write;
end if;
end case;
end process proc_comb;

with stare_urm select -- intrările D ale


adr_d <= "01" when read2, -- bistabilelor pentru adr
"10" when read3,
"11" when read4,
"00" when others;

proc_secv: process (clk, reset)


Structura sistemelor de calcul – Automate de stare în limbajul VHDL 11

begin
if reset = '1' then
stare_prez <= idle;
adr <= "00"; -- reset asincron al
-- bistabilelor pentru adr
elsif rising_edge (clk) then
stare_prez <= stare_urm;
adr <= adr_d; -- valoarea adr_d memorată
-- în adr
end if;
end process proc_secv;

end automat_stare;

În acest exemplu a fost declarat un semnal suplimentar, adr_d. Acest semnal este utilizat pentru a
decodifica în mod combinaŃional valoarea biŃilor de adresă adr în următorul ciclu de ceas. Aceasta se realizează
prin eliminarea instrucŃiunilor de asignare a acestor biŃi din instrucŃiunea case, unde ele se bazează pe starea
prezentă, şi prin inserarea unei instrucŃiuni concurente de asignare selectivă, în care semnalul de selecŃie este
starea următoare. Astfel, semnalul adr_d va fi decodificat din starea următoare, şi nu din starea prezentă. Apoi,
la frontul crescător al semnalului de ceas, semnalul adr_d se asignează biŃilor de adresă adr în procesul
proc_secv.
BiŃii de adresă adr au aceeaşi valoare în acelaşi ciclu de ceas ca şi în implementările precedente, dar
sunt disponibili într-un timp mai redus. Aceasta deoarece biŃii de adresă adr sunt păstraŃi în bistabile, iar ieşirile
acestor bistabile se pot propaga direct la pinii circuitului, în locul propagării acestora prin reŃeaua logică.

7.3.3. Ieşiri codificate în cadrul biŃilor de stare


O altă metodă prin care ieşirile unui automat de stare sunt disponibile într-un timp mai scurt este de a se
utiliza chiar biŃii de stare ca ieşiri. Un numărător este un exemplu de automat de stare pentru care ieşirile
reprezintă şi biŃii de stare. Această metodă necesită ca stările să fie codificate cu atenŃie, astfel încât ieşirile să
corespundă cu valorile păstrate în registrele de stare, după cum se arată în Figura 7.6. Prin utilizarea acestei
metode, proiectul va fi mai dificil de înŃeles şi modificat, astfel încât metoda este recomandată numai în cazurile
în care sunt necesare anumite optimizări specifice ale resurselor necesare şi ale performanŃelor, optimizări care
nu sunt asigurate de sistemul de sinteză în mod automat sau cu ajutorul directivelor de sinteză.

Figura 7.6. Automat Moore cu ieşirile codificate în cadrul registrelor de stare.

Pentru ilustrarea conceptului de codificare a ieşirilor în cadrul registrelor de stare, se va utiliza din nou
exemplul controlerului de memorie. Deoarece există şapte stări distincte ale automatului, numărul minim al
biŃilor de stare necesar este de trei, însă pot fi necesari biŃi suplimentari pentru codificarea ieşirilor. Presupunem
că este necesară propagarea într-un timp mai scurt a tuturor ieşirilor la pinii de ieşire ai circuitului, aceste ieşiri
fiind adr(1), adr(0), oe şi we. Dacă implementarea se realizează într-un circuit CPLD, numărul maxim de
macrocelule necesare este de şapte (pentru trei biŃi de stare şi patru ieşiri). Problema este de a realiza o codificare
a stărilor astfel încât ieşirile să reprezinte o parte a biŃilor de stare. Pentru această codificare, se întocmeşte mai
întâi un tabel cu stările prezente şi ieşirile care trebuie codificate (Tabelul 7.2).
Se examinează apoi tabelul, căutându-se combinaŃia ieşirilor care apare cu frecvenŃa cea mai mare. În
cazul în care toate combinaŃiile ieşirilor ar fi unice, codificarea ar fi terminată. În acest caz, combinaŃia 0000
apare de două ori (pentru stările idle şi decision). Pentru a realiza distincŃia dintre cele două stări idle şi
decision, se adaugă un bit suplimentar, st0. Acest bit se stabileşte în mod arbitrar ca fiind 0 pentru starea
idle şi 1 pentru starea decision. Pentru celelalte stări, valoarea bitului st0 se stabileşte în mod arbitrar ca
fiind 0. ImplicaŃiile alegerii valorii 0 sau 1 pentru celelalte stări vor fi discutate la sfârşitul acestui capitol.
Codificarea finală a stărilor este prezentată în Tabelul 7.3.
12 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

Tabelul 7.2. Ieşirile controlerului de memorie ca funcŃii de starea prezentă.


Stare adr(1) adr(0) oe we
idle 0 0 0 0
decision 0 0 0 0
read1 0 0 1 0
read2 0 1 1 0
read3 1 0 1 0
read4 1 1 1 0
write 0 0 0 1

Tabelul 7.3. Ieşirile controlerului de memorie codificate în cadrul biŃilor de stare.


Stare adr(1) adr(0) oe we st0
idle 0 0 0 0 0
decision 0 0 0 0 1
read1 0 0 1 0 0
read2 0 1 1 0 0
read3 1 0 1 0 0
read4 1 1 1 0 0
write 0 0 0 1 0

Fiind necesari cinci biŃi pentru codificarea stărilor, numărul de macrocelule necesare se reduce cu doi
faŃă de cazul în care ieşirile sunt decodificate în paralel sau serial din biŃii de stare. În general, reducerea
numărului de macrocelule depinde de unicitatea ieşirilor automatului pentru diferitele stări. În cazul cel mai
defavorabil, este necesar acelaşi număr de macrocelule ca şi în cazul în care ieşirile sunt decodificate în registre
paralele. În cazul automatelor de stare implementate cu circuite CPLD, această tehnică va necesita de obicei un
număr mai redus de macrocelule decât cel necesar la utilizarea tehnicilor prezentate anterior.
În cazul circuitelor FPGA, nu există un avantaj clar al utilizării acestei tehnici faŃă de cazul în care
ieşirile sunt decodificate în registre paralele de ieşire. O implementare mai eficientă cu circuitele FPGA se obŃine
prin utilizarea metodei de codificare cu un bistabil pe stare, prezentată în secŃiunea următoare. Se pot utiliza de
asemenea diferite directive de sinteză pentru a se obŃine implementări optime. Automatul de stare utilizat ca
exemplu are un număr redus de stări şi de intrări, iar tranziŃiile sunt relativ simple, astfel încât implementarea
într-un circuit FPGA nu diferă cu mult pentru diferitele metode utilizate.
Pentru descrierea automatului de stare prin această metodă, trebuie să se declare în mod explicit
codificarea stărilor cu ajutorul constantelor. În Exemplul 7.5, semnalul de stare este declarat de tip
std_logic_vector în locul tipului enumerat tip_stare, iar codificarea stărilor este specificată prin
constante. DefiniŃia entităŃii este aceeaşi nu mai este reprodusă.

Exemplul 7.5
architecture automat_stare of contr_mem is
-- Semnalul de stare este de tip std_logic_vector
-- în locul unui tip enumerat
signal stare: std_logic_vector (4 downto 0);
constant idle: std_logic_vector (4 downto 0) := "00000";
constant decision: std_logic_vector (4 downto 0) := "00001";
constant read1: std_logic_vector (4 downto 0) := "00100";
constant read2: std_logic_vector (4 downto 0) := "01100";
constant read3: std_logic_vector (4 downto 0) := "10100";
constant read4: std_logic_vector (4 downto 0) := "11100";
constant write: std_logic_vector (4 downto 0) := "00010";
begin
tranz_st: process (reset, clk)
begin
if (reset = '1') then
stare <= idle;
elsif rising_edge (clk) then
case stare is -- ieşirile nu sunt
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 13

when idle => -- definite aici


if (bus_id = "11110011") then
stare <= decision;
end if; -- fără else;
-- memorie implicită
when decision =>
if (read_write = '1') then
stare <= read1;
else -- read_write = '0'
stare <= write;
end if;
when read1 =>
if (ready = '0') then
stare <= read1;
elsif (burst = '0') then
stare <= idle;
else
stare <= read2;
end if;
when read2 =>
if (ready = '1') then
stare <= read3;
end if; -- fără else;
-- memorie implicită
when read3 =>
if (ready = '1') then
stare <= read4;
end if; -- fără else;
-- memorie implicită
when read4 =>
if (ready = '1') then
stare <= idle;
end if; -- fără else;
-- memorie implicită
when write =>
if (ready = '1') then
stare <= idle;
end if; -- fără else;
-- memorie implicită
when others =>
stare <= "-----"; -- stare indiferentă
end case;
end if;
end process tranz_st;

-- Ieşiri asociate cu conŃinutul registrelor

we <= stare(1);
oe <= stare(2);
adr <= stare (4 downto 3);

end automat_stare;

În acest exemplu, se utilizează un singur proces pentru a descrie şi a sincroniza tranziŃiile stărilor. Acest
proces, tranz_st, este similar celui din Exemplul 7.3, dar în acest caz instrucŃiunea case conŃine o ramură
suplimentară, when others. Această ramură este necesară pentru a acoperi toate valorile posibile ale semnalului
de stare (acest semnal, de tip std_logic_vector, are 95 valori posibile). Deoarece sunt definite numai şapte
stări, celelalte 25 de stări din cele 32 posibile cu 5 biŃi de stare sunt stări ilegale. (Amănunte suplimentare despre
stările ilegale şi toleranŃa la defecte vor fi discutate la sfârşitul acestui capitol.) Deoarece codificarea stărilor a
fost declarată în mod explicit şi a fost aleasă astfel încât să conŃină ieşirile stării prezente, ieşirile pot fi asignate
direct din semnalul de stare.
14 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

7.3.4. Codificarea cu un bistabil pe stare


Această metodă utilizează n bistabile pentru a reprezenta un automat cu n stări. Pentru fiecare stare
există câte un bistabil, un singur bistabil fiind setat la un moment dat. Decodificarea stării prezente constă în
simpla identificare a bistabilului care este setat. TranziŃia dintr-o stare în alta constă în modificarea stării
bistabilului corespunzător stării vechi din 1 în 0 şi a stării bistabilului corespunzător stării noi din 0 în 1.
Avantajul principal al automatelor care utilizează codificarea cu un bistabil pe stare este că numărul de
porŃi necesare pentru decodificarea informaŃiei de stare pentru ieşiri şi pentru tranziŃiile stărilor este cu mult mai
redus decât numărul de porŃi necesare în cazul utilizării altor metode. Această diferenŃă de complexitate creşte pe
măsură ce numărul de stări devine mai mare. Pentru ilustrarea acestui aspect, considerăm un automat cu 18 stări
codificate prin două metode, secvenŃial şi cu un bistabil pe stare. Pentru codificarea secvenŃială, sunt necesare
cinci bistabile, iar pentru codificarea cu un bistabil pe stare sunt necesare 18 bistabile. Presupunem că Figura 7.7
reprezintă o porŃiune a diagramei de stare indicând toate tranziŃiile posibile în starea 15.

Figura 7.7. PorŃiune a diagramei de stare a unui automat indicând toate tranziŃiile posibile în starea 15.

Fragmentul de cod reprezentând această porŃiune a diagramei de stare este următorul:


case stare_prez is
when stare2 =>
if cond1 = '1' then
stare_urm <= stare15;
else ...
when stare15 =>
if ...
elsif cond3 = '0' then
stare_urm <= stare15;
else ...
when stare17 =>
if ...
elsif cond2 = '1' then
stare_urm <= stare15;
else ...
end case;

Vom examina mai întâi logica stării următoare pentru codificarea secvenŃială. Vom nota vectorul de
stare pentru codificarea secvenŃială cu s, acest vector fiind de 5 biŃi, s4s3s2s1s0. Codificarea secvenŃială pentru
starea 15 este 01111. Utilizând diagrama de stare din Figura 7.7, se poate scrie pentru fiecare din cei 5 biŃi ai
vectorului s o ecuaŃie reprezentând condiŃiile care determină setarea bitului respectiv datorită unei tranziŃii în
starea 15:

si,15 = s 4 ⋅ s 3 ⋅ s 2 ⋅ s1 ⋅ s 0 ⋅ cond1
= s 4 ⋅ s 3 ⋅ s 2 ⋅ s1 ⋅ s0 ⋅ cond 2
= s 4 ⋅ s3 ⋅ s 2 ⋅ s1 ⋅ s 0 ⋅ cond 3

unde 0 ≤ i ≤ 4, si reprezintă unul din cei 5 biŃi ai vectorului s, iar si,15 reprezintă ecuaŃiile care determină ca bitul
si să fie setat datorită tranziŃiei în starea 15. Expresia corespunzătoare bitului s4 este 0, deoarece nici o tranziŃie în
starea 15 nu determină setarea bitului c.m.s. al vectorului de stare.
Deşi această ecuaŃie defineşte bitul si pentru tranziŃiile în starea 15, aceasta nu este suficientă pentru a
specifica biŃii s0, s1, s2 şi s3. De exemplu, ecuaŃia pentru s0,15 acoperă numai cazurile pentru care bitul s0 este setat
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 15

datorită tranziŃiilor în starea 15. Bitul s0 este setat şi datorită tranziŃiilor în celelalte stări cu număr impar.
EcuaŃiile logice asociate cu aceste tranziŃii pot fi similare ca şi complexitate cu ecuaŃiile pentru s0,15. Pentru
obŃinerea ecuaŃiei complete corespunzătoare bitului si, trebuie să se însumeze fiecare din ecuaŃiile si,x, unde x este
un întreg de la 0 la 17, reprezentând cele 18 stări. Rezultă că logica pentru bitul si poate fi complexă, chiar şi
pentru o diagramă de stare relativ simplă. În general, prin codificarea secvenŃială vor rezulta deci cinci ecuaŃii
complexe pentru si.
Vom nota vectorul de stare pentru codificarea cu un bistabil pe stare cu t, acest vector fiind de 18 biŃi.
Bitul 15 al acestui vector, corespunzător stării 15, are ecuaŃia următoare:

t15 = t 2 ⋅ cond1 + t17 ⋅ cond 2 + t15 ⋅ cond 3

Această ecuaŃie poate fi dedusă în mod simplu din diagrama de stare. Figura 7.8 prezintă implementarea
logicii pentru tranziŃiile în starea 15. În timp ce codificarea secvenŃială necesită 5 ecuaŃii complexe pentru logica
stării următoare, codificarea cu un bistabil pe stare necesită 18 ecuaŃii simple. În funcŃie de arhitectura
dispozitivului utilizat pentru implementare, un automat de stare care utilizează codificarea cu un bistabil pe stare
poate necesita o cantitate semnificativ mai redusă de resurse pentru implementare decât un automat care
utilizează alte metode de codificare. De asemenea, logica stării următoare necesită de obicei un număr mai redus
de nivele logice între registrele de stare, ceea ce permite o frecvenŃă mai ridicată de funcŃionare.

Figura 7.8. Logica stării următoare pentru tranziŃiile în starea 15 în cazul automatului care utilizează codificarea
cu un bistabil pe stare.

Codificarea cu un bistabil pe stare nu reprezintă însă soluŃia optimă în toate cazurile, în principal
datorită faptului că necesită un număr mai mare de bistabile decât codificarea secvenŃială. În general, codificarea
cu un bistabil pe stare este avantajoasă atunci când arhitectura dispozitivului programabil utilizat conŃine un
număr relativ mare de bistabile şi un număr relativ redus de porŃi logice între bistabile. De exemplu, această
codificare este cea mai avantajoasă pentru automatele de stare implementate cu circuite FPGA, care conŃin de
obicei un număr mai mare de bistabile decât circuitele CPLD. Codificarea cu un bistabil pe stare poate fi soluŃia
optimă chiar şi pentru circuitele CPLD atunci când logica stării următoare necesită treceri multiple prin reŃeaua
logică.
În general, utilizarea codificării cu un bistabil pe stare nu necesită modificarea codului sursă. Multe
sisteme de sinteză permit utilizarea unei directive de sinteză pentru specificarea acestei codificări. Aceste
directive pot fi sub forma unor opŃiuni ale interfeŃei grafice, parametri ai liniei de comandă sau atribute ale
limbajului. Aceste atribute sunt specifice sistemului de sinteză. De exemplu, unele sisteme de sinteză permit
utilizarea atributului state_encoding, care se aplică tipului enumerat utilizat pentru definirea stărilor. În
fragmentul următor, valoarea one_hot a acestui atribut specifică utilizarea codificării cu un bistabil pe stare:
type tip_stare is (idle, decision, read1, read2,
read3, read4, write);
attribute state_encoding of tip_stare: type is one_hot;
signal stare_prez, stare_urm: tip_stare;
Generarea semnalelor de ieşire în cazul automatelor codificate cu un bistabil pe stare este similară cu
generarea acestor semnale la automatele la care ieşirile sunt decodificate din registrele de stare. Decodificarea
este însă foarte simplă, deoarece stările sunt reprezentate prin câte un singur bit, şi nu printr-un vector întreg.
Logica de ieşire constă dintr-o poartă SAU, deoarece automatele Moore au ieşiri care sunt funcŃii de stările
16 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

automatului, iar fiecare stare este reprezentată printr-un singur bit. Decodificarea ieşirilor adaugă un nivel logic
suplimentar şi o întârziere corespunzătoare, ca şi în cazul în care biŃii de stare sunt codificaŃi. În cazul unui
circuit FPGA, întârzierea asociată cu o poartă SAU este acceptabilă, reprezentând o îmbunătăŃire faŃă de situaŃia
în care ieşirile sunt decodificate dintr-un vector întreg de stare. În cazul unui circuit CPLD, poarta SAU necesită o
nouă trecere prin reŃeaua logică. Ieşirile pot fi generate şi prin utilizarea registrelor paralele de ieşire, în modul
descris anterior. Aceasta va elimina nivelul logic suplimentar şi întârzierea asociată acestuia.
Dacă o anumită ieşire este activată într-o singură stare, aceasta va fi codificată în mod automat în cadrul
biŃilor de stare. De exemplu, considerând exemplul controlerului de memorie, semnalul we este activat numai în
timpul stării write:
we <= '1' when stare_prez = write else '0';

Există un bistabil asociat în mod direct cu starea write, astfel încât valoarea semnalului we va fi dată
de starea acestui bistabil. În consecinŃă, acest semnal va fi disponibil la pinii circuitului sau pentru logica internă
fără întârzierea suplimentară asociată cu decodificarea ieşirilor.

7.4. Automate de stare de tip Mealy


În secŃiunile anterioare s-au considerat doar automate de stare de tip Moore, la care ieşirile reprezintă
funcŃii doar de starea prezentă. Automatele de tip Mealy pot avea ieşiri care sunt funcŃii de starea prezentă şi de
intrările prezente, după cum se ilustrează în Figura 7.9.

Figura 7.9. Deosebirea dintre (a) automatele de stare de tip Moore şi (b) automatele de stare de tip Mealy.

OperaŃiile suplimentare necesare pentru descrierea automatelor de tip Mealy faŃă de cele necesare
pentru descrierea automatelor de tip Moore sunt minime. Pentru implementarea unui automat de tip Mealy,
trebuie să se descrie ieşirile ca funcŃii atât de biŃii de stare, cât şi de intrări. De exemplu, dacă există o intrare
suplimentară a controlerului de memorie, numită write_mask, care, atunci când este activată, nu permite
activarea semnalului we, logica pentru semnalul we poate fi descrisă astfel:
if (stare_prez = s6) and (write_mask = '0') then
we <= '1';
else
we <= '0';
end if;
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 17

Tehnicile de proiectare prezentate anterior pentru a asigura ca ieşirile să fie disponibile într-un timp mai
scurt nu pot fi utilizate în cazul unui automat de tip Mealy, deoarece acestea depind şi de intrările prezente, nu
numai de starea prezentă.

7.5. Alte consideraŃii de proiectare

7.5.1. Codificarea stărilor utilizând tipuri enumerate


Tipurile enumerate permit o codificare simplă pentru stările automatelor de stare. La sinteză, semnalele
de stare sunt convertite în vectori. Fiecărei valori a tipului stărilor i se asignează un cod. Pentru codificarea cu un
bistabil pe stare, fiecare valoare a semnalului de stare corespunde unui bistabil. Pentru alte codificări, cum este
cea secvenŃială, numărul minim de stări necesare este log 2 n , unde n este numărul stărilor. În cazul în care log2
n nu este o valoare întreagă, vor exista stări nedefinite.
În cazul controlerului de memorie prezentat ca exemplu, au fost definite 7 stări. Utilizând codificarea
secvenŃială, semnalul de stare va necesita trei bistabile. Din cele opt stări posibile, una va fi nedefinită.
Codificarea secvenŃială a stărilor controlerului de memorie în cazul în care se utilizează un tip enumerat pentru
semnalul de stare este prezentată în Tabelul 7.4, unde vectorul reprezentând codul stărilor este notat cu q.

Tabelul 7.4. Codificarea secvenŃială pentru un tip enumerat.


Stare q2 q1 q0
idle 0 0 0
decision 0 0 1
read1 0 1 0
read2 0 1 1
read3 1 0 0
read4 1 0 1
write 1 1 0
nedefinit 1 1 1

Pentru exemplul prezentat, sistemul de sinteză va presupune că valoarea 111 a vectorului q reprezintă o
condiŃie indiferentă. Nu sunt definite tranziŃii în sau din starea corespunzătoare acestui cod. În cazul în care
automatul de stare ar trece în această stare nedefinită, sau ilegală, nu ar funcŃiona într-un mod predictibil.
Comportamentul automatului de stare, în cazul în care acesta trece într-o stare ilegală, depinde de ecuaŃiile de
tranziŃie ale stărilor. Avantajul specificării tranziŃiilor dintr-o stare ilegală sub forma unor condiŃii indiferente
este că nu este nevoie de o logică suplimentară pentru a asigura că automatul va ieşi din această stare. O
asemenea logică suplimentară poate necesita pentru implementare resurse substanŃiale ale circuitului, în special
dacă există un număr mare de stări nedefinite. Dezavantajul utilizării acestor condiŃii indiferente este că
automatul de stare este mai puŃin tolerant la defecte. Proiectantul trebuie să decidă dacă aceasta este o soluŃie
acceptabilă pentru o anumită aplicaŃie.
În practică, anumite defecte, zgomote sau combinaŃii ilegale ale intrărilor pot determina modificarea
stării unuia sau a mai multor bistabile, ceea ce poate avea ca efect tranziŃia automatului într-o stare ilegală.
Automatul poate rămâne definitiv în această stare ilegală, poate activa o combinaŃie ilegală a ieşirilor, ceea ce
poate cauza alte efecte nedorite.
Automatele de stare pot fi proiectate astfel încât să fie tolerante la defecte prin adăugarea unei logici
care să asigure ieşirea din stările ilegale:
• Mai întâi, trebuie să se determine numărul posibil al stărilor ilegale. Acest număr este egal cu pătratul
diferenŃei dintre numărul bistabilelor utilizate pentru codificarea stărilor şi numărul stărilor automatului.
Pentru controlerul de memorie considerat ca exemplu, există o singură stare ilegală.
• În continuare, trebuie să se includă un nume de stare în cadrul tipului enumerat pentru fiecare stare
nedefinită. De exemplu:
type tip_stare is (idle, decision, read1, read2,
read3, read4, write, nedefinit);
18 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

• În sfârşit, trebuie să se specifice o tranziŃie a automatului de stare pentru ca acesta să iasă din starea
ilegală. Această tranziŃie poate fi specificată sub forma următoare:
case stare_prez is
...
when nedefinit => stare_urm <= idle;
end case;

7.5.2. Codificarea explicită a stărilor


În cazul automatelor de stare la care stările sunt codificate explicit, cum este automatul din Exemplul
7.5, pentru a se crea automate tolerante la defecte, trebuie să se specifice tranziŃii de ieşire ale automatelor din
stările nedefinite sau ilegale. De exemplu, tranziŃia din stările nedefinite în starea iniŃială poate fi specificată sub
forma:
when others => stare <= idle;
Prin specificarea tranziŃiei din stările ilegale într-o stare cunoscută, se va genera o logică suplimentară.
Există cazuri în care costul acestei soluŃii nu este justificat de necesitatea unui automat tolerant la defecte. În
aceste cazuri, se poate specifica în mod explicit faptul că tranziŃia dintr-o stare ilegală este o condiŃie indiferentă
(deci, nu are importanŃă starea în care se efectuează tranziŃia dintr-o stare ilegală, deoarece nu este de aşteptat ca
automatul să treacă într-o asemenea stare). În cazul codificării explicite, condiŃiile indiferente pot fi declarate sub
forma:
when others => stare <= "-----";
unde s-a presupus că semnalul stare este un vector de 5 biŃi.
În timp ce condiŃiile indiferente sunt implicite în cazul automatelor la care se utilizează tipuri enumerate
atunci când nu se specifică toate combinaŃiile posibile ale valorilor, condiŃiile indiferente trebuie definite în mod
explicit în cazul automatelor cu stările codificate în mod explicit. Utilizarea constantelor permite definirea
explicită atât a condiŃiilor indiferente, cât şi a tranziŃiilor din stările ilegale.

7.5.3. ToleranŃa la defecte a automatelor codificate cu un bistabil pe stare


Posibilitatea ca automatul să treacă într-o stare ilegală creşte atunci când se utilizează codificarea cu un
bistabil pe stare sau când ieşirile sunt codificate în cadrul biŃilor de stare. În ambele cazuri poate exista un număr
mare de stări ilegale sau nedefinite. De exemplu, în cazul codificării cu un bistabil pe stare, există 2n valori
posibile ale vectorului de stare de n biŃi, în timp ce automatul are doar n stări. Deşi codificarea cu un bistabil pe
stare se alege de obicei pentru a obŃine o implementare eficientă a automatului de stare, dacă se include logica
pentru tranziŃia din oricare stare ilegală în starea iniŃială sau într-o altă stare cunoscută, va rezulta o
implementare ineficientă. De exemplu, pentru specificarea completă a tranziŃiilor stărilor unui automat cu 18
stări la care se utilizează codificarea cu un bistabil pe stare, trebuie decodificate în plus 218 – 18 = 262.126
tranziŃii.
În locul adăugării unei logici pentru tranziŃia din toate stările ilegale într-o stare cunoscută se poate
include o logică pentru detectarea situaŃiilor în care este setat mai mult decât un bistabil la un moment dat. Se
poate genera un semnal de coliziune pentru a detecta setarea mai multor bistabile în acelaşi timp. Pentru cazul în
care există patru stări notate cu stare1, …, stare4, semnalul de coliziune are forma următoare:
coliziune <= (stare1 and (stare2 or stare3 or stare4)) or
(stare2 and (stare1 or stare3 or stare4)) or
(stare3 and (stare1 or stare2 or stare4)) or
(stare4 and (stare1 or stare2 or stare3));
Această tehnică se poate extinde pentru un număr oarecare de stări. Dacă nu este necesar ca semnalul de
coliziune să fie generat într-un singur ciclu de ceas, se poate utiliza tehnica pipeline pentru generarea acestui
semnal. Prin utilizarea acestei tehnici, frecvenŃa de operare poate fi menŃinută la valoarea maximă.
Proiectantul trebuie să decidă care este cantitatea de resurse care poate fi utilizată pentru creşterea
toleranŃei la defecte a automatului realizat, sau în ce măsură scăderea vitezei de funcŃionare datorită logicii
suplimentare este acceptabilă.
Structura sistemelor de calcul – Automate de stare în limbajul VHDL 19

7.6. AplicaŃii
7.6.1. Considerăm un automat de stare cu trei stări (s0, s1, s2) şi trei ieşiri (out_a, out_b, out_c).
Ieşirea out_a trebuie activată numai în starea s0, ieşirea out_b trebuie activată numai în starea s1, iar ieşirea
out_c trebuie activată numai în starea s2. O secvenŃă posibilă pentru generarea ieşirilor este următoarea:
if (stare_prez = s0) then
out_a <= '1';
elsif (stare_prez = s1) then
out_b <= '1';
else -- stare_prez = s2
out_c <= '1';
end if;
ExplicaŃi motivul pentru care această secvenŃă corectă din punct de vedere sintactic nu este corectă din
punct de vedere funcŃional.
7.6.2. CompilaŃi descrierea controlerului de memorie din Exemplul 7.1 şi urmăriŃi funcŃionarea acestuia
cu simulatorul.
7.6.3. CompletaŃi descrierea controlerului de memorie din Exemplul 7.1 cu secvenŃa necesară pentru
resetarea asincronă a circuitului. CompilaŃi descrierea pentru două variante, cu iniŃializarea semnalelor de ieşire
în secvenŃa de resetare, respectiv fără această iniŃializare. SimulaŃi funcŃionarea acestor variante.
7.6.4. CompilaŃi descrierea controlerului de memorie din Exemplul 7.2 şi urmăriŃi funcŃionarea acestuia
cu simulatorul.
7.6.5. ModificaŃi descrierea controlerului de memorie din Exemplul 7.2 pentru a utiliza un semnal de
resetare asincronă în locul semnalului de resetare sincronă.

Figura 7.10. Automat de stare pentru aplicaŃia 7.6.7: (a) diagrama de stare; (b) tabelul semnalelor de ieşire.

7.6.6. RealizaŃi proiectarea celui de-al doilea controler de memorie (Figura 7.2) utilizând editorul pentru
automate de stare al sistemului Active-HDL. ComparaŃi fişierul sursă obŃinut cu descrierea din Exemplul 7.2.
7.6.7. ProiectaŃi automatul de stare din Figura 7.10 utilizând un tip enumerat pentru definirea stărilor.
20 Structura sistemelor de calcul – Automate de stare în limbajul VHDL

7.6.8. ModificaŃi descrierea automatului de stare din aplicaŃia 7.6.7 astfel încât ieşirile să fie codificate
în cadrul biŃilor de stare.
7.6.9. ProiectaŃi un automat de stare pentru detectarea secvenŃei de biŃi "11101011". SecvenŃa se aplică
automatului începând cu bitul c.m.s. DesenaŃi diagrama de stare a automatului, după care descrieŃi automatul în
limbajul VHDL utilizând două procese şi un tip enumerat pentru definirea stărilor. CompilaŃi descrierea şi
simulaŃi funcŃionarea automatului.
7.6.10. ProiectaŃi automatul specificat pentru aplicaŃia 7.6.9 cu ajutorul editorului pentru automate de
stare în două variante: utilizând codificarea secvenŃială şi codificarea cu un bistabil pe stare. ComparaŃi fişierele
sursă obŃinute.
7.6.11. ProiectaŃi un numărător de 16 biŃi utilizând un automat de stare în locul operatorului "+".
ComparaŃi rezultatul obŃinut utilizând codificarea secvenŃială cu cel obŃinut utilizând codificarea cu un bistabil
pe stare.
7.6.12. ProiectaŃi blocul de comandă al unui circuit de înmulŃire binară care implementează metoda
Booth. DesenaŃi diagrama de stare a blocului de control şi descrieŃi blocul de comandă în VHDL.
7.6.13. ProiectaŃi blocul de comandă al unui circuit de împărŃire binară care implementează metoda
refacerii restului parŃial. UtilizaŃi editorul pentru automate de stare al sistemului Active-HDL pentru a genera
descrierea în VHDL a blocului de comandă.