| (1) Il circuito per il calcolo del valore
assoluto e' sbagliato. Intanto uno XOR con un ingresso fisso a 0 lascia
solo passare immutato il segnale presente sull'altro ingresso (che nel
nostro caso sembrerebbe essere il bit di segno), e dunque non svolge
alcuna funzione. In secondo luogo, non si capisce per quale ragione
l'uscita di tale XOR debba pilotare l'Enable del registro: ma se il segno
e' positivo, il registro non viene neanche caricato! In terzo luogo, il
modulo FA (che immagino sia un Full Adder; ma perche' lasciare tutte
queste cose alla mia immaginazione, e non specificarle piu' chiaramente?)
ha un solo operando, quando sappiamo che un Full Adder di operandi ne ha
due. In quarto luogo, non e' chiara la logica di tutto il modulo: se il
bit di segno ha una certa polarita', lasciamo passare il dato immutato, se
ha la polarita' opposta lasciamo passare lo stesso dato col bit di segno
forzato a zero? (In parte, l'errore e' dato dal fatto che lei definisce
male i numeri negativi: ad esempio, -1 e' codificato come 1111...11, non
come 1000...00!)
Il valore assoluto di un intero N in complemento a 2 veiene generato
con la seguente logica: se il bit di segno e' 0 (numero positivo) si
lascia passare il numero N immutato, se il bit di segno e' 1 (numero
negativo) si lascia passare il complemento a due di N, che viene generato
complementando tutti i bit di N (cosa che indico con N*) e sommando
aritmeticamente 1. Sembrerebbe quindi ci sia bisogno di un multiplexer e
di un addizionatore i cui operandi siano la costante "000...00"
e N* e con CarryIn = 1. In realta' la cosa puo' essere resa ancora piu'
semplice, eliminando il multiplexer e mantenendo solo l'addizionatore: se
il bit di segno è zero, eseguiamo la somma aritmetica 0 + N + 0, mentre
se il bit di segno è 1 eseguiamo la somma aritmetica 0 + N* + 1. Il
circuito che ne deriva appare nel PDF allegato.

0612082046-1.pdf
(2) Dovendo immagazzinare solo numeri positivi, i due registri non
hanno bisogno di particolare inizializzazione se non di una messa a zero
all'inizio delle operazioni, e per questo e' sufficiente usare l'ingresso
di Clear asincrono.
(3) L'abilitazione al caricamento dei registri di massimo e di minimo,
invece, deve essere inibita quando il contatore ha raggiunto il Terminal
Count e dunque quando la sequenza di dati in esame e' terminata.
Attenzione, in tal caso lo stato 0 del contatore, essendo forzato dal
segnale di inizio operazioni, potrebbe essere uno stato
"speciale" di durata non necessariamente uguale a un periodo di
XCLK (questo clock e il System Clock a cui e' legato il segnale di inizio
operazioni *non*
sono correlati) e quindi potrebbe essere opportuno *non*
abilitare i registri di massimo/minimo al carimento in questo stato. Le
normali operazioni partirebbero allora col conteggio 1, e allora
attenzione al Terminal Count, che si setta al conteggio 1023 quando ancora
manca un dato alla fine della sequenza.
(4) Il flip-flop di Interrupt Request deve avere XCLK come clock,
mentre IACK deve andare sull'ingresso di Clear asincrono. Inolttre, IACK
deve anche abilitare l'emissione dell'Interrupt Vector Number sull'I/O
Data Bus.
(5) I vari SEL vanno generati da una decodifica dell'I/O Address Bus,
non dell'I/O Data Bus. Noti che uno stesso SEL puo' essere utilizzato sia
per la lettura (I/O Read) che per la scrittura (I/O Write); nel suo caso,
non e' necessario generare tre SEL distinti (SEL0, SEL1, SEL2) ma ne
bastano due.
Alla fine del procedimento di risoluzione le ho scritto un paio di
domande relative alla prova.
1) ad un certo punto il testo dice che la CPU calcola U e aggiorna
delle locazioni di memoria AMIN,BMAX,UMIN e Umax. Queste azioni mi
sembrano molto semplici da implementare, ma quello che volevo chiederLe
è se devo farle io. Il fatto che il testo dica: "La CPU calcola…."
mi ha portato a pensare che non devo occuparmene.
Quello che lei ha usato e' un testo d'esame per Calcolatori 2, in cui
il software PD-32 faceva parte del programma. Se lei fa parte del Nuovo
Ordinamento, in cui tale argomento non e' in programma, allora non se ne
deve occupare; se lei invece fa parte del Vecchio Ordinamento, in cui tale
argomento *era*
in programma, allora se ne dovra' occupare.
2) Nel mio tentativo di risolvere il problema mi sono accorto di
aver bisogno della collaborazione della CPU, la quale deve inviarmi 2
segnali. Uno di init per inizializzare i due registri Rmin e Rmax e
anche di un segnale che in qualche modo mi resetti il contatore, ovvero
un clear. Penso che questo dovrebbe essere il compito dello SCO.
Potrebbe, anche in linea di massima, dirmi come faccio a progettarlo?
Vedo dal progetto che lei usa una scrittura su porta fittizia (SEL0)
per generare il Clear del contatore: benissimo, lo stesso segnale puo'
anche inizializzare i registri. Quanto allo SCO: ma lei l'ha gia' fatto,
coincide praticamente col contatore modulo 1024, visto che il suo compito
e' proprio quello di enumerare gli stati operativi dell'interfaccia e,
quando e' arrivato al termine del conteggio, a stabilire che le operazioni
sono terminate! |