[email protected] 1 Contatore binario Un contatore binario è una rete sequenziale sincrona che memorizza un numero binario e lo incrementa a ogni fronte positivo del segnale do clock. Dunque un contatore conta i fronti positivi del segnale di clock. z=y Per sommare 1 a una configurazione di n bit bastano n half adder! 1 yn-1 .. 0 Stato presente (n variabili) + Rn CLK Yn-1 .. 0 Stato futuro (n variabili) 2 Contatore binario Contatore x2^n OUT n Se l’uscita del contatore è a n bit ( OUT[n-1 .. 0] ) le configurazioni d’uscita sono 2^n, quindi il valore massimo contato è 2^n -1. 0 2^n-1 1 2^n-2 2 … 3 Contatore binario per 16 In caso di contatore per 16 si scriverà: S k 1 ( S 1 mod 16 )k Visto che dobbiamo considerare gli stati k-esimi e che quando il contatore arriva alla configurazione 1111, ricomincia a contare da 0. CLK Q R4 D 1 + Quando il segnale CLK passa da 0 a 1 (fronte di salita) i 4 FFD del registro da 4 bit R4 leggono il valore su D e lo portano in uscita ( su Q). Negli intervalli di tempo in cui non ci sono fronti di salita su CLK, il valore di Q rimane l’ultimo valore campionato sul fronte di CLK, anche al variare di D. 4 Contatore binario x8 (3 bit) Vediamo ora come realizzare un contatore binario da 3 bit. Ci servirà un sommatore da 3 bit, che potrebbe essere realizzato con 3 full adder e 3 Flip Flop D (ognuno memorizza un bit) come da figura. Ma si noti che il CI è posto a 0 e l’operando B è posto a 1. Lo stesso risultato si può ottenere ponendo CI a 1 e B a 0. A questo punto si potrebbe semplificare grandemente la rete combinatoria eliminando l’operatore B e sostituendo i 3 FULLADDER con 3 HALF-ADDER CI 0 S 1 A B COUNT0 D Q CK CO CI S 0 A B COUNT1 D Q CK CO CI S 0 A B CO D Q COUNT2 CK CO 5 CLK Segnali di comando di un contatore Il contatore binario x8 della slide precedente non può essere controllato: appena acceso, il contatore inizia a contare ininterrottamente. Dunque abbiamo progettato un contatore perfettamente funzionante ma inutilizzabile! Il contatore diventa più interessante se possiamo controllarlo. Ipotizziamo a titolo di esempio i seguenti possibili comandi. I comandi dovranno essere SINCRONI, in modo da assicurare che, se la frequenza di clock è stata ben calcolata, sia soddisfatto il requisito sul tempo di set up minimo dell’ingresso D dei FF rispetto al fronte positivo del Clock: RESET – Il conteggio riparte da zero (qualunque sia il valore di conteggio corrente) ENABLE – Il contatore “conta” cioè incrementa il suo valore in risposta ai fronti positivi del clock solo se il comando di ENABLE è attivo, altrimenti il contatore mantiene il suo valore; ipotizziamo che il reset prevalga sull’enable UP/DOWN# – Se il contatore può contare sia in avanti che all’indietro (cioè se può sia incrementarsi che decrementarsi in risposta ai fronti positivi del clock), allora questo comando indica il senso del conteggio (1 in avanti e 0 all’indietro) INCREMENTO NON UNITARIO – L’equazione diventa S=S+k , dove k è un numero naturale inviato ad appositi ingressi LOAD – Il contatore viene inizializzato con un valore arbitrario inviato ad appositi 6 ingressi (quindi il contatore può partire anche da un valore diverso da zero) Segnali di comando di un contatore EN UP/DOWN# RESET# LOAD LD[2..0] CONTATORE x8 COUNT[2..0] CO 3 I comandi indicati nel lucido precedente sono solo esempi. L’unico ingresso necessario è l’ingresso di RESET che porta il contatore in uno stato iniziale ben definito. Gli altri comandi aggiungono flessibilità al contatore e possono esserci o non esserci. E’ sempre possibile immaginare anche altri possibili comandi. 7 Carry Out Il segnale di uscita CO (carry out dell’Half-Adder più significativo) segnala lo stato di fine-conteggio (111), e può essere lasciato volante oppure può essere utilizzato come ingresso sincrono di un’altra RSS Se si vuol far contare il contatore sia in avanti che all’indietro, allora si propone di realizzare la funzione G con tre FULL-ADDER, piuttosto che con 3 HALF-ADDER. In questo caso: Quando il contatore conta in avanti l’unico caso in cui si ha riporto sull’ultimo Full Adder è quando lo stato presente è 111: infatti in questo stato le uscite della rete dei full-adder daranno 111+1 = 000 con 1 sul carry out dell’ultimo full adder. Dunque CO vale 1 solo quando il contatore finisce di contare! Quando il contatore conta indietro, ad ogni conteggio somma 111 al suo stato presente, quindi c’è sempre un riporto sull’ultimo Carry Out tranne nel caso in cui lo stato presente è 000: infatti 000+111=111 senza riporto. In definitiva il CO vale 0 solo quando il contatore finisce di contare! In pratica se vogliamo sapere quando un contatore è nello stato di fineconteggio, possiamo tenere sotto controllo l’ultimo carry out, senza dover controllare il valore di conteggio; il segnale di fine conteggio si dovrà attivare quando UP/DOWN# e CO sono entrambi a 1 o entrambi a 0. 8 Reset Si può generare lo stato futuro del contatore con un mux da 3 bit a due vie controllato dal segnale di reset. Una via va messa a 0: Y[2..0] = 0.RESET + RESET/ . y[2..0] Dall’espressione si vede che il mux da 3 bit si riduce a tre AND a due ingressi Ogni variabile di stato futuro sarà zero se RESET=1, altrimenti sarà uguale all’altro ingresso dell’AND (uscita della rete dei 3 adder) In questa realizzazione il reset ha priorità su tutti gli altri comandi G D Q R3 RESET/ 9 Enable A lezione abbiamo visto che il comando di enable si può realizzare con un altro mux a due vie sull’ingresso D. Nel caso del nostro contatore proponiamo la seguente variante: si controlla con il segnale ENABLE l’ingresso CI dell’HALF-ADDER meno significativo EN CI S y0 Se CI=EN=0 -> U = I + 0 A CO Se CI=EN=1 -> U = I + 1 CI I U S y1 CO ove I rappresenta lo stato presente (il valore del contatore) e l’uscita U è il prossimo valore (determinato dagli half-adder) CI y2 S A CO CO 10 Up/Down# Il comando Up/Down# seleziona la modalità di conteggio del contatore. Se Up/Down# =1 : COUNT<=COUNT+1 sale a 7 e riparte da 0 Se Up/Down#=0 : COUNT<=COUNT-1 scende a 0 e riparte da 7 Modifichiamo il contatore con i tre Full-Adder in modo da consentirgli di decrementare il suo valore. Dobbiamo agire sulla funzione G: S k 1 ( (S 1) X X [ n 1..0 ]; 2C mod8 )k complement o a 2 X k X 2C (k) X ( k 1 ) Se X è un numero senza segno di n bit in complemento a due si ha: X ( 0 ..001 1 ) X 1 ..110 1 X 1 .. 111 n 1 n 1 n In pratica per sottrarre uno, basta sommare la configurazione di tutti 1, quindi se n=3 abbiamo che: X 001 X 111 11 Up/Down# Quindi: CI 1 se Up / Down# 1 B 000 CI 0 se Up / Down# 0 B 111 CI B0 B1 B2 UP/DOWN# EN 12 Load 3 1 3 3 CI 3 HA 3 3 S 1 A 3 L R3 CK LOAD RESET/ Il load è un caso generalizzato del reset: il reset memorizza nel registro di stato il valore 000, mentre LOAD memorizza un valore qualunque tra 000 e 111 L è il valore che verrà memorizzato in R3 ed è proprio da L che partirà il conteggio;mentre LOAD è il segnale di controllo che abilita la funzione di load. 13 Conteggio fino a X<2^n Una funzione molto utile nei contatori (specialmente in quelli a molti bit) è il conteggio fino ad un numero diverso dal valore massimo di conteggio. Una soluzione può essere quella di realizzare una rete che riconosca il numero X e generi un impulso sul pin di RESET per resettare il contatore. 3 RST CNT X La soluzione prevede la realizzazione di una rete aggiuntiva: il che può andare bene se X è un numero fissato (la rete è semplice) ma il tutto si complica se X è un numero che varia (la rete si complica troppo). Una soluzione più flessibile è quella di partire da X e arrivare a 0 (invece che da 0 a X). Il che è possibile grazie alla modalità di conteggio inversa (UP/DOWN’=0) e al comando di LOAD. EN 1 COUNT Quando COUNT=0 il UP/DWN’ 0 contatore si resetta al 3 valore X e ricomincia a LD X contare fino a 0 LOAD END_T Quale sarà l’espressione di END_T? 14 Contatore BCD Ci sono alcuni casi in cui, anche se la soluzione del conteggio da X a 0 sarebbe più semplice, bisogna per forza utilizzare una rete esterna per riconoscere il numero X e resettare il contatore: un caso del genere è il contatore BCD. Il contatore BCD è un contatore che conta da 0 a 9 (da 0000 a 1001), quindi è necessario usare un contatore x16 in cui lo stato futuro di 9 sia 0 (cioè che si resetti dopo il 9. In questo caso si usa una rete che decodifica lo stato 9 (mintermine m(9) di 4 variabili). Tale mintermine dovrà agire da reset sincrono del contatore. 15