Sunteți pe pagina 1din 6

Lucrarea 2 MC 11 decembrie 2019

SOLUTII POSIBILE
1. Sa se realizeze un program care implementeaza un sistem de alarmare astfel:

- Exista 3 senzori care transmit 1 logic la declansare si 0 logic in rest


- Senzorii pot fi activati/dezactivati in mod ciclic la apasarea si eliberarea a cite unui buton de tip
PUSH BUTTON (o apasare-eliberare realizeaza activarea, iar urmatoarea apasare-eliberare realizeza
dezactivarea)
- Starea senzorului (activ sau inactiv) va fi afisata pe cite un LED (activ - LED aprins)
- Exista un buton de activare a sistemului (de tip ON/OFF). Starea de sistem activ sau inactiv va fi
semnalizata pe un LED (activ - LED aprins)
- Dupa activarea sistemului se asteapta 10 secunde inainte ca sistemul sa poata detecta declansarea
unui senzor
- Declansarea senzorilor va fi afisata pe cite un LED (declansat - LED aprins)
- La declansarea oricarui senzor se va genera un semnal periodic cu frecventa 1 secunda pe un LED.
(4 puncte)
Solutie posibila:

Codul in C este:
Declarare variabile
#define T 500 // perioada de 10 secunde
#define T1 50 // perioada de 1 secunda
char activ[3]; // tabela pentru activarea senzorilor
char alarm[3]; // tabela pentru memorarea declansarii senzorilor
char ALARMA; // variabila pentru alarma declansata
char senzor[3]; // valoare senzorului
int CNT; // contor pentru perioada de asteptare
int CNT1; // contor pentru alarma
char Q; // variabila de stare a procesului secvential
char in; // intrarea
/* in :
SW2,SW1,SW0 PUSH BUTTON apasat "0", neapasat "1"
SW7 (ON/OFF) ON=1, OFF=0
SW6 = PUSH BUTTON RESET,activ in zero
SW5 = senzor 2, SW4 senzor 1, SW3 senzor 0 (senzor declansat 1, nedeclansat 0)
SW2 = buton activare senzor 2
SW1 = buton activare senzor 1
SW0 = buton activare senzor 0
*/
char out; // iesirea
/* out :
LED aprins "1", stins "0"
LED7 = ON/OFF
LED6 = alarma
LED5 = declansare senzor 2, LED4 declansare senzor 1 , LED3 declansare senzor 0
LED2 = activare senzor 2, LED1 activare senzor 1 , LED0 activare senzor 0
*/
int i; // contor ciclu for
Initializari
Q=0;
CNT=0;
CNT1=0;
for (i=0;i<3; i++)
{
activ[i]=0;
senzor[i]=0;
alarm[i]=0;
}
ALARMA=0;
out=0;
PORTB=out;
while (1)
{
}
Rutina de servire a intreruperii
in=PIND; // citeste intrarea
switch(Q)
{
case 0:
tmpi=in&0x80; // test ON/OFF
if (tmpi==0)
{
out=out&0x7F; // se face 0 bitul 7 al iesirii
Q=1;
}
else
{
tmpo=out&0x7F; // se face 0 bitul 7 al iesirii
out = tmpo | 0x80; // se face 1 bitul 7 al iesirii
Q=9;
}
break;
case 1:
tmpi=in&0x01; // test SW0
if (tmpi==0) Q=2; // SW0=0
tmpi=in&0x02; // test SW1
if (tmpi==0) Q=4; // SW1=0
tmpi=in&0x04; // test SW2
if (tmpi==0) Q=6; // SW2=0
tmpi=in&0x40; // test SW6
if (tmpi==0) Q=0; // SW6=0
break;
case 2:
tmpi=in&0x01; // test SW0
if (tmpi!=0) Q=3; // SW0=1
break;
case 3:
activ[0]=(activ[0]+1)%2;
Q=8;
break;
case 4:
tmpi=in&0x02; // test SW1
if (tmpi!=0) Q=5; // SW1=1
break;
case 5:
activ[1]=(activ[1]+1)%2;
Q=8;
break;
case 6:
tmpi=in&0x04; // test SW2
if (tmpi!=0) Q=7; // SW2=1
break;
case 7:
activ[2]=(activ[2]+1)%2;
Q=8;
break;
case 8:
// LED 2, 1, 0 <- activ[2], [1], [0]
for (i=0; i<3; i++)
{
tmpo = out & ~(1<<i);
out = tmpo | (activ[i]<<i);
}
Q=0;
break;
case 9:
CNT++;
if (CNT==T)
{
CNT=0;
Q=10;
}
break;
case 10:
for (i=0; i<3; i++)
{
if (activ[i]==1)
{
tmpi = in & (8<<i); // test SW(3+i)
if (tmpi!=0)
{
senzor[i]=1;
alarm[i]=1;
tmpo = out & ~(8<<i); // LED (3+i) = 0
out = tmpo | ( alarm[i]<< (3+i)); // LED (3+i) = 1
ALARMA=1;
}

}
}
Q=11;
break;
case 11:
if (ALARMA==0) Q=10;
else Q=12;
break;
case 12:
CNT1=(CNT1+1)%T1;
if (CNT1<T1/2)
{
// scrie 1 pe lED 6
tmpo = out & 0xBF; // LED6 = 0
out = tmpo | (1<<6); // LED6 = 1;
}
if (CNT1>=T1/2)
{
// scrie 0 pe lED 6
out = out & 0xBF; // LED6 = 0
}
tmpi=in&0x80; // test ON/OFF
if (tmpi==0) // OFF
{
CNT=0;
CNT1=0;
for (i=0;i<3; i++)
{
activ[i]=0;
senzor[i]=0;
alarm[i]=0;
}
ALARMA=0;
out=0;
Q=0;
}
break;

PORTB=out; // scrie iesirea


2. Sa se scrie in limbaj de asamblare ADSP2181 un program care implementeaza, eficient din punct de
vedere al timpului de executie si al consumului de memorie ecuatia:

Solutie posibila:

Se definesc:
1 buffer circular, X, de dimensiune 3 (linia de intirziere pentru x(n) , x(n-1) si x(n-2)
1 buffer circular, H, de dimensiune 6 pentru coeficientii in ambele situatii (par si impar)

.var/circ X[3]; // linia de intirziere


.var input; // port de intrare
.var output; // port de iesire

.var/circ H[6]={0xF00000,0x200000,0x400000,0x100000,0xE00000,0x400000};
// -0.125, 0.25, 0.5, 0.125, -0.25, 0.5
start:
// initializari
i0=X; // linia de intirziere
l0=3;
m0=1;
i4=H; // coeficientii
l4=6;
m4=1;
// valideaza intreruperi IRQ2
// asteapta intreruperi
et:
nop;
jump et;

SCI:
// citeste intrarea
ar=dm(input);
// actualizeaza linia de intieziere X
dm(i0,m0)=ar;
// sterge iesirea
mr=0; // iesirea y
/* efectueaza calculul din modul in care s-au scris coeficientii
si din modul in care functioneaza linia de intirziere circulara se va face calculul
pentru esantioanele pare sau impare nu e necesar sa se testeze daca esantionul e
par sau impar - eficient // ca timp de prelucrare se consuma minim de memorie */
cntr=3;
do calcul until ce;
mx0=dm(i0,m0);
my0=pm(i4,m4);
calcul:
mr=mr+mx0*my0(ss);
// scrie iesirea
dm(output)=mr1;

rti;
(2 puncte)

3. Explicati, pe scurt, de ce o arhitectura RISC utilizeaza salturi intirziate, iar o arhitectura post-RISC
utilizeaza predictor de salt. Se poate si invers?
(1 punct)
Solutie posibila:

Salturile intirziate reprezinta o modalitate de a limita numarul de tacte de asteptare (stall) in pipeline
prin “umplerea” acestora cu intructiuni care se pot executa inainte de determinarea adresei de salt sau
testarea conditiei de salt. (explicatii pe un desen). Acelasi lucru il face si un predictor de salt. Diferenta
consta in complexitatea metodei (salt intirziat – mai simplu de realizat, predictor de salt – mai compex).
Pentru o arhitectura RISC – cu instructiuni simple – este mai usor sa se “gaseasca” instructiunile
necesare pentru completarea tactelor de asteptare si chiar daca acest lucru nu e posibil, numarul de
tacte de asteptare e mic (lungimea structurii -1) deoarece structura pipe-line are o lungime relativ mica.
Pentru arhitectura post RISC (Pentium), deoarece instructiunea se imparte in microoperatii, este mai
dificil sa se gaseasca microoperatii care sa completeze tactele de asteptare, iar pipe-line-ul are o
lungime mare, deci performanta scade mai mult daca s-ar utiliza salturi intirziate.

4. Explicati, pe scurt, formatul adresei virtuale pentru adresarea cu segmente paginate. De ce trebuie sa
existe mai multe tabele de paginare? Cum se alege numarul acestor tabele?

(1 punct)
Solutie posibila:
Formatul adresei virtuale:
Adresare segmentata SELECTOR; OFFSET
Cimpul SELECTOR indica o intrare intr-o tabela de segmente unde se gasesc o adresa liniara si
drepturile de acces pe segment.
Adresa liniara are formatul: DIR PAG; INDEX PAG; OFFSET unde DIR PAG este o intrare intr-o
tabela de adrese de baza ale tabelelor de paginare, INDEX PAG este index in tabela de paginare
selectata de DIR PAG si contine adresa de baza a paginii referite, iar OFFSET este offset-ul in pagina
referita (copiat din adresa virtuala cu adresare segmentata).
Este necesar sa existe mai multe tabele de paginare deoarece exista mai multe segmente (pentru mai
multe programe) si fiecare segment are in compunere mai multe pagini (este paginat). Numarul maxim
al acestor tabele este dat de numarul maxim de segmente acceptat in sistemul de memorie.

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