49
UNIVERZITET U BEOGRADU ELEKTROTEHNIČKI FAKULTET DIPLOMSKI RAD PROJEKTOVANJE SPECIFIČNOG TIPA VARIJABLE SA POKRETNIM ZAREZOM I POMOĆNIH PROGRAMA ZA OBAVLJANJE ELEMENTARNIH MATEMATIČKIH OPERACIJA Mentor: Student: Dr. Slobodan Vukosavić Dejan Ilić 96/44 Beograd, novembar 2003.

DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

Embed Size (px)

Citation preview

Page 1: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

UNIVERZITET U BEOGRADU ELEKTROTEHNIČKI FAKULTET

DIPLOMSKI RAD

PROJEKTOVANJE SPECIFIČNOG TIPA VARIJABLE SA POKRETNIM ZAREZOM

I POMOĆNIH PROGRAMA ZA OBAVLJANJE ELEMENTARNIH MATEMATIČKIH OPERACIJA

Mentor Student Dr Slobodan Vukosavić Dejan Ilić 9644

Beograd novembar 2003

2

SADRŽAJ

1 UVOD 3 2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU4

21 Predstavljanje binarnih brojeva sa fiksnom tačkom4 22 Predstavljanje binarnih brojeva sa pokretnom tačkom4

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA5 4 OPIS PROGRAMA6

41 Struktura programa6 42 Tip floating-point brojeva7 43 Glavne promenljive9 44 Programske funkcije (rutine)10

441 Asm funkcija _add211 442 Asm funkcija _sub223 443 Asm funkcija _mpy226 444 Asm funkcija _div231 445 C funkcija inconv36 446 C funkcija outconv41 447 C funkcija main44

5 KREIRANJE IZVRŠNOG PROGRAMA47 6 ZAKLJUČAK48 7 LITERATURA49

3

1 UVOD

Ovaj diplomski rad se bavi realizacijom programa koji će omogućiti da se na fixed-point digitalnom signalnom procesoru TMS320C50 vrše aritmetičke operacije sabiranja oduzimanja množenja i deljenja sa floating-point brojevima

Format floating-point brojeva je 23 + 8 + 1 tj 23 bita za mantisu 8 bita za eksponent i jedan bit znaka Dakle ukupno 32 bita

Takođe programom se realizuju i funkcije ulaznoizlazne konverzije koje pretvaraju ulazni podatak tipa integer u floating-point broj i obratno

Realizacijom programa za obavljanje aritmetičkih operacija sa floating-point brojevima na fixed-point procesoru se koriste dobre strane fixed-point digitalnih signalnih procesora a to su velika brzina rada i mala cena i dobre strane floating-point aritmetike a to je velika preciznost izračunavanja

4

2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU

U binarnom sistemu postoji nekoliko načina za predstavljanje numeričkih

podataka Pre svega prema položaju tačke koja razdvaja celobrojni i razlomački deo broja razlikuju se sistemi sa fiksnom tačkom i pokretnom tačkom U okviru svakog od ovih sistema postoji nekoliko načina predstavljanja koji se uglavnom razlikuju po načinu predstavljanja negativnih brojeva

21 PREDSTAVLJANJE BINARNIH BROJEVA SA FIKSNOM TAČKOM

Najjednostavniji način predstavljanja pozitivnih binarnih brojeva je sistem poznat

pod nazivom prirodni binarni kocircd Pozitivni broj N se u takvom sistemu može napisati u obliku

N = bMbM-1b0 b-1b-B

gde su 0 le bi le 1 cifre binarnog sistema Krajnje levi bit binarnog broja bM se naziva bit najveće težine (engl most significant bit ndash MSB) dok se krajnje desni bit b-B naziva bit najmanje težine (least significant bit ndash LSB) Težinski faktor uz LSB 2-B predstavlja razliku dva susedna broja odnosno rezoluciju binarne predstave Da bi se realizovalo predstavljanje negativnih brojeva potrebno je uvesti još jedan bit koji će pokazivati znak broja Binarni kodovi za predstaljanje brojeva sa znakom (označenih brojeva) nazivaju se bipolarni kodovi Danas se koriste četiri bipolarna koda znak plus amplituda pomereni binarni kod komplement jedinice i komplement dvojke Više o ovome se može saznati u [2]

22 PREDSTAVLJANJE BINARNIH BROJEVA SA POKRETNOM TAČKOM

Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom uvedeno je radi povećanja dinamičkog opsega Broj N se u sistemu sa pokretnom tačkom predstavlja u obliku

N = (-1)s middot 2 E middot M gde je M mantisa pozitivni broj sa fiksnom tačkom iz opsega 0 le M lt 1 s je bit znaka a E je pozitivni celi broj koji se naziva eksponent ili karakteristika

Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa

5

fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA Programabilni integrisani digitalni procesori signala predstavljaju mikroračunare

koji su specijalizovani za digitalnu obradu signala u realnom vremenu S obzirom da algoritmi za digitalnu obradu signala sadrže veliki broj numeričkih izračunavanja arhitektura digitalnih procesora signala je optimizovana za efikasno izvršavanje aritmetičkih instrukcija Zbog toga se arhitektura digitalnih procesora signala znatno razlikuje od arhitekture konvencionalnih mikroračunara Pre svega svaki savremeni digitalni procesor signala sadrži integrisani paralelni množač koji omogućava da se operacija množenja meže izvršiti u toku samo jednog instrukcijskog ciklusa Druga bitna razlika odnosi se na arhitekturu memorije koja je tipa Harvard što znači da je memorija podeljena na barem dve nezavisne banke do kojih vode posebne magistrale i kojima se može simultano pristupiti Jedna od banki služi za smeštaj programa (instrukcija) a druga za smeštaj podataka Na taj način je omogućeno istovremeno učitavanje i instrukcije i operanda Treća razlika je u korišćenju principa protočnosti (engl pipeline) čime se omogućava da se instrukcije efektivno izvršavaju u toku samo jednog instrukcijskog ciklusa iako stvarno izvršavanje instrukcija traje više ciklusa Sve ove razlike su dovele do povećanja numeričkih performansi digitalnih signalnih procesora ali po cenu složenijeg postupka programiranja Programiranje digitalnih procesora signala se najčešće izvodi korišćenjem asemblera jer je kvalitet prevodilaca za više programske jezikejoš uvek loš

U ovom diplomskom radu se koristi digitalni procesor signala TMS320C50 američke firme Texas Instruments To je fixed-point DSP što znači da u svom radu može koristiti samo cele brojeve Takvi DSP-ovi broj predstavljaju u fiksnom opsegu sa konačnom preciznošću Naprimer 16-sto bitni procesor će imati opseg plusmn 215 i preciznost od 1 u 32768 Prvi digitalni signalni procesori su bili bazirani na ovoj tehnologiji a i danas u većini primena u industriji se koriste 16-sto bitni fixed-point procesori Njihova značajna prednost je niska cena i velika brzina rada Sa druge strane postoje i floating-point procesori To su procesori TMS320C3x4x i oni su se pojavili kasnije Kod njih se brojevi izražavaju kao mantisa koja leži između -10 i +10 u kombinacij sa skalirajućom funkcijom koja se zove eksponent Ovaj način predstavljanja daje veći dinamički opseg čime se smanjuje mogućnost pojave prekoračenja (overflow) Algoritme za digitalnu obradu signala je mnogo lakše implementirati na floating-point procesorima Međutim procesori ovog tipa su sporiji i skuplji od fixed-point procesora

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 2: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

2

SADRŽAJ

1 UVOD 3 2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU4

21 Predstavljanje binarnih brojeva sa fiksnom tačkom4 22 Predstavljanje binarnih brojeva sa pokretnom tačkom4

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA5 4 OPIS PROGRAMA6

41 Struktura programa6 42 Tip floating-point brojeva7 43 Glavne promenljive9 44 Programske funkcije (rutine)10

441 Asm funkcija _add211 442 Asm funkcija _sub223 443 Asm funkcija _mpy226 444 Asm funkcija _div231 445 C funkcija inconv36 446 C funkcija outconv41 447 C funkcija main44

5 KREIRANJE IZVRŠNOG PROGRAMA47 6 ZAKLJUČAK48 7 LITERATURA49

3

1 UVOD

Ovaj diplomski rad se bavi realizacijom programa koji će omogućiti da se na fixed-point digitalnom signalnom procesoru TMS320C50 vrše aritmetičke operacije sabiranja oduzimanja množenja i deljenja sa floating-point brojevima

Format floating-point brojeva je 23 + 8 + 1 tj 23 bita za mantisu 8 bita za eksponent i jedan bit znaka Dakle ukupno 32 bita

Takođe programom se realizuju i funkcije ulaznoizlazne konverzije koje pretvaraju ulazni podatak tipa integer u floating-point broj i obratno

Realizacijom programa za obavljanje aritmetičkih operacija sa floating-point brojevima na fixed-point procesoru se koriste dobre strane fixed-point digitalnih signalnih procesora a to su velika brzina rada i mala cena i dobre strane floating-point aritmetike a to je velika preciznost izračunavanja

4

2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU

U binarnom sistemu postoji nekoliko načina za predstavljanje numeričkih

podataka Pre svega prema položaju tačke koja razdvaja celobrojni i razlomački deo broja razlikuju se sistemi sa fiksnom tačkom i pokretnom tačkom U okviru svakog od ovih sistema postoji nekoliko načina predstavljanja koji se uglavnom razlikuju po načinu predstavljanja negativnih brojeva

21 PREDSTAVLJANJE BINARNIH BROJEVA SA FIKSNOM TAČKOM

Najjednostavniji način predstavljanja pozitivnih binarnih brojeva je sistem poznat

pod nazivom prirodni binarni kocircd Pozitivni broj N se u takvom sistemu može napisati u obliku

N = bMbM-1b0 b-1b-B

gde su 0 le bi le 1 cifre binarnog sistema Krajnje levi bit binarnog broja bM se naziva bit najveće težine (engl most significant bit ndash MSB) dok se krajnje desni bit b-B naziva bit najmanje težine (least significant bit ndash LSB) Težinski faktor uz LSB 2-B predstavlja razliku dva susedna broja odnosno rezoluciju binarne predstave Da bi se realizovalo predstavljanje negativnih brojeva potrebno je uvesti još jedan bit koji će pokazivati znak broja Binarni kodovi za predstaljanje brojeva sa znakom (označenih brojeva) nazivaju se bipolarni kodovi Danas se koriste četiri bipolarna koda znak plus amplituda pomereni binarni kod komplement jedinice i komplement dvojke Više o ovome se može saznati u [2]

22 PREDSTAVLJANJE BINARNIH BROJEVA SA POKRETNOM TAČKOM

Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom uvedeno je radi povećanja dinamičkog opsega Broj N se u sistemu sa pokretnom tačkom predstavlja u obliku

N = (-1)s middot 2 E middot M gde je M mantisa pozitivni broj sa fiksnom tačkom iz opsega 0 le M lt 1 s je bit znaka a E je pozitivni celi broj koji se naziva eksponent ili karakteristika

Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa

5

fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA Programabilni integrisani digitalni procesori signala predstavljaju mikroračunare

koji su specijalizovani za digitalnu obradu signala u realnom vremenu S obzirom da algoritmi za digitalnu obradu signala sadrže veliki broj numeričkih izračunavanja arhitektura digitalnih procesora signala je optimizovana za efikasno izvršavanje aritmetičkih instrukcija Zbog toga se arhitektura digitalnih procesora signala znatno razlikuje od arhitekture konvencionalnih mikroračunara Pre svega svaki savremeni digitalni procesor signala sadrži integrisani paralelni množač koji omogućava da se operacija množenja meže izvršiti u toku samo jednog instrukcijskog ciklusa Druga bitna razlika odnosi se na arhitekturu memorije koja je tipa Harvard što znači da je memorija podeljena na barem dve nezavisne banke do kojih vode posebne magistrale i kojima se može simultano pristupiti Jedna od banki služi za smeštaj programa (instrukcija) a druga za smeštaj podataka Na taj način je omogućeno istovremeno učitavanje i instrukcije i operanda Treća razlika je u korišćenju principa protočnosti (engl pipeline) čime se omogućava da se instrukcije efektivno izvršavaju u toku samo jednog instrukcijskog ciklusa iako stvarno izvršavanje instrukcija traje više ciklusa Sve ove razlike su dovele do povećanja numeričkih performansi digitalnih signalnih procesora ali po cenu složenijeg postupka programiranja Programiranje digitalnih procesora signala se najčešće izvodi korišćenjem asemblera jer je kvalitet prevodilaca za više programske jezikejoš uvek loš

U ovom diplomskom radu se koristi digitalni procesor signala TMS320C50 američke firme Texas Instruments To je fixed-point DSP što znači da u svom radu može koristiti samo cele brojeve Takvi DSP-ovi broj predstavljaju u fiksnom opsegu sa konačnom preciznošću Naprimer 16-sto bitni procesor će imati opseg plusmn 215 i preciznost od 1 u 32768 Prvi digitalni signalni procesori su bili bazirani na ovoj tehnologiji a i danas u većini primena u industriji se koriste 16-sto bitni fixed-point procesori Njihova značajna prednost je niska cena i velika brzina rada Sa druge strane postoje i floating-point procesori To su procesori TMS320C3x4x i oni su se pojavili kasnije Kod njih se brojevi izražavaju kao mantisa koja leži između -10 i +10 u kombinacij sa skalirajućom funkcijom koja se zove eksponent Ovaj način predstavljanja daje veći dinamički opseg čime se smanjuje mogućnost pojave prekoračenja (overflow) Algoritme za digitalnu obradu signala je mnogo lakše implementirati na floating-point procesorima Međutim procesori ovog tipa su sporiji i skuplji od fixed-point procesora

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 3: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

3

1 UVOD

Ovaj diplomski rad se bavi realizacijom programa koji će omogućiti da se na fixed-point digitalnom signalnom procesoru TMS320C50 vrše aritmetičke operacije sabiranja oduzimanja množenja i deljenja sa floating-point brojevima

Format floating-point brojeva je 23 + 8 + 1 tj 23 bita za mantisu 8 bita za eksponent i jedan bit znaka Dakle ukupno 32 bita

Takođe programom se realizuju i funkcije ulaznoizlazne konverzije koje pretvaraju ulazni podatak tipa integer u floating-point broj i obratno

Realizacijom programa za obavljanje aritmetičkih operacija sa floating-point brojevima na fixed-point procesoru se koriste dobre strane fixed-point digitalnih signalnih procesora a to su velika brzina rada i mala cena i dobre strane floating-point aritmetike a to je velika preciznost izračunavanja

4

2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU

U binarnom sistemu postoji nekoliko načina za predstavljanje numeričkih

podataka Pre svega prema položaju tačke koja razdvaja celobrojni i razlomački deo broja razlikuju se sistemi sa fiksnom tačkom i pokretnom tačkom U okviru svakog od ovih sistema postoji nekoliko načina predstavljanja koji se uglavnom razlikuju po načinu predstavljanja negativnih brojeva

21 PREDSTAVLJANJE BINARNIH BROJEVA SA FIKSNOM TAČKOM

Najjednostavniji način predstavljanja pozitivnih binarnih brojeva je sistem poznat

pod nazivom prirodni binarni kocircd Pozitivni broj N se u takvom sistemu može napisati u obliku

N = bMbM-1b0 b-1b-B

gde su 0 le bi le 1 cifre binarnog sistema Krajnje levi bit binarnog broja bM se naziva bit najveće težine (engl most significant bit ndash MSB) dok se krajnje desni bit b-B naziva bit najmanje težine (least significant bit ndash LSB) Težinski faktor uz LSB 2-B predstavlja razliku dva susedna broja odnosno rezoluciju binarne predstave Da bi se realizovalo predstavljanje negativnih brojeva potrebno je uvesti još jedan bit koji će pokazivati znak broja Binarni kodovi za predstaljanje brojeva sa znakom (označenih brojeva) nazivaju se bipolarni kodovi Danas se koriste četiri bipolarna koda znak plus amplituda pomereni binarni kod komplement jedinice i komplement dvojke Više o ovome se može saznati u [2]

22 PREDSTAVLJANJE BINARNIH BROJEVA SA POKRETNOM TAČKOM

Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom uvedeno je radi povećanja dinamičkog opsega Broj N se u sistemu sa pokretnom tačkom predstavlja u obliku

N = (-1)s middot 2 E middot M gde je M mantisa pozitivni broj sa fiksnom tačkom iz opsega 0 le M lt 1 s je bit znaka a E je pozitivni celi broj koji se naziva eksponent ili karakteristika

Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa

5

fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA Programabilni integrisani digitalni procesori signala predstavljaju mikroračunare

koji su specijalizovani za digitalnu obradu signala u realnom vremenu S obzirom da algoritmi za digitalnu obradu signala sadrže veliki broj numeričkih izračunavanja arhitektura digitalnih procesora signala je optimizovana za efikasno izvršavanje aritmetičkih instrukcija Zbog toga se arhitektura digitalnih procesora signala znatno razlikuje od arhitekture konvencionalnih mikroračunara Pre svega svaki savremeni digitalni procesor signala sadrži integrisani paralelni množač koji omogućava da se operacija množenja meže izvršiti u toku samo jednog instrukcijskog ciklusa Druga bitna razlika odnosi se na arhitekturu memorije koja je tipa Harvard što znači da je memorija podeljena na barem dve nezavisne banke do kojih vode posebne magistrale i kojima se može simultano pristupiti Jedna od banki služi za smeštaj programa (instrukcija) a druga za smeštaj podataka Na taj način je omogućeno istovremeno učitavanje i instrukcije i operanda Treća razlika je u korišćenju principa protočnosti (engl pipeline) čime se omogućava da se instrukcije efektivno izvršavaju u toku samo jednog instrukcijskog ciklusa iako stvarno izvršavanje instrukcija traje više ciklusa Sve ove razlike su dovele do povećanja numeričkih performansi digitalnih signalnih procesora ali po cenu složenijeg postupka programiranja Programiranje digitalnih procesora signala se najčešće izvodi korišćenjem asemblera jer je kvalitet prevodilaca za više programske jezikejoš uvek loš

U ovom diplomskom radu se koristi digitalni procesor signala TMS320C50 američke firme Texas Instruments To je fixed-point DSP što znači da u svom radu može koristiti samo cele brojeve Takvi DSP-ovi broj predstavljaju u fiksnom opsegu sa konačnom preciznošću Naprimer 16-sto bitni procesor će imati opseg plusmn 215 i preciznost od 1 u 32768 Prvi digitalni signalni procesori su bili bazirani na ovoj tehnologiji a i danas u većini primena u industriji se koriste 16-sto bitni fixed-point procesori Njihova značajna prednost je niska cena i velika brzina rada Sa druge strane postoje i floating-point procesori To su procesori TMS320C3x4x i oni su se pojavili kasnije Kod njih se brojevi izražavaju kao mantisa koja leži između -10 i +10 u kombinacij sa skalirajućom funkcijom koja se zove eksponent Ovaj način predstavljanja daje veći dinamički opseg čime se smanjuje mogućnost pojave prekoračenja (overflow) Algoritme za digitalnu obradu signala je mnogo lakše implementirati na floating-point procesorima Međutim procesori ovog tipa su sporiji i skuplji od fixed-point procesora

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 4: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

4

2 PREDSTAVLJANJE BROJEVA U BINARNOM SISTEMU

U binarnom sistemu postoji nekoliko načina za predstavljanje numeričkih

podataka Pre svega prema položaju tačke koja razdvaja celobrojni i razlomački deo broja razlikuju se sistemi sa fiksnom tačkom i pokretnom tačkom U okviru svakog od ovih sistema postoji nekoliko načina predstavljanja koji se uglavnom razlikuju po načinu predstavljanja negativnih brojeva

21 PREDSTAVLJANJE BINARNIH BROJEVA SA FIKSNOM TAČKOM

Najjednostavniji način predstavljanja pozitivnih binarnih brojeva je sistem poznat

pod nazivom prirodni binarni kocircd Pozitivni broj N se u takvom sistemu može napisati u obliku

N = bMbM-1b0 b-1b-B

gde su 0 le bi le 1 cifre binarnog sistema Krajnje levi bit binarnog broja bM se naziva bit najveće težine (engl most significant bit ndash MSB) dok se krajnje desni bit b-B naziva bit najmanje težine (least significant bit ndash LSB) Težinski faktor uz LSB 2-B predstavlja razliku dva susedna broja odnosno rezoluciju binarne predstave Da bi se realizovalo predstavljanje negativnih brojeva potrebno je uvesti još jedan bit koji će pokazivati znak broja Binarni kodovi za predstaljanje brojeva sa znakom (označenih brojeva) nazivaju se bipolarni kodovi Danas se koriste četiri bipolarna koda znak plus amplituda pomereni binarni kod komplement jedinice i komplement dvojke Više o ovome se može saznati u [2]

22 PREDSTAVLJANJE BINARNIH BROJEVA SA POKRETNOM TAČKOM

Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom uvedeno je radi povećanja dinamičkog opsega Broj N se u sistemu sa pokretnom tačkom predstavlja u obliku

N = (-1)s middot 2 E middot M gde je M mantisa pozitivni broj sa fiksnom tačkom iz opsega 0 le M lt 1 s je bit znaka a E je pozitivni celi broj koji se naziva eksponent ili karakteristika

Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa

5

fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA Programabilni integrisani digitalni procesori signala predstavljaju mikroračunare

koji su specijalizovani za digitalnu obradu signala u realnom vremenu S obzirom da algoritmi za digitalnu obradu signala sadrže veliki broj numeričkih izračunavanja arhitektura digitalnih procesora signala je optimizovana za efikasno izvršavanje aritmetičkih instrukcija Zbog toga se arhitektura digitalnih procesora signala znatno razlikuje od arhitekture konvencionalnih mikroračunara Pre svega svaki savremeni digitalni procesor signala sadrži integrisani paralelni množač koji omogućava da se operacija množenja meže izvršiti u toku samo jednog instrukcijskog ciklusa Druga bitna razlika odnosi se na arhitekturu memorije koja je tipa Harvard što znači da je memorija podeljena na barem dve nezavisne banke do kojih vode posebne magistrale i kojima se može simultano pristupiti Jedna od banki služi za smeštaj programa (instrukcija) a druga za smeštaj podataka Na taj način je omogućeno istovremeno učitavanje i instrukcije i operanda Treća razlika je u korišćenju principa protočnosti (engl pipeline) čime se omogućava da se instrukcije efektivno izvršavaju u toku samo jednog instrukcijskog ciklusa iako stvarno izvršavanje instrukcija traje više ciklusa Sve ove razlike su dovele do povećanja numeričkih performansi digitalnih signalnih procesora ali po cenu složenijeg postupka programiranja Programiranje digitalnih procesora signala se najčešće izvodi korišćenjem asemblera jer je kvalitet prevodilaca za više programske jezikejoš uvek loš

U ovom diplomskom radu se koristi digitalni procesor signala TMS320C50 američke firme Texas Instruments To je fixed-point DSP što znači da u svom radu može koristiti samo cele brojeve Takvi DSP-ovi broj predstavljaju u fiksnom opsegu sa konačnom preciznošću Naprimer 16-sto bitni procesor će imati opseg plusmn 215 i preciznost od 1 u 32768 Prvi digitalni signalni procesori su bili bazirani na ovoj tehnologiji a i danas u većini primena u industriji se koriste 16-sto bitni fixed-point procesori Njihova značajna prednost je niska cena i velika brzina rada Sa druge strane postoje i floating-point procesori To su procesori TMS320C3x4x i oni su se pojavili kasnije Kod njih se brojevi izražavaju kao mantisa koja leži između -10 i +10 u kombinacij sa skalirajućom funkcijom koja se zove eksponent Ovaj način predstavljanja daje veći dinamički opseg čime se smanjuje mogućnost pojave prekoračenja (overflow) Algoritme za digitalnu obradu signala je mnogo lakše implementirati na floating-point procesorima Međutim procesori ovog tipa su sporiji i skuplji od fixed-point procesora

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 5: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

5

fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

3 INTEGRISANI DIGITALNI PROCESORI SIGNALA Programabilni integrisani digitalni procesori signala predstavljaju mikroračunare

koji su specijalizovani za digitalnu obradu signala u realnom vremenu S obzirom da algoritmi za digitalnu obradu signala sadrže veliki broj numeričkih izračunavanja arhitektura digitalnih procesora signala je optimizovana za efikasno izvršavanje aritmetičkih instrukcija Zbog toga se arhitektura digitalnih procesora signala znatno razlikuje od arhitekture konvencionalnih mikroračunara Pre svega svaki savremeni digitalni procesor signala sadrži integrisani paralelni množač koji omogućava da se operacija množenja meže izvršiti u toku samo jednog instrukcijskog ciklusa Druga bitna razlika odnosi se na arhitekturu memorije koja je tipa Harvard što znači da je memorija podeljena na barem dve nezavisne banke do kojih vode posebne magistrale i kojima se može simultano pristupiti Jedna od banki služi za smeštaj programa (instrukcija) a druga za smeštaj podataka Na taj način je omogućeno istovremeno učitavanje i instrukcije i operanda Treća razlika je u korišćenju principa protočnosti (engl pipeline) čime se omogućava da se instrukcije efektivno izvršavaju u toku samo jednog instrukcijskog ciklusa iako stvarno izvršavanje instrukcija traje više ciklusa Sve ove razlike su dovele do povećanja numeričkih performansi digitalnih signalnih procesora ali po cenu složenijeg postupka programiranja Programiranje digitalnih procesora signala se najčešće izvodi korišćenjem asemblera jer je kvalitet prevodilaca za više programske jezikejoš uvek loš

U ovom diplomskom radu se koristi digitalni procesor signala TMS320C50 američke firme Texas Instruments To je fixed-point DSP što znači da u svom radu može koristiti samo cele brojeve Takvi DSP-ovi broj predstavljaju u fiksnom opsegu sa konačnom preciznošću Naprimer 16-sto bitni procesor će imati opseg plusmn 215 i preciznost od 1 u 32768 Prvi digitalni signalni procesori su bili bazirani na ovoj tehnologiji a i danas u većini primena u industriji se koriste 16-sto bitni fixed-point procesori Njihova značajna prednost je niska cena i velika brzina rada Sa druge strane postoje i floating-point procesori To su procesori TMS320C3x4x i oni su se pojavili kasnije Kod njih se brojevi izražavaju kao mantisa koja leži između -10 i +10 u kombinacij sa skalirajućom funkcijom koja se zove eksponent Ovaj način predstavljanja daje veći dinamički opseg čime se smanjuje mogućnost pojave prekoračenja (overflow) Algoritme za digitalnu obradu signala je mnogo lakše implementirati na floating-point procesorima Međutim procesori ovog tipa su sporiji i skuplji od fixed-point procesora

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 6: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

6

osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

4 OPIS PROGRAMA

41 STRUKTURA PROGRAMA Program se sastoji iz više delova (modula) Neki od tih modula su napisani u

asembleru a neki u C-u Svaki modul realizuje jednu funkciju (rutinu) ili definiše osnovne promenljive i njihov tip Svi ti moduli su zatim povezani u jedan izvršni program

Osnovne aritmetičke operacije (sabiranje oduzimanje množenje i deljenje) su realizovane kao funkcije tj rutine napisane u asembleru s tim da se mogu pozivati iz C-a Operacije ulazne i izlazne konverzije su ostvarene kao funkcije u C-u Ulazna konverzija predstavlja u stvari pretvaranje ulaznog podatka tipa integer u floating-point broj a izlazna konverzija obrnuto U C-u je napisan i glavni program main koji je zadužen za unošenje podataka i koji poziva funkcije ulaznoizlazne konverzije i asemblerske rutine

Postoji još i modul napisan u asembleru a u kome su definisani specifičan tip floating-point brojeva i glavne promenljive u kojima se smeštaju operandi i rezultat Tim asemblerskim promenljivama se takođe može pristupati iz C-a Čak štaviše one se u C-u i inicijalizuju

Dakle C deo programa manipuliše glavnim promenljivama i poziva rutine tako da on u stvari predstavlja sponu između asemblera i korisnika tj korisnički interfejs

Na slici 1 je prikazana struktura programa

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 7: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

7

Asemblerski deo C deo

Slika 1 Struktura programa

Što se tiče organizacije modula po fajlovima ona je sledeća svi asemblerski moduli su spojeni u jedan asemblerski fajl chiefasm a svakom C modulu odgovara po jedan C fajl Modul main je u cprogc modul Definicija u definc modul Ulazna konverzija u inconvc i modul Izlazna konverzija u outconvc

42 TIP FLOATINGminusPOINT BROJEVA Floating-point broj se predstavlja strukturom od dva polja od po 16 bita Znači ukupno je na raspolaganju 32 bita (dve reči) 23 bita je dodeljeno mantisi 8 eksponentu i 1 bit znaku U prvom polju m se nalazi 16 donjih bita mantise Viših 7 bita mantise je smešteno u 7 najnižih bita drugog polja e Zatim slede 8 bita eksponenta i najzad najviši bit polja e je bit znaka Dakle realizovani floating-point format izgleda ovako

Modul u kome su definisani tip floating-point brojeva i glavne promenljive

add2 Modul koji realizuje funkciju sabiranja

sub2 Modul koji realizuje funkciju oduzimanja

mpy2 Modul koji realizuje funkciju množenja

div2 Modul koji realizuje funkciju deljenja

main Modul koji rukovodi operacijama unošenja podataka i poziva sve ostale rutine

Ulazna konverzija Modul koji realizuje ulaznu konverziju

Definicija Modul u kome je definisan tip floating-point brojeva

Izlazna konverzija Modul koji realizuje izlaznu konverziju

Izvršni modul

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 8: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

8

Bit eksponent mantisa znaka

seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm

e m U asembleru se ova struktura realizuje direktivom struct na sledeći način Real struct m word e word real_len endstruct zatim se pomoću direktive tag labelama dodeljuju karakteristike strukture Direktiva tag ne alocira memoriju _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Gornje labele su u stvari simboli koji se sad mogu iskoristiti za stvarnu alokaciju memorije na sledeći način bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Ove definicije se nalaze u fajlu chiefasm U C-u se struktura kojom se predstavljaju floating-point brojevi realizuje pomoću naredbe typedef typedef struct int m e Real

Ove dve definicije strukture u asembleru i C-u su identične

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 9: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

9

43 GLAVNE PROMENLJIVE

Glavne promenljive su definisane chiefasm To su _a _b i _f U promenljivu _a se smešta prvi operand u promenljivu _b drugi a u _f se smešta rezultat Ove promenljive su tipa strukture Real što znači da one predstavljaju floating-point brojeve u formatu koji je definisan u prethodnom poglavlju

Glavne promenljive su asemblerske promenljive ali se njima može pristupati i iz C-a Čak štaviše one se u C-u i inicijalizuju Da bi to bilo moguće ime takve asemblerske promenljive u asembleru mora početi donjom crtom ( _ ) ali se u C-u dotičnoj promenljivoj pristupa bez donje crte dakle samo a b ili f To je jednostavno pravilo

U fajlu chiefasm su definisane još neke promenljive kojima se ne pristupa iz C-a ali koje koriste druge asemblerske funkcije To su promenljive sa i sb u koje se smešta znak operanada a i b zatim promenljive ea eb i ef u koje smešta eksponent operanada a i b i rezultata f

U nastavku je prikazan deo kocircda kojim se definišu osnovni strukturni tip floating-point brojeva i glavne promenljive Assembly language program Definisanje strukture kojom se predstavlja floating-point broj Real struct m word e word real_len endstruct Dodeljivanje labelama osobine strukture Nije stvarna alokacija memorije _a tag Real _b tag Real _f tag Real temp tag Real pom tag Real Stvarna alokacija memorije tj definisanje promenljivih tipa strukture bss _a real_len u promenljivu _a ćemo smestiti operand bss _b real_len operand bss _f real_len rezultat bss temp real_len pomoćna promenljiva bss pom real_len pomoćna promenljiva Deklarisanje glavnih promenljivih kao spoljašnjih kako bi bile vidljive iz C programa global _a

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 10: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

10

global _b global _f Definisanje pomoćnih promenljivih bss sa 1 tu stavljamo znak operanda _a bss sb 1 znak operanda _b bss ea 1 tu stavljamo eksponent od _a bss eb 1 eksponent od _b bss ef 1 eksponent od _f

44 PROGRAMSKE FUNKCIJE (RUTINE)

Postoje programske funkcije napisane u asembleru i one napisane u C-u Asemblerske funkcije su _add2 _sub2 _mpy2 i _div2 Njima se realizuju operacije sabiranja oduzimanja množenja i deljenja floating-point brojeva respektivno C funkcije su main inconv i outconv Funkcija main je zadužena za unošenje podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije Funkcija inconv obavlja ulaznu konverziju kojom se integer pretvara u floating-point broj a outconv izlaznu konverziju koja vrši obrnut proces

Asm funkcije se pozivaju iz C-a Zato njihova imena u asembleru moraju početi donjom crtom ( _ ) ali se u C-u ona gubi i funkcije se pozivaju uobičajeno kao svake druge C funkcije dakle add2( ) sub2( ) mpy2( ) i div2( ) Iz ovog primera se još nešto može zaključiti ndash da asm funkcije nemaju ulazne argumente Ako bi ih imale oni bi bili čuvani na steku Time bi kocircd opteretili novim instrukcijama za manipulaciju stekom čime bi izgubili na brzini a i uopšte znatno otežali razumevanje programa Iz istog razloga asm funkcije nemaju ni lokalne varijable koje se nalaze na steku tj nemaju lokalni frejm (engl local frame) već koriste asm direktive poput bss da bi alocirale prostor u memoriji za svoje lokalne promenljive Takođe asm rutine ne vraćaju rezultat već ga proizvode kao bočni efekt Rezultat ovih funkcija je floating-point broj koji je tipa strukture od 32 bita a može se vratiti samo 16-bitni integer koji će se smestiti u akumulator (ACC) Pošto asm funkcije ne koriste ulazne argumente za prenos vrednosti operanada one do operanada dolaze preko globalnih promenljivih _a i _b koji se u njima čuvaju Slično i rezultat vraćaju tako što ga sačuvaju u globalnoj promenljivi _f Ta promenljiva se onda pročita iz C-a

Svaka asm funkcija mora ispoštovati tzv C-call konvencije tj obaveze koje pozvana funkcija mora da obavi na samom početku kada se u nju uđe i na kraju kada se iz nje izađe Te obaveze su npr da se sa hardverskog steka uzme adresa povratka i stavi na softverski stek da se FP (Frame Pointer) stavi na softverski stek itd Više o tim obavezama se može saznati u [3]

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 11: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

11

441 ASM FUNKCIJA _add2

U najkraćim crtama algoritam rada funkcije _add2 je funkcija prvo ispituje znak operanada Zatim ispituje koji operand ima veći eksponent Taj eksponent se usvaja kao rezultujući Potom se mantisa operanda sa manjim eksponentom pomera udesno za onoliko mesta koliko iznosi razlika između eksponenata Onda se mantise saberu ispita se da li je došlo do prekoračenja prilikom sabiranja i ako jeste izvrši se normalizacija mantise tako što se ona pomeri za jedno mesto udesno a rezultujući eksponet se poveća za jedan Na kraju se ažurira znak i rezultat smesti u odgovarajuću promenljivu

Na sledećoj slici dat je strukturni blok dijagram asm funkcije _add2

da ne

da ne ne

da ne da ne ne ne

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije

promenljivih

Izdvajanje znaka i eksponenata

operanada _a i _b u odgovarajuće

promenljive

_a gt 0

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea ef = eb

_b gt 0

ea gt eb

ef = ea ef = eb

ea gt eb

ef = ea

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 12: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

12

ne

ne

da ne da da

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _b

pom larr mantisa od _a

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _a udesno da bi izjednačili eksponente

temp larr mantisa od _a

pom larr mantisa od _b

Call SUBTRACT

Goto KRAJ

Šiftujemo mantisu

operanda _b udesno da bi izjednačili eksponente

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _a ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

ef = eb Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Šiftujemo mantisu

operanda _a da bi

izjednačili eksponente

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 13: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

13

ne da

Slika 2 Algoritam asm funkcije _add2

Rezultat stavljamo u

_f

Rezultat stavljamo u

_f

Goto KRAJ Goto KRAJ

Rezultat stavljamo u

_f

Goto KRAJ

Šiftovanu mantisu

smeštamo u ACCB

Mantisa od _b ide u ACC

Saberemo mantise

ACC larr ACC + ACCB

Overflow

Normalizacija mantise tj pomeramo rezultujuću mantisu za

jedno mesto udesno

Povećavamo eksponent ef

za 1

Rezultat stavljamo u

_f

Goto KRAJ

KRAJ

Kocircd da bi se ispoštovale

C-call konvencije

RET

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 14: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

14

Potprogram SUBTRACT obavlja oduzimanje mantisa a to se čini kada je jedan od operanada negativan U promenljivu temp se uvek smešta mantisa negativnog operanda a u promenljivu pom mantisa pozitivnog Zatim se ispituje koja je mantisa veća od nje se oduzme manja i na kraju se shodno tome da li je veća mantisa bila pozitivna ili negativna ažurira znak Sada sledi kompletan kocircd funkcije _add2 _add2 Asm funkcija koja obavlja operaciju sabiranja dva floating-point broja i koja se poziva iz C programa _add2

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije bss diff 1 tu se smešta razlika eksponenata RSXM reset sign-extension mode LACL _ae postupak izdvajanja znaka operanda _a AND 8000h ACCL = 8000h -gt _alt0 ili ACCL = 0 -gt _agt=0 SACL sa LAC _be postupak izdvajanja znaka operanda _b AND 8000h SACL sb LAC _ae postupak izdvajanja eksponenta od _a AND 0111111110000000b SACL ea

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 15: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

15

LAC _be postupak izdvajanja eksponenta od _b AND 0111111110000000b SACL eb LACL sa BZ A_pozitivno ako je ACC = 0 tj _a gt 0 skoči na A_pozitivno B A_negativno u protivnom idi na labelu A_negativno A_pozitivno LACL sb BNZ B_negativno1 skoči ako je ACC = 0 (_b lt 0) LACC 0 SACL _fe stavljamo da je i _f gt= 0 if ea gt eb LAC ea SACL ef eksponent od _f je jednak eksponentu od _a SUB eb SUB 1 ACC = ea-eb-1 SACL diff broj šiftovanja mantise radi izjednačavanja eksponenata LAC _be AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL gornji deo mantise je u ACCH LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _a je u ACCH LAC _am ACC = mantisa od _a ADDB ACC = ACC + ACCB SACL tempm SACH tempe

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 16: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

16

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow1 skoci ako nema LAC tempe 16 ACCH su visih 7 bita mantise LAC tempm ACCL su nizih 16 bita mantise SFR normalizujemo mantisu jer je došlo do prekoračenja SACH tempe za mantisu važi 0 lt= mantisa lt 1 SACL tempm LACL ef ADD 1 inkrementiramo eksponent SACL ef ažurirali smo i eksponent jer je mantisa pomerena No_Overflow1 LAC tempe OR ef SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef eksponent od _f je jednak eksponentu od _b SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b izdvajamo gornji deo mantise RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL gornji deo mantise od _b je u ACCH LAC _bm ACC sadrži mantisu od _b ADDB ACC = ACC + ACCB SACL tempm SACH tempe

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 17: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

17

LACL tempe AND 0000000010000000b ispitujemo da li ima prenosa BZ No_Overflow2 skoči ako nema LAC tempe 16 LAC tempm SFR normalizujemo mantisu jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 inkrementiramo eksponent jer je mantisa pomerena SACL ef No_Overflow2 LAC tempe OR ef SACL _fe _f ge 0 LACL tempm SACL _fm endif B KRAJ skoči na KRAJ B_negativno1 _b lt 0 _a gt= 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b izdvajamo gornji deo mantise od _b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _b LACL _ae AND 0000000001111111b SACL pome LAC _am

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 18: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

18

SACL pomm pom = _a CALL SUBTRACT else ea le eb (i dalje je _b lt 0 _a ge 0) LACL eb SACL ef ef = eb jer je eb ge ea SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _a LACL _be AND 0000000001111111b SACL tempe LAC _bm SACL tempm temp = _b CALL SUBTRACT endif B KRAJ A_negativno _a lt 0 LACL sb BNZ B_negativno2 skoči ako je ACC = 0 (_b lt 0) if ea gt eb LAC ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 19: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

19

LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH pome SACL pomm pom = _b LACL _ae AND 0000000001111111b SACL tempe LAC _am SACL tempm temp = _a CALL SUBTRACT else ea le eb (_a lt 0 _b gt= 0) LAC eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACH tempe SACL tempm temp = _a LACL _be AND 0000000001111111b SACL pome LAC _bm SACL pomm pom = _b CALL SUBTRACT endif

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 20: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

20

B KRAJ B_negativno2 _a lt 0 _b lt 0 if ea gt eb LACL ea SACL ef ef = ea SUB eb SUB 1 ACC = ea-eb-1 SACL diff LAC _be AND 0000000001111111b RPTK 15 SFL LAC _bm RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _b LACL _ae AND 0000000001111111b RPTK 15 SFL u ACCH je gornji deo mantise operanda _a LAC _am ACC = _a ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow3 LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe za mantisu vazi 0 le mantisa lt1 SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow3 LAC tempe OR ef OR 8000h _f lt 0

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 21: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

21

SACL _fe LACL tempm SACL _fm else ea le eb LACL eb SACL ef ef = eb SUB ea SUB 1 ACC = eb-ea-1 SACL diff LAC _ae AND 0000000001111111b RPTK 15 SFL LAC _am RPT diff SFR šiftujemo mantisu da bi izjednačili eksponente SACB ACC ide u ACCB ACCB = mantisa od _a LACL _be AND 0000000001111111b RPTK 15 SFL u ACCH je visi deo mantise od _b LAC _bm ACC = _b ADDB ACC = ACC + ACCB = _a + _b SACL tempm SACH tempe LACL tempe AND 0000000010000000b BZ No_Overflow4 skoči ako nema prenosa LAC tempe 16 LAC tempm SFR normalizacija mantise jer je gt 1 SACH tempe SACL tempm LACL ef ADD 1 povećavamo eksponent za 1 jer smo izvršili SACL ef normalizaciju mantise No_Overflow4 LAC tempe OR ef

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 22: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

22

OR 8000h _f lt 0 SACL _fe LACL tempm SACL _fm endif B KRAJ Potprogram za oduzimanje mantisa SUBTRACT if tempe gt pome LAC pome 16 LAC pomm SACB u ACCB je pom LAC tempe 16 LAC tempm u ACC je temp SBB ACC = ACC - ACCB = temp - pom SACL _fm BSAR 16 ACCH ide u ACCL OR ef OR 8000h _f lt 0 SACL _fe elseif tempe = pome if tempm gt pomm LAC tempm SUB pomm SACL _fm LACC 0 OR ef OR 8000h SACL _fe else tempm le pomm LAC pomm SUB tempm SACL _fm LACC 0 OR ef SACL _fe _f gt 0 endif

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 23: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

23

else tempe lt pome LAC tempe 16 LAC tempm SACB ACCB = temp LAC pome 16 LAC pomm ACC = pom SBB ACC = ACC - ACCB = pom - temp SACL _fm BSAR 16 ACCH ide u ACCL OR ef SACL _fe _f gt 0 endif RET Pošto se asm funkcija _add2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle KRAJ global _add2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

442 ASM FUNCKIJA _sub2

Funkcija _sub2 oduzima dva floating-point broja odnosno preciznije od operanda _a oduzme operand _b i rezultat smesti u promenljivu _f Operacija oduzimanja se obavlja tako što se operandu _b promeni znak a zatim se sabere sa operandom _a tako što se pozove funkcija _add2 Po povratku u funkciju _sub2 operandu _b se vrati stari znak

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 24: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

24

Na početku i kraju funkcije _sub2 je kocircd koji je neophodan da bi se ispoštovale C-call konvencije Na sledećoj slici je prikazan strukturni blok dijagram funkcije

Slika 3 Algoritam asm funkcije _sub2

Sada sledi kompletan kocircd funkcije _sub2

_sub2 Asm funkcija koja obavlja operaciju oduzimanja dva floating-point broja i koja se poziva iz C programa _sub2

START

Kocircd da bi se ispoštovale C-call

konvencije

Definicije i deklaracije promenljivih

Promena znaka operanda _b

Call _add2

Vraćanje starog znaka operandu _b

C-call konvencije

RET

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 25: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

25

version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija _sub2 poziva drugu funkciju (_add2) pa se adresa povratka mora uzeti sa hardverskog steka i staviti na softverski stek Funkcija _sub2 nema lokalne promenljive pa ona i ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) POPD + pop return address push on software stack SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Telo funkcije ref _add2 LACL _be XORK 8000h menjamo znak operandu _b SACL _be B _add2 bezuslovni skok na labelu _add2 tj poziv funkcije LACL _be XORK 8000h vraćamo stari znak operandu _b SACL _be Posto se asm funkcija _sub2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _sub2 Telo funkcije je završeno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - pop FP PSHD push return address on hardware stack RET

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 26: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

26

443 ASM FUNKCIJA _mpy2 Operacija množenja dva floating-point broja se obavlja tako što se njihove

mantise pomnože a eksponenti saberu Pošto mantise nisu 16-bitni brojevi već 23-bitni onda se množenje ne može obaviti samo prostim korišćenjem instrukcije mpy nego je algoritam množenja znatno složeniji

Algoritam se sastoji u tome da se mantise predstave kao 32-bitne označene vrednosti s tim što su vodećih 9 bita nule a nižih 23 bita predstavljaju mantisu Dakle mantise posmatramo kao označene vrednosti ali već unapred znamo da su one pozitvne jer je vodeći bit nula Rezultat množenja je 64-bitna vrednost a njenih najviših 23 bita ćemo uzeti kao rezultantnu mantisu Celu 32-bitnu mantisu operanda _a čuvamo u dve memorijske lokacije X1 i X0 a mantisu operanda _b u Y1 i Y0 Rezultat smeštamo u lokacije W3 W2 W1 W0

U ovom algoritmu se koristi jedna važna instrukcija a to je MPYU (unsigned multiplication) koja omogućava množenje dva 16-bitna neoznačena broja i smeštanje 32-bitnog rezultata u PREG u toku samo jednog ciklusa

Isto tako u ovom algoritmu je neophodno obaviti i množenje jednog označenog i jednog neoznačenog 16-bitnog celog broja Za 16-bitno množenje celih brojeva (integer) gde je jedan operand označeni integer u drugom komplementu a drugi operand neoznačeni integer može se koristiti algoritam prikazan na narednoj slici [4]

Označeni integer Neoznačeni integer Označeno množenje + Dodaj X ako je Y15 = 1 Konačni 32-bitni rezultat

Slika 4 Algoritam množenja 16-bitnih celih brojeva Ono što treba uočiti u ovom algoritmu je to što se na proizvod dva operanda X i

Y koje oba tretiramo kao označene brojeve mora dodati korekcioni faktor tj operand X ako je MSB operanda Y jednak 1 To je zato što je težina najvišeg bita bilo kog neoznačenog 16-bitnog broja 215

X

Y

X Y

X

W

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 27: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

27

Algoritam množenja dve mantise je predstavljen na sledećoj slici Neoznačeno množenje Označeno množenje Označeno množenje Ako je MSB od Y0 =1 Ako je MSB od X0 =1 + Označeno množenje Konačni 64-bitni rezultat

Slika 5 Algoritam množenja Sada se od 64-bitnog rezultata uzmu 23 najviša bita koja predstavljaju

rezultantnu mantisu Sledeće što treba uraditi je sabrati eksponente ažurirati znak i sačuvati rezultat u

promenljivoj _f U nastavku je dat kompletan kocircd funkcije mpy2

_mpy2 Asm funkcija koja obavlja operaciju množenja dva floating-point broja i koja se poziva iz C programa

X0X1

Y0Y1

X0 Y0

X1 Y0

X0 Y1

X1

Y1

X1 Y1

W3 W2 W1 W0

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 28: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

28

_mpy2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek Funkcija nema lokalne promenljive pa se ne alocira lokalni frejm pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP)

SAR AR1 SP = SP Sledi telo funkcije Prvo se množe mantise Njih predstavljamo kao dva neoznačena integera od 32 bita s tim da vodecih 9 bita su nule Operandi tj mantise se dohvataju iz memorije a tamo se smesta i rezultat Data storage X1 X0 32-bit operand Y1 Y0 32-bit operand W3 W2 W1 W0 64-bit result Od 64-bitnog rezultata ćemo uzeti 23 najviših bita za rezultujuću mantisu bss X1 1 bss X0 1 bss Y1 1 bss Y0 1 bss W3 1 bss W2 1 bss W1 1 bss W0 1 LACL _ae AND 0000000001111111b RPTK 15 SFL LAC _am ACC = mantisa od _a SACL X0

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 29: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

29

SACH X1 LACL _be AND 0000000001111111b RPTK 15 SFL LAC _bm ACC = mantisa od _b SACL Y0 SACH Y1 RSXM reset sign-extension mode BIT X0 0 TC = X0 bit 15 LT X0 T = X0 MPYU Y0 P = X0Y0 SPL W0 sačuvaj W0 SPH W1 sačuvaj parcijalni W1 MPY Y1 P = X0Y1 LTP X1 ACC = X0Y1 T = X1 MPY Y0 P = X1Y0 MPYA Y1 ACC = X0Y1 + X1Y0 P = X1Y1 ADDS W1 ACC = X0Y1 + X1Y0 + X0Y02^-16 SACL W1 sačuvaj konačni W1 BSAR 16 šiftuj ACC udesno za 16 XC 1 TC ako je MSB od X0 jednak 1 ADD Y1 dodaj Y1 BIT Y0 0 TC = Y0 bit 15 APAC ACC = X1Y1 + (X0Y1 + X1Y0)2^-16 XC 1 TC ako je MSB od Y0 jednak 1 ADD X1 dodaj X1 SACL W2 sačuvaj W2 SACH W3 sačuvaj W3 Rezultat se nalazi u W3W2W1W0 Sada treba od ovih 64 bita uzeti 23 najviša i smestiti ih u promenljivu _f Ta 23 bita predstavljaju rezultantu mantisu LACC W3 16 ACC = W3 00 ADDS W2 ACC = W3 W2 RPTK 8 logički šiftujemo ACC udesno za 9 bita SFR vodećih 9 bita ACC se puni nulama SACL _fm sačuvaj mantisu SACH _fe LACL _ae AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 30: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

30

SACL ea tu je eksponent od _a LAC _be AND 0111111110000000b RPTK 6 SFR pomeraj od 7 mesta udesno SACL eb tu je eksponent od _b ADD ea prilikom množenja dva broja eksponenti se sabiraju SACL ef RPTK 6 SFL pomeraj od 7 mesta ulevo tj na staro mesto OR _fe SACL _fe eksponent je ažuriran LACL _ae XOR _be AND 8000h izdvojili smo znak proizvoda u ACCL to je najviši bit OR _fe SACL _fe Pošto se asm funkcija _mpy2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _mpy2 Telo funkcije je zavrseno Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 31: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

31

444 ASM FUNKCIJA _div2 Dva floating-point broja se dele tako što se njihove mantise podele a eksponenti

oduzmu Za deljenje mantisa se koristi instrukcija SUBC Da bi se ona koristila neophodno je da deljenik i delioc budu 16-bitni pozitivni brojevi To znači da ćemo od 23-bitnih mantisa uzeti njihovih 16 najviših bita Zatim se instrukcija SUBC ponovi 15 ili 16 puta što zavisi od toga da li je deljenik manji ili veći od delioca Rezultat će biti u akumulatoru i to 16-bitni količnik u donjem delu akumulatora (ACCL) a 16-bitni ostatak u gornjem delu akumulatora (ACCH)

U zavisnosti od toga da li je deljenik (brojilac) veći ili manji od delioca (imenioca) razlikujemo dve vrste deljenja celo (integer) i razlomačko (fractional) Razlika je u tome što se kod celog deljenja instrukcija SUBC ponavlja 16 puta a kod razlomačkog deljenja 15 puta Više o ovome se može saznati iz [3]

Asm funkcija _div2 uzima operand _a kao deljenik a operand _b kao delioc Prvo se u posebne promenljive NUMERA i DENOM smesti 16 najviših bita mantise operanda _a odnosno _b Koristeći postupak celog ili razlomačkog deljenja mantise se podele i 16-bitni količnik sačuva u promenljivoj QUOT Ostatak se ne iskorišćuje Sada se od 16-bitne rezultantne mantise načini 23-bitna To se izvodi tako što se mantisa jednostavno šiftuje za 7 mesta ulevo a najniži biti popune nulama Tako šiftovana mantisa se smesti u promenljivu _f Naredni korak je oduzimanje eksponenata Ako je razlika pozitivna ona se kao rezultantni eksponent smesti u promenljivu ef i kasnije u _f Ako je razlika negativna onda se uzme njena apsolutna vrednost i za taj iznos šiftuje rezultantna mantisa udesno Rezultantni eksponent je tada nula Zadnji korak ovog algoritma je ažuriranje znaka

Kao i svaka asm funkcija i funkcija _div2 počinje i završava kocircdom koji je neophodan da bi se ispoštovale C-call konvencije

Algoritam funkcije je prikazan na sledećoj slici

START

Kocircd da bi se ispoštovale

C-call konvencije

Definicije i deklaracije

promenljivih

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 32: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

32

da ne da ne

NUMERA larr 16 najviših bita mantise operanda _a

DENOM larr 16 najviših bita mantise operanda _b

DENOM = 0

Goto KRAJ

NUMERA gt DENOM

Intdiv ACC larr NUMERA

Fracdiv ACC larr NUMERA

SUBC DENOM ponovi 16 puta

SUBD DENOM ponovi 15 puta

QUOT larr količnik REM larr ostatak

QUOT larr količnik REM larr ostatak

Šiftuj QUOT za 7 mesta ulevo i to sačuvaj kao rezultantnu

mantisu u _f

ea larr eksponent od _a eb larr eksponent od _b

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 33: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

33

da ne

Slika 7 Algoritam asm funkcije _div2 Sledi kocircd asm funkcije _div2

div2 Asm funkcija koja obavlja operaciju deljenja dva floating-point broja i koja se poziva iz C programa

ea ndash eb gt 0

ef larr ea ndash eb Za (eb ndash ea) mesta pomeri mantisu

udesno

ef larr 0

ef smesti u _f

Ažuriraj znak

KRAJ Kocircd da bi se

ispoštovale C-call konvencije

RET

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 34: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

34

_div2 version 50 Sledi kocircd koji funkcija mora da odradi kako bi bile ispoštovane C-call konvencije Funkcija ne poziva drugu funkciju pa nema potrebe da se adresa povratka uzme sa hardverskog steka i stavi na softverski stek pretpostavljamo da je ARP = AR1 (SP) SAR AR0 + push AR0 (Frame Pointer-FP) SAR AR1 SP = SP Sledi telo funkcije Kada se dele dva floating-point broja njihove mantise se podele a eksponenti oduzmu Mantise se dele pomocu SUBC instrukcije Od 23 bita mantise uzmu se 16 najviših Prilikom deljenja mantisa postoje dva slucaja kada je mantisa u brojiocu veca od one u imeniocu i obratno Razlike u kocircdu za svaki slučaj su male bss NUMERA 1 brojilac tj 16 najviših bita mantise koja je deljenik bss DENOM 1 imenilac (16 najviših bita mantise koja je delilac) bss QUOT 1 tu se smešta rezultat deljenja bss REM 1 tu se smešta ostatak pri deljenju bss DIFFEXP 1 tu se smešta razlika eksponenata Sada ćemo izdvojiti 16 najviših bita mantise operanda _a (deljenik) LACL _ae AND 0000000001111111b RPTK 15 SFL ACCH sadrži viših 9 bita mantise LAC _am BSAR 7 ACCL sadrži viših 16 bita mantise SACL NUMERA Sada ćemo izdvojiti 16 najviših bita mantise operanda _b (delilac) LACL _be AND 0000000001111111b RPTK 15

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 35: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

35

SFL ACCH sadrži viših 9 bita mantise LAC _bm BSAR 7 ACCL sadrži viših 16 bita mantise SACL DENOM BZ Kraj vrati se iz rutine ako je imenilac = 0 Početak deljenja Prvo treba ustanoviti ko je veći brojilac ili imenilac pa prema tome odrediti koji će se deo kocircda izvršiti (tzv integer division ili fractional division) LACL NUMERA SUB DENOM BLZ Fracdiv Intdiv LACL NUMERA RPT 15 16 cycle integer division SUBC DENOM SACL QUOT SACH REM B Nastavi1 Fracdiv LACL NUMERA RPT 14 15 cycle fractional division SUBC DENOM SACL QUOT SACH REM Nastavi1 LACL QUOT RPT 6 SFL SACL _fm najnižih 7 bita rezultujuće mantise su nule SACH _fe ostatak nismo iskoristili LACL _ae izdvajamo eksponent deljenika _a AND 0111111110000000b BSAR 7 SACL ea LACL _be izdvajamo eksponent delioca _b AND 0111111110000000b BSAR 7 SACL eb LACL ea SUB eb BLZ Azuriraj SACL ef rezultujući eksponent B Nastavi2 Azuriraj ABS ACC je sada pozitivan SACL DIFFEXP LAC _fe 16 u ACCH je viših 7 bita mantise

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 36: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

36

LAC _fm u ACCL je nižih 16 bita mantise RPT DIFFEXP-1 SFR mantisa je sada ažurirana LACC 0 SACL ef rezultujući eksponent je jednak nuli Nastavi2 OR _fe SACL _fe Ažuriranje znaka rezultata LACL _ae XOR _be AND 8000h OR _fe SACL _fe Pošto se asm funkcija _div2 poziva iz C programa ona mora biti deklarisana kao spoljašnja dakle global _div2 Sada sledi kocircd koji funkcija prilikom izlaska mora da izvrši kako bi bile ispoštovane C-call konvencije Kraj LARP AR1 set ARP = AR1 (SP) SBRK 1 LAR AR0 - restore frame pointer(FP) RET

445 C FUNKCIJA inconv Funkcija inconv vrši ulaznu konverziju pretverajući integer u floating-point broj

Funkcija ima dva ulazna argumenta tipa integer a kao rezultat vraća floating-point broj tipa Real Prvi ulazni argument koji se zove ulaz predstavlja izmerenu veličinu sa nekog AD konvertora a drugi argument ndash nivo predstavlja nivo jedinice tj neku nominalnu vrednost u odnosu na koju se dobija relativna vrednost ulaza To znači da se u okviru C funkcije inconv izračuna količnik ulaznivo (q) i da se tako dobijeni broj koji je tipa float ili double pretvori u floating-point broj tipa Real Dakle moramo odrediti eksponent i mantisu Eksponent je broj od 0 do 255 a određuje se tako što se ispita koji je najmanji stepen na koji treba podići broj 2 kako bi tako dobijeni broj bio veći ili jednak količniku q Taj stepen predstavlja u stvari eksponent Da bi odredili mantisu izračunaćemo količnik q2eksponent (x) koji je manji ili jednak od 1 Taj broj se zatim standardnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 37: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

37

algoritmom za konverziju brojeva iz decimalnog u binarni sistem [5] pretvori u 23-bitnu mantisu Sacircm postupak pretvaranja je dosta komplikovan i zametan jer mantisa ne postoji u memoriji kao jedinstvena lokacija već se nalazi u polju m i u 7 najnižih bita polja e strukturne promenljive _f Da bi se razumeo postupak izračunavanja mantise neophodno je proučiti postupak konverzije decimalnog broja koji je u intervalu od 0 do 1 u binarni brojni sistem

Na početku funkcije inconv postoji jedna include direktiva kojom je u fajl inconvc uključen fajl definc u kome je definisan tip floating-point brojeva Real Ta definicija je identična asemblerskoj definiciji strukture Real a u C-u ona glasi

Definicija strukture kojom se predstavlja floating-point broj typedef struct int m e Real ova definicija je identična onoj iz asemblera

Na sledećoj slici je prikazan algoritam funkcije inconv

START

Definicije promenljivih

q = ulaznivo

Određivanje znaka

Određivanje eksponenta

x = q2eksponent

Postupak pretvaranja broja x (0 le x le 1) u

23-bitnu mantisu

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 38: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

38

Slika 8 Algoritam funkcije inconv Sada sledi kocircd funkcije inconv

Funkcija koja vrši ulaznu konverziju tj int ulaz normalizuje i pretvara u floating-point broj tipa Real include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi Real inconv (int ulaz int nivo) Real rezultat Real pomocni double q količnik ulaza i nivoa double u n x pomoćne promenljive char brojac = 0 pomoćna promenljiva short int eksponent short int je duzine 16 bita short int sign short int prenos pomoćna promenljiva u = (double) ulaz n = (double) nivo q = un if (q lt 0) sign = 0x8000 q = fabs(q) Odredjivanje eksponenta for (int k = 0 k lt 256 k++) if (q lt pow(2 k)) eksponent = k break ispadamo iz for petlje if (k = 255) printf(Overflow)

Ažuriranje konačnog rezultata

Return rezultat

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 39: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

39

eksponent ltlt= 7 shift left eksponent za 7 eksponent amp= 0x7F80 izdvoj samo eksponent Odredjivanje mantise x = q pow(2 eksponent) x le 1 for (int i = 0 i lt 23 i++) x = 2 if (x gt 1) x -= 1 if (brojac lt 16) to znači da se još nije napunio donji deo mantise (nižih 16 bita) pomocnim ltlt= 1 shift left pomoćni pomocnim |= 1 brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni da bi stvorio mesta za novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ else if (x lt 1) if (brojac lt 16) pomocnim ltlt= 1 pomocnim amp= 0xFFFE brojac++ else prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 40: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

40

pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE brojac++ else x = 1 if (brojac lt 16) pomocnim ltlt= 1 shift left jer dolazi novi bit pomocnim |= 1 novi bit je 1 brojac++ for (int j = brojac j lt 16 j++) pomocnim ltlt= 1 pomocnim amp= 0xFFFE for (int j = 16 j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i) else brojac ge 16 for (int j = brojac j lt 23 j++) prenos = pomocnim amp 0x8000 uzimamo najviši bit prenos gtgt= 15 shift right za 15 prenos amp= 0x0001 pomocnie ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnie |= prenos unos novog bita iz donjeg dela mantise pomocnim ltlt= 1 shift left pomoćni jer dolazi novi bit pomocnim amp= 0xFFFE break ispadamo iz velike for petlje (for i)

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 41: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

41

pomocnie = pomocnie | eksponent | sign rezultat = pomocni return rezultat

446 C FUNKCIJA outconv Funkcija outconv vrši konverziju floating-point broja u integer Funkcija ima dva

ulazna argumenta koji su floating-point brojevi tipa Real a vraća rezultat koji je integer Isto kao i kod C funkcije inconv prvi argument se zove ulaz a drugi nivo Drugi argument predstavlja nivo jedinice tj nominalnu vrednost u odnosu na koju se izračuna relativna vrednost ulaza Količnik ulaznivo se određuje tako što se vrednosti ulaznih argumenata ulaz i nivo dodele glavnim promenljivama _a i _b pa se u okviru funkcije outconv pozove asm funkcija div2 Rezultat se smešta u promenljivu _f Taj rezultat treba pretvoriti u broj tipa integer Prvo se izračuna vrednost 23-bitne mantise na sledeći način najviši bit mantise ima težinu 2-1 a najniži 2-23 saberu se težine svih onih bita koji su jednaki 1 i to je vrednost mantise koja je realan broj tipa double (ili float) Potom se vrednost mantise pomnoži sa 2eksponent Dobijeni broj se onda pomoću C operatora cast pretvori u integer Nakon toga ažurira se znak i na kraju dobijeni integer skalira tako što se pomnoži sa (215-1)

Na početku fajla outconvc se navodi direktiva include koja uključuje fajl definc u kome se nalazi definicija strukturnog tipa Real Ova definicija je identična odgovarajućoj asemblerskoj definiciji Potom se navode deklaracije glavnih globalnih asemblerskih promenljivih _a _b i _f Takođe navodi se i deklaracija asm funkcije _div2

Na sledećoj slici prikazan je algoritam funkcije outconv

START

Definicije promenljivih

a = ulaz b = nivo

CALL div2( )

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 42: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

42

Slika 9 Algoritam funkcije outconv Sada sledi kocircd funkcije outconv

Funkcija koja vrši izlaznu konverziju tj floating-point broj normalizuje i onda ga pretvori u int include definc tu se nalazi definicija strukture kojom se predstavljaju floating-point brojevi extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f extern void div2 (void) asm funkcija _div2 long int outconv (Real ulaz Real nivo) long int rezultat tu smeštamo rezultat

Iz promenljive f izdvojimo mantisu i izračunamo njenu

vrednost

Iz promenljive f izdvojimo eksponent

rezultat = 2eksponent (vrednost mantise)

Ažuriranje znaka rezultata

Skaliranje rezultata rezultat = rezultat (215 ndash 1)

Return rezultat

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 43: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

43

long int mantisa = 0 tu smeštamo mantisu od 23 bita (long int ima bar 32 bita) long int marker markerom ispitujemo pojedinačne bite mantise long int pomocna pomoćna promenljiva char eksponent tu smeštamo eksponent floating-point broja (on ima 8 bita) double suma = 0 tu se smešta vrednost mantise 0 le mantisa lt 1 a = ulaz b = nivo div2( ) f = a b u asembleru je to _f = _a _b mantisa |= _fe mantisa amp= 0x007F izdvajamo najviših 7 bita mantise mantisa ltlt 16 stvaramo prostor za smeštanje nižih 16 bita mantise mantisa |= _fm sada imamo svih 23 bita mantise u promenljivoj mantisa marker = 1 marker ltlt 22 1 se nalazi na 23-em bitu bitu najvise težine za mantisu for (i = 1 i lt= 23 i++ marker gtgt 1) pomocna = mantisa amp marker if (pomocna = 0) suma += pow(2 -i) mantisa = 0 mantisa |= _fe mantisa amp= 0x7F80 izdvajamo eksponent mantisa gtgt 7 eksponent = (char) mantisa rezultat = (long int) (pow(2 eksponent) suma) mantisa = 0 mantisa |= _fe mantisa amp= 0x8000 izdvajamo znak if (mantisa = 0) rezultat -= 0 ažuriramo znak rezultata rezultat = (pow(2 15) - 1) (2^15 - 1) return rezultat

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 44: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

44

447 C FUNKCIJA main U modulu cprogc definisana je funkcija main Ona je zadužena za unošenje

podataka pozivanje funkcije ulazne konverzije inicijalizovanje glavnih promenljivih pozivanje asm funkcija za obavljanje aritmetičkih operacija i pozivanje funkcije izlazne konverzije

Pre funkcije main navode se deklaracije spoljašnjih asm promenljivih i funkcija kao i C funkcija inconv i outconv

U funkciji main se prvo definišu promenljive za smeštanje rezultata Treba obratiti pažnju na definiciju promenljive jedinica koja je tipa Real Ona je značajna za izlaznu konverziju kada floating-point broj treba pretvoriti u integer ali bez normalizovanja Ona je u stvari floating-point broj jednak 10 Normalizacija sa takvim brojem ne menja broj koji se normalizuje Zato se jedinica uzima kao drugi argument funkcije outconv

U funkciji main se unose vrednosti za ulaz i nivo kako bi se pomoću funkcije ulazne konverzije inconv inicijalizovali operandi a i b Kada se to odradi kreće se sa pozivanjem asm funkcija za obavljanje aritmetičkih operacija rezultati se smeštaju u posebne promenljive i poziva se funkcija izlazne konverzije outconv sa drugim argumentom koji je jedinica

Na kraju kao demonstracija upotrebe funkcije outconv za njene ulazne argumente se uzmu operandi a i b

Na sledećoj slici je prikazan blok dijagram funkcije main

START

Definicije promenljivih

Inicijalizacija operanda a

Inicijalizacija operanda b

CALL add2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 45: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

45

Slika 10 Blok dijagram funkcije main

Sada sledi kocircd funkcije main

C program include definc tu se nalazi definicija strukture Real kojom se predstavljaju floating-point brojevi Sada moramo promenljive definisane u asembleru deklarisati kao extern da bi ih mogli normalno koristiti u C-u

CALL sub2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL mpy2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL div2( )

Izlazna konverzija rezultata normalizovanog sa jedinicom

CALL outconv(a b) i prikaži rezultat

KRAJ

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 46: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

46

extern Real a u asembleru je to promenljiva _a extern Real b u asembleru _b extern Real f u asembleru _f Isto tako moramo i funkcije definisane u asembleru deklarisati kao extern da bi ih mogli pozivati iz C-a extern void add2 (void) to je u asembleru funkcija _add2 extern void sub2 (void) asm funkcija _sub2 extern void mpy2 (void) asm funkcija _mpy2 extern void div2 (void) asm funkcija _div2 Deklaracije C funcija za ulaznu i izlaznu konverziju Real inconv (int int) deklaracija funkcije koja vrši ulaznu konverziju long int outconv (Real Real) deklaracija funkcije za izlaznu konverziju main ( ) Real suma tu ćemo smestiti a + b Real razlika tu ćemo smestiti a - b Real proizvod tu ćemo smestiti a b Real kolicnik tu ćemo smestiti a b Real jedinica = 0x00C0 0x0000 floating-point broj koji je jednak 10 eksponent = 1 mantisa = 05 21 05 = 1 long int s r p k d promenljive za smeštanje rezultata izlazne konverzije Asm promenljivama pristupamo iz C-a normalno ali bez donje crte (_) ispred njihovog imena a = inconv (5 2) proizvoljno smo inicijalizovali prvi operand a b = inconv (4 7) proizvoljno smo inicijalizovali drugi operand b Asm funkcije pozivamo iz C-a kao obične funkcije ali bez navođenja donje crte (_) ispred njihovog imena add2 ( ) poziv asm funkcije _add2 rezultat će biti smešten u f (_f) f = a + b suma = f tj suma = _f

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 47: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

47

s = outconv (suma jedinica) sub2 ( ) poziv asm funkcije _sub2 rezultat u f (_f) f = a - b razlika = f r = outconv (razlika jedinica) mpy2 ( ) poziv asm funkcije _mpy2 rezultat u f (_f) f = a b proizvod = f p = outconv (proizvod jedinica) div2 ( ) poziv asm funkcije _div2 rezultat u f ( _f) f = a b kolicnik = f k = otconv (kolicnik jedinica) d = outconv (a b)

5 KREIRANJE IZVRŠNOG PROGRAMA

C fajlovi su C kompajlerom za TMS320C50 prevedeni u asemblerske fajlove i zatim zajedno sa pravim asm fajlovima asemblerom za C50 prevedeni u objektne fajlove Objektni fajlovi se pomoću linkera kombinuju u jedinstveni izvršni modul To je u stvari fajl sa ekstenzijom out Prilikom linkovanja neophodno je kao ulaz linkera navesti i objektnu biblioteku rts50lib koja sadrži tzv runtime-support funkcije To su zapravo standardne ANSI funkcije koje obavljaju zadatke kao što su alokacija memorije string konverzija pretraživanje stringova itd Ova objektna biblioteka je napravljena od asemblerskog i C kocircda sadržanog u izvorišnoj biblioteci rtssrc

Naredba kojom se poziva linker koji pravi izvršni fajl izvrsniout izgleda ovako

dsplnk chief ndashc defin inconv outconv cprog ndasho izvrsniout ndashl rts50lib

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 48: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

48

6 ZAKLJUČAK Programabilni integrisani digitalni procesori signala su specijalizovani za

digitalnu obradu signala Takva obrada zahteva intezivna numerička izračunavanja u kojima se koriste ne samo celi već i razlomljeni brojevi Ovi drugi se mogu predstaviti u formatu sa fiksnom tačkom i u formatu sa pokretnom tačkom Osnovni nedostatak predstave brojeva sa fiksnom tačkom je što je rezolucija konstantna i određena brojem upotrebljenih bitova za predstavljanje broja Ako je potrebno povećati opseg brojeva izvan ndash1 le N le 1 bez povećanja broja bita to se može izvesti samo pomeranjem položaja tačke udesno što izaziva smanjenje rezolucije Predstavljanje brojeva sa pokretnom tačkom poboljšava dinamički opseg ne narušavajući rezoluciju i u tom pogledu znatno nadmašuje sisteme predstavljanja sa fiksnom tačkom Osnovni nedostaci sistema sa pokretnom tačkom leže u povećanoj složenosti hardvera za izvođenje aritmetičkih operacija kao i u manjoj brzini izračunavanja Razlog za oba nedostatka je jasan prilikom svake aritmetičke operacije moraju se vršiti operacije i sa mantisom i sa karakteristikom Zbog svojih prednosti predstavljanje brojeva sa pokretnom tačkom se koristi u svim primenama gde brzina obrade nije važna kao što je to slučaj u obradi signala van realnog vremena na računarima opšte namene

Postoje digitalni procesori signala koji mogu da rade samo sa celim brojevima To su tzv fixed-point procesori i takav je naprimer TMS320C50 Postoje i digitalni procesori signala koji rade sa razlomljenim brojevima u formatu sa pokretnom tačkom To su tzv floating-point procesori kakvi su iz familija TMS320C3x4x Fixed-point procesori imaju tu prednost što su brzi i jeftini ali mogu da rade samo sa celim brojevima a u algoritmima za digitalnu obradu signala se koriste i razlomljeni brojevi Sa druge strane floating-point procesori imaju tu prednost što se na njima lakše mogu implementirati algoritmi za digitalnu obradu signala jer mogu da rade sa floating-point brojevima ali su ti procesori zato sporiji i skuplji

U ovom diplomskom radu je napravljen kompromis između visoke cene i sporosti rada floating-point procesora sa jedne strane i činjenice da fixed-point procesori mogu raditi samo sa celim brojevima sa druge strane tako što je realizovan program na fixed-point procesoru koji simulira predstavljanje brojeva sa pokretnom tačkom i obavljanje osnovnih aritmetičkih operacija sa njima Time se koriste dobre osobine fixed-point DSP-ova što su velika brzina rada i niska cena i dobre osobine floating-point aritmetike što su veća preciznost u radu i lakša implementacija algoritama za digitalnu obradu signala

Programskom realizacijom floating-point brojeva je ostvarena velika fleksibilnost u radu jer je tako omogućeno korisniku da sacircm određuje željeni format floating-point brojeva i time reguliše dinamički opseg i preciznost U ovom diplomskom radu upotrebljeni format floating-point brojeva je 23 + 8 + 1 ali se malim izmenama u programu taj format može vrlo lako promeniti

Upravo je mogućnost da korisnik lako može promeniti format floating-point brojeva najveća prednost programske realizacije floating-point brojeva plus još to što je program napisan za fixed-point procesor koji je brži i jeftiniji od floating-point procesora Loša strana je to što je pisanje takvih programa vrlo teško i zamorno

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997

Page 49: DIPLOMSKI RAD - emp.etf.rsemp.etf.rs/radovi/Diplomski/Ilic.pdf · univerzitet u beogradu elektrotehniČki fakultet diplomski rad projektovanje specifiČnog tipa varijable sa pokretnim

49

7 LITERATURA 1 Slobodan N Vukosavić Projektovanje adaptivnog mikroprocesorskog

upravljanja brzinom i pozicijom asinhronog motora 2 Miodrag Popović Digitalna obrada signala Nauka Beograd 1997 3 Texas Instruments Co TMS320C2xC2xxC5x Optimizing C Compiler Userrsquos

Guide 1997 4 Texas Instruments Co TMS320C5x General Purpose Applications Userrsquos

Guide 1997 5 Laslo Kraus Zbirka zadataka iz programskih jezika Elektrotehnički fakultet

Beograd 1996 6 Laslo Kraus Programski jezik C Elektrotehnički fakultet Beograd 1998 7 Texas Instruments Co TMS320C1xC2xC2xxC5x Assembly Language Tools

Userrsquos Guide 1995 8 Texas Instruments Co TMS320C5x DSK Applications Guide 1997