Appunti di Architettura degli Elaboratori

Table of Contents

1. Rappresentazione dell'informazione

1.1. Proprietà delle codifiche

Per alfabeto A si intende un insieme finito e distinguibile di segni. Una parola o stringa su A è una sequenza finita di simboli di A. Indichiamo con A* tutte le possibili parole generabili dall'alfabeto A.

Un linguaggio L sull'alfabeto A è un qualsiasi sottoinsieme di A* (L ⊆ A*).

Associando gli elementi di un insieme D ad L otterremo una codifica di L. Una codifica è una funzione totale f: D → L:

  • Se f non è suriettiva è ridondante: Se f è suriettiva ogni stringa in L è la codifica di almeno un elemento in D
  • Se f non è iniettiva è ambigua: Se f è iniettiva ogni stringa in L corrisponde al più ad un solo elemento in D
  • Una codifica è quindi non ambigua e non ridondante se è biunivoca
  • ND è la cardinalità di D, mentre NL è la cardinalità di L:
    • Se ND < NL allora qualsiasi codifica è ambigua
    • Se NL < ND allora qualsiasi codifica è ridondante

Le proprietà delle codifiche sono quindi le seguenti:

  • Ambiguità/Non ambiguità
  • Ridondanza/Non Ridondanza
  • Economicità (numero di simboli usati per unità di informazione)
  • Semplicità nella codifica/decodifica
  • Semplicità nell'operare sull'informazione codificata

1.2. Rappresentazione in una base generica

Ad ogni naturale b > 1 corrisponde una codifica in base b. L'alfabeto Ab consiste in b simboli che corrispondono ai numeri che vanno da 0 a b-1. Un numerale di cifre Ab rappresenta il numero: \[ \sum_{i=0}^{m-1}s \times b^i \]

Notazione standard:

  • n denota un generico numero a prescindere dalla base
  • nb denota un numero in base b, esempio: 10012 rappresenta il numero 9 (base dieci) in base 2.

1.2.1. Lunghezza e valore massimo rappresentabile

La lunghezza di n rispetto a b rappresenta il numero di cifre che occorrono per rappresentare quel numero nella data base:

  • La lunghezza di 101 in base 2 è 7: 11001012
  • In base 7: 2037
  • In base 6: 2456

Il valore massimo rappresentabile in una base b con m cifre è dato dalla formula: \[ v_{max} = b^m - 1 \]

1.2.2. Cifre necessarie per rappresentare un numero

Per sapere quante cifre m occorrono per rappresentare un numero, il massimo numero rappresentabile con m dovrà essere maggiore o uguale allo stesso: \[ b^m - 1 \ge n \] \[ b^m \ge n + 1 \] \[ m \ge \log_b(n + 1) \]

1.2.3. Cambiamento di base

L'algoritmo di cambio di base consiste nel dividere ripetutamente n per la base di arrivo e di raccogliere i resti dalla cifra meno significativa a quella più significativa.

Per passare da una base diversa da quella decimale ad un'altra base ancora diversa, conviene dividere il problema in due parti:

  1. Convertire il numero in base 10
  2. Convertire il numero da base 10 alla base di arrivo

1.2.4. Esempio di conversione da base 5 a base 8

Supponiamo di voler convertire \(101_5\) in base 8:

  • Primo, convertiamo \(101_5\) in base 10: \[ 101_5 = 1 \times 5^2 + 0 \times 5^1 + 1 \times 5^0 = 25 + 0 + 1 = 26_{10} \]
  • Ora, convertiamo \(26_{10}\) in base 8: \[ 26 \div 8 = 3 \quad \text{con resto} \ 2 \] \[ 3 \div 8 = 0 \quad \text{con resto} \ 3 \] Quindi, raccogliamo i resti in ordine inverso e otteniamo: \[ 26_{10} = 32_8 \]

Pertanto, \(101_5 = 32_8\).

1.3. Codifica binaria e esadecimale

Possiamo usare dei trucchetti per rendere più semplice la codifica/decodifica in una base m potenza di 2, esempio:

  • Poiché 16 = 24 è possibile utilizzare una cifra esadecimale per codificare 4 bit:
    • 1112 → 78
    • 011 1112 → 378
  • Analogamente, poiché 8 = 23 è possibile utilizzare una cifra ottale per codificare 3 bit:
    • 1010 11112 → AF16
    • 1111 11112 → FF16

1.3.1. Rappresentazione dei registri

Un computer le grandezze numeriche sono elaborate mediante sequenze di simboli di lunghezza fissa dette parole, poiché una cifra esadecimale codifica 4 bit:

  • 1 byte (8 bit) → 2 cifre esadecimali
  • 2 byte (16 bit) → 4 cifre esadecimali
  • 4 byte (32 bit) → 8 cifre esadecimali
  • 8 byte (64 bit) → 16 cifre esadecimali

1.3.2. Numeri con parole di lunghezza fissa

I registri dei computer moderni sono tipicamente a 32 o 64 bit. Con parole di lunghezza fissa sono rappresentabili un nmero finito di naturali. Con m bit di lunghezza possiamo rappresentare 2m-1 naturali. Siccome le parole sono di lunghezza fissa, anche per un numero che richiede meno cifre dovremo utilizzare degli zeri di riempimento. Esempio di rappresentazione del numero 4 in biario con parole di 8 bit: \[00000100_2\].

Quando un'operazione produce un numero troppo grande per essere rappresentato dalla parola a causa della dimensione fissa avviene il fenomeno dell'overflow.

1.4. Rappresentazione dei numeri interi

1.4.1. Con segno

Nella rappresentazione con segno il bit più significativo rappresenta il segno del numero. Per questo motivo con questa codifica sarà possibile, con m bit, rappresentare i numeri da -(bm-1-1) a bm-1.

Bisogna prestare attenzione delle operazioni di somma e sottrazione: dovremo infatti mantenere il segno del numero maggiore in termini di valore assoluto.

1.4.2. Complemento a due

La rappresentazione è analoga a quella con segno, con la differenza che il bit più significativo non rappresenta il segno, ma direttamete il massimo numero negativo rappresentabile (-2m-1):

Numero binario 1 0 0 1 1 1 0 0
Valore -128 +0 +0 +16 +8 +4 +0 +0

Lo zero ha un'unica rappresentazione e il range di rappresentazione è [-2m-1,2m-1-1]. Per complementare un numero dobbiamo invertirne le cifre e aggiungere 1:

  • 2 = 0010 → -2 = 1101 + 0001 = 1110

L'overflow in complemento a due avviene solo quando gli operandi sono entrambi positivi o negativi e il risultato ha segno opposto. Esempio con 4 bit:

  • 0111 + 0111 = 1000

1.4.3. Binary Coded Decimal

La codifica BCD è una codifica ridondante utilizzata per fornire una naturale rappresentazioe binaria del sistema decimale. Vengono utilizzati 4 bit ma solo e posizioni da 0 a 9 vengono impiegate. Ogni cifra viene codificata singolarmente e non viene rispettato il sistema posizionale. Esempio:

  • Il numero 44 viene rappresentato come 0100 0100BCD → Le singole cifre decimali vengono codificate indipendentemente.

1.5. Numeri con virgola

Per rappresentare un numero con virgola in una generica base b: \[ \sum_{i=-k}^{h-1} s_i \cdot b^i \] Dove:

  • n è il numero di cifre presenti;
  • si è la i-esima cifra;
  • bi è la base elevata alla i-esima posizione;
  • −k è l’indice dell’ultima cifra dopo la virgola

Esempio in base dieci con il numero 10,46:

  • 1 × 101 + 0 × 100 + 4 × 10-1 + 6 × 10-2

1.5.1. Cambiamenti di base con virgola

Si procede separatamente a convertire la parte intera e la parte reale nel caso di conversione da una base a ad una base b di un numero n con virgola:

  • Per la parte intera si procede come per i numeri interi
  • Per la parte frazioaria il procedimento è inverso:
    1. Si moltiplica n per b
    2. La parte frazioaria del risultato si moltiplica ancora per b e la uova parte intera costituisce la seconda cira frazionaria
    3. Si riparte dallo step 1 fino a quando la parte frazionaria non è 0 o si è raggiunta la precisione desiderata

Esempio di coversione del numero 3,2 da base 10 a base 7:

  • Parte intera: 310 → 37
  • Parte frazionaria:
    1. Primo passaggio: \(0,2 \times 7 = 1,4\) ⇒ \(1\) è la prima cifra della parte frazionaria in base 7.
    2. Secondo passaggio: \(0,4 \times 7 = 2,8\) ⇒ \(2\) è la seconda cifra della parte frazionaria in base 7.
    3. Terzo passaggio: \(0,8 \times 7 = 5,6\) ⇒ \(5\) è la terza cifra della parte frazionaria in base 7.

La rappresentazione del numero \(3,2_{10}\) in base 7 è quindi: \(3,125_7\).

1.5.2. Virgola fissa

Nella rappresentazione dei numeri con virgola fissa, utilizziamo parole con lunghezza fissata di \(m\) bit per rappresentare i numeri. Questo comporta notevoli svantaggi dal momento che gli \(m\) bit vengono divisi in due sotto-parole:

  • I primi \(h\) bit (\(h
  • I restanti \(k = m-h\) rappresentano la parte frazionaria

1.5.3. Virgola mobile

Fissare a priori la lunghezza della parte intera e di quella frazionaria costituisce una scelta rigida. Per ovviare a queste difficoltà è stata introdotta la rappresentazione a virgola mobile. Questo tipo di rappresentazione permette di rappresentare un numero reale con una tripla \((s, e, m)\), dove:

  • \(s\) determina il segno: \(0\) per positivo, \(1\) per negativo;
  • \(e\) è detto esponente;
  • \(m\) è detta mantissa e viene rappresentata in notazione scientifica come \(1.xyz\), normalizzata.

La rappresentazione completa di un numero reale è: \[ x = (-1)^s \times m \times b^e \]

Si utilizza sempre la rappresentazione scientifica in cui \(1 \leq m < b\), perché esistono infiniti modi di rappresentare un numero reale \(x\). Ad esempio, per \(3.46_{10}\):

  • \(0.356 \times 10^1\)
  • \(0.0356 \times 10^2\)
  • \(34.6 \times 10^{-1}\)

1.5.4. Standard IEEE 754

L'IEEE 754 è lo standard per la rappresentazione dei numeri a virgola mobile. I numeri possono essere rappresentati con precisione singola (32 bit) o doppia (64 bit):

Precisione Segno Esponente Mantissa
Precisione singola 1 bit 8 bit 23 bit
Precisione doppia 1 bit 11 bit 52 bit

Per la codifica dell’esponente si utilizza la rappresentazione polarizzata (\(e = e' + P\)), dove: \[ P = 2^{k-1} - 1 \] Avendo 8 bit (\(k = 8\)): \(P = 2^7 - 1 = 127\). In altre parole, gli esponenti sono codificati in ordine crescente.

1.5.5. Esempio di Codifica IEEE 754

Per convertire il numero \(-4.63\) in binario:

  1. Segno: \(1_2\) (Il numero è negativo).
  2. Parte intera in binario: \(4 \to 100_2\).
  3. Parte frazionaria in binario:
    • \(0.63 \times 2 = 1.26 \to 1\)
    • \(0.26 \times 2 = 0.52 \to 0\)
    • \(0.52 \times 2 = 1.04 \to 1\)
    • \(0.04 \times 2 = 0.08 \to 0\)
    • Risultato: \(0.101_2\).
  4. Unione della parte intera e frazionaria: \(100.0101_2\).
  5. Normalizzazione: Spostiamo la virgola di 2 posizioni:\[100.101_2 = 1.000101_2 \times 2^2\]
  6. Calcolo dell’esponente polarizzato:\[e = 127 + 2 = 129 \to 10000001_2\]
  7. Costruzione del numero a 32 bit:

    Segno Esponente Mantissa
    1 10000001 00010100000000000000000

1.6. TODO Codifica dei caratteri alfanumerici

I processori moderni non posseggono istruzioni per il trattamento dei caratteri, per questa ragione è necessario codificarli in numeri interi con i quali il calcolatore può lavorare. Un testo è una sequeza di caratteri e i codici associano un numero ad ogni sequenza.

1.6.1. Ascii

Codice a 7 bit: 95 caratteri stampabili e 33 di controllo assegnati ai primi 32 numerali: – null indica la fine di una stringa – carriage return porta il cursore su una nuova riga (andata a capo) – horizontal tab è l’usuale carattere tab

Decimal Hex Binary Char Description
0 00 00000000 NUL Null
1 01 00000001 SOH Start of Header
2 02 00000010 STX Start of Text
3 03 00000011 ETX End of Text
4 04 00000100 EOT End of Transmission
5 05 00000101 ENQ Enquiry
6 06 00000110 ACK Acknowledge
7 07 00000111 BEL Bell
8 08 00001000 BS Backspace
9 09 00001001 TAB Horizontal Tab
10 0A 00001010 LF Line Feed

1.6.2. Unicode

Codice a 21 bit (1 milione di simboli). Attualmente (v. 9.0) definiti circa 128.000 caratteri! Viene ulteriormente codificato in UTF-8.

Codice Carattere Significato
U+0434 д Lettera cirillica “de”
U+6328 ب Lettera araba “ba”
U+0E10 Lettera tailandese “tho than”
U+1F63A 😺 “Smiling cat face with open mouth”
U+1F382 🎂 Torta di compleanno

1.6.3. TODO UTF-8

La codifica UTF-8 è una codifica variabile che usa da 1 a 4 byte per rappresentare ciascun carattere Unicode. La lunghezza della sequenza di byte dipende dal valore del carattere, e il primo byte della sequenza di ogni carattere indica quanto lunga sarà la sequenza complessiva.

La codifica UTF-8 si basa su una sequenza di byte, e il primo byte (il cosiddetto "byte di controllo") definisce la lunghezza della sequenza.

2. Algebra di Boole

2.1. Porte Logiche

Le porte logiche sono i componenti fondamentali che costituiscono un calcolatore, essere prendono uno o più input e realizzano un output. Gli input si indicano generalmente con le prime lettere dell'alfabeto mentre gli output con le ultime

Porte logiche fondamentali:

  • AND (Congiunzione):

    A B A ∧ B
    0 0 0
    0 1 0
    1 0 0
    1 1 1
  • OR (Disgiunzione):

    A B A ∨ B
    0 0 0
    0 1 1
    1 0 1
    1 1 1
  • NOT (Complemento):

    A ¬A
    0 1
    1 0

Altre porte logiche ottenibili combinando le porte fondamentali:

  • NAND, che si ottiene mettendo in serie una porta AND e una porta NOT:

    A B A ↑ B
    0 0 1
    0 1 1
    1 0 1
    1 1 0
  • XOR, che si ottiene mediante la combinazione di porte AND, OR e NOT:

    A B A ⊕ B
    0 0 0
    0 1 1
    1 0 1
    1 1 0

    \[ A \oplus B = (A \land \neg B) \lor (\neg A \land B) \]

  • XNOR, che equivale alla negazione dello XOR:

    A B A ≡ B
    0 0 1
    0 1 0
    1 0 0
    1 1 1

    \[ A \leftrightarrow B = \neg (A \oplus B) = \neg((A \land \neg B) \lor (\neg A \land B)) \]

    • NOR, che equivale alla negazione dell'OR:
    A B ¬ (A ∨ B)
    0 0 1
    0 1 0
    1 0 0
    1 1 0

Le porte logiche possono avere anche più linee di input, ad esempio possiamo avere una porta AND con quattro linee di input.

Nella realizzazione fisica delle porte logiche i valori in ingresso binari devono corrispondere ad una certa grandezza fisica. La grandezza che reifica i valori 0 e 1 è il potenziale elettrico che genera corrente elettrica all'interno del circuito:

  • Il valore logico 0 è rappresentato dal valore di potenziale V0 (GRD)
  • Il valore logico 1 è rappresentato da un valore di potenziale VDD ≤ 1,5V

Un circuito è soggetto a rumore che potrebbe alterare i valori nominali, per questo si impiegano delle bande di guardia attraverso delle soglie di tolleranza:

  • GRD-VOL
  • VOH - VDD

2.2. Funzioni Booleane

\[ f: \{0, 1\}^N \to \{0, 1\} \]

Avendo a disposizione parole di \(N\) bit, abbiamo a disposizione \(2^N\) combinazioni possibili. Essendo che una funzione booleana può assegnare ad ogni combinazione un valore di \(0\) o \(1\), abbiamo quindi \(2^{2^N}\) funzioni booleane possibili:

x1 x2 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
      AND         XOR OR NOR XNOR       NAND    

2.3. Circuiti digitali

Un circuito digitale è una rete che elabora segnali discreti. Prescindendo dalla sua configurazione interna, possiamo vederli come delle black-box con:

  • Uno o più input/output
  • Una specifica funzionale (relazione fra input e output)
  • Una specifica temporale (ritardo della propagazione degli input fino agli output)

Un circuito è composto inoltre da:

  • Elementi (altri circuiti)
  • Nodi (che interconnettono gli elementi, i nodi possono essere di input, output o interni)

circ_dig.png

I circuiti digitali si dividono in reti combinatorie e reti sequenziali. In una rete combinatoria il valore degi output dipende esclusivamente dai valori di input correnti, mentre in una rete sequenziale i valori degli output dipendono anche dai valori precedenti (il circuito ha quindi memoria).

2.4. Reti Combinatorie

La composizione di reti combinatorie segue delle regole ben precise:

  1. Ogni elemento della rete è esso stesso una rete combinatoria
  2. Ogni elemento non di input connette esattamente un output di un elemento
  3. Nella rete non devono esistere percorsi ciclici, ogni cammino interno visita un nodo al più una volta

Visualizzare una rete come una scatola nera con un’interfaccia e una funzione ben definite è un’applicazione del principio dell’astrazione e della modularità, così come la costruzione di una rete a partire da elementi circuitali più piccoli è un’applicazione del principio della gerarchia. Le regole della composizione combinatoria sono, infine, un’applicazione della regolarità.

Le specifiche funzionali di un circuito combinatorio sono descritte tramite tabelle di verità o espressioni booleane. Più espressioni booleane corrispondono alla stessa tabella.

2.5. Ricavare tabelle da espressioni

Per ricavare una tabella da un'espressione basta calcolare a ritroso le tabelle delle sue sotto-espressioni: \[ \neg A \land \neg B \oplus \neg (C \land \neg B) \]

A B C ¬A ¬B ¬(C ∧ ¬B) ¬A ∧ ¬B Risultato
0 0 0 1 1 1 1 0
0 0 1 1 1 0 1 1
0 1 0 1 0 1 0 1
0 1 1 1 0 1 0 1
1 0 0 0 1 1 0 1
1 0 1 0 1 0 0 0
1 1 0 0 0 1 0 1
1 1 1 0 0 1 0 1

2.6. Ricavare espressioni da tabelle

Per effettuare il procedimento inverso, ovvero ricavare espressioni a partire da tabelle di verità, possiamo servirci delle forme SOP (somma di prodotti) e POS (prodotto di somme). Definizioni preliminari

  • Una variabile booleana \(A\) e la sua negata \(\neg A\) sono detti litterali
  • Un prodotto di litterali è detto implicante (AND)
  • Dato un insieme \(K\) di variabili booleane, un mintermine di \(K\) è un implicante (prodotto ∧) che comprende, positive o negate, tutte le variabili in \(K\).
  • Analogamente, un maxtermine di \(K\) è una somma (∨) di litterali che comprende tutte le variabili in \(K\).
  • Ordine di precedenza:
    1. NOT ¬
    2. AND ∧
    3. OR ∨

Esempio per \(K = \{A, B, C\}\):

  • Mintermine: ¬ A ∧ B ∧ ¬ C
  • Maxtermine: ¬ A ∨ ¬ B ∨ C

Se la tabella ha pochi 1 allora la forma SOP è più succinta, altrimenti se ha pochi 0 è meglio utilizzare la forma POS. In caso di numero simile di zero e uno una vale l'altra.

2.6.1. Forma SOP (Sum of Products)

Ognuna delle 2N righe di una tabella di verità è caratterizzata da un mintermine. I mintermini sono enumerati a partire da 0 rigo dopo rigo. Ad ogni tabella di verità corrisponde un'espressione ottenuta sommando tutti i mintermini per cui il valore di output (\(Y\)) della funzione è 1:

A B Y minterm minterm name
0 0 0 ¬ A ∧ ¬ B m0
0 1 1 ¬ A ∧ B m1
1 0 0 A ∧ ¬ B m2
1 1 1 A ∧ B m3

\[ Y = \sum(m_1, m_3) \] \[ Y = (\neg A \land B) \lor (A \land B) \]

2.6.2. Forma POS (Product of Sums)

La forma POS è la forma duale della SOP e funziona in maniera analoga. Ad ogni riga di una tabella di verità corrisponde un maxtermine che è uguale a 0 solo per quella riga.

A B Y maxtern maxterm name
0 0 0 A ∨ B M0
0 1 1 A ∨ ¬ B M1
1 0 0 ¬ A ∨ B M2
1 1 1 ¬ A ∨ ¬ B M3

\[ Y = \prod(m_0, m_2) \] \[ Y = (A \lor B) \land (\neg A \lor B) \]

2.7. Algebra di Boole

L'algebra booelana prende il nome dal matematico inglese George Bool. L'oggetto di questa algebra non erano le porte logiche ma le leggi del pensiero e della deduzione, difatti si può dare un'iterpretazione puramente logica alle espressioni booelane.

2.7.1. Assiomi dell'algebra di Boole

assiomi.png

2.7.2. Teoremi ad una variabile

teoremi.png

2.7.3. Teoremi a più variabili

teoremi2.png

2.7.4. Tecniche di dimostrazione

Ci sono diversi modi per verificare se due espressioni booleane sono equivalenti:

  • Tramite confronto delle tabelle di verità (Perfect Induction): Questa tecnica è semplice ma priva di intelligenza, al crescere delle espressioni diventa sempre più laboriosa e complessa da gestire.
  • Utilizzando gli assiomi ed i teoremi sopra descritti
  • Sfruttare la struttura delle espressioni e verificare che le tabelle di verità coincidono solo nei casi rilevanti

2.7.5. Alcuni teoremi per semplificare espressioni

  1. T8 (Distributivity)

    \[ B \land (C \lor D) = B \land C \lor B \land D \] \[ B \lor (C \land D) = (B \lor C) \land (B \lor D) \]

  2. T9' (Covering)

    \[ A \lor (A \land P) = A \]

  3. T10 (Combining)

    \[ (P \land (\neg A)) \lor (P \land A) = P \]

  4. Expansion

    \[ P = (P \land (\neg A)) \lor (P \land A) \] \[ A = A \lor (A \land P) \]

  5. Duplication

    \[ A = A \lor A \]

  6. "Simplification" theorem

    \[ (P \land (\neg A)) \lor A = P \lor A \] \[ (P \land A) \lor \neg A = P \lor (\neg A) \]

2.8. Teoremi di De Morgan

Il teorema di De Morgan ci dice che:

  • La negata di un prodotto è uguale alla somma delle negate
  • La negata di una somma è uguale al prodotto delle negate

demorgan.png

I teoremi di De Morgan ci consentono di convertire una porta AND in una OR e viceversa:

andor.png

Esempio: \[ Y = \neg((A \lor \neg(B \land C)) \land C) \] \[ = \neg(A \lor \neg B \lor \neg D) \lor C \] \[ = \neg A \land \neg(\neg B) \land \neg(\neg D) \lor C \] \[ = \neg A \land B \land C \lor D \]

2.8.1. Da SOP a POS

I teoremi di De Morgan consentono di ricavare la forma POS a partire dalla SOP (e viceversa):

A B Y ¬ Y minterm
0 0 0 1 ¬ A ∧ ¬ B
0 1 0 1 ¬ A ∧ B
1 0 1 0 A ∧ ¬ B
1 1 1 0 A ∧ B

\[ \neg Y = \neg A \land \neg B \lor \neg A \land B \] \[ \neg(\neg Y) = \neg((\neg A \land \neg B) \lor (\neg A \land B)) = \neg(\neg A \land \neg B) \land \neg(\neg A \land B) = (A \lor B) \land (A \lor \neg B) \]

2.9. Completezza degli operatori

Qualsiasi funzione booleana \(f:\{0,1\}^N \to \{0,1\}\) può essere spressa in forma SOP. La forma SOP usa solo gli operatori AND (∧), OR (∨) e NOT (¬): questo vuol dire che questo insieme di operatori costituisce un insieme completo. Per le leggi di De Morgan:

  • A ∧ B = ¬(¬ A ∨ ¬ B) (AND può essere espresso in termini di NOT e OR)
  • A ∨ B = ¬(¬ A ∧ ¬ B) (OR può essere espresso in termini di NOT e AND)

Quindi {NOT, AND, OR} è un insieme di operatori completo ma non minimale, quindi anche {NOT, AND} e {NOT, OR} sono completi.

2.9.1. Operatori insiemistici

insiemi.png

  • \( T \): insieme universo
  • \( 2^T = \{ A \mid A \subseteq T \} \): insieme dei sottoinsiemi di \( T \)
  • \( \cap \): AND
  • \( \cup \): OR
  • \( T' \): NOT
  • \( 1 \): \( T \)
  • \( 0 \): \( \emptyset \)

2.10. Schemi circuitali

Uno schema circuitale è un diagramma di una rte digitale che ne mostra gli elementi e i fili che li connettono tra loro. Ad ogni espressione booleane corrisponde un circuito combinatorio. Linee guida da seguire durante la realizzazione di uno schema:

  • Gli ingressi vengono collocati in alto o a sinistra
  • Le uscite vengono collocate in basso o a destra
  • Quando possibile, le porte logiche vanno disegnate in modo che gli ingressi vadano da sinistra verso destra
  • I fili dritti si prefeiscono a quelli con troppi angoli
  • Fili che arrivano ad una giunzione a T sono collegati
  • Un punto disegnato dove due fili si incontrano indica che sono collegati
  • Fili che si incrociano ma che non hanno un punto non sono collegati tra loro

Questo stile di disegno è chiamato matrice logica programmabile (PLA) perché i negatori, le porte AND e OR sono allineati in maniera sistematica.

circuito.png

2.10.1. Semplificare formule SOP

Le formule in forma SOP hanno degli schemi circuitali molto regolari:

  • Una linea di input per ogni variabile che occorre positiva
  • Una linea NOT per ogni variabile che occorre negata
  • Una porta AND per ogni mintermine con le linee di input che corrispondono ai relativi litterali
  • Tutte le porte AND finiscono in un unica porta OR

La proprietà principale che si utilizza per ridurre le forme SOP è il T10 (Combining): \[ (P \land \neg B) \lor (P \land B) = P \]

Un implicante è detto implicante primo se non può essere combinato con altri implicanti per ottenere un nuovo implicante con meno litterali. Una forma SOP si dice minimale se tutti i suoi implicanti sono primi.

Nella minimizzazione di forme SOP può essere necessario sdoppiare un implicante (T8 ad esempio) allorché questo può essere ridotto in modi differenti.

2.10.2. Semplificare formule POS

Nelle forme POS valgono generalmente le stesse regole delle forme SOP. La proprietà principale che si usa è il combining: \[ (B \lor C) \land (B \lor \neg C) = B \]

2.10.3. Circuito a priorità

I circuiti a priorità vengono utilizzati per assegnare una risorsa condivisa secondo un ordine di priorità fra chi ne fa richiesta.

priority.png

2.10.4. Valori don't cares

Si noti che nel circuito mostrato in precedenza, se A3 è portato a uno, le uscite non tengono conto dei valori degli altri ingressi.

Per progettare un circuito a priorità basta scriverne la tabella di verità, tradurla in espressione e successivamente tradurre l'espressione in porte logiche. Gli ingressi ignorati nelle uscite vengono contrassegnati con una X e vengono chiamati valori Don't cares (o indifferenze).

2.10.5. Bubble Pushing

Il bubble pushing è una tecnica grafica che applica le leggi di De Morgan e la legge della doppia negazione per eliminare le negazioni annidate nei circuiti con tante porte NAND e NOR, per semplificarli e renderli più leggibili.

Usare logiche multilivello e porte NAND/NOR a volte rende difficile capire quale funzione booleana un circuito realizza a causa delle molte negazioni annidate. Per avere un'espressione più leggibile si possono applicare le leggi di De Morgan:

  • Partendo dall’output Y si applicano a ritroso le leggi di De Morgan in modo che l’input e l’output di ogni nodo siano entrambi positivi o negati

bubbles.png

2.10.6. Valori illegali

Si ha un valore illegale quando il valore del potenziale è portato ad essere contemporaneamente sia 0 che VDD, queste configurazioni venono dette illegali perché il valore di Y dipendera dalla natura fisica delle porte:

  • Stabile ma indeterminato
  • Oscillante fra 0 e VDD
  • Possiede un valore intermedio

2.10.7. Alta impedenza e bus condiviso

Un nodo oltre ad essere in uno stato di 0 o 1 può anche trovarsi nello stato \(Z\) di alta impedenza (no passaggio di corrente). Gli stati di alta impedenza vengono utilizzati per disconnettere una parte del circuito dal resto. Per questo si utilizzano i tristate buffer:

buffertri.png

I tristate buffers sono usati in bus che connettono diversi chip per evitare la trasmissione di segnali illegali nel momento in cui più componenti vogliono immetere segnali sul bus, limitando la comunicazione ad un singolo componente per volta.

2.11. Mappe di Karnaugh

Le mappe di Karnaugh sono un metodo grafico per semplificare espressioni in forma SOP.

La proprietà sulla quale si basano le mappe di Karnaugh è il T10 (Combining): \( P \neg B \lor PB = P \)

I numeri binari nella griglia mostrano le combinazioni per tutti i possibili valori di ingresso:

  1. Dovremmo inserire 1 nelle caselle che, date le opportune configurazioni di ingresso, restituiscono 1 nella tabella di verità dell'espressione
  2. Successivamente dovremmo raggrupare e cerchiare gli 1 presenti nei riquadri adiacenti
  3. Per ogni cerchio si deve scrivere l'implicante corrispondente (un implicante è il prodotto tra uno o più litterali)
  4. Le variabili presenti sia in forma dritta che negata vanno eliminate (vedere la variabile \(C\) nell'esempio)

Regole per il raggruppamento:

  1. Usare il minimo numero di bolle necessarie per ricoprire tutti gli 1
  2. Tutte le caselle sottese da una bolla devono contenere 1
  3. Ogni bolla ricopre un blocco di caselle che è una potenza di 2
  4. Ogni bolla deve essere più larga possibile
  5. Dal momento che la mappa ha una struttura toroidale, una bolla può trasbordare la mappa
  6. Una casella può essere ricoperta da più bolle se così facendo si hanno un numero inferiore di bolle

kmap.png

La semplificazione risultante dalla mappa di Karnaugh elimina l'implicante \(C\) (che compare sia in forma dritta che negata) riducendo l'espressione a: \[ \neg A\neg B \]

Risolutore mappe di Karnaugh per controllare la correttezza degli esercizi svolti.

2.12. Display a 7 segmenti

Un decoder display 7 segmenti riceve in input 4 segnali D0:3 e produce sette output Sa:g per controllare i led che rappresentano i numeri da 0 a 9.

7s1.png

Ogni output è una funzione indipendente a 4 variabili che accende o spegne un singolo segmento del display. Attraverso le tabelle di verità è possibile ricavare le funzioni booleane associate ad ogni segmento.

7s2.png

D3:0 Sa Sb Sc Sd Se Sf Sg
0000 1 1 1 1 1 1 0
0001 0 1 1 0 0 0 0
0010 1 1 0 1 1 0 1
0011 1 1 1 1 0 0 1
0100 0 1 1 0 0 1 1
0101 1 0 1 1 0 1 1
0110 1 0 1 1 1 1 1
0111 1 1 1 0 0 0 0
1000 1 1 1 1 1 1 1
1001 1 1 1 0 0 1 1
others 0 0 0 0 0 0 0

2.12.1. Don't care in output

I valori da 10 a 15 producono sempre lo stesso output (0) dal momento che sono indifferenze. Possiamo sfruttare a nostro vantaggio queste indifferenze e trattare gli output come 0 o 1 a nostra discrezione durante la costruzione delle mappe di Karnaugh.

I valori \(X\) (le indifferenze) possono essere impiegati quando il loro utilizzo ci consente di cerchiare più valori 1 con meno bolle o utilizzando bolle più grandi.

dc.png

2.13. Multiplexer

I multiplexer (mux) sono tra i circuiti combinatori più utilizzati. I mux selezionano un output da vari input in base al valore di un segnale select.

2.13.1. Multiplexer 2:1

Un multiplexer 2:1 riceve in input due segnali D0:1 e un segnale S di selezione. Restituisce in output l'input selezionato dal segnale S. Ad esempio per S = 0, Y = D0 e per S = 1, Y = D1:

mux21.png

Il circuito di un multiplexer può essere costruito a partire dalla logica SOP:

mux21circ.png

2.13.2. Multiplexer 4:1

I mux 4:1 possono selezionare un segnale da mandare in output partendo da 4 segnali di input D0:3. Per questo motivo servono due segnali di selezione S0:1:

Un multiplexer 4:1 può essere realizzando tramite 3 mutliplexer 2:1:

mux4121.png

In generale, per costruire un multiplexer con N ingressi servono log2(N) linee di selezione.

2.13.3. Sintetizzare funzioni booleane con mux

I multiplexer possono essere utilizzati per sintetizzare funzioni booleane. Sintetizzare una unzione di \(m\) variabili con un mux a 2m linee è semplice:

  • Le variabili saranno linee di selezione. Data una certa configurazione delle variabii, la linea di ingresso corrispondente sarà posta al valore della funzione in quella configurazione
  • Le linee di ingresso riroducono la tabella di verità della funzione

mux41.png

È possibile utilizzare mux con 2m-1 ingressi per sintetizzare funzioni ad m variabili:

  • Le prime m-1 variabili saranno linee di selezione
  • Le linee di ingresso possono essere poste a 0, 1 oppure all'ultima variabile (positiva o negata)
  • Bisogna ridurre la tabella di verità della funzione di partenza

muxredux.png

2.14. TODO Decoder

2.14.1. Sintetizzare funzioni booleane con decoder

3. Circuiti sequenziali

I circuiti sequenziali sono dei circuiti le cui uscite dipendono sia dai valori attuali che dai valori precedenti. Di conseguenza, si può dire che i circuiti sequenziali hanno memoria.

3.1. Bistabile

Si definisce circuito bistabile un circuito in grado di tenere due stati stabili. La figura sotto tiportata mostra un semplice circuito bistabile composto da una coppia di NOT connessi a croce. La rete non ha ingressi ma possiede due uscite Q e ¬ Q.

bistabile.png

Analisi del circuito:

  • Caso 1: \(Q = 0\):
    • l2 riceve 0 in input, quindi produce 1 in output.
    • l1 riceve 1 in input e produce 0 in output
  • Caso 2: \(Q = 1\):
    • l2 riceve 1 in input, quindi produce 0 in output
    • l1 riceve 0 in input, quindi produce 1 in output

Un circuito con un numero N di stati stabili è caratterizzato da log2N bit di informazione, quindi un circuito bistabile immagazzina un bit di informazione.

Anche se questo circuito è in grado di immagazzinare un bit di informazione, non è molto utile dal momento che l’utente non ha a disposizione un ingresso che permetta di controllare lo stato. Invece altri circuiti bistabili, come ad esempio i latch e i flip-flop, sono provvisti di ingresso per il controllo del valore della variabile di stato.

3.2. Latch

3.2.1. Latch-SR

Il Latch-SR è un circuito sequenziale composto da due porte NOR, collegate a croce. Il Latch-SR ha due ingressi S ed R, e due uscite Q e ¬ Q.

srlatch.png

Gli ingressi \(S\) ed \(R\) significano rispettivamente set e reset (da cui il noe Latch Set-Reset). Da notare che la configurazione di partenza \(S = 1\), \(R = 1\) è illegale in quanto otterremo in output \(Q = 0\) e \(\neg Q = 0\), il che è impossibile.

3.2.2. Latch-D

Il Latch-D è un circuito sequenziale che permette di evitate che gli ingressi S ed R del Latch-SR siano simultaneamente attivi. Il Latch-D è composto da due ingressi: un ingresso dati D che controlla in che cosa l'output cambia ed un ingresso CLK, che controlla QUANDO l'output cambia.

latchd.png

3.3. Flip-Flop

3.3.1. Flip-Flop D

Un Flip-Flop D è un circuito sequenziale che può essere costituito da due Latch-D in cascata controllati da due segnali di clock complementari.

dflipflop.png

I latch in configurazione Master-Slave (come nel caso del Flip-Flop D) vengono così denominati perché operano in modo complementare, sincronizzati dal segnale di clock (CLK). Di seguito una spiegazione dettagliata del funzionamento:

  1. CLK = 0

    Quando il clock è basso: clck0flipflop.png

    • Il latch master (L1) è trasparente.
    • Il latch slave (L2) è opaco.
    • Il segnale di ingresso D viene propagato al nodo intermedio N1.
  2. Transizione sul fronte di salita (CLK: 0 → 1)

    Durante il fronte di salita del clock: clck01flipflop.png

    • Il latch master (L1) diventa opaco.
    • Il latch slave (L2) diventa trasparente.
    • Il dato presente in N1 viene trasferito all'uscita Q.
  3. CLK = 1

    Quando il clock è alto: clck1flipflop.png

    • Il latch master rimane opaco.
    • Il latch slave è trasparente, mantenendo stabile il dato sull'uscita Q.
  4. Transizione sul fronte di discesa (CLK: 1 → 0)

    Durante il fronte di discesa del clock: clck10flipflop.png

    • Il latch master torna trasparente.
    • Il latch slave diventa opaco, mantenendo il dato catturato.

Differenze tra Latch-D e Flip-Flop D

  • Nei Latch-D, il dato D viene trasferito all'uscita Q quando il latch è trasparente. Il dato può cambiare anche se D varia durante il periodo di trasparenza.
  • Nei Flip-Flop D, il dato D viene catturato solo durante il fronte del clock (di salita o di discesa, a seconda della configurazione). Una volta catturato, il dato rimane stabile sull'uscita Q fino al prossimo fronte del clock.

Un cambiamento nel valore di D non avrà effetto sull'uscita Q finché non si verifica il prossimo fronte del clock.

3.3.2. Registri: Multi-bit Flip-Flop

Un registro ad N bit è un banco di N Flip-Flop che condividono un ingresso CLCK comune

Gli input D3:0 e gli output Q3:0 sono bus a 4 bit. regff.png

3.3.3. Flip-Flop Enable

Un Flip-Flop Enable presenta un altro ingresso EN (ENABLE) per determinare se memorizzare o no il dato sul fronte di salita del clock.

  • \(EN = 0\): Il Flip-Flop ignora il clock e mantiene il proprio stato (\(D\) passa fino a \(Q\))
  • \(EN = 1\): Il Flip-Flop si comporta come un normale Flip-Flop D

ffen.png

3.3.4. Flip-Flop Settabile e Resettabile

Un Flip-Flop resettabile aggiunge un ingresso RESET che, quando è vero, ignora l'ingresso D e porta l'uscita Q a 0.

Questi Flip-Flop possono essere resettati in modo sincrono o asincrono:

  • Sincrono: si resettano solo sul fronte di salita del CLK quando RESET = 1
  • Asincrono: si resettano non appena RESET = 1
    • Per i Flip-Flop asincroni occorre modificare il circuito interno del Flip-Flop

Mentre un Flip-Flop settabile lavora praticamente allo stesso modo:

  • Quando SET = 1, allora Q = 1
  • Quando SET = 0, il circuito si comporta come un normale Flip-Flop D

3.4. Logiche sequenziali sincrone

I circuiti asincroni presentano delle criticità a volte difficilmente analizzabili che possono dipendere da:

  • Struttura fisica dei componenti
  • Differenze nella manifattura
  • Temperatura
  • Tensione in ingresso

Il comportamento di una rete asincrona può quindi variare considerevolmente in base ai ritardi accumulati sui cammini, dato che nei circuiti asincroni l'output è retroazionato in maniera diretta. Per questo motivo si cerca di evitare la retroazione dell'output in maniera diretta e si interpone un registro nel ciclo di retroazione.

Nell’ipotesi che il clock sia più lento del ritardo accumulato sul cammino, il registro consente al sistema di essere sincronizzato col clock: circuito sincrono.

In generale, in una rete combinatoria l'output dipende esclusivamente dall'input: \[ out = f(in) \] Un circuito sequenziale sincrono possiede una serie di stati (\(\{S_0, S_1, ..., S_{k-1}\}\)), quindi l'output dipende sia dai valori attuali che dallo stato corrente: \[ out = f(in, s_c) s_n = g(in, s_c) \]

Per avere una rete sequenziale sincrona, i componenti del circuito devono essere interconnessi in modo che:

  • Ogni elemento della rete è o un registro o una rete combinatoria
  • Ci deve essere almeno un registro
  • Tutti i registri ricevono lo stesso segnale di clock
  • Ogni ciclo contiene almeno un registro

L'esempio più comune di rete sequenziale sincrona dato che possiede due stati {0, 1}, dove Q = Sc (current state) mentre D = Sn (next state):

ffns.png

3.5. Macchine a stati finiti (FSM)

3.5.1. Moore FSM

3.5.2. Meeley FSM

3.6.

4. Circuiti aritmetici e memorie

5. ARM assembly

L'architettura di un calcolatore definisce come esso viene visto dal programmatore. Tale architettura è definita in termini di set di istruzioni (linguaggio) e di locazione degli operandi (registri e memoria).

Le parole che costituiscono il linguaggio di un'architettura sono chiamate istruzioni, e il vocabolario delle possibili parole è l'instruction-set del calcolatore. Le istruzioni indicano:

  • L'operazione da eseguire
  • Gli operandi da usare, che si possono trovare in memoria, nei reistri o nelle istruzioni stesse

Bisogna precisare che l'architettura del calcolatore non definisce la sottostante struttura circuitale, che viene invece definita dalla microarchitettura.

L'architettura ARM rappresenta ogni istruzione con una parola di 32 bit e si basa su 4 principi fondamentali:

  1. La regolarità favorisce la semplicità
  2. Rendere veloci le cose frequenti
  3. Più piccolo è più veloce
  4. Un buon progetto richiede buoni compromessi

5.1. Operandi: registri, memoria e costanti

5.1.1. Registri

ARM ha 16 registri a 32 bit (R0… R15) fisicamente equivalenti tra loro ma logicamente utilizzati con scopi specifici

Name Use
R0 Argument / return value / temporary variable
R1-R3 Argument / temporary variables
R4-R11 Saved variables
R12 Temporary variable
R13 (SP) Stack Pointer
R14 (LR) Link Register
R15 (PC) Program Counter

5.1.2. Costanti/Immediati

Le costanti si possono definire attraverso l'istrusione MOV:

; R0 = a, R1 = b
mov R0, #23
mov R1, #0x45
//int: 32-bit signed word
int a = 23;
int b = 0x45;

Le costanti così generate hanno una precisione di massimo 8 bit.

Nota: MOV può anche essere usato per spostare il contenuto di un registro in un altro registro:

mov R7, R9

5.1.3. Memoria

5.2. Costrutti di selezione

5.2.1. if

5.2.2. if/else

5.2.3. switch/case

5.3. Cicli

5.3.1. While

5.3.2. For

5.4. Arrays

6. Microarchitettura

7. Memorie

Author: Gianmarco Davini

Created: 2025-01-21 Tue 22:13

Validate