Architettura dei calcolatori/Periferiche

Periferiche modifica

In un sistema di elaborazione sono considerati \emph{periferiche} tutti i componenti eccetto il processore e la memoria; possono essere \emph{periferiche interne}, che sono puramente elettroniche, svolgono le loro funzioni in corrispondenza di processore e memoria e sono montate sul bus di sistema (controllore delle interruzioni e DMA, porte di I/O, north bridge, adattatori per alcuni tipi di bus, \ldots), oppure \emph{periferiche esterne}, connesse al sistema tramite le periferiche interne e costituite spesso da un trasduttore elettromeccanico e da un controllore che interfaccia il trasduttore con il sistema.

\section{Alcune periferiche interne} \subsection{Porta parallela} La struttura varia a seconda delle funzioni richieste alla periferica stessa; nei casi semplici deve solo mettere in comunicazione il processore con il mondo esterno con un numero limitato di linee di connessione e senza particolari requisiti di temporizzazione dei segnali. In generale la porta parallela serve per trasferire dati bidirezionalmente tra un sistema di elaborazione ed il mondo esterno un byte alla volta; è costituita da linee per trasferimento dati e di sincronizzazione (sono linee multisegnali e necessitano di poca logica), possono essere con o senza handshake (le porte con handshake possono essere ottenute con pi\`u porte senza handshake).

La velocità di trasferimento è piuttosto bassa ed il colloquio è completamente asincrono; è tipicamente usata per connettere stampanti.

\subsection{Porta seriale asincrona} è simile alla porta parallela ma ha un minore numero di linee con temporizzazioni pi\`u complicate (almeno per il trasferimento di piccole unità di informazione); richiedono una rete sequenziale sincronizzata per essere gestite.

\section{Periferiche con requisiti temporali stretti} Per alcune applicazioni sono necessarie interfacce di I/O che garantiscano il trasferimento di informazioni con una cadenza costante; questo è necessario ogni volta che si ha un dispositivo che produce o consuma dati ad una velocità non controllabile dall'esterno: bisogna che sia rispettato un intervallo di tempo $\tau$ tra una transizione e l'altra.

Dispositivi che hanno queste necessità sono ad esempio memorie di massa con velocità di trasferimento fissa, dispositivi per il campionamento e la riproduzione di segnali, dispositivi real-time, dispositivi di comunicazione basati su multiplex temporale (in sistema può cumunicare in finestre temporali che si presentano ad intervalli regolari); in questi casi il sistema deve garantire l'esecuzione di una o pi\`u istruzioni di I/O con la cadenza richiesta.

è possibile dedicare il sistema a questo tipo di applicazioni (microcontrollori) e programmare il modulo master calcolando con accuratezza il tempo di esecuzione del programma in maniera che le temporizzazioni richieste siano rispettate: è necessario conoscere l'esatta durata delle fasi di fetch, decodifica, lettura operandi, esecuzione, scrittura e lettura in memoria e in I/O per ogni istruzione e pilotare ogni dispositivo a controllo di programma e effettuare cicli a vuoto per rispettare le temporizzazioni.

Questa tecnica è usata in piccoli sistemi dedicati che dispongono di un solo processore la cui unica funzione è quella di pilotare i dispositivi di I/O, ma non può essere usata in un sistema di elaborazione general purpose come una workstation perch\'e: \begin{itemize} \item il tempo di esecuzione di una sezione di programma non è facilmente calcolabile (ogni istruzione richiede un tempo diverso, hanno differente lunghezza e numero di operandi) e non è costante (ad esempio a causa della cache che rende imprevedibile il tempo di accesso alla memoria); \item l'esecuzione di un programma può essere interrotta dall'arrivo di un'interruzione che richiede per essere gestita un tempo imprevedibile a priori; \item un sistema multitasking non può essere unicamente dedicato alla gestione di una periferica. \end{itemize}

In un sistema di uso generale è comunque possibile pilotare periferiche con requisiti temporali stretti, a condizione che l'intervallo di pilotaggio $\tau$ non sia eccessivamente basso. Le temporizzazioni sono ricavare da un \emph{timer} che contiene un contatore pilotato a frequenza costante; questo è in grado di generare un segnale su un piedino apposito al termine del conteggio ed il valore del contatore è leggibile da alcune porte di I/O.

Il trasferimento di informazioni con cadenza costante si ottiene con due metodi diversi a seconda della frequenza con cui vanno effettuate le operazioni.

\subsection{Trasferimenti a bassa frequenza} Nel caso di trasferimenti lenti di dati (con $\tau$ elevato rispetto alla frequenza del processore) è possibile sfruttare il meccanismo dell'interruzione.

Il segnale proveniente dal timer è usato per generare una richiesta di interruzione al processore, che risponde mandando in esecuzione la routine di interrupt che esegue i trasferimenti richiesti e termina.

Il ritardo con cui la routine dal momento in cui è generata l'interruzione va in esecuzione non è determinabile con precisione (ci possono essere interruzioni a priorità maggiore, la routine attualmente in esecuzione può non essere interrompibile, \ldots), ma dipende dallo stato del processore nel momento in cui arriva la richiesta; questo causa un \emph{jitter} (ritardo variabile tra un'esecuzione e l'altra).

Per compensare il jitter si inserisce un registro aggiuntivo all'uscita della periferica che prende il valore di uscita nel momento in cui arriva l'interruzione successiva (l'uscita del timer, oltre a generare l'interruzione, è collegata all'ingresso strobe del registro; è possibile anche inserire un invertitore nel collegamento per evitare il jitter anche nel primo semiperiodo oltre che nel secondo).

Lo stato della periferica viene modificato con il programma di servizio dell'interruzione ed il trasferimento verso l'esterno è effettuato al successivo fronte in salita del timer; si introduce un ritardo nella produzione del dato (che deve essere anche maggiore del tempo $t_{propagation}$ del registro di uscita della periferica per evitare che il registro pilotato dal timer fotografi lo stato precedente)'

Il meccanismo dell'interruzione richiede l'effettuazione di un gran numero di operazioni (salvataggio dello stato del processore, \ldots) che fissano un limite alla frequenza massima ottenibile.

\subsection{Trasferimenti ad alta frequenza} Per diminuire l'intervallo di pilotaggio della periferica si usano trasferimenti in DMA; questo riduce l'overhead del sistema ma si ha ancora un jitter in quanto è necessario un certo tempo per l'arbitraggio del bus tra processore e controllore DMA.

L'interfaccia è attiva ed il registro passa il dato se arriva $/DACK$ dal controllore DMA o viene selezionato (è necessario disabilitare le maschere delle periferiche quando si fanno trasferimenti DMA da I/O a memoria)'

\section{Periferiche con trasferimenti a blocchi} Le periferiche che devono trasferire grandi quantità di dati sono pi\`u efficienti se si trasferiscono dati in blocchi di lunghezza fissa piuttosto che singoli byte; queste periferiche sono dotate di un controllore che trasferisce i dati dalla periferica ad una sua memoria dedicata che è anche accessibile dal processore (\emph{memorie dual-port}), la memoria può essere mappata nello spazio di memoria o di I/O.

\subsection{Memorie dual-port mappate nello spazio di memoria} Una memoria dual-port piccola rispetto allo spazio di indirizzamento del processore può essere completamente mappata nello spazio di memoria: processore e controllore accedono ad essa attraverso una circuiteria di controllo che effettua l'arbitraggio.

\subsection{Memorie dual-port mappate nello spazio di I/O} In questo caso la memoria è vista come memoria dal controllore ma come una periferica di I/O dal processore come alcune porte mappate nello spazio di I/O: questo consente di avere una memoria grande a piacimento ma complica il circuito di controllo che, per consentire il trasferimenti di un blocco a burst, deve avere tre porte nello spazio di I/O (buffer, indirizzo base ed indice) ed un contatore che provvede a generare gli indirizzi a partire dall'indirizzo base.

Questo metodo è usato per periferiche quali il controllore video, l'adattatore di rete, memorie di massa, interfacce per campionamento di segnali.