Tesi triennale - unipr.it

64
Universit` a degli Studi di Parma DIPARTIMENTO DI MATEMATICA E INFORMATICA Corso di Laurea in Informatica Tesi triennale Progettazione e realizzazione di un emulatore funzionale di componenti TTL per architetture complesse in linguaggio Java Design and implementation of a functional emulator of TTL components for complex architectures in Java Candidato: Laura Savino Matricola 212375 Relatore: Prof. Bergenti Federico Anno Accademico 2012–2013

Transcript of Tesi triennale - unipr.it

Universita degli Studi di Parma

DIPARTIMENTO DI MATEMATICA E INFORMATICA

Corso di Laurea in Informatica

Tesi triennale

Progettazione e realizzazione di un emulatore funzionaledi componenti TTL per architetture complesse

in linguaggio Java

Design and implementation of a functional emulatorof TTL components for complex architectures in Java

Candidato:

Laura SavinoMatricola 212375

Relatore:

Prof. Bergenti Federico

Anno Accademico 2012–2013

Indice

Indice i

Prefazione iiTecnologia TTL e la serie 74xx . . . . . . . . . . . . . . . . . . . . . iiiCPU di Eckert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

1 Componenti 1Codifica dei componenti TTL . . . . . . . . . . . . . . . . . . . . . 2TTL 7400 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3TTL 7402 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4TTL 7474 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5TTL 74138 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6TTL74181 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7EIA RS-232 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9MAX232 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Sviluppo del codice 13Connessione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

La classe SimulatedConnection . . . . . . . . . . . . . . . . . 14Clock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

La classe SimulatedClock . . . . . . . . . . . . . . . . . . . . 18Emulazione componenti TTL . . . . . . . . . . . . . . . . . . . . . 20

La classe SimulatedTTL7400 . . . . . . . . . . . . . . . . . . . 22La classe SimulatedTTL7402 . . . . . . . . . . . . . . . . . . . 25La classe SimulatedTTL7474 . . . . . . . . . . . . . . . . . . . 28La classe SimulatedTTL74138 . . . . . . . . . . . . . . . . . . 33La classe SimulatedTTL74181 . . . . . . . . . . . . . . . . . . 38

Comunicazione RS232 - architettura TTL . . . . . . . . . . . . . . . 51La classe SimulatedMAX232 . . . . . . . . . . . . . . . . . . . 52

Conclusioni e sviluppi futuri 56

Bibliografia 58

i

Prefazione

Il seguente lavoro di tesi si propone di illustrare il processo di realizzazioneper l’emulazione di una CPU secondo l’architettura di Eckert.

Per giungere a tale scopo si sono dapprima emulati una serie di compo-nenti TTL per poi combinarli e raggiungere una simulazione funzionaleper un’architettura complessa.

La scelta di tale argomento è stata dettata da diversi motivi:

- un interesse personale della sottoscritta, decisa ad approfondire al-cuni aspetti come il funzionamento a livello hardware di una CPU el’interazione software-hardware di un emulatore;

- un interesse accademico, in quanto solitamente l’interesse per emula-zioni di componenti TTL va a ricercare una profonda precisione main architetture semplici, piuttosto che sviluppare un interesse solo alivello funzionale, ma di oggetti più completi.

In seguito ad uno studio preliminare dei concetti di base necessari all’ap-proccio del progetto, si è conclusa la necessità di implementare emulatorifunzionali per ciascuno dei seguenti:

- un ALU;

- 5 diversi registri registri;

- una RAM;

- una ROM;

- il bus di collegamento.

Inoltre si è deciso di dare la possibilità di accedere all’emulatore anche dal-la rete andando ad implementare l’emulatore per una porta seriale RS-232.

Giunti a questo punto si è cominciato a selezionare i componenti ritenutinecessari per la realizzazione del progetto descritti nel capitolo 1 per poipassare all’implementazione di essi come analizzato nel capitolo 2.

ii

Prefazione

Tecnologia TTL e la serie 74xxPer la realizzazione funzionale dell’emulatore si è scelto di utilizzare com-ponenti Transistor-Transistor Logic inventata nel 1961.

Già dal 1963 sono stati prodotti i primi circuiti integrati commerciali con di-spositivi TTL e a partire dal 1964 la Texas Instruments introdusse sul mer-cato la serie 5400 e successivamente la serie 7400, una famiglia di circuitiintegrati comprendente un’ampia gamma di funzioni logiche.

La serie 7400 (anche nota come serie 74xx, dal prefisso costante dato adogni componente) divenne uno standard industriale, e molti, tra le qualiMotorola e National Semiconductor, cominciarono produrla; mentre alcu-ne industrie produssero dispositivi in questa tecnologia, molti dei qualicompatibili in modo diretto con la serie 7400, ma definendoli con sigle pro-prietarie, come la serie 9300 di Fairchild Semiconductor.

Vi furono diverse versioni successive di questa famiglia:

- la LS, relativamente veloce con consumi di corrente ridotti,

- la S, caratterizzata da maggiore velocità di commutazione a scapitodel consumo di corrente

- la C, direttamente in concorrenza con la serie 4000 in tecnologia CMOS,(stessa funzione con identica piedinatura) e consumi estremamentebassi

- la versione military con sigla 54xx, caratterizzata da un più ampiomargine di temperatura di lavoro garantita (-55 125 C° a differenzadella prima, limitata a 0 75 C°).

Il materiale del package di questa famiglia (come in altre), poteva essere inresina o ceramica (per la classe di temperatura con margine più esteso).

La TTL è una tecnologia importante ed estremamente diffusa perché gra-zie al suo basso costo rese economico l’utilizzo di approcci digitali laddoveprima si utilizzavano metodi analogici. Per fare alcuni esempi, il Kenbak-1, uno dei primi Personal Computer, usava chip TTL al posto di un singolomicroprocessore (che non esisteva ancora nel 1971) e uno degli ultimi com-puter ad utilizzare questa famiglia di chip fu l’Olivetti P6060 (presentatonel 1975), il quale aveva la CPU realizzata su una coppia di schede in vetro.

iii

Prefazione

CPU di Eckert

Figura 1: CPU di Eckert

La CPU di Eckert è costituita da

- un ALU a 12 bit con due registri dedicati anch’essi a 12 bit;

- una RAM a 8 bit anch’essa con due registri dedicati, entrambi a 12bit;

- un PC a 8 bit;

- una ROM anch’essa a 8 bit(non visibile nell’immagine);

- e un IR a 12 bit,

- il tutto collegato da un bus che può essere a 12 bit oppure a 8 bit;

dove i comandi in figura 1 corrispondono alle seguenti funzioni:

L (load) riempie il registro (carica);

E (enable) scrive il contenuto del registro sul bus;

A esegue una somma;

S calcola una differenza.

iv

1. Componenti

Per la realizzazione di questo lavoro si è scelto di utilizzare la famiglia dicircuiti integrati TTL 74xx per tre motivi principali:

- innanzitutto costituì uno standard de-facto nella disposizione dellapiedinatura (le varie famiglie con prestazioni migliorate sia nel con-sumo di corrente che in velocità di commutazione che succedettero aquesta, tranne qualche eccezione, mantennero la compatibilità dellapiedinatura);

- inoltre è composta da centinaia di dispositivi aventi tutte le funzioninecessarie: dalle porte logiche di base, ai i flip-flop, passando per icontatori, i transceiver di bus e le unità aritmetiche e logiche (ALU);

- infine i componenti della serie sono facilmente reperibili in una qual-che versione delle precedenti descritte.

Prima di arrivare a considerazioni relative al codice elaborato, nel capitolosuccessivo, andiamo ad esplorare un minimo come riconoscere un compo-nente della serie in analisi, nonché il funzionamento logico dei componentiche si è scelto di utilizzare in questo lavoro.Infine descriveremo come sia possibile trasmettere i dati ottenuti dal nostroinsieme di componenti a logica TTL con uno standard di tipo diverso, nellospecifico l’RS-232.

1

Componenti

Codifica dei componenti TTL

Figura 1.1: Circuito integrato TTL7400

Guardando la figura 1.1 che illustra il primo integrato della serie, il 7400(leggi 74-zero-zero), possiamo andare a descrivere la codifica standardiz-zata della serie:

- logo del costruttore (nella figura a destra: Texas Instruments);

- una o più lettere che identificano il costruttore (nella figura SN);

- il numero 74, tipico della famiglia logica;

- il numero 00, in altri casi costituito da più di due cifre, indicante lefunzioni logiche svolte dal dispositivo;

- una o più lettere indicanti il tipo di contenitore del dispositivo (PTHo SMD) (in figura N che indica un dispositivo detto DIP Dual in-line package, sempre meno usato nelle grosse produzioni e sostituitodalla versione SMD);

- segue, nella seconda riga, un codice che in genere indica settimana eanno di produzione (nella figura la 45° settimana dell’anno 1976);

- Sul retro dell’integrato vi sono talvolta altre indicazioni (lotto, stabi-limento di produzione ed eventuali altre informazioni).

2

Componenti

TTL 7400

Il primo della serie, l’integrato digitale 7400, è costituito da 14 piedini. Traessi abbiamo Vcc (14) collegato all’alimentazione +5V e GND (7) collegatoa massa, per poter alimentare i transistor che formano il circuito delle portelogiche, mentre gli altri sono suddivisi come:

Pin Nome Funzione

(1) D0a INPUT(2) D0b INPUT(4) D1a INPUT(5) D1b INPUT(8) D2a INPUT(9) D2b INPUT(11) D3a INPUT(12) D3b INPUT

Pin Nome Funzione

(3) Q0 OUTPUT(6) Q1 OUTPUT(10) Q2 OUTPUT(13) Q3 OUTPUT

Il 7400, contiene 4 porte logiche NAND, ciascuna indipendente rispetto allealtre. Realizza quindi 4 NAND su coppie di dati Da, Db in ingresso, resti-tuendo il risultato sull’output Q.

3

Componenti

TTL 7402

L’integrato digitale 7402 è costituito da 14 piedini. Come prima, tra essiabbiamo Vcc (14) collegato all’alimentazione +5V e GND (7) collegato amassa, per poter alimentare i transistor che formano il circuito delle portelogiche, mentre gli altri sono suddivisi come:

Pin Nome Funzione

(2) D0a INPUT(3) D0b INPUT(5) D1a INPUT(6) D1b INPUT(8) D2a INPUT(9) D2b INPUT(11) D3a INPUT(12) D3b INPUT

Pin Nome Funzione

(1) Q0 OUTPUT(4) Q1 OUTPUT(10) Q2 OUTPUT(13) Q3 OUTPUT

Il 7402, contiene 4 porte logiche NOR, ciascuna indipendente rispetto allealtre. Realizza quindi 4 NOR su coppie di dati Da, Db in ingresso, restituen-do il risultato sull’output Q.

4

Componenti

TTL 7474

Il 7474 è un dual positive edge triggered D-type flip-flop con 14 piedini.Ovviamente tra essi abbiamo Vcc (14) collegato all’alimentazione +5V eGND (7) collegato a massa, per poter alimentare i transistor che formano ilcircuito delle porte logiche, mentre gli altri sono suddivisi come:

INPUTPin Nome Funzione

(2) D0 dato(12) D1 dato(3) CP0 CLOCK(11) CP1 CLOCK(4) SD0 SET(10) SD1 SET(1) RD0 RESET(13) RD1 RESET

OUTPUTPin Nome Funzione

(5) Q0 risultato(6) Q0 risultato(8) Q1 risultato(9) Q1 risultato

Con il 7474 abbiamo che il dato in ingresso D, che soddisfa il set-up e man-tiene il clock in una transizione verso l’alto (low-to-high), viene memoriz-zato nel flip-flop e appare in output su Q.

5

Componenti

TTL 74138

L’integrato digitale 7402 è costituito da 16 piedini e va a realizzare un de-coder/demultiplexer con 3 linee in entrata e 8 in uscita. Come prima, traessi abbiamo Vcc (14) collegato all’alimentazione +5V e GND (7) collegatoa massa, per poter alimentare i transistor che formano il circuito delle portelogiche, mentre gli altri sono suddivisi come:

Pin Nome Funzione

(1) A SELEZIONE(2) B SELEZIONE(3) C SELEZIONE(5) G2A AUTORIZZAZIONE(6) G2B AUTORIZZAZIONE(8) G1 AUTORIZZAZIONE

Pin Nome Funzione

(7) Y7 OUTPUT(9) Y6 OUTPUT(10) Y5 OUTPUT(11) Y4 OUTPUT(12) Y3 OUTPUT(13) Y2 OUTPUT(14) Y1 OUTPUT(15) Y0 OUTPUT

Il decoder 74138 accetta tre ingressi di indirizzamento ponderati binari (A,B e C) e, quando attivato, fornisce 8 uscite active low (da Y0 a Y7) mutua-mente esclusive.

6

Componenti

TTL74181

Il 74181 è un ALU (Aritmethic Logic Unit) a 24 piedini. Di nuovo, tra essiabbiamo Vcc (14) collegato all’alimentazione +5V e GND (7) collegato amassa, per poter alimentare i transistor che formano il circuito delle portelogiche, mentre gli altri sono suddivisi come:

INPUTPin Nome Funzione

(1) B0 operando(2) A0 operando(18) B3 operando(19) A3 operando(20) B2 operando(21) A2 operando(22) B1 operando(23) A1 operando

INPUTPin Nome Funzione

(3) S3 SELEZIONE(4) S2 SELEZIONE(5) S1 SELEZIONE(6) S0 SELEZIONE(7) Cn SELEZIONE(8) M SELEZIONE

OUTPUTPin Nome Funzione

(9) F0 risultato operazioni(10) F1 risultato operazioni(11) F2 risultato operazioni(13) F3 risultato operazioni(14) A=B comparatore(15) P propagatore di riporto(17) G generatore di riporto(16) Cn+4 riporto

7

Componenti

L’ALU 74181 contiene l’equivalente di 75 porte logiche ed è in grado dieseguire tutte le tradizionali operazioni di somma/sottrazione/decremen-to con o senza riporto, così come AND/NAND,OR/NOR, XOR, e lo spo-stamento per un totale di 16 operazioni aritmetiche e 16 operazioni logichetra parole di 4 bit.

Sfortunatamente le operazioni di moltiplicazione e divisione non sono di-rettamente fornite, ma possono essere rese in step successivi utilizzandofunzioni di shifts, somme e sottrazioni. Allo stesso modo lo shift non è rea-lizzato come funzione esplicita ma può essere derivato da alcune funzionicome A plus A, dove plus è l’operazione di somma aritmetica.

Il 74181 realizza queste operazioni su due operandi da 4 bit generando unrisultato con riporto (in 22 nanosecondi).

8

Componenti

EIA RS-232

(a) Connettore maschile

(b) Connettore femminile

Figura 1.2: Disposizione pin porta seriale

Dal punto di vista hardware, una porta realizza di fatto un’interfaccia trauna macchina e altri computer o periferiche:

• fisicamente, una porta è un’uscita specializzata su una parte di appa-recchio a cui viene collegata una spina o un cavo;

• elettronicamente, i numerosi conduttori che compongono la presaforniscono un trasferimento del segnale tra i dispositivi.

L’EIA RS-232, o più semplicemente RS-232 o porta seriale, è uno standardeuropeo che definisce un’interfaccia seriale a bassa velocità di trasmissioneper lo scambio di dati tra dispositivi digitali.

9

Componenti

La comunicazione definita in tale standard è di tipo seriale asincrona:

• seriale perché le informazioni vengono inviate un bit alla volta;

• asincrona poiché l’invio non avviene in intervalli di tempo predefini-ti;

dunque il trasferimento dei dati può iniziare in qualsiasi momento ed ècompito del ricevitore rilevare quando un messaggio inizi e termini.Nel caso specifico si è presa in considerazione una porta con 9 piedini, siaper quanto riguarda il connettore maschio che per quello femmina (comeindicato in figura 1.2); in realtà i pin che vengono considerati nell’utilizzopratico sono solamente 3 (il secondo, il terzo e il quinto), come vedremopiù avanti.

Pin Descrizione

1 Portante in ricezione presente

2 Dati in ricezione

3 Dati in trasmissione

4 Dispositivo terminale pronto

5 Massa dei segnali

6 Dispositivo di comunicazione pronto

7 Richiesta di trasmissione

8 Pronto a trasmettere

9 Chiamata in arrivo

10

Componenti

MAX232

Figura 1.3: MAX232 della Maxim Integrated Products

La scelta dell’oggetto da emulare è ricaduta sul circuito integrato MAX-232, creato nel 1987 da Maxim Integrated Products, che converte i segnalida una porta seriale RS-232 in segnali adatti per l’uso in TTL circuiti logicidigitali compatibili.

Figura 1.4: Circuito integrato MAX232

Il MAX232 è costituito da 16 pins e dispone di due canali per la comu-nicazione RS-232 bidirezionali, nello specifico la tabella seguente spiegabrevemente il significato della piedinatura.

11

Componenti

Pin Descrizione

1Polo positivo del condensatore per il convertitore a pompa di carica

per generare la tensione positiva

2Uscita tensione positiva dello stadio di duplicazione

della tensione di alimentazione

3Polo negativo del condensatore per il convertitore a pompa di carica

per generare la tensione positiva

4Polo positivo del condensatore per il convertitore a pompa di carica

per generare la tensione negativa

5Polo negativo del condensatore per il convertitore a pompa di carica

per generare la tensione negativa

6Uscita tensione negativa dello stadio dell’inversione

della tensione di alimentazione

7 Uscita RS-232 canale 2

8 Ingresso RS-232 canale 2

9 Uscita TTL/CMOS canale 2

10 Ingresso TTL/CMOS canale 2

11 Ingresso TTL/CMOS canale 1

12 Uscita TTL/CMOS canale 1

13 Ingresso RS-232 canale 1

14 Uscita RS-232 canale 1

15 Segnale di massa

16 Positivo all’alimentazione

Inoltre, il MAX232, richiede solo +5Vcc anche per supportare, in trasmis-sione, lo standard RS-232. Ciò è possibile, grazie a due stadi convertitoriDC-DC, ovvero un elevatore di tensione a capacità, da +5Vcc a +12Vcc;cui segue uno stadio invertitore di polarità, sempre a capacità, da +12Vcca −12Vcc. Queste tensioni, poi sono poi rese disponibili per altri impieghial pin 2 (+12Vcc) e al pin 6 (−12Vcc).

Infine, i condensatori presenti collegati al circuito integrato permettono ilregolare funzionamento degli stadi convertitori DC-DC1.

1Circuito che converte una sorgente di corrente continua da una tensione a un’altra.

12

2. Sviluppo del codice

Il codice è stato realizzato utilizzando il linguaggio Java, mentre come am-biente di sviluppo integrato per la stesura e la strutturazione del progettosi è scelto di utilizzare l’IDE open source Eclipse.

La parte di sviluppo del codice si è divisa in blocchi, rispecchiati da unasuddivisione interna dell’intero progetto in pacchetti (laddove il progettodi base è raggruppato a sua volta nello specifico pacchetto da noi definitocom.bergenti.fmachines), distribuiti per la realizzazione di:

• alcuni modelli relativi all’emulazione hardware [pacchetto .model];

• un interfaccia specifica per ciascun componente TTL che deve essereemulato [pacchetto .model.ttl];

• due interfacce e due classi relative alla creazione e manipolazione dioggetti emulati [pacchetto .simulator];

• alcuni modelli relativi alla creazione e manipolazione per l’emulazio-ne hardware [pacchetto .simulator.model];

• emulatori di tipo funzionale per ciascun componente TTL necessarioalla realizzazione dell’architettura [pacchetto .simulator.model.ttl].

Tramite tale suddivisione siamo andati a creare la struttura del progetto ditesi, dopodiché l’abbiamo utilizzata per andare ad emulare i diversi com-ponenti.

Proseguiamo ora andando ad esporre ed analizzare la gerarchia e il funzio-namento delle classi implementate, tenendo conto del fatto che alcune diesse (e alcune loro funzioni) presentate non verranno esaminate in quantola denominazione risulta essere un completo commento alle loro semplicifunzionalità.

13

Sviluppo del codice

ConnessionePer la realizzazione di un emulatore dal punto di vista hardware, risultavanecessaria l’implementazione di un simulatore per la connessione dei com-ponenti dell’architettura. Essa è stata realizzata, come visibile in figura 2.1,tramite un’architetture a quattro livelli costituiti da classi così suddivise:

1. • un’interfaccia di definizione dei metodi basilari per la gestionedella connessione [Connection];

2. • una classe astratta che implementa l’interfaccia Connection condue campi protetti, costruttore e due funzioni di sovrascritturaper i metodi dell’interfaccia madre[AbstractConnection];

• un’interfaccia che eredita dall’interfaccia Connection per la ge-stione del contatto [Contact];

3. • una classe Java che realizza funzionalmente l’implementazionedella connessione [SimulatedConnection].

• un’interfaccia identificativa della messa a terra che eredita dal-l’interfaccia Contact [Ground];

• una classe astratta che implementa la classe Contact con un cam-po privato, costruttore, un metodo di sovrascrittura rispetto allafunzione dell’interfaccia Contact e un metodo proprio;

• un’interfaccia che definisce tre metodi base per l’emulazione diun pin.

4. una classe astratta che eredita dalla classe AbstractContact edimplementa l’interfaccia Pin con un campo privato, costruttoree una funzione di sovrascrittura per il metodo getNumber del-l’interfaccia Pin.

Andiamo ora ad analizzare la classe che realizza funzionalmente la connes-sione.

La classe SimulatedConnection

package com.bergenti.fmachines.simulator.model;2

import com.bergenti.fmachines.model.AbstractConnection;4

public class SimulatedConnection extends AbstractConnection {

Come possiamo vedere, dopo l’ importazione della classe astratta Abstrac-Connection (e la dichiarazione di appartenenza al pacchetto simulator.model),vediamo, come detto poco sopra, che la nostra classe SimulatedClock esten-de la classe astratta AbstractConnection ed è priva di campi personali.

14

Sviluppo del codice

Figu

ra2.

1:D

iagr

amm

ade

llecl

assi

inte

ress

ate

per

lage

stio

nee

l’em

ulaz

ione

della

conn

essi

one

15

Sviluppo del codice

6 public SimulatedConnection(SimulatedContact source ,SimulatedContact sink) {

super(source , sink);8

source.addConnection(this);10

sink.addConnection(this);12 }

Abbiamo poi il costruttore che, presi in input due parametri entrambi ditipo SimulatedContact identificativi rispettivamente della sorgente e delladestinazione per la connessione, va a richiamare il costruttore della classebase con i due valori ricevuti e collega la connessione sia alla sorgente chealla destinazione.

14 public void onLevelChanged(SimulatedContact contact) {if(contact == source) {

16 SimulatedContact other = (SimulatedContact)sink;

18 other.setDigitalLevel(contact.getDigitalLevel ());} else if(contact == sink) {

20 SimulatedContact other = (SimulatedContact)source;

22 other.setDigitalLevel(contact.getDigitalLevel ());}

24 }}

Infine la classe SimulatedContact possiede il metodo onLevelChanged (per-sonale, non di sovrascrittura) che, preso in input un oggetto di tipo Simu-

latedContact verifica:

• se il parametro in input è uguale alla sorgente allora

– inizializza un nuovo oggetto SimulatedContact di destinazione(dopo un opportuno casting);

– imposta il livello digitale dell’oggetto creato con quello del pa-rametro in input alla funzione;

• se il parametro in input è uguale alla destinazione allora

– inizializza un nuovo oggetto SimulatedContact con l’alimenta-zione (dopo un opportuno casting);

– imposta il livello digitale dell’oggetto creato con quello del pa-rametro in input alla funzione.

16

Sviluppo del codice

Clock

Figura 2.2: Diagramma delle classi per emulazione/gestione del clock

Per la realizzazione di un emulatore dal punto di vista hardware, risultavanecessaria l’implementazione di un simulatore per il clock dell’architettura.Esso è stato realizzato, come visibile in figura 2.2, tramite:

• un’interfaccia di definizione dei metodi basilari per la gestione delclock [Clock];

• un’interfaccia per la gestione delle sorgenti di evento [EventSource];

• una classe astratta che implementa l’interfaccia Clock con un campoprotetto, costruttore e una funzione di sovrascrittura per un metododella classe base[AbstractClock];

17

Sviluppo del codice

• una classe Java che realizza funzionalmente l’implementazione delclock [SimulatedClock].

Andiamo ora ad analizzare proprio quest’ultima classe (la più completa peruna breve trattazione riguardo la gestione/emulazione del clock).

La classe SimulatedClock

package com.bergenti.fmachines.simulator.model;2

import com.bergenti.fmachines.model.AbstractClock;4 import com.bergenti.fmachines.model.Contact;import com.bergenti.fmachines.simulator.EventSource;

6 import com.bergenti.fmachines.simulator.Simulator;

8 public class SimulatedClock extends AbstractClock implementsEventSource {

private long elapsedInNanos;10

private Contact output;

Dopo le importazioni necessarie (e la dichiarazione di appartenenza al pac-chetto simulator.model), vediamo, come detto poco sopra, che la nostra clas-se SimulatedClock estende la classe astratta AbstractClock e implemental’interfaccia EventSource; inoltre ha come campi privati due oggetti:

• uno di tipo long per misurare il tempo trascorso in nanosecondi

• l’altro di tipo Contact [riferimento sezione Connessione] per l’output.

12 public SimulatedClock(Simulator simulator , String name , intperiodInNanos) {

super(periodInNanos);14

this.elapsedInNanos = 0;16

this.output = new SimulatedContact(simulator , name + ".OUT");

18 }

Abbiamo poi il costruttore della classe che prende in input tre parametri,nello specifico un oggetto di tipo Simulator e una stringa che servirannoper la costruzione del simulatore, più un intero che identifica la durata delclock in nanosecondi; dopodichè

• richiama il costruttore della classe base utilizzando l’ultimo parame-tro in input;

• inizializza il campo relativo al tempo trascorso a zero;

• alloca l’oggetto privato di tipo Contact utilizzando i primi due para-metri in input e aggiungendo ad essi la stringa identificativa .OUT.

18

Sviluppo del codice

20 @Overridepublic Contact getOutput () {

22 return output;}

24

@Override26 public void timeElapsed(long timeInNanos) {

elapsedInNanos += timeInNanos;28

if(elapsedInNanos >= (periodInNanos / 2)) {30 elapsedInNanos = 0;

32 SimulatedContact simulatedOutput = (SimulatedContact)output;

34 simulatedOutput.toggleDigitalLevel ();}

36 }}

Infine la classe SimulatedContact sovrascrive i metodi:

• getOutput dell’interfaccia madre che semplicemente ritorna l’outputinizializzato nel costruttore;

• timeElapsed dell’interfaccia EventSource che, preso in input un in-tero rappresentante il tempo trascorso dall’ultima volta che è statachiamata la funzione (misurato in nanosecondi), va ad aggiornareil campo elapsedInNanos in dipendenza dal parametro passato allafunzione. Dopodiché se il tempo trascorso è maggiore o uguale dellametà della durata del clock lo va ad azzerare e, inizializzato un og-getto locale SimulatedContact con il campo output (dopo opportunocasting), va a modificare il livello digitale di quest’ultimo.

19

Sviluppo del codice

Emulazione componenti TTLL’emulazione di ciascun circuito integrato descritto nel capitolo 1 è stretta-mente legata alla gerarchia di tutto il progetto di tesi, escludendo la parterelativa al clock, dunque per avere un’idea della strutturazione alla basedelle classi che realizzazione l’emulazione funzionale dei nostri componen-ti riportiamo in figura 2.3 il diagramma delle classi coinvolte nell’emula-zione del circuito integrato, andando a scrivere il termine COMPONENT alposto della siglai di ciascun circuito.

Si tratta di una strutturazione a 6 livelli, in cui il primo (più in alto) è costi-tuito solamente da interfacce e alla base della piramide (il sesto livello, inbasso) troviamo la nostra classe cumulativa SimulatedCOMPONENT (al paridella classe per la simulazione della fonte di alimentazione).

Come si può facilmente notare per rendere possibile la simulazione del cir-cuito integrato di nostro interesse abbiamo precedentemente implementatoun’interfaccia che ne descrive la composizione con tutti i suoi pin e le fun-zioni di base.

Andiamo a vedere la realizzazione del codice, secondo la struttura presen-tata e analizzata, per i componenti che abbiamo realizzato:

• 7400 [NAND];

• 7402 [NOR];

• 7474 [FLIP-FLOP per l’implementazione dei registri];

• 74138 [3-8 decoder/DEMULTIPLEXER];

• 74181 [ALU];

• MAX232 [convertitore TTL – RS232].

20

Sviluppo del codice

Figu

ra2.

3:D

iagr

amm

ade

llecl

assi

inte

ress

ate

per

lage

stio

nee

l’em

ulaz

ione

deic

ompo

nent

iTTL

21

Sviluppo del codice

La classe SimulatedTTL7400

Analizziamo la classe che implementa un NAND logico su due valori ininput per quattro coppie di valori in ingresso.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.TTL7400;import com.bergenti.fmachines.simulator.EventSink;

6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;public class SimulatedTTL7400 extends SimulatedChip implements

TTL7400 , EventSink10

public SimulatedTTL7400(Simulator simulator , String name) {12 super(simulator , name , Package.DIP , 14);

14 for (int i = 0; i < pins.length; i++) {pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);16 }

}

dopodiché possiamo vedere che la nostra classe SimulatedTTL7402 ereditadalla SimulatedChip ed implementa le classi TTL7400 (il modello dell’og-getto) e EventSink, cioè la classe relativa alle modalità di gestione. La classeper l’emulatore non ha campi specifici e quindi ne vediamo direttamente ilcostruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

18 @Overridepublic void initialize () {

20 computeOutputs ();}

22

@Override24 public void onLevelChanged(SimulatedPin pin) {

computeOutputs ();26 }

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia TTL7400 implementata dal nostro emulatore.

22

Sviluppo del codice

private void computeOutputs () {28 SimulatedPin a = (SimulatedPin)get1A(), b = (SimulatedPin)

get1B();

30 if(a.isConnected () && b.isConnected ()) {boolean by = !(a.getDigitalLevel () && b.getDigitalLevel ()

);32

SimulatedPin y = (SimulatedPin)get1Y();34

y.setDigitalLevel(by);36 }

38 a = (SimulatedPin)get2A(); b = (SimulatedPin)get2B ();

40 if(a.isConnected () && b.isConnected ()) {boolean by = !(a.getDigitalLevel () && b.getDigitalLevel ()

);42

SimulatedPin y = (SimulatedPin)get2Y();44

y.setDigitalLevel(by);46 }

48 a = (SimulatedPin)get3A(); b = (SimulatedPin)get3B ();

50 if(a.isConnected () && b.isConnected ()) {boolean by = !(a.getDigitalLevel () && b.getDigitalLevel ()

);52

SimulatedPin y = (SimulatedPin)get3Y();54

y.setDigitalLevel(by);56 }

58 a = (SimulatedPin)get4A(); b = (SimulatedPin)get4B ();

60 if(a.isConnected () && b.isConnected ()) {boolean by = !(a.getDigitalLevel () && b.getDigitalLevel ()

);62

SimulatedPin y = (SimulatedPin)get4Y();64

y.setDigitalLevel(by);66 }

}

La funzione computeOutputs() è la funzione centrale dell’emulatore e, do-po aver inizializzato due oggetti locali per l’emulazione dei pin dedicatiall’input (che verranno sovrascritti ogni volta necessaria), realizza quattrovolte la stessa implementazione (poiché, come abbiamo visto nel capitolo 1,il 7400 realizza un NAND logico su 4 diverse coppie di input):

• dopo aver verificato che i due oggetti locali di tipo SimulatedPin sia-no connessi, ne estrapola il livello digitale e va a settare con la nega-zione dell’AND logico tra essi il rispettivo pin di output simulato;

• realizza i passi precedenti anche sulle restanti 3 coppie di pin di input.

23

Sviluppo del codice

68 @Overridepublic Pin getVCC () {

70 return getPin (14);}

72

@Override74 public Pin getGND () {

return getPin (7);76 }

78 @Overridepublic Pin get1A() {

80 return getPin (1);}

82

@Override84 public Pin get1B() {

return getPin (2);86 }

88 @Overridepublic Pin get1Y() {

90 return getPin (3);}

92

@Override94 public Pin get2A() {

return getPin (4);96 }

98 @Overridepublic Pin get2B() {

100 return getPin (5);}

102

@Override104 public Pin get2Y() {

return getPin (6);106 }

108 @Overridepublic Pin get3A() {

110 return getPin (9);}

112

@Override114 public Pin get3B() {

return getPin (10);116 }

118 @Overridepublic Pin get3Y() {

120 return getPin (8);}

122

@Override124 public Pin get4A() {

return getPin (12);126 }

128 @Override

24

Sviluppo del codice

public Pin get4B() {130 return getPin (13);

}132

@Override134 public Pin get4Y() {

return getPin (11);136 }

}

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

La classe SimulatedTTL7402

Analizziamo la classe che implementa un NAND logico su due valori ininput per quattro coppie di valori in ingresso.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.TTL7402;import com.bergenti.fmachines.simulator.EventSink;

6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;

public class SimulatedTTL7402 extends SimulatedChip implementsTTL7402 , EventSink {

10 public SimulatedTTL7402(Simulator simulator , String name) {super(simulator , name , Package.DIP , 14);

12

for (int i = 0; i < pins.length; i++) {14 pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);}

16 }

dopodiché possiamo vedere che la nostra classe SimulatedTTL7402 ereditadalla SimulatedChip ed implementa le classi TTL7402 (il modello dell’og-getto) e EventSink, cioè la classe relativa alle modalità di gestione. La classeper l’emulatore non ha campi specifici e quindi ne vediamo direttamente ilcostruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

@Override18 public void initialize () {

computeOutputs ();

25

Sviluppo del codice

20 }

22 @Overridepublic void onLevelChanged(SimulatedPin pin) {

24 computeOutputs ();}

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia TTL7402 implementata dal nostro emulatore.

26 private void computeOutputs () {SimulatedPin a = (SimulatedPin)get1A(), b = (SimulatedPin)

get1B();28

if(a.isConnected () && b.isConnected ()) {30 boolean by = !(a.getDigitalLevel () || b.getDigitalLevel ()

);

32 SimulatedPin y = (SimulatedPin)get1Y();

34 y.setDigitalLevel(by);}

36

a = (SimulatedPin)get2A();38

b = (SimulatedPin)get2B();40

if(a.isConnected () && b.isConnected ()) {42 boolean by = !(a.getDigitalLevel () || b.getDigitalLevel ()

);

44 SimulatedPin y = (SimulatedPin)get2Y();

46 y.setDigitalLevel(by);}

48

a = (SimulatedPin)get3A();50

b = (SimulatedPin)get3B();52

if(a.isConnected () && b.isConnected ()) {54 boolean by = !(a.getDigitalLevel () || b.getDigitalLevel ()

);

56 SimulatedPin y = (SimulatedPin)get3Y();

58 y.setDigitalLevel(by);}

60

a = (SimulatedPin)get4A();62

b = (SimulatedPin)get4B();64

if(a.isConnected () && b.isConnected ()) {66 boolean by = !(a.getDigitalLevel () || b.getDigitalLevel ()

);

68 SimulatedPin y = (SimulatedPin)get4Y();

26

Sviluppo del codice

70 y.setDigitalLevel(by);}

72 }

La funzione computeOutputs() è la funzione centrale dell’emulatore e, do-po aver inizializzato due oggetti locali per l’emulazione dei pin dedicatiall’input (che verranno sovrascritti ogni volta necessaria), realizza quattrovolte la stessa implementazione (poiché, come abbiamo visto nel capitolo 1,il 7402 realizza un NOR logico su 4 diverse coppie di input):

• dopo aver verificato che i due oggetti locali di tipo SimulatedPin

siano connessi, ne estrapola il livello digitale e va a settare con lanegazione dell’OR logico tra essi il rispettivo pin di output simulato;

• realizza i passi precedenti anche sulle restanti 3 coppie di pin di input.

@Override74 public Pin getVCC () {

return getPin (14);76 }

78 @Overridepublic Pin getGND () {

80 return getPin (7);}

82

@Override84 public Pin get1A() {

return getPin (2);86 }

88 @Overridepublic Pin get1B() {

90 return getPin (3);}

92

@Override94 public Pin get1Y() {

return getPin (1);96 }

98 @Overridepublic Pin get2A() {

100 return getPin (5);}

102

@Override104 public Pin get2B() {

return getPin (6);106 }

108 @Overridepublic Pin get2Y() {

110 return getPin (4);}

112

@Override114 public Pin get3A() {

27

Sviluppo del codice

return getPin (8);116 }

118 @Overridepublic Pin get3B() {

120 return getPin (9);}

122

@Override124 public Pin get3Y() {

return getPin (10);126 }

128 @Overridepublic Pin get4A() {

130 return getPin (11);}

132

@Override134 public Pin get4B() {

return getPin (12);136 }

138 @Overridepublic Pin get4Y() {

140 return getPin (13);}

142 }

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

La classe SimulatedTTL7474

Analizziamo la classe che implementa un flip-flop necessario per la realiz-zazione dei registri.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.TTL7474;import com.bergenti.fmachines.simulator.EventSink;

6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;

public class SimulatedTTL7474 extends SimulatedChip implementsTTL7474 , EventSink {

10 private boolean state1 = false;private boolean state2 = false;

12

public SimulatedTTL7474(Simulator simulator , String name) {14 super(simulator , name , Package.DIP , 14);

28

Sviluppo del codice

16 for (int i = 0; i < pins.length; i++) {pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);18 }

}

dopodiché possiamo vedere che la nostra classe SimulatedTTL74138 eredi-ta dalla SimulatedChip ed implementa le classi TTL74138 (il modello del-l’oggetto) e EventSink, cioè la classe relativa alle modalità di gestione. Laclasse per l’emulatore ha due campi specifici di tipo boolean necessari amantenere lo stato del clock e il costruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

20 @Overridepublic void initialize () {

22 computeOutputs ();}

24

@Override26 public void onLevelChanged(SimulatedPin pin) {

computeOutputs ();28 }

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia TTL74138 implementata dal nostro emulatore.

private void computeOutputs () {30 SimulatedPin PR1 = (SimulatedPin)getPR1 (), CLR1 = (

SimulatedPin)getCLR1 ();SimulatedPin CLK1 = (SimulatedPin)getCLK1 (), D1 = (

SimulatedPin)getD1();32

if(PR1.isConnected () && CLR1.isConnected () && CLK1.isConnected () && D1.isConnected ()) {

34

SimulatedPin Q1 = (SimulatedPin)getQ1(), cQ1 = (SimulatedPin)getcQ1 ();

36

if(Q1.isConnected () && cQ1.isConnected ()) {38

boolean pr1 = PR1.getDigitalLevel (), clr1 = CLR1.getDigitalLevel ();

40 boolean clk1 = CLK1.getDigitalLevel (), d1 = D1.getDigitalLevel ();

42 if(pr1 == false && clr1 == true) {Q1.setDigitalLevel(true);

44 cQ1.setDigitalLevel(false);}

46

else if(pr1 == true && clr1 == false) {

29

Sviluppo del codice

48 Q1.setDigitalLevel(false);cQ1.setDigitalLevel(true);

50 }

52 else if(pr1 == false && clr1 == false) {Q1.setDigitalLevel(true);

54 cQ1.setDigitalLevel(true);}

56

else if(pr1 == true && clr1 == true && d1 == true) {58 // transizione verso l’alto del clock clk1

if(clk1==true && state1 ==false) {60 Q1.setDigitalLevel(true);

cQ1.setDigitalLevel(false);62 }

}64

else if(pr1 == true && clr1 == true && d1 == false) {66 // transizione verso l’alto del clock clk1

if(clk1==true && state1 ==false) {68 Q1.setDigitalLevel(false);

cQ1.setDigitalLevel(true);70 }

}72

else if(pr1 == true && clr1 == true) {74 // non transizione verso l’alto del clock clk1

if(clk1!=true && state1 !=false) {76 // e necessario implementare l’hold?

// boolean q01 = Q1.getDigitalLevel (), cq01 = cQ1.getDigitalLevel ();

78 // Q1.setDigitalLevel(q01);// cQ1.setDigitalLevel(cq01);

80 }}

82

state1 = clk1;84 }

}86

SimulatedPin PR2 = (SimulatedPin)getPR2 (), CLR2 = (SimulatedPin)getCLR2 ();

88 SimulatedPin CLK2 = (SimulatedPin)getCLK2 (), D2 = (SimulatedPin)getD2();

90 if(PR2.isConnected () && CLR2.isConnected () && CLK2.isConnected () && D2.isConnected ()) {

92 SimulatedPin Q2 = (SimulatedPin)getQ2(), cQ2 = (SimulatedPin)getcQ2 ();

94 if(Q2.isConnected () && cQ2.isConnected ()) {

96 boolean pr2 = PR2.getDigitalLevel (), clr2 = CLR2.getDigitalLevel ();

boolean clk2 = CLK2.getDigitalLevel (), d2 = D2.getDigitalLevel ();

98

if(pr2 == false && clr2 == true) {100 Q2.setDigitalLevel(true);

cQ2.setDigitalLevel(false);102 }

30

Sviluppo del codice

104 else if(pr2 == true && clr2 == false) {Q2.setDigitalLevel(false);

106 cQ2.setDigitalLevel(true);}

108

else if(pr2 == false && clr2 == false) {110 Q2.setDigitalLevel(true);

cQ2.setDigitalLevel(true);112 }

114 else if(pr2 == true && clr2 == true && d2 == true) {// transizione verso l’alto del clock clk2

116 if(clk2==true && state2 ==false) {Q2.setDigitalLevel(true);

118 cQ2.setDigitalLevel(false);}

120 }

122 else if(pr2 == true && clr2 == true && d2 == false) {// transizione verso l’alto del clock clk2

124 if(clk2==true && state2 ==false) {Q2.setDigitalLevel(false);

126 cQ2.setDigitalLevel(true);}

128 }

130 else if(pr2 == true && clr2 == true && clk2 == false) {// non transizione verso l’alto del clock clk1

132 if(clk2!=true && state2 !=false) {// e necessario implementare l’hold?

134 // boolean q02 = Q2.getDigitalLevel (), cq02 = cQ2.getDigitalLevel ();

// Q2.setDigitalLevel(q02);136 // cQ2.setDigitalLevel(cq02);

}138 }

140 state2 = clk2;}

142 }}

La funzione computeOutputs() è la funzione centrale dell’emulatore e rea-lizza due volte la stessa implementazione:

• crea e inizializza 4 oggetti di tipo SimulatedPin necessari alla sele-zione dell’operazione da effettuare, nello specifico i pin di set, reset,clock input e dati in input;

• in caso i 4 precedenti siano tutti connessi crea ed inizializza altri dueoggetti di tipo SimulatedPin per il settaggio degli output, nello spe-cifico uno la negazione dell’altro;

• nel caso anche questi ulteriori 2 siano connessi implementa la tabellain figura 2.4 tramite una serie di controlli condizionali, nello specificoif - else if - else;

31

Sviluppo del codice

• aggiorna il valore del campo state con il livello digitale del pin rap-presentate il clock.

Figura 2.4: Tabella funzionale del TTL 7474

144 @Overridepublic Pin getVCC () {

146 return getPin (14);}

148

@Override150 public Pin getGND () {

return getPin (7);152 }

154 @Overridepublic Pin getCLR1 () {

156 return getPin (1);}

158

@Override160 public Pin getD1() {

return getPin (2);162 }

164 @Overridepublic Pin getCLK1 () {

166 return getPin (3);}

168

32

Sviluppo del codice

@Override170 public Pin getPR1 () {

return getPin (4);172 }

174 @Overridepublic Pin getQ1() {

176 return getPin (5);}

178

@Override180 public Pin getcQ1 () {

return getPin (6);182 }

184 @Overridepublic Pin getcQ2 () {

186 return getPin (8);}

188

@Override190 public Pin getQ2() {

return getPin (9);192 }

194 @Overridepublic Pin getPR2 () {

196 return getPin (10);}

198

@Override200 public Pin getCLK2 () {

return getPin (11);202 }

204 @Overridepublic Pin getD2() {

206 return getPin (12);}

208

@Override210 public Pin getCLR2 () {

return getPin (13);212 }

}

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

La classe SimulatedTTL74138

Analizziamo la classe che realizza un decoder/demultiplexer con 3 linee inentrata e 8 in uscita.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.TTL74138;

33

Sviluppo del codice

import com.bergenti.fmachines.simulator.EventSink;6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;

public class SimulatedTTL74138 extends SimulatedChip implementsTTL74138 , EventSink {

10 public SimulatedTTL74138(Simulator simulator , String name) {super(simulator , name , Package.DIP , 16);

12

for (int i = 0; i < pins.length; i++) {14 pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);}

16 }

dopodiché possiamo vedere che la nostra classe SimulatedTTL74138 ere-dita dalla SimulatedChip ed implementa le classi TTL74138 (il modellodell’oggetto) e EventSink, cioè la classe relativa alle modalità di gestio-ne. La classe per l’emulatore non ha campi specifici e quindi ne vediamodirettamente il costruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

@Override18 public void initialize () {

computeOutputs ();20 }

22 @Overridepublic void onLevelChanged(SimulatedPin pin) {

24 computeOutputs ();}

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia TTL74138 implementata dal nostro emulatore.

26 private void computeOutputs () {

28 SimulatedPin y0 = (SimulatedPin)getY0();y0.setDigitalLevel(true);

30 SimulatedPin y1 = (SimulatedPin)getY1();y1.setDigitalLevel(true);

32 SimulatedPin y2 = (SimulatedPin)getY2();y2.setDigitalLevel(true);

34 SimulatedPin y3 = (SimulatedPin)getY3();y3.setDigitalLevel(true);

36 SimulatedPin y4 = (SimulatedPin)getY4();

34

Sviluppo del codice

y4.setDigitalLevel(true);38 SimulatedPin y5 = (SimulatedPin)getY5();

y5.setDigitalLevel(true);40 SimulatedPin y6 = (SimulatedPin)getY6();

y6.setDigitalLevel(true);42 SimulatedPin y7 = (SimulatedPin)getY7();

y7.setDigitalLevel(true);44

SimulatedPin g1 = (SimulatedPin)getG1(), g2a = (SimulatedPin)getG2A (), g2b = (SimulatedPin)getG2B ();

46 SimulatedPin a = (SimulatedPin)getA(), b = (SimulatedPin)getB(), c = (SimulatedPin)getC();

48 if(g1.isConnected () && g2a.isConnected () && g2b.isConnected()) {

if (!(g1.getDigitalLevel ()) || (g2a.getDigitalLevel ()) ||(g2b.getDigitalLevel ())) {

50 }

52 else if (a.isConnected () && b.isConnected () && c.isConnected ()) {

boolean aa = a.getDigitalLevel ();54 boolean bb = b.getDigitalLevel ();

boolean cc = c.getDigitalLevel ();56

if(aa == false && bb == false && cc == false) {58 y0.setDigitalLevel(false);

}60

else if(aa == false && bb == false && cc == true) {62 y1.setDigitalLevel(false);

}64

else if(aa == false && bb == true && cc == false) {66 y2.setDigitalLevel(false);

}68

else if(aa == false && bb == true && cc == true) {70 y3.setDigitalLevel(false);

}72

else if(aa == true && bb == false && cc == false) {74 y4.setDigitalLevel(false);

}76

else if(aa == true && bb == false && cc == true) {78 y5.setDigitalLevel(false);

}80

else if(aa == true && bb == true && cc == false) {82 y6.setDigitalLevel(false);

}84

else {86 y7.setDigitalLevel(false);

}88 }

}90 }

La funzione computeOutputs() è la funzione centrale dell’emulatore e:

35

Sviluppo del codice

• crea 7 oggetti locali per l’emulazione dei pin dedicati all’output;

• inizializza il livello digitale di ciascun oggetto creato a true;

• crea e inizializza 3 oggetti di tipo SimulatedPin per le abilitazioni,nello specifico G1, G2A e G2B;

• crea e inizializza 3 oggetti di tipo SimulatedPin necessari alla sele-zione dell’operazione da effettuare, nello specifico A, B e C;

• in caso i 3 pin simulati dedicati alle abilitazioni siano connessi neestrapola il livello digitale;

• nel caso in cui anche i 3 pin di selezione siano connessi ne estrapola illivello digitale;

• implementa la tabella in figura 2.5 tramite una serie di controlli con-dizionali, nello specifico if - else if - else andando a settare afalse l’opportuno pin di output simulato.

Figura 2.5: Tabella funzionale del 74138

@Override92 public Pin getVCC () {

return getPin (16);94 }

96 @Overridepublic Pin getGND () {

98 return getPin (8);}

36

Sviluppo del codice

100

@Override102 public Pin getA() {

return getPin (1);104 }

106 @Overridepublic Pin getB() {

108 return getPin (2);}

110

@Override112 public Pin getC() {

return getPin (3);114 }

116 @Overridepublic Pin getG2A () {

118 return getPin (4);}

120

@Override122 public Pin getG2B () {

return getPin (5);124 }

126 @Overridepublic Pin getG1() {

128 return getPin (6);}

130

@Override132 public Pin getY7() {

return getPin (7);134 }

136 @Overridepublic Pin getY6() {

138 return getPin (9);}

140

@Override142 public Pin getY5() {

return getPin (10);144 }

146 @Overridepublic Pin getY4() {

148 return getPin (11);}

150

@Override152 public Pin getY3() {

return getPin (12);154 }

156 @Overridepublic Pin getY2() {

158 return getPin (13);}

160

@Override

37

Sviluppo del codice

162 public Pin getY1() {return getPin (14);

164 }

166 @Overridepublic Pin getY0() {

168 return getPin (15);}

170 }

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

La classe SimulatedTTL74181

Analizziamo la classe che implementa l’ALU, cuore dell nostro emulatore.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.TTL74181;import com.bergenti.fmachines.simulator.EventSink;

6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;

public class SimulatedTTL74181 extends SimulatedChip implementsTTL74181 , EventSink {

10 public SimulatedTTL74181(Simulator simulator , String name) {super(simulator , name , Package.DIP , 24);

12

for (int i = 0; i < pins.length; i++) {14 pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);}

16 }

dopodiché possiamo vedere che la nostra classe SimulatedTTL74138 ere-dita dalla SimulatedChip ed implementa le classi TTL74181 (il modellodell’oggetto) e EventSink, cioè la classe relativa alle modalità di gestio-ne. La classe per l’emulatore non ha campi specifici e quindi ne vediamodirettamente il costruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

@Override18 public void initialize () {

computeOutputs ();

38

Sviluppo del codice

20 }

22 @Overridepublic void onLevelChanged(SimulatedPin pin) {

24 computeOutputs ();}

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia TTL74181 implementata dal nostro emulatore.

26 private void computeOutputs () {

28 SimulatedPin S0 = (SimulatedPin)getS0(), S1 = (SimulatedPin)getS1();

SimulatedPin S2 = (SimulatedPin)getS2(), S3 = (SimulatedPin)getS3();

30

if(S0.isConnected () && S1.isConnected () && S2.isConnected ()&& S3.isConnected ()) {

32

SimulatedPin M = (SimulatedPin)getM(), C0 = (SimulatedPin)getC0();

34

if(M.isConnected () && C0.isConnected ()) {36

boolean s0 = S0.getDigitalLevel (), s1 = S1.getDigitalLevel ();

38 boolean s2 = S2.getDigitalLevel (), s3 = S3.getDigitalLevel ();

40 SimulatedPin A0 = (SimulatedPin)getA0(), A1 = (SimulatedPin)getA1();

SimulatedPin A2 = (SimulatedPin)getA2(), A3 = (SimulatedPin)getA3();

42

SimulatedPin B0 = (SimulatedPin)getB0(), B1 = (SimulatedPin)getB1();

44 SimulatedPin B2 = (SimulatedPin)getB2(), B3 = (SimulatedPin)getB3();

46 if(A0.isConnected () && A1.isConnected () && A2.isConnected () && A3.isConnected ()&& B0.isConnected () && B1.isConnected () && B2.

isConnected () && B3.isConnected ()) {48

boolean a0 = A0.getDigitalLevel (), a1 = A1.getDigitalLevel ();

50 boolean a2 = A2.getDigitalLevel (), a3 = A3.getDigitalLevel ();

52 boolean b0 = B0.getDigitalLevel (), b1 = B1.getDigitalLevel ();

boolean b2 = B2.getDigitalLevel (), b3 = B3.getDigitalLevel ();

54

SimulatedPin F0 = (SimulatedPin)getF0(), F1 = (SimulatedPin)getF1();

56 SimulatedPin F2 = (SimulatedPin)getF2(), F3 = (SimulatedPin)getF3();

39

Sviluppo del codice

58 SimulatedPin CNp4 = (SimulatedPin)getCNp4 ();

60 if(F0.isConnected () && F1.isConnected () && F2.isConnected () && F3.isConnected ()){

//M = high62 if(M.getDigitalLevel ()) {

setLogical(s0, s1, s2, s3, F0, F1, F2, F3, a0, a1, a2 , a3, b0, b1, b2, b3);

64

}66

// M = L (se ho riporto aggiungo 1 all’operazionenel commento della setAritmethical)

68 else {if(C0.isConnected ()) {

70 // imposta il riporto a 0 o 1 in base all’opportuno pin (C0)

int carry = C0.getDigitalLevel () ? 1 : 0;72

int A = setInput(a0, a1, a2, a3);74 int B = setInput(b0, b1, b2, b3);

76 setAritmethical(s0, s1, s2, s3, F0, F1, F2, F3,A, B, carry , CNp4);

78 }}

80 }}

82 }}

84 }

La funzione computeOutputs() è la funzione centrale dell’emulatore e rea-lizza due volte la stessa implementazione:

• crea e inizializza 4 oggetti di tipo SimulatedPin necessari alla sele-zione dell’operazione da effettuare;

• in caso i 4 precedenti siano tutti connessi crea ed inizializza altri dueoggetti di tipo SimulatedPin uno sempre necessario per selezione euno dedicato alla gestione di eventuale riporto, rispettivamente M eC0;

• nel caso anche questi ulteriori 2 siano connessi estrapola i livelli digi-tali dei primi 4 pin di selezione;

• crea e inizializza 8 oggetti di tipo SimulatedPin che identificano gliinput da elaborare e ne estrae il livello digitale;

• crea e inizializza 4 oggetti di tipo SimulatedPin che identificano glioutput da settare;

• crea e inizializza un ulteriore oggetto di tipo SimulatedPin per lagestione/propagazione di eventuali riporti;

40

Sviluppo del codice

• implementa la tabella in figura 2.6 tramite un controllo condiziona-le, nello specifico if - else, andando a richiamare la più opportunatra la funzione setLogical() e la setAritmethical(), più eventual-mente il metodo setInput().

public int setInput(boolean i0, boolean i1, boolean i2,boolean i3) {

86

int tmp = i0 ? 1 : 0;88 int I = tmp;

90 tmp = i1 ? 1 : 0;I = I + tmp * 2;

92

tmp = i2 ? 1 : 0;94 I = I + tmp * 4;

96 tmp = i3 ? 1 : 0;I = I + tmp * 8;

98

return I;100

}

Abbiamo poi la funzione setInput che, presi 4 valori di tipo boolean ininput, costruisce un intero con i parametri per svolgere le operazioni arit-metiche;

102 public void setOutput(int F, SimulatedPin F0, SimulatedPin F1, SimulatedPin F2, SimulatedPin F3 ,SimulatedPin CNp4) {

104

if(F!=-1) {106 boolean tmp = (F % 2) > 0 ? true : false;

108 F0.setDigitalLevel(tmp);

110 F = F / 2;tmp = (F % 2) > 0 ? true : false;

112 F1.setDigitalLevel(tmp);

114 F = F / 2;tmp = (F % 2) > 0 ? true : false;

116 F2.setDigitalLevel(tmp);

118 F = F / 2;tmp = (F % 2) > 0 ? true : false;

120 F3.setDigitalLevel(tmp);

122 if(F > 0) {CNp4.setDigitalLevel(true);

124 }}

126

else {128 F0.setDigitalLevel(true);

F1.setDigitalLevel(false);130 F2.setDigitalLevel(false);

F3.setDigitalLevel(true);

41

Sviluppo del codice

132 }

134 }

mentre, in maniera complementare a prima, la funzione setOutput(), presiin ingresso:

• un intero contente il risultato delle operazioni eseguite;

• 4 oggetti di tipo SimulatedPin rappresentanti i pin da settare con ilprimo parametro in input alla funzione;

• un ulteriore oggetti SimulatedPin per l’eventuale gestione/propaga-zione del riporto derivato dalle operazioni svolte;

ripartisce i 5 bit per l’output dall’intero calcolato tramite operazioni aritme-tiche.

public void setLogical(boolean s0 , boolean s1, boolean s2,boolean s3,

136 SimulatedPin F0, SimulatedPin F1, SimulatedPin F2,SimulatedPin F3,

boolean a0, boolean a1, boolean a2, boolean a3,138 boolean b0, boolean b1, boolean b2, boolean b3) {

140 if(s3 == false && s2 == false && s1 == false && s0 == false){

// F = not A142 F0.setDigitalLevel (!a0);

F1.setDigitalLevel (!a1);144 F2.setDigitalLevel (!a2);

F3.setDigitalLevel (!a3);146

}148

else if(s3 == false && s2 == false && s1 == false && s0 ==true) {

150 // F = not(A+B)F0.setDigitalLevel (!(a0 || b0));

152 F1.setDigitalLevel (!(a1 || b1));F2.setDigitalLevel (!(a2 || b2));

154 F3.setDigitalLevel (!(a3 || b3));}

156

else if(s3 == false && s2 == false && s1 == true && s0 ==false) {

158 // F = not(A)BF0.setDigitalLevel ((!a0) && b0);

160 F1.setDigitalLevel ((!a1) && b1);F2.setDigitalLevel ((!a2) && b2);

162 F3.setDigitalLevel ((!a3) && b3);}

164

else if(s3 == false && s2 == false && s1 == true && s0 ==true) {

166 // F = false (logical zero)F0.setDigitalLevel(false);

168 F1.setDigitalLevel(false);F2.setDigitalLevel(false);

42

Sviluppo del codice

170 F3.setDigitalLevel(false);}

172

else if(s3 == false && s2 == true && s1 == false && s0 ==false) {

174 // F = not (AB)F0.setDigitalLevel (!(a0 && b0));

176 F1.setDigitalLevel (!(a1 && b1));F2.setDigitalLevel (!(a2 && b2));

178 F3.setDigitalLevel (!(a3 && b3));}

180

else if(s3 == false && s2 == true && s1 == false && s0 ==true) {

182 // F = not BF0.setDigitalLevel (!b0);

184 F1.setDigitalLevel (!b1);F2.setDigitalLevel (!b2);

186 F3.setDigitalLevel (!b3);}

188

else if(s3 == false && s2 == true && s1 == true && s0 ==false) {

190 // F = A XOR BF0.setDigitalLevel(a0 ^ b0);

192 F1.setDigitalLevel(a1 ^ b1);F2.setDigitalLevel(a2 ^ b2);

194 F3.setDigitalLevel(a3 ^ b3);}

196

else if(s3 == false && s2 == true && s1 == true && s0 == true) {

198 // F = Anot(B)F0.setDigitalLevel(a0 && (!b0));

200 F1.setDigitalLevel(a1 && (!b1));F2.setDigitalLevel(a2 && (!b2));

202 F3.setDigitalLevel(a3 && (!b3));}

204

else if(s3 == true && s2 == false && s1 == false && s0 ==false) {

206 // F = not(A) + BF0.setDigitalLevel ((!a0) || b0);

208 F1.setDigitalLevel ((!a1) || b1);F2.setDigitalLevel ((!a2) || b2);

210 F3.setDigitalLevel ((!a3) || b3);}

212

else if(s3 == true && s2 == false && s1 == false && s0 ==true) {

214 // F = not(A XOR B)F0.setDigitalLevel (!(a0 ^ b0));

216 F1.setDigitalLevel (!(a1 ^ b1));F2.setDigitalLevel (!(a2 ^ b2));

218 F3.setDigitalLevel (!(a3 ^ b3));}

220

else if(s3 == true && s2 == false && s1 == true && s0 ==false) {

222 // F = BF0.setDigitalLevel(b0);

224 F1.setDigitalLevel(b1);

43

Sviluppo del codice

F2.setDigitalLevel(b2);226 F3.setDigitalLevel(b3);

}228

else if(s3 == true && s2 == false && s1 == true && s0 == true) {

230 // F = ABF0.setDigitalLevel(a0 && b0);

232 F1.setDigitalLevel(a1 && b1);F2.setDigitalLevel(a2 && b2);

234 F3.setDigitalLevel(a3 && b3);}

236

else if(s3 == true && s2 == true && s1 == false && s0 ==false) {

238 // F = true (logical 1)F0.setDigitalLevel(true);

240 F1.setDigitalLevel(true);F2.setDigitalLevel(true);

242 F3.setDigitalLevel(true);}

244

else if(s3 == true && s2 == true && s1 == false && s0 == true) {

246 // F = A + not(B)F0.setDigitalLevel(a0 || (!b0));

248 F1.setDigitalLevel(a1 || (!b1));F2.setDigitalLevel(a2 || (!b2));

250 F3.setDigitalLevel(a3 || (!b3));}

252

else if(s3 == true && s2 == true && s1 == true && s0 == false) {

254 // F = A + BF0.setDigitalLevel(a0 || b0);

256 F1.setDigitalLevel(a1 || b1);F2.setDigitalLevel(a2 || b2);

258 F3.setDigitalLevel(a3 || b3);}

260

else {262 // F = A

F0.setDigitalLevel(a0);264 F1.setDigitalLevel(a1);

F2.setDigitalLevel(a2);266 F3.setDigitalLevel(a3);

}268 }

Vediamo ora la funzione setLogical(), fondamentale per il funzionamen-to del metodo computeOutputs(); essa

• prende in input i 4 bit di selezione dell’operazione, i 4 pin simulati perl’output, i 4 bit per la prima variabile in input e i 4 bit per la secondavariabile in input;

• setta i valori di output ottenuti tramite operazioni logiche secondo latabella in figura 2.6 tramite una serie di controlli condizionali, nellospecifico if - else if - else.

44

Sviluppo del codice

public void setAritmethical(boolean s0 , boolean s1, boolean s2,boolean s3,

270 SimulatedPin F0, SimulatedPin F1, SimulatedPin F2,SimulatedPin F3,

int A, int B, int carry , SimulatedPin CNp4) {272

if(s0 == false && s1 == false && s2 == false && s3 == false) {

274 // F = Aint F = A + carry;

276 setOutput(F, F0, F1, F2, F3, CNp4);

278 }

280 else if(s0 == false && s1 == false && s2 == false && s3 ==true) {

// F = A + B282 int F = (A ^ B) + carry;

setOutput(F, F0, F1, F2, F3, CNp4);284

}286

else if(s0 == false && s1 == false && s2 == true && s3 ==false) {

288 // F = A + not(B)int F = (A ^ (~B)) + carry;

290 setOutput(F, F0, F1, F2, F3, CNp4);

292 }

294 else if(s0 == false && s1 == false && s2 == true && s3 ==true) {

// F = minus 1 (2s Comp)296 int F = (-1) + carry;

setOutput(F, F0, F1, F2, F3, CNp4);298

}300

else if(s0 == false && s1 == true && s2 == false && s3 ==false) {

302 // F = A plus (A*(notB))int F = A + (A & (~B)) + carry;

304 setOutput(F, F0, F1, F2, F3, CNp4);

306 }

308 else if(s0 == false && s1 == true && s2 == false && s3 ==true) {

// F = (A + B) plus A*(notB)310 int F = (A ^ B) + (A & (~B)) + carry;

setOutput(F, F0, F1, F2, F3, CNp4);312

}314

else if(s0 == false && s1 == true && s2 == true && s3 ==false) {

316 // F = A minus B minus 1int F = A - B - 1 + carry;

318 setOutput(F, F0, F1, F2, F3, CNp4);

320 }

45

Sviluppo del codice

322 else if(s0 == false && s1 == true && s2 == true && s3 ==true) {

// F = A*(notB) minus 1324 int F = (A & (~B)) - 1 + carry;

setOutput(F, F0, F1, F2, F3, CNp4);326

}328

else if(s0 == true && s1 == false && s2 == false && s3 ==false) {

330 // F = A plus A*Bint F = A + (A & B) + carry;

332 setOutput(F, F0, F1, F2, F3, CNp4);

334 }

336 else if(s0 == true && s1 == false && s2 == false && s3 ==true) {

// F = A plus B338 int F = A + B + carry;

setOutput(F, F0, F1, F2, F3, CNp4);340

}342

else if(s0 == true && s1 == false && s2 == true && s3 ==false) {

344 // F = (A + not(B)) plus A*Bint F = (A ^ (~B)) + (A & B) + carry;

346 setOutput(F, F0, F1, F2, F3, CNp4);

348 }

350 else if(s0 == true && s1 == false && s2 == true && s3 ==true) {

// F = A*B minus 1352 int F = (A & B) - 1 + carry;

setOutput(F, F0, F1, F2, F3, CNp4);354

}356

else if(s0 == true && s1 == true && s2 == false && s3 ==false) {

358 // F = A plus A* (each bit is shifted to the next moresignificant position)

int F = A + A + carry;360 setOutput(F, F0, F1, F2, F3, CNp4);

362 }

364 else if(s0 == true && s1 == true && s2 == false && s3 ==true) {

// F = (A + B) plus A366 int F = (A ^ B) + A + carry;

setOutput(F, F0, F1, F2, F3, CNp4);368

}370

else if(s0 == true && s1 == true && s2 == true && s3 ==false) {

372 // F = (A + not(B)) plus Aint F = (A ^ (~B)) + A + carry;

46

Sviluppo del codice

374 setOutput(F, F0, F1, F2, F3, CNp4);

376 }

378 else {// F = A minus 1

380 int F = A - 1 + carry;setOutput(F, F0, F1, F2, F3, CNp4);

382

}384

}

Continuiamo con la funzione setAritmethical(), anch’essa fondamentaleper il funzionamento del metodo computeOutputs(); la quale

• prende in input i valori dei 4 bit di selezione dell’operazione, nellospecifico s0, s1, s2 e s3;

• i 4 pin simulati per l’output, nello specifico F0, F1, F2 e F3;

• un intero rappresentante la prima variabile, nello specifico A;

• un intero rappresentante la seconda variabile, nello specifico B;

• il valore del riporto in input e il pin simulato per il riporto in output,rispettivamente C0 e CNp4;

• setta i valori di output ottenuti tramite operazioni aritmetiche secon-do la tabella in figura 2.5 tramite una serie di controlli condizionali,nello specifico if - else if - else.

Osservazioni sulla tabella 2.6

• Con + si intende una somma esclusiva bit a bit (che non genera ripor-to);

• con plus una somma aritmetica;

• con * un prodotto bit a bit (che non genera riporto);

• con minus una sottrazione aritmetica;

• con not una negazione bit a bit.

Inoltre, nel caso Cn = L (nell’implementazione delle operazioni aritmeti-che), sarà sufficiente sottrarre 1 al risultato mostrato in tabella.

386 @Overridepublic Pin getVCC () {

388 return getPin (24);}

390

@Override

47

Sviluppo del codice

Figura 2.6: Tabella funzionale in caso di operazioni aritmetiche per il 74181

392 public Pin getGND () {return getPin (12);

394 }

396 @Overridepublic Pin getB0() {

398 return getPin (1);}

400

@Override402 public Pin getA0() {

return getPin (2);404 }

406 @Overridepublic Pin getS3() {

408 return getPin (3);}

410

@Override412 public Pin getS2() {

return getPin (4);414 }

48

Sviluppo del codice

416 @Overridepublic Pin getS1() {

418 return getPin (5);}

420

@Override422 public Pin getS0() {

return getPin (6);424 }

426 @Overridepublic Pin getC0() {

428 return getPin (7);}

430

@Override432 public Pin getM() {

return getPin (8);434 }

436 @Overridepublic Pin getF0() {

438 return getPin (9);}

440

@Override442 public Pin getF1() {

return getPin (10);444 }

446 @Overridepublic Pin getF2() {

448 return getPin (11);}

450

@Override452 public Pin getF3() {

return getPin (12);454 }

456 @Overridepublic Pin getAeqB () {

458 return getPin (14);}

460

@Override462 public Pin getP() {

return getPin (15);464 }

466 @Overridepublic Pin getCNp4 () {

468 return getPin (16);}

470

@Override472 public Pin getG() {

return getPin (17);474 }

476 @Overridepublic Pin getB3() {

49

Sviluppo del codice

478 return getPin (18);}

480

@Override482 public Pin getA3() {

return getPin (19);484 }

486 @Overridepublic Pin getB2() {

488 return getPin (20);}

490

@Override492 public Pin getA2() {

return getPin (21);494 }

496 @Overridepublic Pin getB1() {

498 return getPin (22);}

500

@Override502 public Pin getA1() {

return getPin (23);504 }

506 }

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

50

Sviluppo del codice

Comunicazione RS-232 - architettura TTL

Figura 2.7: Schema di realizzazione della comunicazione RS-232 - TTL

La figura 2.7 rappresenta la strutturazione di base di collegamento tra unaporta seriale1 e un MAX2322.

Qui vediamo un MAX232 che realizza ricezione e trasferimenti di dati, col-legato ad un connettore RS-232 che invia dati su un cavo seriale (serial cable);in questo modo e grazie all’interazione dei componenti i risultati ottenutiin logica TTL possono essere trasmessi secondo lo standard RS-232.

1Sezione di riferimento 1.2Sezione di riferimento 1.

51

Sviluppo del codice

La classe SimulatedMAX232

Analizziamo la classe relativa all’implementazione del convertitore TTL –RS232.

package com.bergenti.fmachines.simulator.model.ttl;2

import com.bergenti.fmachines.model.Pin;4 import com.bergenti.fmachines.model.ttl.MAX232;import com.bergenti.fmachines.simulator.EventSink;

6 import com.bergenti.fmachines.simulator.Simulator;import com.bergenti.fmachines.simulator.model.SimulatedChip;

8 import com.bergenti.fmachines.simulator.model.SimulatedPin;

Innanzitutto abbiamo le importazioni necessarie per i modelli di riferimen-to usati nella creazione/utilizzo di tutti gli elementi emulati e la dichiara-zione di appartenenza al pacchetto simulator.model.ttl;public class SimulatedMAX232 extends SimulatedChip implements

MAX232 , EventSink {10 public SimulatedMAX232(Simulator simulator , String name) {

super(simulator , name , Package.DIP , 14);12

for (int i = 0; i < pins.length; i++) {14 pins[i] = new SimulatedPin(this , name + "." + PIN_NAMES[i

], i + 1);}

16 }

dopodiché possiamo vedere che la nostra classe SimulatedMAX232 ereditadalla SimulatedChip ed estende le classi MAX232 (il modello dell’oggetto) eEventSink, cioè la classe relativa alle modalità di gestione.

La classe per l’emulatore non ha campi specifici e quindi ne vediamo diret-tamente il costruttore; esso

• richiama il costruttore della classe base;

• crea l’array contente i valori dei corrispondenti pin dell’oggetto fisico.

@Override18 public void initialize () {

computeOutputs ();20 }

22 @Overridepublic void onLevelChanged(SimulatedPin pin) {

24 computeOutputs ();}

Abbiamo poi due funzioni sovrascritte rispetto alla classe base che sempli-cemente vanno a richiamare il metodo computeOutputs(); la loro imple-mentazione è necessaria in quanto vengono dichiarate all’interno dell’in-terfaccia MAX232 implementata dal nostro emulatore.

52

Sviluppo del codice

26 private void computeOutputs () {SimulatedPin T1IN = (SimulatedPin)getT1IN (), T2IN = (

SimulatedPin)getT2IN ();28

if(T1IN.isConnected ()) {30 boolean t1in = T1IN.getDigitalLevel ();

32 SimulatedPin T1OUT = (SimulatedPin)getT1OUT ();

34 T1OUT.setDigitalLevel (!t1in);}

36

if(T2IN.isConnected ()) {38 boolean t2in = T2IN.getDigitalLevel ();

40 SimulatedPin T2OUT = (SimulatedPin)getT2OUT ();

42 T2OUT.setDigitalLevel (!t2in);}

44

SimulatedPin R1IN = (SimulatedPin)getR1IN (), R2IN = (SimulatedPin)getR2IN ();

46

if(R1IN.isConnected ()) {48 boolean r1in = R1IN.getDigitalLevel ();

50 SimulatedPin R1OUT = (SimulatedPin)getR1OUT ();

52 R1OUT.setDigitalLevel (!r1in);}

54

if(R2IN.isConnected ()) {56 boolean r2in = R2IN.getDigitalLevel ();

58 SimulatedPin R2OUT = (SimulatedPin)getR2OUT ();

60 R2OUT.setDigitalLevel (!r2in);}

62 }

La funzione computeOutputs() è la funzione centrale dell’emulatore e rea-lizza due volte la stessa implementazione (poiché, come abbiamo visto nelcapitolo 1, il MAX232 realizza due canali di comunicazione):

• crea i simulatori per i due pin dedicati all’input;

• dopo aver verificato che il primo sia connesso, ne estrapola il livellodigitale e va a settare con la negazione logica di esso il rispettivo pindi output simulato;

• realizza il passo precedente anche sul secondo pin di input.

public boolean returnOutput1 () {64 SimulatedPin T1OUT = (SimulatedPin)getT1OUT ();

return T1OUT.getDigitalLevel ();66 }

68 public boolean returnOutput2 () {

53

Sviluppo del codice

SimulatedPin T2OUT = (SimulatedPin)getT2OUT ();70 return T2OUT.getDigitalLevel ();

}

Le due funzioni che vediamo qui sopra possono essere trattate insieme inquanto, di fatto, gemelle; esse semplicemente restituiscono gli output dainviare.

Risulta necessaria una precisazione, dal punto di vista logico dovrebbe-ro restituire il dato in RS-232, ma dal punto di vista funzionale del nostroprogetto ci sono sufficienti due oggetti di tipo boolean in quanto la nostraporta seriale (a cui collegare il MAX232) sarà trasparente a livello di codice.

72 @Overridepublic Pin getVCC () {

74 return getPin (16);}

76

@Override78 public Pin getGND () {

return getPin (15);80 }

82 @Overridepublic Pin getC1p () {

84 return getPin (1);}

86

@Override88 public Pin getVsp () {

return getPin (2);90 }

92 @Overridepublic Pin getC1n () {

94 return getPin (3);}

96

@Override98 public Pin getC2p () {

return getPin (4);100 }

102 @Overridepublic Pin getC2n () {

104 return getPin (5);}

106

@Override108 public Pin getVsn () {

return getPin (6);110 }

112 @Overridepublic Pin getT2OUT () {

114 return getPin (7);}

116

@Override

54

Sviluppo del codice

118 public Pin getR2IN () {return getPin (8);

120 }

122 @Overridepublic Pin getR2OUT () {

124 return getPin (9);}

126

@Override128 public Pin getT2IN () {

return getPin (10);130 }

132 @Overridepublic Pin getT1IN () {

134 return getPin (11);}

136

@Override138 public Pin getR1OUT () {

return getPin (12);140 }

142 @Overridepublic Pin getR1IN () {

144 return getPin (13);}

146

@Override148 public Pin getT1OUT () {

return getPin (14);150 }

Infine abbiamo tutti i metodi di restituzione per ogni specifico pin dell’e-mulatore.

55

Conclusioni e sviluppi futuri

Il presente progetto di tesi mira a fornire un’impostazione gerarchica per larealizzazione di un emulatore hardware di componenti TTL di tipo funzio-nale per architetture complesse secondo il modello di Eckert.

Dopo una prima breve introduzione sulla tecnologia Transistor-TransistorLogic, la serie di componenti 74xx utilizzata (introdotta sul mercato dallaTexas Instruments a metà degli anni ’60) e la descrizione del funzionamentodi una CPU di Eckert; si passa ad un’analisi più approfondita degli specifi-ci componenti utilizzati approfondendone la struttura e il comportamentologico per poi presentare una strutturazione funzionale che li utilizzi per larealizzazione di un’architettura complessa.

La strutturazione per l’emulazione può essere vista logicamente suddivisa;partendo dalla creazione, il collegamento e la gestione dei contatti interni,si può poi prendere in esame la realizzazione e il management del segnaledi clock, per poi analizzare successivamente la costruzione dei componen-ti specifici e le loro funzionalità; per terminare, si ha la realizzazione diun profilo comunicativo tra due oggetti che utilizzano differenti standardlogici.Nello specifico i componenti realizzati a livello di codice sono stati:

• il 7400 che realizza un NAND logico su quattro coppie di bit in inputcon quattro bit di output (uno per ciascuna coppia di valori);

• il 7402 per ottenere un NOR logico anch’esso tra quattro coppie di bitin input con quattro bit di output (uno per ciascuna coppia di valori);

• il 7474, ovvero la struttura di un FLIP-FLOP da riprodurre più volteper l’implementazione dei registri;

• il 74138 che implementa un decoder/DEMULTIPLEXER nella versio-ne con tre linee in ingresso e 8 linee in uscita;

• il 74181 per l’Aritmethic e Logic Unit;

• il MAX232 che è un convertitore da logica TTL a RS-232 e vieceversa.

56

Sviluppo del codice

A livello di possibili sviluppi futuri del progetto, si è pensato all’imple-mentazione di un bus di collegamento e alla realizzazione di due ulterioriemulatori per oggetti della serie 74xx:

• il 7488 che realizza una ROM da 256 bit;

• il 74189 che implementa una RAM da 64 bit.

L’introduzione di questo ulteriore sviluppo renderebbe possibile il collega-mento di tutti i componenti e la realizzazione di un’architettura perfetta-mente emulabile dal punto di vista hardware.

Vista la semplicità e la potenza dell’architettura di Eckert, che la rende unutile strumento didattico, già vari istituti scolastici si sono dichiarati in-teressati all’emulatore oggetto di questo lavoro di tesi come strumento disupporto all’insegnamento dei principi della progettazione degli elabora-tori.

57

Bibliografia

[1] J Presper Eckert Jr. A survey of digital computer memory systems.Proceedings of the IRE, 41(10):1393–1406, 1953.

[2] Datasheet 74F00 Quad 2-input NAND gate. http://www.nxp.com/

documents/data_sheet/74F00.pdf, 1990.

[3] Datasheet 74F02 Quad 2-input NOR gate. http://www.nxp.com/

documents/data_sheet/74F02.pdf, 1990.

[4] Datasheet 74F74 Dual D-type flip-flop. http://www.nxp.com/

documents/data_sheet/74F74.pdf, 1996.

[5] Datasheet 74HC/HCT138 3-to-8 line decoder/demultiplexer. http://www.nxp.com/documents/data_sheet/74HC_HCT138.pdf, 2012.

[6] Datasheet 74HC/HCT181 4-bit arithmetic logic unit. http:

//www.ic.unicamp.br/~cortes/mc613/material_complementar/

74HC_HCT181_Philips.pdf, 1998.

[7] Datasheet MAX232 Dual EIA-232 Drivers/Receivers. http://www.ti.com/lit/ds/symlink/max232.pdf, 1989.

58