Computer / Programmazione / Z80 · 6 febbraio 2019 0

LM80C: clock e reset

Oltre all’alimentazione una CPU, per lavorare correttamente, ha bisogno di qualche altro segnale. Quelli base sono i segnali di reset e di clock. Il primo è usato per… resettare la CPU. Questo segnale è generato sia quando viene fornita l’alimentazione al sistema sia manualmente (ad esempio premendo uno specifico pulsante). Il reset è molto importante perché imposta la CPU al suo stato iniziale pulendo i registri iniziali e impostando i pin esterni in alta impedenza. Il clock è importante quanto il reset: è come un direttore, che detta i giusti tempi a tutti gli strumenti dell’orchestra.

Il primo circuito che esamineremo è quello del reset. Questo è molto facile da realizzare: è basato sul diffuso timer NE555, uno dei più longevi circuiti integrati. L’NE555 ha un diverse modalità di utilizzo: per questo particolare compito lo imposteremo in modalità monostabile, vale a dire che l’NE555 imposta su HIGH il suo pin di uscita per un certo asso di tempo non appena rileva una caduta di segnale sul suo pin di ingresso. La durata dell’impulso alto può essere impostata combinando un paio di componenti esterni, un resistore ed un condensatore. Il tempo T in secondi dell’impulso è dato dalla seguente formula: T = 1,1 * R * C, dove R è il valore del resistore in Ohm e C la capacit à del condensatore in Farad. Ciò è necessario perché il segnale di reset deve rimanere attivo per almeno 3 cicli di clock prima che il processo di reset sia completato. Ma siccome useremo il segnale di reset per resettare l’intero sistema, ci assicureremo che esso faccia il suo lavoro correttamente scegliendo un tempo ben più lungo. Dato che non abbiamo fretta di vedere il nostro sistema pronto e funzionante ho deciso che possiamo aspettare per circa mezzo secondo. Per ottenere questo tempo, data la formula precedente, possiamo utilizzare un resistore da 47 Kohm con un condensatore da 10 uF. Infatti, T = 1,1 * 47K * 10uF = 1,1 * 47000 * 0,00001 = 0,517 s. C’è però un piccolo problema: l’uscita dell’NE555 viene attivata con un segnale alto (HIGH) mentre il /RESET è un ingresso attivo basso (LOW): ciò significa che messa così la cosa non funzionerà. Ma c’è una soluzione semplice: dobbiamo solo usare un 7404 Hex Inverter che, come suggerisce il suo nome, semplicemente inverte il segnale in ingresso. Dato un segnale basso otteniamo un segnale alto, e viceversa Perciò, quando andremo ad accendere il nostro sistema l’NE555 terrà la linea del reset bassa per mezzo secondo, dando così il tempo all’intero sistema di raggiungere un livello di tensione bello stabile. Ho anche aggiunto un piccolo pulsante switch per resettare manualmente il sistema, dovesse casomai rendersi necessario.

Ecco lo schema:

LM80C: reset circuit

LM80C: reset circuit

R1 e C1 sono utilizzati come un piccolo filtro anti-rimbalzo per il pulsante. R3 è usato come resistore di pull-up per dare un valore alto stabile alla linea di reset quando l’NE555 non lavora. Quando l’NE555 scatta, ad esempio dopo l’accensione o la pressione del pulsante, il timer terrà la sua linea di uscita alta per circa 0,5 secondi: dato che l’uscita del timer è connessa all’ingresso dell’inverter, la linea di reset verrà tenuta bassa finché il timer non rilascerà l’uscita, andando ad un livello basso che, conseguentemente, farà andare la linea di RESET alta. Sarà solo in quel momento che la CPU, e tutti gli altri chip collegati alla linea di reset, si avvierà.

Il passo successivo è quello di progettare un buon circuito di clock. La CPU Z80 necessita di un segnale di clock monofase: rispetto ad altri microprocessori di quel periodo che richiedevano 2 distinti segnali di clock (alto e basso, separati sulle linee Phase 1 e Phase 2), essa vuole solo un segnale ad onda quadra su una singola linea. L’altra cosa importante è la frequenza del clock, che impatta in maniera diretta sulla velocità della CPU. Lo Z80 è una CPU complessa, ed è stata progettata per lavorare con cicli interni chiamati “cicli macchina” (“machine cycles”): ogni istruzione necessita di almeno 3 cicli macchina (alcune anche di 4 cicli), ed ogni ciclo è composto da 4 segnali di clock, e questa è la ragione per cui lo Z80 è sempre stato indicato come una CPU lenta se comparata al 6502, ad esempio: essa ha bisogno di più cicli di clock. Per ottenere buone prestazioni essa deve operare a frequenze più alte rispetto a quelle dei rivali. Infatti, il 6502 normalmente operava a 1 MHz mentre i sistemi basati sullo Z80 di solito operavano a 3,5/4 MHz. Un clock comune era 3,58 MHz perché è la frequenza della portante del colore (colorburst) nel segnale NTSC. Molti sistemi Z80 usavano il TMS9918 come chip video: dato che questo chip necessita di un quarzo esterno da 10,76 MHz per ottenere il segnale del colore a 3,58 MHz e dato che esso può portare tale clock su un pin esterno, era comune tra i fabbricanti di computer, per risparmiare, utilizzare tale clock come clock di sistema. I computer MSX lavoravano in questo modo. Noi, invece, sceglieremo un’altra frequenza: dato che ho pensato di collegare l’LM80C ad un computer tramite la seriale, e dato che la serial, per lavorare correttamente, ha alcune restrizioni sulla velocità che possiamo ottenere dato un certo clock, ho optato per una frequenza di 3,68 MHz, che non è molto lontana dai 3,58 MHz menzionati in precedenza. Per ottenere questa frequenza useremo un quarto da 7,37 MHz. Perché facciamo così? Il motivo è dato dal fatto che abbiamo bisogno di ottenere un’onda quadra molto stabile con un duty cycle (il rapporto fra il fronte alto e quello basso del segnale) perfettamente del 50%. Per ottenere ciò utilizzeremo una coppia di porte dell’hex inverter che abbiamo usato per il reset. Il 7404 è chiamato “hex” inverter perché ha 6 porte invertenti. Usiamo l’inverter per stabilizzare il segnale clock dato che la porta invertente scatta solo quando il segnale raggiunge un minimo valore di tensione. Utilizzando 2 porte invertenti siamo sicuri che il clock sarà ben stabilizzato e “squadrato”. Utilizzeremo poi un flip flop di tipo D per dimezzare il clock a 7,37 MHz così da ottenere un segnale a 3,68 MHz. Ecco lo schema:

LM80C: clock circuit

LM80C: clock circuit

C5 e C6 servono per evitare l’auto-risonanza del cristallo: questi valori non sono assoluti, e dipendono dal cristallo che avete scelto, fate riferimento al suo datasheet. R4 è usata per dare il feedback alla porta invertente. Quando il clock esce dalla seconda porta invertente è ancora a 7,37 MHz: usando il flip flop di tipo D, un comune integrato 7474, andiamo a dimezzare tale frequenza ai 3,68 MHz richiesti. Ho usato il mio Arduino con la libreria FreqCounter per misurare il clock:

Frequency check

Frequency check

Molto stabile, vero?

Alla fine, oggi abbiamo fatto un bel lavoro. In un prossimo articolo cercheremo di far compiere al nostro sistema basilare qualche piccolo compito. Restate sintonizzati.

AGGIORNAMENTO: vorrei spendere alcune parole sulla CPU e sui chip della serie 74xx. Zilog ha prodotto diverse versioni della sua CPU, esse variano per il clock massimo a cui possono lavorare e per i tipo di gate. I primi modelli fabbricati alla fine degli anni ’70 ed agli inizi degli anni ’80 erano chip NMOS, poi Zilog è passata al processo di fabbricazione CMOS. Questi possono essere identificati facilmente perché di solito hanno la lettera “C” nel mezzo del loro codice, ad esempio “Z84C00”. Lo stesso dicasi per i chip periferici: essi possono essere sia CMOS che non-CMOS. Una buona regola sarebbe quella di non mischiare componenti NMOS con quelle CMOS perché esse hanno diversi valori di capacità dei loro pin. Perciò se comprate una CPU CMOS, comprate anche chip periferici CMOS. E viceversa, se acquistate una CPU NMOS, comprate chip periferici NMOS. La questione della frequenza: LO z80 fu inizialmente costruito per lavorare ad un clock massimo di 2,5 MHz. Il chip era marchiato semplicemente “Z80”. In seguito Zilog fabbricò altri modelli con differenti frequenze massime di funzionamento: il modello “A” poteva lavorare fino a 4 MHz, il modello “B” fino a 6 MHz, l'”H” fino a 8 MHz. Le vecchie, originali CPU hanno questa lettera dopo il nome, es. “Z80B”. I modelli più recenti possono lavorare fino a 25 MHz e sono marchiati di solito con un codice, come ad esempio Z84C0006, dove le ultime 2 cifre a destra indicano la frequenza massima: nell’esempio “06” sta per 6 MHz. Per i nostri scopi scegliete un modello che possa lavorare almeno a 4 MHz, meglio se a 6 MHz. Ad esempio uno Z80B (se del passato) o uno Z84C0006 (se fabbricato recentemente). Lo stesso vale per i chi periferici: ad esempio un PIO che può lavorare fino a 6 MHz può essere marchiato come “Z80B PIO” (se vecchio) oppure “Z84C2006” (se nuovo).

Questione serie 74xx. La famiglia di integrati 74xx è in commercio da un sacco di tempo, da più di 40 anni. Durante questo periodo il processo produttivo è stato cambiato molte volte. Per lavorare con le nostre CPU abbiamo bisogno di chip che sono compatibili TTL, vale a dire che devono poter lavorare con i segnali TTL, ossia 5 V per il segnale alto e 0 V per il segnale basso. Inoltre, le varie serie differiscono per la massima corrente che possono erogare/assorbire. In passato era usata la serie LS, ma questi chip sono rari: fortunatamente possono essere rimpiazzati dai modelli “HCT“. Perciò, quando dico che sto usando un 7404 intendo che sto usando un chip 74HCT04. E così via. Tenetelo a mente anche quando guardate un mio schema. Se per caso trovaste una serie differente, vuol dire che non ho trovato il componente tra le librerie di Eagle per cui ho usato un chip dello stesso tipo, con la stessa piedinatura ma di un’altra famiglia (ad esempio un AC al posto dell’HCT) e mi sono scordato di cambiare la sigla.

Il codice e gli schemi sono disponibili su questo repository su GitHub.