Post on 22-Jun-2015
transcript
Microcontroler 8 biți Page 1
Microcontroler
pe 8 biți
Îndrumător:
Mihai Cristian Timar
Studenți:
Vlad Mărginean
Iuonaș Ovidiu
Secția:
Calculatoare și Tehnologia Informației
Grupa:
30214
Microcontroler 8 biți Page 2
CUPRINS
1) Specificaţie;
2) Schema bloc cu componentele principale;
3) Evidenţierea unităţii de comandă şi a celei de execuţie;
4) Etapele de proiectare;
5) Lista componentelor utilizate;
6) Semnificaţia notaţiilor efectuate şi a pinilor interfeţei cu exteriorul;
7) Justificarea soluţiei alese;
8) Instrucţiuni de utilizare şi întreţinere;
9) Posibilităţi de dezvoltare ulterioară.
Microcontroler 8 biți Page 3
1. SPECIFICAȚIE
Un controler este un sistem folosit pentru a comanda și a prelua stări de la un process sau
un aspect al mediului înconjurător. La început controler-ul era un echipament de dimensiuni
mari. După aparițtia microprocesoarelor, dimensiunile controlerelor s-au redus semnificativ.
Procesul de miniaturizare a continuat, toate componentele necesare unui controler au fost
integrate pe același chip. S-a născut astfel calculatorul pe un singur chip specializat pentru
implementarea operațiilor de control. Acesta este microcontroler-ul.
Microcontroler-ul este o structură electronică destinată controlului unui proces, sau mai
general unei acțiuni caracteristice cu mediul exterior, fără sa fie nevoie de intervenția
operatorului uman. Proiectul are la bază un microcontroller inspirat din Microcontrolerul
PicoBlaze 8-bit Microcontroller for Virtex-E and Spartan-II/IIE Devices.
Microcontroler 8 biți Page 4
2. SCHEMA BLOC CU COMPONENTELE
PRINCIPALE
Ideea de implementare a proiectului a pornit de la următoarea schema bloc:
Microcontroler 8 biți Page 5
3. EVIDENȚIEREA UNITĂȚII DE COMANDĂ ȘI
CELEI DE EXECUȚIE
Microcontroler-ul prezentat în acestă documentație este format din cele două mari părți
care sunt constituite de către unitatea de execuție și cea de comandă. Acest sistem realizează
operații cu numere pe 8 biți stocate în memorie și preluate cu ajutorul a 16 regiștrii, specificate
prin instrucțiuni pe 16 biți. Instrucțiunile scrise de utilizator sunt stocate în interiorul unei
memorii RAM.
Problema care apare este problema ordinii de execuție a instrucțiunilor, deoarece
componentele se execută in mod concurent. Astfel, in unitatea de comandă realizăm o execuție
secvențiala a programului astfel încât să urmărim operațiile efectuate. Din această cauză am creat
un numarator (Program Counter) cu care parcurgem pe rând de la 0 la 255 (FF) toate
instrucțiunile din Memoria RAM.
Componentele unității de comandă sunt: decodificatorul, memoria și program counterul.
Decodificatorul este o componentă esențială deoarece decodifică instrucțiunile pe 16 biți și
generează comanda pentru Unitatea Aritmetico-Logică. Regiștrii sunt cei care furnizează
operanzii in funcție de adresa primită de la decodificator, și care stochează in memorie rezultatul
obținut in urma operațiilor. Astfel prin conectarea acestor unități reușim să deținem controlul
asupra operațiilor efectuate și sa le putem folosi mai departe în alte scopuri. Este de asemenea
prezentă o stivă care stocheaza adresele de revenire în cazul instrucțiunii CALL.
Unitatea de execuție este o structură complexă, realizată din mai multe componente ale
microcontroler-ului cu ajutorul cărora se prelucrează și se afișează datele. Principala componentă
din unitatea de execuție o reprezintă Unitatea Aritemtico-Logică (UAL), în care se fac operațiile
propriu-zise primite de la 16 regiștrii pe 8 biți. De la Unitatea Aritmetico-Logică, rezultatul
merge spre afișor, unde este văzut de către utilizator.
Microcontroler 8 biți Page 6
4. ETAPELE DE PROIECTARE
1. În primul stadiu al proiectului am stablilit metoda de abordare a implementării
microcontorollerului. Am realizat de asemenea un desen schematic pe baza documentației
celor de la Xilinx, cuprinzând principalele componente și legăturile dintre ele.
2. Am desenat schema detaliată și am început scrierea codului actual pentru a putea testa fiecare
componentă pe rând. Astfel ne-am asigurat că nu o să existe erori interne de cod în momentul
în care vom lega împreună toate componentele.
3. Am realizat Afișorul cu 7 segmente și l-am testat independent pentru a ne asigura că datele
citite de utilizator nu vor fi eronate.
4. Am trecut apoi la realizarea unui bloc de 16 Regiștrii folositi la stocarea datelor (numerotati
de la 0 la F).
5. Am scris Unitatea Aritmetico – Logică pentru a verifica corectitudinea operațiilor. Testul a
fost realizat pe plăcuța FPGA Nexys3 fără program counter, executănd o singură operație,
transmițând apoi rezultatul pentru verificare către Afișorul cu 7 segmente.
6. În continuare, am construit partea centrală a microcontrolerului, Decodificatorul. Acesta
împarte instrucțiunile pe 16 biți în 4 părți a câte 4 biți și stabilește pentru fiecare combinație
comanda pentru ALU și adresele regiștrilor din care se extrag datele cu care se realizează
operațiile.
7. Era necesar să construim Memoria RAM si Program Counterul pentru a putea realiza
secvențial o succesiune de instrucțiuni scrise de catre utilizator.
8. Pentru implementarea funcțiilor de CALL și RETURN, am avut nevoie de o Stivă. Aceasta
cuprinde maxim 15 adrese, salvate automat la întâlnirea instrucțiunii CALL. Instrucțiunea
RETURN preia de pe stivă adresa salvată de ultimul CALL.
9. Instrucțiunea INTERRUPT a avut nevoie de altă componentă pentru controlul acestei
operații. Aceasta a fost scrisă ultima dată și acționează direct asupra Program Counterului,
modificând adresa la FE.
Microcontroler 8 biți Page 7
5. LISTA COMPONENTELOR UTILIZATE
Componentele utilizate în realizarea microcontrollerului sunt:
a) Memorie RAM
b) Decodificator
c) Program Counter
d) Unitate Aritmetico-Logică
e) Afișor
f) Stivă
g) Regiștrii
h) Debouncer
i) Multiplexoare
j) Bistabil D
k) Interrupt_control
Microcontroler 8 biți Page 8
a) Memoria RAM:
Memoria RAM este folosită pentru a stoca instrucțiunile pe 16 biți. De la Memoria RAM,
instrucțiunile sunt transmise spre decodificator, pentru a fi folosite mai departe. Această memorie
este legată la clock-ul plăcuței Nexys-3. Instrucțiunile din memorie pot fi rescrise, atunci când
WE (write enable) are valoarea 1, iar când va avea valoarea 0 se va face doar ieșirea instrucțiunii
spre decodificator prin portul dataout. La portul clk se leagă clockul de 100 MHz.
Numărătorul Program Counter transmite fiecare număr către Memoria RAM, acesta
reprezentând adresa din memorie către instrucțiunea care va fi transmisă spre decodificator.
În această memorie se pot scrie 256 de instrucțiuni de cate 16 biți sub forma de o matrice
cu 256 de linii și 16 coloane.
entity mem is
port ( adr : in std_logic_vector(7 downto 0);
we : in std_logic;
clk: in std_logic;
datain : in std_logic_vector(15 downto 0);
dataout : out std_logic_vector(15 downto 0));
end mem;
Microcontroler 8 biți Page 9
b) Decodificatorul:
Decodificatorul este una dintre cele mai importante componente ale microcontrolerului.
Această componentă permite decodificarea instrucțiunilor pe 16 biți primite de la Memoria RAM
prin intermediul semnalului instr. Din instrucțiunea decodificată fac parte operația transmisă
către Unitatea Aritmetico-Logică (CMD), adresele către regiștrii in care sunt memorați operanzii
(A, B), constanta (KK), dacă operația se face cu constante și adresele pentru instrucțiunile JUMP
sau CALL (jump_en, push_en, stack_en).
entity ent_decode is
port ( instr : in std_logic_vector(15 downto 0);
clk : in std_logic;
KK : out std_logic_vector (7 downto 0);
A, B : out std_logic_vector (3 downto 0);
k_en : out std_logic;
CMD : out std_logic_vector (4 downto 0);
j_adr: out std_logic_vector (7 downto 0);
jump_en: out std_logic;
push_en: out std_logic;
stack_en: out std_logic;
CF: in std_logic;
ZF: in std_logic;
reset_counter: out std_logic;
interrupt_en: out std_logic);
end entity;
Instrucțiunile primite de decodificator sunt formate din 16 biți de informație, iar structura
comenzilor este prezentată în următorul tabel:
Microcontroler 8 biți Page 10 N
rIn
stru
ctio
n15
1413
1211
109
87
65
43
21
0
JUM
P1
00
01
aa
aa
aa
aa
CALL
10
01
1a
aa
aa
aa
a
RETU
RN1
00
00
10
00
00
00
RETU
RNI E
NAB
LE1
00
00
00
01
11
10
00
0
RETU
RNI D
ISAB
LE1
00
00
00
01
10
10
00
0
ENAB
LE IN
TERR
UPT
10
00
00
00
00
11
00
00
DISA
BLE
INTE
RRU
PT1
00
00
00
00
00
10
00
0
0LO
AD sX
,kk
00
00
xx
xx
kk
kk
kk
kk
1AN
D sX
,kk
00
01
xx
xx
kk
kk
kk
kk
2O
R sX
,kk
00
10
xx
xx
kk
kk
kk
kk
3XO
R sX
,kk
00
11
xx
xx
kk
kk
kk
kk
4AD
D sX
,kk
01
00
xx
xx
kk
kk
kk
kk
5AD
DCY
sX,k
k0
10
1x
xx
xk
kk
kk
kk
k
6SU
B sX
,kk
01
10
xx
xx
kk
kk
kk
kk
7SU
BCY
sX,k
k0
11
1x
xx
xk
kk
kk
kk
k
LOAD
sX,s
Y1
10
0x
xx
xy
yy
y0
00
0
AND
sX,s
Y1
10
0x
xx
xy
yy
y0
00
1
OR
sX,s
Y1
10
0x
xx
xy
yy
y0
01
0
XOR
sX,s
Y1
10
0x
xx
xy
yy
y0
01
1
ADD
sX,s
Y1
10
0x
xx
xy
yy
y0
10
0
ADDC
Y sX
,sY
11
00
xx
xx
yy
yy
01
01
SUB
sX,s
Y1
10
0x
xx
xy
yy
y0
11
0
SUBC
Y sX
,sY
11
00
xx
xx
yy
yy
01
11
SHIF
T/RO
T RI
GHT
11
01
xx
xx
00
00
1
SHIF
T/RO
T LE
FT1
10
1x
xx
x0
00
00
INPU
T sX
,pp
10
10
xx
xx
pp
pp
pp
pp
INPU
T sX
(sY)
10
11
xx
xx
yy
yy
00
00
OU
TPU
T sX
,pp
11
10
xx
xx
pp
pp
pp
pp
OU
TPU
T sX
(sY)
11
11
xx
xx
yy
yy
00
00
Microcontroler 8 biți Page 11
c) Program Counterul:
Program Counter-ul este un numărător pe 8 biți care numără de la 0 la 255, care ajută la
efectuarea secvențială a instrucțiunilor din Memoria RAM. Acesta numără instrucțiunile și
transmite adresa instrucțiunii către Memoria RAM prin adresa_count, această instrucțiune fiind
transmisă ulterior către decodificator. Acest numărător se poate reseta, atunci cand reset_count
are valoarea 1 , și se poate face o încărcare în paralel cu load_counter, care ajută la efectuarea
instrucțiunilor JUMP sau CALL. În momentul în care se va activa interrupt (valoarea 1),
Program Counterul va forța pe ieșire adresa unde se face tratarea interruptului (FE).
entity count is
port( clk_buton: in std_logic;
reset_count: in std_logic;
adresa_count: out std_logic_vector(7 downto 0);
load_counter: in std_logic;
adr_load: in std_logic_vector (7 downto 0);
interrupt: in std_logic);
end count
Microcontroler 8 biți Page 12
d) Unitatea Aritmetico-Logică:
Unitatea Aritmetico-Logică este cea care efectuează operațiile. Această componentă
primește comanda pe 5 biți (SEL). Operanzii (A și B), pe 8 biți, vin de la regiștrii, iar în funcție
de decodificare, operația poate face fie între doi regiștrii sau între un registru și o constantă. Tot
aici în Unitate, se va face semnalarea daca rezultatul are valoarea 0 (ZEROFLAG), si se va
semnala dacă rezultatul de după operație va avea CARRY (CARRYFLAG). Semnalele
CARRY_JUMP și ZERO_JUMP sunt transmise decodificatorului pentru a fi folosite în cadrul
operațiunilor de Flow Control condiționate.
Operațiile pe care Unitatea Aritmetico-Logică le efectuează sunt:
LOGICE: Load, And, Or, Xor;
ARITMETICE: Adunare, Adunare cu Carry, Scădere, Scădere cu Carry;
SHIFTĂRI: Shiftare / rotire la stânga și la dreapta.
Microcontroler 8 biți Page 13
entity ual is
port( CIN: in std_logic;
SEL: in std_logic_vector(4 downto 0);
A: in std_logic_vector(7 downto 0);
B: in std_logic_vector(7 downto 0);
Q_UAL: out std_logic_vector(7 downto 0);
CARRYFLAG: out std_logic;
ZEROFLAG: out std_logic;
CARRY_JUMP: out std_logic;
ZERO_JUMP: out std_logic);
end ual;
Operațiile care pot fi realizate sunt:
OPERATIE SEL ZEROFLAG CARRYFLAG
LOAD 00000 * CIN
AND 00001 * 0
OR 00010 * 0
XOR 00011 * 0
ADD 00100 * **
ADDCY 00101 * **
SUB 00110 * ***
SUBCY 00111 * ***
SR0 01000 * A(0)
SR1 01001 * A(0)
SRX 01010 * A(0)
SRA 01011 * A(0)
RR 01100 * A(0)
SL0 01101 * A(7)
SL1 01110 * A(7)
SLX 01111 * A(7)
SLA 10000 * A(7)
RL 10001 * A(7)
Microcontroler 8 biți Page 14
(*) ZEROFLAG s-a determinat astfel
ZEROFLAG := not(INTQ(7) or INTQ(6) or INTQ(5) or INTQ(4) or INTQ(3) or INTQ(2) or
INTQ(1) or INTQ(0));
(**) CARRYFLAG s-a determinat astfel
CARRY(0) := A(0) and B(0);
for I in 1 to 7 loop
CARRY(I) := (A(I) and B(I)) or (A(I) and CARRY(I-1)) or (B(I) and CARRY(I-1));
end loop;
CARRYFLAG <= CARRY(7);
Sau pentru ADDCY
CARRY(0) := (A(0) and B(0)) or (A(0) and CIN) or (B(0) and CIN);
for I in 1 to 7 loop
CARRY(I) := (A(I) and B(i)) or (A(I) and CARRY(I-1)) or (B(I) and CARRY(I-1));
end loop;
CARRYFLAG <= CARRY(7);
(***) CARRYFLAG s-a determinat astfel
if TO_INTEGER(UNSIGNED(A)) < TO_INTEGER(UNSIGNED(B)) then
CARRYFLAG <= '1';
else
CARRYFLAG <= '0';
end if;
Sau pentru SUBCY
if TO_INTEGER(UNSIGNED(A)) < TO_INTEGER(UNSIGNED(B+CIN)) then
CARRYFLAG <= '1';
else
CARRYFLAG <= '0';
end if;
Microcontroler 8 biți Page 15
e) Afișorul:
Afișorul plăcuței Nexys-3 este format din 4 anozi si 7 catozi prin intermediul cărora
putem afișa pe unul din cele 4 ecrane, o informație pe 7 segmente. Nu putem afișa simultan mai
mult de un număr pe ecran, fiindcă cei 4 anozi impart aceiași catozi. Soluția pentru a vedea
informația dorită este să reușim să modificăm la o viteză potrivită cele 4 informații, astfel încât
ochiul uman să aibă impresia că informția este stabilă.
Pentru a face ca totul sa fie posibil, am folosit: un divizor de frecvență, un registru de
deplasare, un multiplexor 16:1 și un decodificator. Ne folosim de componenta reg pentru a
aprinde pe rând unul din cei 4 anozi, afișând câte o informație diferită pe cele 4 poziții. Ieșirile
registrului de deplasare vor fi folosite ca selecție pentru multiplexor.
Ieșirea multiplexorului intră intr-un decodificator 7 segmente primind o intrare pe 4 biți
pe care o transformă într-o ieșire pe 7 biți, corespunzătoare celor 7 segmente.
Pentru că noi dorim ca aceste etape să se desfășoare suficient de repede astfel încât
imaginea să fie stabile pentru ochiul uman, o sa folosim clock-ul de pe placuță, însă divizat la o
frecvență de 200Hz.
entity sist is
port ( clk: in std_logic;
reset: in std_logic;
an: out std_logic_vector (3 downto 0);
ca: out std_logic_vector (6 downto 0);
numar: in std_logic_vector(7 downto 0);
instructiune: in std_logic_vector(7 downto 0));
end sist;
Microcontroler 8 biți Page 16
f) Stiva:
Stiva folosită la acest microcontroler este de fapt o memorie de tip LIFO. Această stivă
este folosită pentru a memora adresa trebuie să revenim după instrucțiunea CALL. Această stivă
poate conține până la 15 elemente de câte 8 biți. Când stiva se va umple, se va rescrie peste cel
mai vechi element. Operațiile cu stiva se realizează doar în cât timp semnalul enable este 1.
În stivă se va scrie atunci când push_pop va avea valoarea 1, iar când va avea valoarea 0,
se va extrage din stivă elementul de sus. Stiva va fi legată la clock-ul de pe plăcuță.
Ieșirile Empty și Full semnalizează când stiva este goală sau plină.
entity stack is
port( clk: in std_logic;
enable: in std_logic;
d_in: in std_logic_vector (7 downto 0);
d_out: out std_logic_vector (7 downto 0);
push_pop: in std_logic);
end stack;
Microcontroler 8 biți Page 17
g) Regiștrii :
Cei 16 regiștrii reprezintă de fapt o singură componentă, valorile fiind stocate într-o
matrice 16x8. Funcționalitățile clasice sunt de la sine înțelese: resetarea se face folosind portul de
intrare reset, adresele pentru cei doi operanzi vin pe intrările adr1_r și adr2_r, iar datele din
regiștrii sunt scoase pe porturile out1_r și out2_r.
Implementarea aleasă pentru generarea semnaului interior notat de noi we, implică
utilizarea a doua clockuri pentru componenta regiștrii: clk este clockul plăcuței FPGA Nexys3 la
o frecvență de 100Mhz, care permite funcționarea „permanentă” a regiștrilor, întrucât
modificările sunt foarte rapide, iar clk_buton este clockul de la buton stabilizat de debouncing în
funcție de care se stabilește valoarea semnalului interior we, astfel:
if rising_edge(clk) then
if (clk_buton = '1') then
write_e <= '0';
elsif (clk_buton = '0' and nrclk > 0) then
write_e <= '1';
end if;
end if;
unde nr_clk este un semnal auxiliar de tip integer, care initial este 0 și care începe să se
incrementeze după prima citire din regiștrii, având scopul de a evita scrierea în prima instanță
(clk_buton fiind 0) a unor valori greșite de pe portul input_r în registrul selectat cu adr1_r.
entity registers is
port ( input_r: in std_logic_vector (7 downto 0);
adr1_r: in std_logic_vector (3 downto 0);
adr2_r: in std_logic_vector (3 downto 0);
clk_buton: in std_logic;
out1_r: out std_logic_vector (7 downto 0);
out2_r: out std_logic_vector (7 downto 0);
clk: in std_logic;
reset: in std_logic);
end registers;
Microcontroler 8 biți Page 18
h) Debouncerul:
Debouncer-ul este folosit pentru a stabiliza clock-ul de la buton folosit în unele
componente ale proiectului și care ar creea probleme la testare.
Două bistabile D salvează ultimele 2 valori ale clockului de la buton, iar printr-un XOR
se determină resetarea unui numărător pe 19 biți având rolul de a regla intervalul de apăsare a
butonului, până să scoată pe portul output semnalul stabilizat.
entity debouncer is
port( clk : in std_logic;
input : in std_logic;
output : out std_logic);
end debouncer;
i) Multiplexoarele:
Pentru microcontroler-ul nostru avem nevoie de 2 multiplexoare 2:1. Unul dintre
multiplexoare are ca intrări un număr pe 8 biți de la regiștrii și o constantă venită de la
decodificator. În funcție de valoarea lui k_en (venit de la decodificator) care este selecția, va
trimite către UAL constanta sau numărul din registru.
Celălalt multiplexor are ca intrări o adresă la care trebuie să facem JUMP venită de la
decodificator și ultima adresă scrisă pe stivă (pentru RETURN). Aici selecția va fi dată de
push_en care ne spune dacă adresa trimisă către Program Counter este de pe stivă sau de la
decodificator.
entity MUX is
port( sel: in std_logic;
i1_mux: in std_logic_vector(7 downto 0);
i2_mux: in std_logic_vector(7 downto 0);
out_mux: out std_logic_vector(7 downto 0));
end MUX;
Microcontroler 8 biți Page 19
j) Bistabilul D:
Am avut nevoie doar de un bistabil D, care va face ca rezultatul operației, venit de la
UAL, să fie transmis întârziat spre registrul pe care îl va rescrie. Acesta va fi legat la clock-ul de
pe buton ieșit din circuitul de debounce.
entity bistabil is
port( clk: in std_logic;
input: in std_logic_vector(7 downto 0);
output: out std_logic_vector(7 downto 0));
end bistabil;
k) Interrupt controlul:
Componenta de Interrupt Control actionează în momentul în care utilizatorul activează
semnalul int_buton doar daca semnalul int_enable este 1 (interruptul nu a fost dezactivat de altă
comandă).
Prin portul de ieșire go_interrupt care ajunge la Program Counter se semnalizează
aparitia semnalului de interrupt și forțează un JUMP la adresa FE, unde va fi tratat de o operație
prescrisă.
entity interrupt is
port( int_buton, int_enable: in std_logic;
go_interrupt: out std_logic);
end interrupt;
Microcontroler 8 biți Page 20
6. SEMNIFICAȚIA NOTAȚIILOR EFECTUATE ȘI A PINILOR
INTERFEȚEI CU EXTERIORUL
Privit în ansamblu, microcontroller-ul are următoarea interfață cu exteriorul:
Intrările folosite sunt legate corespunzător pe plăcuța FPGA Nexys3, facilitând astfel
interacțiunea utilizatorului cu ansamblul intern de componente.
Microcontroller-ul primeste 3 semnale de intrare: clk, care reprezintă clockul plăcuței
FPGA de 100 MHz, clk_buton, care permite efectuarea instrucțiunilor pas cu pas și int_buton,
fiind butonul ce controlează semnalul de interrupt prezent în interiorul microcontrollerului.
Ieșirile out_carry și out_zero sunt iesirile Unității aritmetico-logice și au rolul de a
semnaliza utilizatorului prezența carry-ului la operația anterioară, sau golirea registrului curent.
Celelalte două ieșiri sunt legate la afișorul plăcuței FPGA și realizează controlul celor 4
afișoare (anod), respectiv valoarea care este afișata pe acestea (catod).
Microcontroler 8 biți Page 21
Fișierul .ucf care asigură funcționarea proiectului pe placa FPGA Nexys3 are următoarea
structură:
net "anod(3)" loc = P17;
net "anod(2)" loc = P18;
net "anod(1)" loc = N15;
net "anod(0)" loc = N16;
net "catod(6)" loc = L14;
net "catod(5)" loc = N14;
net "catod(4)" loc = M14;
net "catod(3)" loc = U18;
net "catod(2)" loc = U17;
net "catod(1)" loc = T18;
net "catod(0)" loc = T17;
net "out_carry" loc = T11;
net "out_zero" loc = U16;
net "int_buton" loc = T5;
NET "clk" loc = V10;
NET "clk_buton" loc = C9;
NET "clk_buton" CLOCK_DEDICATED_ROUTE = FALSE;
Microcontroler 8 biți Page 22
7. JUSTIFICAREA SOLUȚIEI ALESE
Metoda implementată a fost aleasă în urma studiului documentației celor de la Xilinx
pentru Microcontrollerul PicoBlaze 8 bit. Structura prezentată de ei a stat la baza schemei
detaliate realizată în începutul proiectului.
Modul de funcționare este de asemenea asemănător, folosind majoritatea componentelor
din documentație. Decodificatorul, Program Counterul, Memoria RAM și Regiștrii asigura flow-
ul programului.
Comenzile primite din memoria RAM sunt decodificate într-un mod eficient și ușor de
înțeles, iar semnalele transmise la următoarele componente au fost denumite sugestiv astfel încât
traseul datelor să fie ușor de urmărit.
Pentru o verificare mai ușoară a rezultatelor, am implementat un afișor pe 7 segmente,
legat la afișoarele placuței FPGA. Acesta asigură un test rapid al programului scris în memoria
RAM de către utilizator, datele de ieșire fiind afișate în hexazecimal.
Microcontroler 8 biți Page 23
8. INSTRUCȚIUNI DE UTILIZARE SI ÎNTREȚINERE
Încărcarea programului în memorie se face manual de către utilizator. Este recomandat
să aibă în vedere codificarea exactă a instrucțiunilor, pentru a nu avea rezultate eronate
în momentul în care ruleaza programul.
Programul se va termina cu o instrucțiune de tipul „FFFF”, aceasta servind la resetarea
Program Counter-ului pentru a nu parcurge toată memoria.
Folosirea instrucțiunii CALL obligă utilizatorul să plaseze, după scrierea funcției dorite,
intrucțiunea RETURN pentru a reveni în programul principal unde se vor continua
instrucțiunile.
Funcțiile apelate cu CALL se vor scrie dupa instrucțiunea de final de program „FFFF”
pentru a nu afecta flow-ul programului principal și pentru a se executa o singură data la
un apel al utilizatorului.
Rezultatele operațiilor vor fi plasate pe afișorul plăcuței FPGA astfel:
- Pe primele 2 afișoare este pus numărul instrucțiunii efectuate
- Pe următoarele 2 afișoare este pus rezultatul operației
Semnalul de interrupt poate fi activat de pe switch-ul cel mai din dreapta, în orice
moment al simulării (acesta funcționează asincron).
Semnalizarea golirii unui registru (ZEROFLAG) se va face pe LED-ul din dreapta, iar
semnalul de CARRYFLAG se va face pe LED-ul din stânga.
Microcontroler 8 biți Page 24
Un exemplu de program scris în memoria RAM și testat prin simulare în Active-HDL
este prezentată în continuare:
Microcontroler 8 biți Page 25
Microcontroler 8 biți Page 26
9. POSIBILITĂȚI DE DEZVOLTARE ULTERIOARĂ
Decodificatorul reprezintă partea care ar putea fi îmbunătățită pentru a spori eficiența
proiectului.
De asemenea, Unitatea Aritmetico-Logică ar putea fi modificată pentru a realiza
operații mai complexe pe lângă cele deja prezente în decodificator.
Funcțiile de JUMP, CALL, RETURN condiționate ar trebui optimizate pentru
implementare, lăsând loc unei dezvoltări ulterioare.
Funcțiile de intrare în regiștrii și de ieșire pe alte porturi ale plăcuței nu au fost
implementate și ar fi o îmbunătățire considerabilă adusă proiectului.