Archivi categoria: Articoli

Articoli scritti da me, reportages. Piu in genere, tutto ciò che è troppo grosso per essere passato ragionevolmente via feed RSS generico.

L’adder

Bentornati nel nostro piccolo corso alla scoperta dell’intimo funzionamento dei nostri computer. La volta scorsa abbiamo visto le porte logiche di base, e vi avevo lasciato da svolgere un piccolo esercizio, che ora vediamo di risolvere insieme. Eccovi la soluzione:

+----+----+----+----+----+----+----+
| 1A | 2A | 1B | 2B | 1C | 2C | EX |
+----+----+----+----+----+----+----+
|  0 |  0 |  0 |  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  1 |  0 |  0 |  0 |
|  0 |  0 |  1 |  1 |  0 |  1 |  1 |
|  0 |  1 |  0 |  0 |  0 |  0 |  0 |
|  0 |  1 |  0 |  1 |  0 |  0 |  0 |
|  0 |  1 |  1 |  1 |  0 |  1 |  1 |
|  1 |  0 |  0 |  0 |  0 |  0 |  0 |
|  1 |  0 |  0 |  1 |  0 |  0 |  0 |
|  1 |  0 |  1 |  1 |  0 |  1 |  1 |
|  1 |  1 |  0 |  0 |  1 |  0 |  1 |
|  1 |  1 |  0 |  1 |  1 |  0 |  1 |
|  1 |  1 |  1 |  0 |  1 |  0 |  1 |
|  1 |  1 |  1 |  1 |  1 |  1 |  0 |
+----+----+----+----+----+----+----+

Vediamo di spiegare, per coloro che non avessero ancora chiaro il funzionamento delle porte logiche; partiamo dalla prima riga: alle entrate del primo AND (1A e 2A) abbiamo due zeri. Se andiamo a leggere nella tabella dell’AND, pubblicata sullo scorso numero, troveremo “che 0 AND 0” da in uscita uno 0. 1C, quindi, vale 0. Stesso discorso vale per 2C, risultato dell’AND con entrate 1B (0) e 2B (0). A questo punto, quindi avremo alle entrate dello XOR, due zeri, che daranno in uscita un 0 (0 XOR 0 = 0). Vediamo quindi la riga dopo: 0 AND 0 = 0; 0 AND 1 = 0; 0 XOR 0 = 0. Terza riga: 0 AND 0 = 0; 1 AND 1 = 1; 0 XOR 1 = 1. E cosi via, fino a completare tutta la tabella.

Come avete visto, il funzionamento delle porte logiche non è complesso, e anzi, è piuttosto intuitivo, una volta entrati nel giusto ordine di idee. State cominciando a capire come “pensa” un computer. Se volete esercitarvi, provate a creare dei piccoli elementi voi, collegando i diversi componenti che abbiamo trovato. Potete arrivare a componenti molto complessi, che troverete estremamente divertendi da risolvere…C’è da fare solo una piccola precisazione, prima di continuare. Abbiamo detto, nella prima parte di questa serie di lezioni, che i componenti sono tutti (tranne il NOT) a due entrate ed una uscita. Ora, questa è una semplificazione logica, in quanto i componenti a piu entrate (3,4,5 o piu) sono divisibili e rappresentabili tramite composizione di piu elementi “base” a due entrate ed una uscita. Per intenderci, 1 AND 0 AND 1 = (1 AND 0) AND 1 = 0 AND 1 = 0.

Abbiamo appena visto le porte lorighe ed il loro funzionamento. Abbiamo capito che sono il cuore del nostro elaboratore, ma ancora non ci è chiaro come sia possibile, con il solo aiuto di questi piccoli componenti, realizzare circuiti che diano un risultato chiaramente utile. Ad esempio, costruiamo un circuito in grado di addizionare due numeri.
Innanzitutto, vediamo come funziona un’addizione in binario:

0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10

Possiamo facilmente vedere che nel caso si sommino due 1, avremo in uscita uno 0, e dovremo riportare un 1. Vediamo quindi ora una sintesi di quello che il nostro circuito dovrà fare, nella seguente tabella:

+---------+-------------+
|  INPUT  |   OUTPUT    |
+----+----+-----+-------+
|  A |  B | SUM | CARRY |
+----+----+-----+-------+
|  0 |  0 |   0 |     0 |
|  0 |  1 |   1 |     0 |
|  1 |  0 |   1 |     0 |
|  1 |  1 |   1 |     1 |
+----+----+-----+-------+

Dove SUM è la somma delle due cifre ricevute in ingresso (A e B) mentre CARRY è il bit di riporto.
Per realizzare il circuito che abbiamo descritto in tabella, cioè un sommatore di 1 bit, basterebbe un circuito come quello che vediamo in figura 1, costituito quindi da una porta AND (per il riporto) e una XOR (per la somma vera e propria).
Il problema di questo circuito, è che non tiene conto dell’eventuale riporto ricevuto da un altro adder, e quindi non permette di addizionare piu di una singola coppia di bit. Vediamo allora di implementare un bit di “carry in”, di modo da poter affiancare piu adder per dar vita ad un adder piu complesso.

+--------------+------------+
|     INPUT    |   OUTPUT   |
+----+----+----+-----+------+
|  A |  B | Cin| SUM | Cout |
+----+----+----+-----+------+
|  0 |  0 |  0 |   0 |    0 |
|  0 |  0 |  1 |   1 |    0 |
|  0 |  1 |  0 |   1 |    0 |
|  0 |  1 |  1 |   0 |    1 |
|  1 |  0 |  0 |   1 |    0 |
|  1 |  0 |  1 |   0 |    1 |
|  1 |  1 |  0 |   0 |    1 |
|  1 |  1 |  1 |   1 |    1 |
+----+----+----+-----+------+

Ecco qua, questa è la tabella che il nostro circuito dovrà implementare. Vediamo ora (figura 2) come potremmo strutturare il circuito per fargli eseguire questa operazione.
Sapendo che la somma altro non è che uno XOR (l’abbiamo visto nel primo circuito), possiamo semplificare la nostra operazione con un `(A XOR B) XOR Cin’
Come per il primo circuito, collegheremo al primo XOR, i bit provenienti dalle entrate A e B, e ne otterremo la somma.
Gli stessi due bit, li collegheremo ad una porta AND. Se infatti sono entrambi ad 1 (e quindi l’AND restituisce un 1), significa che avremo un riporto.
A questo punto, abbiamo un bit di Cout e un bit di somma per A e B. A questo, aggiungeremo il Cout di C. Dovremo quindi implementare un’altra porta XOR e un’altra porta AND (a entrambe collegheremo l’uscita di A XOR B, e il bit Cin, per lo stesso discorso che ci ha permesso di sommare A e B).
Ultimo dettaglio del circuito, ci troviamo ora con due bit di Cout, uno per A XOR B, e uno per lo XOR della somma con C. Ovviamente se uno dei due è a 1, dovremo avere 1 in uscita. Questo lavoro è svolto dalla porta OR, che ci permette di ridurre ad 1 il numero di Cout.

Non è difficile, no? Si tratta solo di farci la mano, imparare a giocare con i componenti. Nel prossimo appuntamento, vedremo come fare ad implementare le condizioni al nostro circuito. Happy hacking a tutti 🙂

Annunci

Logica booleana

Tutti (o quasi) abbiamo in casa un computer. Ma quanti di noi sanno effettivamente cosa succede dentro “la scatola”? Cosa avviene effettivamente quando schiacciamo il pulsante di accensione, e diamo corrente a quell’ammasso di ferraglia? Lo scopo di questo articolo, è proprio lo spiegare, in termini ragionevolmente semplici, come funziona un processore, ed in che modo i programmi che scriviamo e compiliamo, sono in grado di interagire con il sistema.

Per capire come funziona un computer, dobbiamo partire dalla sua base. Che cos’è un bit. Si senta tanto parlare di bit, megabit, gigabit… e molti di noi ancora si chiedono, cos’è, questo fantomatico bit? Bene, è presto detto: il bit è un impulso. Un minuscolo impulso elettrico che viaggia sui circuiti integrati della nostra “scatola magica”. Puo assumere due diversi valori, 1 o 0, o true o false, vero o falso, o una qualsiasi altra coppia di valori a mutua esclusione (ad esempio nero o bianco…). Il significato del bit, però, è solo una semplificazione che l’uomo fa per capire di cosa sta parlando. La macchina, in se, riconosce solo gli impulsi, i segnali. Contatto aperto, o contatto chiuso. 1 o 0. Punto. Stop. Fine. Dobbiamo abituarci, se vogliamo imparare come funziona intimamente un computer, a pensare come lui. A saper interpretare al volo il significato di 1 e 0.

Ora questo non è un corso avanzato di architettura dei compilatori. Non staremo qui a spiegare dettagliatamente il funzionamento fisico della macchina, perchè ci vogliono basi molto solide, soprattutto in elettronica, che non tutti potremmo avere. Non staremo quindi a spiegare come effettivamente un componente di un circuito integrato riesce a realizzare la propria funzione. Inizieremo invece a spiegare da un livello superiore, da un’astrazione un gradino piu su. I componenti, appunto.

In linea di massima, in un circuito integrato, troveremo un numero piuttosto limitato di componenti base. In particolare sono molto frequenti i componenti AND, i NOT, gli OR e XOR. Non fatevi spaventare dalle sigle usate, ora spiegheremo cosa sono e a cosa servono. Iniziamo col dire che questi “componenti”, si chiamano porte logiche, e sono alla base di qualsiasi altro componente. Le combinazioni di questi elementi, creano altri componenti, via via piu complessi, fino a dare apparente vita autonoma alla nostra “scatola”. Un esempio? Se mettiamo insieme un NOT e un OR, avremo un NOR, un NOT e un AND, avremo un NAND. Vi state ancora chiedendo cosa sono, vero? Ok, passiamo a spiegare.
Le porte logiche sono le implementazioni fisiche della logica booleana. Non per niente, i loro nomi sono quelli delle parole che caratterizzano la logica booleana. Facciamo un breve ripasso (chi si trovasse spaesato, puo fare una brevissima ricerca online, e troverà moltissimo materiale esplicativo su questa logica, detta anche binaria).
AND:

Un AND è una porta logica con due entrate ed un’uscita. In particolare restituisce in uscita un 1, nel caso in cui entrambi i segnali in entrata siano settati a 1.

1 AND 0 = 0
0 AND 0 = 0
1 AND 1 = 1
0 AND 1 = 0

OR:

Un OR è una porta logica con due entrate ed un’uscita. In particolare restituisce in uscita un 1, nel caso uno dei due ingressi sia settato ad 1.

1 OR 0 = 1
0 OR 0 = 0
1 OR 1 = 1
0 OR 1 = 1

NOT:

Un NOT è una porta logica con una sola entrata ed una sola uscita. In particolare restituisce in uscita un 1, nel caso l’ingresso sia settato ad 1, e viceversa.

NOT 1 = 0
NOT 0 = 1

XOR:

Uno XOR è una porta logica con due entrate ed un’uscita. In particolare restituisce in uscita un 1, nel caso uno dei due ingressi non siano uguali.

1 XOR 0 = 1
0 XOR 0 = 0
1 XOR 1 = 0
0 XOR 1 = 1

Ora proviamo a combinare le porte logiche che abbiamo visto fino ad ora, ed otterremo:
NAND:

NOT (1 AND 0) = 1
NOT (0 AND 0) = 1
NOT (1 AND 1) = 0
NOT (0 AND 1) = 1

NOR:

NOT (1 OR 0) = 0
NOT (0 OR 0) = 1
NOT (1 OR 1) = 0
NOT (0 OR 1) = 0

XNOR:

NOT (0 XOR 0) = 1
NOT (0 XOR 1) = 0
NOT (1 XOR 0) = 0
NOT (1 XOR 1) = 1

Come vedere il contetto non è difficile. Ora proviamo a complicare un po le cose. Colleghiamo insieme alcuni di questi componenti. Ad esempio, colleghiamo alle due entrate di uno XOR, due AND. Chiameremo le 4 entrate degli AND rispettivamente 1A,2A e 1B,2B. Chiameremo quindi le entrate dello XOR (che sono poi le uscite dei due AND) 1C e 2C. Il nostro primo appuntamento si conclude con un esercizio. Risolvete per la prossima volta lo schemino sottostante, riportando il valore d’uscita del circuito (cioè quello dello XOR, che chiamaremo EX) a seconda dei valori in entrata dei due AND.

+----+----+----+----+----+----+----+
| 1A | 2A | 1B | 2B | 1C | 2C | EX |
+----+----+----+----+----+----+----+
|  0 |  0 |  0 |  0 |    |    |    |
|  0 |  0 |  0 |  1 |    |    |    |
|  0 |  0 |  1 |  1 |    |    |    |
|  0 |  1 |  0 |  0 |    |    |    |
|  0 |  1 |  0 |  1 |    |    |    |
|  0 |  1 |  1 |  1 |    |    |    |
|  1 |  0 |  0 |  0 |    |    |    |
|  1 |  0 |  0 |  1 |    |    |    |
|  1 |  0 |  1 |  1 |    |    |    |
|  1 |  1 |  0 |  0 |    |    |    |
|  1 |  1 |  0 |  1 |    |    |    |
|  1 |  1 |  1 |  0 |    |    |    |
|  1 |  1 |  1 |  1 |    |    |    |
+----+----+----+----+----+----+----+

Sembra difficile? Non fatevi assalire dal panico, e provateci. Tra due settimane, la risposta 🙂