Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica...

26
Capitolo 3 Simulazioni e verifiche

Transcript of Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica...

Page 1: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3

Simulazioni e verifiche

Page 2: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 64

3.1 Introduzione

La verifica del sistema nel suo complesso è stata effettuata simulando il funzionamento

di ogni modulo separatamente. La sintesi di ogni singolo blocco, realizzata mediante

linguaggio VHDL, è avvenuta mediante il software “Active VHDL” della Aldec [6].

L’implementazione nella FPGA, presente sulla scheda demo della Avnet [7], dei soli

moduli di codifica/decodifica FHSS non consente di per se una totale verifica sul

funzionamento dell’apparato. Si deve perciò trovare un modo semplice per fornire al

codificatore i dati, sottoforma di ottetti, provenienti dal sottolivello MAC. In pratica,

deve avvenire una simulazione dell’interazione tra il livello fisico (costituito dal

codificatore FHSS) ed il sottolivello MAC.

In un primo tempo si era pensato di utilizzare una ROM di 4096 bytes, implementata

direttamente sulla FPGA, per fornire gli ottetti di dati MAC. In uscita al decodificatore

FHSS, una RAM di 4096 bytes consentiva la memorizzazine dei dati ricevuti. A

trasmissione effettuata, la verifica comparata di ogni singolo ottetto di dati contenuto

nella ROM e nella RAM permetteva la verifica della trasmissione.

Successivamente si è pensato che un modo più veloce e meno restrittivo per eseguire la

simulazione fosse quello di utilizzare al posto della ROM una RAM precaricata di

informazioni. Restava tuttavia il problema su come eseguire questa precarica. La

presenza della porta seriale sulla scheda FPGA è stata fondamentale consentendo

l’utilizzo di un computer, collegato tramite un cavo “null modem” (vedi Appendice) al

connettore RS-232 della scheda, come simulatore della “sorgente” di informazioni

MAC. Questi dati, giunti alla scheda mediante la porta seriale, venivano memorizzate

nella RAM ed erano pronti per essere utilizzati dal codificatore durante la costruzione

del pacchetto.

I dati in uscita al decodificatore, salvati nella seconda RAM, vengono ritrasmessi al

computer mediante il solito collegamento seriale. Il computer riesce così a confrontare i

dati in arrivo sulla porta RS-232 con quelli che aveva trasmesso in precedenza. Questa

verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Page 3: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 65

3.2 Sistema completo

Dal paragrafo precedente si denota la necessità di implementare sulla FPGA moduli

aggiuntivi per il supporto della comunicazione seriale, della simulazione della sorgente

dati del livello MAC e della gestione delle interfacce presenti sulla scheda (pulsanti e

displays a 7 segmenti).

Si devono così creare due memorie RAM, di tipo dual port, di 4096 bytes ognuna.

Per la gestione degli indirizzi di tali memorie sono necessari due contatori a 12 bits

(ram addr counter).

Il computer, prima dei dati MAC, deve inviare anche i valori PLW e PSF (16 bits) per

inizializzare il codificatore e quindi sono necessari due registri di 8 bits per la loro

memorizzazione (header register).

S3 push anti-bumper

7 segments displays handler

S2 push anti-bumper

header (low word) register (8 bits)

header (high word) register (8 bits)

Clock

reset

Push_S2

reset

reset

clock

push

push_ab

Clock

reset

Push_S3

push

reset

clock

push

push_ab

Clock

reset

display1(3:0)

Segment(7:0)

reset

clock

display1(3:0)

segment(7:0)

display2(3:0) display2(3:0)

display3(3:0) display3(3:0)

display4(3:0) display4(3:0)

Digit(3:0)digit(3:0)

Clock

reset

enable_reg_1

plw(11:4)

reset

clock

enable

reg(7:0)

serial_out(7:0) data_in(7:0)

Clock

reset

enable_reg_2

plw(3:0) & psf(3:0)

reset

clock

enable

reg(7:0)

serial_out(7:0) data_in(7:0)

Clock

reset

start_tx

finish_tx

FHSSPHY encoder

reset

clock

start

finish

plw(11:0) plw(11:0)

psf(3:0) psf(3.0)

mac_data_tx(7:0) mac_data(7:0)

busy busy_tx

next_mac_data next_mac_data

data_out TP1

error error_tx

unsupported_data_rate error_1

nr_PSDU_octets_null error_2

Clock

reset

start_rx

finish_rx

FHSSPHY decoder

reset

clock

start

finishTP1 data_in

mac_data_ready mac_data_ready

mac_data(7:0) mac_data_rx(7:0)

error error_rx

error_3 unsupported_data_rate

error_4 crc_error

rate rate_tx

plw(11:0) plw_rx(7:0)

rate rate_rx

Clock

reset

UART transmitter

reset

clock

serial_in(7:0) data_in(7:0)

UART_busy busy

transmit_serial_data transmit_data

Clock

reset

UART receiver

reset

clock

RxD RxD

serial_data_sentdata_sent

TxD TxD

serial_data_readydata_ready

serial_out(7:0)data_out(7:0)

Figura 1: Moduli implementati sulla FPGA (I parte)

Page 4: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 66

Clock

reset

pushreset_ram_addr

main control unit

reset

clock

pushreset_ram_addrdipswitch(0) dipswitch(0)

serial_data_sent serial_data_sent

error_1

serial_data_ready serial_data_ready

plw(11:0) plw(11:0)

psf(3:0) psf(3:0)

ram_addr_tx(11:0) ram_addr_tx(11:0)

ram_addr_rx(11:0) ram_addr_rx(11:0)

enable_reg_1 enable_reg_1

enable_reg_2 enable_reg_2

enable_ram_addr_tx

error_2

enable_ram_addr_rx

error_tx

we_ram_tx

finish_tx

start_tx

error_3

start_rx

error_4

transmit_serial_data

display1(3:0)

error_rx

finish_rx

enable_ram_addr_tx

enable_ram_addr_rx

we_ram_tx

start_fhss_rx

start_fhss_tx

transmit_serial_data

display1(3:0)

display2(3:0) display2(3:0)

display3(3:0) display3(3:0)

display4(3:0) display4(3:0)

error_1

error_2

error_tx

finish_tx

error_3

error_4

error_rx

finish_rx

serial_out(7:0) serial_out(7:0)

serial_in(7:0) serial_in(7:0)

Clock

Clock

we_ram_tx

FHSSPHY encoder dual port ram (4096 x 8 bits)

clkb

clka

wea

ram_addr_tx(11:0) addra(11:0)

ram_addr_tx(11:0) addrb(11.0)

serial_out(7:0) dina(7:0)

doutb(7:0) mac_data_tx(7:0) Clock

Clock

mac_data_ready

FHSSPHY decoder dual port ram (4096 x 8 bits)

clkb

clka

wea

ram_addr_rx(11:0) addra(11:0)

ram_addr_rx(11:0) addrb(11.0)

mac_data_rx(7:0) dina(7:0)

doutb(7:0) serial_in(7:0)

Clock

reset_ram_addr

enable_ram_addr_txor next_mac_data

ram_addr_tx(11:0)

FHSSPHY encoder ram addr counter (12 bits)

reset

clock

enable

count(11:0) Clock

reset_ram_addr

enable_ram_addr_rx or mac_data_ready

ram_addr_rx(11:0)

FHSSPHY decoder ram addr counter (12 bits)

reset

clock

enable

count(11:0)

Figura 2: Moduli implementati sulla FPGA (II parte)

La comunicazione seriale viene realizzata dell’UART transmitter e dall’UART receiver

[8].

La gestione dei pulsanti viene effettuata dai moduli push anti-bumper. Essi evitano il

problema della presenza di segnali spuri alla durante la pressione e forniscono in uscita

un impulso sincrono al clock e di durata di un solo periodo ad ogni attivazione.

Il modulo 7 segments displays handler permette la visualizzazione, sui displays a sette

segmenti della scheda, dei valori in ingresso al modulo in formato esadecimale.

La main control unit si occupa delle varie fasi che compongono il processo di verifica

del funzionamento dei dispositivi FHSSPHY encoder e FHSSPHY decoder in prova.

La Figura 1 e la Figura 2 mostrano lo schema del sistema completo con i vari dispositivi

implementati sulla FPGA.

Page 5: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 67

3.2.1 Push anti-bumper

Per realizzare il dispositivo di eliminazione dei segnali spuri sono sufficienti un flip flop

SR ed un contatore. La pressione del pulsante della scheda comporta che il segnale,

associato ad esso e che normalmente è a livello alto, si porti al livello basso. Questo

cambiamento fa commutare l’uscita del flip flop al livello alto abilitando così il

contatore che fornisce l’impulso desiderato (sincrono al clock e di durata di un periodo)

quando il conteggio raggiunge il valore 1. Durante questa fase l’ingresso SET del flip

flop, essendo in relazione con l’uscita Q, non è più attivabile. Una pressione sul

pulsante si traduce ancora in un impulso in uscita solo quando il contatore è arrivato a

“fine corsa”. Infatti, quando il contatore raggiunge il valore “111...1”, si ha un segnale

di RESET sul flip flop, l’uscita Q si riporta a valore basso e si riabilita nuovamente

l’ingresso SET che resta in attesa di una nuova pressione del pulsante. Il periodo di

disabilitazione del pulsante è pari al periodo di clock per il valore di “fine corsa” del

contatore, cioè:

419,021040121 24

624 =⋅

⋅=⋅=

clockdis f

T [secondi]

La figura seguente mostra lo schema dell’anti-bumper.

clock

reset or end_disabling

disabling push counter (24 bits)

reset

clock count=1

push_disabled

end_disabling

push_ab

enable

clock

reset or end_disabling

push nor push_disabled

enabling counter ff sr

set

clock

reset

q push_disabled

count=”111…11”

Figura 3: Push anti-bumper

3.2.2 7 segments displays handler

I quattro displays a 7 segmenti presenti sulla scheda non possono essere accesi

contemporaneamente ma uno alla volta. Per poter visualizzare tutte e quattro le cifre è

così necessario un sistema che sia in grado di accendere in modo sequenziale un display

alla volta con una frequenza tale da farli apparire accesi tutti e quattro.

Page 6: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 68

La frequenza scelta è fornita dal contatore switch display digit ed è pari a:

1522

10402 18

6

18 =⋅

== clockswitch

ff [Hz]

La ROM ha il compito di indicare quali segmenti del display accendere per visualizzare

il valore in ingresso in formato esadecimale.

Il decoder ed il multiplexer sono comandati entrambi dal contatore fornendo

l’accensione dei displays in sequenza desiderata.

display segments rom (16 x 8 bits)

clock

reset

sel_digit(1:0)

switch display digit counter (19 bits)

reset

clock count(18:17)

display(3:0) segment(7:0)addr(3:0) out(7:0)

sel_digit(1:0) digit(3:0)

digit select decoder

addr(1:0) out(3:0)display select mux

sel_digit(1:0)

display1(3:0)

display2(3:0)

display(3:0)

a(3:0)

sel(1:0)

b(3:0)

out(3:0)

display3(3:0)

display4(3:0) d(3:0)

c(3:0)

Figura 4: 7 segments displays handler

3.2.3 UART transmitter

La trasmissione dei dati dalla FPGA al computer viene realizzata da questo dispositivo.

La specifica comunicazione seriale implementata è caratterizza da una velocità di

trasmissione di 9600 bps, otto bits di dati, nessun bit di parità e un solo bit di stop.

UART tx data reverse

shift register (9 bits) clock

reset

trigger

reset (reg=”11…1”)

clock

enable

data_in(7:0) & ‘0’ data_in(8:0)

load_data load

clock

reset

transmit_data

UART transmitter control unit

reset

clock

transmit_data

finish and trigger finish

reset_div_freqreset_div_freq

clock

reset or data_sent

UART tx nr bits counter (4 bits)

reset

clock finish count=9TxD

load_dataload_data

busy busy

reg(0)

din‘1’

trigger enable

data_sentdata_sentclock

reset_div_freqor trigger

UART tx divide frequency counter (13 bits)

reset

clock triggercount=4166

Figura 5: UART transmitter

Page 7: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 69

Il contatore divide frequency permette allo shift register di uscita di fornire i dati alla

frequenza di trasmissione desiderata (9600 bps). I dati da trasmettere vengono caricati

nello shift register in modo parallelo e trasmessi serialmente in uscita. Il contatore nr

bits determina la fine della trasmissione di un frame di dati (un bit di start, otto bits di

dati ed un bit di stop).

L’UART transmitter control unit è costituita da due stati: il primo è di attesa mentre nel

secondo avviene la trasmissione del frame seriale.

finish=’1’ andtransmit_data=’0’

reset_div_freq <= ‘0’ busy <= ‘1’

load_data <= transmit_data and finishdata_sent <= finish

1

reset_div_freq <= ‘1’ busy <= ‘0’

load_data <= transmit_data

0

transmit_data=’1’

reset=’1’

Figura 6: Diagramma a stati della UART transmitter control unit

3.2.4 UART receiver

Il sistema acquisisce i dati provenienti dalla porta seriale del computer mediante questo

ricevitore. Le informazioni seriali in arrivo vengono memorizzate nello shift register. I

parametri che specificano il tipo di comunicazione seriale sono identiche a quelle

utilizzate nel trasmettitore UART. Il contatore divide frequency serve a sincronizzare lo

shift register alla velocità di 9600 bps. Il contatore nr bits, oltre a determinare l’ultimo

bit del frame (bit di stop), indica quando il bit che si sta ricevendo fa parte degli otto bits

dati ed abilita lo shift register di ingresso per la memorizzazione. Al termine della

ricezione, l’ottetto dati è disponibile all’uscita parallela del registro a scorrimento.

Page 8: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 70

UART rx data reverse shift register (8 bits)

clock

reset

data_bit and trigger

reset

clock

enable

data_out(7:0) data_out(7:0)

clock

reset

not Rxd

UART receiver control unit

reset

clock

receive_data

finish and trigger finish

reset_div_freqreset_div_freq

clock

reset or data_ready

UART rx nr bits counter (4 bits)

reset

clock

finish count=9

data_readydata_ready

din RxD

trigger enable

data_bitcount=1,2,3,4,5,6,7,8

clock

reset_div_freq orcount=4166

UART rx divide frequency counter (13 bits)

reset

clock triggercount=2083

Figura 7: UART receiver

Il diagramma a stati della UART receiver control unit è mostrato in Figura 8. Lo stato 0

è di attesa di un frame seriale e lo stato 1 si occupa dell’estrazione del dato contenuto in

quest’ultimo.

finish=’1’

reset_div_freq <= ‘0’ data_ready <= finish

1

reset_div_freq <= ‘1’ 0

receive_data=’1’

reset=’1’

Figura 8: Diagramma a stati della UART receiver control unit

3.2.5 Main control unit

Il processo di verifica del funzionamento dei avviene principalmente in tre fasi.

La prima fase (stati 0, 1, 2 e 3) riguarda la ricezione e la memorizzazione dei dati

provenienti dal computer nei due registri (memorizzazione di PLW e PSF) e nella RAM

(dati di simulazione livello MAC).

Page 9: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 71

serial_data_ready=’1’

serial_data_ready=’1’

enable_reg_1 <= serial_data_ready display1 <= serial_in(7:4) display2 <= serial_in(3:0)

display3 <= serial_out(7:4) display4 <= serial_out(3:0)

0

reset=’1’

reset_ram_addr <= serial_data_ready enable_reg_2 <= serial_data_ready

1

we_ram_tx <= serial_data_ready enable_ram_addr_tx <=

serial_data_ready reset_ram_addr <= ‘1’ when

ram_addr_tx=plw start_fhss_rx <= ‘1’ when

ram_addr_tx=plw

2

display1 <= plw(11:8) display2 <= plw(7:4) display3 <= plw(3:0)

display4 <= psf start_fhss_tx <= push or

dipswitch

3

ram_addr_tx=plw

display1 <= “1111” display2 <= “1111” display3 <= “1111” display4 <= “1111”

enable_ram_addr_rx <= push or dipswitch

transmit_serial_data <= push or dipswitch

6

push=’1’ ordipswitch=’1’

display1 <= “0000” display2 <= “0000” display3 <= “0000” display4 <= “0000”

reset_ram_addr <= finish_rx

4

finish_rx=’1’ orerror_rx=’1’ or

error_tx=’1’

enable_ram_addr_rx <= serial_data_sent

transmit_serial_data <= serial_data_sent when

ram_addr_rx/=plw display1 <= serial_in(7:4) display2 <= serial_in(3:0)

display3 <= serial_out(7:4) display4 <= serial_out(3:0)

7

serial_data_sent=’1’ and

ram_addr_rx=plw

push=’1’ or dipswitch=’1’

display1,display2,display3,display4 <= “0001” when error_1=’1’ else “0010” when error_2=’1’ else “0011” when error_3=’1’ else “0100” when error_4=’1’

else “0000”

5

error_rx=’0’ and error_tx=’0’

Figura 9: Diagramma a stati della main control unit

Nella seconda fase (stati 4, 5 e 6) avverrà il processo codifica e decodifica FHSS con i

dati MAC decodificati memorizzati nella seconda RAM.

Nella terza ed ultima fase (stato 7) si effettuerà la trasmissione dei dati decodificati al

computer che verificherà se il processo di codifica-decodifica è andato a buon fine

comparando i dati trasmessi con quelli ricevuti.

Il dipswitch 0, presente sulla scheda, consente di comandare il passaggio da una fase a

quella successiva mediante la pressione del pulsante S3. Se il dipswitch 0 non è attivato

allora il passaggio avviene automaticamente.

Page 10: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 72

Sui displays della scheda, durante ogni fase, vengono visualizzate diverse informazioni.

Durante la prima e la terza fase vengono visualizzati in successione i dati seriali in

arrivo ed in partenza; inoltre, a ricezione avvenuta, vengono mostrati i valori di PLW e

PSF. Nella seconda fase i displays permettono di evidenziare il verificarsi di uno dei

quattro possibili errori (“1111” o “2222” indicano gli errori di codifica “unsupported

data rate” o “number of PSDU octets null”, “3333” o “4444” indicano agli errori di

decodifica “unsupported data rate” o “crc error”) oppure di comunicare una codifica-

decodifica corretta (“FFFF”).

La Figura 10 rappresenta la la scheda FPGA utilizzata per la prova. Da questa foto si

notano i vari dispositivi di I/O come i pulsanti, il dipswitch e i displays a 7 segmenti.

Figura 10: Fotografia della scheda FPGA

Page 11: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 73

3.3 Programma di comunicazione

Esistono due metodi per la scrittura del codice di un programma di comunicazione

seriale (vedi Appendice). Si può eseguire un “polling” sulla UART, per vedere se

qualche nuovo dato è disponibile oppure si può configurare la gestione degli interrupts

[9] per rimuovere i dati dall’UART quando quest’ultima genera un interrupt. La

gestione di tipo “polling” è un metodo molto lento poiché utilizza intensivamente la

CPU del sistema. Quindi si può raggiungere una velocità massima di trasmissione di

circa 38,4 kbps prima di iniziare a perdere dati. L’altra opzione è quella della gestione

degli interrupts ed è quella che verrà utilizzata. Essa supporta facilmente velocità di

115,2 kbps anche su computer di fascia bassa.

INT (Hex) IRQ Uso comune 08 0 Timer di sistema 09 1 Tastiera 0A 2 Reindirizzato 0B 3 Comunicazione seriale: COM2/COM4 0C 4 Comunicazione seriale: COM1/COM3 0D 5 Riservato/Scheda audio 0E 6 Controller del floppy disk 0F 7 Comunicazione parallela 70 8 Real Time Clock 71 9 Riservato 72 10 Riservato 73 11 Riservato 74 12 Mouse PS/2 75 13 Coprocessore matematico 76 14 Hard Disk Drive 77 15 Riservato

Tabella 1: Vettori di interrupt (Solo hardware)

Il polling della UART è, per esempio, un buon metodo per la diagnostica o per capire a

quale indirizzo o a quale IRQ fa riferimento la porta seriale in esame. Nella Tabella 1

sono riportati gli indirizzi di base e gli IRQ più comunemente usati.

Page 12: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 74

3.3.1 Vettori di interrupt

Dopo aver trovato l’IRQ della porta seriale, il passo successivo è di cercare il suo

vettore di interrupt. Fondamentalmente, ogni processore della famiglia 8086, ha un set

di 256 vettori di interrupt, numerati da 0 a 255. Ognuno di questi vettori contiene un

codice a 4 byte che è un indirizzo dell’ISR (Interrupt Service Routine) [9].

Fortunatamente il C, essendo un linguaggio di alto livello, si prende cura degli indirizzi

autonomamente. Tutto quello che interessa è quindi solo il vettore di interrupt effettivo.

La Tabella 1 mostra solo gli interrupt che sono associati con gli IRQ. Gli altri 240 non

interessano nella programmazione di una comunicazione di tipo RS-232.

Per esempio se si sta utilizzando la porta COM3 che ha un IRQ pari a 4, allora il vettore

dell’interrupt deve essere 0C in esadecimale. Usando il linguaggio C dovremo settare il

vettore tramite l’istruzione setvect(0x0C, PORT1INT); dove PORT1INT conduce ad un

set di istruzioni di servizio per l’interrupt.

Comunque, prima di procedere, è buona norma salvare i dati relativi agli indirizzi del

vecchio vettore e ripristinarli alla fine dell’esecuzione del programma. Questo è fatto

grazie all’istruzione oldport1isr = getvect(INTVECT); dove oldport1isr è

definito usando la dichiarazione void interrupt (*oldport1isr)();

3.3.2 Interrupt Service Routine

La PORT1INT vista prima è l’etichetta riferita alla procedura di gestione dell’interrupt

denominata Interrupt Service Routine (ISR). Essa è la seguente:

void interrupt PORT1INT() /* Interrupt Service Routine for PORT1 */ { int c; do

{ c = inportb(PORT1 + 5); if (c & 1)

{ buffer[bufferin] = inportb(PORT1); bufferin++; if (bufferin == 1024) {bufferin = 0;} }

} while (c & 1); outportb(0x20,0x20); }

Page 13: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 75

La procedura controlla se c’è un carattere da ricevere ed in caso affermativo lo rimuove

dal dalla UART e lo salva in un buffer contenuto nella memoria. Il controllo sulla

UART viene mantenuto, nel caso in cui i buffers FIFO siano abilitati, in modo tale da

poter prelevare tutti i dati disponibili all’istante di manifestazione dell’interrupt (e non

un solo carattere).

L’ultima riga contiene l’istruzione outportb(0x20,0x20); che comunica al

Programmable Interrupt Controller [9] che l’interrupt ha finito. Ora verrà analizzato

proprio il Programmable Interrupt Controller (PIC). Tutte le routine precedenti sono

state analizzate considerando che tutto sia configurato correttamente e che tutto sia

pronto per l’uso; ciò significa che i registri dell’UART ed il Programmable Interrupt

Controller siano stati inizializzati senza commettere errori.

Il Programmable Interrupt Controller gestisce gli interrupts hardware. La maggior parte

dei PC ne hanno due collocati a due indirizzi diversi.

Uno gestisce gli IRQ da 0 a 7 e l’altro gli IRQ da 8 a 15. Nella maggior parte dei casi

gli interrupts delle comunicazioni seriali risiedono negli IRQ da 0 a 7, quindi viene

usato il PIC1, che è localizzato all’indirizzo esadecimale “0x20”.

Bit Disabilitazione IRQ Funzione 7 IRQ7 Porta parallela 6 IRQ6 Controller del floppy disk 5 IRQ5 Riservato/Scheda audio 4 IRQ4 Porta seriale 3 IRQ3 Porta seriale 2 IRQ2 PIC2 1 IRQ1 Tastiera 0 IRQ0 Timer di sistema

Tabella 2: Control Word del PIC1 ("0x21")

Bit Disabilitazione IRQ Funzione 7 IRQ15 Riservato 6 IRQ14 Hard disk drive 5 IRQ13 Coprocessore matematico 4 IRQ12 Mouse PS/2 3 IRQ11 Riservato 2 IRQ10 Riservato 1 IRQ9 IRQ2 0 IRQ8 Real Time Clock

Tabella 3: Control Word del PIC2 ("0xA1")

Page 14: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 76

Porte di tipo Multi-Comm stanno diventando abbastanza comuni e quindi la Tabella 3

include i dati per il PIC2, che è localizzato all’indirizzo esadecimale “0xA0”. Il PIC2 è

responsabile degli IRQ da 8 a 15. Esso opera esattamente allo stesso modo del PIC1 ad

eccezione del fatto che gli EOI (End Of Interrupt) vanno alla porta “0xA0” mentre le

disabilitazioni (“Masking”) degli IRQ sono eseguite usando la porta “0xA1”.

Molte delle procedure di inizializzazione sono fatte dal BIOS. Il nostro interesse si deve

quindi focalizzare solo su due istruzioni di setup. La prima è

outportb(0x21,(inportb(0x21) & 0xFE); che seleziona quali interrupts devono

essere disabilitati (“Mask”). Così se vogliamo abilitare l’IRQ4 dobbiamo

complementare ad uno la word “0x10” (16) e quindi ottenere la word “0xEF” (239).

Questo significa disabilitare gli IRQ 7,6,5,3,2,1 e 0 lasciando abilitato l’IRQ 4.

Naturalmente questa istruzione non altera l’abilitazione degli IRQ fatta da altri

programmi poiché la funzione & (and o prodotto logico) tra la word corrispondente

all’istruzione inportb(0x21) e la word “0xFE” è uno solo quando i rispettivi bit sono

entrambi ad uno. Per esempio, se un altro programma aveva abilitato l’IRQ5 e quindi il

bit corrispondente era a zero, il prodotto logico di zero con uno da come risultato ancora

zero e quindi l’interrupt resta abilitato.

L’altra istruzione da considerare è outportb(0x20,0x20); che segnala la fine

dell’interrupt al PIC. Si utilizza questo comando alla fine della procedura di servizio

dell’interrupt in modo tale che si possano di nuovo accettare gli interrupts a bassa

priorità.

3.3.3 Configurazione dell’UART

Come prima istruzione bisogna disattivare la generazione di interrupt della UART per

far in modo che l’inizializzazione della stessa non possa essere interrotta. Quindi si ha, a

questo punto, il setup dei vettori di interrupt. Il passo successivo è quello di scegliere la

velocità della comunicazione; si deve perciò impostare il bit 7 (DLAB) dell’LCR (Line

Control Register) per poter accedere ai bytes alto e basso del Divisor Latch. Se, ad

esempio, si vuole una velocità di 38,4 kbps bisogna impostare una divisione per tre e

quindi byte alto del Divisor Latch deve essere “0x00” e quello basso “0x03”.

L’operazione successiva è quella di disattivare il Divisor Latch Access Bit (DLAB) in

modo da poter accedere all’Interrupt Enable Register ed ai buffers di ricezione e di

trasmissione. Per disattivare il DLAB e contemporaneamente impostare la

Page 15: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 77

comunicazione (per esempio a 8 bits dati, nessuna partità e 1 bit di stop) bisogna

caricare nel registro di controllo di linea (LCR) la word “0x03”.

La linea di codice successiva abilita i buffers FIFO agendo sul First In/First Out Control

Register (FCR). Per avere il livello di trigger a 14 bytes, i bits 6 e 7 sono a valore alto e

per attivare i buffers FIFO il bit 0 è alto. Inoltre per ripulire i due buffers si devono

impostare ad uno i bit 2 e 3 (che passano a valore basso automaticamente dopo il reset

dei buffers). Si trova perciò che la word da caricare nel registro FCR deve essere

“0xC7”.

Successivamente vengono attivati i segnali DTR, RTS e OUT 2 (quest’ultimo per

maggiore compatibilità) grazie all’istruzione outportb(PORT1 + 4,0x0B);. Ora non

resta che riattivare gli interrupt; poiché il programma è interessata solo all’interrupt

segnalante nuovi dati ricevuti occorrerà abilitare solo questo tipo di interrupt tramite

l’istruzione outportb(PORT1 + 1,0x01);. L’Appendice fornisce una descrizione

completa dei registri appena menzionati. Ecco la parte di codice in questione:

outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */ oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector of later recovery */ setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */ /* PORT 1 - Communication Settings */ outportb(PORT1 + 3 , 0x80); /* SET DLAB ON */ outportb(PORT1 + 0 , 0x0C); /* Set Baud rate-Divisor Latch Low Byte */ /* Default 0x03 = 38,400 BPS */ /* 0x01 = 115,200 BPS */ /* 0x02 = 57,600 BPS */ /* 0x06 = 19,200 BPS */ /* 0x0C = 9,600 BPS */ /* 0x18 = 4,800 BPS */ /* 0x30 = 2,400 BPS */ outportb(PORT1 + 1 , 0x00); /* Set Baud rate-Divisor Latch High Byte*/ outportb(PORT1 + 3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ outportb(PORT1 + 2 , 0xC7); /* FIFO Control Register */ outportb(PORT1 + 4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ outportb(0x21,(inportb(0x21) & 0xEF)); /* Set Programmable Interrupt Controller */ /* COM1 (IRQ4) - 0xEF */ /* COM2 (IRQ3) - 0xF7 */ /* COM3 (IRQ4) - 0xEF */ /* COM4 (IRQ3) - 0xF7 */ outportb(PORT1 + 1 , 0x01); /* Interrupt when data received */

Page 16: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 78

3.3.4 Routine principale

Il programma si occupa di verificare che il file specificato nella linea di comando sia

valido e che sia possibile aprire in scrittura il file ausiliario per salvare i dati ricevuti.

Dalla linea di comando è inoltre possibile specificare il rate di codifica desiderato

digitando “1” oppure “2” subito dopo il file di ingresso. Se questo controllo da esito

positivo, il programma attende la pressione di un tasto prima di inviare i dati alla seriale.

Il codice della routine principale è il seguente:

do { if (bufferin != bufferout) { ch = buffer[bufferout]; bufferout++; if (bufferout == 1024) {bufferout = 0;} fputc(ch,foutput); bytessalvati++; } if (byteslettitotali==bytessalvati) { if (!feof(finput)) { bytesletti=0; while ((bytesletti<4095)&&(!feof(finput))) { carattere=fgetc(finput); if (!feof(finput)) { bufferfile[bytesletti]=carattere; bytesletti++; } } byteslettitotali+=bytesletti; header1=bytesletti/16; header2=(bytesletti%16)*16+rate*2; outportb(PORT1, header1); outportb(PORT1, header2); for(i=0;i<bytesletti;i++) outportb(PORT1, bufferfile[i]); printf("Inviati %d bytes\n",bytesletti); } } if (kbhit()) c = getch(); } while (((!feof(finput))||(byteslettitotali!=bytessalvati))&&(c!=27)); outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */ outportb(0x21,(inportb(0x21) | 0x10)); /* MASK IRQ using PIC */ /* COM1 (IRQ4) - 0x10 */ /* COM2 (IRQ3) - 0x08 */ /* COM3 (IRQ4) - 0x10 */ /* COM4 (IRQ3) - 0x08 */ setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */

Page 17: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 79

Sono presenti in un ciclo do-while tre controlli if:

• Controllo della presenza di nuovi dati in arrivo e salvataggio degli stessi in un

file;

• Controllo della possibilità di spedire nuovi dati sulla porta seriale se si sono già

ricevuti quelli spediti in precedenza (o non si è ancora spedito niente);

• Controllo della pressione di un tasto.

Prima dei dati del file vengono inviati i dati header1 e header2 che contengono i valori

di PLW e PSF (calcolati dal numero di word del file da inviare e dal rate scelto).

Il loop di controllo termine quando tutti i dati del file da spedire sono stati trasmessi e

ricevuti oppure se viene premuto il tasto “ESC” sulla tastiera. Le righe successive

servono per chiudere correttamente la trasmissione seriale, riportando ai valori di

partenza l’IRQ e l’interrupt vector della porta seriale usata. Successivamente il

programma si occupa di confrontare i dati ricevuti, memorizzati nel file ausiliario, con

quelli contenuti nel file di ingresso. Se il programma riscontra una differenza,

comparando i due files, si ha una segnalazione di errore e viene evidenziata la posizione

nella quale c’è stata l’incongruenza.

La figura seguente mostra il programma in esecuzione. Come file di ingresso si è scelto

l’eseguibile del programma stesso e il rate scelto è di 2 Mbps come specificato nella

linea di comando. Si può notare l’invio e la ricezione di 4095 bytes di informazioni alla

volta.

Figura 11: Programma per la prova in esecuzione

Page 18: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 80

3.4 Verifica

Dopo aver introdotto i moduli aggiuntivi implementati sulla FPGA ed il programma in

esecuzione sul PC per la comunicazione seriale si può ora procedere alla descrizione del

processo di verifica vero e proprio dei dispositivi di codifica-decodifica FHSS.

Il sistema nel suo complesso può essere schematizzato nella figura seguente:

Clock

Dipswitch(7:0)

Push_S2

TxD

RxD

Push_S3

Digit(3:0)

Segment(7:0)

TP1

FPGAOscillatore (40 MHz)

Pulsanti

Dipswitch

Computer

Oscilloscopio

Display

TxD

RxD

Figura 12: Sistema completo

La figura seguente mostra una fotografia del banco di prova utilizzato.

Figura 13: Fotografia del banco di prova

Page 19: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 81

Per la simulazione dei dati MAC è possibile utilizzare qualsiasi tipo di file

(naturalmente di lunghezza non nulla) poiché le informazioni sono sempre memorizzate

come una successione di bytes (8 bits) di dati.

Se il file in ingresso ha una dimensione maggiore di 4095 bytes (il payload del

pacchetto può essere costituito al massimo da 4095 ottetti), il programma invierà alla

FPGA blocchi di 4095 bytes per volta aspettando di ricevere i dati decodificati prima

dell’invio del blocco successivo (vedi Figura 11).

Per la prova si è scelto di utilizzare un semplice file di testo (“prova.txt”) di 19 bytes. Le

informazioni contenute nel file verranno inserite nel payload del pacchetto durante la

codifica.

La scelta di un file di dimensione ridotta permette di visualizzare in modo soddisfacente

la forma d’onda del pacchetto sull’oscilloscopio nella sua interezza.

Prima di iniziare la prova è necessario il RESET del sistema che si ottiene premendo il

pulsante S2 della scheda. La connessione tra il PC e la scheda avviene tramite un cavo

“null modem” (vedi Appendice) che permette la comunicazione tra le due porte seriali.

Sulla scheda sono presenti diversi “test point” che permettono di rendere disponibili

all’esterno segnali interni della FPGA. Questi collegamenti devono essere specificati

opportunamente nel constraints file letto dal software durante la fase di

implementazione della FPGA. Uno di questi “test point” (TP1) viene quindi collegato al

pin DATA_OUT dell’encoder che, a sua volta, è cortocircuitato con il pin DATA_IN

del decoder. Rilevando la tensione presente su questo morsetto mediante una delle

sonde dell’oscilloscopio, è possibile visualizzare la forma d’onda del pacchetto FHSS.

L’oscilloscopio deve essere configurato in modo tale da campionare il segnale rilevato

sulla sonda per un certo intervallo di tempo e partendo dal fronte di salita del segnale.

3.4.1 Pacchetto FHSS codificato al rate di 1 Mbps

Per effettuare la prova occorre digitare dalla linea di comando DOS del PC:

> starttxrx prova.txt

La Figura 14 mostra il contenuto della finestra “Prompt dei comandi” dopo tale

digitazione. Si può notare che la verifica del processo di codifica-decodifica è andato a

buon fine.

La fotografia di Figura 15 rappresenta la forma d’onda del pacchetto visualizzata sullo

schermo dell’oscilloscopio.

Page 20: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 82

L’oscilloscopio consente di salvare la forma d’onda campionata durante la prova su un

dischetto. I dati vengono salvati in un formato tale da poter essere elaborati, in un

secondo tempo, con programmi tipo Microsoft Excel o MATLAB.

Figura 14: Prova ad 1 Mbps

Figura 15: Fotografia dell'oscilloscopio in fase di salvataggio dei campioni sul dischetto

Page 21: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 83

I campioni, salvati nel file creato dall’oscilloscopio, sono costituiti da una serie di

coppie (tempo, ampiezza). Importando tale file in Microsoft Excel è possibile creare il

grafico della forma d’onda campionata. La figura seguente mostra il grafico del

pacchetto FHSS.

Pacchetto FHSS (1 Mbps)

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

-1 19 39 59 79 99 119 139 159 179 199 219 239 259 279

Tempo (μs)

Am

piez

za (V

)

Figura 16: Forma d'onda del pacchetto FHSS (1 Mbps)

L’asse dei tempi inizia da –1 μs poiché l’oscilloscopio pone l’origine dei tempi in

corrispondenza del primo fronte di salita del segnale.

Si possono analizzare separatamente le varie parti che compongono il pacchetto:

La parte Sync durerà per i primi 80 μs come evidenziato in Figura 17.

Nei successivi 16 μs si avrà lo Start Frame Delimiter (SFD) costituito dalla sequenza

“0000110010111101” (Figura 18)

Dopo lo SFD si avrà l’Header del pacchetto di durata pari a 32 μs (Figura 19). I primi

12 valori (“11001000000”) corrispondono al PLW che è stato spedito partendo bit meno

significativo. Il valore in decimale è 19 e rappresenta il numero di ottetti contenuti nel

payload. I successivi quattro valori (“0000”) identificano il PSF. Infine gli ultimi 16

valori dell’Header determinano il campo HEC.

Page 22: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 84

In Figura 20 è presente il grafico del primo blocco di 33 simboli della parte “Whitened

PSDU” del pacchetto. Il primo valore rappresenta il simbolo detto “stuff” che ha valore

“1”; ciò determina che i successivi 32 simboli saranno invertiti.

Sync

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

-1 9 19 29 39 49 59 69 79

Tempo (μs)

Am

piez

za (V

)

Figura 17: Parte Sync del pacchetto FHSS

SFD

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

79 81 83 85 87 89 91 93 95

Tempo (μs)

Am

piez

za (V

)

Figura 18: Parte SFD del pacchetto FHSS

Page 23: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 85

Header

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

95 100 105 110 115 120 125

Tempo (μs)

Am

piez

za (V

)

Figura 19: Parte Header del pacchetto FHSS (1 Mbps)

Whitened PSDU (Primo blocco di 33 simboli)

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

127 132 137 142 147 152 157

Tempo (μs)

Am

piez

za (V

)

Figura 20: Primo blocco di 33 simboli “Whitened PSDU” (1 Mbps)

Page 24: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 86

3.4.2 Pacchetto FHSS codificato al rate di 2 Mbps

Per effettuare la prova occorre digitare dalla linea di comando DOS del PC:

> starttxrx prova.txt 2

La Figura 21 mostra il contenuto della finestra “Prompt dei comandi” dopo tale

digitazione.

Figura 21: Prova a 2 Mbps

Ancora una volta è possibile analizzare separatamente le varie parti che compongono il

pacchetto grazie al segnale campionato al morsetto TP1 dall’oscilloscopio.

La parte di Preambolo viene sempre codificata alla velocità di 1 Mbps ed è quindi del

tutto identica a quella vista nel paragrafo precedente (vedi Figura 17 e Figura 18).

In Figura 23 è rappresentato l’Header del pacchetto: i primi 12 valori indicano, partendo

dal bit meno significativo, il PLW che è ancora pari a 19 (in decimale); i successivi 4

valori (“0010”) identificano, partendo ancora dal bit meno significativo, il campo PSF; i

rimanenti 16 valori appartengono al campo HEC dell’Header.

La Figura 24 mostra il primo blocco di 33 simboli della parte “Whitened PSDU” del

pacchetto codificato al rate di 2 Mbps. Il primo simbolo (“10”) specifica che i successivi

32 simboli hanno subito una inversione.

Page 25: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 87

Pacchetto FHSS (2 Mbps)

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

-1 19 39 59 79 99 119 139 159 179 199

Tempo (μs)

Am

piez

za (V

)

Figura 22: Forma d'onda del pacchetto FHSS (2 Mbps)

Header

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

95 100 105 110 115 120 125

Tempo (μs)

Am

piez

za (V

)

Figura 23: Parte Header del pacchetto FHSS (2 Mbps)

Page 26: Simulazioni e verifiche - fsartori.altervista.orgfsartori.altervista.org/capitolo_3.pdf · verifica permette di rilevare se il processo di codifica-decodifica è andato a buon fine.

Capitolo 3 – Simulazioni e verifiche 88

Whitened PSDU (Primo blocco di 33 simboli)

-0,20

0,20,40,60,8

11,21,41,61,8

22,22,42,62,8

33,23,4

127 132 137 142 147 152 157

Tempo (μs)

Am

piez

za (V

)

Figura 24: Primo blocco di 33 simboli “Whitened PSDU” (2 Mbps)