Skip to content

Commit

Permalink
eeprom + correzioni
Browse files Browse the repository at this point in the history
  • Loading branch information
andreamazzai authored Nov 26, 2024
1 parent 3ad9336 commit ee737de
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 25 deletions.
2 changes: 1 addition & 1 deletion docs/_docs/40-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ Il SAP-1 prevedeva un numero fisso di 5 step; conseguentemente, tutte le istruzi

*Microcode del computer SAP.*

Nello schema del *Ring Counter del SAP* si nota che il contatore '161 presenta le sue uscite agli ingressi di selezione del demultiplexer '138, che attiva in sequenza le uscite invertite (active = LO) da 00 a 05: ad ogni attivazione di quest'ultima, le due NAND attivano l'ingresso di Reset /MR del '161, che riporta il conteggio degli step allo zero iniziale, cominciando così una nuova istruzione.
Nello schema del *Ring Counter del SAP-1* si nota che il contatore '161 presenta le sue uscite agli ingressi di selezione del demultiplexer '138, che attiva in sequenza le uscite invertite (active = LO) da 00 a 05: ad ogni attivazione di quest'ultima, le due NAND attivano l'ingresso di Reset /MR del '161, che riporta il conteggio degli step allo zero iniziale, cominciando così una nuova istruzione.

E' facile notare come questa architettura comporti uno spreco di cicli di elaborazione durante l'esecuzione di istruzioni che richiedono pochi passaggi, in quanto il RC deve comunque attendere l'attivazione dell'ultima uscita 05 per essere resettato.

Expand Down
52 changes: 28 additions & 24 deletions docs/_docs/90-eeprom.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ Tutti i progetti descritti in questa pagina sono basati su Arduino, ad evidenza

## PROGRAMMATORE

- Nei link mettere il link a Tommy PROM, spiegare CHE IL MIO PROGRAMMATORE DI EPPROM di è basata un po sul DIWSEGNO originale di ben , UN PO' SUL TOMMYPROM
- Verificare anche se è Il programmatore dietro di ben Tom che utilizza lo stesso codice di programmazione del Tommyprom; in realtà mi sembra di ricordare che sia una versione tagliata del tommyprom

La mia prima esperienza con un programmatore di EEPROM risale alla costruzione del computer SAP-1 di Ben Eater e alla realizzazione del programmatore basato sui suoi schema e sketch. Questo progetto, molto semplice, permetteva di programmare le EEPROM del microcode, anche se la scrittura risultava particolarmente lenta. Ciononostante, la programmazione di una EEPROM (dapprima manualmente, poi con il programmatore) è stato un momento euforico - mai avrei pensato di riuscire a comprendere i (tutto sommato semplici) meccanismi che lo rendevano possibile.
La mia prima esperienza con la programmazione di EEPROM risale alla costruzione del computer SAP-1 di Ben Eater e alla realizzazione del programmatore basato sui suoi schema e sketch. Questo progetto, molto semplice, permetteva di programmare le EEPROM del microcode, anche se la scrittura risultava particolarmente lenta. Ciononostante, la programmazione di una EEPROM (dapprima manualmente, poi con il programmatore) è stato un momento euforico - mai avrei pensato di riuscire a comprendere i (tutto sommato semplici) meccanismi che lo rendevano possibile.

[![Schema del programmatore di EEPROM del computer SAP](../../assets/eeprom/eeprom-ben.png "Schema del programmatore di EEPROM del computer SAP"){:width="100%"}](../../assets/eeprom/eeprom-ben.png)

Expand All @@ -34,53 +31,47 @@ Non volevo iniziare un nuovo progetto, quello di un nuovo programmatore di EEPRO

Il mio programmatore iniziale era uguale a quello sviluppato da Ben Eater e utilizzava i <a href="https://www.ti.com/lit/ds/symlink/sn74hc595.pdf" target="_blank">74HC595</a> anziché i <a href="https://www.ti.com/lit/ds/symlink/sn74ls164.pdf" target="_blank">74HCT164</a> utilizzati in origine da Tom. In una sezione della documentazione, Tom evidenziava che il suo codice non funzionava sul progetto di Ben e che necessitava di significative modifiche. Se si desideravano i benefici del TommyPROM sull'hardware di Ben, Tom indicava che la strada più facile non era quella di modificare il software, bensì di adattare l'hardware rendendolo uguale a quello del TommyPROM.

Nella mia testardaggine, avevo optato per un compromesso: modificare solo parzialmente l'hardware sviluppato nel progetto iniziale di Ben e contemporaneamente approfittarne per studiare e aggiornare il software di Tom rendendolo compatibile col mio hardware ed effettuando il minor numero di modifiche possibili. In quel momento non sapevo che il programmatore rivisitato avrebbe visto la lucce in un tempo sostanzialmente limitato, ma che la corretta implementazione della modalità *Page Write* avrebbe richiesto uno sforzo molto più esteso.
Nella mia testardaggine, avevo optato per un compromesso: modificare solo parzialmente l'hardware sviluppato nel progetto iniziale di Ben e contemporaneamente approfittarne per studiare e aggiornare il software di Tom rendendolo compatibile col mio hardware ed effettuando il minor numero di modifiche possibili. In quel momento non sapevo che il programmatore rivisitato avrebbe visto la luce in un tempo sostanzialmente limitato, ma che la corretta implementazione della modalità *Page Write* avrebbe richiesto uno sforzo molto più esteso.

Le modifiche minime necessarie rispetto al programmatore originale del SAP-1 erano le seguenti:

1. il pin Write Enable della EEPROM (/WE) non più controllato dal segnale D13 di Arduino, bensì da A2.
2. il pin Chip Enable della EEPROM (/CE) non più connesso a ground (chip sempre attivo), bensì controllato dal pin A0 di Arduino.
3. il pin Output Enable della EEPROM (/OE) non più connesso allo Shift Register, ma controllato dal pin A1 di Arduino.

Come spiegava Tom, D13 controllava il segnale Write Enable del programmatore di Ben Eater. Poiché D13 è internamente connesso al LED integrato su Arduino, che lampeggia durante il boot, a ogni accensione del programmatore potrebbero verificarsi scritture indesiderate nella EEPROM. Questo non rappresentava un problema per lo sketch di Ben, poiché a ogni esecuzione la EEPROM veniva completamente riprogrammata, sovrascrivendo eventuali scritture spurie. Tuttavia, dato che il TommyPROM poteva essere utilizzato anche solo per leggere una EEPROM, queste scritture iniziali indesiderate avrebbero potuto causare problemi: di qui la necessità di governare /WE con un segnale diverso da D13.
Come spiegava Tom, D13 controllava il segnale Write Enable del programmatore di Ben Eater. Poiché D13 è internamente connesso al LED integrato su Arduino, che lampeggia durante il boot, a ogni accensione del programmatore potrebbero verificarsi scritture indesiderate nella EEPROM. Questo non rappresentava un problema per lo sketch di Ben, poiché a ogni esecuzione la EEPROM veniva completamente riprogrammata, sovrascrivendo eventuali scritture spurie. Tuttavia, dato che il TommyPROM poteva essere utilizzato anche per la sola lettura di una EEPROM, le scritture iniziali indesiderate avrebbero potuto causare problemi: di qui la necessità di governare /WE con un segnale diverso da D13.

Altro aspetto da tenere in considerazione era il pin /OE delle EEPROM: gli Shift Register '164 non sono dotati di una memoria intermedia che funga da *latch* durante il caricamento. Di conseguenza, gli output vengono immediatamente modificati ad ogni Rising Edge del clock, sottoponendo /OE a possibili attivazioni indesiderate. Viceversa, i 74HC595 permettono il caricamento seriale dei dati in un latch interno e la erogazione contemporanea di tutti i nuovi stati di output al Rising Edge di un segnale dedicato (RCLK), annullando il rischio di attivazioni indesiderate di /OE. Tuttavia, durante la realizzazione delle modifiche al programmatore non avevo ben compreso questo aspetto e avevo deciso di seguire l'indicazione di Tom, cioè di dedicare un output di Arduino specificamente ad /OE della EEPROM. In altre parole, la modifica al punto 3 si sarebbe potuta evitare, ma in quel momento non l'avevo capito.

28C series EEPROMS, like the X28C256, sometimes ship from the factory with Data Protection enabled. Use the UNLOCK command to disable this. See the 28C256 Notes for more information. https://tomnisbet.github.io/TommyPROM/docs/28C256-notes

## Schema

[![Schema del programmatore di EEPROM del computer BEAM](../../assets/eeprom/90-eeprom-schema.png "Schema del programmatore di EEPROM del computer BEAM"){:width="100%"}](../../assets/eeprom/90-eeprom-schema.png)

*Schema del programmatore di EEPROM del computer BEAM.*

## Link utili

- Il video <a href="https://www.youtube.com/watch?v=BA12Z7gQ4P0" target="_blank">Using an EEPROM to replace combinational logic</a> di Ben Eater, che descrive la programmazione manuale di una EEPROM.
- Il video <a href="https://www.youtube.com/watch?v=K88pgWhEb1M" target="_blank">Build an Arduino EEPROM programmer</a> e il repository GitHub <a href="https://github.com/beneater/eeprom-programmer" target="_blank">Arduino EEPROM programmer</a> di Ben Eater.
- Il programmatore di EEPROM <a href="https://github.com/TomNisbet/TommyPROM" target="_blank">TommyProm</a> e lo <a href="https://tomnisbet.github.io/nqsap/docs/microcode/" target="_blank">sketch semplificato</a> necessario alla sola programmazione delle EEPROM dell'NQSAP di Tom Nisbet, che ho studiato e implementato nel programmatore di EEPROM del BEAM.

## Spiegazione del codice

1. Calcolo di un checksum sui dati da scrivere sulla EEPROM
Il programmatore di EEPROM sviluppato non è interattivo, a differenza del ben più completo TommyProm. Una volta fatto partire, esegue i seguenti passi ed è pronto per un reset e la programmazione di una nuova EEPROM:

1. Calcolo di un checksum dei dati da scrivere sulla EEPROM
2. Sblocco della EEPROM
3. Cancellazione della EEPROM
4. Programmazione della EEPROM
5. Blocco della EEPROM
6. Calcolo del checksum sulla rilettura dei dati scritti sulla EEPROM e verifica col valore calcolato al punto 1
6. Calcolo del checksum rileggendo i dati scritti e confronto col valore calcolato al punto 1
7. Stampa del tempo trascorso

### Un po' di teoria... in pratica


Per governare tutti i segnali di controllo di ALU, RAM, SP, registri ecc. sono necessarie quattro EEPROM, cioè un totale di 32 bit. Ogni EEPROM mette a disposizione per l'output 8 bit, cioè un byte. Poiché ogni *Step* di ogni *Istruzione* del BEAM deve essere indirizzabile singolarmente su ogni EEPROM, sono necessarie EEPROM di dimensione 16 step * 256 istruzioni = 4096 byte dedicati alla decodifica delle istruzioni e all'impostazione degli opportuni segnali di output. Per indirizzare 4096 byte sono necessari 12 pin di indirizzamento (2^8 = 256 istruzioni e 2^4 = 16 step), cioè da A0 a A11; quattro EEPROM da 4KB, ognuna delle quali programmata con il proprio microcode, possono svolgere il compito richiesto.
Per governare tutti i segnali di controllo di ALU, RAM, SP, registri ecc. sono necessarie quattro EEPROM, cioè un totale di 32 bit. Ogni EEPROM mette a disposizione 8 bit in output, cioè un byte. Poiché ogni *Istruzione* del BEAM è composta da 16 *Step*, sono necessarie EEPROM di dimensione 256 * 16 = 4096 byte dedicati a decodifica delle istruzioni e impostazione degli opportuni segnali in uscita. Per indirizzare 4096 byte sono necessari 12 pin di indirizzamento (2^8 = 256 istruzioni e 2^4 = 16 step), cioè da A0 a A11; quattro EEPROM da 4KB, ognuna delle quali programmata con il proprio microcode, possono svolgere il compito richiesto.

Vediamo in dettaglio il microcode di alcune istruzioni di esempio:

~~~text
<0> <1> <2> <3> <4> <5> <6> <7> <8> <9>
{ RPC|WM, RR|WIR|PCI HLT, NI, 0, 0, 0, 0, 0, 0 }, // istruzione 0 - HLT
{ RPC|WM, RR|WIR|PCI, RPC|WM, RR|WM, RR|WPC|NI, 0, 0, 0, 0, 0 }, // istruzione 0 - JPM (indiretto)
{ RPC|WM, RR|WIR|PCI, RPC|WM, RR|WB, RX|WH, CS|C0|FNZC|RL, RA|WH|PCI|NI, 0, 0, 0 }, // istruzione 6 - CPX
<0> <1> <2> <3> <4> <5> <6> <7> <8> <9>
{ RPC|WM, RR|WIR|PCI HLT, NI, 0, 0, 0, 0, 0, 0 }, // istruzione 0 - HLT
{ RPC|WM, RR|WIR|PCI, RPC|WM, RR|WM, RR|WPC|NI, 0, 0, 0, 0, 0 }, // istruzione 0 - JPM (indiretto)
{ RPC|WM, RR|WIR|PCI, RPC|WM, RR|WB, RX|WH, CS|C0|FNZC|RL, RA|WH|PCI|NI, 0, 0, 0 }, // istruzione 6 - CPX
~~~

L'istruzione più lunga è la CPX, la cui durata è di 7 step (da 0 a 6).
Expand All @@ -102,11 +93,13 @@ Anziché effettuare quattro programmazioni distinte, risulta però molto più co
|| 8192 | 12287 | 0x2000 | 0x2FFF | 0 | 1 |
|| 12288 | 16383 | 0x2000 | 0x3FFF | 1 | 1 |

Impostando a valori fissi le linee di indirizzamento A12 e A13 sarà possibile mettere in output su ogni EEPROM la porzione corretta di microcode; si vedano le connessioni fisse a Vcc o GND nello [schema](../control/#schema) della Control Logic.
Impostando a valori fissi le linee di indirizzamento A12 e A13 è possibile mettere in output su ogni EEPROM la porzione corretta di microcode; si vedano le connessioni fisse a Vcc o GND nello [schema](../control/#schema) della Control Logic.

In altre parole, abbiamo 256 istruzioni che si sviluppano in 16 step, ognuno composto da una Control Word da 32 bit (4 byte) = 16.384 byte totali. Si dovrebbero programmare 4 EEPROM da 4K: una per i primi 8 bit della Control Word, una per gli 8 bit successivi e così via. Anziché programmare quattro diverse EEPROM da 4K con il microcode specifico, è possibile programmare 4 EEPROM da 16K. Nei primi 4K byte si posiziona la codifica per i primi 8 bit della Control Word, nei secondi 4K la codifica per i secondi 8 bit, e così via. Infine, si settano opportunamente gli indirizzi A12 e A13 delle varie EEPROM, in modo che ognuna esponga solo la porzione specifica di microcode relativa ai segnali di controllo cablati sui suoi output.

In relazione al conteggio della dimensione, si veda anche la sezione [Instruction Register e Istruzioni](../control/#instruction-register-e-istruzioni).

Fatta questa premessa, utile per capire la struttura del microcode nelle varie EEPROM, possiamo analizzare alcuni aspetti importanti dello sketch Arduino del programmatore.
Fatta questa premessa, utile per capire la distribuzione del microcode nelle varie EEPROM, possiamo analizzare alcuni aspetti importanti dello sketch Arduino del programmatore.

### Calcolo del CRC pre-programmazione

Expand Down Expand Up @@ -889,3 +882,14 @@ void loop()
delay(800);
}
~~~
## Link utili
- Il video <a href="https://www.youtube.com/watch?v=BA12Z7gQ4P0" target="_blank">Using an EEPROM to replace combinational logic</a> di Ben Eater, che descrive la programmazione manuale di una EEPROM.
- Il video <a href="https://www.youtube.com/watch?v=K88pgWhEb1M" target="_blank">Build an Arduino EEPROM programmer</a> e il repository GitHub <a href="https://github.com/beneater/eeprom-programmer" target="_blank">Arduino EEPROM programmer</a> di Ben Eater.
- Il programmatore di EEPROM <a href="https://github.com/TomNisbet/TommyPROM" target="_blank">TommyProm</a> e lo <a href="https://tomnisbet.github.io/nqsap/docs/microcode/" target="_blank">sketch semplificato</a> necessario alla sola programmazione delle EEPROM dell'NQSAP di Tom Nisbet, che ho studiato e implementato nel programmatore di EEPROM del BEAM.
## TO DO
28C series EEPROMS, like the X28C256, sometimes ship from the factory with Data Protection enabled. Use the UNLOCK command to disable this. See the 28C256 Notes for more information. https://tomnisbet.github.io/TommyPROM/docs/28C256-notes

0 comments on commit ee737de

Please sign in to comment.