dit artikel is gericht op het leren hoe een Microcontroller core is ontworpen, en is alleen bedoeld voor educatief gebruik. Bezoek A. U. B. www.zilog.com en controleer de productlijn van de fabrikant om een microcontroller te selecteren die past bij uw projectbehoeften (van acht-bit Z8 toegiften! en eZ80 juicht toe aan de 32-bit ARM Cortex-M3 gebaseerde ZNEO32! inclusief geavanceerde motorbesturingsmogelijkheden).Mijn liefdesrelatie met microcontrollers en microprocessors begon in 1988 toen ik werkte aan een technisch diploma aan CEFET-PR (een vierjarige Braziliaanse middelbare/technische school en Universiteit gevestigd in Curitiba). Ik begon met het leren van de basis tijdens het verkennen van de klassieke Zilog Z-80 (figuur 1a).
figuur 1A. de Zilog Z-80A (met dank aan Wikimedia Commons).
Fast forward door een carrière van programmeren, waaronder het schrijven van enkele boeken over microcontroller programmeren( zie bronnen), het starten van een klein ontwerphuis (ScTec), en het afronden van een post-afstudeerprogramma aan CEFET-SC (een andere Braziliaanse universiteit in Florianopolis). Dit was in 2008, toen ik meer contact had met programmable logic en VHDL en mijn nieuwsgierigheid piekte. Jaren later, in 2016, vond ik een zeer betaalbare FPGA (Field-Programmable Gate Array) kit en besloot om het een kans te geven, en begon meer te leren over FPGA technologie.
Wat is er beter dan het ontwerpen van een softcore om meer te leren over VHDL (vhsic hardware description language), FPGA ‘ s en microprocessorkernen zelf? Uiteindelijk koos ik voor een moderne Z-80 familielid: de Zilog Z8 toegift! (ook bekend als eZ8; figuur 1b).
figuur 1B. Zilog eZ8.
het is een acht-bit microcontroller kern met een eenvoudige-maar krachtige-instructie set en een zeer mooie on-chip debugger. Met zijn lichtgewicht IDE (integrated development environment) en gratis ANSI C compiler, is het een uitstekend project om te leren (en ook te leren) over embedded systemen.
voordat we duiken in de diepte van de kern operatie, VHDL, en FPGA’ s, laten we een kijkje nemen op de Zilog Z8 Encore! functie.
figuur 1C. FPz8 op een FPGA.
Zilog Z8 Encore!De eZ8 is een acht-bit microcontroller familie gebaseerd op Zilog ‘ s succesvolle Z8 familie en op de grote Z-80 erfgoed. Het beschikt over een Harvard CISC machine met maximaal 4.096 bytes van RAM (file register en speciale functie registers gebied), maximaal 64 KB van programmageheugen (meestal Flash-geheugen), en maximaal 64 KB van gegevensgeheugen (RAM). De eZ8-kern omvat ook een vectored onderbreek controlemechanisme met programmeerbare prioriteit en een on-spaander debugger die met de hostcomputer communiceert gebruikend asynchrone periodieke mededeling. Deze microcontrollers zitten boordevol een zeer mooie randapparatuur, variërend van veelzijdige 16-bit timers tot motor control timers, van meerdere UARTs (IrDA ready) tot USB-apparaten, en nog veel meer (bezoek www.zilog.com om de volledige productlijn te controleren).
een belangrijk kenmerk van het eZ8-programmeermodel is het ontbreken van een vaste accumulator. In plaats daarvan kan elk van de 4.096 mogelijke RAM-adressen als accumulator werken. De CPU behandelt zijn belangrijkste RAM (het dossier en SFRs-speciale functieregisters-gebied) als een grote reeks CPU registers. Om dat te bereiken wordt RAM opgesplitst in registergroepen (er zijn 256 groepen van elk 16 werkregisters). Een instructie werkt meestal binnen een enkele werk register groep, die wordt geselecteerd door een SFR genaamd RP (register pointer). Merk op dat alle SFRs zich op de laatste pagina van het RAM bevinden (adressen vanaf 0xF00 tot 0xFFF).
met betrekking tot de instructieset zijn er 83 verschillende instructies opgesplitst in twee opcode-pagina ‘ s. Het bevat gebruikelijke instructies voor basisbewerkingen zoals optellen, aftrekken, logische bewerkingen, instructies voor gegevensmanipulatie, schakelinstructies, instructies voor verandering van stroom, enkele 16-bits instructies, bit testen en manipuleren, 8×8 vermenigvuldigen, enz.
het geheugengebied van het programma is zo georganiseerd dat de eerste adressen voor speciale doeleinden zijn bestemd. Adressen 0x0000 en 0x0001 zijn gewijd aan de configuratie-opties; adressen 0x0002 en 0x0003 slaan de reset vector; en ga zo maar door. Tabel 1 toont de organisatie van het programmageheugen.
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.
sommige apparaten bevatten ook een tweede gegevensruimte (tot 65.536 adressen) die alleen toegankelijk is met behulp van LDE/LDEI-instructies. Dit gebied kan worden gebruikt om minder gebruikte gegevens op te slaan (aangezien het lezen/schrijven ervan langzamer is dan het RAM/SFR-gebied).
FPz8
de eerste implementatie van FPz8 maakt gebruik van een zeer conservatieve en hardwired ontwerpbenadering met twee hoofdbussen: een voor programmageheugen en een andere voor registergeheugen. Omdat ik ervoor koos om geen gegevensgeheugengebied op te nemen, zijn de LDE/LDEI instructies Niet geïmplementeerd.
de programmageheugenbussen bestaan uit een 16-bit instruction address bus( IAB), een 8-bit instruction data bus (IDB voor het lezen van gegevens uit het programmageheugen), een 8-bit instruction write data bus (IWDB voor het schrijven van gegevens naar het programmageheugen), en een pgm_wr signaal dat het schrijven naar het programmageheugen regelt. FPz8 omvat 16.384 bytes programmageheugen geà mplementeerd met behulp van synchrone blok RAM (wat betekent dat de inhoud van het programmageheugen verloren gaat wanneer het apparaat wordt uitgeschakeld).
de vijf registerbussen bestaan uit drie voor het file register area (user RAM) en nog eens twee voor speciale functieregisters. Er is een main 12-bit file register address bus (FRAB), een acht-bit file register input data bus (FRIDB), een acht-bit file register output data bus (FRODB), een acht-bit register input data bus (RIDB), en tot slot een acht-bit register output data bus (RODB) voor het schrijven naar SFRs. De FPz8 bevat 2,048 bytes van de gebruiker RAM geheugen geà mplementeerd met behulp van synchrone blok RAM.
Figuur 2 toont een blokschema van de FPz8; u kunt de CPU zien, twee geheugeneenheden (een voor programmaopslag en de andere voor gegevensopslag), en ook een externe timermodule.
figuur 2. Fpz8 blokdiagram.
merk op dat ik geen bidirectionele bussen gebruik voor interconnecties in dit project. Unidirectionele bussen zijn eenvoudiger te gebruiken, hoewel ze minder ruimtebesparend zijn.
de VHDL-beschrijving van de FPz8 is groot en een beetje complex, dus ik ga de werking ervan opsplitsen in enkele modules om het begrip te vergemakkelijken:
- Instruction queuing engine
- Instruction decoding
- Interrupt processing
- Debugger
Instruction Queuing Engine
instructies ophalen is een primaire taak voor elke CPU. De Harvard-architectuur van de Fpz8 maakt gelijktijdig ophalen en toegang tot gegevens mogelijk (door aparte bussen voor instructie en gegevens). Dat betekent dat de CPU een nieuwe instructie kan ophalen terwijl een ander leest of schrijft in het gegevensgeheugen.
het eZ8 heeft een instructiewoord met variabele lengte (instructielengte varieert van één byte tot vijf bytes); sommige instructies zijn lang, maar lopen sneller dan anderen. Op die manier heeft een BRK instructie een lengte van één byte en loopt in twee cycli, terwijl een LDX IM, ER1 vier bytes lang is en in twee klokcycli draait.
dus, hoe kunnen we met succes al deze instructies decoderen? Met een instructiewachtrij; dat wil zeggen, een mechanisme dat bytes uit het programmageheugen blijft ophalen en opslaat in een acht-byte array:
if (CAN_FETCH=’1′) dan
if (IQUEUE.FETCH_STATE = F_ADDR) dan
FETCH_ADDR: = PC;
IAB < = PC;
IQUEUE.WRPO ‘ S: = 0;
IQUEUE.RDPO ‘ S: = 0;
IQUEUE.CNT := 0;
IQUEUE.FETCH_STATE : = F_READ;
else
if (IQUEUE.Vol= “0”) dan
IQUEUE.WACHTRIJ (IQUEUE.WRPOS): = IDB;
FETCH_ADDR: = FETCH_ADDR + 1;
IAB <= FETCH_ADDR;
IQUEUE.WRPOS : = IQUEUE.WRPO ‘ S + 1;
IQUEUE.CNT: = IQUEUE.CNT + 1;
end if;
end if;
end if;
if (IQUEUE.CNT = 7) dan IQUEUE.FULL: = ‘1’; else IQUEUE.Volledig: = “0”;
end if;
LISTING 1. Instructiewachtrijmotor.
Fetching wordt bestuurd door een main enable signaal (CAN_FETCH) dat in sommige speciale gevallen kan worden uitgeschakeld (interrupt verwerking, door LDC/LDCI instructies of debugger toegang). Er is ook een structuur (IQUEUE) die verschillende interne parameters opslaat (fetching state, lees en schrijf pointers, queue array zelf, een teller, en een volledige indicator).
de wachtrijteller (CNT) wordt gebruikt om het aantal bytes te identificeren dat beschikbaar is voor gebruik (lezen) in de wachtrij. De decoder fase gebruikt dit nummer om te controleren of het gewenste aantal bytes voor de instructie al beschikbaar is in de wachtrij.
instructie decodering
Dit is waar de eigenlijke magie gebeurt. De instructiedecoder leest opcodes uit de instructiewachtrij en vertaalt ze naar overeenkomstige bewerkingen.
instructie decoder ontwerp begon met het uitzoeken van de relatie tussen alle instructies en adresseringsmodi. Op het eerste gezicht is het gemakkelijk te zien dat sommige instructies (Figuur 3) zijn gegroepeerd per kolom (DJNZ, JR cc, X,LD r1, IM,JP cc, DA,EN INC r1). Decoderen van een INC r1 instructie is eenvoudig: op deze single-byte instructies, de hoge nibble specificeert de bron / bestemming register en de lagere nibble specificeert de instructie zelf (0xE).
figuur 3. Opcodes per groep.
de meeste instructies kunnen volgens enkele basisregels worden ingedeeld:
- kolommen (de onderste Knabbel van een opcode) geven meestal een adresseringsmodus aan: Kolom 0x9 instructies, bijvoorbeeld, gebruiken meestal de IM, ER1 adresseringsmodus en zijn vier bytes lang (de tweede byte is de directe operand en de twee laatste bytes zijn het doel uitgebreide adres).
- rijen (de hogere Knabbel van een opcode) geven meestal een bewerking aan: Rij 0x0 instructies zijn meestal optelbewerkingen; rij 0x2 instructies zijn meestal aftrekken operaties, enzovoort.
als we naar Rij 0x1 kijken, kunnen we zien dat kolommen 0x0 en 0x1 RLC-instructies zijn, en kolommen 0x2 tot en met 0x9 ADC-instructies. Zo kunnen we een ALU ontwerpen die een knabbel als invoer neemt (de hogere Knabbel uit de opcode) en deze dienovereenkomstig decodeert. Hoewel dit zou werken voor kolommen 0x2 tot 0x9, zouden we een andere aanpak nodig hebben voor de eerste twee kolommen.
daarom heb ik uiteindelijk twee eenheden geschreven: een ALU dat zich concentreert op de meeste rekenkundige en logische instructies; en een tweede eenheid (logische eenheid 2, of LU2) die andere bewerkingen uitvoert die in kolommen 0x0 en 0x1 worden weergegeven (NIET alle bewerkingen die op die kolommen worden gezien worden uitgevoerd door LU2). De bedieningscodes voor zowel ALU als LU2 zijn gekozen om overeen te komen met de in Figuur 3 getoonde opcode-rijen.
een ander belangrijk detail is dat alle instructies binnen dezelfde kolom en groep dezelfde grootte hebben in bytes, dus kunnen worden gedecodeerd in dezelfde decoder sectie.
het decoderontwerp maakt gebruik van een grote eindige staatsmachine (FSM) die op elke klokteek vooruitgaat. Elke instructie start in de CPU_DECOD stat. Dit is waar de decoder daadwerkelijk decodeert de opcodes, bereidt bussen en interne ondersteunende signalen, en stappen naar andere uitvoering Staten. Van al deze toestanden, twee worden veel gebruikt door een heleboel instructies: CPU_OMA en CPU_OMA2. Kun je raden waarom? Als je zei omdat ze gerelateerd zijn aan ALU en LU2, heb je helemaal gelijk!
OMA is een afkorting voor One Memory Access en is de laatste status voor alle ALU-gerelateerde instructies (ADD, ADC, ADDX, ADCX, SUB, SBC, SUBX, SBCX, OR, ORX, ANDX, XOR, XORX, CP, CPC, TCM, TCMX, TM, TMX, en enkele varianten van LD en LDX). Aan de andere kant is CPU_OMA2 de laatste status voor alle LU2 gerelateerde instructies (RLC, INC, DEC, DA, COM, RL, CLR, RRC, SRA, SRL, RR en SWAP).
laten we nu eens een kijkje nemen in de CPU_DECOD status. Zie Figuur 4.
figuur 4. CPU_DECOD status.
binnen de CPU_DECOD status kunnen we zien dat er veel actie plaatsvindt. In het begin worden sommige tijdelijke variabelen geïnitialiseerd naar een standaardvoorwaarde. Merk op dat NUM_BYTES erg belangrijk is omdat het bepaalt hoeveel bytes werden verbruikt door de instructie decoder. De waarde ervan wordt gebruikt in het laatste deel van deze fase om de PC (programmateller) te verhogen, de leespinter van de wachtrij te versnellen en het aantal beschikbare bytes in de wachtrij te verminderen.
na de initialisatie sectie, kunnen we de interrupt processing sectie zien. Het is verantwoordelijk voor het opsporen van eventuele lopende interrupts en bereidt de CPU dienovereenkomstig. Ik zal dit in de volgende sectie behandelen.
het eigenlijke instructiedecoderingsblok controleert of een modus met laag vermogen niet actief is en ook of de debuggermodus uit is (OCDCR.DBGMODE = 0). Of, terwijl in debug-modus, een single step debug commando werd uitgegeven (OCDCR.DBGMODE = 1 en OCD.SINGLE_STEP = 1). Het controleert vervolgens de beschikbare bytes in de wachtrij en gaat verder met decoderen.
sommige instructies (meestal de enkelvoudige) worden binnen de CPU_DECOD-status ingevuld, terwijl andere meerdere statussen nodig hebben totdat ze volledig zijn voltooid.
merk op dat sommige instructie decodering gebruik kan maken van verschillende functies en procedures die speciaal zijn geschreven voor de FPz8:
- DATAWRITE – deze procedure bereidt bussen voor op een schrijfoperatie. Het selecteert of de bestemming een interne SFR, een externe SFR of een RAM-locatie van de gebruiker is.
- DATAREAD – dit is een wederkerige functie voor DATAWRITE. Het wordt gebruikt om een bronadres te lezen en kiest automatisch of het een interne SFR, een externe SFR of een RAM-locatie voor gebruikers is.
- CONDITIONCODE-gebruikt voor voorwaardelijke instructies (zoals JR en JP). Het neemt een vier-bits condition code, test het, en geeft het resultaat.
- ADDRESSER4, ADDRESSER8 en ADDRESSER12-deze functies retourneren een 12-bits adres van een 4-, 8-of 12-bits bron. Ze gebruiken de inhoud van het RP-register om het uiteindelijke 12-bit-adres te genereren. ADDRESSER8 en ADDRESSER12 controleren ook op een escaped addressing mode.
- ADDER16-dit is een 16-bit adder voor de berekening van de adresverschuiving. Het neemt een acht-bits ondertekende operand, teken breidt het uit, voegt het toe aan het 16-bits adres, en retourneert het resultaat.
- ALU en LU2-deze werden eerder besproken en voeren de meeste rekenkundige en logische bewerkingen uit.
interrupt Processing
zoals ik al eerder zei, eZ8 heeft een vectored interrupt controller met programmeerbare prioriteit. Eerst dacht ik dat dit gedeelte niet zo moeilijk zou zijn omdat interrupts niet zo erg zijn, toch? Nou, toen ik begon om erachter te komen hoe om alle benodigde taken te doen (het opslaan van context, vectoring, het beheren van prioriteiten, enz.), Realiseerde ik me dat het moeilijker zou zijn dan ik eerst dacht. Na een paar uur kwam ik met het huidige ontwerp.
het interruptsysteem van FPz8 werd uiteindelijk eenvoudig. Het heeft acht ingangen (INT0 tot INT7); een globale interrupt inschakelen (IRQE bit gelegen in IRQCTL register); twee registers voor prioriteitsinstelling (IRQ0ENH en IRQ0ENL); en een register voor interrupt vlaggen (IRQ0). Het ontwerp maakt gebruik van een geneste IF-keten die een vectoradres genereert bij detectie van een interruptgebeurtenis met betrekking tot een ingeschakelde interrupt.
Figuur 5 toont een gecomprimeerde weergave van het interruptsysteem. Merk op dat er een eerste IF statement is met een symbool ATM_COUNTER. Dit is een eenvoudige teller gebruikt door de ATM Instructie (het schakelt interrupts voor drie instructiecycli, waardoor atomaire operaties).
figuur 5. Fpz8 interrupt systeem.
een laatste opmerking over interrupts: De interrupt flag register (IRQ0) samples onderbreken invoer elke stijgende rand van de systeemklok. Er zijn ook twee buffer variabelen (IRQ0_LATCH en OLD_IRQ0) die de huidige en laatste status van de vlaggen opslaan. Dit maakt interrupt randdetectie mogelijk en synchroniseert ook de Externe ingangen naar de interne klok (FPGA ‘ s werken niet goed met asynchrone interne signalen).
On-Chip Debugger
dit is waarschijnlijk de coolste eigenschap van deze softcore omdat het een commerciële geïntegreerde ontwikkelomgeving (IDE) mogelijk maakt; zoals Zilog ‘ s ZDS-II) om software te communiceren, te programmeren en te debuggen die draait op de FPz8. De on-chip debugger (OCD) bestaat uit een UART met autobaud mogelijkheid en een command processor aangesloten op het. De UART voert seriële communicatie uit met een host PC, en levert commando ’s en gegevens aan de debugger state machine die debug commando’ s verwerkt (de debugger command processing FSM bevindt zich in de cpu_decod state).
figuur 6. On-chip debugger UART (let op de dbg_rx synchronizer).
mijn OCD-ontwerp implementeert bijna alle commando ’s die beschikbaar zijn op de echte hardware, met uitzondering van de commando’ s die gerelateerd zijn aan het gegevensgeheugen (debug-opdrachten 0x0C en 0x0D); de read runtime counter (0x3); en het read program memory CRC (0x0E).
een ding dat ik wil benadrukken is dat voorzichtigheid geboden is bij het omgaan met asynchrone signalen binnen FPGA ‘ s. Mijn eerste ontwerp hield daar geen rekening mee tijdens het verwerken van het dbg_rx ingangssignaal. Het resultaat was absoluut vreemd. Mijn ontwerp had feilloos gewerkt in simulatie. Ik downloadde het naar een FPGA en begon te spelen met de debug seriële interface met behulp van een seriële terminal (mijn FPGA board heeft een ingebouwde seriële-USB converter).
tot mijn verbazing, hoewel ik meestal met succes commando ‘ s kon verzenden en de verwachte resultaten kon ontvangen, zou het ontwerp soms gewoon bevriezen en stoppen met reageren. Een zachte reset zou ervoor zorgen dat alles weer goed gaat, maar dat intrigeerde me. Wat gebeurde er?
na veel testen en wat googlen, kwam ik erachter dat het mogelijk gerelateerd was aan de asynchrone randen van het seriële ingangssignaal. Ik vervolgens opgenomen een trapsgewijze vergrendeling om het signaal te synchroniseren met mijn interne klok en alle problemen waren verdwenen! Dat is een moeilijke manier om te leren dat je altijd externe signalen moet synchroniseren voordat je ze invoert in complexe logica!
ik moet zeggen dat het debuggen en verfijnen van de debugger code het moeilijkste deel van dit project was; vooral omdat het interageert met alle andere subsystemen, waaronder bussen, de decoder en instructiewachtrij.
synthetiseren en testen
eenmaal volledig gecompileerd (ik gebruikte Quartus II v9.1 sp2), gebruikte de fpz8-kern 4.900 logische elementen, 523 registers, 147.456 bits on-chip geheugen en een ingebouwde negen-Bits multiplier. In totaal gebruikt het FPz8 80% van de beschikbare middelen van het EP4CE6. Hoewel dit veel is, zijn er nog steeds ongeveer 1.200 logische elementen beschikbaar voor randapparatuur (mijn eenvoudige 16-bit timer telt op ongeveer 120 logische elementen en 61 registers). Hij past zelfs op de kleinste cycloon IV FPGA — de EP4CE6 — die gemonteerd is op het goedkope minibord dat ik hier gebruikte (Figuur 7).
figuur 7. Altera Cyclone IV EP4CE6 mini bord.
de minibordfuncties (samen met het ep4ce6-apparaat): een EPCS4 serieel configuratiegeheugen (gemonteerd aan de onderkant); een FTDI serieel-naar-USB-converterchip en een 50 MHz kristaloscillatormodule; enkele knoppen; LED ‘ s; en pin headers om toegang te krijgen tot FPGA-pinnen. Er is geen geà ntegreerde USB-Blaster (voor FPGA programmering), maar het pakket dat ik kocht bevatte ook een externe programmering dongle.
wat betreft de real world tests, onnodig te zeggen, de FPz8 werkte niet de eerste keer! Na het denken een beetje en het lezen van compiler output berichten, Ik bedacht dat het waarschijnlijk een timing probleem. Dit is een veel voorkomend dilemma bij het ontwerpen met programmeerbare logica, maar omdat dit mijn tweede FPGA ontwerp ooit was, heb ik er niet genoeg aandacht aan besteed.
bij het controleren van de timing analyse berichten, kon ik een waarschuwing zien dat de maximale klok rond 24 MHz zou moeten zijn. In eerste instantie probeerde ik een divider-by-2 te gebruiken om een 25 MHz CPU klok te genereren, maar het was niet betrouwbaar. Ik gebruikte toen een divider-door-3. Alles begon perfect te werken!
daarom draait FPz8 momenteel op 16.666 MHz. Het is mogelijk om hogere snelheden te bereiken door een van de interne PLL ‘ s te gebruiken om de hoofdklok te vermenigvuldigen/delen om een resulterende klok lager te krijgen dan 24 MHz, maar hoger dan 16.666 MHz.
programmeren en debuggen
met behulp van de FPz8 is zeer eenvoudig en duidelijk. Zodra het ontwerp is gedownload naar de FPGA, zal de CPU elk programma starten dat in het geheugen is geladen. U kunt een hex-bestand opgeven en de Megawizard Plug-In Manager gebruiken om het initialisatiebestand van het programmageheugen te wijzigen. Op die manier, uw applicatie code zal beginnen met het uitvoeren van een reset signaal.
u kunt de Zilog ZDS-II IDE gebruiken om Assembly of C-code te schrijven en de benodigde hex-bestanden te genereren (meestal selecteer ik de Z8F1622 als mijn doelapparaat omdat het ook 2 KB RAM en 16 KB programmageheugen heeft). Dankzij de on-chip debugger is het ook mogelijk om de ZDS-II IDE te gebruiken om code te downloaden naar de FPz8 met behulp van een seriële debug verbinding (USB, in ons geval).
voordat u verbinding maakt, moet u ervoor zorgen dat de debugger-instellingen hetzelfde zijn als in Figuur 8. Schakel het vinkje uit “Use page erase before flashing” optie, en selecteer “SerialSmartCable” als de huidige debug tool. Vergeet niet om ook te controleren of de FTDI ‘ s virtuele COM poort correct is geselecteerd als de debug poort (gebruik de Setup knop). U kunt ook de gewenste communicatiesnelheid instellen; 115.200 bps werkt heel goed voor mij.
figuur 8. Debugger instellingen.
merk op dat bij het verbinden met de FPz8, de ZDS-II IDE een waarschuwingsbericht zal tonen dat het doelapparaat niet hetzelfde is als het project. Dat gebeurt omdat ik sommige ID geheugen gebieden Niet geïmplementeerd. Negeer gewoon de waarschuwing en ga verder met de debugging sessie.
zodra de code succesvol is gedownload, kunt u de applicatie starten (GO-knop), instructies stappen, registers inspecteren of bewerken, breekpunten instellen, enz. Zoals met elke andere goede debugger, kunt u bijvoorbeeld het paout register (onder PORTSGROEP) selecteren en zelfs de status van de LED ‘ s die zijn aangesloten op PAOUT wijzigen.
enkele eenvoudige voorbeelden van C-code zijn te vinden in de downloads.
houd er rekening mee dat de FPz8 een Vluchtig programmageheugen heeft. Dus, elk programma gedownload naar het is verloren wanneer de FPGA wordt uitgeschakeld.
afsluiting
dit project kostte me een paar weken om te voltooien, maar het was leuk om een microcontroller-kern te onderzoeken en te ontwerpen.
ik hoop dat dit project nuttig kan zijn voor iedereen die iets wil leren over computing basics, microcontrollers, embedded programming en/of VHDL. Ik ben van mening dat — indien gekoppeld aan een goedkope FPGA board-De FPz8 een fantastische leer – (en onderwijs) tool kan bieden. Veel plezier! NV
CEFET-PR:
www.utfpr.edu.br
ScTec:
www.sctec.com.br
HCS08 ontketend:
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