Számítógép szimuláció Digital programban VHDL segítségével

Van egy Digital nevű áramkör szimulátor program. Ez tud VHDL és Verilog nyelven írt áramköröket is szimulálni a GHDL és az Icarus Verilog segítségével. Első körben megpróbáltam egy Z80-as processzor VHDL kódját betölteni. De sajnos nem tudja betölteni az áramkört. A Z80-as processzorhoz tartozó VHDL több fájlban van. Próbáltam egy 6809-es processzort, az egy VHD-ben van definiálva, azt simán be tudtam tölteni.

Nem vagyok nagy VHDL guru, pár egyszerűbb áramkört már kreáltam benne, de ez a Z80 processzor feladta a leckét.

Az lenne a cél, hogy egy egyszerű "egykártyás" gépet összerakjak a szimulátorban. A 6502, 6809, 68000-as procikat már nagyjából ismerem. Most a Z80-al szeretnék ilyen módon ismerkedni. Aztán megnézni a mostanában másik témákban felbukkant magyar 8-bites masinákat (Homelab).

Tehát szükségem lenne egy Z80-as VHDL implementációra, amit tudnék használni a szimulátorban, vagy a linkelt T80-ast kellene úgy gatyába rázni, hogy működjön a Digital-ban.

Hozzászólások

Szerkesztve: 2023. 11. 06., h – 16:24

Mi a hiba a fenti T80-al? Quartus, Vivado nem problémázik vele. GHDL-t még nem próbáltam mondjuk, de olyan nagy baj nem lehet.

De van a T80-nak Verilog átirata, a TV80, bár ebbe nagyon sok bugfix nincs benne, ami a fentiben igen, viszont gondolom te nem tökéletes cikluspontosságú demokat akarsz rajta futtatni, így érdemes meggondolni. Jobb, ha nem kevered a nyelveket. Szóval vagy minden legyen VHDL, vagy minden Verilog.

Meg sokminden máshoz is ez van használva.

Egy fájlba másolhatod, de ez az egész hierarchikusan épül fel. A top-level mondjuk legyen T80a (ennek az eredeti chippel megegyező az interface), alatta lesz a T80, az alatt pedig az _ALU, _MCode, _Reg. Szóval neked a T80a kell közvetlenül, a többit automatikusan kéne használnia.

Kísérleteztem vele, meg elkezdtem beleásni magam a VHDL bugyraiba. Amit elképzeltem nem nagyon fog összejönni. Ezek a programok (Digital, Logisim), ahogy néztem az első 'ENTITY'-t nézik a VHDL fájlban és ha az másik VHDL fájlban definiált elemekre hivatkozik, azokat nem nézi. Még nem teljesen tiszta a library meg package, hogy hogyan is épül fel egy hierarchikus VHDL dizájn. Egyelőre még nem tudom ki kivel van.

Ez ellen azt lehetne tenni, hogy az _ALU, _MCode, _Reg-et behúzod a Digitalba, mint külön komponens, viszont így a T80 interfacebe (port listába) ki kell exportálni azokat a jeleket, amik ezekbe be vannak kötve, és akkor a GUI-ban összekötözheted őket. Csak ez rengeteg vezeték lenne.

 

Van a NextZ80 CPU:

https://opencores.org/websvn/listing?repname=nextz80&path=%2Fnextz80%2F…

Ez ugyan nem cikluspontos, de egyetlen Verilog fájlból áll (NextZ80CPU.v)

A kétirányú buszok FPGA-n belül nem léteznek, azért nem szeretik őket. HDL-ben semmi akadálya használni őket, csak legfeljebb nem tudod szintetizálni (vagy ha olyan a tool, akkor "megoldja").

Ha nagyon kétirányúvá akarnád tenni pl. a NextZ80-t, mert fel szeretnéd használni valódi Z80 helyettesítésére, akkor (legyen D a kétirányú adatbusz, WR negatív aktív logika):

D <= !WR ? DO : 8'hZ;

DI <= D;

Igen, jogos, ez így a pontosabb :) A gyakorlatban a tool-ok megoldják, és kb ugyanez lesz az eredmény is. Kerdes inkabb az hogy melyik az atlathatobb es/vagy logikusabb hosszabbtavon. Vagy ugye a harmadik alternativa a wand/wor (wired and, wired or) is ott lehet ami egy egész jo kompromisszum. 

Szerintem az a jó, ha van egy modul egyirányú buszokkal, ha pedig ki akarod vezetni FPGA-n kívülre, arra teszel egy top-levelt, ami kétirányúsítja a buszt. A T80 is ilyen, T80 modul maga az két egyirányú buszként kezeli az adatbuszt, a T80a pedig ezt kétirányúsítja. Ha eleve úgy van írva a modul, hogy kétirányú buszokat használ, ott szívás lehet egy SoC-szerű projektben felhasználni, ahol FPGA-n belül kell összekötözni más modulokkal.

Még 1 Z80, ami egy fájlból áll (igaz, több modulból, de szerintem az iVerilog máshogy működik, mint a GHDL, szóval nem probléma):

https://github.com/nukeykt/Nuked-MD-FPGA/blob/main/z80.v

Ezt nukeykt a die shot-ból fejtette vissza, gyakorlatilag egy netlist, szóval nem túl olvasható a kód, viszont ez majdnem olyan, mint az eredeti CPU, annyi a különbség, hogy mivel FPGA-n belüli felhasználásra van szánva, van egy master clock (MCLK), és ebben a domainben mintavételezi a CPU valós órajelét (CLK).

Ha system-on-a-chip szerű (i.e. "egykártyás") számítógépes rendszereket tervezel akkoris több dologra van szükséged:

  • processzor
  • ROM (boot ROM, BIOS vagy flash): bármi, ami minimális vagy akár teljes programot tartalmaz, azaz  lényegében az első valid utasítást tartalmazza amit a processzor végregajt amint kikerül a reset/initial/stall állapotból - aztán ez a ROM tartalmazhatja ez akár a teljes futtatandó programot (ezt hivjuk a gyakorlatban mikrokontrollernek) vagy csak annyi programot ami egy külső perifériáról be tud rántani valamit valahova (RAM-ba) majd átadja oda a vezérlést (gyakorlatban ez a "nagyszámítógép"). És persze ez a "ROM" lehet akar kesőbb irható is (a lényeg hogy tartalmaznia kell a hardveresen inicializált programkódot)
  • RAM, amennyiben szükséges (de azért nem árt ha van :p :))
  • legalább egy periféria amin keresztül ez a számítógép üzen a nagyvilágnak, hogy "helló, itt vagyok".

Nezd meg hogy ezek a peldák a fentiekből mit tartalmaznak és hogy hogyan tudod interface-elni a processzort a ROM/RAM/periféria hármassal. 

Ha szimulálsz pl iVerilog-ban, akkor persze pár dolgot össze is tudsz vonni. Peldaul: elég csak RAM de az már az RTL szintézis során tartalmazza a futtatandó programot azon a címen ahonnan a processzor indul. Ez Verilogban ugye az initial begin ... end közé megy, sima tömbös értékadással vagy readmemh()-val. Vagy a periféria lehet egy darab árva regiszterecske is amibe ha beírsz adatot akkor a szimulátor kiirja azt az értéket a dump-ba vagy a konzolra. 

Bármilyen is az architektúra, kb így indulnék neki.