Bruk av PicoBlaze mikrokontroller i Xilinx System Generator (Matlab - Simulink) Kristian Thorsen April 2010 T-01
Sammendrag Sammendrag På laboratoriene til Institutt for Data- og Elektroteknikk ved UiS, er det en utstrakt bruk av FPGA-kretser og såkalte myke prosessorer. Myke prosessorer er mikroprosessorer implementert i programmerbar elektronikk (FPGA). På laboratoriet har man til nå i stor utstrekning brukt den myke prosessoren MicroBlaze fra Xilinx Inc. MicroBlaze er en avansert 32-bits prosessor, men tar relativt stor plass i FPGA-kretsene. For mange applikasjoner og systemer er en 32-bits prosessor det man på engelsk kaller «overkill». Dette gjelder både med tanke på at den er mye kraftigere enn hva man trenger og at den legger beslag på mye mer systemressurser (logiske porter) i FPGA-kretsene. Et MicroBlaze basert system tar for eksempel opp rundt 75 % av systemressursene som er tilgjengelige i de FPGA-kretser som brukes i faget Digital og Analog Elektronikk 1. Det er altså ønskelig å kunne bruke en enklere prosessor for de systemer eller delsystemer som ikke trenger all den regnekraften som MicroBlaze tilbyr. Et alternativ er den myke mikrokontrolleren PicoBlaze fra Xilinx Inc. Dette er er en enkel 8-bits mikrokontroller som i tillegg til prosessorkjerne inneholder internt programminne, arbeidsminne, mulighet for avbrudd samt et sett med inn- og utporter. Målet med denne rapporten er å vise hvordan denne enkle kontrolleren kan implementeres i FPGA-kretsen ved hjelp av verktøyet Xilinx System Generator som kjøres i Matlab (Simulink). 1 Xilninx Spartan-3 XC3S200. 2 T-01
Om PicoBlaze 1 Om PicoBlaze PicoBlaze er en enkel 8-bits mikrokontroller som kan implementeres i de fleste av Xilinxs FPGA-familier. PicoBlaze finnes i flere versjoner og hvilken versjon som brukes avhenger av FPGA-familien det implementeres mot. For Spartan-3, Virtex II og Virtex II-Pro FPGA-er er det versjon 3 som er aktuell. PicoBlaze3 har blant annet følgende egenskaper: 16, 8-bits registre. RISC design med totalt 53 forskjellige instruksjoner. Internt programminne (ROM) med plass til 1024 instruksjoner (18-bit pr. instruksjon). Internt arbeidsminne (RAM) på 64 Byte. 256 inngangsporter og 256 utgangsporter hver med 8-bits bredde 2. Fast instruksjonstid, 2 klokkesykler pr. instruksjon. Lavt ressursbehov i FPGA-kretsene. Avbruddslinje for bruk av avbruddsbasert programmering. Figur 1.1, hentet fra [2], viser en blokkskjematisk fremstilling av PicoBlaze. Figur 1.1: Blokkskjematisk oversikt over PicoBlaze PicoBlaze programmeres i assembly og assemblykoden kompileres ved bruk av Xilinxs kcpsm3 kompilator. Instruksjonssettet har de vanligste instruksjoner bortsett fra multiplikasjon og divisjon, disse kan dog enkelt implementeres ved å bruke aritmetikk og bitskift. For enkelhets skyld har Xilinx laget ferdige rutiner for disse og flere andre ofte bruke instruksjoner som PicoBlaze mangler. Disse rutinene finnes som assemblykode i [2] og kan kopieres direkte inn i egen kode. 2 Egentlig har PicoBlaze bare en inngangsport og en utgangsport med bredde på 8-bit hver. Sammen med en ekstra utgangsport (kalt Port Id) på 8-bit kan man da ved å multiplekse få hele 256 inngangsog utgangsporter. 3 T-01
PicoBlaze i Xilinx System Generator PicoBlaze kan settes opp ved hjelp av de vanlige EDK verktøyene til Xilinx, men det finnes også en blokk for bruk i Xilinx System Generator. Resten av denne rapporten vil ta for seg hvordan man bruker denne blokka og programmerer PicoBlaze fra System Generator (Matlab). 2 PicoBlaze i Xilinx System Generator For resten av rapporten forutsettes det at leseren er kjent med Matlab verktøyet Xilinx System Generator. Dette er et verktøy som på laboratoriet brukes i faget Anvendt Signalbehandling og som muliggjør at modeller for digitale filter kan lages i Simulink/Matlab og deretter kompileres og kjøres på FPGA-kretser fra Xilinx. For en introduksjon til System Generator anbefales brukermanualen [4]. For å bruke PicoBlaze i Xilinx System Generator hentes blokka ut fra «Xilinx Blockset» biblioteket. PicoBlaze ligger under Control Logic. PicoBlaze blokka kobles sammen med en ROM-blokk som inneholder selve programminnet, dette er vist i figur 2.1. Programminnet skal fylles med det programmet som skal kjøre på kontrolleren. Dette gjøres ved hjelp av kcpsm3 kompilatoren, som blant annet lage et Matlab-script 3 som kan brukes for å fylle ROM. Figur 2.1: System Generator Blokker for PicoBlaze med ROM For å vise hvordan PicoBlaze kan implementeres og programmeres fra Matlab og Xilinx System Generator brukes et eksempel. I dette eksempelet skal PicoBlaze kontrollere noen enkle lysdioder. Eksempelet er skrevet for FPGA-en «Spartan-3E XC3S500E» og kortet «Spartan-3E Starter Kit Board»,figur 2.2 på neste side, men kan enkelt tilpasses andre FPGA-er og utviklingskort fra Xilinx. Eksempelet tar for seg oppbygningen av systemet steg for steg og er skrevet slik at leseren skal kunne utføre eksempelet. Systemet som skal lages er vist i figur 2.3 på side 6. 3.m fil. 4 T-01
2.1 Oppsett av modell i Simulink Figur 2.2: Spartan-3E Starter Kit Board, utviklingskort 2.1 Oppsett av modell i Simulink 1. Start med en ny modell i Simulink. 2. Fra Xilinx Blockset - Basic Elements biblioteket hentes System Generator blokka, denne stilles inn som vist i figur 2.4 på side 7. «Part» feltet inneholder FPGA-en som det skal programmeres mot, og «FPGA clock period» er klokkeperioden som brukes. 20 ns tilsvarer altså 50 MHz. Merk at andre FPGAer og utviklingskort vil ha andre innstillinger i denne blokka, spesielt er «FPGA clock period» av interesse da denne har betydning for venteløkkene som skal lages senere. 3. Neste punkt er å finne PicoBlaze blokka, denne ligger under Control Logic. Etter at blokka er lagt inn i skjemaet er det viktig at man dobbeltklikker på denne og kontrollerer at det er PicoBlaze3 som er valgt. 4. Addr og instr linjene på PicoBlaze tilkobles en ROM blokk. I innstillingene til denne blokka settes dybden til 1024 og «initial value vector» settes til ROM (denne variabelen skal vi senere fylle med maskinkoden til programmet. Latency skal være 1 og under output settes bredden til 18-bit, altså Unsigned 18_0. 5. Resten av blokkene settes opp som vist i figur 2.3 på neste side. Konstanten som settes på inngangsporten skal være av typen Unsigned 8_0 og samplet. Break og resett, brk og rst, kobles til 0 da disse ikke brukes. Videre er det en sammenlikningsblokk (relational) som går høy hver gang PicoBlaze skriver ut et nytt LED mønster på port 255 (0xFF). Det nye mønsteret sendes da gjennom MUX-blokka, som ellers bare beholder forrige mønster. Det er 8 Sliceblokker som sender en enkelt bitverdi videre til tilhørende LEDs utgangsport. LED plasseringen vil være avhengig av hvilket utviklingskort som brukes, for «Spartan-3E Starter Kit Board» skal plasseringen fra topp til bunn være: 5 T-01
2.1 Oppsett av modell i Simulink Figur 2.3: Eksempelsystem, LED kontroll med PicoBlaze F9 = F9 E9 = E9 D11 = D11 C11 = C11 F11 = F11 E11 = E11 E12 = E12 F12 = F12 Lista ovenfor kan legges inn i et Matlab skript og kjøres, en kan da enkelt i utgangsblokkene sette henholdsvis F9, E9 o.s.v i «IOB pad location» feltet som vist i figur 2.5 på neste side. 6 T-01
2.1 Oppsett av modell i Simulink Figur 2.4: Innstilling av System Generator blokka Figur 2.5: IOB pad location i Gatway Out blokka settes til tilhørende LED-plassering 7 T-01
2.2 Program 2.2 Program Neste skritt er å skrive selve programmet som skal kjøre i mikrokontrolleren. Programmet skal i dette eksempelet først lese verdien på inngangsporten. Denne verdien inkrementeres og skrives ut på lysdiodene. Deretter kjører programmet i en evig løkke der verdien på lysdiodene inkrementeres for hvert sekund. Flytskjema vises i figur 2.6. Det anbefales at man setter seg inn i instruksjonssettet til PicoBlaze3 før man starter med selve programmeringen, en kort oversikt er gitt i kapittel 3 i [2]. Merk spesielt at alle tall i assemblykoden er heksadesimale. Figur 2.6: Flytskjema for testprogram For å programmere PicoBlaze trenger man kompilatoren fra Xilinx, kcpsm3, og en teksteditor for å skrive selve assemblykoden. Editoren som er inkludert i Matlab kan med fordel brukes. Lag en ny tekstfil og lagre denne som prog.psm 4, for at kompilatoren skal kunne lese filen er det viktig at filnavnet ikke er lengre enn 8 tegn og ikke inneholder fantasifulle spesialtegn. Selve hovedprogrammet for dette eksempelet trenger ikke mer enn 6 instruksjoner og er som følger, tegnet definerer en kommentar. INPUT s6, 80 Laster inn verdien på inngangsport til register s6 loop: ADD s6, 01 inkrementerer s6 OUTPUT s6, FF Skriver ut s6 til utgangsport 255 CALL delay_1s Kaller opp subrutine (venteløkke) JUMP loop Hopper tilbake til loop Det første som gjøres er at inngangsporten leses og verdien på denne lagres i register s6. Som blokkskjemaet av Simulinkmodellen, figur 2.3 på side 6, viser er det ingen kontroll på hvilken innport som aktiveres, det kunne derfor stått et annet tall enn 80 i INPUT-instruksjonen. Programmet går så inn i en evig løkke (loop), s6 inkrementeres, ADD, og skrives så ut på utgangsport FF, OUTPUT. Før løkka startes på nytt kalles subrutinen delay_1s opp. 4 Pass på at du har nødvendige rettigheter til å endre filetternavn. 8 T-01
2.3 Kompilering av assemblykode 2.2.1 Venteløkker Da alle instruksjonene har like lang instruksjonstid er det å lage venteløkker nesten trivielt. Med en klokkefrekvens på 50 MHz vil hver instruksjon ta 40 ns. En venteløkke som realiserer en ventetid på 1 µ s blir da: delay_1us: LOAD s0, delay_1us_constant wait_1us: SUB s0, 01 JUMP NZ, wait_1us RETURN Konstanten delay_1us_constant lastes inn i register s0, deretter kjøres en løkke som trekker fra 1 på denne verdien helt til tallet er nede i 0. (JUMP NZ, hopp så lenge ikke null). Selve løkken tar da 80 ns for hver iterasjon og det vil være totalt 3 ekstra instruksjoner som må utføres i tillegg til løkkeiterasjonene, CALL, LOAD, og RETURN. Konstanten delay_1us_constant må for et mikrosekund, altså 1000 ns være: 1000 3 40 2 40 = 11 (2.1) Altså 0B heksadesimalt. Alternativt kan formel 2.2 nedenfor brukes: delay_1us_constant = clock_rate 6 4 (2.2) Der clock_rate er klokkeraten til PicoBlaze i MHz. Å realisere en venteløkke på 1 sekund vil nå kunne gjøres ved å lage flere venteløkker som bruker hverandre. Dette er gjort i selve programkoden som er lagt med som vedlegg. 2.3 Kompilering av assemblykode Før programmet kan kompileres må kompilatoren og noen viktige tilhørende filer finnes frem. Kompilatoren leveres med System Generator og vil på lab-pc-ene på UiS kunne hentes fra C:\APPL\Xilinx\SG10_0\DSP_Tools\sysgen. Fra denne stien skal følgende filer hentes og kopieres til et foretrukket arbeidsområde på C:\ disken 5. KCPSM3.EXE,ligger i ~\bin ROM_form.vhd, ligger i ~\hdl ROM_form.v ligger i ~\hdl ROM_form.coe ligger i ~\data Kopier også programfilen prog.psm inn i dette arbeidsområdet. Figur 2.7 på neste side viser hvordan arbeidsområdet skal se ut. 5 Da kompilatoren kjøres fra kommandolinje er det best å legge filene på C:\ disk og så nært opp til root som mulig. 9 T-01
2.4 Kompilering og overføring av Simulinkmodell Figur 2.7: Arbeidsområde før kompilering For å kompilere selve programmet brukes kcpsm.exe, dette gjøres ved å starte opp kommandolinja. Fra Windows-Xp kan dette gjøres ved å velge start kjør, skrive inn cmd og trykke enter. Bruk så cd-kommandoen til å navigere til arbeidsområdet. Programmet kompileres ved å skrive: kcpsm3.exe prog.psm Se også figur 2.8. Figur 2.8: Bruk av kommandolinje Dersom det er feil i koden vil kompilatoren fortelle om dette, forhåpentligvis er det ikke det og programmet kompileres. Kompilatoren lager blant annet et Matlab-skript PROG.M, det er denne filen som skal brukes videre. Husk å gjøre denne fila tilgjengelig for Matlab, enten ved å kopiere den til Matlabs arbeidsområde, eller ved å legge den til i Path-variabelen i Matlab. 2.4 Kompilering og overføring av Simulinkmodell Med PROG.M fila tilgjengelig for Matlab brukes kommandoen: ROM = PROG Variabelen, ROM, som er innholdet i ROM-blokka blir da fylt med maskinkoden til programmet. 10 T-01
2.4 Kompilering og overføring av Simulinkmodell Nå er selve modellen klar til å kompileres. Dobbeltklikk på System Generator blokka i modellen, se figur 2.3 og 2.4, og velg Generate. Når kompileringen av modellen er ferdig startes programmet Xilinx Impact for å overføre programmet til FPGA-en. Impact forutsettes kjent, så bare hovedlinjene er tatt med. I figur 2.9 vises skjermbildet fra Impact, der man har fått kontakt med utviklingskortet. FPGA-en (grønn i figur) programmeres med det nylig kompilerte programmet, mens de to andre kretsene bypasses. Forhåpentligvis stemmer alt nå og en vil se at FPGA-kretsen begynner å telle oppover på lysdiodene. Figur 2.9: Skjermbilde fra Impact koblet opp mot Spartan-3E Starter Kit Board 11 T-01
Oppsummering REFERANSER 3 Oppsummering Som rapporten viser kan PicoBlaze enkelt implementeres i FPGA ved hjelp av Xilinx System Generator for Matlab (Simulink). Det enkle eksempelet i rapporten kan enkelt utvides. På IDE har vi utvidet dette og laget en egen subblokk for Simulink som tar inn 4 signaler, leser disse og skriver ut verdien av dem på 16x2 linjers LCDskjerm. Denne blokken bruker en PicoBlaze mikrokontroller til å styre grensesnittet mot LCD-skjermen. Ved hjelp av denne blokken kan man for eksempel i faget Anvendt Signalbehandling enkelt visualisere hvordan maksimalverdien til et signal endres ved bruk av forskjellige digitale filtre. Grunnet det lave ressursbehoved til PicoBlaze kan denne blokken brukes uten at den opptar så mye ressurser at det går på bekostning av signalbehandlingssystemene som også implementeres i samme FPGAbrikke. For enda et introduksjonsprosjekt til PicoBlaze anbefales introduksjonsprosjektet for utviklingskortet «Spartan-3E Starter Kit Board» laget av Ken Chapman hos Xilinx [1]. Dette prosjektet har vært grunnlag for det eksempelet som brukes i denne rapporten. I tillegg til venteløkker og grensesnitt inneholder introduksjonsprosjektet også en demonstrasjon av avbruddsbasert programmering på PicoBlaze. Referanser [1] Ken Chapman. PicoBlaze Initial Design for Spartan-3E Starter Kit (LCD Display Control). Xilinx, San Jose, CA, Februar 2006. [2] Xilinx. PicoBlaze 8-bit Embedded Microcontroller User Guide (UG129). San Jose, CA, Juni 2004. [3] Xilinx. Spartan-3E Starter Kit Board User Guide (UG230). San Jose, CA, Mars 2006. [4] Xilinx. System Generator for DPS User Guide (UG640). San Jose, CA, Desember 2009. 12 T-01
Kildekode A Kildekode PicoBlaze 3 Testprogram Kristian Thorsen UIS Vår 2010 Basert på eksempelprogram av Ken Chapman - Xilinx Ltd Versjon 0.1 **************************************** Konstanter **************************************** CONSTANT delay_1us_constant, 0B **************************************** Hovedprogram **************************************** INPUT s6, 80 Laster inn verdien på inngangsport til register s6 loop: ADD s6, 01 inkrementerer s6 OUTPUT s6, FF Skriver ut s6 til utgangsport 255 CALL delay_1s Kaller opp subrutine (venteløkke) JUMP loop Hopper tilbake til loop **************************************** Venteløkker **************************************** Delay of 1us. Registers used s0 delay_1us: LOAD s0, delay_1us_constant wait_1us: SUB s0, 01 JUMP NZ, wait_1us RETURN Delay of 40us. Registers used s0, s1 delay_40us: LOAD s1, 28 40 x 1us = 40us 13 T-01
Kildekode wait_40us: CALL delay_1us SUB s1, 01 JUMP NZ, wait_40us RETURN Delay of 1ms. Registers used s0, s1, s2 delay_1ms: LOAD s2, 19 25 x 40us = 1ms wait_1ms: CALL delay_40us SUB s2, 01 JUMP NZ, wait_1ms RETURN Delay of 20ms. Delay of 20ms used during initialisation. Registers used s0, s1, s2, s3 delay_20ms: LOAD s3, 14 20 x 1ms = 20ms wait_20ms: CALL delay_1ms SUB s3, 01 JUMP NZ, wait_20ms RETURN Delay of approximately 1 second. Registers used s0, s1, s2, s3, s4 delay_1s: LOAD s4, 32 50 x 20ms = 1000ms wait_1s: CALL delay_20ms SUB s4, 01 JUMP NZ, wait_1s RETURN 14 T-01