| (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!  |