denne artikkelen er fokusert på å lære hvordan en microcontroller core er designet,og er ment for pedagogisk bruk. Vennligst besøk www.zilog.com og sjekk produsentens produktlinje for å velge en mikrokontroller som passer dine prosjektbehov (fra åtte-bit Z8 Encore! og eZ80 Acclaims til 32-bit ARM Cortex-M3 basert ZNEO32! som inkluderer avanserte motorstyringsfunksjoner).
min kjærlighetsaffære med mikrokontrollere og mikroprosessorer begynte tilbake i 1988 da jeg jobbet mot en teknisk grad VED CEFET-PR (en Fireårig Brasiliansk videregående/teknisk skole og universitet i Curitiba). Jeg begynte med å lære det grunnleggende mens jeg utforsket den klassiske Zilog Z-80 (Figur 1a).
FIGUR 1A. Zilog Z-80A(høflighet Av Wikimedia Commons).
Spol frem gjennom en karriere med programmering som inkluderte redigering av noen bøker om mikrokontroller programmering (se Ressurser), starte et lite designhus (ScTec), og fullføre et etterutdanningsprogram VED CEFET-SC (et Annet Brasiliansk universitet i Florianopolis). Dette var i 2008, da jeg hadde mer kontakt med programmerbar logikk og VHDL og min nysgjerrighet var toppet. År senere i 2016 fant jeg et veldig rimelig fpga-sett (Field-Programmable Gate Array) og bestemte meg for å gi det en sjanse, og begynte å lære mer OM FPGA-teknologi.
Hva ville være bedre enn å designe en softcore for å lære MER OM VHDL (VHSIC hardware description language), Fpga-Er og mikroprosessorkjerner selv? Jeg endte opp med å velge en moderne z-80 slektning: Zilog Z8 Encore! (aka, eZ8; Figur 1b).
FIGUR 1b.Zilog eZ8.
Det er en åtte-bits mikrokontrollerkjerne med et enkelt, men kraftig instruksjonssett og en veldig fin on-chip debugger. Med sin lette IDE (integrated development environment) og gratis ANSI c-kompilator, er det et utmerket prosjekt for å lære (og også lære) om innebygde systemer.
før du dykker inn i dypet av kjerneoperasjonen, VHDL og FPGAs, la Oss ta et blikk På Zilog Z8 Encore! funksjon.
FIGUR 1C. FPz8 på EN FPGA.
Zilog Z8 Encore!
eZ8 er en åtte-biters mikrokontrollerfamilie basert På Zilogs vellykkede Z8-familie og på den store Z-80-arven. Den har En Harvard cisc-maskin med opptil 4096 byte RAM (filregister og spesialfunksjonsregistre), opptil 64 KB programminne (vanligvis Flashminne) og opptil 64 KB dataminne (RAM). EZ8 kjernen inkluderer også en vektorisert avbryte kontrolleren med programmerbar prioritet og en on-chip debugger som kommuniserer med vertsmaskinen ved hjelp av asynkron seriell kommunikasjon. Disse mikrokontrollene er fullpakket med et veldig fint perifert sett, alt fra allsidige 16-bits timere til motorstyringstimere, fra flere Uarts (IrDA ready) TIL USB-enheter, og mye mer (besøk www.zilog.com for å sjekke hele produktlinjen).
en viktig funksjon i eZ8 programmering modellen er mangelen på en fast akkumulator. I stedet kan noen av DE 4,096 MULIGE RAM-adressene fungere som akkumulatorer. CPU behandler sin VIKTIGSTE RAM (filen og SFRs — special function registers-area) som et stort sett MED CPU registre. FOR å oppnå DET, ER RAM delt inn i registergrupper(det er 256 grupper med 16 arbeidsregistre hver). En instruksjon fungerer vanligvis innenfor en enkelt arbeidsregistergruppe, som velges AV EN SFR som heter RP (register pointer). Merk at alle SFRs er plassert på den siste SIDEN AV RAM (adresser som starter fra 0xF00 opp til 0xFFF).
når det gjelder instruksjonssettet, er det 83 forskjellige instruksjoner delt inn i to opcode-sider. Det består av vanlige instruksjoner for grunnleggende operasjoner som addisjon, subtraksjon, logiske operasjoner, data manipulasjon instruksjoner, skiftende instruksjoner, endring-av-flyt instruksjoner, noen 16-bits instruksjoner, bit testing og manipulasjon, 8×8 multiplisere, etc.
programminneområdet er organisert slik at de første adressene er dedikert til spesielle formål. Adresser 0x0000 og 0x0001 er dedikert til konfigurasjonsalternativene; adresser 0x0002 og 0x0003 lagrer nullstillingsvektoren; og så videre. Tabell 1 viser programminneorganisasjon.
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.
Noen enheter har også et ekstra datarom (opptil 65 536 adresser) som bare kan nås ved hjelp AV lde/LDEI-instruksjoner. Dette området kan brukes til å lagre mindre brukte data (som lesing/skriving til det er tregere ENN RAM/SFR-området).
FPz8
den første implementeringen Av FPz8 bruker en svært konservativ og hardwired designtilnærming med to hovedbusser: en for programminne og en annen for registerminne. Da jeg valgte å ikke inkludere et dataminneområde, blir ikke lde / LDEI-instruksjonene implementert.
programminnebussene består av en 16-biters instruksjonsadressebuss (iab), en åtte-biters instruksjonsdatabuss (IDB for lesing av data fra programminne), en åtte-biters instruksjonsdatabuss (IWDB for skriving av data til programminne) og ET pgm_wr-signal som styrer skriving til programminne. FPz8 inkluderer 16 384 byte programminne implementert ved hjelp av synkron blokk RAM (som betyr at programminneinnholdet går tapt når enheten er slått av).
de fem registerområdebussene består av tre for filregisterområdet (BRUKER RAM), og ytterligere to dedikert til spesielle funksjonsregistre. Det er en hoved 12-bit file register address bus (FRAB), en åtte-bit file register input data bus (FRIDB), en åtte-bit file register output data bus (FRODB), en åtte-bit register input data bus (RIDB), og til slutt en åtte-bit register output data bus (RODB) for å skrive Inn SFRs. FPz8 inkluderer 2048 byte bruker RAM-minne implementert ved hjelp av synkron blokk RAM.
Figur 2 viser et blokkdiagram over FPz8; DU kan se CPU, to minneenheter (en for programlagring og den andre for datalagring), og også en ekstern timermodul.
FIGUR 2. FPz8 blokkdiagram.
Merk at Jeg ikke bruker toveis busser for eventuelle sammenkoblinger i dette prosjektet. Enveis busser er enklere å bruke, selv om de er mindre plassbesparende.
vhdl-beskrivelsen Av FPz8 er stor Og litt kompleks, så jeg skal dele operasjonen i noen moduler for å lette forståelsen:
- Instruction queueing engine
- instruction queueing Engine
- Avbryt behandling
- Debugger
Instruction Queueing Engine
Henteinstruksjoner er en primær OPPGAVE for ENHVER CPU. Fpz8s Harvard-arkitektur muliggjør samtidig henting og datatilgang (på grunn av separate busser for instruksjon og data). DET betyr AT CPU kan hente en ny instruksjon mens en annen leser eller skriver inn i dataminnet.
eZ8 har en variabel lengde instruksjon ord (instruksjon lengde varierer fra en byte opp til fem byte); noen instruksjoner er lange, men kjører raskere enn andre. På den måten HAR EN BRK-instruksjon en lengde på en byte og går i to sykluser, mens EN LDX IM, ER1 er fire byte lang og går i to klokkesykluser.
så hvordan kan vi dekode alle disse instruksjonene? Med en instruksjonskø; det vil si en mekanisme som fortsetter å hente byte fra programminnet og lagre dem i en åtte-byte-array:
if (CAN_FETCH=’1′) og deretter
if (IQUEUE.FETCH_STATE=F_ADDR) så
FETCH_ADDR := PC;
IAB < = PC;
IQUEUE.WRPOS: = 0;
IQUEUE.RDPOS: = 0;
IQUEUE.CNT := 0;
IQUEUE.FETCH_STATE: = F_READ;
annet
hvis (IQUEUE.FULL= ‘0’) så
IQUEUE.KØ(IQUEUE.WRPOS): = IDB;
FETCH_ADDR: = FETCH_ADDR + 1;
IAB < = FETCH_ADDR;
IQUEUE.WRPOS: = IQUEUE.WRPOS + 1;
IQUEUE.CNT: = IQUEUE.CNT + 1;
avslutt hvis;
avslutt hvis;
avslutt hvis;
hvis (IQUEUE .CNT = 7) DERETTER IQUEUE.FULL:= ‘1’; annet IQUEUE.FULL:=’0′;
slutt hvis;
OPPFØRING 1. Instruksjon kø motor.
Henting styres av et hovedaktiveringssignal (CAN_FETCH) som kan deaktiveres i noen spesielle tilfeller(avbryt behandling, AV LDC/LDCI instruksjoner eller debugger tilgang). Det er også en struktur (IQUEUE) som lagrer flere interne parametere (hente tilstand, lese og skrive pekere, kø array selv, en teller, og en full indikator).
køtelleren (cnt) brukes til å identifisere antall byte som er tilgjengelige for bruk (lesing) i køen. Dekodertrinnet bruker dette nummeret til å kontrollere at ønsket antall byte for instruksjonen allerede er tilgjengelig i køen.
Instruksjonsdekoding
det er her den faktiske magien skjer. Instruksjonsdekoderen leser opkoder fra instruksjonskøen og oversetter dem til tilsvarende operasjoner.
Instruksjonsdekoderdesign startet med å finne ut forholdet mellom alle instruksjonene og adresseringsmodusene. Ved første øyekast er det lett å se at noen instruksjoner (Figur 3) er gruppert etter kolonne (DJNZ, JR cc,X, LD r1,IM, JP cc,DA og INC r1). Dekoding AV EN INC r1-instruksjon er enkel: på disse enkeltbyteinstruksjonene spesifiserer den høye nibble kilden / destinasjonsregisteret, og den nedre nibble spesifiserer instruksjonen selv (0xE).
FIGUR 3. Opcodes av grupper.
de fleste instruksjoner kan klassifiseres i henhold til noen grunnleggende regler:
- Kolonner (den nedre nibble av en opcode) angir vanligvis en adresseringsmodus: Kolonne 0x9 instruksjoner, for eksempel, for det meste bruke IM, er1 adressering modus og er fire byte lang (den andre byte er umiddelbar operand og de to siste byte er målet utvidet adresse).
- Rader (jo høyere nibble av en opcode) angir vanligvis en operasjon: Rad 0x0 instruksjoner er for det meste addisjonsoperasjoner; rad 0x2 instruksjoner er for det meste subtraksjonsoperasjoner, og så videre.
hvis vi ser på rad 0x1, kan vi se at kolonner 0x0 og 0x1 er rlc-instruksjoner, og kolonner 0x2 opp til 0x9 ER adc-instruksjoner. Så, vi kan designe EN ALU som tar en nibble som input(jo høyere nibble fra opcode) og dekoder den tilsvarende. Mens dette ville fungere for kolonner 0x2 til 0x9, ville vi trenge en annen tilnærming til de to første kolonnene.
derfor endte jeg med å skrive to enheter: en ALU som konsentrerer seg om de fleste aritmetiske og logiske instruksjoner; og en annen enhet (Logisk Enhet 2 ELLER LU2) som utfører andre operasjoner vist i kolonner 0x0 og 0x1 (ikke alle operasjoner sett på disse kolonnene utføres AV LU2). Operasjonskodene FOR BÅDE ALU og LU2 ble valgt for å matche opcode-radene vist i Figur 3.
En annen viktig detalj er at alle instruksjoner i samme kolonne og gruppe har samme størrelse i byte, og dermed kan dekodes i samme dekoderseksjon.
dekoderen design gjør bruk av en stor endelig tilstand maskin (FSM) som fremskritt på hver klokke tick. Hver instruksjon starter I CPU_DECOD stat. Det er her dekoderen faktisk dekoder opcodes, forbereder busser og interne støttesignaler, og trinn til andre utførelsestilstander. Blant alle disse statene er to mye brukt av mange instruksjoner: CPU_OMA og CPU_OMA2. Kan du gjette hvorfor? Hvis du sa fordi DE er relatert TIL ALU OG LU2, har du helt rett!
OMA er kort For One Memory Access, og det er den siste tilstanden for ALLE alu-relaterte instruksjoner (ADD, ADC, ADDX, ADCX, SUB, SBC, SUBX, SBCX, ELLER ORX, ANDX, XOR, XORX, CP, CPC, TCM, TCMX, TM, TMX, og noen varianter AV LD og LDX). PÅ den annen side ER CPU_OMA2 den siste tilstanden for ALLE LU2-relaterte instruksjoner (RLC, INC, DEC, DA, COM, RL, CLR, RRC, SRA, SRL, RR og SWAP).
Nå, la Oss ta en titt inne I CPU_DECOD-staten. Se figur 4.
FIGUR 4. CPU_DECOD tilstand.
INNENFOR CPU_DECOD-staten kan vi se at mye handling finner sted. I begynnelsen initialiseres noen midlertidige variabler til en standardbetingelse. LEGG merke TIL AT NUM_BYTES er svært viktig da den styrer hvor mange byte som ble konsumert av instruksjonsdekoderen. Verdien brukes i den siste delen av dette stadiet for å øke PCEN( programteller), fremme køen lesepekeren og redusere antall tilgjengelige byte i køen.
Etter initialiseringsdelen kan vi se avbruddsprosessdelen. Det er ansvarlig for å oppdage eventuelle ventende avbrudd og forbereder CPUEN tilsvarende. Jeg vil dekke dette i neste avsnitt.
den faktiske instruksjonsdekodingsblokken kontrollerer om en lav strømmodus ikke er aktiv, og også om feilsøkingsmodusen er slått av (OCDCR.DBGMODE = 0). Eller, mens i feilsøkingsmodus, ble en enkelt trinns feilsøkingskommando utstedt (OCDCR.DBGMODE = 1 OG OCD.SINGLE_STEP = 1). Den sjekker deretter de tilgjengelige byte i køen og fortsetter med dekoding.
noen instruksjoner (for det meste singlebyte-ene) er fullført i CPU_DECOD-staten, mens andre trenger flere stater til de er fullført.
Merk at noen instruksjon dekoding kan gjøre bruk av flere funksjoner og prosedyrer skrevet spesielt For FPz8:
- DATAWRITE-denne prosedyren forbereder busser for en skriveoperasjon. Den velger om målet er en intern SFR, en ekstern SFR, eller en BRUKER RAM plassering.
- DATAREAD — DETTE er en gjensidig funksjon FOR DATAWRITE. Den brukes til å lese en kildeadresse og velger automatisk om det er en intern SFR, en ekstern SFR, eller en BRUKER RAM plassering.
- BETINGELSESKODE — Brukes for betingede instruksjoner (FOR EKSEMPEL JR og JP). Det tar en fire-bit tilstand kode, tester det, og returnerer resultatet.
- ADRESSE4, ADRESSE8 OG ADRESSE12 – disse funksjonene returnerer en 12-biters adresse fra en fire -, åtte-eller 12-biters kilde. De bruker innholdet I rp-registeret til å generere den endelige 12-biters adressen. ADDRESSER8 OG ADDRESSER12 også sjekke for noen rømt adressering modus.
- ADDER16-Dette er en 16-bit adder for adresse offset beregning. Det tar en åtte-biters signert operand, sign utvider den, legger den til 16-biters adressen, og returnerer resultatet.
- ALU OG LU2 – Disse ble diskutert tidligere — og utfører de fleste aritmetiske og logiske operasjoner.
Avbruddsbehandling
som jeg sa før, har eZ8 en vectored interrupt controller med programmerbar prioritet. Først trodde jeg at denne delen ikke ville være så vanskelig fordi avbrudd ikke er så stor, ikke sant? Vel, da jeg begynte å finne ut hvordan jeg skal gjøre alle nødvendige oppgaver (lagre kontekst, vektorering, administrere prioriteringer, etc.), Skjønte jeg at det ville være tøffere enn jeg først trodde. Etter et par timer kom jeg opp med dagens design.
Fpz8s avbruddssystem endte med å være enkelt. Den har åtte innganger (INT0 TIL INT7); en global interrupt enable (IRQE bit ligger I IRQCTL register); to registre for prioritetsinnstilling (IRQ0ENH OG IRQ0ENL); og ett register for interrupt flags (IRQ0). Designet bruker en nestet IF-kjede som genererer en vektoradresse ved påvisning av en avbruddshendelse angående en aktivert avbrudd.
Figur 5 viser en komprimert visning av avbruddssystemet. Merk det er en første IF-setning med et symbol ATM_COUNTER. Dette er en enkel teller som brukes AV ATM-instruksjonen(den deaktiverer avbrudd for tre instruksjonssykluser, slik at atomoperasjoner).
FIGUR 5. FPz8 avbryte systemet.
En siste kommentar angående avbrudd: Interrupt flag register (IRQ0) prøver avbryter innganger hver stigende kant av systemklokken. DET er også to buffervariabler (IRQ0_LATCH og OLD_IRQ0) som lagrer nåværende og siste tilstand av flaggene. Dette gjør det mulig å avbryte kantdeteksjon og synkroniserer også de eksterne inngangene til den interne klokken (Fpgaer fungerer ikke bra med asynkrone interne signaler).
On-Chip Debugger
dette er trolig den kuleste funksjonen i denne softcore som det tillater et kommersielt integrert utviklingsmiljø (IDE; slik Som Zilogs ZDS-II) for å kommunisere, programmere og feilsøke programvare som kjører På FPz8. On-chip debugger (OCD) består av EN UART med autobaud-evne og en kommandoprosessor knyttet til den. UART utfører seriell kommunikasjon med en verts-PC, og leverer kommandoer og data til debugger state machine som behandler feilsøkingskommandoer (debugger command processing FSM er plassert inne I CPU_DECOD-tilstanden).
FIGUR 6. On-chip debugger UART (merk dbg_rx samtidighet).
MIN OCD-design implementerer nesten alle kommandoer som er tilgjengelige på den virkelige maskinvaren, bortsett fra de som er relatert til dataminne (feilsøkingskommandoer 0x0C og 0x0D); les runtime-telleren (0x3); OG les programminnet CRC (0x0E).
En ting jeg ønsker å fremheve er omsorg er nødvendig når du arbeider med asynkrone signaler inne Fpga. Mitt første design tok ikke hensyn til det mens du behandlet dbg_rx-inngangssignalet. Resultatet var helt rart. Mitt design hadde jobbet feilfritt i simulering. Jeg lastet den ned til EN FPGA og begynte å spille rundt med debug seriell grensesnitt ved hjelp av en seriell terminal (MIN fpga bord har en innebygd seriell-USB converter).
til min overraskelse, mens jeg mesteparten av tiden kunne sende kommandoer og motta de forventede resultatene, ville designen noen ganger bare fryse og slutte å svare. En myk tilbakestilling ville få ting til å gå tilbake til riktig drift, men det var spennende meg. Hva skjedde?
etter mange tester og Litt Googling fant jeg ut at det muligens var relatert til de asynkrone kantene til seriell inngangssignal. Jeg inkluderte da en kaskad lås for å synkronisere signalet til min interne klokke og alle problemene var borte! Det er en tøff måte å lære at du alltid må synkronisere eksterne signaler før du mater dem inn i kompleks logikk!
jeg må si at feilsøking og raffinering av debugger-koden var den vanskeligste delen av dette prosjektet; mest fordi det samhandler med alle de andre delsystemene, inkludert busser, dekoderen og instruksjonskøen.
Syntetisering Og Testing
når fullstendig kompilert (jeg brukte Quartus II v9.1 sp2), FPz8 kjernen brukt opp 4900 logiske elementer, 523 registre, 147 456 biter av on-chip minne, og en innebygd ni-bit multiplikator. Samlet sett bruker FPz8 80% AV EP4CE6S tilgjengelige ressurser. Selv om dette er mye, er det fortsatt noen 1200 logiske elementer tilgjengelig for eksterne enheter (min enkle 16-bits timer legger opp til rundt 120 logiske elementer og 61 registre). Den passer til og med på den minste Cyclone IV FPGA-EP4CE6-som er den som er montert på lavpris mini-kortet jeg brukte her (Figur 7).
FIGUR 7. Altera Cyclone IV EP4CE6 mini bord.
mini styret funksjoner (SAMMEN MED EP4CE6 enhet): EN EPCS4 seriell konfigurasjon minne (montert på undersiden); EN ftdi seriell-TIL-USB converter chip samt en 50 MHz krystall oscillator modul; noen knapper; Lysdioder; og pin overskrifter for å få TILGANG TIL FPGA pins. Det er ingen integrert USB-Blaster (FOR fpga programmering), men pakken jeg kjøpte inkluderte også en ekstern programmeringsdongle.
når det gjelder de virkelige verdenstestene, unødvendig å si, fungerte FPz8 ikke første gang! Etter å ha tenkt litt og lest kompilatorutgangsmeldinger, fant jeg ut at det var sannsynligvis et timingproblem. Dette er et veldig vanlig dilemma når du designer med programmerbar logikk, men da dette var mitt andre fpga-design noensinne, betalte jeg ikke nok oppmerksomhet til det.
Kontrollerer timinganalysemeldingene, jeg kunne se en advarsel om at maksimal klokke skal være rundt 24 MHz. Først prøvde jeg å bruke en divider-by-2 for å generere en 25 MHz CPU-klokke, men det var ikke pålitelig. Jeg brukte en divider-by-3. Alt begynte å fungere perfekt!
Derfor kjører FPz8 for tiden på 16.666 MHz. Det er mulig å oppnå høyere hastigheter ved å bruke en av de interne Pllene til å multiplisere / dele hovedklokken for å få en resulterende klokke lavere enn 24 MHz, men høyere enn 16.666 MHz.
Programmering Og Feilsøking
Bruk Av FPz8 Er veldig enkelt og greit. Når designet er lastet ned TIL FPGA, VIL CPUEN begynne å kjøre et program lastet i minnet. Du kan levere en hex-fil og bruke Megawizard Plug-in Manager for å endre programmet minne initialisering fil. På den måten vil programkoden din begynne å kjøre etter et tilbakestillingssignal.
Du kan bruke Zilog ZDS-II IDE til å skrive Assembly eller C-kode, og generere de nødvendige hex-filene (jeg velger VANLIGVIS Z8F1622 som målenheten min, da den også har 2 KB RAM og 16 KB programminne). Takket være on-chip debugger er DET også mulig Å bruke ZDS-II IDE til å laste ned kode Til FPz8 ved hjelp av en seriell feilsøkingstilkobling (USB, i vårt tilfelle).
før du kobler til, må du kontrollere at feilsøkingsinnstillingene er de samme som I Figur 8. Fjern merket for «Bruk side slett før blinkende» alternativet, og velg «SerialSmartCable» som gjeldende feilsøkingsverktøy. Ikke glem å også sjekke OM FTDIS virtuelle COM-port er riktig valgt som feilsøkingsport (bruk Setup-knappen). Du kan også angi ønsket kommunikasjonshastighet; 115,200 bps fungerer veldig bra for meg.
FIGUR 8. Debugger innstillinger.
Merk at NÅR DU kobler Til FPz8, VIL ZDS-II IDE vise en advarsel om at målenheten ikke er den samme som prosjektet. Det skjer fordi jeg ikke implementerte NOEN ID-minneområder. Bare ignorere advarselen og fortsett med feilsøkingsøkten.
når koden er lastet ned, kan du starte programmet (GÅ-knappen), trinninstruksjoner, inspisere eller redigere registre, sette stoppunkter, etc. Som med alle andre gode debugger, kan DU for eksempel velge PAOUT register (UNDER PORTS group) og til og med endre tilstanden Til Lysdiodene som er koblet TIL PAOUT.
noen enkle c-kodeeksempler finner du i nedlastingene.
bare husk at FPz8 har et flyktig programminne. Dermed er ethvert program lastet ned til det tapt når FPGA er slått av.
Lukking
dette prosjektet tok meg et par uker å fullføre, men Det var herlig å undersøke og designe en mikrokontrollerkjerne.
jeg håper dette prosjektet kan være nyttig for alle som ønsker å lære om grunnleggende databehandling, mikrokontrollere, innebygd programmering og / eller VHDL. Jeg tror at — hvis parret MED et LAVPRIS FPGA-brett-Kan FPz8 gi et fantastisk læringsverktøy (og undervisningsverktøy). Ha det gøy! NV
CEFET-PR:
www.utfpr.edu.br
ScTec:
www.sctec.com.br
HCS08 Sluppet Løs:
https://www.amazon.com/HCS08-Unleashed-Designers-Guide-Microcontrollers/dp/1419685929
zilog eZ8 CPU Manuell (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