Ústav radioelektroniky Vysoké učení technické v Brně Programování signálových procesorů Mikroprocesorová technika, přednáška č. 13 Ing. Frýza Tomáš, Ph.D. 18. prosince 2007
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Obecná struktura signálového procesoru (Harvardská architektura) Signálový procesor je charakterizován několika znaky Pamět ová oblast pro program a data je oddělena, Pro efektivnější výkon programu se využívá zřetězeného zpracování instrukcí (pipelining), Kromě aritmeticko/logické jednotky obsahuje centrální jednotka také hardwarovou násobičku, Pro přenos dat i adres uvnitř procesoru je využíváno většího počtu oddělených sběrnic, Instrukční soubor s omezeným počtem instrukcí, jejichž výkon trvá obecně jeden nebo dva instrukční cykly, Přesun informací (např. z/do I/O jednotek) je realizován tzv. přímým přístupem do paměti DMA (Direct Memory Access).
Přímý přístup do paměti Pomocí DMA je přenos dat mezi vyrovnávací pamětí I/O zařízení a pamětí systému prováděn bez zatěžování procesoru. Procesor tak nemusí přerušovat výkon programu, pouze musí uvolnit příslušné sběrnice. Přesun řídí (generace adres, časování přesunu) jednotka DMA (viz. blokové schéma DSP).
Struktura signálového procesoru (TI) Obrázek: Jádro procesoru TMS320C67xx
Operace funkčních jednotek (TMS320C64xx) Typ operace.l.s.d.m 32bitové aritmetické operace + + + Dvě 16bit. nebo čtyři 8bit. aritm. oper. + + 40bitové aritmetické operace + 32bitové logické operace + + + 32 nebo 40bitové posuny + + 32bitové operace s jednotlivými bity + Násobení dvou 16bitových operandů + Dvě 16bitové nebo čtyři 8bitové násobení + Přístup do paměti + Větvení programu +
Instrukční paket DSP VLIW U DSP s architekturou typu VLIW jsou instrukce (instrukční paket) složeny z dílčích instrukcí. Každá z instrukcí je právě 32bitová a nese informaci pro jednu řídicí jednotku. DSP TMS320C6xxx obsahuje celkem 8 jednotek, proto jeden instrukční paket obsahuje 8 32 = 256b. Tvorbě instrukčních paketů je podřízeno také programování v jazyce symbolických adres DSP Na jednotlivé pakety se lze odkazovat pomocí návěští (např. u podmíněných či nepodmíněných skoků), U dílčích instrukcí v paketu to nelze. Celý paket se chápe jako celek a stejně tak se nahrává do řídicí jednotky při výkonu programu, Dílčí instrukce v paketu se píší na samostatné řádky, které začínají symbolem. Např.: navesti: ldh.d1t1 *a4++,a9 ; reg. a9 = *a4 ldh.d2t2 *b4++,b9 ; reg. b9 = *b4
Struktura instrukce VLIW navesti: ldh.d1t1 *a4++,a9 ; reg. a9 = *a4 Návěští Identifikuje adresu, od které je v paměti uložen instrukční paket. Název instrukce Označení konkrétní instrukce, tj. operace která se má vykonat (např. ldh načtení dat z paměti, mpy násobení,...). Funkční jednotka Označení jednotky, která má instrukci vykonat (např. D1), Může být spojeno s označením sběrnice pro přenos dat (T1). Argumenty instrukce Např. *a4++, a9. Na rozdíl od mikrokontrolérů zde první operand udává zdroj a poslední destinaci, U DSP TMS320C6xxx není využito přímé adresování. Název registru uvozený hvězdičkou tedy reprezentuje ukazatel, tj. místo kde je uložena adresa operandu.
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Způsoby adresování u DSP Výpočet adres pro čtení/zápis operandů v registrech nebo v paměti provádí jednotka generování adres AGU (Address Generation Unit) Využívá se celočíselná aritmetika (tedy ne zlomkový tvar), Obsahuje vlastní ALU jednotku(y) a datové/řídicí registr(y) pro nastavení způsobu adresování, Nejčastější způsoby u DSP jsou: lineární adresování (přímé/nepřímé), adresování modulo, adresování v bitově reverzním pořadí. Pozn.: Způsob adresování se u TMS320C6000 nastavuje v registru AMR (Addressing Mode Register).
Lineární adresování Přímé adresování Operand instrukce obsahuje přímo zadanou adresu, kde v paměti se nachází hodnota pro výkon instrukce, Pozn.: U TMS320C6000 není tento způsob využit. Nepřímé adresování hodnot operandů Operand instrukce obsahuje adresu, kde je v paměti uložena hodnota pro výkon instrukce. Je to tedy ukazatel na hodnotu, Značení pomocí hvězdičky : *nazev registru. Při použití instrukcí pro přístup do paměti je možné měnit hodnotu ukazatele Inkrementace/dekrementace před/po vykonání adresace, Relativní změna o větší počet pozic, Adresace bez změny ukazatele.
Nepřímé adresování Tabulka: Změna hodnot ukazatelů Změna Před adresací Po adresaci Inkrementace *++rx *rx++ Dekrementace *--rx *rx-- Větší zvýšení *++rx[konst] *rx++[konst] Větší zmenšení *--rx[konst] *rx--[konst] Beze změny *rx *rx
Nepřímé adresování hodnot operandů Tabulka: Načtení dat z paměti do registru: ldw.d1 *a10,b1 (Load from memory) Název registru/pozice Před výkonem Po výkonu b1 0x0000 0000 0x0000 1234 a10 0x0000 0100 0x0000 0100 pamět 0x100 0x0000 1234 0x0000 1234 Tabulka: Uložení hodnoty do paměti: stb.d1 a1,*--a10 (Store to memory) Název registru/pozice Před výkonem Po výkonu a1 0x0012 3456 0x0012 3456 a10 0x0000 0101 0x0000 0100 pamět 0x100 0x0000 1111 0x0012 3456 pamět 0x101 0x1111 1111 0x1111 1111
Adresování modulo Kromě lineárního způsobu adresování (hodnota ukazatele se konstantně zvyšuje/snižuje) je u DSP častým způsobem adresování tzv. adresování modulo (tzv. kruhová pamět ) V datové paměti se vyhradí blok určité délky a pouze v něm se pohybuje ukazatel operandu, Až ukazatel obsahuje nejvyšší možnou adresu a instrukcí se provede další zvýšení, je do ukazujícího registru automaticky nahrána nejnižší adresa ve vyčleněném bloku, Velikost bloku je možné vybrat z pevně daných intervalů (viz. registr AMR). Příklad použití kruhové paměti Periodické čtení koeficientů filtru, Dvojice ukazatelů pro ukládání přijatých/vyslaných dat do paměti.
Nastavení způsobu adresování u TMS320C6000 U každého z registrů A4-A7 a B4-B7 je možné specifikovat způsob adresování (lineární/modulo) v registru AMR (31:0) BK1 (25:21), BK0 (20:16) - určují velikost bloku pro adresování modulo podle vztahu velikost [B] = 2 BKn+1, Je tedy možné nastavit 32 různých velikostí bloku pro adresování typu modulo: od 2B až po 4 294 967 296B, B7mode (15:14), B6mode (13:12),..., A4mode (1:0) - udává typ adresování pro konkrétní registr B7-B4 a A7-A4. 0b00: lineární, 0b01: modulo podle BK0, 0b10: modulo podle BK1.
Adresování v bitově reverzním pořadí Generování adresy v bitově reverzním pořadí je patrně nejméně běžný způsob adresování. Využívá se pouze u speciálních algoritmů, které vstupní/výstupní data přerovnávají z běžného pořadí do jiného. Příkladem je algoritmus rychlé Fourierovy transformace FFT (Fast Fourier Transform), která je často realizována pomocí DSP Jsou-li vstupní vzorky pro výpočet FFT v přirozeném pořadí, tj. 0, 1, 2,..., 7 (příklad N = 8), je pořadí bitů u indexu výstupních vzorků v obráceném pořadí (LSB na prvním místě, MSB poslední), 000=0; 001=1; 010=2; 011=3; 100=4; 101=5; 110=6; 111=7, 000=0; 100=4; 010=2; 110=6; 001=1; 101=5; 011=3; 111=7, Z důvodu usnadnění výpočtu FFT, obsahují DSP hardwarovou část, která realizuje toto přehození adresování v bitově reverzním pořadí.
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Ukázka aplikace v JSA Ukázka implementace jednoduchého algoritmu na signálový procesor TMS320C6000 využívající dvě základní operace DSP: součet, součin y = N 1 n=0 a n x n, N = 10. Obecný popis operací Násobení: a0 x 0 = y 0 mpy.m a0,x0,y0 Akumulace mezivýsledků: y 0 + mezisoucet = y add.l y0,mezisoucet,y Hodnoty operandů jsou ukládány v registrech mpy.m a0,a1,a3 ; a0 * a1 = a3 add.l a4,a3,a4 ; a4 + a3 = a4 Help: mpy - Integer multiply 16 LSB, add - Addition without saturation. Připomenutí: TMS320C6000 obsahuje 32bitové registry (A0-A15 a B0-B15).
Adresování hodnot operandů Hodnoty proměnných a n a x n je nutno do registrů a0, a1 nejprve načíst z paměti. Využijeme nepřímého adresování, kdy registry a5, a6 obsahují ukazatele na vzorky a 0 a x 0 ldh.d *a5++,a0 ; načtení aktuálního vzorku a ldh.d *a6++,a1 ; načtení aktuálního vzorku x Help: ldh - Load from memory. Naplnění 32bitové adresy ukazatelů a5, a6 musí samozřejmě předcházet uvedené instrukce a probíhá ve dvou krocích pomocí instrukcí mvkl a mvkh mvkl.s konst low,a5 ; nižších 16bitů adresy ukazatele mvkh.s konst hi,a5 ; vyšších 16bitů adresy ukazatele mvkl.s konst low,a6 ; nižších 16bitů adresy ukazatele mvkh.s konst hi,a6 ; vyšších 16bitů adresy ukazatele Help: mvkl - Move 16 LSB constant into register, mvkh - Move 16 MSB constant into register.
Větvení programu Cyklus je nutné realizovat pomocí instrukce skoku b.s navesti ; skok na návěští Help: b - Branch. U DSP TMS320C6000 lze podmínit výkon každé instrukce. Jako argument je možné použít obsah registrů A1,A2,B0,B1 nebo B2. Testovaná hodnota se zapíše do [] před instrukci, jejíž výkon má být podmíněn [b0] b.s navesti ; skok na návěští pokud b0!= 0 [!b0] b.s navesti ; skok na návěští pokud b0 = 0 Realizace cyklu je analogická s instrukční sadou AVR; jen s tím rozdílem, že zde netestujeme příznakový bit Zero navesti:... sub.s b0,1,b0 ; b0-1 = b0 [b0] b.s navesti ; skoč pokud je b0!= 0
Dokončení algoritmu Výpis celého algoritmu výpočtu skalárního součinu (konstanty pt1 až pt3 reprezentují adresy, kde jsou v paměti uloženy vstupní vzorky, příp. výstupní hodnota). Help: zero - Zero a register, sth - Store to memory.
Dokončení algoritmu mvkl.s2 pt1,a5 ; ukazatel na vektor a mvkh.s2 pt1,a5 mvkl.s2 pt2,a6 ; ukazatel na vektor x mvkh.s2 pt2,a6 mvkl.s2 pt3,a7 ; ukazatel na výstupní vzorek y mvkh.s2 pt3,a7 mvkl.s2 10,b0 ; počet opakování cyklu zero.l a4 ; nulování mezivýsledku: a4 = 0 navesti: ldh.d *a5++,a0 ; načtení aktuál. vzorku a ldh.d *a6++,a1 ; načtení aktuál. vzorku x mpy.m a0,a1,a3 ; a0 * a1 = a3 add.l a4,a3,a4 ; a4 + a3 = a4 sub.s b0,1,b0 ; b0-1 = b0 [b0] b.s navesti ; if b0!= 0 skoč na navesti sth.d a4,*a7 ; uložení výsledku na adresu ukazatele a7...
Programování v jazyce C Při programování v jazyce C lze kombinovat několik možností Celý kód v jazyce C, Použití speciálních funkcí intrinsic, Kritické pasáže přepsat pomocí funkcí v JSA (*.asm) a ty volat z jazyka C, Kritické pasáže přepsat pomocí lineárního asembleru (*.sa). Speciální funkce intrinsic Jedná se o funkce v jazyce, které ale překladač zamění jednou, příp. několika instrukcemi, Help: int abs( int src ) ; int add2( int src1, int src2 ) ; int mpy( int src1, int src2 ) ;...
Ukázka programování v jazyce C int main( void ) { short a = 0x40 ; short b = 0x20 ; int y ; y = (a + b) << 1 ; // variable declaration // y = 2(a+b) while( 1 ) ; // forever loop return( 1 ) ; // return value = 1 }
Kombinace zdrojového kódu v JSA a v jazyce C Obecně platí zásada, že vyšší programovací jazyk C se při programování DSP používá pro inicializaci aplikace a pro nekritické pasáže kódu (z pohledu velikosti nebo rychlosti). Kritické části je vhodné z hlediska absolutní kontroly rychlosti a velikosti přeloženého kódu programovat v assembleru, příp. v tzv. lineárním assembleru (Texas Instruments). Tři způsoby kombinace kódu napsaného v C a v JSA Funkce v C volá jinou funkci v JSA (uloženou v souboru *.asm), Přerušení spouští obsluhu napsanou v JSA, Instrukce v JSA je spuštěna speciální funkcí překladače intrinsic.
Volání funkce v JSA z jazyka C Funkce v JSA i v C používají stejné registry. Mohou si také vyměňovat parametry/výsledné hodnoty. Názvy veškerých proměnných či funkcí definovaných v C musí být v JSA uvozeny. Registr B3 obsahuje návratovou adresu z funkce v JSA. int main() { }... y = asmfunction( a,b ) ;... // volání funkce v JSA asmfunction:... b b3 ; návrat z funkce v JSA
Vstupní parametry/výstupní hodnota funkce v JSA Funkce v JSA může obsahovat až 10 vstupních parametrů. Ty jsou vždy postupně uloženy v registrech A4, B4, A6, B6, A8, B8, A10, B10, A12 a B12. Pokud funkce vrací hodnotu, je nutné ji před návratem uložit do registru A4. Funkce se ukončí skokem na návratovou adresu, tj. b B3 Příklad Jaké hodnoty obsahují registry A4 a B4 před a po vykonání funkce y = asmfunction( a,b ), která realizuje operaci y = 2 (a + b)? Necht hodnoty a = 0x40 a b = 0x20. Řešení Registr Před Po A4 0x40 (64) 0xc0 (192) B4 0x20 (32) 0x20 (32)
Volání funkce v JSA z jazyka C extern int asmfunction( short,short ) ; // function in assembler int main( void ) { int y = asmfunction( 0x40,0x20 ) ; // call assembler function while( 1 ) ; // forever loop return( 1 ) ; // return value = 1 }.global _asmfunction ; global parameter definition _asmfunction: add.d1x a4,b4,a4 ; a4 + b4 = a4 shl.s1 a4,1,a4 ; a4 << 1 = a4 b.s2 b3 ; return from function nop 4
Vstupní parametry/výstupní hodnota funkce v JSA Vzhledem k situaci, že jak kód napsaný v C tak i v JSA může používat (přepisovat) registry, je potřeba je zálohovat Registry A0,B0 až A9,B9 se automaticky ukládají do paměti při volání funkce v JSA. Po ukončení funkce se hodnoty nahrají zpět (neplatí pro vstupní/výstupní hodnoty), Ostatní registry A10,B10 až A15,B15 musí zálohovat programátor ručně na začátku volané funkce v JSA.
Lineární assembler TMS320C6000 Při programování v JSA signálového procesoru TMS320C6000 je potřeba specifikovat názvy registrů a především hĺıdat časování jednotlivých instrukcí Např. instrukci pro přístup do paměti doplnit 4 instrukcemi nop, Přístup do paměti trvá 5 strojových cyklů; 1. cyklus spuštění instrukce; načtená/uložená hodnota je k dispozici za další 4 cykly. Lineární asembler je jakýmsi mezikrokem mezi JSA a jazykem C. Umožňuje snadnější práci pro programátora, ale ponechává mu značnou kontrolu nad výsledným kódem Je možné používat symbolické názvy registrů, včetně předávaných parametrů (podobně jako proměnné v jazyce C), Správné časování výkonu instrukcí se provádí automaticky, Programuje se přímo pomocí instrukcí bez nutnosti specifikovat funkční jednotku. Kód je optimalizován mezi volné jednotky.
Ukázka aplikace v lineárním assembleru Zdrojový kód uložený v souboru s koncovkou *.sa musí obsahovat několik částí Identifikace symbolu/funkce definovaného v jiném zdrojovém souboru pomocí direktivy.global, Specifikace začátku funkce.cproc, Konec funkce.endproc, Přiřazení vstupních hodnot proměnným za.cproc, Deklarace proměnných (symbolické označení registrů).reg, Návratová hodnota funkce.return.
Ukázka aplikace v lineárním assembleru.global _asmfunction ; the.global directive identifies a symbol ; that is used in the current file but ; defined in another file _asmfunction:.cproc a,b ; beginning of the section _asmfunction ; a, b are inputs of procedure.reg y ; descriptive name to be used for a register add a,b,y shl y,1,y.return y.endproc ; a + b = y ; y << 1 = y ; return value in y ; end of the section _asmfunction
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Zdroje informací Lapsley, P., Bier, J., Shoham, A., Lee, E.A. DSP Processor Fundamentals. Architectures and Features. John Wiley & Sons, New York, 1996, ISBN 0-7803-3405-1. Smékal, Z., Sysel, P. Signálové procesory VLIW firmy Texas Instruments. Sdělovací technika. Dahnoun, N. Linear assembly. University of Bristol, 2002. Dahnoun, N. Interfacing C and assembly code. University of Bristol, 2002.
Obsah přednášky Architektury signálových procesorů Způsoby adresování u signálových procesorů Lineární adresování Adresování modulo Bitově reverzní pořadí Programování signálových procesorů Jazyk symbolických adres Programování v jazyce C Kombinace JSA a C Zdroje informací Otázky a příklady k procvičení
Otázky a příklady k procvičení 1. Navrhněte postup výpočtu jednoho vzorku konvoluce vektorů x a h (N = 4) uložených v paměti DSP TMS320C64xx. Zaměřte se na efektivní využití co největšího počtu funkčních jednotek. Přesné označení instrukcí není důležité. 2. Vyjmenujte všechny funkční jednotky signálového procesoru TMS320C6414. Které z nich umožňují načítání hodnot z paměti? 3. S jakou minimální frekvencí hodinového signálu je možné dosáhnout početního výkonu u DSP TMS320C6211 1 200 MIPS? 4. Napište tělo funkce y = komplex sum( A re, A im, B re, B im ) ; v lineárním asembleru TMS320C6400 realizující součet dvou komplexních čísel.