Design della CPU molto semplice in LogiSim


8

Sono attualmente un liceo e mi sono interessato all'ingegneria informatica / elettrica, in particolare alla progettazione di microprocessori. Ho letto il Codice di Charles Petzold e ho iniziato a leggere il Wikibook del Microprocessore (che sembra essere incompleto). Leggendo il Codice , capisco la logica di base dietro una CPU e ho iniziato a costruirne una in LogiSim. Il capitolo 17 in Codice descrive in dettaglio la CPU che voglio costruire, ma i circuiti mancano di componenti chiave: segnali di clock e decodifica delle istruzioni. Alcuni dei segnali di clock sembrano essere abbastanza ovvi (il PC sembra aver bisogno di un segnale di clock costante) ma altri (come come bloccare i valori di RAM) che ho dovuto riflettere e provare a far funzionare.

Posso costruire un accumulatore funzionante (non può essere definito con precisione un ALU, penso, perché manca la parte L) che passa tra addizione e sottrazione con un singolo input, e capisco che questo è tutto ciò di cui ho bisogno per la parte aritmetica - una volta che avrò funzionato i codici operativi di salto, posso implementare la moltiplicazione e la divisione nel codice. La parte con cui sto lottando è la decodifica delle istruzioni. Attraverso alcune ricerche su Google, vedo che ogni codice operativo deve essere interpretato come micro-istruzioni multiple, ma mi sono perso su come ho bisogno di questo per funzionare. Attualmente, il mio decodificatore di istruzioni è solo un circuito di analisi combinatoria con una singola uscita binaria per ogni codice operativo - 13 in tutto.

Il modo in cui funziona il codice è che ha un valore di codice a 8 bit (io uso solo il byte di fascia bassa), quindi due valori di indirizzo a 8 bit separati che poi combino per essere l'ingresso di indirizzo a 16 bit nella RAM. Per bloccare i valori, ho un contatore separato che conta fino a 10b e quindi reimposta su 00b. È l'ingresso di clock per ciascun latch a sua volta (per i tre latch, c'è a, b e c. I secondi orologi hanno un 1 mentre b & c sono 0, quindi b è 1 e 1 & c sono 0, quindi c è uno e 1 & b sono 0, quindi si ripristina). Ma su istruzioni come ADD 000Ah, il PC passa a 000AH ... che dovrebbe essere aggiunto nell'accumulatore, ma in realtà viene bloccato nel latch del codice e viene quindi interpretato come il successivo codice operativo, che fa andare il tutto pazza.

Mi sento come se mi mancassero alcune informazioni importanti sulla decodifica delle istruzioni e su come devo fare i segnali di clock ...

Ecco i file .circ di LogiSim: https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdder.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdderSubtractor.circ https: // dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitInverter.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitLatch.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5 ID.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/PetzoldMk5.circ

PetzoldMk5 è la CPU principale, basandosi sugli altri file da importare come librerie.

Ecco un elenco di codici operativi (tutti binari):

Load                 0001
Add                  0010
Add w/ Carry         0011
Sub                  0100
Sub w/ Borrow        0101
Jump                 0110
Jump w/ Carry        0111
Jump W/ 0            1000
Jump w/o C           1001
Jump W/o 0           1010
Store                1011
Halt                 1100
Reset                1101

1
Desideri condividere il tuo file .circ della CPU Logisim esistente? E solo per rendere la vita un po 'più complicata, dovresti leggere attentamente e comprendere l'aiuto di Logisim, sotto la voce "Propagazione del valore". Se non l'hai già fatto. (Potresti averlo, dato tutto il lavoro che hai già applicato. Molto felice di sentirti affrontare questo!)
Jon

@jonk grazie per le belle parole. Modifica del post con i file .circ associati.
Will Hodges,

Sono 6 file, quindi, del tutto? (Suppongo che questo sia per LogiSim 2.7.1, 2011?)
Jon

@jonk sì, lo è, per entrambe le domande
Will Hodges,

Come gestisci la sottrazione? Usi / Q da un latch di input a uno degli input A / B della tua ALU e modifichi il carry-in? O qualche altro metodo?
Jon

Risposte:


3

Odio pubblicare un "solo link" come la risposta, ma penso che dovresti essere consapevole del lavoro di Warren Toomey con CPU in Logisim, dal momento che probabilmente è esattamente quello che stai cercando.

Ha un paio di tutorial che si sviluppano fino a una CPU ragionevolmente semplice qui ...

http://minnie.tuhs.org/CompArch/Tutes/

E se questo non fa galleggiare la tua barca, ha una CPU più sofisticata qui ...

http://minnie.tuhs.org/Programs/UcodeCPU/

... Tutto ciò è ben spiegato e ha download in file .circ.


Un altro grande e probabilmente più funzionale CPU / computer fai -da- te è Magic-1 disponibile su http://www.homebrewcpu.com/ . Sebbene non sia fatto in Logisim, è abbastanza ben documentato, tra cui immagini, schemi, descrizione. È anche molto più di una semplice CPU in un simulatore. Ha un compilatore ANSI C, un sistema operativo e alcuni software. Ha anche il netto vantaggio di essere stato effettivamente costruito nell'hardware. In effetti, è attualmente attivo e funzionante e serve pagine Web!


Alla fine The Elements of Computing Systems e il sito associato nand2tetris.org entrano come la risorsa di informazione consigliata n. 1 per costruire il tuo computer da zero ogni volta che lo guardo. Credo che molti contenuti (tutti?) Siano gratuiti. YouTube sarebbe d'accordo; molte persone hanno realizzato progetti partendo da questa unica fonte.


1
Anche dare un'occhiata al video Youtbue di Ben Eater sulla costruzione di un computer da 8 bit è molto utile!
Francis Cugler,

1

Penso che ti manchi un aspetto chiave del funzionamento delle ALU. Di solito ogni bit dell'accumulatore è collegato a ciascuno dei vari blocchi funzione tramite un demultiplexer. Utilizzando un byte di comando, la funzione viene selezionata e ogni bit dell'accumulatore è collegato all'ingresso corretto del blocco funzione. La dimensione del demultiplexer determina quante funzioni è in grado di gestire l'ALU. Nel mio esempio molto grezzo mostrato di seguito, un ALU con un input a 4 bit potrebbe fare riferimento a 16 diverse funzioni usando il demultiplexer:

Collegamento dell'accumulatore a vari blocchi funzione all'interno di una ALU

Si noti che nella maggior parte delle CPU, questo design è ottimizzato in un casino di porte per ridurre il conteggio dei transistor.

È possibile utilizzare più funzioni con un registro comandi più grande, ma ciò richiederebbe anche più cicli di clock per caricare il comando.

Consiglio vivamente di leggere il seguente libro se vuoi saperne di più sul design digitale: Fundamentals of Logic Design 7th ed.


Questo tipo di risposta confonde le istruzioni con le operazioni ALU. Nello specifico questo demultiplexer verrebbe usato solo per selezionare quale operazione aritmetica scegliere per un'istruzione aritmetica. Dovresti alimentare il demultiplexer con, diciamo, 3 bit da un'istruzione a 8 bit, per scegliere quale operazione aritmetica. È necessario un meccanismo completamente separato per decodificare e sequenziare le istruzioni in generale. A parte questo, la maggior parte delle CPU che ho visto non usano un demultiplexer come questo nell'ALU, ma usano un casino ottimizzato di gate per eseguire le giuste operazioni.
Ken Shirriff,

1
@KenShirriff Ho apportato alcune modifiche per chiarezza. Sentiti libero di apportare alcune modifiche come ritieni opportuno.
Prendi il

1

Sembra che tu sia sulla buona strada.

Quando si pianificano le micro-istruzioni, è necessario definire chiaramente nella propria mente il modello di "traffico" per lo spostamento dei dati attraverso i vari blocchi. L'esecuzione di un ADD richiederà più passaggi. Se disponi di registri in possesso dei tuoi due operandi ALU, questi dovranno essere caricati dalla RAM o da alcuni registri o bus. Se si dispone di un bus interno condiviso, potrebbe essere necessario caricare un operando alla volta. Una volta che sai quali byte (indirizzo, letterale immediato, dati RAM, puntatore) devono spostarsi dove, pianifica l'ordine del movimento dei byte attraverso il bus (i) dentro e fuori dai vari registri. Potrebbe rimanere bloccato e potrebbe essere necessario aggiungere un registro di mantenimento interno perché un valore intermedio deve essere conservato fino al passaggio di microistruzione successivo.

Penso che ciò che sospetti sia mancante è la complessità richiesta affinché la logica prenda l'istruzione o il codice operativo e la traduca in più stati all'interno della CPU. Può essere complesso, ma è possibile creare una macchina a stati un po 'semplice e poi espanderla con concetti logici di base.

Ad esempio, supponiamo che si stiano creando i passaggi di microistruzione per un'operazione MOVE. Ciò potrebbe essere liberamente descritto in 3 passaggi: 1) Assegnare il contenuto del registro di origine sul bus interno, 2) lampeggiare l'orologio di scrittura del registro di destinazione, 3) Disinserire il contenuto del registro di origine dal bus interno. I passaggi da 1) a 3) descrivono i tempi per un'abilitazione dell'uscita del registro (OE) e un'abilitazione della scrittura del registro (WE) che potrebbe essere selettivamente distribuita a qualsiasi registro di origine e qualsiasi registro di destinazione collegato al bus interno condiviso con demultiplexer.

Se non hai molta pratica nella creazione di macchine a stati finiti, potrebbe essere utile esaminare i diversi approcci per darti un altro elemento fondamentale per generare i segnali di controllo dal tuo micro-sequencer.

Insisti. La quantità di conoscenza acquisita sarà fenomenale. E spero ti divertirai molto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.