construirea propriului microcontroler

acest articol se concentrează pe învățarea modului în care este proiectat un nucleu de microcontroler și este destinat numai utilizării educaționale. Vă rugăm să vizitați www.zilog.com și verificați linia de produse a producătorului pentru a selecta un microcontroler care se potrivește nevoilor dvs. de proiect (de la bisuri Z8 pe opt biți! și eZ80 Acclaims la 32-bit ARM Cortex-M3 bazat pe ZNEO32! care include capabilități avansate de control al motorului).

povestea mea de dragoste cu microcontrolerele și microprocesoarele a început în 1988, când lucram la o diplomă tehnică la CEFET-PR (O școală secundară/tehnică braziliană de patru ani și universitate situată în Curitiba). Am început prin a învăța elementele de bază în timp ce exploram clasicul Zilog Z-80 (figura 1a).

figura 1A. Zilog Z-80A (prin amabilitatea Wikimedia Commons).

derulează rapid printr-o carieră de programare care a inclus crearea unor cărți despre programarea microcontrolerelor (vezi resurse), începerea unei mici case de design (ScTec) și finalizarea unui program post-absolvire la CEFET-SC (o altă universitate Braziliană situată în Florianopolis). Acest lucru a fost în 2008, când am avut mai mult contact cu logica programabilă și VHDL și curiozitatea mea a fost maximă. Ani mai târziu, în 2016, am găsit un kit FPGA (Field-Programmable gate Array) foarte accesibil și am decis să-i dau o șansă și am început să învăț mai multe despre tehnologia FPGA.

ce ar fi mai bine decât proiectarea unui softcore pentru a afla mai multe despre VHDL (vhsic hardware description language), FPGA-uri și nucleele microprocesorului? Am ajuns să aleg o rudă modernă Z – 80: Zilog Z8 Encore! (alias eZ8; figura 1b).

figura 1b. Zilog eZ8.

este un nucleu de microcontroler pe opt biți, cu un set de instrucțiuni simplu-dar puternic — și un depanator foarte frumos pe cip. Cu IDE-ul său ușor (integrated development environment) și compilatorul gratuit ANSI C, este un proiect excelent pentru a învăța (și, de asemenea, pentru a preda) despre sistemele încorporate.

înainte de a vă scufunda în adâncurile operațiunii de bază, VHDL și FPGA, să aruncăm o privire asupra Zilog Z8 Encore! caracteristici.

figura 1C. FPz8 pe un FPGA.

Zilog Z8 Bis!

eZ8 este o familie de microcontrolere pe opt biți bazată pe familia Z8 de succes a Zilog și pe marea moștenire Z-80. Dispune de o mașină Harvard CISC cu până la 4.096 octeți de memorie RAM (registru de fișiere și zonă de registre de funcții speciale), până la 64 KB de memorie de program (de obicei memorie Flash) și până la 64 KB de memorie de date (RAM). Nucleul eZ8 include, de asemenea, un controler de întrerupere vectorizat cu prioritate programabilă și un debugger on-chip care comunică cu computerul gazdă folosind comunicare serială asincronă. Aceste microcontrolere sunt ambalate cu un set periferic foarte frumos, variind de la cronometre versatile pe 16 biți la cronometre de control al motorului, de la mai multe UARTs (IrDA ready) la dispozitive USB și multe altele (vizitați www.zilog.com pentru a verifica linia completă de produse).

o caracteristică majoră a modelului de programare eZ8 este lipsa unui acumulator fix. În schimb, oricare dintre cele 4.096 de adrese RAM posibile poate funcționa ca acumulatori. CPU tratează memoria RAM principală (fișierul și SFR-urile-registre de funcții speciale-zonă) ca un set mare de registre CPU. Pentru a realiza acest lucru, RAM este împărțit în grupuri de registre (există 256 de grupuri de 16 registre de lucru fiecare). O instrucțiune funcționează de obicei într-un singur grup de registru de lucru, care este selectat de un SFR numit RP (registru pointer). Rețineți că toate SFr-urile sunt localizate la ultima pagină a RAM (adrese începând de la 0xF00 până la 0xFFF).

în ceea ce privește setul de instrucțiuni, există 83 de instrucțiuni diferite împărțite în două pagini opcode. Acesta cuprinde instrucțiuni obișnuite pentru operațiile de bază, cum ar fi adunarea, scăderea, operațiile logice, instrucțiunile de manipulare a datelor, instrucțiunile de schimbare, instrucțiunile de schimbare a fluxului, unele instrucțiuni pe 16 biți, testarea și manipularea bitului, înmulțirea 8×8 etc.

zona de memorie a programului este organizată astfel încât primele adrese să fie dedicate unor scopuri speciale. Adresele 0x0000 și 0x0001 sunt dedicate opțiunilor de configurare; adresele 0x0002 și 0x0003 stochează vectorul de resetare; și așa mai departe. Tabelul 1 prezintă organizarea memoriei programului.

0x0000 Option bytes
0x0002 Reset vector
0x0004 WDT vector
0x0006 Illegal instruction vector
0x0008 to 0x0037 Interrupt vectors
0x0038 to 0xFFFF User program memory area

TABLE 1. Simplified program memory organization.

unele dispozitive includ, de asemenea, un al doilea spațiu de date (până la 65.536 de adrese) care poate fi accesat numai utilizând instrucțiunile LDE/LDEI. Această zonă poate fi utilizată pentru a stoca date mai puțin utilizate (deoarece citirea/scrierea este mai lentă decât zona RAM/SFR).

FPz8

prima implementare a FPz8 folosește o abordare de proiectare foarte conservatoare și cablată, cu două autobuze principale: una pentru memoria programului și alta pentru memoria registrului. Deoarece am ales să nu includ o zonă de memorie de date, instrucțiunile LDE/LDEI nu sunt implementate.

magistralele de memorie a programului cuprind o magistrală de adresă de instrucțiuni pe 16 biți (IAB), o magistrală de date de instrucțiuni pe opt biți (IDB pentru citirea datelor din memoria programului), o magistrală de date de scriere a instrucțiunilor pe opt biți (IWDB pentru scrierea datelor în memoria programului) și un semnal PGM_WR care controlează scrierea în memoria programului. FPz8 include 16.384 octeți de memorie de program implementată folosind RAM bloc sincron (ceea ce înseamnă că conținutul memoriei programului se pierde atunci când dispozitivul este oprit).

cele cinci autobuze din zona registrului cuprind trei pentru zona registrului de fișiere (RAM utilizator) și alte două dedicate registrelor de funcții speciale. Există o magistrală principală de adresă a registrului de fișiere pe 12 biți (FRAB), o magistrală de date de intrare a registrului de fișiere pe opt biți (FRIDB), o magistrală de date de ieșire a registrului de fișiere pe opt biți (FRODB), o magistrală de date de intrare a registrului pe opt biți (RIDB) și, în final, o magistrală de date de ieșire a registrului pe opt biți (RODB) pentru scrierea în SFr-uri. FPz8 include 2.048 octeți de memorie RAM utilizator implementat folosind RAM bloc sincron.

Figura 2 prezintă o diagramă bloc a FPz8; puteți vedea CPU, două unități de memorie (una pentru stocarea programului și cealaltă pentru stocarea datelor), precum și un modul de temporizare extern.

figura 2. Diagrama bloc FPz8.

rețineți că nu folosesc autobuze bidirecționale pentru nicio interconectare din acest proiect. Autobuzele unidirecționale sunt mai simple de utilizat, deși sunt mai puțin eficiente din punct de vedere al spațiului.

descrierea VHDL a FPz8 este mare și un pic complex, așa că am de gând să împartă funcționarea sa în unele module pentru a ușura înțelegerea:

  1. motor de așteptare instrucțiuni
  2. decodare instrucțiuni
  3. prelucrare întrerupere
  4. depanator

motor de așteptare instrucțiuni

preluarea instrucțiuni este o sarcină principală pentru orice CPU. Arhitectura Harvard a FPz8 permite preluarea simultană și accesul la date (datorită autobuzelor separate pentru instrucțiuni și date). Asta înseamnă că procesorul poate prelua o nouă instrucțiune în timp ce altul citește sau scrie în memoria de date.

eZ8 are un cuvânt de instrucțiuni de lungime variabilă (lungimea instrucțiunii variază de la un octet până la cinci octeți); unele instrucțiuni sunt lungi, dar rulează mai repede decât altele. În acest fel, o instrucțiune BRK are o lungime de un octet și rulează în două cicluri,în timp ce un LDX IM, ER1 are o lungime de patru octeți și rulează în două cicluri de ceas.

Deci, cum putem decoda cu succes toate aceste instrucțiuni? Cu o coadă de instrucțiuni; adică un mecanism care păstrează preluarea octeților din memoria programului și stocarea lor într-o matrice de opt octeți:

if (CAN_FETCH=’1′) apoi
if (IQUEUE.FETCH_STATE = F_ADDR) apoi
FETCH_ADDR := PC;
IAB<= PC;
IQUEUE.WRPOS: = 0;
IQUEUE.RDPOS: = 0;
IQUEUE.CNT := 0;
IQUEUE.FETCH_STATE: = F_READ;
else
dacă (IQUEUE.FULL = ‘0’) apoi
IQUEUE.COADĂ(IQUEUE.WRPOS): = IDB;
FETCH_ADDR:= FETCH_ADDR + 1;
IAB < = FETCH_ADDR;
IQUEUE.WRPOS: = IQUEUE.WRPOS + 1;
IQUEUE.CNT: = IQUEUE.CNT + 1;
sfârșit dacă;
sfârșit dacă;
sfârșit dacă;
sfârșit dacă (IQUEUE.CNT = 7) apoi IQUEUE.FULL: = ‘1’; altfel IQUEUE.FULL: = ‘0’;
end if;

listare 1. Motor coadă de instrucțiuni.

preluarea este controlată de un semnal principal de activare (CAN_FETCH) care poate fi dezactivat în unele cazuri speciale (Procesarea întreruperii, prin instrucțiuni LDC/LDCI sau acces depanator). Există, de asemenea, o structură (IQUEUE) care stochează mai mulți parametri interni (preluarea de stat, citește și scrie indicii, matrice coadă în sine, un contor, și un indicator complet).

contorul de coadă (CNT) este utilizat pentru a identifica numărul de octeți disponibili pentru utilizare (Citire) în coadă. Etapa de decodare utilizează acest număr pentru a verifica dacă numărul dorit de octeți pentru instrucțiune este deja disponibil în coadă.

decodarea instrucțiunii

aici se întâmplă magia reală. Decodorul de instrucțiuni citește opcodes din coada de instrucțiuni și le traduce în operații corespunzătoare.

proiectarea decodorului de instrucțiuni a început prin a afla relația dintre toate instrucțiunile și modurile de adresare. La prima vedere, este ușor de observat că unele instrucțiuni (Figura 3) sunt grupate pe coloane (DJNZ,JR cc, X,LD r1, IM,jp cc, DA și INC r1). Decodarea unei instrucțiuni INC r1 este simplă: pe aceste instrucțiuni cu un singur octet, nibble-ul înalt specifică Registrul sursă/destinație, iar nibble-ul inferior specifică instrucțiunea în sine (0xE).

figura 3. Opcodes de grupuri.

cele mai multe instrucțiuni pot fi clasificate în conformitate cu unele reguli de bază:

  1. coloanele (ciugulitul inferior al unui opcode) specifică de obicei un mod de adresare: Instrucțiunile din coloana 0x9, de exemplu,folosesc în cea mai mare parte IM, modul de adresare ER1 și au patru octeți lungi (al doilea octet este operandul imediat și ultimii doi octeți sunt Adresa extinsă de destinație).
  2. rânduri (ciuguli mai mare de un opcode) specifica, de obicei, o operație: instrucțiuni rând 0x0 sunt în mare parte operații de adăugare; instrucțiuni rând 0x2 sunt în mare parte operații de scădere, și așa mai departe.

dacă ne uităm la rândul 0x1, putem vedea că coloanele 0x0 și 0x1 sunt instrucțiuni RLC, iar coloanele 0x2 până la 0x9 sunt instrucțiuni ADC. Deci, putem proiecta un ALU care ia un ciugulit ca intrare (ciugulitul mai mare din opcode) și îl decodează în consecință. În timp ce acest lucru ar funcționa pentru coloanele 0x2 până la 0X9, am avea nevoie de o altă abordare pentru primele două coloane.

de aceea am ajuns să scriu două unități: una ALU care se concentrează pe majoritatea instrucțiunilor aritmetice și logice; și o a doua unitate (unitatea logică 2 sau LU2) care efectuează alte operații prezentate în coloanele 0x0 și 0x1 (nu toate operațiile văzute pe acele coloane sunt efectuate de LU2). Codurile de operare atât pentru Alu, cât și pentru LU2 au fost alese pentru a se potrivi rândurilor opcode prezentate în Figura 3.

un alt detaliu important este că toate instrucțiunile din aceeași coloană și grup au aceeași dimensiune în octeți, astfel pot fi decodate în aceeași secțiune de decodare.

designul decodor face uz de o mașină mare de stare finită (FSM) care avansează pe fiecare bifă de ceas. Fiecare instrucțiune începe în CPU_DECOD stat. Acest lucru este în cazul în care decodorul decodează de fapt opcodes, pregătește autobuze și semnale de sprijin interne, și pași pentru alte stări de execuție. Dintre toate aceste state, două sunt utilizate pe scară largă de o mulțime de instrucțiuni: CPU_OMA și CPU_OMA2. Poți ghici de ce? Dacă ați spus pentru că sunt legate de ALU și LU2, aveți absolut dreptate!

OMA este prescurtarea de la One Memory Access și este ultima stare pentru toate instrucțiunile legate de ALU (ADD, ADC, ADDX, ADCX, SUB, SBC, SUBX, SBCX, OR, ORX, AND, ANDX, XOR, XORX, CP, CPC, TCM, TCMX, TM, TMX și unele variante de LD și LDX). Pe de altă parte, CPU_OMA2 este ultima stare pentru toate instrucțiunile legate de LU2 (RLC, INC, DEC, DA, COM, RL, CLR, RRC, SRA, SRL, RR și SWAP).

acum, să aruncăm o privire în interiorul statului CPU_DECOD. Vezi Figura 4.

figura 4. Stare CPU_DECOD.

în starea CPU_DECOD, putem vedea că are loc o mulțime de acțiuni. La început, unele variabile temporare sunt inițializate la o condiție implicită. Rețineți că NUM_BYTES este foarte important, deoarece controlează câți octeți au fost consumați de decodorul de instrucțiuni. Valoarea sa este utilizată în ultima parte a acestei etape pentru a incrementa PC-ul (contorul de programe), pentru a avansa indicatorul de citire a cozii și pentru a scădea numărul de octeți disponibili în coadă.

în urma secțiunii de inițializare, putem vedea secțiunea de procesare a întreruperii. Este responsabil pentru detectarea oricăror întreruperi în așteptare și pregătește procesorul în consecință. Voi acoperi acest lucru în secțiunea următoare.

blocul real de decodare a instrucțiunilor verifică dacă un mod de consum redus nu este activ și, de asemenea, dacă modul depanator este oprit (TOCCR.DBGMODE = 0). Sau, în modul de depanare, a fost emisă o comandă de depanare cu un singur pas (TOCCR.DBGMODE = 1 și toc.SINGLE_STEP = 1). Apoi verifică octeții disponibili în coadă și continuă cu decodarea.

unele instrucțiuni (mai ales cele singlebyte) sunt finalizate în starea CPU_DECOD, în timp ce altele au nevoie de mai multe stări până când sunt complet finalizate.

rețineți că unele instrucțiuni decodare poate face uz de mai multe funcții și proceduri scrise special pentru FPz8:

  • DATAWRITE-această procedură pregătește autobuze pentru o operație de scriere. Se selectează dacă destinația este un SFR intern, un SFr extern, sau o locație de utilizator RAM.
  • DATAREAD — aceasta este o funcție reciprocă pentru DATAWRITE. Este folosit pentru a citi o adresă sursă și alege automat dacă este un SFR intern, un SFr extern sau o locație RAM a utilizatorului.
  • CONDITIONCODE — utilizat pentru instrucțiuni condiționale (cum ar fi JR și JP). Este nevoie de un cod de stare pe patru biți, îl testează și returnează rezultatul.
  • ADDRESSER4, ADDRESSER8 și ADDRESSER12 — aceste funcții returnează o adresă de 12 biți dintr-o sursă de patru, opt sau 12 biți. Ei folosesc conținutul registrului RP pentru a genera adresa finală pe 12 biți. ADDRESSER8 și ADDRESSER12 verifică, de asemenea, orice mod de adresare scăpat.
  • ADDER16 — acesta este un sumator de 16 biți pentru calcularea adresei offset. Este nevoie de un operand semnat pe opt biți, semnul îl extinde, îl adaugă la adresa pe 16 biți și returnează rezultatul.
  • ALU și LU2 — acestea au fost discutate anterior și efectuează majoritatea operațiilor aritmetice și logice.

întreruperea procesării

așa cum am spus mai devreme, eZ8 are un controler de întrerupere vectorizat cu prioritate programabilă. La început, am crezut că această secțiune nu va fi atât de dificilă, deoarece întreruperile nu sunt mari, nu? Ei bine, când am început să-mi dau seama cum să fac toate sarcinile necesare (salvarea contextului, vectorizarea, gestionarea priorităților etc.), Mi-am dat seama că va fi mai greu decât am crezut prima dată. După câteva ore, am venit cu designul actual.

sistemul de întrerupere al FPz8 a ajuns să fie simplu. Are opt intrări (INT0 până la INT7); o activare globală de întrerupere (bit IRQE situat în registrul IRQCTL); două registre pentru setarea priorității (IRQ0ENH și IRQ0ENL); și un registru pentru Steaguri de întrerupere (IRQ0). Designul folosește un lanț if imbricat care generează o adresă vectorială la detectarea unui eveniment de întrerupere cu privire la o întrerupere activată.

Figura 5 prezintă o vizualizare comprimată a sistemului de întrerupere. Notă există o primă declarație IF cu un simbol ATM_COUNTER. Acesta este un contor simplu utilizat de instrucțiunea ATM (dezactivează întreruperile pentru trei cicluri de instrucțiuni, permițând operații atomice).

Figura 5. Sistemul de întrerupere FPz8.

un ultim comentariu privind întreruperile: Eșantioanele de înregistrare a pavilionului de întrerupere (IRQ0) întrerup intrările la fiecare margine în creștere a ceasului sistemului. Există, de asemenea, două variabile tampon (IRQ0_LATCH și OLD_IRQ0) care stochează starea curentă și ultima a steagurilor. Acest lucru permite detectarea marginilor de întrerupere și, de asemenea, sincronizează intrările externe cu ceasul intern (FPGA-urile nu funcționează bine cu semnalele interne asincrone).

depanator On-Chip

aceasta este probabil cea mai tare caracteristică a acestui softcore, deoarece permite un mediu de dezvoltare integrat comercial (IDE; ZDS-ii de la Zilog) pentru a comunica, programa și depana software-ul care rulează pe FPz8. Depanatorul on-chip (TOC) este compus dintr-un UART cu capacitate autobaud și un procesor de comandă atașat la acesta. UART efectuează comunicarea serială cu un PC gazdă și livrează comenzi și date către mașina de stare a depanatorului care procesează comenzile de depanare (debugger command processing FSM se află în interiorul stării CPU_DECOD).

figura 6. Debugger On-chip UART (rețineți sincronizatorul DBG_RX).

designul meu toc implementează aproape toate comenzile disponibile pe hardware-ul real, cu excepția celor legate de memoria de date (comenzile de depanare 0x0C și 0x0D); contorul de execuție citit (0x3); și memoria programului citit CRC (0x0E).

un lucru pe care aș dori să subliniez este este nevoie de îngrijire atunci când se ocupă cu semnale asincrone în interiorul FPGA. Primul meu design nu a cont de faptul că în timp ce procesarea semnalului de intrare DBG_RX. Rezultatul a fost absolut ciudat. Designul meu a funcționat perfect în simulare. L-am descărcat într-un FPGA și am început să joc cu interfața serială de depanare utilizând un terminal serial (placa mea FPGA are un convertor serial-USB încorporat).

spre surprinderea mea, în timp ce de cele mai multe ori puteam trimite cu succes comenzi și primi rezultatele așteptate, uneori designul pur și simplu îngheța și nu mai răspundea. O resetare soft ar face lucrurile să revină la funcționarea corectă, dar asta m-a intrigat. Ce se întâmpla?

după o mulțime de teste și unele Googling, mi-am dat seama că a fost posibil legată de marginile asincrone ale semnalului de intrare serial. Apoi am inclus un zăvor în cascadă pentru a sincroniza semnalul cu ceasul meu intern și toate problemele au dispărut! Acesta este un mod greu de a învăța că trebuie să sincronizați întotdeauna semnalele externe înainte de a le alimenta într-o logică complexă!

trebuie să spun că depanarea și rafinarea codului depanatorului a fost cea mai grea parte a acestui proiect; mai ales pentru că interacționează cu toate celelalte subsisteme, inclusiv autobuzele, decodorul și coada de instrucțiuni.

sintetizarea și testarea

odată compilat complet (am folosit Quartus II V9.1 sp2), nucleul FPz8 a folosit 4.900 de elemente logice, 523 registre, 147.456 biți de memorie pe cip și un multiplicator încorporat pe nouă biți. În general, FPz8 utilizează 80% din resursele disponibile ale EP4CE6. Deși acest lucru este mult, există încă aproximativ 1.200 de elemente logice disponibile pentru periferice (cronometrul meu simplu pe 16 biți adaugă până la aproximativ 120 de elemente logice și 61 de registre). Se potrivește chiar și pe cel mai mic Cyclone IV FPGA — EP4CE6 — care este cel montat pe placa mini low cost pe care am folosit-o aici (Figura 7).

figura 7. Altera Cyclone IV EP4CE6 mini bord.

caracteristicile mini board (împreună cu dispozitivul EP4CE6): o memorie de configurare serială EPCS4 (montată pe partea de jos); un cip Convertor Serial-USB FTDI, precum și un modul oscilator de cristal de 50 MHz; unele butoane; LED-uri; și anteturi de pini pentru a accesa pinii FPGA. Nu există un USB-Blaster integrat (pentru programarea FPGA), dar pachetul pe care l-am cumpărat a inclus și un dongle de programare extern.

în ceea ce privește testele din lumea reală, este inutil să spun că FPz8 nu a funcționat prima dată! După ce m-am gândit puțin și am citit mesajele de ieșire ale compilatorului, mi-am dat seama că este probabil o problemă de sincronizare. Aceasta este o dilemă foarte frecventă atunci când proiectăm cu logică programabilă, dar, deoarece acesta a fost al doilea design FPGA vreodată, nu I-am acordat suficientă atenție.

verificând mesajele de analiză a sincronizării, am putut vedea un avertisment că ceasul maxim ar trebui să fie în jur de 24 MHz. La început, am încercat să folosesc un divizor-by-2 pentru a genera un ceas CPU 25 MHz, dar nu a fost fiabil. Apoi am folosit un divizor-cu-3. Totul a început să funcționeze perfect!

de aceea FPz8 rulează în prezent la 16.666 MHz. Este posibil să se atingă viteze mai mari utilizând unul dintre PLL-urile interne pentru a multiplica/împărți ceasul principal pentru a obține un ceas rezultat mai mic de 24 MHz, dar mai mare de 16,666 MHz.

programarea și depanarea

utilizarea FPz8 este foarte simplă și directă. Odată ce designul este descărcat în FPGA, procesorul va începe să ruleze orice program încărcat în memorie. Puteți furniza un fișier hex și puteți utiliza Managerul plug-in MegaWizard pentru a schimba fișierul de inițializare a memoriei programului. În acest fel, codul aplicației dvs. va începe să ruleze în urma unui semnal de resetare.

puteți utiliza IDE Zilog ZDS-II pentru a scrie codul de asamblare sau C și pentru a genera fișierele hex necesare (de obicei selectez Z8F1622 ca dispozitiv țintă, deoarece are și 2 KB de memorie RAM și 16 KB de memorie de program). Datorită depanatorului on-chip, este de asemenea posibil să utilizați IDE-ul ZDS-II pentru a descărca codul pe FPz8 folosind o conexiune de depanare serială (USB, în cazul nostru).

înainte de conectare, asigurați-vă că setările depanatorului sunt aceleași ca în Figura 8. Debifați opțiunea” Utilizați ștergerea paginii înainte de a clipi „și selectați” SerialSmartCable ” ca instrument de depanare curent. Nu uitați să verificați, de asemenea, dacă portul COM virtual al FTDI este selectat corect ca port de depanare (utilizați butonul de configurare). Puteți seta și viteza de comunicare dorită; 115.200 bps funcționează foarte bine pentru mine.

figura 8. Setări depanator.

rețineți că atunci când vă conectați la FPz8, IDE-ul ZDS-II va afișa un mesaj de avertizare care vă informează că dispozitivul țintă nu este același cu proiectul. Asta se întâmplă pentru că nu am implementat unele zone de memorie ID. Ignorați avertismentul și continuați cu sesiunea de depanare.

odată ce codul este descărcat cu succes, puteți porni aplicația (butonul GO), instrucțiuni pas, inspecta sau edita registre, setați puncte de întrerupere, etc. Ca și în cazul oricărui alt depanator bun, puteți, de exemplu, să selectați registrul PAOUT (sub grupul porturi) și chiar să schimbați starea LED-urilor conectate la PAOUT.

câteva exemple simple de cod C pot fi găsite în descărcări.

rețineți că FPz8 are o memorie de program volatilă. Astfel, orice program descărcat la acesta se pierde atunci când FPGA este oprit.

închiderea

acest proiect mi-a luat câteva săptămâni pentru a finaliza, dar a fost încântător să cercetez și să proiectez un nucleu de microcontroler.

sper că acest proiect poate fi util pentru oricine dorește să învețe despre elementele de bază de calcul, microcontrolere, programare încorporată și/sau VHDL. Cred că – dacă este asociat cu o placă FPGA cu costuri reduse — FPz8 poate oferi un instrument fantastic de învățare (și predare). Distracție plăcută! NV

CEFET-PR:
www.utfpr.edu.br
ScTec:
www.sctec.com.br
HCS08 dezlănțuit:
https://www.amazon.com/HCS08-Unleashed-Designers-Guide-Microcontrollers/dp/1419685929
Zilog eZ8 CPU Manual (UM0128):
www.zilog.com/docs/UM0128.pdf
Zilog Z8F64xx Product Specification (PS0199):
www.zilog.com/docs/z8encore/PS0199.pdf
Zilog ZDS II IDE User Manual (UM0130):
www.zilog.com/docs/devtools/UM0130.pdf
Zilog ZDS-II Software Download:
https://www.zilog.com/index.php?option=com_zcm&task=view&soft_id=7&Itemid=74
Zilog Microcontroller Product Line:
http://zilog.com/index.php?option=com_product&task=product&businessLine=1&id=2&parent_id=2&Itemid=56
Project Files available at:
https://github.com/fabiopjve/VHDL/tree/master/FPz8
FPz8 at Opencores.org:
http://opencores.org/project,fpz8

Lasă un răspuns

Adresa ta de email nu va fi publicată.