Modulatore QPSK

Transcript

Modulatore QPSK
Università di Roma Tor Vergata - Facoltà di Ingegneria
Dipartimento di Elettronica Digitale
Definizione, progetto VHDL-RTL e realizzazione
tramite FPGA di un modulatore QPSK con
sagomatura di impulso a coseno rialzato
a sintesi diretta
Relatore
Ch. mo Prof.
Giancarlo Cardarilli
Correlatore
Ing.
Marco Re
Correlatore
Ing.
Domenico Giancristofaro
Anno Accademico 2000-2001
Tesi di laurea di
Antonio D’Ottavio
matr. II009409
Indice
Elenco delle figure
vi
1 Modulazioni digitali
1.1 Sommario . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Modulazione . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Traslazione in frequenza . . . . . . . . . . . .
1.2.1.1 Spazio dei segnali . . . . . . . . . .
1.2.1.2 Tipologie di modulazioni satellitari
1.3 Principi di demodulazione . . . . . . . . . . . . . . .
1.3.1 Demodulatore . . . . . . . . . . . . . . . . . .
1.3.2 Decisore . . . . . . . . . . . . . . . . . . . . .
1.3.3 Interferenza intersimbolica . . . . . . . . . . .
1.3.4 Principi di codifica . . . . . . . . . . . . . . .
1.3.5 Capacità trasmissiva . . . . . . . . . . . . . .
2 Architetture modulatori QPSK
2.1 Sommario . . . . . . . . . . . . . . . . . . .
2.2 Realizzazioni digitali di modulatori QPSK .
2.2.1 Modulatore DDFS . . . . . . . . . .
2.2.2 Modulatore classico . . . . . . . . .
2.2.2.1 Modulatore classico con fclk
3 Implementazione SRRC polifase
3.1 Sommario . . . . . . . . . . . . . . . .
3.2 Progetto del filtro SRRC . . . . . . . .
3.3 Implementazione polifase SRRC . . . .
3.3.1 Modello Matlab . . . . . . . . .
3.4 Modello VHDL . . . . . . . . . . . . .
3.4.1 Polifase standard gated-clock .
3.4.1.1 SRRCxN . . . . . . .
3.4.1.2 Rate Adapter . . . . .
3.4.1.3 Risultati sperimentali
3.4.2 ROM Polifase clock-enable . . .
i
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . .
. . . . . .
. . . . . .
. . . . . .
= 4 × fif
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
4
6
6
12
12
14
17
21
23
.
.
.
.
.
26
26
27
27
28
30
.
.
.
.
.
.
.
.
.
.
33
33
33
35
35
37
37
37
39
40
40
3.4.2.1
Risultati sperimentali . . . . . . . . . . . . .
4 Implementazione Modulatore QPSK
4.1 Sommario . . . . . . . . . . . . . . . .
4.2 Modello Matlab . . . . . . . . . . . . .
4.3 Modelli VHDL . . . . . . . . . . . . .
4.3.1 Modulatore classico . . . . . .
4.3.2 ThinModulator . . . . . . . . .
4.3.2.1 Risultati sperimentali
4.3.2.1.1 Test VHDL .
4.3.2.1.2 Test FPGA .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
44
44
44
47
47
49
53
53
54
5 Conclusioni
58
A Sintesi diretta di frequenza digitale
A.1 Sommario . . . . . . . . . . . . . . .
A.2 DDFS . . . . . . . . . . . . . . . . .
A.3 Pianificazione delle frequenze . . . .
A.3.1 Spurie dovute al DAC . . . .
A.3.2 Spurie dovute al troncamento
A.4 Convertitore Fase-Frequenza . . . . .
A.4.1 Algoritmo CORDIC . . . . .
A.5 Descrizione modello matematico . .
A.6 Descrizione modello VHDL . . . . .
. . .
. . .
. . .
. . .
della
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
fase
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
59
59
61
61
62
63
64
65
66
B Sistemi Multirate
B.1 Sommario . . . . . . . . . . .
B.2 Downsampling e Upsampling
B.3 Architetture Multirate . . . .
B.3.1 CIC . . . . . . . . . .
B.3.2 Polifase . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
71
71
71
74
75
78
C Logiche programmabili
C.1 Sommario . . . . . . . . . . . . . .
C.2 Tipologie di logiche programmabili
C.3 Architettura Virtex . . . . . . . . .
C.3.1 CLB . . . . . . . . . . . . .
C.3.2 IOB . . . . . . . . . . . . .
C.3.3 Risorse di connessione . . .
C.3.4 Circuiti di utilità . . . . . .
C.3.4.1 DLL . . . . . . . .
C.3.4.2 BlockRAM . . . .
C.3.4.3 SRL16 . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
81
81
81
83
83
85
86
86
87
87
88
ii
.
.
.
.
.
.
.
.
.
.
D Flusso di progettazione
D.1 Sommario . . . . . . . . . . .
D.2 Modello Matematico . . . . .
D.3 Modello VHDL . . . . . . . .
D.4 Sintesi del progetto . . . . . .
D.5 Mappatura . . . . . . . . . .
D.6 Piazzamento delle risorse . .
D.7 Connessione delle risorse . . .
D.8 Simulazione back-annotata .
D.9 Programmazione della FPGA
D.10 Verifica sperimentale . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
89
89
89
89
90
90
91
91
91
91
92
E Listati Matlab
E.1 NCO . . . . . . . . . . . . . . . . . . . . . . . . .
NCO Q.m . . . . . . . . . . . . . . . . . . . . .
Imposta frequenze Q.m . . . . . . . . .
Imposta NCO Q.m . . . . . . . . . . . .
Crea super accumulatore Q.m . . . . .
Tronca Q.m . . . . . . . . . . . . . . . .
Crea coseno e seno Q.m . . . . . . . .
Forward cordic Q.m . . . . . . . . . . .
Calcola rotazioni Cordic.m . . .
Visualizza spettro e SFDR p.m
Calcola SFDR.m . . . . . . . . . . . . .
Calcola incremento fase NCO.m . . . . . . . .
Visualizza spettro NCO VHDL.m . . . . . . .
E.2 Creazione vettori di test . . . . . . . . . . . . . .
CreaVettoriTest.m . . . . . . . . . . . . . . . . .
CreaSequenzaPatternGenerator.m . . . . . . . .
E.3 Polifase . . . . . . . . . . . . . . . . . . . . . . .
Creazione coefficienti . . . . . . . . . . . . . . . .
CreaCoeffsFreqSamplScaled.m . . . . . .
applica polifase.m . . . . . . . . . . . . .
RaisedCosineResponse.m . . . . . . . . .
CreaROM.m . . . . . . . . . . . . . . . .
Test VHDL . . . . . . . . . . . . . . . . . . . . .
PolyphasePSDVHDLvsPSDMatlab.m . .
applica polifase.m . . . . . . . . .
Test FPGA . . . . . . . . . . . . . . . . . . . . .
VisualizzaPSDPolifaseVHDLFPGAout.m
applica polifase.m . . . . . . . . .
E.4 Modulatore . . . . . . . . . . . . . . . . . . . . .
Tabella e grafico BER . . . . . . . . . . . . . . .
CreaTabellaBER.m . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
93
94
94
94
94
95
96
96
96
97
97
97
97
98
100
100
100
101
102
102
103
104
105
105
105
106
106
106
106
107
iii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
calcolaBER.m . . . . . . . . . . . .
Test VHDL . . . . . . . . . . . . . . . . . . . . .
QPSKModemPSDeBERVHDLvsMatlab.m
applica polifase.m . . . . . . . . .
Test FPGA . . . . . . . . . . . . . . . . . . . . .
QPSKModemPSDFPGAvsPSDMatlab.m
applica polifase.m . . . . . . . . .
F Listati VHDL
nco.vhd . . . . . . . . . . . . . . . . .
accumulator.vhd . . . . . . . . .
cordic pipelined unrolled.vhd .
cordic base j.vhd . . . .
adder 12.vhd . . .
adder 13.vhd . . .
reg 12.vhd . . . .
reg 13.vhd . . . .
shifter.vhd . . . . .
cosine rebuild.vhd . . . . . . . .
delay 13.vhd . . . . . . . . . . .
sine rebuild.vhd . . . . . . . . .
to first quadrant.vhd . . . . . .
troncatore 12.vhd . . . . . . . .
polyphase gatedClock.vhd . . . . . .
srrc coeffs.vhd . . . . . . . . . .
rate adapter.vhd . . . . . . . . .
coeffs selector.vhd . . . .
counter divider 3.vhd .
counter divider 4.vhd .
fftr.vhd . . . . . .
counter divider 6.vhd .
selector.vhd . . . . . . . .
srrc x n.vhd . . . . . . . . . . .
fir 1.vhd . . . . . . . . .
adder 7.vhd . . .
fir multiplier.vhd
shift reg.vhd . . .
mux 6.vhd . . . . . . . .
ROM polyphase.vhd . . . . . . . . .
counter.vhd . . . . . . . . . . . .
srrc x n.vhd . . . . . . . . . . .
demux 3x10.vhd . . . . .
mux 3x12.vhd . . . . . .
ROMx3.vhd . . . . . . . .
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
108
108
112
112
112
113
114
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
115
116
117
120
121
121
122
122
122
123
123
123
124
124
124
125
125
126
130
130
131
131
132
132
136
138
139
139
139
140
140
141
143
143
143
148
ROMx4.vhd . . . . . . . . . . . . . .
ROMx6.vhd . . . . . . . . . . . . . .
shift reg.vhd . . . . . . . . . . . . .
Modulator BlockRAM.vhd . . . . . . . . . . . .
adder I Q.vhd . . . . . . . . . . . . . . . .
counter.vhd . . . . . . . . . . . . . . . . . .
multiplier I Q.vhd . . . . . . . . . . . . .
NCO basic.vhd . . . . . . . . . . . . . . .
srrc x n.vhd . . . . . . . . . . . . . . . . .
ram.vhd . . . . . . . . . . . . . . . .
shift reg.vhd . . . . . . . . . . . . .
FIFO RAM ThinModulator.vhd . . . . . . . .
counter.vhd . . . . . . . . . . . . . . . . . .
Data Source Interface.vhd . . . . . . . . .
asynch fifo 2x15.vhd . . . . . . . .
ffd.vhd . . . . . . . . . . . . . . . . .
ffd en.vhd . . . . . . . . . . . . . .
ffs.vhd . . . . . . . . . . . . . . . . .
ThinModulator.vhd . . . . . . . . . . . . .
mult C2 adder.vhd . . . . . . . . .
mux 2x7.vhd . . . . . . . . . . . . .
ram 12x4096 rising registered.vhd
shift reg.vhd . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
153
161
162
163
164
164
164
165
166
166
166
168
168
169
170
170
170
171
172
173
173
174
174
G Acronimi
175
Bibliografia
178
Indice analitico
183
v
Elenco delle figure
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10
1.11
1.12
1.13
1.14
1.15
1.16
1.17
1.18
1.19
1.20
1.21
1.22
1.23
1.24
Spettro segnale NRZ . . . . . . . . . . . . . . . . . . . . .
Spettro di un segnale in banda traslata . . . . . . . . . . .
Trasformata di Hilbert nel dominio della frequenza . . . .
Modulazione QPSK nel tempo . . . . . . . . . . . . . . .
Tipologie di QPSK . . . . . . . . . . . . . . . . . . . . . .
Confronto costellazioni M–QAM e M–PSK . . . . . . . . .
Andamento temporale BFSK . . . . . . . . . . . . . . . .
Andamento temporale fase del segnale MSK . . . . . . . .
Risposta all’impulso del filtro gaussiano . . . . . . . . . .
Confronto spettri QPSK, MSK e GMSK . . . . . . . . . .
Demodulatore con banco di correlatori . . . . . . . . . . .
Demodulatore con filtro adattato . . . . . . . . . . . . . .
Effetto filtro adattato . . . . . . . . . . . . . . . . . . . .
Costellazione BPSK e densità di probabilità condizionate
Effetto
. . . . . . . . . . . . . .
intersimbolica
P∞ interferenza
m
1
X f + T per T < 2W . . . . . . . . . . . . . .
Pm=−∞
∞
1
X f+m
m=−∞ T per T = 2W . . . . . . . . . . . . . .
t
sinc
P∞ π T . . . .m. . . . . . . 1. . . . . . . . . . . . . . . .
m=−∞ X f + T per T > 2W . . . . . . . . . . . . . .
Sagomatura d’impulso a coseno rialzato . . . . . . . . . .
Diagrammi vettoriali QPSK con sagomatura d’impulso . .
Trasmissione numerica . . . . . . . . . . . . . . . . . . . .
Codificatore (3, 1, 3) . . . . . . . . . . . . . . . . . . . . .
Piano di Shannon . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
5
8
8
9
10
11
11
12
13
14
15
16
18
19
19
19
20
21
21
22
23
25
2.1
2.2
2.3
2.4
2.5
2.6
Modulatore
Modulatore
Modulatore
Modulatore
Modulatore
Modulatore
.
.
.
.
.
.
.
.
.
.
.
.
26
27
29
30
31
32
3.1
SRRC 19 coefficienti interpolante 3 . . . . . . . . . . . . . . .
36
Standard . . . . . . . . . .
DDFS . . . . . . . . . . .
QPSK classico per un solo
QPSK classico 3 data rate
QPSK classico 3 data rate
QPSK classico 3 data rate
vi
. . . . . . . .
. . . . . . . .
data rate . .
. . . . . . . .
Ottimizzato .
fclk = 4 × fif
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
SRRC 25 coefficienti interpolante 4 . . . . .
SRRC 39 coefficienti interpolante 6 . . . . .
SRRC interpolante 3, 4, 6 . . . . . . . . . .
FIR iesimo . . . . . . . . . . . . . . . . . . .
Rate Adapter . . . . . . . . . . . . . . . . .
SRRCxN versione ROM . . . . . . . . . . .
Confronto Polifase VHDL – Polifase Matlab
Confronto Polifase FPGA – Polifase Matlab
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
36
36
37
38
39
41
42
43
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
4.10
4.11
4.12
4.13
4.14
Effetto del canale sul segnale modulato QPSK . . . . .
Grafico prestazioni modem Matlab in termini di BER
Modulatore classico . . . . . . . . . . . . . . . . . . . .
SRRCxN versione RAM . . . . . . . . . . . . . . . . .
RAM 12 × 4096 . . . . . . . . . . . . . . . . . . . . . .
Temporizzazioni modulatore classico . . . . . . . . . .
ThinModulator . . . . . . . . . . . . . . . . . . . . . .
FIFO RAM ThinModulator . . . . . . . . . . . . . . .
Clock×2 . . . . . . . . . . . . . . . . . . . . . . . . . .
Interfaccia modulatore – sorgente dati . . . . . . . . .
Confronto Modulatore x3 VHDL – Matlab . . . . . . .
Confronto Modulatore x3 FPGA – Matlab . . . . . . .
Confronto Modulatore x4 FPGA – Matlab . . . . . . .
Confronto Modulatore x6 FPGA – Matlab . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
45
46
47
48
48
49
50
51
52
52
53
56
57
57
A.1 Schema di principio DDFS . . . . . . . . . . .
A.2 Spettro in uscita dal DAC . . . . . . . . . . .
A.3 Andamento nel tempo della parola troncata .
A.4 Spettro dente di sega . . . . . . . . . . . . . .
A.5 Ottimizzazione del convertitore fase-ampiezza
A.6 Rotazione planare . . . . . . . . . . . . . . .
A.7 Uscita DDFS nel tempo . . . . . . . . . . . .
A.8 Spettro Coseno Matlab . . . . . . . . . . . . .
A.9 NCO VHDL . . . . . . . . . . . . . . . . . . .
A.10 Iterazione iesima . . . . . . . . . . . . . . . .
A.11 Cordic Pipelined Unrolled . . . . . . . . . . .
A.12 Spettro coseno generato dal DDFS VHDL . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
60
61
62
62
63
64
66
67
67
68
69
70
B.1
B.2
B.3
B.4
B.5
B.6
B.7
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
72
73
73
74
74
75
76
Upsampling . . . . . . . . . . . . . . .
Upsampler . . . . . . . . . . . . . . . .
Downsampling . . . . . . . . . . . . .
Downsampler . . . . . . . . . . . . . .
Cambiamento di rate frazionario . . .
Nobili Identità . . . . . . . . . . . . .
Integratore e sua risposta in frequenza
vii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
B.8
B.9
B.10
B.11
B.12
B.13
Comb e sua risposta in frequenza . . .
Interpolatore CIC . . . . . . . . . . . .
Decimatore CIC . . . . . . . . . . . .
Spettro del CIC per R=2, N=1, M=1
Effetto di M sulla frequenza del CIC .
Trasformazioni interpolatore polifase .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
76
76
77
77
78
79
C.1
C.2
C.3
C.4
C.5
C.6
C.7
Gerarchia implementazioni circuiti logici
Implementazione di un moltiplicatore . .
Slice Virtex . . . . . . . . . . . . . . . .
CLB Virtex . . . . . . . . . . . . . . . .
VersaBlock . . . . . . . . . . . . . . . .
Clock globale . . . . . . . . . . . . . . .
Configurazione delle BlockRAM . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
81
84
85
85
86
87
88
viii
Ringraziamenti
Dal punto di vista didattico desidero ringraziare molti dei miei insegnanti,
un pensiero particolare per Francesco Valdoni che mi ha introdotto ad una
visione più ingegneristica delle Comunicazioni Elettriche, e per Giancarlo
Cardarilli, Marco Re, Andrea Del Re e Dario Gelfusa grazie ai quali quegli stessi concetti hanno trovato applicazione pratica in questa Tesi in un
contesto fortemente motivante.
Un ringraziamento ad Alenia Spazio per l’occasione formativa ed in
particolare all’Ing. Domenico Giancristofaro per la pazienza dimostrata nei
miei confronti ed il notevole apporto teorico.
Un rilevante contributo è giunto anche dai NewsGroup Comp.arch.fpga,
comp.lang.vhdl e comp.dsp nei quali Ray Andraka, Allan Herrimann, Jacky
Renaux e Brian Philopsky svolgono un importante servizio di volontariato
culturale.
Come dimenticare i compagni con cui sin dall’inizio abbiamo affrontato
insieme questa avventura, i loro nomi sono nella mia mente e nei tanti ricordi che ci accomunano, un grazie particolare a chi ha sempre corso dinanzi
a me dimostrandomi giorno per giorno che ciò che sembrava impossibile in
realtà non lo era, l’auspicio è di rimanere in contatto con tutti.
Ancora un grazie per la mia famiglia, per tutto ciò che non mi viene in
mente perché è banale, scontato, però esiste e mi ha consentito di arrivare
a questo traguardo, grazie Mamma perché ogni giorno trascorso con te è un
giorno felice.
ix
Introduzione
Le comunicazioni spaziali rappresentano probabilmente uno dei settori di
maggiore interesse dell’elettronica e delle telecomunicazioni, ad esse direttamente o indirettamente si debbono molti dei progressi scientifici degli
ultimi 50 anni, numerose sono infatti le applicazioni nella vita quotidiana
di idee e materiali derivati da attività spaziali. Queste comunicazioni erano
un tempo adibite esclusivamente ad attività militare o scientifica e pertanto
presentavano costi elevati e scarsa efficienza, l’avvento di servizi quale la tv
digitale, la telefonia, il GPS ed altri le hanno rese maggiormente soggette
alle leggi del mercato conseguentemente si è assistito ad un miglioramento
progressivo delle prestazioni, dei costi e dell’efficienza.
In questa rapida evoluzione l’unico aspetto che non è mai stato messo in
discussione è la modulazione adottata, infatti da sempre per la trasmissione
in ambito spaziale di segnali non di servizio si utilizza la modulazione QPSK
in quanto essa come vedremo individua il punto di minimo in un ideale
spazio sui cui assi ci sono l’efficienza spettrale, la semplicità circuitale1 e
l’efficienza energetica2 .
L’argomento della Tesi si può pertanto definire datato ed in fondo ben
conosciuto tuttavia il rapido e costante evolversi delle tecniche digitali, affiancato dai processi di integrazione su larga scala, consente di dire qualcosa di nuovo anche nella realizzazione di un modulatore QPSK, al riguardo
basta osservare che attualmente le FPGA3 sono utilizzate in applicazioni
spaziali soltanto per circuiti marginali mentre esse sono destinate ad un
ruolo primario nelle future realizzazioni in virtù delle prestazioni in rapida
ascesa, della loro riprogrammabilità a distanza e soprattutto della riduzione
di costi e tempi di progettazione che implicitamente consentono.
Le specifiche tecniche dalle quali trae origine il modulatore QPSK sono
state emesse dall’Alenia Aerospazio, una Società del gruppo Finmeccanica
all’avanguardia nell’industria aerospaziale mondiale. Tra i suoi prodotti di
maggior successo indubbiamente SkyPlex, un processore che consente l’accesso al satellite non più ad un unico flusso dati assemblato dalla stazione
1
che si traduce in spazi e pesi ridotti ovvero costi di lancio ridotti
molta della energia del satellite viene utilizzata per comunicare, ottimizzando questo
consumo si può aumentare sensibilmente la vita delle batterie e quindi del satellite stesso
3
Field Programmable Gate Array
2
1
2
gateway, bensi a più flussi i quali vengono demodulati separatamente, opportunamente assemblati e successivamente di nuovo modulati ed inviati
verso Terra in un unico flusso. I satelliti che attualmente utilizzano Skyplex
sono gli HotBird 4 e 5, dei geostazionari appartenenti all’operatore EUTELSAT [4] impiegati prevalentemente per la televisione digitale, al riguardo la
presenza di molteplici piccole emittenti che hanno accesso al satellite, sembra confermare l’idea che Skyplex abbia effettivamente rappresentato un
modo nuovo di concepire le comunicazioni satellitari.
Le portanti utilizzate sono a 14GHz per HotBird 5 e 19Ghz per HotBird
4, è naturalmente impensabile allo stato attuale della tecnologia digitale
pensare di produrre direttamente questi segnali, tuttavia i vantaggi del digitale sono fortemente desiderati ed allora nella presente Tesi si propone una
soluzione di compromesso ossia l’utilizzo di un modulatore digitale che modula una portante intermedia a 40MHz generata in forma digitale mediante
un DDFS4 a partire da un clock superiore a 160MHz, successive conversioni
di frequenza analogiche traslano poi il segnale modulato alle frequenze realmente applicate all’amplificatore di potenza TWTA5 che alimenta l’antenna
irradiante verso Terra. Le specifiche del modulatore digitale richiedono che
esso sia in grado di accettare tre distinti data rate, 55Mbps, 82, 5Mbps e
110Mbps, inoltre al fine di eliminare l’interferenza intersimbolica deve essere applicata una sagomatura d’impulso con spettro a coseno rialzato e
α = 0, 35 quale fattore di roll-off.
4
5
Direct Digital Frequency Synthesizer
Travelling Wave Tube Amplifier
Capitolo 1
Modulazioni digitali
1.1 Sommario
La trasmissione di informazione tra una sorgente ed un destinatario attraverso un mezzo trasmissivo comporta sempre il ricorso alla modulazione
che, a seconda della particolare applicazione, si propone di ottenere uno o
più dei seguenti obiettivi:
• minimizzare la potenza irradiata.
• minimizzare la banda occupata.
• minimizzare la complessità e quindi i costi.
in questo capitolo si cercherà di evidenziare i motivi che da sempre portano
a considerare la modulazione QPSK1 come la più adatta a comunicazioni
spaziali ad elevato data rate, in quest’ottica vengono anche introdotti concetti quali la sagomatura dell’impulso, la demodulazione con filtro adattato,
i criteri di decisione e la codifica.
1.2 Modulazione
Molte delle moderne comunicazioni elettriche avvengono in forma digitale
indipendentemente dal fatto che la sorgente sia digitale oppure analogica,
il motivo di ciò è che a monte e/o a valle del canale trasmissivo il segnale
subisce comunque delle elaborazioni digitali volte ad ottimizzarne le caratteristiche, pertanto la scelta di una trasmissione digitale rappresenta una
soluzione di continuità.
Lo spettro di un generico segnale randomico NRZ2 mostrato in Figura(1.1) evidenzia tuttavia come i segnali digitali non siano adatti alle tra1
2
Quadrature Phase Shift Keying
No Return to Zero
3
CAPITOLO 1. MODULAZIONI DIGITALI
4
Figura 1.1: Spettro segnale NRZ
smissioni in mezzi fisici reali, vi è infatti troppa potenza distribuita sui lobi
laterali, essa è sia inutile ai fini della trasmissione dell’informazione che deleteria in quanto aumenta il livello del rumore in eventuali canali adiacenti.
La potenza utile è invece addensata nei pressi della continua pertanto si
rende necessaria una traslazione in frequenza al fine di poter inviare più
sequenze digitali su di un unico mezzo trasmissivo.
1.2.1 Traslazione in frequenza
La traslazione in frequenza nella sua forma più semplice si ottiene moltiplicando il segnale digitale in banda base, opportunamente filtrato, per una
portante analogica a frequenza fc , ne deriva uno spettro bilatero centrato
su questa frequenza come in Figura(1.2).
Figura 1.2: Spettro di un segnale in banda traslata
Al fine di poter confrontare sistemi operanti a frequenze diverse è importante poter rappresentare in banda base un qualsiasi segnale in banda
CAPITOLO 1. MODULAZIONI DIGITALI
5
traslata s (t), a tal riguardo, in riferimento a sistemi reali, è di interesse il
solo asse positivo delle frequenze, descritto dal segnale analitico [2]
s+ (t) = s (t) + ŝ (t)
(1.1)
dove
ŝ (t) =
1
∗ s (t)
πt
(1.2)
è la trasformata di Hilbert di s (t) il cui effetto nel dominio della frequenza
è visualizzato in Figura(1.3), essa ruota di +90◦ le componenti a frequenza
Figura 1.3: Trasformata di Hilbert nel dominio della frequenza
positiva e di −90◦ quelle a frequenza negativa, ricordando inoltre che la
traslazione in frequenza corrisponde ad una moltiplicazione per l’esponenziale complesso nel dominio del tempo si ottiene l’espressione dell’inviluppo
complesso sl (t):
sl (t) = s+ (t) e−2πfc t
(1.3)
Il segnale in banda traslata s (t) può pertanto essere rappresentato in
tre diverse forme:
Inviluppo Complesso:
s (t) = < sl (t) e−2πfc t
(1.4)
s (t) = a (t) cos (2πfc t + ϕ (t))
(1.5)
Modulo e fase:
dove a (t) e ϕ (t) sono dei segnali reali in banda base che rappresentano
rispettivamente l’ampiezza e la fase del segnale in banda traslata s (t).
Quadratura:
s (t) = sc (t) cos (2πfc t) − ss (t) sin (2πfc t)
(1.6)
CAPITOLO 1. MODULAZIONI DIGITALI
6
essendo sc (t) e ss (t) dei segnali in banda base denominati rispettivamente componente in fase e componente in quadratura del segnale in
banda traslata s (t).
La formulazione(1.6) è di fondamentale importanza in questa Tesi in quanto
da essa si evince in maniera immediata lo schema di un possibile modulatore.
1.2.1.1 Spazio dei segnali
Un qualsiasi segnale reale può essere rappresentato come un vettore nello spazio dei segnali, tale spazio eredita le proprietà classiche degli spazi
vettoriali definiti dall’algebra lineare, in particolare è caratterizzato da una
norma:
s
Z b
p
|s (t)|2 dt
(1.7)
ks (t) k = hs (t) , s (t)i =
a
che consente di individuare una base ossia un gruppo di N segnali ψj aventi
norma unitaria ed ortogonali tra loro:
hψj , ψk i = 0 ∀ j, k : j 6= k
(1.8)
Ogni segnale sm (t) appartenente allo spazio dei segnali può essere rappresentato come combinazione lineare dei vettori ψj (t) della base
sm (t) =
N
X
smj ψj (t)
(1.9)
J=1
essendo smj (t) la proiezione di sm (t) lungo la direzione dello spazio vettoriale individuata dal jesimo vettore ψj (t) della base. Nel caso di uno spazio
bidimensionale si ha che m ∈ (1, 2) pertanto tralasciando la base che è
uguale per ogni segnale si ha che il generico segnale sm (t) è individuato dal
vettore s = [sm1 sm2 ].
Il progetto di una modulazione digitale si basa quindi sulla scelta di una
base ortonormale nella quale rappresentare M segnali disposti a formare
una costellazione le cui caratteristiche geometriche influenzano il progetto
del trasmettitore e la qualità della ricezione. La sequenza di bit da trasmettere viene suddivisa in gruppi costituiti da b = log2 M bits, ogni gruppo
individua un simbolo tra gli M di un alfabeto cui sono associati gli M
segnali della costellazione.
1.2.1.2 Tipologie di modulazioni satellitari
Il segnale in banda traslata espresso dall’equazione(1.5) evidenzia come l’informazione in banda base possa essere codificata sia nel modulo che nella
CAPITOLO 1. MODULAZIONI DIGITALI
7
fase3 della portante. Per applicazioni satellitari non si utilizzano modulazioni che associano informazione al modulo della portante in quanto richiedono
amplificatori lineari in classe A che non sfruttano al meglio la scarsa energia disponibile, inoltre tali modulazioni sono vulnerabili alle variazioni del
guadagno del canale stesso.
Nel caso di una modulazione M–PSK4 utilizzante una portante a frequenza fc e per la quale ogni simbolo da trasmettere sia caratterizzato da
energia ES si ha l’espressione del segnale modulato:
r
2ES
2π
sm (t) =
g (t) cos
(m − 1) cos (2πfc t) −
T
M
(1.10)
r
2ES
2π
g (t) cos
(m − 1) sin (2πfc t)
T
M
dove g(t) è la sagomatura d’impulso5 ed m = 1, 2, . . . , M è un intero
associato al simbolo del quale è richiesta la trasmissione.
La base è costituita dalle funzioni
r
2
ψ1 (t) =
g (t) cos (2πfc t)
T
r
2
ψ2 (t) =
g (t) sin (2πfc t)
T
(1.11)
pertanto ogni segnale modulato può essere rappresentato da un vettore:
sm = [sm1 sm2 ] =
√
Es cos
2π
M
(m − 1)
√
Es sin
2π
M
(m − 1)
(1.12)
Le tipologie più comuni di M–PSK sono la BPSK6 (M= 2) e la QPSK(M=
4), per quest’ultima l’andamento nel tempo è illustrato in Figura(1.4), dove
non essendo stata applicata la sagomatura dell’impulso si ha che l’inviluppo è costante, tale soluzione è di solo interesse teorico in quanto l’efficienza energetica che ne deriva non bilancia i numerosi problemi derivanti
dall’insorgere dell’interferenza intersimbolica.
La costellazione QPSK è costituita da 4 punti individuati sostituendo
m = 1, 2, 3, 4 nella equazione(1.13),
Z
smj =
T
sm (t) ψj (t)
0
i loro valori sono riportati in Tabella(1.1).
3
e quindi nella frequenza
Phase Shift Keying
5
Sezione(1.3.3)
6
Binary Phase Shift Keying
4
(1.13)
CAPITOLO 1. MODULAZIONI DIGITALI
8
Figura 1.4: Modulazione QPSK nel tempo
Simbolo
00
01
10
11
Segnale
s0
s1
s2
s3
Coordinata I
+1
-1
-1
+1
Coordinata Q
+1
+1
-1
-1
Tabella 1.1: Punti della costellazione QPSK
Le brusche transizioni della fase in Figura(1.4) si hanno nel passaggio
dal simbolo che nella costellazione di Figura(1.5a) ha coordinate (1, 1) al
simbolo con coordinate (−1, −1) , l’inviluppo complesso passa per l’origine e compie una ampia escursione in ampiezza inadatta agli amplificatori
non lineari utilizzati per ottimizzare l’impiego dell’energia nel satellite. La
Figura 1.5: Tipologie di QPSK
modulazione OQPSK7 la cui costellazione è rappresentata in Figura(1.5b)
è una variante della QPSK che risolve il problema delle transizioni di fase
7
Offset Quadrature Phase Shift Keying
CAPITOLO 1. MODULAZIONI DIGITALI
9
mediante uno sfasamento temporale tra la componente in fase e quella in
quadratura, esse non cambiano mai contemporaneamente pertanto la massima variazione dell’ampiezza dell’inviluppo complesso è di circa 3dB contro
i 40dB della QPSK.
La modulazione π4 QPSK [1] risolve il medesimo problema ruotando di
π
4 la costellazione ad ogni simbolo come in Figura(1.5c), in tal modo la
escursione di fase massima è di 135◦ , intermedia tra i 180◦ della QPSK
convenzionale ed i 90◦ della OQPSK, rispetto a quest’ultima però si ha il
vantaggio di poter utilizzare la demodulazione incoerente, l’informazione è
infatti associata all’ampiezza della variazione di fase ed alla direzione in
cui avviene la rotazione pertanto non è necessario che il ricevitore conosca
la fase in anticipo visto che il riferimento per la demodulazione del simbolo attuale è costituito dal simbolo precedente. Il ricevitore π4 QPSK ha
un’architettura più semplice ma la probabilità d’errore è maggiore di circa
3dB rispetto all’equivalente ricevitore coerente in quanto sono possibili due
sorgenti d’errore, un simbolo corrotto oppure un riferimento errato.
Una diretta estensione della modulazione M–PSK è la M–QAM8 , le
loro costellazioni coincidono nel caso di M = 4 mentre per valori diversi
differiscono profondamente come evidenziato in Figura(1.6) nel caso di M =
16.
Figura 1.6: Confronto costellazioni M–QAM e M–PSK
Per entrambe l’efficienza spettrale è ηs = 4 in quanto ad ogni simbolo
sono associati 4 bit mentre nella QPSK soltanto due, i segnali della costellazione QAM tuttavia non hanno tutti la stessa energia pertanto, per i motivi
precedentemente esposti, non sono adatti ad applicazioni spaziali.
Dalla costellazione della 16–PSK si può osservare come i segnali siano
ravvicinati tra loro molto più che nella QPSK dove se ne ha uno in ogni
quadrante, ciò determina un aumento della probabilità di scambiare un
8
Quadrature Amplitude Modulation
CAPITOLO 1. MODULAZIONI DIGITALI
10
segnale per uno dei segnali adiacenti pertanto occorre aumentare la potenza
al fine di ottenere la stessa probabilità d’errore della QPSK.
L’altra grande famiglia di modulazioni digitali utilizzata in ambito spaziale è quella che interessa le variazioni della frequenza della portante e che
va sotto il nome di M–FSK9 [7], continua o discontinua a seconda che la
variazione tra le M frequenze associate ai simboli da trasmettere avvenga
con continuità di fase o meno. In Figura(1.7) è riportato l’andamento tem-
Figura 1.7: Andamento temporale BFSK
porale di una M–FSK incoerente per il caso di M = 2, essa si realizza con
due oscillatori, a seconda del simbolo da trasmettere il modulatore emette
una portante oppure l’altra.
Le discontinuità nella fase che si hanno nella M–FSK incoerente determinano una banda molto ampia e pertanto una scarsa efficienza spettrale,
per questo motivo si sono affermate le tecniche a fase continua CPFSK10 il
cui generico segnale modulato è descritto dalla:
r
sm (t) =
Z t
2Eb
cos 2πfc t + 2πkf
m (τ ) dτ
Tb
−∞
(1.14)
dove la fase del segnale modulato è continua in quanto non direttamente
proporzionale al segnale modulante digitale m (t) ma al suo integrale. L’indice di modulazione kf = 2∆f
Rb determina la separazione tra i toni, essa è
minima nel caso della MSK11 per la quale si ha kf = 0, 5. L’andamento
della fase nel tempo per la MSK è rappresentato in Figura(1.8), ad ogni bit
1 da trasmettere viene associato un aumento della fase pari a +90◦ mentre
ad ogni bit 0 si associa una diminuzione di −90◦ della stessa.
Una derivazione della MSK è la GMSK12 che riduce ulteriormente la
banda filtrando la modulante digitale con un filtro gaussiano avente risposta
9
Frequency Shift Keying
Continuous Phase Frequency Shift Keying
11
Minimum Shift Keying
12
Gaussian Minimum Shift Keying
10
CAPITOLO 1. MODULAZIONI DIGITALI
11
Figura 1.8: Andamento temporale fase del segnale MSK
all’impulso
√
hG (t) =
π − π22 t2
e α
α
(1.15)
rappresentata in Figura(1.9),
Figura 1.9: Risposta all’impulso del filtro gaussiano
esso è completamente descritto dal prodotto BT dove T è l’intervallo
di simbolo e B la banda a 3dB determinata da α = 1,8
B , quanto più BT
diminuisce tanto più lo spettro diviene compatto comportando però un
aumento dell’interferenza intersimbolica13 .
La Figura(1.10) illustra un confronto spettrale tra le modulazioni MSK,
GMSK e QPSK, lo spettro di quest’ultima è il più stretto per quel che
riguarda la banda utile me presenta molta energia distribuita inutilmente
sui lobi secondari, la modulazione più efficiente sotto questo punto di vista
è la GMSK che, per tal motivo, è utilizzata nella telefonia cellulare GSM
13
Sezione(1.3.3)
CAPITOLO 1. MODULAZIONI DIGITALI
12
Figura 1.10: Confronto spettri QPSK, MSK e GMSK
dove i canali sono molto vicini tra loro e si richiede elevata autonomia delle
batterie.
1.3 Principi di demodulazione
Questa Tesi è volta alla realizzazione di un modulatore QPSK, ciò implica
tuttavia la conoscenza almeno dei principi della demodulazione che vengono
qui brevemente esposti tralasciando il caso in cui il segnale in ingresso al
ricevitore presenti una deriva di fase, frequenza o temporizzazione.
Un generico ricevitore digitale è costituito dalla cascata di due circuiti,
un demodulatore ed un decisore, il primo si occupa di estrarre dal segnale
modulato affetto da rumore le componenti nelle direzioni dei vettori ψi della
base dello spazio dei segnali utilizzato, compito poi del decisore è di scegliere
quale tra i segnali appartenenti alla costellazione trasmessa sia da associare
al segnale ricevuto.
1.3.1 Demodulatore
Il segnale r (t) in ingresso al ricevitore è la somma del segnale modulato sm (t) e del rumore n (t) introdotto dal canale, quest’ultimo può essere espresso come combinazione lineare dei vettori ψi della base14 , si ha
14
la parte di n (t) che non è rappresentabile come combinazione lineare degli ψi è
irrilevante nel processo di decisione
CAPITOLO 1. MODULAZIONI DIGITALI
13
pertanto:
T
Z
rj (t) =
r (t) ψj (t) dt
0
T
Z
Z
=
sm (t) ψj (t) dt +
0
T
n (t) ψj (t) dt
(1.16)
0
= smj (t) + nj (t)
questa equazione descrive in maniera immediata il demodulatore che può
essere realizzato con un banco di correlatori ciascuno dei quali correla il segnale ricevuto r (t) con uno dei vettori della base restituendone la proiezione
in quella direzione, tale demodulatore è descritto in Figura(1.11).
Figura 1.11: Demodulatore con banco di correlatori
Un demodulatore ben più semplice può essere dedotto dalla medesima
equazione(1.16) scrivendo la correlazione come una convoluzione:
Z
T
rj =
r (τ ) ψj (τ ) dτ
0
Z
T
r (τ ) ψj (T − t + τ ) dτ |t=T
=
(1.17)
0
= [r (t) ∗ ψj (T − t)] |t=T
ne consegue che la componente rj (t) del segnale ricevuto può essere calcolata campionando al tempo t = T l’uscita di un filtro avente risposta
all’impulso h (t) = ψj (T − t). Il demodulatore basato su questo banco di
filtri che si dicono adattati ai segnali della base è illustrato in Figura(1.12),
per esso una considerazione importante è che l’uscita dai filtri adattati è
CAPITOLO 1. MODULAZIONI DIGITALI
14
Figura 1.12: Demodulatore con filtro adattato
campionata soltanto a t = T, essendo T il tempo di simbolo, e quindi
non è richiesto che essa sia uguale all’impulso trasmesso in ogni istante, è
sufficiente che lo sia nel solo istante di campionamento.
Il filtro adattato è il demodulatore che consente di ottenere il più alto
SNR15 , la sua risposta in frequenza è infatti:
HRX (f ) = HT∗ X (f ) e−2πf t
(1.18)
che corrisponde a ruotare tutte le componenti del segnale d’ingresso in modo
che abbiano la stessa fase come illustrato graficamente in Figura(1.13), si
ottiene cosı̀ che i moduli delle singole componenti del segnale si sommano in
maniera costruttiva massimizzando l’energia del segnale mentre quella del
rumore rimane invariata.
1.3.2 Decisore
L’uscita del demodulatore lungo il jesimo vettore della base dello spazio dei
segnali è somma di una componente deterministica e di una componente aleatoria gaussiana generata dall’elaborazione di un processo di rumore
gaussiano, la componente deterministica individua con precisione nello spazio dei segnali il segnale trasmesso mentre la componente gaussiana provoca
una deviazione rispetto ad esso la cui ampiezza è individuata dal valore
della densità spettrale di rumore N20 .
15
Signal to Noise Ratio
CAPITOLO 1. MODULAZIONI DIGITALI
(a) Segnale trasmesso
15
(b) Uscita
adattato
del
filtro
Figura 1.13: Effetto filtro adattato
Il processo di decisione [13] che associa il segnale demodulato r0 ad uno
dei vettori della costellazione può essere implementato secondo il criterio
ML16 oppure il MAP17 :
ML: consiste nello scegliere il vettore sj della costellazione che ha la maggior probabilità di coincidere col segnale sm emesso.
MAP: è uguale al criterio ML ma tiene anche conto del fatto che non
necessariamente tutti i segnali appartenenti alla costellazione hanno
la stessa probabilità di essere emessi.
Se i segnali della costellazione sono equiprobabili allora i due criteri
coincidono e il decisore non fa altro che calcolare le distanze tra il segnale
demodulato r0 e tutti i segnali sj della costellazione optando poi a favore del
più vicino, in sostanza quindi il decisore suddivide lo spazio dei segnali in M
regioni dette di decisione, ciascuna contiene un punto sj della costellazione
e tutti i punti che sono più vicini ad esso che non agli altri punti della costellazione. Nel caso si utilizzi il criterio MAP le regioni si ampliano per quei
punti della costellazione che hanno maggiore probabilità di essere emessi a
discapito delle regioni che contengono i punti con minore probabilità.
Le probabilità d’errore [8] di BPSK e QPSK coincidono in quanto la
QPSK è data dall’unione
di due √
costellazioni BPSK ortogonali tra loro, I
√
due segnali s1 = Eb e s2 = − Eb della costellazione BPSK sono rappresentati in Figura(1.14) insieme alla densità di probabilità condizionate:
√
(r− Eb )
1
−
N0
p (r|s1 ) = √
e
πN0
16
17
Maximum Likelihood
Maximum A Posteriori probability
2
(1.19)
CAPITOLO 1. MODULAZIONI DIGITALI
16
Figura 1.14: Costellazione BPSK e densità di probabilità condizionate
√
(r+ Eb )
1
−
N0
p (r|s2 ) = √
e
πN0
2
(1.20)
Nell’ipotesi che sia stato emesso s1 (t) la probabilità d’errore si ottiene integrando la gaussiana da −∞ a 0 infatti quella è la regione di decisione
associata al simbolo s2 , si ha:
Z 0
P (e|s1 ) =
P (r|s1 ) dr
−∞
√
Z 0
(r− Eb )2
1
−
N0
e
=√
dr
πN0 −∞
r
Z 2Eb
N0
x2
1
e− 2 dx
=√
2π −∞
Z +∞
2
1
− x2
r
e
dx
=√
2Eb
2π
N0

s
!
r
2
Eb
2Eb
d12  1
=Q
= Q
= erf c
N0
2N0
2
N0
(1.21)
essendo erf c (x) la funzione complementare di errore
erf c (x) =
2
π
Z
+∞
2
e−y dy
(1.22)
x
Il medesimo risultato si ha per P (e|s2 ) e, per via della simmetria della costellazione, entrambe coincidono con la probabilità d’errore della mo-
CAPITOLO 1. MODULAZIONI DIGITALI
17
dulazione BPSK e quindi anche della QPSK che tuttavia ha un’efficienza
spettrale doppia in quanto ad ogni simbolo associa due bit e non uno.
L’ultima formulazione della (1.21) consente due osservazioni importanti:
Eb
1. la probabilità d’errore dipende unicamente dal rapporto N
denomi0
nato rapporto segnale/rumore per bit e non da altre caratteristiche
del segnale o del rumore.
2. quanto più sono ravvicinati i simboli della costellazione tanto più
peggiora la probabilità d’errore, questo è il motivo per il quale alla
16–PSK si preferisce la QPSK anche se l’efficienza spettrale è inferiore.
La BER18 esprime lo stesso concetto della probabilità d’errore ma in
maniera più immediata, essa è infatti il rapporto tra il numero dei bit
ricevuti in maniera errata ed il numero totale dei bit trasmessi, una analoga
misura è la SER19 che esprime invece il rapporto tra il numero dei simboli
ricevuti in maniera errata ed il numero totale dei simboli trasmessi, esse
coincidono per la QPSK a patto di utilizzare la codifica di Gray la quale
associa a segnali adiacenti della costellazione gruppi di bit che differiscono
tra loro soltanto per un bit.
1.3.3 Interferenza intersimbolica
L’equazione delle onde per un mezzo debolmente disomogeneo e non dissipativo
∇2 E + κ20 n2 (r) E = 0
(1.23)
p
è funzione dell’indice di rifrazione n(r) = 0 (r) essendo 0 la parte reale
della costante dielettrica del mezzo.
Ipotizzando per la (1.23) una soluzione espressa nella forma della espansione asintotica di Luneburg-Kline
−jκ0 Φ(r)
E (r) = e
∞
X
Em (r)
(κ0 )m
(1.24)
m=0
si perviene all’importante risultato secondo il quale nel caso in cui l’indice
di rifrazione del mezzo trasmissivo dipende dalla frequenza si ha che un
impulso trasmesso subisce un allargamento temporalmente e per il principio
della conservazione dell’energia diminuisce in ampiezza [11]. Il fenomeno
viene denominato ISI20 ed è particolarmente deleterio nelle trasmissioni di
impulsi digitali reali come quelli tratteggiati in Figura(1.15a), essi vengono
deformati come in Figura(1.15b) pertanto negli istanti di campionamento
18
Bit Error Rate
Symbol Error Rate
20
Inter Symbol Interference
19
CAPITOLO 1. MODULAZIONI DIGITALI
(a) Segnale Tx ed Rx
18
(b) Effetto ISI su impulsi
Figura 1.15: Effetto interferenza intersimbolica
del ricevitore si hanno contributi derivanti da più impulsi il che può generare
errori come ad esempio nell’istante (3) dove il segnale ricevuto ha ampiezza
dimezzata rispetto al simbolo trasmesso.
Il problema dell’interferenza intersimbolica è stato individuato sin dalle
prime trasmissioni transoceaniche di Morse, una soluzione intuitiva fu quella di operare al massimo data rate in grado di consentire una ricezione di
buona qualità21 , tuttavia l’evolversi delle tecnologia e la sempre più stringente necessità di trasmettere in tempi brevi grandi moli di informazione ha
portato ad una soluzione più ingegnosa.
Ricordando che il ricevitore basato sul filtro adattato richiede l’uguaglianza tra l’impulso trasmesso e quello ricevuto soltanto nell’istante di campionamento ne consegue che si può scegliere una forma dell’impulso qualsiasi a
patto che si annulli in tutti i multipli dell’istante di campionamento tranne
uno, il suo andamento temporale è pertanto:
1 se n = 0
(1.25)
x (nT ) =
0 se n 6= 0
in virtù della condizione di Nyquist [8] per l’annullamento dell’ISI si ha che
gli impulsi x (t) che rispettano la (1.25) sono tutti quelli la cui trasformata
di Fourier risponde al vincolo
∞
X
m
X f+
=T
T
m=−∞
(1.26)
dove W è la banda del canale.
I casi possibili sono tre:
T <
1
2W :
T =
1
2W :
21
le repliche di X (f ) non si sovrappongono pertanto non c’è modo
di rispettare il criterio di Nyquist e quindi l’utilizzo di queste tipologie
di impulsi porta a trasmissioni affette da ISI.
questa condizione implica che le repliche spettrali si tocchino solo
in un punto come in Figura(1.17), l’unico spettro che soddisfa questa
circa 200Baud per il telegrafo
CAPITOLO 1. MODULAZIONI DIGITALI
19
T
-W
-1/T
Figura 1.16:
-1/T
W
0
P∞
m=−∞ X
f+
m
T
per T <
1
2W
T
-W
-1/T
Figura 1.17:
-1/T
W
0
P∞
m=−∞ X
f+
m
T
per T =
1
2W
condizione è descritto dalla
X (f ) =
se |f | < W
altrimenti
T
0
(1.27)
si tratta di un rettangolo in frequenza cui corrisponde la
sin π Tt
x (t) =
π Tt
t
≡ sinc π
T
(1.28)
rappresentata in Figura(1.18), essa presenta la banda minima ma è
praticamente irrealizzabile per via della anticausalità e delle lunghe
code che si estendono illimitatamente e decadono come x1 .
Figura 1.18: sinc π Tt
T >
1
2W :
le repliche spettrali in questo caso si sovrappongono, vi sono quindi molti impulsi che rispettano il criterio di Nyquist, la famiglia più
CAPITOLO 1. MODULAZIONI DIGITALI
20
T
-W
-1/T
Figura 1.19:
0
P∞
m=−∞ X
-1/T
W
f+
m
T
per T >
1
2W
utilizzata è quella degli spettri a coseno rialzato descritti dalla

0 ≤ |f | ≤

 Th
i se
(1−α)
(1+α)
T
πT
Hrc (f ) =
|f | − 2T
se
2 1 + cos α
2T ≤ |f | ≤


0
se
0 ≤ |f | ≥
(1+α)
2T
(1−α)
2T
(1−α)
2T
(1.29)
dove α è il fattore di roll-off ed assume valori compresi tra 0 ed 1,
in particolare per α = 0 la banda occupata dall’impulso è proprio la
minima di Nyquist22 , al crescere di α essa aumenta sino a raddoppiare
per α = 1. L’individuazione degli spettri a coseno rialzato parte dalla
antitrasformata di Fourier:
sin 2πt
TS
cos (2παt)
(1.30)
h (t) =
2πT 1 − 2αt 2
π
che evidenzia come la sinc viene corretta con il coseno al fine di migliorarne le caratteristiche, rilevante l’ossevazione che le code dell’impulso sagomato pur continuando ad estendersi illimitatamente decadono come x13 pertanto molto più rapidamente che non nel caso in cui
l’impulso sagomato sia una sinc.
Nelle applicazioni pratiche si utilizza la sagomatura d’impulso con spettro a coseno rialzato, la risposta in frequenza e nel tempo è illustrata al variare di α in Figura(1.20) si può osservare come quanto più α tende a zero,
tanto più hanno ampiezza elevata i lobi laterali, ciò determina forti escursioni dell’inviluppo complesso come mostrato in Figura(1.21), pertanto per
consentire un utilizzo ottimale degli amplificatori, nelle applicazioni spaziali
si utilizza il valore α = 0, 35.
Alla luce dei concetti esposti per il filtro adattato, si comprende come
sia sensato suddividere la sagomatura a coseno rialzato tra il trasmettitore
ed il ricevitore secondo la
Hrc (f ) = HT x (f ) HRx (f )
22
ossia
Rs
2
(1.31)
CAPITOLO 1. MODULAZIONI DIGITALI
(a) Risposta in frequenza
21
(b) Risposta nel tempo
Figura 1.20: Sagomatura d’impulso a coseno rialzato
Figura 1.21: Diagrammi vettoriali QPSK con sagomatura d’impulso
in entrambe sono infatti necessari dei filtri23 che possono essere progettati in
modo da eseguire anche la sagomatura dell’impulso, il modulo della risposta
in frequenza per entrambe gli SRRC24 sarà pertanto:
|HT x (f )| = |HRx (f )| =
p
Hrc (f )
(1.32)
1.3.4 Principi di codifica
Tralasciando l’eventuale conversione in digitale di una sorgente analogica,
si ha che una generica trasmissione numerica può essere realizzata come in
figura(1.22) dove la codifica di sorgente si propone di rimuovere le dipendenze tra i simboli da trasmettere al fine di ridurne il numero come nel caso
degli algoritmi che nei computer vengono utilizzati per la compressione dei
file.
23
il filtro in trasmissione riduce le emissioni nelle bande adiacenti mentre quello in
ricezione effettua la demodulazione ed elimina il rumore esterno alla banda utile.
24
Square Root Raised Cosine
CAPITOLO 1. MODULAZIONI DIGITALI
22
Figura 1.22: Trasmissione numerica
La codifica di canale si basa sull’introduzione di simboli addizionali nella sequenza trasmessa, essi sono scelti in modo da presentare una qualche
correlazione tra loro consentendo cosı̀ la rivelazione degli errori e conseguentemente la riduzione della probabilità di errore intrinseca del canale.
Le principali tecniche di correzione degli errori sono due, la ARQ25 e la
FEC26 :
ARQ: suddivide in blocchi l’informazione da trasmettere, se in ricezione
si individua la presenza di errori in un blocco ne viene richiesta la
ritrasmissione, necessita di un canale duplex ed ha lo svantaggio che
anche un singolo errore comporta la ritrasmissione dell’intero blocco
in cui è contenuto.
FEC: non richiede un canale duplex ma il numero di simboli ridondanti da
aggiungere è molto maggiore rispetto all’ARQ, ne consegue che il data
rate effettivo si riduce ma, per il teorema di Shannon sulla Capacità
trasmissiva27 si riduce anche la potenza necessaria per ottenere una
trasmissione numerica praticamente esente da errori.
In ambito satellitare si utilizza la codifica di canale di tipo FEC, in una
o più delle seguenti forme:
Codifica a blocchi: la più importante è la Reed-Salomon (204,188), essa
aggiunge 16 bytes di ridondanza per ogni 188 bytes da trasmettere,
in tal modo si possono correggere sino a 8 errori e la BER richiesta
passa da 10−4 a più di 10−10 . Il principio è che con l’aggiunta di bit si
ottengono delle combinazioni le quali possono essere ricevute soltanto
in caso di errore, una volta che esso è stato rilevato si sceglie nell’alfabeto dei possibili simboli trasmessi quello che presenta la distanza di
Hamming28 minore rispetto al simbolo ricevuto.
Codifica convoluzionale: viene specificata con i tre parametri (n,k,m)
dove k è il numero di bit in ingresso ed n il numero di bit in uscita
dal codificatore, entrambe assumono valori compresi tra 1 ed 8, m è
invece il numero di registri utilizzati ed è compreso tra 2 e 10.
25
Automatic ReQuest for repeat
Forward Error Correction
27
Sezione(1.3.5)
28
è il numero di bit diversi tra due simboli
26
CAPITOLO 1. MODULAZIONI DIGITALI
23
Un esempio di codificatore è riportato in Figura(1.23), esso produce 3
Figura 1.23: Codificatore (3, 1, 3)
bit di uscita per ogni bit di ingresso quindi il ritmo di codifica è 1/3,
ogni bit d’uscita è generato quale somma di alcuni dei bit presenti negli m = 3 registri di memoria, il criterio di selezione di questi polinomi
generatori determina la qualità della codifica. Laddove si desideri un
ritmo di codifica variabile si ricorre alla versione Punctured, in particolare se si richiede la massima qualità vengono utilizzano tutte le n
uscite del codificatore convoluzionale, altrimenti soltanto una parte di
esse.
Interleaving: le codifiche precedenti hanno prestazioni eccellenti ma in
presenza di un gruppo di errori ravvicinati non sono in grado di ricostruire la sequenza trasmessa, il problema si risolve mescolando i bit
della sequenza da trasmettere ad esempio caricando una ROM lungo
le righe e leggendone il contenuto lungo le colonne.
1.3.5 Capacità trasmissiva
Per confrontare differenti tipi di modulazione e comprendere come l’effetto
dei codici possa migliorare la qualità di una trasmissione numerica è molto
utile il teorema [3] seguente:
Teorema 1 (di Shannon) Un qualsiasi canale caratterizzato da una velocità di segnalazione Rs = T1s , una varianza29 di rumore al ricevitore σS2 ed
2 pone un limite, denominato capacità
una varianza del segnale ricevuto σN
di canale C, al massimo flusso informativo che transita in esso:
C=
29
potenza
1
2TS log2
1+
2
σS
2
σN
(bit/s)
(1.33)
CAPITOLO 1. MODULAZIONI DIGITALI
24
nel caso di rumore gaussiano additivo bianco con densità spettrale di
2 = N B
potenza SW (f ) = N20 si ha che la potenza di rumore è PW = σW
0
inoltre se la sorgente è gaussiana e limitata nella banda B può essere rappresentata con 2B campioni30 ciascuno con la medesima potenza PS = σS2 ,
ne deriva che l’equazione(1.33) può essere riscritta nella forma:
C = Blog2 1 +
PS
N0 B
(bit/s)
(1.34)
dalla quale si deduce che a parità di rumore se si vuole aumentare la capacità trasmissiva di un canale conviene aumentare la banda B, un aumento
della potenza ha infatti minore effetto essendo mitigato dal logaritmo.
E’ interessante una rappresentazione grafica dell’equazione(1.34) nel cosiddetto piano di Shannon, si giunge ad essa partendo dall’ipotesi che il
ritmo binario in trasmissione sia uguale alla capacità del canale, si ha cioè
C = Rb = T1b pertanto
C
R b PS T b
C PS Tb
C Eb
= log2 1 +
= log2 1 +
= log2 1 +
B
N0 B
B N0
B N0
(1.35)
da cui si ottiene
C
Eb
2B − 1
(1.36)
=
C
N0
B
che rappresenta la curva limite nel piano di Shannon illustrato in Figura(1.24), la regione sottostante è quella permessa ed in essa giacciono i
punti corrispondenti alle varie modulazioni, quanto più essi si avvicinano
Eb
alla curva limite riuscendo a mantenere basso il rapporto N
tanto più la
0
modulazione è efficiente.
I punti corrispondenti alle modulazioni si ottengono imponendo per tutte una determinata probabilità d’errore, 10−5 per il piano in Figura(1.24),
Eb
ad essa nel caso della QPSK corrisponde N
= 9, 6dB mentre l’efficienza
0
Rb
spettrale è ηS = B = 2 in quanto ad ogni coppia di bit si associa un simbolo, le coordinate del punto sono pertanto (9, 6 , 2). La modulazione BPSK
Eb
presenta lo stesso N
e quindi la stessa efficienza energetica ma l’efficienza
0
spettrale vale 1 pertanto sotto questo punto di vista è più lontana dalla
curva limite e quindi le sue prestazioni sono inferiori. Nel caso di una QPSK con codifica convoluzionale, caratterizzata da un ritmo di codifica 1/2 e
k = 7 bit, si ha un guadagno di codifica di 5, 2dB rispetto alla QPSK non
codificata mentre l’efficienza spettrale vale 1 pertanto le coordinate del punto sono (4, 4 , 1), la forte vicinanza alla curva limite giustifica il crescente
interesse per i turbocodici. E’ interessante osservare come le modulazioni di
30
per il teorema del campionamento
CAPITOLO 1. MODULAZIONI DIGITALI
25
Figura 1.24: Piano di Shannon
tipo M–QAM con costellazione quadrata incrementano l’efficienza spettrale
della trasmissione, ma penalizzano l’efficienza energetica di circa 6 dB per
ogni quadruplicazione dei punti della costellazione.
Capitolo 2
Architetture modulatori
QPSK
2.1 Sommario
Dalla formula che descrive la generica modulazione M–PSK
r
2ES
2π
g (t) cos
(m − 1) cos (2πfc t) −
sm (t) =
T
M
r
2ES
2π
g (t) cos
(m − 1) sin (2πfc t)
T
M
(2.1)
si ricava immediatamente lo schema di un modulatore che la implementi
infatti cos (2πfc t) e sin (2πfc t) sono due portanti in quadratura generabili
in forma analogica come in Figura(2.1)
Figura 2.1: Modulatore Standard
o in forma digitale ottenendo in tal caso risultati nettamente superiori
in termini di purezza spettrale e risoluzione.
26
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
27
La modulante
agisce su m ∈ (0, 1, 2, 3), corrispondentemente il termine
(m
−
1)
si valorizza nell’insieme (−1, 0, +1) e quindi ben si presta
cos 2π
M
ad una realizzazione digitale. La sagomatura dell’impulso1 g (t) necessaria
ai fini dell’eliminazione dell’ISI si realizza con un filtro analogico o digitale,
quest’ultimo è da preferire in quanto non necessita di tarature individuali
ed è meno ingombrante.
L’orientamento pertanto è stato sin dall’inizio per una realizzazione completamente digitale, tuttavia anche nel solo ambito digitale vi sono diverse
modalità di implementare alcuni dei blocchi costituenti il modulatore, nel
seguito verranno esposte le diverse soluzioni prese in considerazione ed i
criteri che hanno portato alla selezione dell’architettura adottata.
2.2 Realizzazioni digitali di modulatori QPSK
Sono state individuate due diverse architetture per la realizzazione del modulatore QPSK, la prima lo vede realizzato variando alcuni dei parametri
di un DDFS mentre la seconda si ottiene digitalizzando uno o più blocchi
dello schema classico di Figura(2.1).
2.2.1 Modulatore DDFS
Il DDFS2 è costituito da un accumulatore di fase il quale somma al suo
valore precedente un contributo fisso generando cosı̀ una rampa di fase, applicandola poi ad un convertitore fase-ampiezza si ottiene la funzione sinusoidale desiderata. Il DDFS può essere utilizzato per realizzare tre differenti
modulazioni come illustrato in Figura(2.2).
Figura 2.2: Modulatore DDFS
La scelta dell’incremento di fase, congiuntamente alla frequenza di clock
del sistema, determina la frequenza generata, sommando all’incremento fisso
1
2
Sezione(1.3.3)
Appendice(A.2)
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
28
un valore variabile in funzione della modulante si realizza una modulazione
di frequenza con ottime prestazioni in quanto il cambio frequenza avviene
con continuità di fase ed istantaneamente.
La modulazione di fase si ottiene in maniera analoga sommando la modulante alla rampa di fase generata dall’accumulatore, l’inviluppo costante
che ne deriva non consente di implementare sagomatura dell’impulso3 in
quanto questa, come visto in Figura(1.21), produce un inviluppo il cui modulo varia nel tempo e viene a coincidere con i punti della costellazione nei
soli istanti di simbolo.
La terza modulazione implementabile è quella d’ampiezza che si ottiene
secondo lo schema classico ossia moltiplicando la portante sinusoidale che si
ha in uscita dal convertitore fase-ampiezza per la modulante.
In definitiva il modulatore basato sul DDFS è molto flessibile e consente
di applicare contemporaneamente ad una stessa modulante una o più modulazioni4 tuttavia la limitazione che riguarda l’inviluppo complesso lo rende
inutilizzabile per la realizzazione di un modulatore QPSK per applicazioni
spaziali.
2.2.2 Modulatore classico
L’implementazione digitale del modulatore classico si basa anche essa sul
DDFS5 il quale genera due portanti in quadratura aventi frequenza che da
specifica deve essere 40MHz, esse sono in formato digitale pertanto ogni
loro campione assume un valore compreso tra −1 e +1 ed è espresso in
complemento a due su 12 bit. I campioni delle portanti vengono emessi alla
frequenza di clock di 165MHz che è stata scelta in quanto multiplo intero
dei 3 ritmi di simbolo di cui si richiede l’implementazione, in questo modo
gli interpolatori6 sono più semplici da realizzare rispetto al caso frazionario.
I valori dell’interpolazione sono riportati in Tabella(2.1) e vengono realiData Rate Ingresso (Mbps)
55
82, 5
110
Symbol Rate (MSpS)
27, 5
41, 25
55
Interpolazione
6
4
3
Tabella 2.1: Valori interpolazione richiesti
zzati tutti mediante una architettura polifase7 sia perché l’architettura CIC8
3
Sezione(1.3.3)
ottenendo cosı̀ una cifratura della comunicazione che ne può aumentare la segretezza
5
Appendice(A.2)
6
Appendice(B.2)
7
Appendice(B.3.2)
8
Appendice(B.3.1)
4
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
29
per valori cosı̀ bassi richiede la compensazione del guadagno, che per il fatto che nel CIC la sagomatura d’impulso e l’eliminazione delle immagini9
richiedono un ulteriore filtro che invece nel polifase è intrinseco.
Il DDFS viene realizzato utilizzando come convertitore fase-ampiezza
un processore CORDIC10 il quale ottimizza l’implementazione su FPGA ed
è particolarmente adatto per modulatori in quadratura in quanto genera
simultaneamente ed in maniera implicita sia il seno che il coseno.
Considerando per semplicità il solo data rate di 55Mbps in ingresso al
modulatore, lo schema che risulta dalle precedenti considerazioni è mostrato
in Figura(2.3),
Figura 2.3: Modulatore QPSK classico per un solo data rate
essa evidenzia l’utilizzo di un blocco S/P il quale ha in ingresso un flusso
binario a 55Mbps che suddivide in due flussi a 27, 5MSpS semplicemente
distribuendo i bit pari sul ramo superiore11 del modulatore ed i bit dispari
sul ramo inferiore12 .
L’architettura polifase richiede un clock con frequenza pari al ritmo di
simbolo, nel caso in Figura(2.3) il divisore per 6 genera un clock a 27, 5MHz
a partire da un clock a 165MHz, la complessità che deriva dall’implementazione del divisore di frequenza è compensata dal fatto che gran parte
della architettura polifase opera con un clock che è 6 volte inferiore rispetto al clock di sistema, di qui una minore dissipazione ed una più semplice
progettazione del filtro ospitato dall’architettura stessa.
Lo schema del modulatore classico che consente di accettare 3 diversi
9
create con l’inserzione di zeri nel processo di interpolazione
Appendice(A.4.1)
11
nel seguito denominato ramo I
12
nel seguito denominato ramo Q
10
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
30
data rate in ingresso è in Figura(2.4), ad ogni data rate corrisponde un
Figura 2.4: Modulatore QPSK classico 3 data rate
clock ridotto ed un diverso interpolatore polifase, si tratta pertanto di una
soluzione abbastanza onerosa in termini di implementazione su FPGA richiede infatti 6 interpolatori, il che significa nella migliore delle ipotesi la
necessità di 6 sommatori ciascuno avente fino ad un massimo di 7 ingressi a
12 bit, la complessità è molto elevata quindi la massima frequenza ottenibile
con questa architettura è bassa.
Rispetto all’architettura in Figura(2.4) si possono introdurre diverse ottimizzazioni, come mostrato dalla Figura(2.5) nella quale si utilizzano due
soli interpolatori, uno per il ramo I e l’altro per il ramo Q, essi sono dimensionati per il massimo rate d’interpolazione, cioè 6, per esso la decomposizione polifase prevede 6 filtri FIR ognuno dei quali utilizza 7 coefficienti13 .
Nel caso che invece di interpolare 6, che è il valore di default, si voglia interpolare 4 oppure 3 occorre caricare l’insieme dei coefficienti corrispondente
ed impostare la divisione in modo da avere il giusto valore del clock ridotto,
l’iterazione ciclica deve poi coinvolgere i primi 4 oppure i primi 3 rami della
decomposizione polifase invece che tutti e 6 i rami.
2.2.2.1 Modulatore classico con fclk = 4 × fif
Lo schema in Figura(2.5) comporta una notevole riduzione della complessità
tuttavia prevede ancora l’utilizzo di un DDFS e di una coppia di moltiplicatori ciascuno con due ingressi a 12 bit, una loro implementazione su FPGA
13
valore desunto analizzando la risposta in frequenza ai tre diversi data rate
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
31
Figura 2.5: Modulatore QPSK classico 3 data rate Ottimizzato
è particolarmente onerosa, basti pensare che nella Xilinx Virtex2 essi vengono realizzati come blocchi ad alto livello implementati nella BlockRAM14
e pertanto ottimizzati per velocità e dissipazione. In realtà imponendo tra
la frequenza di clock fclk e la frequenza intermedia desiderata fif il vincolo:
fclk = 4 × fif
(2.2)
si ha che il seno ed il coseno vengono campionati in corrispondenza degli
angoli π2 , π, 3π
2 , 2π e loro multipli in corrispondenza dei quali le due funzioni
assumono uno dei 3 valori (−1, 0, 1) come illustra la Tabella(2.2).
Angolo (rad)
π
2n
πn
3π
2 n
2πn
Coseno
0
−1
0
1
Seno
1
0
−1
0
Tabella 2.2: Coseno e seno nel caso di fclk = 4 × fif
Il DDFS compie una enorme elaborazione cercando di approssimare questi valori come evidenziato dalla Figura(A.7) relativa ad una simulazione
VHDL, tuttavia gli stessi possono essere ottenuti in maniera molto più efficiente e precisa utilizzando un contatore ed una ROM i quali sono in grado
di generare una qualsiasi sequenza ripetitiva. Dati i valori assunti da seno
e coseno la moltiplicazione non è una vera moltiplicazione ma si riduce a
14
Appendice(C.3.4.2)
CAPITOLO 2. ARCHITETTURE MODULATORI QPSK
32
lasciar passare il campione proveniente dall’interpolatore SRRC, annullarlo
oppure invertirlo in complemento a due a seconda che la funzione trigonometrica valga rispettivamente 1, 0 oppure −1. Lo schema che deriva dalle
precedenti considerazioni è mostrato in Figura(2.6)
Figura 2.6: Modulatore QPSK classico 3 data rate fclk = 4 × fif
Un’ultima importante osservazione sulle sequenze seno e coseno che si
hanno sotto l’ipotesi fclk = 4 × fif è che esse alternano uno zero ad un
altro valore, quindi in sostanza effettuano un’interpolazione di valore 2 che
è in cascata a quella prodotta dall’SRRC polifase, essa può pertanto essere ridotta consentendo al polifase di operare ad una frequenza più bassa,
tale opportunità non è stata utilizzata in quanto l’ortogonalità delle due
sequenze consente un’ottimizzazione ancor più rilevante come descritto nel
Capitolo(4).
L’unico svantaggio arrecato dal vincolo fclk = 4 × fif è che fif non è
più 40MHz bensı̀ 41, 25MHz, non appare tuttavia come una grande limitazione in quanto in ogni caso l’uscita modulata, centrata sulla frequenza
intermedia, deve essere traslata a frequenze più consone alla trasmissione
satellitare.
Capitolo 3
Implementazione SRRC
polifase
3.1 Sommario
La struttura polifase ha un ruolo preponderante nell’architettura del modulatore pertanto ogni miglioramento ad essa apportato si riversa in maniera
proporzionale sulle prestazioni globali del circuito. Dopo aver descritto il
progetto del filtro SRRC da essa ospitato, si passa a definire due diverse realizzazioni, la prima deriva direttamente dalla teoria e non è adatta
ad una implementazione su FPGA, la seconda comporta una progettazione più elaborata ma l’implementazione è semplificata, vengono presentate
entrambe al fine di mettere in evidenza le scelte progettuali.
3.2 Progetto del filtro SRRC
Le considerazioni emerse nella trattazione dell’ISI1 hanno portato ad individuare la seguente famiglia di spettri a coseno rialzato:
Hrc (f ) =


 Th
T
2


1 + cos πT
α
i se
(1−α)
|f | − 2T
se
0
se
0 ≤ |f | ≤
(1+α)
2T
≤ |f | ≤
0 ≤ |f | ≥
(1+α)
2T
(1−α)
2T
(1−α)
2T
(3.1)
per essa le specifiche prevedono un fattore di roll-off α = 0, 35 scelto come
compromesso tra utilizzazione della banda e complessità della realizzazione, la risposta in frequenza viene suddivisa equamente tra trasmissione e
ricezione
p
|HT x (f )| = |HRx (f )| = Hrc (f )
(3.2)
1
Sezione(1.3.3)
33
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
34
in modo da poter utilizzare il filtro in ricezione anche come filtro adattato
e quindi demodulatore secondo quanto visto in Sezione(1.3.1).
Il progetto del filtro è stato effettuato col metodo del campionamento
della risposta in frequenza data dalle equazioni (3.1) e (3.2), di essa si prendono N 2−1 campioni e per simmetria si ricavano i restanti N 2−1 , effettuando
per ciascuno di essi la IDFT2 si ottiene un campionamento della risposta
impulsiva e quindi gli N coefficienti del filtro SRRC. L’espressione della
IDFT è:
N
−1
X
2π
hd (n) =
Hd (k) e( N )kn
(3.3)
k=0
che per la condizione di simmetria si riduce a:
N −1
2
hd (n) = Hd (0) +
X
Hd (k) cos
k=0
2π
kn
N
(3.4)
L’anticausalità viene rimossa traslando la risposta impulsiva di N 2−1 campioni.
Non necessariamente un numero di campioni maggiore si traduce in un
aumento dell’attenuazione del filtro in banda oscura, ad esempio il filtro
SRRC interpolante 6 è stato realizzato con 39 coefficienti piuttosto che con
i 42 consentiti dall’architettura in quanto per quest’ultimo valore gli estremi
della risposta impulsiva hanno un’ampiezza maggiore che si traduce in un
innalzamento della soglia del rumore. Partendo da questa considerazione e
tenendo conto del fatto che i tre valori di interpolazione vengono implementati tutti con una unica architettura, si è individuato il n◦ di coefficienti
ottimale nei tre casi, in particolare l’interpolazione 3 viene realizzata con 19
coefficienti, l’interpolazione 4 con 25 coefficienti e l’interpolazione 6 con 39
coefficienti.
La tecnica di progetto basata sul campionamento in frequenza ben si
presta ad una eventuale compensazione della risposta in frequenza del DAC3
dovuta al mantenimento di ordine zero:
sin
HDAC (f ) =
πf
fs
πf
−π
e
f
fs
(3.5)
tale compensazione si realizza moltiplicando la risposta in frequenza dell’SRRC per l’inverso della risposta in frequenza del DAC per poi procedere
al campionamento della risposta globale.
2
3
Inverse Discrete Fourier Transform
Digital Analog Converter
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
35
3.3 Implementazione polifase SRRC
La decomposizione polifase4 può essere implementata in maniera immediata
distribuendo ciclicamente i coefficienti del filtro SRRC su un banco di N filtri
FIR con N pari al valore di interpolazione desiderata. Ogni FIR utilizza 7
coefficienti pertanto per interpolare 3 i 19 coefficienti con l’aggiunta di due
coefficienti nulli vengono distribuiti sui primi 3 FIR, per interpolare 4 i 25
coefficienti più 3 nulli sono applicati ai primi 4 FIR ed infine per interpolare
6 i 39 coefficienti più due nulli vengono distribuiti su tutti i FIR.
3.3.1 Modello Matlab
Lo script Matlab CreaCoeffsFreqSamplScaled.m (Listato E.3.1) effettua
il calcolo dei coefficienti del filtro SRRC in accordo alla teoria espressa in
Sezione(3.2), in particolare la risposta in frequenza descritta dall’equazione(3.1) è implementata dalla funzione RaisedCosineResponse.m (Listato E.3.3) . La distribuzione dei coefficienti sui diversi filtri viene eseguita
tramite la funzione applica polifase.m (Listato E.3.2) , essa calcola il numero dei FIR in base al valore dell’interpolazione poi associa a ciascuno
di essi una riga in una matrice che viene riempita una colonna alla volta
sino all’esaurimento dei coefficienti. La sequenza dati di test viene applicata
ad ognuno di questi FIR tramite la funzione filter, di Matlab, ottenendo
una matrice con un numero di righe pari al numero di FIR ed un numero di colonne pari alla dimensione del vettore di test, gli elementi di questa
matrice vengono prelevati colonna per colonna modellando cosı̀ il comportamento del commutatore presente nella descrizione della architettura polifase
ottimizzata, di questo vettore viene calcolato lo spettro. CreaCoeffsFreqSamplScaled.m (Listato E.3.1) consente anche di scalare i coefficienti al
fine di utilizzare al massimo la dinamica della rappresentazione in complemento a due utilizzata5 in particolare la somma che si effettua in ogni FIR
del polifase deve valere al massimo 1, essa è nota a priori in quanto sono
noti i coefficienti ed il segnale d’ingresso appartiene all’insieme (+1, −1).
Lo stesso CreaCoeffsFreqSamplScaled.m (Listato E.3.1) consente il confronto tra il filtro progettato col campionamento in frequenza e quello che
Matlab progetta automaticamente con la funzione rcosine, tale confronto
mostra come le prestazioni del campionamento in frequenza siano nettamente superiori. La risposta in frequenza ed all’impulso degli SRRC per i
tre data rate richiesti in specifica è rappresentata nelle Figure (3.1), (3.2)
e (3.3) che evidenziano una differenza di circa 40dB tra banda passante e
banda oscura.
4
5
Appendice(B.3.2)
12 bit di cui 1 per il segno ed i restanti per la parte dopo la virgola
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
(a) Risposta in frequenza
(b) Risposta all’impulso
Figura 3.1: SRRC 19 coefficienti interpolante 3
(a) Risposta in frequenza
(b) Risposta all’impulso
Figura 3.2: SRRC 25 coefficienti interpolante 4
(a) Risposta in frequenza
(b) Risposta all’impulso
Figura 3.3: SRRC 39 coefficienti interpolante 6
36
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
37
3.4 Modello VHDL
Le differenze sostanziali tra le due implementazioni VHDL del polifase risiedono nella strategia di creazione e distribuzione dei clock ridotti, generati
a partire dal clock di sistema a 165MHz, e nella dislocazione della logica
combinatoria.
3.4.1 Polifase standard gated-clock
Questa realizzazione è costituita principalmente da due blocchi:
SRRCxN: incorpora i FIR ed un multiplexer che seleziona ciclicamente,
ad ogni colpo di clock, l’uscita di uno di essi.
RateAdapter: in funzione del data rate selezionato applica ad SRRCxN
il giusto set di coefficienti, il clock ridotto ed una conta ciclica da 0 a
N-1 essendo N il valore dell’interpolazione.
3.4.1.1 SRRCxN
Nello schema a blocchi in Figura(3.4), associato al file srrc x n.vhd
Figura 3.4: SRRC interpolante 3, 4, 6
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
38
(Listato F.2.10) , si ha che il multiplexer descritto in mux 6.vhd (Listato F.2.15) opera alla frequenza di clock mentre ciascuno dei 6 FIR descritto da fir 1.vhd (Listato F.2.11) e rappresentato in Figura(3.5) utilizza la
Figura 3.5: FIR iesimo
stessa temporizzazione dei dati in ingresso.
I moltiplicatori sono in genere la parte più delicata nelle implementazioni di algoritmi DSP6 su FPGA, laddove possibile è bene non utilizzarli o
semplificarli al massimo, nel modulatore QPSK il segnale d’ingresso ai FIR
può assumere soltanto i valori7 +1 e −1 pertanto ogni moltiplicatore può essere sostituito con una descrizione VHDL che ad ogni colpo del clock ridotto
presenta in uscita il valore del coefficiente o il suo negato. La negazione di un
numero rappresentato in complemento a due si realizza invertendone tutti
i bit e sommando 1, necessita pertanto di un sommatore che è un altro dei
circuiti critici dei DSP, per evitarlo dato il numero esiguo di coefficienti si è
scelto di fornire alla descrizione VHDL fir multiplier.vhd (Listato F.2.13)
che di fatto sostituisce il moltiplicatore, sia il coefficiente che il suo negato.
La somma delle uscite dei moltiplicatori viene effettuata in adder 7.vhd
(Listato F.2.12) , un sommatore la cui complessità limita le prestazioni del
modulatore sia perché è costituito da 7 ingressi a 12bit sia perché lo schema
del modulatore in Figura(2.6) ne richiede 12.
Gli elementi di ritardo tipici dei FIR sono realizzati con un registro a
6
Digital Signal Processing
due valori si rappresentano con 1 solo bit anche se in complemento a due a +1
corrisponde 01 e a −1 corrisponde 11
7
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
39
scorrimento SIPO8 il cui VHDL è in shift reg.vhd (Listato F.2.14) , tale
soluzione è migliore rispetto al mettere in cascata 7 descrizioni FFD9 in
quanto segnala chiaramente al sintetizzatore VHDL che essi debbono esser
posti quanto più vicini possibile tra di loro.
3.4.1.2 Rate Adapter
Nello schema a blocchi in Figura(3.6), associato al file rate adapter.vhd
Figura 3.6: Rate Adapter
(Listato F.2.3) , si ha che selector.vhd (Listato F.2.9) a seconda del data rate
impostato tramite rate sel seleziona uno tra i contatori/divisori descritti
da counter divider 3.vhd (Listato F.2.5) , counter divider 4.vhd
(Listato F.2.6) e counter divider 6.vhd (Listato F.2.8) , tra essi il più
critico è senza dubbio il contatore/divisore per 3 in quanto utilizza entrambe
i fronti del clock e pertanto è come se operasse ad una velocità di clock
doppia rispetto agli altri due.
La selezione di quale banco di coefficienti utilizzare viene effettuata in
coeffs selector.vhd (Listato F.2.4) basandosi sul valore di rate sel, si tratta di una descrizione non efficiente in quanto il sintetizzatore la implementa
8
9
Serial In Parallel Out
Flip Flop D
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
40
con un multiplexer le cui dimensioni divengono molto grandi al crescere del
numero di coefficienti.
Trattandosi di una architettura gated-clock , si ha che i clock ridotti
vengono generati con elaborazioni combinatorie sul clock di sistema, ciò è da
evitare in quanto un semplice rumore, termico o ambientale, può dar luogo a
problemi di corsa critica, per questo motivo viene preferita la tecnica clockenable nella quale tutti i blocchi che richiedono il clock ridotto operano in
realtà col clock di sistema ma dispongono di un segnale di abilitazione clockenable pilotato tramite della logica combinatoria anch’essa temporizzata dal
clock di sistema, in tal modo non è nemmeno più necessario che i clock
ridotti abbiano un duty-cycle del 50%.
3.4.1.3 Risultati sperimentali
Il VHDL di questo progetto è stato ampliamente testato ed ha rappresentato un punto di partenza verso una conoscenza più approfondita delle
tematiche della sintesi tuttavia non è stata effettuata alcuna implementazione su FPGA in quanto l’eccessiva sensibilità del gated-clock lo rende
inadatto ad applicazioni spaziali dove i circuiti sono soggetti a radiazioni,
stress meccanici e termici.
3.4.2 ROM Polifase clock-enable
La Figura(3.5) è il punto di partenza per una semplificazione sostanziale
del polifase e quindi del modulatore, essa evidenzia come ognuno degli addendi che giungono al sommatore può assumere solo due valori, quello del
coefficiente o il suo negato, pertanto il numero di combinazioni possibili al
suo ingresso è 27 = 128, un numero finito e tutto sommato limitato, di qui
l’idea di inserire in una ROM i risultati delle somme corrispondenti a queste
128 combinazioni, eliminando in tal modo il grosso sommatore che limita la
massima frequenza di clock applicabile al modulatore.
Ogni FIR viene pertanto realizzato con una ROM ed un registro a scorrimento nel quale fluiscono i simboli da trasmettere, le uscite in parallelo
del registro individuano una locazione di memoria nella quale è memorizzato su 12 bit il risultato della somma. Un polifase che interpoli N si realizza
con una unica ROM avente nelle prime 128 locazioni le somme per il primo FIR, nelle successive 128 le somme per il secondo FIR e cosı̀ via sino
alle somme per il FIR Nesimo . Il multiplexer che ha il compito di iterare
ciclicamente sulle uscite dei FIR si ottiene aggiungendo dei bit alla ROM e
facendoli pilotare direttamente dal contatore/divisore che quindi in ogni periodo di clock va a selezionare un diverso banco di 128 locazioni di memoria
corrispondente ad uno degli N FIR.
Sulla base delle precedenti considerazioni il polifase che consente di
implementare i 3 data rate richiesti dalle specifiche diviene quello in Fi-
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
41
gura(3.7), cui corrisponde il file srrc x n.vhd (Listato F.3.3) , in esso
Figura 3.7: SRRCxN versione ROM
il segnale rate sel imposta il data rate e conseguentemente il multiplexer descritto in mux 3x12 (Listato F.3.5) insieme al demultiplexer demux 3x10.vhd (Listato F.3.4) seleziona la ROM da utilizzare tra quelle
descritte in ROMx3.vhd (Listato F.3.6) , ROMx4.vhd (Listato F.3.7) e
ROMx6.vhd (Listato F.3.8) .
I valori da inserire nelle ROM sono determinati da CreaROM.m (Listato E.3.4) a partire dal file contenente i coefficienti scalati, esso calcola tutte
le possibili somme per ogni FIR, le pone in cascata, implementando cosı̀ un
intero polifase, e produce delle descrizioni della ROM in uno dei 3 formati:
COSTANTE: è il formato utilizzato per piccole ROM, viene sintetizzato infatti come un multiplexer le cui dimensioni possono divenire
rilevanti.
CASE: è adatto a ROM di medie dimensioni in quanto il costrutto VHDL
CASE viene riconosciuto dal sintetizzatore XST che lo implementa
sulla RAM distribuita in ogni CLB10 .
BlockRAM: viene utilizzato per ROM di dimensioni molto grandi implementate tramite la BlockRAM11 presente nella FPGA Virtex, è una
soluzione che consente velocità di clock inferiori rispetto alla ROM
distribuita nelle CLB, tuttavia è decisamente più agevole il Floorplanning12 . Il file di testo prodotto può essere applicato al Core Generator
per ottenere la BlockRAM inizializzata.
10
Configurable Logic Block
Appendice(C.3.4.2)
12
Appendice(D.6)
11
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
42
La produzione e distribuzione dei clock ridotti a partire dal clock di
sistema a 165MHz per i motivi precedentemente espressi non avviene più
secondo la tecnica gated-clock ma secondo la clock-enable. I 3 contatori/divisori utilizzati nel precedente progetto vengono soppiantati dal contatore/divisore programmabile descritto in counter.vhd (Listato F.3.2) , esso
produce sia la conta ciclica sino ad N − 1 che la produzione di un impulso
di abilitazione ogni N colpi di clock destinato alle descrizioni che debbono
operare a velocità ridotta. Apparentemente, per quello che riguarda i vincoli sulle temporizzazioni, il clock-enable introduce un abbassamento della
massima frequenza di clock in quanto circuiti ai quali prima si applicava
il vincolo del clock ridotto ora si vedono applicato il vincolo del clock di
sistema che è più stringente, tuttavia per essi si può settare una specifica
denominata multi-cycle che comunica al sintetizzatore di rilassare le loro
temporizzazioni di un fattore N.
3.4.2.1 Risultati sperimentali
Per la versione ROM clock-enable del polifase sono state effettuate le due
seguenti verifiche sperimentali:
VHDL: si è applicata alla descrizione VHDL del polifase la medesima sequenza applicata al polifase Matlab, gli spettri risultanti sono praticamente coincidenti come illustra la Figura(3.8) riferita ad un clock di
Figura 3.8: Confronto Polifase VHDL – Polifase Matlab
CAPITOLO 3. IMPLEMENTAZIONE SRRC POLIFASE
43
sistema di 40MHz generata tramite PolyphasePSDVHDLvsPSDMatlab.m (Listato E.3.5) .
FPGA: l’implementazione su FPGA è stata abbastanza elaborata per via
della necessità di adattare il ritmo dei dati provenienti dal patterngenerator con il ritmo del segnale di abilitazione generato a partire dal
clock di sistema, la soluzione trovata viene descritta in Sezione(4.3.2),
qui ci si limita a riportare i risultati ottenuti tramite PolyphasePSDFPGAvsPSDMatlab.m (Listato E.3.7) in termini di confronto
spettrale col modello Matlab, essi sono graficati in Figura(3.9) che
Figura 3.9: Confronto Polifase FPGA – Polifase Matlab
ricalca quella ottenuta per il modello VHDL.
Capitolo 4
Implementazione Modulatore
QPSK
4.1 Sommario
I principali risultati di questa Tesi sono racchiusi in questo capitolo dove
vengono illustrati due diverse realizzazioni, una ricalca lo schema classico
del modulatore QPSK mentre l’altra è una diretta estensione del progetto
ROM Polifase clock-enable 1 .
Il modello Matlab dell’intero canale di comunicazione comprendente trasmettitore, canale e ricevitore, ha consentito sia una valutazione qualitativa
dei risultati tramite gli spettri che una misura quantitativa tramite la BER
agevolando inoltre lo sviluppo di entrambe i modelli VHDL.
4.2 Modello Matlab
La descrizione del modello è sia in QPSKModemPSDeBERVHDLvsMatlab.m (Listato E.4.4) che in QPSKModemPSDFPGAvsPSDMatlab.m (Listato E.4.6) , la sua definizione si basa, per quel che riguarda il
trasmettitore, sullo schema del modulatore classico con fclk = 4 × fif di Figura(2.6) mentre per il ricevitore si è utilizzata la teoria della demodulazione
con filtro adattato2 ed il criterio di decisione ML descritto in Sezione(1.3.2),
essa è di riferimento anche per la caratterizzazione del rumore introdotto
dal canale. Segue una breve descrizione del modello:
Trasmettitore: dal rapporto tra la frequenza di clock ed il ritmo di simbolo viene dedotto il file di coefficienti da utilizzare, essi sono calcolati da CreaCoeffsFreqSamplScaled.m (Listato E.3.1) e memorizzati
in SRRCx3 FreqSampl scaled.dat, SRRCx4 FreqSampl scaled.dat e
1
2
Sezione(3.4.2)
Sezione(1.3.1)
44
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
45
SRRCx6 FreqSampl scaled.dat. La sequenza randomica dei bit da
trasmettere viene caricata da bit tx.dat ed è anche utilizzata per caratterizzare il modello VHDL e l’implementazione su FPGA al fine di
poter effettuare confronti in termini di BER. Dalla sequenza bit tx
se ne ottengono due, quella contenente i bit dispari viene applicata al
ramo I del modulatore mentre l’altra, contenente i bit pari, viene applicata al ramo Q per poi essere applicate entrambe ai due filtri SRRC
polifase, implementati tramite applica polifase.m (Listato E.3.2) .
Le uscite degli interpolatori sono moltiplicate rispettivamente con i
campioni del coseno e del seno rispondenti al vincolo fclk = 4 × fif , i
campioni risultanti vengono poi sommati.
Canale: viene sommato del rumore gaussiano al segnale in uscita dal modulatore, nel caso di un rumore quantificato con Eb/No = 6dB l’effetto
è rappresentato in Figura(4.1).
(a) Uscita Tx QPSK
(b) Ingresso Rx QPSK
Figura 4.1: Effetto del canale sul segnale modulato QPSK
Ricevitore: il segnale QPSK affetto da rumore viene applicato ad un
ADC3 e successivamente moltiplicato per i campioni delle due portanti in quadratura, il successivo filtro adattato utilizza i medesimi
coefficienti dell’SRRC in trasmissione ma mantiene inalterato il ritmo dei campioni, i simboli che si ottengono alla sua uscita vengono
applicati al decisore implementato tramite la funzione demodmap di
Matlab. La sequenza di bit ricevuta viene confrontata con quella trasmessa, non essendo stati utilizzati dei bit di segnalazione tale operazione si effettua traslando la sequenza ricevuta di un numero di bit
N bit sfasamento Matlab rispetto a quella trasmessa, il valore viene determinato in maniera empirica effettuando diverse traslazioni e
scegliendo quella cui corrisponde il minimo numero di bit errati.
3
Analog Digital Converter
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
46
Lo script CreaTabellaBER.m (Listato E.4.1) consente una valutazione
globale delle prestazioni del modulatore, esso infatti confronta sia in forma tabellare che grafica la probabilità d’errore teorica con la BER ricavata
sperimentalmente, a tal fine si avvale della funzione calcolaBER.m (Listato E.4.2) che valuta la BER in corrispondenza di un dato valore di Eb/No.
Il numero di bit applicati al modulatore è funzione di Eb/No infatti se ad
esempio per un dato valore di Eb/No la probabilità d’errore è dell’ordine di
10−4 allora il numero di bit da trasmettere è 10×104 . La Tabella(4.1) è riferita al data rate 110Mbps e alla frequenza di clock 165MHz cui corrisponde
Eb/No (dB)
0
1
2
3
4
5
6
7
8
9
Probabilità d’errore teorica
0.07864960
0.05628195
0.03750612
0.02287840
0.01250081
0.00595386
0.00238829
0.00077267
0.00019090
0.00003362
BER Modem QPSK Matlab
0.07849516
0.05538872
0.03828828
0.02435769
0.01584918
0.00667334
0.00309671
0.00084889
0.00020659
0.00003194
Tabella 4.1: Tabella prestazioni modem Matlab in termini di BER
la curva del BER rappresentata in Figura(4.2).
Figura 4.2: Grafico prestazioni modem Matlab in termini di BER
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
47
4.3 Modelli VHDL
Dopo aver introdotto la realizzazione VHDL dello schema di principio presentato in Figura(2.6) si passa alla descrizione del progetto ThinModulator
che incorpora tutte le ottimizzazioni dedotte nel capitolo precedente e ne
introduce altre consentite dall’ortogonalità dei due rami del modulatore
QPSK.
4.3.1 Modulatore classico
Lo schema in Figura(4.3) corrisponde a Modulator BlockRAM.vhd
Figura 4.3: Modulatore classico
(Listato F.4.1) , si assume che il modulatore riceva in ingresso sia la sequenza
dei bit pari che quella dei bit dispari, esse vengono applicate al filtro SRRC
polifase in Figura(4.4) che si differenzia da quello di Figura(3.7) unicamente
per il modo in cui vengono memorizzati i risultati delle somme, non più in
3 ROM distribuite nelle CLB bensı̀ in un’unica RAM4 abilitata soltanto in
lettura ed implementata nella BlockRAM5 tramite un Core Xilinx.
Trattandosi di un modulatore QPSK per applicazioni spaziali sono importanti sia le dimensioni che la massima frequenza di clock implementabile,
nel progetto della RAM si è scelto di ottimizzare quest’ultimo aspetto inserendo le somme per ogni interpolatore SRRC in 1024 locazioni di memoria
4
5
inizializzata con il file generato da CreaROM.m (Listato E.3.4)
Appendice(C.3.4.2)
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
48
Figura 4.4: SRRCxN versione RAM
indipendentemente dal fatto che siano tutte necessarie oppure no, in tal
modo si può selezionare un SRRC oppure un altro applicando il segnale rate sel ad ulteriori 2 bit di indirizzo della RAM la quale quindi non richiede
alcuna logica combinatoria a monte della sua rete di indirizzamento intrinseca. La descrizione VHDL del polifase è in srrc x n.vhd (Listato F.4.6)
mentre il file per la simulazione della RAM è ram.vhd (Listato F.4.7) tuttavia si può evitare l’utilizzo del Core Xilinx istanziando 12 BlockRAM nel
formato 1 × 4096bit come in Figura(4.5).
Figura 4.5: RAM 12 × 4096
Le due portanti in quadratura sono generate da NCO basic.vhd (Listato F.4.5) a partire dal clock di sistema mediante un contatore modulo 4
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
49
alla cui conta ciclica vengono associati i valori di coseno e seno riportati in
Tabella(4.2), i campioni delle portanti cosı̀ generate vengono moltiplicati per
Valore contatore
0
1
2
3
Coseno
1
0
−1
0
Seno
0
−1
0
1
Tabella 4.2: Generazione funzioni trigonometriche col contatore
i campioni provenienti dagli SRRC, in particolare in multiplier I Q.vhd
(Listato F.4.4) essi vengono lasciati passare, annullati oppure invertiti a se-
conda del valore della corrispondente portante per poi essere sommati in
adder I Q.vhd (Listato F.4.2) la cui complessità può essere evitata, sostituendo il sommatore con un più semplice commutatore operante alla
frequenza di clock, i due ingressi sono infatti alternativamente nulli. Tale
ottimizzazione, cosı̀ come le prove sperimentali e la successiva implementazione su FPGA, è stata inserita nella rielaborazione del progetto denominata
ThinModulator la quale include anche l’interfacciamento tra il modulatore
e la sorgente dei dati.
4.3.2 ThinModulator
Il nome ThinModulator6 evidenzia come in questo progetto siano state inserite tutte le ottimizzazioni rese possibili dalla modulazione QPSK, esse
sono evidenziate dal diagramma temporale in Figura(4.6), relativo alla rea-
Figura 4.6: Temporizzazioni modulatore classico
6
modulatore snello in inglese
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
50
lizzazione VHDL del modulatore classico di Figura(4.3), in particolare si
evincono due considerazioni:
1. l’uscita QPSK out del modulatore si ottiene prelevando alternativamente l’uscita QPSK I del moltiplicatore sul ramo I oppure l’uscita
QPSK Q del moltiplicatore sul ramo Q.
2. le sequenze seno e coseno sono sfasate tra loro di 90◦ , immaginando di
sommarle algebricamente si ottiene una sequenza che per due periodi
di clock vale +1 e per i successivi due periodi vale −1.
su di esse si basa il ThinModulator mostrato in Figura(4.7),
Figura 4.7: ThinModulator
i due interpolatori SRRC vengono realizzati con una unica RAM in
quanto il contenuto per il ramo I è uguale a quello del ramo Q inoltre, come evidenziato in Figura(4.6), un campione ogni due dell’uscita del polifase
viene annullato nel successivo moltiplicatore, pertanto è sensato intercalare
i campioni, cosa che del resto nello schema in Figura(4.3) veniva effettuata dal sommatore d’uscita. Il commutatore mux 2x7.vhd (Listato F.5.10)
provvede ad inviare alternativamente all’unica RAM un indirizzo oppure
l’altro, vengono poi aggiunti 2 bit per la selezione del FIR7 ed altri 2 bit per
la selezione del data rate. Nell’architettura ThinModulator le moltiplicazioni e la somma finale vengono tutte effettuate in mult C2 adder.vhd
(Listato F.5.9) che opera in maniera ciclica lasciando passare inalterati 2
campioni provenienti dalla RAM ed invertendo i successivi due.
Il ThinModulator necessita per il suo funzionamento del contatore programmabile counter.vhd (Listato F.3.2) descritto nella Sezione(3.4.2), esso genera il segnale di abilitazione per la tecnica clock-enable e la conta ciclica che va a selezionare l’Nesimo banco di 128 locazioni nella RAM
corrispondente all’Nesimo FIR del polifase SRRC.
7
e quindi del banco di 128 locazioni di memoria
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
51
Il modulatore QPSK effettivamente implementato sulla FPGA è quello
il cui schema a blocchi è rappresentato in Figura(4.8), esso include anche
Figura 4.8: FIFO RAM ThinModulator
una interfaccia verso il mondo esterno resasi necessaria in quanto il clock
associato ai dati provenienti dal pattern-generator ha la stessa frequenza del
segnale clock-enable ma la relazione di fase tra i due è aleatoria e pertanto
si possono verificare situazioni non previste in fase di progetto.
Le possibili soluzioni al problema sono due:
1. utilizzare il clock dei dati per produrre il clock di sistema, da esso
poi si ricava il segnale clock-enable, la soluzione è impraticabile in
quanto le specifiche implicano la moltiplicazione del clock per fattori
3, 4 e 6 mentre la FPGA Virtex consente soltanto la moltiplicazione
per 2 utilizzando una ClkDLL89 come in Figura(4.9). oppure per 4
mettendone due in cascata.
2. una FIFO10 consente di mettere in fase le due temporizzazioni, essa è
costituita da un registro a scorrimento nel quale i dati vengono scritti
utilizzando la temporizzazione che giunge dal pattern-generator e letti
utilizzando quella prodotta localmente dal contatore programmabile
counter.vhd (Listato F.3.2) .
L’unica soluzione che soddisfa le specifiche del modulatore è la 2) tuttavia essa richiede che le due temporizzazioni abbiano la stessa frequenza
altrimenti dopo poco tempo la FIFO o si svuota o si riempie completamente
determinando cosı̀ perdita di informazione, per soddisfare questo vincolo si
8
Appendice(C.3.4.1)
la frequenza minima in ingresso alla ClkDLL è 25MHz
10
First In First Out
9
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
52
Figura 4.9: Clock×2
è scelto di inviare al pattern-generator, quale sincronismo per l’emissione dei
dati, il segnale di clock-enable che si ottiene a partire dal clock di sistema11 .
Lo schema dell’interfaccia tra il modulatore e la sorgente dati è in Figura(4.10) cui corrisponde Data Source Interface.vhd (Listato F.5.3) , la
Figura 4.10: Interfaccia modulatore – sorgente dati
FIFO è stata implementata con un Core Xilinx per la cui simulazione si utilizza asynch fifo 2x15.vhd (Listato F.5.4) , il clock in scrittura è quello
proveniente dal pattern-generator mentre quello in lettura è il clock di sistema tuttavia l’abilitazione alla lettura è determinata dal segnale clock-enable
proveniente dal counter.vhd (Listato F.3.2) . La logica che gravita intorno
11
40MHz per la scheda DINI sulla quale è stato implementato il modulatore
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
53
alla FIFO ha il compito di consentire la prima lettura soltanto dopo che
essa sia stata parzialmente riempita, si deve cioè attendere che il segnale
almost-empty passi per la prima volta al livello logico basso.
4.3.2.1 Risultati sperimentali
4.3.2.1.1 Test VHDL La medesima sequenza dati applicata al modello
Matlab è stata applicata alla descrizione VHDL, l’uscita è poi nuovamente esportata in Matlab dove, dopo una conversione dalla rappresentazione
in complemento a due al formato reale, ne viene prodotto e visualizzato
lo spettro confrontandolo con quello ottenuto con il modello Matlab del
modem, i due sostanzialmente coincidono come mostrato in Figura(4.11)
riferita ad un modulatore interpolante 3 e che, per garantire conformità con
Figura 4.11: Confronto Modulatore x3 VHDL – Matlab
i risultati dell’implementazione su FPGA12 , opera ad una frequenza di clock
di 40MHz. Per una verifica più puntuale lo stesso script QPSKModemPSDeBERVHDLvsMatlab.m (Listato E.4.4) realizza anche una misura di
BER, a tal fine viene aggiunto del rumore gaussiano dovuto al canale ed
il segnale risultante è poi applicato al demodulatore che richiede di esser
tarato con la procedura inserita quale commento nello script, la corretta taratura del demodulatore consente di ottenere misure di BER praticamente
identiche ai risultati teorici.
12
la scheda DINI ospita un quarzo a 40MHz eventualmente modificabile
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
54
4.3.2.1.2 Test FPGA La sequenza da trasmettere è stata caricata nel
Pattern Generator tramite il file di testo prodotto da CreaSequenzaPatternGenerator.m (Listato E.2.2) del quale si propone il seguente stralcio:
ASCII
000000
ASCDOWN
FORMAT:MODE FULL
FORMAT:CLOCK EXTERNAL, LEFifty
LABEL dummy, 24
LABEL data_in_SRRCxN_tx_Q, 4
LABEL rate_sel_x3, 4
LABEL reset, 4
LABEL data_in_SRRCxN_tx_I, 4
VECTOR
000000 0 0 1 0
000000 0 0 1 0
000000 0 0 1 0
000000 0 0 1 0
000000 0 0 1 0
000000 0 0 0 0
000000 0 0 0 0
000000 0 0 0 0
000000 0 0 0 0
000000 0 0 0 0
*M
000000 0 0 0 0
000000 1 0 0 0
000000 1 0 0 0
000000 0 0 0 1
000000 0 0 0 0
000000 0 0 0 1
000000 1 0 0 1
000000 1 0 0 1
000000 0 0 0 0
...... . . . .
000000 0 0 0 1
essa segnala al pattern-generator di predisporsi per ricevere dall’esterno
il sincronismo per il clock associato ai dati emessi i quali sono allocati
sui canali data in SRRCxN tx I e data in SRRCxN tx Q mentre rate sel x3 imposta il data rate e reset consente l’inizializzazione della FPGA. Il segnale reset è al livello 1 soltanto nella sequenza che precede *M
in quanto questa viene emessa una sola volta mentre la sequenza successiva
viene ripetuta ciclicamente un numero infinito di volte.
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
55
Le connessioni tra pattern-generator, scheda DINI ed analizzatore di stati
logici sono descritte nel seguente testo estratto dal file .ucf il quale viene
utilizzato per immettere i vincoli fisici e temporali nella sintesi del progetto
sulla FPGA Xilinx Virtex1000BG560-4:
################################################
NET "clk" LOC = "D17"; #clock a 40MHz interno
################################################
#
POD CLK PATTERN GENERATOR
#
################################################
NET "data_in_clk" LOC = "A17"; #JP11 pin 12
NET "data_in_clk_sync" LOC = "C28"; #JP1 pin 20
################################################
#
POD 1 PATTERN GENERATOR
#
################################################
NET "reset" LOC = "AE31"; #JP12 pin 10
NET "data_in_I" LOC = "AD29"; #JP12 pin 8
NET "data_in_q" LOC = "V29"; #JP12 pin 3
################################################
#
POD 2 PATTERN GENERATOR
#
################################################
NET "rate_sel<0>" LOC = "V31"; #JP12 pin 4
NET "rate_sel<1>" LOC = "Y29"; #JP12 pin 6
#
################################################
#
POD 2 ANALIZZATORE STATI
#
################################################
NET "modulator_out<0>" LOC = "C29"; #JP6 pin 1
NET "modulator_out<1>" LOC = "A31"; #JP6 pin 3
NET "modulator_out<2>" LOC = "B30"; #JP6 pin 5
NET "modulator_out<3>" LOC = "C30"; #JP6 pin 7
NET "modulator_out<4>" LOC = "D28"; #JP6 pin 9
NET "modulator_out<5>" LOC = "F29"; #JP6 pin 13
NET "modulator_out<6>" LOC = "H31"; #JP6 pin 15
NET "modulator_out<7>" LOC = "P30"; #JP6 pin 19
NET "modulator_out<8>" LOC = "A28"; #JP6 pin 4
NET "modulator_out<9>" LOC = "C27"; #JP6 pin 8
NET "modulator_out<10>" LOC = "D32"; #JP6 pin 10
NET "modulator_out<11>" LOC = "E30"; #JP6 pin 12
NET "data_out_clk" LOC = "B29"; #JP1 pin 19
################################################
#
AZIONAMENTO MANUALE
#
################################################
NET "count_clk_en_reset" LOC = "AK24"; #JP12 pin 15
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
56
Al fine di agevolare il raggiungimento dei vincoli temporali con stati scelti i
pin della FPGA più vicini alle 12 BlockRAM utilizzate nel progetto, esse si
trovano infatti distribuite in due colonne laterali.
L’analizzatore di stati logici consente di prelevare dall’uscita del modulatore un pacchetto di 64000 campioni adiacenti, applicandoli allo script
Matlab QPSKModemPSDFPGAvsPSDMatlab.m (Listato E.4.6) sono
stati ottenuti gli spettri mostrati nelle figure (4.12), (4.13) e (4.14), essi evidenziano una forte similitudine tra il risultato teorico ed il risultato
sperimentale.
Figura 4.12: Confronto Modulatore x3 FPGA – Matlab
CAPITOLO 4. IMPLEMENTAZIONE MODULATORE QPSK
Figura 4.13: Confronto Modulatore x4 FPGA – Matlab
Figura 4.14: Confronto Modulatore x6 FPGA – Matlab
57
Capitolo 5
Conclusioni
E’ stato progettato ed implementato su FPGA un modulatore QPSK con
ottime prestazioni sia in termini di purezza spettrale che di BER, la semplicità dell’architettura individuata la rende fortemente suscettibile ai continui
progressi apportati alle moderne FPGA dalle principali fonderie.
Possibili evoluzioni di questo lavoro di Tesi possono riguardare i seguenti
aspetti:
• determinazione del numero di bit effettivamente necessari in uscita
dal modulatore, una riduzione in tal senso si rifletterebbe proporzionalmente sulle dimensioni della ROM.
• il modulatore è pensato per applicazioni spaziali, un ambiente particolarmente ostile per i circuiti a larga scala di integrazione richiede
pertanto l’implementazione di una tecnica di riconfigurazione ciclica volta a ridurre gli effetti delle radiazioni sul funzionamento del
circuito.
• realizzazione di una scheda che applichi l’uscita del modulatore ad un
convertitore digitale/analogico il quale dovrà essere precompensato
tramite i coefficienti del filtro ospitato dalla struttura polifase.
L’architettura proposta è stata sviluppata su FPGA tuttavia essa si
compone di una ROM, dei registri a scorrimento e poca altra logica combinatoria, si può pertanto ipotizzare una realizzazione non su logiche programmabili quali FPGA o ASIC bensı̀ su componenti VLSI commerciali.
58
Appendice A
Sintesi diretta di frequenza
digitale
A.1 Sommario
La generazione di portanti sinusoidali, una delle funzioni chiave dell’elettronica applicata alle telecomunicazioni, è stata realizzata con tecniche analogiche sino agli anni ’70 quando l’avvento dei circuiti a larga scala d’integrazione ha aperto la strada a realizzazioni digitali con prestazioni decisamente
superiori, esse permettono infatti di variare la frequenza in istantaneamente
e con continuità di fase raggiungendo risoluzioni dell’ordine del µHz, il tutto
con costi e dimensioni contenuti.
L’unico aspetto nel quale le tecniche analogiche sono superiori è l’estensione spettrale che raggiunge diversi GHz pertanto la norma di progetto
è di utilizzare tecniche digitali laddove possibile ed integrarle con tecniche
analogiche negli altri casi.
A.2 DDFS
La sintesi diretta di frequenza digitale si basa sullo schema in Figura(A.1)
che viene indifferentemente denominato DDS1 , NCO2 oppure DDFS, esso
genera una funzione a frequenza arbitraria e non lineare, quale il seno o il
coseno3 , nei tre seguenti passi:
1. genera una sequenza di valori dell’argomento variabile in funzione
della frequenza che si desidera ottenere.
2. associa alla sequenza generata le corrispondenti ampiezze del seno o
del coseno.
1
Direct Digital Synthesizer
Numerical Control Oscillator
3
caratterizzate tuttavia da un argomento ϕ lineare nel tempo
2
59
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
60
Accumulatore di fase
A-1
Registro
Incremento A-1
fase (T)
A
Registro
di fase
A
P
Convertitore
Fase-Ampiezza
B
Convertitore
Digitale/Analogico
Filtro
A
Figura A.1: Schema di principio DDFS
3. converte in analogico l’ampiezza espressa in digitale.
Con riferimento alla Figura(A.1) la sequenza dei valori dell’argomento, ciascuno rappresentato con A bit, viene generata mediante l’accumulatore di
fase, esso si compone di un registro di fase e di un sommatore che aggiunge
al valore precedentemente contenuto nel registro il valore T di una parola di sintonia contenuta in un registro ad A−1 bit4 . Variando il valore T
contenuto nel registro di incremento il progettista o l’operatore ha modo di
variare la frequenza generata dal DDFS:
fout =
T × fclk
2A
(A.1)
per variare la risoluzione in frequenza occorre invece cambiare il numero
di bit A del registro di fase, si tratta di un valore da decidere in sede di
progetto tenendo conto della applicazione cui è destinato il DDFS, valori
elevati di A infatti aumentano la risoluzione, pari a f2clk
A , ma comportano una
maggiore complessità circuitale e conseguentemente una minor frequenza di
clock applicabile al sistema il ché per il teorema di Nyquist5 si traduce in
una riduzione della massima frequenza generabile.
Dopo aver generato la rampa di fase il convertitore fase/ampiezza la
trasforma nella funzione sinusoidale prescelta, esso ha in ingresso P bits con
P A in quanto l’utilizzo di tutti i bit che provengono dall’accumulatore di
fase determina una complessità non gestibile indipendentemente dal modo
in cui il convertitore è realizzato. Il troncamento della fase determina in
uscita dal DDFS la presenza di spurie la cui distribuzione ed ampiezza
può tuttavia essere controllata mediante una opportuna pianificazione delle
frequenze.
4
5
per ottemperare al criterio di Nyquist
Appendice(B.2)
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
61
La sequenza discreta ottenuta dal convertitore fase-ampiezza viene applicata ad un DAC il cui numero di bit B in ingresso determina il massimo
livello delle spurie da esso prodotte, l’ordine zero del campionamento da poi
luogo ad una sagomatura sin(x)
dello spettro che richiede una precompensax
zione. Il filtro anti-aliasing ha il compito di lasciare passare in uscita il solo
Figura A.2: Spettro in uscita dal DAC
spettro compreso nella banda 0 < fout <
fclk
2
detta di Nyquist.
A.3 Pianificazione delle frequenze
A.3.1 Spurie dovute al DAC
Come evidenziato in Figura(A.2) la non-linearità del DAC genera alla sua
uscita oltre alla frequenza fondamentale fout anche delle immagini aventi frequenza fclk ± fout , scegliendo fout > fN yquist abbiamo che la prima
immagine cade nella banda di Nyquist e quindi non può essere filtrata pertanto, tenendo conto anche della banda di transizione non nulla del filtro
anti-aliasing, si ha che la massima frequenza generabile è dell’ordine di
0, 4fout .
La distribuzione delle spurie dovute al DAC è imposta dalla relazione
tra fclk e fout mentre la loro ampiezza è determinata dal numero di bit B
S
in particolare abbiamo che il rapporto N
espresso in dB tra il segnale ed il
rumore di quantizzazione [10] vale:
S
N (dB)
= 6.02 × B + 1.76 + 20 log10 (F F S)
(A.2)
dove con FFS si indica la percentuale del fondoscala a cui lavora il DAC.
La potenza del rumore di quantizzazione è costante per un dato valore
di B pertanto se si riduce la banda utile ossia si lavora in una frazione della
S
banda di Nyquist si ottiene un miglioramento del rapporto N
.
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
62
A.3.2 Spurie dovute al troncamento della fase
La risoluzione in frequenza aumenta al crescere del numero di bit A nell’accumulatore di fase tuttavia, allo stato attuale della tecnica, soltanto i P bit
più significativi possono essere applicati al convertitore fase-ampiezza che
altrimenti diviene irrealizzabile.
Il troncamento da luogo ad un errore che è periodico e pertanto produce
delle frequenze spurie in uscita dal DDFS, la loro ampiezza varia da un
minimo di 0 quando i P bit eliminati sono tutti 0, condizione che si verifica
per6 :
GCD T, 2(A−P ) = 2(A−P )
(A.3)
ad un massimo di −6.02P dBc nel caso l’MSB7 dei P bit troncati sia 1 e
tutti gli altri siano 0 il che accade se:
GCD T, 2(A−P ) = 2(A−P )
(A.4)
Per comprendere la distribuzione di queste spurie si parte dall’osservazione
che il segnale d’errore è proprio la parola troncata espressa su R = A−P
bits, la parola di sintonia ad essa associata è ET W = T mod 2R la quale
accumulandosi da luogo alla forma d’onda a dente
di sega di Figura(A.3)
ET W
avente frequenza fondamentale F0 = Fclk × 2R e spettro rappresentato
Figura A.3: Andamento nel tempo della parola troncata
in Figura(A.4). Le righe spettrali che cadono in multipli dispari della banda
Figura A.4: Spettro dente di sega
di Nyquist hanno delle immagini proprio all’interno di essa e pertanto non
sono eliminabili mediante filtraggio, si può soltanto ridistribuirne la potenza
6
7
GDC indica il massimo comun divisore tra i due argomenti
Most Significant Bit
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
63
mediante la tecnica del dithering che consiste nel distruggere la periodicità
aggiungendo delle quantità randomiche prima del troncamento.
A.4 Convertitore Fase-Frequenza
Vi sono due tipi di convertitore fase-ampiezza:
ROM le fasi troncate in uscita dall’accumulatore di fase individuano delle
locazioni di memoria in una ROM le quali contengono la corrispondente ampiezza del seno o del coseno. La simmetria del coseno e del
seno consente di ridurre le dimensioni della ROM limitandosi a memorizzare i valori delle ampiezze per le sole fasi comprese tra 0 e 90◦
ed utilizzando i due bit più significativi della parola di fase troncata
per ricostruire l’ampiezza corretta come in Figura(A.5).
Figura A.5: Ottimizzazione del convertitore fase-ampiezza
CORDIC la simmetria del coseno e del seno viene utilizzata anche nella soluzione CORDIC [9], della quale esistono due forme denominate
Vectoring CORDIC e Rotation CORDIC, quest’ultima è quella utile
per la generazione di seno e coseno a partire dall’argomento, si cerca
infatti di annullare l’angolo ϕ iniziale sommando e sottraendo ad esso
degli angoli via via più piccoli, al crescere del numero di iterazioni
aumenta la precisione del risultato e conseguentemente migliora l’approssimazione sia per il seno che per il coseno dell’angolo di partenza.
L’algoritmo è adatto ad applicazioni digitali in quanto le rotazioni si
basano su moltiplicazioni per potenze di due.
La ROM risulta una soluzione conveniente nel caso si scelga una fase
troncata con al massimo 14 bit [14], oltre conviene la soluzione CORDIC
la quale ha anche il vantaggio di produrre congiuntamente ed in maniera
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
64
intrinseca sia seno che coseno risultando ottimale per la realizzazione di un
modulatore con portanti in quadratura, per questi motivi nel seguito verrà
tralasciata la trattazione del DDFS basato sulla ROM.
A.4.1 Algoritmo CORDIC
Si basa su di una rotazione planare che trasforma un vettore (Xi , Yi ) in
un nuovo vettore (Xn , Yn ), la forma matriciale di una generica rotazione
Y
(Xn , Yn)
(Xi , Yi)
X
Figura A.6: Rotazione planare
planare di un angolo ϕ è
Xn
Yn
cos ϕ sin ϕ
sin ϕ cos ϕ
=
Xi
Yi
(A.5)
trattandosi di un algoritmo iterativo la rotazione ϕ viene scomposta in n
rotazioni ϕi ciascuna delle quali è espressa dalla
Xi+1
Yi+1
cos ϕi sin ϕi
sin ϕi cos ϕi
=
Xi
Yi
(A.6)
da cui raccogliendo cos (ϕi ) si ha
Xi+1
Yi+1
= cos ϕi
1
− tan ϕi
tan ϕi
1
Xi
Yi
(A.7)
quest’ultima forma è vantaggiosa in quanto il numero di moltiplicazioni
passa da 4 a 3, l’ulteriore vincolo
tan ϕi = Si 2(−i)
(A.8)
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
65
con Si ∈ {−1; +1} consente di ottimizzare l’implementazione su sistemi
digitali in quanto le moltiplicazioni per potenze di due si ottengono facendo
scorrere il contenuto di un registro in una direzione o nell’altra.
Il valore di Si alla iesima iterazione viene determinato richiedendo che
sia minima la differenza tra l’angolo iniziale e l’angolo che si ottiene dalla
somma degli angoli delle iterazioni precedenti, se tale differenza è minore di
zero allora Si = −1 altrimenti Si = +1.
Il vincolo descritto dall’equazione(A.8) è fondamentale nella semplificazione dell’algoritmo in quanto cos (ϕi ) = cos (−ϕi ) e quindi per una data
iterazione n la produttoria dei cos (ϕi ) delle iterazioni precedenti è nota a
priori e vale
Kn =
n−1
Y
i=0
Ki =
n−1
Y
i=0
cos arctan
1
2i
=
n−1
Yp
1 + 2(−2i)
(A.9)
i=0
tale valore approssima 0, 607252935008881 per n → ∞ ma già per n = 5
vale 0, 607351770141296 pertanto per algoritmi CORDIC con un numero di
iterazioni maggiori di 10 si può considerare un numero costante soprattutto
in considerazione della lunghezza finita dei registri. Il reciproco di K vale approssimativamente 1, 64676025812107 ed è denominato guadagno del
CORDIC, se occorre che il vettore risultante abbia modulo unitario deve
essere compensato utilizzando una delle seguenti strategie:
1. per la prima iterazione si ha Xi = 1 , Yi = 0 , alla fine occorre dividere
sia Xn che Yn per il guadagno.
2. iniziando con Xi = 0.607351770141296 , Yi = 0 non è poi necessario
dividere per il guadagno tuttavia le prestazioni sono inferiori rispetto
alla soluzione precedente in quanto 0, 607351770141296 non è potenza
di due e quindi la sua implementazione in un registro implica un errore
iniziale.
3. compensazione del guadagno ad ogni iterazione.
Omettendo K per semplicità di rappresentazione si ha che l’iesima iterazione del CORDIC è descritta dalle equazioni:

 Xi+1 = Xi − Si 2(−2i) Yi
Y
= Yi + Si 2(−2i) Xi
 i+1
ϕi+1 = ϕi − Si arctan 2(−2i)
(A.10)
A.5 Descrizione modello matematico
Lo script Matlab che descrive l’NCO è NCO Q.m (Listato E.1.1) , tramite
Imposta frequenze Q (Listato E.1.2) vengono impostate la frequen-
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
66
za di clock e quella desiderata in uscita mentre Imposta NCO Q.m
(Listato E.1.3) consente di impostare i parametri:
n
n
n
n
n
bit acc
periods
bit cordic
it cordic
bit dac
N◦
N◦
N◦
N◦
N◦
di
di
di
di
di
bit accumulatore di fase
periodi della funzione generata
bit per la fase troncata
iterazioni del CORDIC
bit per seno e coseno prodotti dal CORDIC
L’accumulatore di fase in Crea super accumulatore Q.m (Listato E.1.4) è modellato con un vettore contenente tutti i valori consecutivi della
fase da applicare al CORDIC, in tale vettore sono memorizzate n periods
rampe di fase. Tronca Q.m (Listato E.1.5) consente di passare da una rappresentazione della fase su n bit acc bits ad una su n bit cordic bits, tale
vettore quantizzato è poi utilizzato da Crea coseno e seno Q.m (Listato E.1.6) il quale per ogni campione di fase invoca Forward cordic Q.m
(Listato E.1.7) che opera riportando tutte le fasi nel primo quadrante in accordo alla Figura(A.5) ed eseguendo iterativamente per n it cordic volte le
equazioni(A.10). Partendo con il coseno che vale 0, 607252936517011 invece
che 1 non è necessario dividere dopo l’ultima iterazione per il guadagno del
CORDIC8 tuttavia occorre riportare i valori calcolati nel giusto quadrante,
del seno e coseno ottenuti viene visualizzato un periodo nel dominio del
tempo come in Figura(A.7) relativa al caso di fclk = 4 × fout .
(a) Coseno
(b) Seno
Figura A.7: Uscita DDFS nel tempo
Per la determinazione dello spettro viene utilizzato il metodo MultiTaper in Visualizza spettro e SFDR p.m (Listato E.1.9) il quale
mostra anche l’SFDR9 determinato in Calcola SFDR.m (Listato E.1.10)
quale differenza tra il massimo assoluto dello spettro ed il maggior massimo
relativo, un esempio dei risultati ottenuti è in Figura(A.8).
A.6 Descrizione modello VHDL
Il file NCO.vhd (Listato F.1.1) descrive lo schematico di Figura(A.9), quando
8
9
Appendice(A.9)
Spurious Free Dynamic Range
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
67
Figura A.8: Spettro Coseno Matlab
U2
Theta_tr(12)
ctrl(1)
clk
in_delay_13 out_delay_13
delay_13
ctrl(1:0)
U1
Theta_tr(11)
ctrl(0)
clk
in_delay_13 out_delay_13
delay_13
ctrl(1:0)
cos(11:0)
accumulator
clk
freq_word(31:0)
freq_word(31:0)
load
coseno(11:0)
in_cosine_rebuild(11:0) out_cosine_rebuild(11:0)
U4
U5
troncatore_12
Theta(31:0)
theta(31:0)
ingresso(31:0)
clear
uscita(12:0)
U6
Theta_tr(12:0)
U0
in_tfq(12:0)
out_tfq(12:0)
fase(12:0)
U8
clk coseno(11:0)
cosine_rebuild
fase(12:0)
seno(11:0)
to_first_quadrant
cordic_pipelined_unrolled
load
sin(11:0)
clear
U3
Theta_tr(12)
clk
in_delay_13 out_delay_13
out_sine_rebuild(11:0)
in_sine_rebuild(11:0)
ctrl
U7
sine_rebuild
seno(11:0)
ctrl_segno_seno
delay_13
Figura A.9: NCO VHDL
LOAD è alto l’accumulatore Accumulator.vhd (Listato F.1.2) viene caricato con la parola di sintonia il cui valore in binario viene calcolato tramite
lo script Matlab Calcola incremento fase NCO.m (Listato E.1.11) ad
ogni colpo di clock questo incremento si somma al valore precedentemente
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
68
contenuto nel registro a 32 bit per poi essere troncato a 12 bit tramite Troncatore 12.vhd (Listato F.1.14) , i 2 bit più significativi vengono ritardati
da Delay 13.vhd (Listato F.1.11) di 13 periodi di clock in modo da poter
associare al giusto quadrante il seno ed il coseno calcolati per un dato valore della fase che viene confinata tra 0◦ e 90◦ da To first quadrant.vhd
(Listato F.1.13) , in pratica questi due bit vanno a pilotare delle inversioni in
complemento a due realizzate condizionatamente in Cosine rebuild.vhd
(Listato F.1.10) e Sine rebuild.vhd (Listato F.1.12) .
Coseno e seno vengono calcolati mediante un’architettura CORDIC non
iterativa al fine di ottenere la massima velocità di clock di sistema, ogni iterazione è effettuata tramite Cordic base j.vhd (Listato F.1.4) in accordo
alle equazioni(A.10) visivamente descritte in Figura(A.10).
U0
clk
reg_12
clk
in_x(11:0)
adder_12
U4
x_out_reg(11:0)
in_reg_12(11:0)out_reg_12(11:0)
in_a(11:0)
U2
shifter
coseno(11:0)
out_adder_12(11:0)
shifter_to_adder_x(11:0)
in_b(11:0)
sgn
in_shifter(11:0) out_shifter(11:0)
clk
U3
clk
U1
in_b(11:0)
clk
in_a(11:0)
a_cost_j(12:0)
reg_13
clk
seno(11:0)
out_adder_12(11:0)
y_out_reg(11:0)
in_reg_12(11:0)out_reg_12(11:0)
U6
sgn
shifter_to_adder_y(11:0)
reg_12
clk
in_z(12:0)
sgn
in_shifter(11:0) out_shifter(11:0)
clk
in_y(11:0)
z_out_reg(12)
shifter
U5
adder_12
U7
adder_13
in_b(12:0)
out_adder_13(12:0)
z_out_reg(12:0)
in_reg_13(12:0)out_reg_13(12:0)
in_a(12:0)
fase_j(12:0)
sgn
z_out_reg(12)
Figura A.10: Iterazione iesima
Vengono eseguite 13 iterazioni in cascata, tramite la descrizione Cordic pipelined unrolled.vhd (Listato F.1.3) cui è associato lo schema in
Figura(A.11) in esso i valori degli angoli elementari da sommare o sottrarre vengono calcolati ed espressi in binario tramite lo script Matlab Calcola rotazioni Cordic.m (Listato E.1.8) i cui risultati sono visualizzati
in Tabella(A.1) che ben evidenzia come l’entità della rotazione i esima si
dimezza rispetto alla rotazione precedente.
Tramite lo script Matlab Visualizza spettro NCO VHDL.m (Listato E.1.12) è possibile ottenere lo spettro del coseno generato dal CORDIC
VHDL, un esempio di risultato è riportato in Figura(A.12).
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x0(11:0)
y0(11:0)
in_y(11:0)
z0(12:0)
y1(11:0)
seno(11:0)
in_z(12:0)
z1(12:0)
fase_j(12:0)
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x1(11:0)
in_y(11:0)
seno(11:0)
in_z(12:0)
fase_j(12:0)
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x2(11:0)
y2(11:0)
in_y(11:0)
seno(11:0)
in_z(12:0)
fase_j(12:0)
z2(12:0)
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x3(11:0)
y3(11:0)
in_y(11:0)
z3(12:0)
y4(11:0)
seno(11:0)
in_z(12:0)
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x4(11:0)
in_y(11:0)
seno(11:0)
in_z(12:0)
fase_j(12:0)
z4(12:0)
fase_j(12:0)
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x5(11:0)
y5(11:0)
in_y(11:0)
z5(12:0)
seno(11:0)
in_z(12:0)
fase_j(12:0)
x6(11:0)
y6(11:0)
z6(12:0)
69
cordic_base_j
clk
in_x(11:0) coseno(11:0)
in_y(11:0)
seno(11:0)
in_z(12:0)
fase_j(12:0)
x7(11:0)
y7(11:0)
z7(12:0)
fase(12:0)
a_cost_j(12:0)
U0
a_cost_j(12:0)
U1
a_0(12:0)
SignalAssignments_2
SignalAssignments_3
a_0<= "0010000000000"
;
in_y(11:0)
in_z(12:0)
seno(11:0)
fase_j(12:0)
y8(11:0)
in_y(11:0)
z8(12:0)
in_z(12:0)
a_cost_j(12:0)
U7
a_7(12:0)
SignalAssignments_9
a_7 <= "0000000001010"
;
seno(11:0)
fase_j(12:0)
y9(11:0)
in_y(11:0)
z9(12:0)
in_z(12:0)
a_cost_j(12:0)
U8
a_8(12:0)
SignalAssignments_10
a_8 <= "0000000000101"
;
seno(11:0)
fase_j(12:0)
x10(11:0)
y10(11:0)
z10(12:0)
in_y(11:0)
in_z(12:0)
a_cost_j(12:0)
U9
a_9(12:0)
SignalAssignments_11
a_9 <= "0000000000010"
;
seno(11:0)
fase_j(12:0)
x11(11:0)
y11(11:0)
z11(12:0)
clk
x12(11:0)
in_x(11:0) coseno(11:0)
in_y(11:0)
seno(11:0)
y12(11:0)
in_y(11:0)
fase_j(12:0)
z12(12:0)
in_z(12:0)
in_z(12:0)
a_10(12:0)
SignalAssignments_12
a_10 <= "0000000000001"
;
a_cost_j(12:0)
U11
a_11(12:0)
SignalAssignments_13
a_11 <= "0000000000000"
;
seno(11:0)
x13(11:0)coseno(11:0)
y13(11:0)seno(11:0)
fase_j(12:0)
a_cost_j(12:0)
U12
a_12(12:0)
SignalAssignments_14
a_12 <= "0000000000000"
;
Figura A.11: Cordic Pipelined Unrolled
Iterazione
1
2
3
4
5
6
7
8
9
10
11
12
13
a_6 <= "0000000010100"
;
cordic_base_j
clk
in_x(11:0) coseno(11:0)
a_cost_j(12:0)
U10
a_6(12:0)
SignalAssignments_8
a_5 <= "0000000101000"
;
cordic_base_j
a_cost_j(12:0)
U6
a_5(12:0)
SignalAssignments_7
a_4 <="0000001010001"
;
cordic_base_j
clk
in_x(11:0) coseno(11:0)
a_cost_j(12:0)
U5
a_4(12:0)
SignalAssignments_6
a_3 <= "0000010100010"
;
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x9(11:0)
a_cost_j(12:0)
U4
a_3(12:0)
SignalAssignments_5
a_2 <="0000100111111"
;
cordic_base_j
clk
in_x(11:0) coseno(11:0)
x8(11:0)
a_cost_j(12:0)
U3
a_2(12:0)
SignalAssignments_4
a_1 <="0001001011100"
;
cordic_base_j
clk
in_x(11:0) coseno(11:0)
a_cost_j(12:0)
U2
a_1(12:0)
Angolo ϕi
45, 0000
26, 5651
14, 0362
7, 1250
3, 5763
1, 7899
0, 8952
0, 4476
0, 2238
0, 1119
0, 0560
0, 0280
0, 0140
Tabella A.1: Rotazioni elementari CORDIC
SignalAssignments_15
x0 <= "010011011100"
;
y0 <= "000000000000"
;
APPENDICE A. SINTESI DIRETTA DI FREQUENZA DIGITALE
Figura A.12: Spettro coseno generato dal DDFS VHDL
70
Appendice B
Sistemi Multirate
B.1 Sommario
Tutti i sistemi dove l’elettronica analogica deve interfacciarsi con l’elettronica digitale sono dei sistemi multirate nei quali vi sono campioni generati
con frequenze di campionamento FS diverse, in particolare si può pensare
che la parte analogica del sistema operi con FS → ∞ mentre la parte digitale con la minima FS sufficiente all’elaborazione desiderata, vengono cosı̀
mantenute basse sia la complessità che la dissipazione del sistema digitale.
Numerosi sono gli esempi di sistemi multirate completamente digitali, ad
esempio per l’audio digitale si ha che gli studi di produzione campionano a
48kHz mentre lo standard per i CD è a 44, 1kHz ed il broadcasting a 32kHz,
per passare informazioni da un ambiente all’altro si rende quindi necessario
a seconda dei casi un upsampler1 che consente di salire ad un rate più alto
oppure un downsampler2 col quale scendere ad un rate più basso.
B.2 Downsampling e Upsampling
Nei sistemi multirate il seguente teorema del campionamento assume importanza fondamentale:
Teorema 2 (di Shannon e Nyquist) Se un segnale continuo x (t) possiede trasformata di Fourier X (f ) a banda limitata (i.e. |X (f )| = 0 ∀ |f | 6∈
[f0 , f0 + B]) allora x (t) può essere ricostruito in maniera univoca e senza
errore a partire dai suoi campioni x (kT ) a patto che la frequenza di campionamento Fs = T1 sia maggiore della frequenza di Nyquist FN yquist = 2B
del segnale.
Nel caso la condizione sulla banda limitata non sia rispettata si ha
aliasing [10], le code di una replica spettrale centrate su di un multiplo
1
2
il termine interpolatore non include il filtro anti-immagine situato a valle
il termine decimatore non include il filtro anti-aliasing situato a monte
71
APPENDICE B. SISTEMI MULTIRATE
72
della frequenza di campionamento si vanno cioè a sovrapporre a quelle della
replica antecedente e della replica successiva.
L’upsampler si basa sull’interpolatore il quale deve produrre in uscita
più campioni di quanti ne abbia in ingresso mantenendo uno spettro simile,
ciò si può ottenere o aggiungendo L − 1 zeri tra due campioni d’ingresso adiacenti nel caso si voglia interpolare L, oppure ripetendo L − 1 volte
ogni campione, quest’ultima soluzione è più complessa da un punto di vista
circuitale e conduce a risultati peggiori in quanto si tratta di un campionamento con tenuta di ordine zero. Per comprendere la necessità di un filtro
a valle dell’interpolatore si fa riferimento alla Figura(B.1), in particolare in
Figura B.1: Upsampling
(B.1.a) si ha lo spettro di un generico segnale campionato caratterizzato da
una banda inferiore alla banda di Nyquist e con delle repliche centrate intorno ai multipli della frequenza di campionamento FS1 , lo spettro all’uscita
dell’interpolatore è rappresentato in (B.1.b) e si differenzia dal precedente
in quanto all’uscita dell’interpolatore la frequenza di campionamento è FS2
e pertanto all’interno della banda di Nyquist sono presenti delle componenti
spettrali che non c’erano a monte dell’interpolatore, esse sono dette immagini ed il filtro passabasso tramite il quale vengono eliminate è detto filtro
APPENDICE B. SISTEMI MULTIRATE
73
anti-immagine. L’upsampler è pertanto costituito da un interpolatore ed un
filtro anti-immagine come in Figura(B.2).
Figura B.2: Upsampler
Il downsampler è basato sul decimatore il quale deve produrre in uscita meno campioni di quanti ne abbia in ingresso mantenendo uno spettro
simile, ciò si ottiene prendendo un campione ogni M nel caso si voglia decimare il rate di un valore M. La Figura(B.3) illustra la necessità di un
filtro a monte del decimatore in particolare in (B.3.a) si ha lo spettro di
Figura B.3: Downsampling
un generico segnale campionato caratterizzato da una banda inferiore alla
banda di Nyquist riferita alla frequenza di campionamento FS1 in ingresso al downsampler, il segnale in uscita dal decimatore occupa la medesima
APPENDICE B. SISTEMI MULTIRATE
74
banda tuttavia essendo diminuita la frequenza di campionamento3 , è diminuita anche la banda di Nyquist che essendo divenuta inferiore a quella del
segnale, in virtù del teorema del campionamento, determina aliasing.
A monte del decimatore è pertanto necessario un filtro detto antialiasing che limiti la banda del segnale d’ingresso all’interno della banda
di Nyquist relativa al rate più basso conseguentemente lo schema a blocchi
del downsampler è quello rappresentato in Figura(B.4).
Figura B.4: Downsampler
Lavorando sui campioni è implicito siano possibili soltanto fattori interi
d’interpolazione o decimazione, nel caso in cui se ne richiedano di frazionari
occorre mettere in cascata il decimatore e l’interpolatore facendo attenzione
che l’interpolatore preceda il decimatore come in Figura(B.5) in quanto alFS
trimenti la banda del segnale d’ingresso deve essere confinata in 2M
essendo
M il fattore di decimazione.
Figura B.5: Cambiamento di rate frazionario
Nel caso in cui si desideri realizzare dei fattori di interpolazione o decimazione elevati occorre suddividere la catena in più stadi, in genere due
o tre, ed implementare il rate più elevato nell’ultimo stadio, tornano molto
utili inoltre le Nobili Identità in Figura(B.6), dimostrate in [12], le quali
consentono di spostare l’operazione di filtraggio verso la regione del sistema
che opera con il rate più basso ottenendo cosı̀ una notevole semplificazione.
B.3 Architetture Multirate
Diverse architetture sono state sviluppate allo scopo di realizzare sistemi
multirate tuttavia al momento le opzioni più valide ed utilizzate sembrano
3
che in figura vale FS2 =
FS1
3
APPENDICE B. SISTEMI MULTIRATE
75
Figura B.6: Nobili Identità
essere la decomposizione polifase ed il CIC4 , esse presentano caratteristiche
abbastanza diverse pertanto a seconda dell’applicazione si può trovare una
oppure l’altra o anche entrambe.
B.3.1 CIC
Il CIC è stato introdotto da Hogenhauer [6] nel 1981 si caratterizza per
la sua estrema semplicità che ne porta a trascurare i difetti quali la risposta in frequenza non piatta e l’eccessivo guadagno. E’ costituito da una
cascata di n blocchi integratori5 ed n blocchi comb6 , ciascuno di essi contiene un sommatore ed un ritardo, sono quindi assenti i moltiplicatori la
cui implementazione su FPGA determina spesso la massima frequenza di
clock utilizzabile nel circuito, l’architettura CIC è quindi ideale per sistemi dove siano richiesti elevati cambiamenti di rate corrispondenti ad alte
frequenze non raggiungibili dai moltiplicatori. La funzione di trasferimento
dell’integratore nel piano Z è
HI (z) =
1
1 − z −1
(B.1)
ha pertanto un polo in z= −1 che ne determina il comportamento passabasso ma con un guadagno infinito nell’origine, si tratta pertanto di un
sistema instabile che viene compensato inserendo in cascata un comb la cui
funzione di trasferimento è
HC (z) = 1 − z −RM
(B.2)
dove R è la variazione del data rate desiderata mentre M è il ritardo differenziale che sovente assume i valori 1 o 2 ed in pratica si realizza inserendo
M blocchi di ritardo nella catena che porta al sommatore. L’interpolatore o
il decimatore CIC si ottengono rispettivamente ponendo in cascata N comb
4
Cascaded Integrator Comb
Figura(B.7)
6
Figura(B.8)
5
APPENDICE B. SISTEMI MULTIRATE
76
(a) Integrator
(b) Integrator
Figura B.7: Integratore e sua risposta in frequenza
(a) Comb
(b) Comb
Figura B.8: Comb e sua risposta in frequenza
ed N integratori oppure viceversa, se però tra i blocchi si effettua il cambiamento del rate come nelle Figure (B.9) e (B.10) si ottiene che metà del CIC
opera ad un rate più basso con gli indubbi vantaggi che ne conseguono ed
inoltre il progetto dei due blocchi diviene indipendente dal cambiamento di
rate desiderato quindi la struttura può esser resa programmabile.
Figura B.9: Interpolatore CIC
In entrambe i casi la risposta in frequenza nel piano z è:
H (z) =
HIN
(z) HCN
(z) =
1 − z −RM
N
(1 − z −1 )N
=
RM
−1
X
k=0
!N
z
−k
(B.3)
APPENDICE B. SISTEMI MULTIRATE
77
Figura B.10: Decimatore CIC
il cui spettro nel caso di R = 2 rappresentato in Figura(B.11) evidenzia un
Figura B.11: Spettro del CIC per R=2, N=1, M=1
nullo in corrispondenza della frequenza di campionamento relativa al rate
minore, mentre in corrispondenza della sua frequenza di Nyquist ossia al
margine della banda utile presenta un’attenuazione di circa 5 dB, questa
osservazione da sola è sufficiente ad affermare che il CIC è inadatto per
implementazioni di piccoli cambi di data rate, nel qual caso occorre compensare la risposta in frequenza in modo da renderla maggiormente piatta
nella banda utile. Per ampi valori del cambiamento di rate R si ottiene
dall’Equazione(B.3) l’approssimazione
N
πM f H (f ) = RM sinπM
f se 0 ≤ f <
1
M
(B.4)
che consente le seguenti tre osservazioni importanti ai fini del progetto:
1
1. nello spettro vi sono dei nulli in corrispondenza dei multipli di f = M
modificando M, R ed N opportunamente si può fare in modo che i termini di aliasing o immagine cadano in queste regioni come evidenziato
in Figura(B.12).
2. al crescere di N aumenta velocemente l’attenuazione il che significa
che la banda nella quale la risposta in frequenza è piatta si restringe
ulteriormente, diviene pertanto sempre più necessario l’inserimento a
monte di una precompensazione.
APPENDICE B. SISTEMI MULTIRATE
(a) N = 4, M = 1, R = 7
78
(b) N = 4, M = 2, R = 7
Figura B.12: Effetto di M sulla frequenza del CIC
3. si ha un guadagno molto elevato infatti a fronte di Bin bits in ingresso
si hanno Bout = [N log2 RM + Bin ] bits in uscita7 , la dipendenza da
R comporta che la decisione sul numero di bit debba tenere conto sia
del massimo che del minimo rate8 a cui il CIC deve operare.
B.3.2 Polifase
La struttura polifase [5] ha il grande vantaggio di essere un upsampler vero e
proprio infatti l’architettura determina il cambiamento di rate mentre i suoi
coefficienti impostano la risposta dei filtri anti-aliasing o anti-immagine.
Ipotizzando di voler interpolare 3 e di disporre dei coefficienti h (n) del
filtro anti-immagine, cui corrisponde la trasformata
H (z) =
N
−1
X
h (n) z −n
(B.5)
n=0
7
8
nel caso di un decimatore implementato con una aritmetica in complemento a due
determina il numero di bit da mantenere nello stadio finale
APPENDICE B. SISTEMI MULTIRATE
79
scomponibile nelle tre componenti polifase H0 (z), H1 (z) ed H2 (z):
H (z) =
N
−1
X
h (n) z −n
n=0
=
N −1
3
N −1
3
X
X
h (3n) z −(3n) +
n=0
=
N −1
3
h (3n + 1) z −(3n+1) +
n=0
N −1
3
X
X
n=0
= H0 (z) + z
−1
H1 (z) + z
h (3n + 2) z −(3n+2)
n=0
N −1
3
h (3n) z −(3n) + z −1
X
n=0
−2
N −1
3
h (3n) z −(3n) + z −2
X
h (3n) z −(3n)
n=0
H2 (z)
(B.6)
si ha che l’ultima equazione è implementabile con lo schema in Figura(B.13
a), da essa tramite un risultato classico della teoria dei sistemi si ottiene
lo schema(B.13 b) quindi utilizzando la Nobile Identità (b) si giunge allo
schema(B.13 c) nel quale la parte terminale non è altro che un commutatore che ad ogni intervallo di clock preleva in maniera ciclica una delle tre
componenti polifase come evidenziato in Figura(B.13 d).
Figura B.13: Trasformazioni interpolatore polifase
Rispetto alla forma polifase di partenza quella ottenuta è più efficiente in
quanto le tre componenti operano ad un rate minore rispetto al commutatore inoltre estendendo la precedente trattazione si possono ottenere risultati
simili sia per un interpolatore polifase di ordine N che per un decimatore
polifase.
Nella realizzazione pratica non si fa altro che distribuire i coefficienti del
filtro di partenza su L filtri se L è il fattore di interpolazione, ognuno di
questi filtri implementa una decomposizione polifase, l’uscita dei filtri può
APPENDICE B. SISTEMI MULTIRATE
80
andare ad un sommatore oppure più intelligentemente ad un commutatore
il quale ne trasferisce in uscita solo uno alla volta in maniera ciclica ad un
rate L volte superiore al rate dei dati in ingresso al polifase, ciò è possibile
in quanto il processo d’interpolazione inserisce L − 1 zeri per ogni campione
d’ingresso, è pertanto inutile calcolare il prodotto di questo campione nullo
per il rispettivo coefficiente del filtro.
Appendice C
Logiche programmabili
C.1 Sommario
Dopo aver elencato le diverse tipologie di logiche programmabili evidenziandone i principali pregi e difetti si passa ad una descrizione particolareggiata dell’architettura Virtex [15] alla quale appartiene l’FPGA utilizzata
nell’implementazione del modulatore.
C.2 Tipologie di logiche programmabili
Le logiche programmabili sono una delle diverse possibità di implementazione di un circuito digitale, la gerarchia delle possibili soluzioni è illustrata
in Figura(C.1).
Figura C.1: Gerarchia implementazioni circuiti logici
La prima tipologia di logica programmabile è stata la PAL1 che implementa una somma di prodotti programmabile una sola volta, la sua diretta
1
Programmable Array Logic
81
APPENDICE C. LOGICHE PROGRAMMABILI
82
estensione è rappresentata dalle PLD2 le quali dispongono di un elevato
numero di blocchi logici interconnessi tra loro, ciascuno di essi implementa
una somma di prodotti che può essere registrata o meno, il ritardo che ne
deriva è quindi ben definito. Vi sono poi le CPLD3 le quali non presentano delle interconnessioni globali bensi delle strutture di routing raccolte in
fasci pertanto il ritardo risulta definito soltanto a livello locale mentre non
è possibile conoscere a priori quali gruppi di fasci verranno effettivamente
utilizzati per le interconnessioni. Diverse CPLD sono del tipo ISP4 possono
cioè essere programmate senza estrazione dal circuito, tale programmazione
rimane memorizzata sin quando non è necessario mutare il funzionamento
della CPLD in accordo a mutate esigenze della logica d’utente. Chiudono
il quadro delle logiche programmabili le FPGA, dispositivi molto complessi
nei quali sono immersi un numero elevato di blocchi logici abbastanza semplici ma tutti interconnessi tra loro, il ritardo è pertanto non predicibile a
priori.
Si sono nel tempo affermate due diverse tipologie di FPGA, le OTP5
e le ISP anche dette SRAM6 , tra le OTP la tecnologia più rilevante è la
antifuse caratterizzata da elementi molto piccoli e veloci da programmare
i quali però per tale operazione richiedono ai bordi del circuito integrato
un numero elevato di transistori aventi il compito di fondere il polisilicio
amorfo. I veri vantaggi sono pertanto:
1. non è possibile carpire la logica a partire dal dispositivo che pertanto è
adatto ad applicazioni dove sia richiesto un certo grado di segretezza.
2. sopporta elevate radiazioni elettromagnetiche senza subire alterazioni
funzionali il che è importante in applicazioni spaziali.
Le FPGA con tecnologia SRAM richiedono la riprogrammazione ad ogni
riaccensione, a tal fine si utilizza una PROM esterna la quale contiene la
configurazione in maniera stabile e ad ogni ripartenza la passa ad una o
più FPGA disposte in catena. Attualmente si tratta della tecnologia che
consente di raggiungere le prestazioni più elevate sia in termini di velocità
di clock che di complessità delle funzioni realizzate, nella seguente sezione
viene descritta l’architettura Virtex della Xilinx che ha riscosso un notevole
successo commerciale in virtù delle numerose innovazioni tecnologiche da
essa introdotte.
L’evoluzione verso le famiglie Virtex E , Virtex 2 e Virtex 2 Pro ha
riguardato i seguenti aspetti:
1. diminuzione dello spessore dello strato di ossido7 .
2
Programmable Logic Device
Complex Programmable Logic Device
4
In System Programmable
5
One Time Programmable
6
Static Random Access Memory
7
dai 0.22-µm della Virtex ai 0.13-µm della Virtex 2 Pro
3
APPENDICE C. LOGICHE PROGRAMMABILI
83
2. aumento del numero di strati di metallo8 .
3. progressiva integrazione ed ottimizzazione dei dispositivi aritmetici
alla base delle applicazioni DSP.
La Virtex 2 e la Virtex 2 PRO sono inoltre delle platform FPGA le quali
consentono di realizzare in un solo dispositivo delle funzionalità complesse
che attualmente vengono implementate con più circuiti integrati, a tal fine
oltre a essere disponibili in formati molto grandi9 implementano numerose
agevolazioni quali dei blocchi di memoria RAM, moltiplicatori precablati
ed ottimizzati, possibilità di ospitare dei moduli altrui protetti da licenze
quali ad esempio il Power PC IBM e i Multi-Gigabit Transceivers presenti
di default nella Virtex 2 PRO.
C.3 Architettura Virtex
La famiglia Virtex si compone di nove diverse FPGA diverse tra loro per le
dimensioni che vanno da 50mila porte logiche sino ad 1milione, quest’ultimo formato è quello utilizzato per l’implementazione del modulatore, nella
fattispecie la scheda DINI utilizza 6 FPGA XCV1000BG560-4 dove BG560
indica il formato BallGrid da 560 pin, mentre -4 è lo speed grade il quale
viene calcolato statisticamente, migliori prestazioni in termini di velocità di
clock si possono ottenere utilizzando versioni con speed grade -5 o -6. Alla
base della architettura Virtex ci sono i CLB e gli IOB10 , i primi si occupano
di realizzare le funzionalità che il progettista richiede mediante un linguaggio ad alto livello quale il VHDL11 o il VERILOG, i secondi realizzano
invece dell’interfacciamento di questa logica con il mondo esterno.
Oltre a CLB e IOB ogni FPGA contiene anche un numero elevato di
risorse dedicate alle connessioni, esse sono diversificate in termini di estensione e capacità di pilotaggio ed alcune sono espressamente dedicate al
routing di segnali particolarmente importanti come ad esempio il clock.
C.3.1 CLB
L’entità logica programmabile di base della architettura Virtex è la LC12 ,
essa include:
8
dai 5 strati della Virtex ai 9 della Virtex 2 Pro
sino a 10M gate
10
Input Output Block
11
VHSIC Hardware Description Language
12
Logic Cell
9
APPENDICE C. LOGICHE PROGRAMMABILI
84
• un generatore di funzioni13 che può anche essere utilizzato come RAM14
sincrona distribuita nel formato 16 × 1 bit oppure come SRL1615 .
• logica dedicata al riporto nelle operazioni aritmetiche, tra cui una
porta XOR denominata XORCY che consente l’implementazione di
un full-adder ad 1 bit, un multiplexer denominato MUXCY ed una
porta AND che ottimizza l’implementazione dei moltiplicatori.
Figura C.2: Implementazione di un moltiplicatore
• un registro che può essere configurato sia come FFD sensibile al fronte
del clock che come latch sensibile al livello.
L’unione di due LC viene denominata Slice, come evidenziato in Figura(C.3) il multiplexer F5 combina le uscite delle LUT consentendo di
realizzare le seguenti strutture:
• generatore di funzioni a 5 ingressi.
• multiplexer 4:1.
• funzioni specifiche sino ad un massimo di 9 ingressi.
inoltre la combinazione delle due LUT può dar luogo ad una RAM sincrona
16 × 2 bit o 32 × 1 bit oppure una RAM sincrona a doppia porta 16 × 1 bit.
Il CLB rappresentato in Figura(C.4) contiene 2 Slice e quindi 4 LC, in
esso il multiplexer F6 coadiuvato dal multiplexer F5 combina le uscite delle
4 LUT consentendo di implementare:
• generatore di funzioni a 6 ingressi.
• multiplexer 8:1.
• funzioni specifiche sino ad un massimo di 19 ingressi.
13
implementato con una LUT a 4 ingressi
Random Access Memory
15
Shift Register Left 16-bit
14
APPENDICE C. LOGICHE PROGRAMMABILI
85
Figura C.3: Slice Virtex
Figura C.4: CLB Virtex
C.3.2 IOB
Come precedentemente affermato gli IOB si occupano dell’interfacciamento
della logica implementata nelle CLB con il mondo esterno, ognuno si essi
è dotato di 3 registri che possono essere configurati sia come sensibili al
livello che al fronte, da progetto si può decidere di includere della logica in
questi registri oppure non utilizzarli. Vi sono inoltre dei resistori di pull-up
APPENDICE C. LOGICHE PROGRAMMABILI
86
e di pull-down di valore compreso tra 50 e 100Ω. Sono possibili 13 diversi
standard di interfacciamento col mondo esterno, nella fattispecie LVTTL,
LVCMOS2, PCI 5V, PCI 3, 3V, GTL, GTL+, HSTL I, HSTL III, HSTL
IV, SSTL3 I e II, SSTL2 I e II, CTT e AGP dei quali molti richiedono una
tensione di riferimento, in particolare gli IOB sono suddivisi in 8 banchi
all’interno di ognuno dei quali può essere utilizzata soltanto una tensione di
riferimento.
C.3.3 Risorse di connessione
Le CLB sono connesse tra di loro tramite la GRM16 costituita da matrici di
commutazione locate nell’intersezione dei canali di smistamento orizzontali
e verticali, ogni CLB appartiene ad un VersaBLOCK il quale realizza il
routing locale come illustrato in Figura(C.5).
Figura C.5: VersaBlock
Ogni GRM è connessa tramite 24 linee ad ognuna delle 4 GRM adiacenti, 96 linee esadecimali connettono inoltre ogni GRM con quella che dista
da essa 6 GRM in ogni direzione, lungo i bordi della FPGA c’è poi il VersaRing che rende flessibile il progetto mappato rispetto all’assegnamento dei
pin del dispositivo.
Si hanno delle linee di routing dedicate per i bus 3-state e per i segnali di
riporto verso le CLB verticalmente adiacenti, inoltre ogni CLB è raggiunta
da 4 linee di clock globali, che debbono essere pilotate da opportuni buffer, e
da 24 linee secondarie dedicate allo smistamento di segnali ad ampio fan-out
non necessariamente segnali di clock.
C.3.4 Circuiti di utilità
All’interno della Virtex oltre alle CLB vi sono dei circuiti che implementano
alcune funzionalità molto utilizzate nella progettazione digitale, tra di essi
16
General Routing Matrix
APPENDICE C. LOGICHE PROGRAMMABILI
87
Figura C.6: Clock globale
vi sono le DLL17 , le BlockRAM e gli SRL16.
C.3.4.1 DLL
Le DLL ottimizzano lo smistamento del segnale di clock all’interno delle
grandi FPGA infatti sulla base della differenza tra il clock in ingresso ed il
clock distribuito applicano a quest’ultimo un ritardo opportuno eliminando
pertanto lo skew. La struttura può essere utilizzata sia per raddoppiare o
quadruplicare la frequenza di clock in ingresso alla FPGA18 che per effettuare su di essa delle divisioni del clock per i valori 1, 5 , 2 , 2, 5 , 3 , 4 ,
5 , 8 o 16. Nella Virtex vi sono 4 DLL, una per ogni linea di clock globale
e per ogni buffer globale come illustrato in Figura(C.6).
C.3.4.2 BlockRAM
La BlockRAM è un blocco di memoria SRAM che complementa la RAM
distribuita nelle LUT delle CLB, nella Virtex ogni blocco è alto 4 CLB,
ne consegue che sulla XCV1000 ve ne sono 16 ai bordi di ognuno dei due
lati verticali. Ogni blocco dispone di 4096 celle di memoria alle quali si può
accedere in configurazione singola porta o doppia porta19 . Ogni BlockRAM
può essere anche configurata in sola lettura, per la sua inizializzazione si
possono utilizzare i Core opportuni oppure istanziare la primitiva desiderata
ed assegnare dei valori alle 16 stringhe di inizializzazione ciascuna delle quali
è composta da 64 cifre esadecimali e pertanto copre 256 bit.
17
Delay Locked Loop
la frequenza di clock in ingresso deve essere maggiore di 25MHz
19
le due porte hanno in comune le stesse 4096 celle di memoria
18
APPENDICE C. LOGICHE PROGRAMMABILI
(a) Primitive BlockRAM
88
(b) Stringhe d’inizializzazione
Figura C.7: Configurazione delle BlockRAM
C.3.4.3 SRL16
La LUT presente in ogni LC viene utilizzata come multiplexer 16:1 avente 4 ingressi che seleziona come uscita seriale di un registro a scorrimento
a 16 bit. Una tale struttura consente di creare delle reti di ritardo molto compatte particolarmente adatte all’implementazione della tecnica del
pipelining.
Appendice D
Flusso di progettazione
D.1 Sommario
In questa appendice viene descritto tutto il processo che consente di passare
da una descrizione matematica del sistema che si intende implementare su
FPGA sino alla verifica del suo effettivo funzionamento passando per la
verifica funzionale del VHDL.
D.2 Modello Matematico
La stesura di un modello matematico è di aiuto sia nella verifica della correttezza di una idea che nella comprensione stessa di determinati aspetti
di una tematica che possono inizialmente rimanere poco chiari, soprattutto
i numerosi esempi del Toolbox per le comunicazioni di Matlab oltre alle
funzioni ad alto livello consentono un approccio semplice a tematiche quali
modulazioni e demodulazioni, progettazione di filtri, codifiche e decodifiche.
Sostanziale è anche l’utilità di Matlab laddove si desideri spostare tutta la
complessità del progetto in migliaia di cifre contenute in una RAM, l’allestimento di script parametrici consente infatti di rispondere con rapidità a
modifiche delle specifiche di progetto. Si può passare alla fase successiva del
progetto solo dopo aver realizzato delle simulazioni su dei modelli matematici il più possibile vicini alla reale architettura che si intende implementare,
in tal modo si possono ad esempio dimensionare opportunamente il numero
di bit da assegnare a determinati segnali influenzando cosı̀ la stesura del
modello VHDL.
D.3 Modello VHDL
Anche nella realizzazione del modello VHDL occorre tener conto del passo successivo, l’implementazione, questo in quanto il VHDL è anche un
linguaggio descrittivo pertanto alcuni modelli che potrebbero soddisfare
89
APPENDICE D. FLUSSO DI PROGETTAZIONE
90
una verifica funzionale possono risultare non sintetizzabili, ciò si verifica
ad esempio se all’interno di un processo si richiede che si operi su entrambe
i fronti del clock. La verifica funzionale avviene applicando degli stimoli al
modello e verificando le risposte o in termini di forme d’onda digitali oppure
nel dominio del tempo o della frequenza previa creazione di un file e sua
esportazione in Matlab dove si possono utilizzare delle varianti degli script
che compongono il modello matematico. Quale software per la verifica e la
stesura del modello VHDL si è utilizzato ActiveHDL, esso realizza anche un
ambiente integrato verso diversi tipi di sintetizzatori VHDL e software per
l’implementazione effettiva su FPGA consentendo di uno stesso progetto la
verifica funzionale, RTL1 e back-annotata.
D.4 Sintesi del progetto
La sintesi consente di passare dalla descrizione VHDL del progetto alla
descrizione RTL ossia la sua espressione in termini di registri e logica combinatoria, in questa fase è importante l’utilizzo di un software quale Synplify
che illustra graficamente la corrispondenza tra le due descrizioni ed effettua anche una verifica delle prestazioni in risposta a determinati vincoli
sul timing di alcuni segnali di rilievo tra cui certamente il clock. La Xilinx
distribuisce con i suoi prodotti anche XST un sintetizzatore meno grafico
rispetto a Synplify ma con prestazioni abbastanza simili, esso ha il vantaggio di riconoscere automaticamente le stringhe di inizializzazione delle
BlockRAM2 consentendo pertanto un più veloce passaggio dal VHDL per
la verifica al VHDL per la sintesi.
In questa fase oltre ai vincoli temporali al progetto è bene inserire anche
i vincoli sui pin che si desiderano utilizzare, al fine di ottimizzare il timing
ad esempio nel progetto ThinModulator son stati prescelti tutti pin che si
trovano dal lato della FPGA dove sono dislocate le BlockRAM utilizzate,
con questo semplice accorgimento si risparmia una inutile fatica al software
d’implementazione, occorre però tener presente che non tutti i pin della
FPGA sono disponibili sugli slot che sulla scheda DINI sono adiacenti ad
essa.
D.5 Mappatura
Impostando in Synplify anche il tipo di FPGA sul quale si desidera realizzare il progetto è possibile ottenere la vista tecnologica che mostra come il
progetto RTL e quindi il progetto VHDL viene effettivamente implementato
nel dispositivo, in sostanza in questa fase vengono stabilite quali tipologie
di risorse verranno utilizzate.
1
2
Register Transfer Logic
Appendice(C.3.4.2)
APPENDICE D. FLUSSO DI PROGETTAZIONE
91
D.6 Piazzamento delle risorse
Una volta individuate la tipologia di risorse da utilizzare rimane da effettuare il piazzamento, ossia la selezione nominale delle risorse da utilizzare,
questa fase è in genere abbastanza veloce ed il progettista la può influenzare
mediante il FloorPlanner con il quale si specificano quali siti all’interno della
FPGA debbono ospitare una determinata funzione, in sostanza si impongono dei vincoli fisici che possono essere memorizzati in un file UCF3 o PCF4 .
Il Floorplanner può risultare utile ad esempio per impostare le BlockRAM
da utilizzare per un dato segnale in modo da rendere il più breve possibile
il percorso dalla sua uscita sino al registro ed al pin d’uscita.
D.7 Connessione delle risorse
Questa fase è sicuramente la più lunga e complessa, vengono selezionate
le risorse di connessione5 che consentono di soddisfare al meglio i vincoli temporali impostati nel file UCF garantendo comunque i vincoli fisici
impostati nel file UCF o PCF. Anche per questa fase Xilinx mette a disposizione del progettista un Tool quale FPGA Editor che gli consente di
imporre determinate connessioni o modificare le connessioni effettuate dal
tool automatico.
D.8 Simulazione back-annotata
Dopo aver verificato mediante lo STA6 che i vincoli sul timing sono soddisfatti si può generare il modello di simulazione del progetto ottenuto dopo
il PAR7 , esso è costituito da due file uno con estensione .sdk e l’altro .vhd,
quest’ultimo realizza l’architettura structure del modello VHDL, creando
per essa un TestBench si debbono ottenere a parità di stimoli le stesse
forme d’onda che si ottengono dal modello funzionale.
D.9 Programmazione della FPGA
Se anche la simulazione back-annotata ha avuto esito positivo si passa alla
creazione del file .bit e successivamente del file .hex da inserire nella PROM
che ad ogni riaccensione si occupa di riprogrammare le FPGA presenti
sulla scheda DINI. E’ necessario impostare per il file il formato HEX e non
selezionare l’opzione swap bits. Il Data Stream deve contenere nell’ordine il
3
User Constrain File
Physical Constrain File
5
Appendice(C.3.3)
6
Static Timing Analyzer
7
Place And Route
4
APPENDICE D. FLUSSO DI PROGETTAZIONE
92
file fpga f.bit per la gestione del bus PCI, il file .bit relativo al progetto che
andrà ad occupare la FPGA A e 4 file blank 1.bit che riempiranno le altre
FPGA. Salvando viene automaticamente generato il file .hex, per trasferirlo
nella Prom occorre seguire la seguente procedura sul computer nel quale è
stata installata la scheda DINI:
1. inserire il Jumper J2 sulla scheda e premere il tasto giallo.
2. riavviare il computer.
3. spostare il file .hex generato dal prom formatter nella directory
F:/SchedaDini/AETEST/aetest_nt .
4. far partire il programma AETEST.EXE ed eseguire i diversi passi di
programma:
• selezionare Open Device.
• selezionare 3) Flash menu.
• selezionare 6) Download Hex File.
• scrivere il nome del file .hex e premere invio.
• premere due volte invio quindi uscire.
5. togliere il Jumper J2 e premere il tasto giallo.
6. controllare che si spengano i led rossi superiori.
D.10 Verifica sperimentale
Per la verifica sperimentale vengono utilizzati un pattern-generator che viene caricato con dei vettori di test da applicare alla FPGA in maniera ripetitiva o singola, lo script Matlab CreaSequenzaPatternGenerator.m
(Listato E.2.2) consente di creare in maniera automatica il file di testo con il
quale caricare il pattern-generator, in esso si può anche impostare se il clock
di emissione dei dati debba esser prodotto autonomamente dal patterngenerator oppure sincronizzato ad un clock esterno come è avvenuto per
le prove del modulatore. Le uscite del modulatore vengono invece inviate
all’analizzatore di stati logici, si effettua una singola acquisizione di 64mila
campioni in accordo ai 6mila applicati ed il file ottenuto viene esportato verso Matlab dove un’analisi dello spettro consente di confrontare il risultato
teorico col risultato sperimentale.
Appendice E
Listati Matlab
E.1 NCO
Listato E.1.1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
% Pulizia ambiente Matlab
clear all
;
close all
;
clc
;
% Imposto la frequenza di clock e la frequenza richiesta in uscita dall ’ NCO
[f_out , f_clk] = imposta_frequenze_Q ;
% Imposto le caratteristiche dell ’ NCO
[n_bit_acc, n_bit_cordic, n_bit_dac, n_it_cordic, n_periods] = imposta_NCO_Q ;
% creo l ’ accumulatore il quale contiene i soli valori delle fasi che elaborati
% alla frequenza di clock generano in uscita la frequenza desiderata
super_acc = crea_super_accumulatore_Q(f_out , f_clk , n_bit_acc, n_periods) ;
% le fasi vengono troncate da una rappresentazione con n_bit_acc bits ad una
% rappresentazione con n_bit_cordic bits
super_acc_T = tronca_Q(super_acc , n_bit_cordic) ;
% vengono generati tramite l ’ algoritmo CORDIC i valori del seno e del coseno
% corrispondenti agli angoli presenti in super_acc
[coseno , seno] = crea_coseno_e_seno_Q(super_acc_T, n_bit_cordic, ...
n_bit_dac, n_it_cordic) ;
% grafico un periodo del seno e del coseno calcolati con il CORDIC
figure ;
subplot(2,1,1); stairs(super_acc , coseno) ;
xlim( [ 0 , 6.2832 ] ); ylim( [ -1.01 , +1.01 ] );
subplot(2,1,2); stairs(super_acc , seno );
xlim( [ 0 , 6.2832 ] ); ylim( [ -1.01 , +1.01 ] );
% Rappresentazione nel dominio della frequenza del coseno generato dal CORDIC
visualizza_spettro_e_sfdr_p( coseno , f_clk );
% salva il coseno nel file coseno . dat
fid = fopen(’coseno_Q.dat’,’w’) ;
fprintf(fid,’%20.19f\n’, coseno) ;
fclose(fid)
;
% salva il seno nel file seno . dat
fid = fopen(’seno_Q.dat’,’w’) ;
fprintf(fid,’%20.19f\n’, seno) ;
fclose(fid)
;
Listato E.1.2:
1
2
3
4
5
6
7
8
9
NCO Q.m
% DESCRIPTION : Implementa un NCO quantizzato , ne grafica i risultati sia nel
%
dominio del tempo che della frequenza e valuta l ’ SFDR
Imposta frequenze Q.m
% DESCRIPTION : consente d ’ impostare frequenza di clock e d ’ uscita dall ’ NCO
function [f_out,f_clk]=imposta_frequenze_Q
prompt = {’Frequenza desiderata in uscita (Hz) :’,
’Frequenza di clock (Hz)
:’};
title = ’Caratteristiche NCO’;
lines = 1;
def
= {’41.25e6’,’165e6’};
93
APPENDICE E. LISTATI MATLAB
94
10
11
12
answer = inputdlg(prompt,title,lines,def) ;
f_out = str2double(answer(1));
f_clk = str2double(answer(2));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
% DESCRIPTION : consente d ’ impostare le dimensioni dei bus dell ’ accumulatore ,
%
del Cordic e del DAC
Listato E.1.3:
function [n_bit_acc,n_bit_cordic,n_bit_dac,n_it_cordic,n_periods]=imposta_NCO_Q
= {’N◦◦ di bit accumulatore di fase : ’,
’N◦ di bit per la fase in ingresso al Cordic : ’,
’N◦ di bit per seno e coseno prodotti dal Cordic : ’,
’N di iterazioni del Cordic : ’,
’N◦ di periodi della funzione generata : ’};
title
= ’Caratteristiche NCO’;
lines
= 1;
def
= {’32’,’13’,’12’,’13’,’3000’};
answer
= inputdlg(prompt,title,lines,def) ;
◦
% n di bit in ingresso all ’ accumulatore di fase
n_bit_acc = str2double(answer(1));
% n◦ di bit per la fase in ingresso al Cordic
n_bit_cordic = str2double(answer(2));
% n◦ di bit per seno e coseno prodotti dal Cordic
n_bit_dac = str2double(answer(3));
% n◦ di iterazioni del Cordic
n_it_cordic = str2double(answer(4));
% n◦ di periodi generati
n_periods = str2double(answer(5));
prompt
Listato E.1.4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Imposta NCO Q.m
Crea super accumulatore Q.m
% DESCRIPTION : implementa un accumulatore contenente le fasi che lette
%
alla velocità del clock producono in uscita dal Cordic
%
la frequenza desiderata , può memorizzare più periodi
function super_acc = crea_super_accumulatore_Q(f_out,f_clk,n_bit_acc,n_periods)
% caratteristiche dell ’ accumulatore di fase
% massimo numero di fasi memorizzabili nell ’ accumulatore
range_acc = 2^n_bit_acc ;
% minima frequenza generabile
f_res
= f_clk / range_acc ;
% minima fase memorizzabile
phi_res = 2*pi / range_acc ;
% determina l ’ incremento di fase necessario ad ottenere f_out
f_word = f_out / f_res ;
% incremento di fase che alla frequenza di clock produce in uscita la
%
frequenza desiderata
delta_phi = f_word * phi_res ;
% dimensioni dell ’ accumulatore contenente 1 periodo con le sole fasi che danno
% luogo alla corretta frequenza generata
dim_acc
= round(range_acc/f_word) ;
% massimo numero di fasi memorizzabili nel superaccumulatore
dim_super_acc = dim_acc * n_periods ;
% creazione del superaccumulatore
super_acc = 0 : 1 : dim_super_acc ;
super_acc = delta_phi * super_acc ;
Listato E.1.5:
1
2
3
4
5
6
7
8
Tronca Q.m
% DESCRIPTION : le fasi vengono troncate da una rappresentazione con
%
n_bit_acc bits ad una rappresentazione con n_bit_cordic bits
function super_acc_T = tronca_Q(super_acc , n_bit_cordic)
super_acc = rem(super_acc , 2*pi) ;
new_risoluzione_fase = 2*pi / 2^n_bit_cordic ;
super_acc_T = [fix(super_acc / new_risoluzione_fase)] * new_risoluzione_fase ;
APPENDICE E. LISTATI MATLAB
Listato E.1.6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Crea coseno e seno Q.m
% DESCRIPTION : imposta le caratteristiche del CORDIC e calcola seno e
%
coseno per tutte le fasi presenti nel vettore super_acc
function [coseno , seno] = crea_coseno_e_seno_Q(super_acc_T, n_bit_cordic,...
n_bit_dac, n_it)
% ottengo le dimensioni del super_accumulatore
dim_super_acc_T = size(super_acc_T , 2)
;
% queste inizializzazioni velocizzano l ’ esecuzione del ciclo CORDIC
coseno = zeros(1,dim_super_acc_T) ;
seno = zeros(1,dim_super_acc_T) ;
new_capacity_fase = 2^(n_bit_cordic - 1) ;
new_capacity_ampiezza = 2^(n_bit_dac - 1) ;
for j = 1 : dim_super_acc_T
[coseno(j),seno(j)] = forward_cordic_Q(n_it,super_acc_T(j), ...
new_capacity_fase, new_capacity_ampiezza);
end ;
Listato E.1.7:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
95
Forward cordic Q.m
% DESCRIPTION : esegue N iterazioni dell ’ algoritmo Cordic per calcolare il
%
seno ed il coseno dell ’ angolo Theta che riceve in ingresso ,
%
si parte dal valore 0.607252936517011 per il coseno in modo
%
da evitare la moltiplicazione finale ed evitare l ’ utilizzo
%
di un bit per il solo valore 1 del coseno che del seno .
% m =1 individua le coordinate circolari mentre Nit è il n◦ di iterazioni
function [coseno, seno] = forward_cordic(N_it, Theta, new_capacity_fase,...
new_capacity_ampiezza);
% per semplificare il CORDIC riportiamo l ’ angolo nel primo quadrante ,
% l ’ angolo effettivo potrà poi essere ricavato mediante multcos e multsin
multcos = 1;
multsin = 1;
if ( Theta > pi/2 & Theta < pi)
% l ’ angolo viene riportato dal 2 ◦ quadrante al 1 ◦
Theta = pi/2 - rem(Theta,pi/2);
multcos = -1;
end
if (Theta >= pi & Theta < (3/2)*pi)
% l ’ angolo viene riportato dal 3 ◦ quadrante al 1 ◦
Theta = rem(Theta,pi/2);
multcos = -1;
multsin = -1;
end
if (Theta >= (3/2)*pi & Theta < 2*pi)
% l ’ angolo viene riportato dal 4 ◦ quadrante al 1 ◦
Theta = pi/2 - rem(Theta,pi/2);
multsin = -1;
end
% x ed y sono vettori aventi lunghezza pari al n◦ di iterazioni , contengono
% il coseno ed il seno dell ’ angolo inizialmente è memorizzato in z_attuale
x_attuale = [floor(0.607252936517011* new_capacity_ampiezza)] / ...
new_capacity_ampiezza ;
y_attuale = 0
;
z_attuale = Theta ;
% calcola il seno ed il coseno mediante N_it iterazioni dell ’ algoritmo CORDIC
for i = 0:(N_it-1)
% calcola il fattore moltiplicativo mu per la p_esima iterazione
if z_attuale <= 0
mu = -1;
else
mu = 1;
end
S = 2^(-i) ;
% Standard Cordic iteration , m = 1 per le coordinate circolari
x_succ = x_attuale - [floor((mu * S * y_attuale) * ...
new_capacity_ampiezza)] / new_capacity_ampiezza;
y_succ = y_attuale + [floor((mu * S * x_attuale) * ...
new_capacity_ampiezza)] / new_capacity_ampiezza;
z_succ = z_attuale - [floor((mu * atan( S ))* ...
new_capacity_fase)] / new_capacity_fase;
x_attuale = x_succ ; y_attuale = y_succ ;
z_attuale = z_succ ;
end
% Vengono restituiti il coseno ed il seno opportunamente scalati e riportati
%
nelal giusto quadrante
% new_capacity_ampiezza = 2^(12 - 1) ;
coseno = [floor((multcos * x_attuale)*new_capacity_ampiezza)]/...
new_capacity_ampiezza;
seno = [floor((multsin * y_attuale)*new_capacity_ampiezza)]/...
new_capacity_ampiezza;
APPENDICE E. LISTATI MATLAB
Listato E.1.8:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
% Pulizia ambiente Matlab
clear all
;
close all
;
clc
;
disp(’Valore degli angoli di rotazione a(n)’) ;
% Calcolo dei valori degli a ( n )
for i = 0:1:12
a(i+1) = atan(2^(-i));
end ;
i = [1:1:13] ;
valore = [ i’ , ((a)* 180 / pi)’ ]
a_tot = sum((a)* 180 / pi)
% converto ora gli a ( i ) in complemento a due su 1 bit per il segno e dodici
% per la parte intera
n_bit = 13 ;
a_bin = dec2bin( (2^n_bit .* a(i) )/ (2*pi) )
disp(’Valore dei fattori di scaling k(n)’) ;
% Calcolo il valore degli scalamenti da effettuare ad ogni rotazione
k = sqrt(2) ;
valore = [ 0 , k]
for i = 1:1:13
k = k*sqrt(1 + 2^(-2*i)) ;
valore = [i , k]
end ;
Listato E.1.9:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Calcola rotazioni Cordic.m
% DESCRIPTION : Per ogni iterazione del Cordic calcola l ’ angolo di rotazione
%
e il fattore di scaling
Visualizza spettro e SFDR p.m
% DESCRIPTION : plotta la stima dello spettro e l ’ SFDR
function visualizza_spettro_e_SFDR_p( segnale , f_clk );
% ottengo le dimensioni del vettore segnale
dim_segnale = ( size(segnale , 2) )- 1 ;
% viene calcolata e plottata la densità spettrale di potenza
[Pxx , f] = pmtm(segnale , 8 , 4096 , f_clk) ;
Pxx_dB = 10*log10(Pxx) ;
figure;
plot(f , Pxx_dB - max(Pxx_dB) );
grid ;
xlim([0 f_clk/2]) ;
title(’Power spectral density MultiTaper’);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% viene calcolato e visualizzato il valore dello SFDR
valore_sfdr = calcola_sfdr(Pxx) ;
text(1e7,-50,[’SFDR = ’,num2str(valore_sfdr)],’FontSize’,13);
Listato E.1.10:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Calcola SFDR.m
% DESCRIPTION : calcola l ’ SFDR del vettore passato in ingresso
function [valore_sfdr] = calcola_sfdr(Pxx)
% diff prende il vettore Pxx e costruisce un vettore i cui elementi sono
% la differenza tra elementi adiacenti del vettore Pxx , si ottiene quindi
% un vettore più corto di uno .
der = diff(Pxx);
% dal vettore precedente ottengo il vettore dei segni corrispondenti
signs=sign(der);
% viene inizializzato il ciclo che individua i massimi della PSD
signold = 0 ;
% contiene il valore del segno precedente
signnew = 0 ;
% contiene il valore del segno attuale
p = 1
;
% puntatore per riempire il vettore dei massimi
% Siamo in presenza di un massimo se il segno della derivata nel punto
% precedente è negativo mentre il segno della derivata nel punto attuale
% è positivo , viene scandito il vettore dei segni alla ricerca di questa
% condizione e solo se verificata il massimo viene memorizzato
for k=1:(length(signs)-1)
signold = signs(k) ;
96
APPENDICE E. LISTATI MATLAB
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
signew = signs(k+1) ;
% individua la presenza di un massimo ed eventualmente lo memorizza
if (signold == 1 & signew == -1)
vettore_massimi(p) = Pxx(k+1) ;
p=p+1
;
end
end
% ottengo posizione e valore del massimo assoluto
[max_assoluto , pos] = max(vettore_massimi);
% annullo il valore del massimo assoluto in modo da poter ricercare il
% primo massimo relativo
vettore_massimi(1 , pos) = 0;
% ottengo il valore del 1 ◦ massimo relativo
primo_max_relativo = max(vettore_massimi) ;
% restituisco l ’ SFDR
valore_sfdr = 10.*log10(max_assoluto)-10.*log10(primo_max_relativo);
Listato E.1.11:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
% Pulizia ambiente Matlab
clear all
;
close all
;
clc
;
f_clk
= 165e6 ;
f_out
= 41.25e6 ;
n_bit_acc
= 32
;
n_bit_cordic = 13
;
fw = round( (f_out * 2^n_bit_acc) / f_clk )
fw_hex = dec2hex(fw)
fw_bin = dec2bin(fw)
Listato E.1.12:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Calcola incremento fase NCO.m
% DESCRIPTION : calcola la Frequency Word dell ’ NCO in 3 formati diversi
Visualizza spettro NCO VHDL.m
% DESCRIPTION : visualizza lo spettro del seno prodotto dall ’ NCO VHDL
% Pulizia ambiente Matlab
clear all
;
close all
;
clc
;
% Imposto la frequenza di clock del sistema e quella prodotta dall ’ NCO
f_out = 40e6 ;
f_clk = 165e6 ;
% carica la sequenza filtrata dal file data_out_SRRC_I . dat
fid = fopen(’sine_to_matlab.dat’ , ’r’) ;
seno_vhdl_dec = fscanf(fid,’%f’)
;
fclose(fid)
;
n_bit_dopo_virgola = 11
;
seno_vhdl = seno_vhdl_dec .* 2^(- n_bit_dopo_virgola) ;
% Rappresentazione nel dominio della frequenza del coseno generato dall ’ NCO
visualizza_spettro_e_sfdr_p( seno_vhdl , f_clk );
E.2 Creazione vettori di test
Listato E.2.1:
1
2
3
4
5
6
7
8
9
10
11
CreaVettoriTest.m
% DESCRIPTION : Crea dei vettori NRZ e RZ da applicare al VHDL
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% vengono impostate le caratteristiche del polifase
prompt
= {’N◦ bit Reset attivo :’,
’Interpolazione :’,
’Nome del file sorgente :’ };
title
= ’Impostazione delle caratteristiche dei segnali di test’;
97
APPENDICE E. LISTATI MATLAB
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
lines
= 1;
def
= {’5’ , ’4’, ’bit_tx.dat’ };
answer
= inputdlg(prompt,title,lines,def) ;
n_bit_reset_alto = str2double(answer(1));
interp_rate
= str2double(answer(2));
nome_file_sorgente = char(answer(3));
% legge da un file i bit randomici da trasmettere
fid
= fopen( nome_file_sorgente , ’r’) ;
bit_tx = fscanf(fid,’%f’)
;
fclose(fid)
;
% determinazione del numero di bit di test da applicare
n_bits2tx = length(bit_tx) ;
% creazione del segnale di reset
n_bit_dummy = 4*n_bit_reset_alto ;
reset = zeros(n_bits2tx/2, 1)
;
% vengono aggiunti 10 bit 1 all ’ inizio del segnale di reset più altri 10
reset =[ones(1,n_bit_reset_alto) zeros(1,n_bit_dummy/4) reset’]’;
% salva su file il vettore di test RZ per la componente Q
fid = fopen(’reset.dat’,’w’) ;
fprintf(fid,’%d\n’, reset) ;
fclose(fid)
;
% vengono aggiunti dei bit di inizializzazione alla sequenza da trasmettere
bit_tx =[zeros(1,n_bit_dummy) bit_tx’]’;
% viene creato il vettore dei bit pari e quello dei bit dispari
bit_I = bit_tx(1 : 2 : n_bits2tx + n_bit_dummy)
;
bit_Q = bit_tx(2 : 2 : n_bits2tx + n_bit_dummy)
;
% salva su file il vettore di test RZ per la componente I
fid = fopen(’data_in_SRRCxN_tx_I_rz.dat’,’w’) ;
fprintf(fid,’%d\n’, bit_I)
;
fclose(fid)
;
% salva su file il vettore di test RZ per la componente Q
fid = fopen(’data_in_SRRCxN_tx_Q_rz.dat’,’w’) ;
fprintf(fid,’%d\n’, bit_Q)
;
fclose(fid)
;
% i bit vengono opportunamente mappati
data_in_SRRC_tx_I = -2*bit_I + 1
;
data_in_SRRC_tx_Q = -2*bit_Q + 1
;
% salva su file il vettore di test RZ per la componente I
fid = fopen(’data_in_SRRCxN_tx_I_nrz.dat’,’w’) ;
fprintf(fid,’%+d\n’, data_in_SRRC_tx_I) ;
fclose(fid)
;
% salva su file il vettore di test RZ per la componente Q
fid = fopen(’data_in_SRRCxN_tx_Q_nrz.dat’,’w’) ;
fprintf(fid,’%+d\n’, data_in_SRRC_tx_Q) ;
fclose(fid)
;
% si tiene conto del fatto che rate_sel è codificato su due bit
switch interp_rate
case 3
rate_sel_coded = 0 ;
case 4
rate_sel_coded = 1 ;
case 6
rate_sel_coded = 2 ;
otherwise
error(’Impossible !!! ’)
end
% creazione del segnale rate_sel per l ’ impostazione del data_rate
rate_sel = rate_sel_coded * ones(length(data_in_SRRC_tx_Q) , 1) ;
fid = fopen(strcat(’rate_sel_x’, num2str(interp_rate), ’.dat’),’w’);
fprintf(fid,’%+d\n’, rate_sel) ;
fclose(fid) ;
disp(’Vettori di test generati correttamente.’) ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% DESCRIPTION : Ha in ingresso i file con le sequenze da applicare ai
%
rispettivi canali del pattern generator
Listato E.2.2:
CreaSequenzaPatternGenerator.m
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
fclose(’all’);
% vengono impostate le caratteristiche del polifase
prompt
= {’Tipo
di clock (int , ext) :’,
’N◦◦ di segnali :’,
’N di bit nella sequenza d’’inizializzazione :’,
’Nome file di test da produrre :’ };
title
= ’Caratteristiche dei vettori di test da applicare all’’FPGA’;
lines
= 1;
def
= {’ext’ , ’3’, ’10’ , ’I_testVector_x3.dat’};
answer
= inputdlg(prompt,title,lines,def) ;
tipo_clock = char(answer(1));
n_segnali = str2double(answer(2));
n_bit_start = str2double(answer(3));
nome_file_test = char(answer(4));
98
APPENDICE E. LISTATI MATLAB
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
99
switch lower(tipo_clock)
case ’int’,
% viene richiesto di impostare il valore del clock interno
answer
= inputdlg( {’frequenza del clock interno :’}, ...
’Impostazione del clock interno del Pattern Generator’,1,{’40’}) ;
f_clk
= str2double(answer(1))*10^6;
clk_string = [’FORMAT:CLOCK INTERNAL,’ num2str((1/f_clk)*10^9)’E-9’];
case ’ext’,
% viene richiesto di impostare il range del clock esterno
clk_ext = questdlg(’Selezionare range clock al Pattern Generator:’,...
’Selezione clock esterno’, ...
’f_clk_ext < 50MHz’,’50MHz < f_clk_ext < 100MHz’, ...
’f_clk_ext > 100MHz’,’f_clk_ext < 50MHz’);
% viene ricavata la stringa da settare per il range esterno selezionato
switch clk_ext
case ’f_clk_ext < 50MHz’, ...
clk_string = ’FORMAT:CLOCK EXTERNAL, LEFifty’;
case ’50MHz < f_clk_ext < 100MHz’, ...
clk_string = ’FORMAT:CLOCK EXTERNAL, GTFifty’;
case ’f_clk_ext < 50MHz’, ...
clk_string = ’FORMAT:CLOCK EXTERNAL, GTONe’;
end
end
% si itera per acquisire i valori da assegnare ai diversi canali
for s = 1 : 1 : n_segnali
prompt
= {’Nome del segnale :’,
’N◦ di bit associati (multiplo di 4) :’,
’Nome file sorgente :’ };
title
= [’Caratteristiche del segnale ’ num2str(s) ];
lines
= 1;
def
= {’data_in_SRRCxN_tx_I’,’4’,’data_in_SRRCxN_tx_I_rz.dat’};
answer
= inputdlg(prompt,title,lines,def) ;
label(s) = answer(1);
n_bit_label(s) = str2double(answer(2));
eing_file(s) = answer(3);
end
% vengono caricati da file i segnali di test da applicare
for s = 1 : n_segnali
fid_in(s)
= fopen( char(eing_file(s)) , ’r’) ;
segnale(:,s) = fscanf(fid_in(s),’%d’)
;
end
% viene calcolata la lunghezza della stringa dummy costituita da tutti 0
n_cifreHEX_dummy = num2str( (40 - sum(n_bit_label) )/ 4 );
% scrivo su file le stringhe esadecimali calcolate
fid_out = fopen([tipo_clock ’Clk_’ nome_file_test ],’w’);
% aggiungo al file l ’ intestazione
fprintf(fid_out,’%s\n’, ’ASCII 000000’) ;
fprintf(fid_out,’%s\n’, ’ASCDOWN’) ;
fprintf(fid_out,’%s\n’, ’FORMAT:MODE FULL’) ;
fprintf(fid_out,’%s\n’ , clk_string );
% vengono aggiunte le label
fprintf(fid_out,’%s’, ’LABEL dummy, ’) ;
fprintf(fid_out,’%s\n’, num2str(40 - sum(n_bit_label) ));
for s = 1 : n_segnali
fprintf(fid_out,’%s’, ’LABEL ’) ;
fprintf(fid_out,’%s’, char(label(s)) );
fprintf(fid_out,’%s’, ’, ’) ;
fprintf(fid_out,’%s\n’, num2str( n_bit_label(s) ));
end
fprintf(fid_out,’%s\n’, ’VECTOR’) ;
% si itera su tutta la lunghezza della sequenza d ’ inizializzazione
for row = 1 : 1 : n_bit_start
% viene stampata una riga del vettore di test finale
fprintf(fid_out,strcat(’%0’, n_cifreHEX_dummy ,’d’), 0 );
for s = 1 : n_segnali
fprintf(fid_out,’%s’, ’ ’) ;
fprintf(fid_out, strcat(’%0’, num2str(n_bit_label(s) / 4 ), ’X’), ...
segnale(row,s) );
end
fprintf(fid_out,’%s\n’, ’’) ;
end
fprintf(fid_out,’%s\n’, ’*M’) ;
% si itera su tutta la lunghezza dei vettori di test d ’ ingresso
for row = n_bit_start + 1 : 1 : length(segnale)
% viene stampata una riga del vettore di test finale
fprintf(fid_out,strcat(’%0’, n_cifreHEX_dummy ,’d’), 0 );
for s = 1 : n_segnali
fprintf(fid_out,’%s’, ’ ’) ;
fprintf(fid_out, strcat(’%0’, num2str(n_bit_label(s) / 4 ), ’X’), ...
segnale(row,s) );
end
fprintf(fid_out,’%s\n’, ’’) ;
end
% chiusura dei file contenenti i segnali di test da applicare
for s = 1 : n_segnali
fclose(fid_in(s));
end
% chiusura del file di test da applicare alla FPGA
fclose(fid_out);
% segnalazione di fine creazione del file
sound(wavread(’drumroll.wav’));
APPENDICE E. LISTATI MATLAB
113
100
disp(’Vettore di test generato correttamente.’)
E.3 Polifase
Creazione coefficienti
Listato E.3.1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
CreaCoeffsFreqSamplScaled.m
% DESCRIPTION : calcola e confronta l ’ SRRC Matlab col FreqSampl e
%
condizionatamente scala i coefficienti
% pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% vengono impostate le caratteristiche del polifase
prompt
= {’Frequenza di clock :’,
’Data Rate :’,
’Roll
Off :’,
’N◦◦ coefficienti del FIR desiderati :’,
’N di bit dopo la virgola :’,
’Scaling :’ };
title
= ’Caratteristiche del polifase’;
def
= {’165’, ’110’, ’0.35’, ’19’, ’11’, ’Si’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
symbol_rate
= str2double(answer(2))*10^6 / 2;
roll_off
= str2double(answer(3));
n_coeffs
= str2double(answer(4));
n_bit_dopo_virgola = str2double(answer(5));
Scaling
= answer(6);
% calcolo della interpolazione richiesta
SpS
= f_clk/symbol_rate ;
% carica da file la sequenza dei dati da filtrare
fid = fopen(’data_in_SRRCxN_tx_I_nrz.dat’ , ’r’) ;
data_in_SRRCxN_tx_I = fscanf(fid,’%f’)
;
fclose(fid)
;
% ***************************** MATLAB SRRC **********************************
delay
= 3
;
input_rate_SRRC = symbol_rate ;
output_rate_SRRC = f_clk
;
num_fir = rcosine(input_rate_SRRC,output_rate_SRRC,’fir/sqrt’,roll_off,delay);
% viene filtrata la sequenza d ’ ingresso
data_out_SRRC_matlab = applica_polifase(data_in_SRRCxN_tx_I, SpS , num_fir);
% Power Spectral Density plotting
[Pyy_matlab , f_out] = pwelch(data_out_SRRC_matlab, [] , [] , ’onesided’, ...
length(data_out_SRRC_matlab) - 1 , f_clk) ;
Pyy_matlab_dB = 10*log10(Pyy_matlab) ;
figure ;
plot(f_out , Pyy_matlab_dB - max(Pyy_matlab_dB) );
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’SRRCx’ num2str(SpS) ’ Matlab ’ [num2str(symbol_rate/10^6)] ’ MSpS’]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
figure ; impz(num_fir) ;
% ***************************** FreqSampl SRRC ****************************
Ts
= 1/symbol_rate ; % tempo di simbolo
% risposta in frequenza nell ’ origine del filtro a radice di coseno rialzato
H(1) = sqrt(RaisedCosineResponse(0,roll_off,Ts));
% per la simmetria occorrono solo N /2 campioni della risposta in frequenza
for k = 1 : (n_coeffs - 1)/2,
H(k + 1) = sqrt(RaisedCosineResponse(k*f_clk/n_coeffs, roll_off, Ts));
H(n_coeffs - k + 1) = H(k + 1);
end
% mediante la trasformata di Fourier discreta inversa IDFT viene calcolata la
% risposta all ’ impulso e traslata per garantire la causalità
for n = (-(n_coeffs - 1)/2) : ((n_coeffs - 1)/2)
num_fir_FreqSampl(n + ((n_coeffs - 1)/2) +1) = H(0 + 1);
for m = 1 : (n_coeffs - 1)/2,
num_fir_FreqSampl(n + ((n_coeffs - 1)/2) +1) = ...
num_fir_FreqSampl(n + ((n_coeffs-1)/2)+1) + ...
2*H(m + 1)*cos(2*pi*m*n / n_coeffs);
end
end
% calcolo il fattore di scaling e l ’ aggiunta al nome del file dei coefficienti
if strcmp(Scaling, ’No’)
% i coefficienti non scalati vengono salvati nel file
fid
= fopen(strcat(’SRRCx’ , num2str(SpS) , ’_FreqSampl.dat’) , ’w’);
fprintf(fid,’%20.19f\n’, num_fir_FreqSampl) ;
APPENDICE E. LISTATI MATLAB
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
fclose(fid)
;
% la sequenza dati è applicata all ’ SRRC progettato campionando in frequenza
data_out_SRRC_FreqSampl = ...
applica_polifase(data_in_SRRCxN_tx_I, SpS , num_fir_FreqSampl);
% Power Spectral Density plotting
[Pyy_FreqSampl , f_out] = pwelch(data_out_SRRC_FreqSampl, [] , [] , ...
’onesided’, length(data_out_SRRC_FreqSampl) - 1 , f_clk) ;
Pyy_FreqSampl_dB = 10*log10(Pyy_FreqSampl) ;
figure ;
plot(f_out , Pyy_FreqSampl_dB - max(Pyy_FreqSampl_dB) );
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’SRRCx’ num2str(SpS) ’ FreqSampl ’ ...
[num2str(symbol_rate/10^6)] ’MSpS’]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
figure ; impz(num_fir_FreqSampl) ;
else
% n◦ di FIR che effettivamente costituiscono il polifase
n_fir
= SpS
;
% lunghezza massima dei FIR costituenti il polifase
max_dim_fir = ceil( n_coeffs / n_fir) ;
% creo una matrice che in ogni riga ha i coefficienti
% di uno dei rami del filtro SRRC polifase
% la inizializzo per velocizzare il riempimento
matrice_dei_fir = zeros(n_fir, max_dim_fir) ;
for i = 1 : n_fir
% riempio una riga alla volta
% estraggo i coefficenti dell ’ i_esimo fir
fir_i = num_fir_FreqSampl(i : n_fir : n_coeffs) ;
% figure ; freqz ( fir_i ) ; figure ; impz ( fir_i ) ;
% li copio nella matrice dei fir
matrice_dei_fir(i , 1:length(fir_i) )= fir_i ;
end
% sommo i moduli dei coefficienti di ogni FIR
for i = 1 : n_fir
modulo_i = sum(abs(matrice_dei_fir(i,:)));
vettore_moduli(i) = modulo_i ;
end
% calcolo il fattore di scaling
scaling_factor
= max(vettore_moduli) / 0.95 ;
% viene applicato il fattore di scaling
num_fir_FreqSampl_scaled = num_fir_FreqSampl / scaling_factor ;
% i coefficienti scalati vengono salvati nel file
fid
= fopen(strcat(’SRRCx’,num2str(SpS),’_FreqSampl_scaled.dat’),’w’);
fprintf(fid,’%20.19f\n’, num_fir_FreqSampl_scaled);
fclose(fid);
% la sequenza dati è applicata all ’ SRRC coi coefficienti scalati
data_out_SRRC_FreqSampl_scaled = applica_polifase(data_in_SRRCxN_tx_I, ...
SpS , num_fir_FreqSampl_scaled);
% Power Spectral Density plotting
[Pyy_FreqSampl_scaled , f_out] = pwelch(data_out_SRRC_FreqSampl_scaled,...
[],[], ’onesided’, length(data_out_SRRC_FreqSampl_scaled) - 1 , f_clk);
Pyy_FreqSampl_scaled_dB = 10*log10(Pyy_FreqSampl_scaled) ;
figure; plot(f_out,Pyy_FreqSampl_scaled_dB-max(Pyy_FreqSampl_scaled_dB));
grid ; xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’SRRCx’ num2str(SpS) ’ FreqSampl scaled ’ ...
[num2str(symbol_rate/10^6)] ’ MSpS’ ]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
figure ; impz(num_fir_FreqSampl_scaled) ;
end
Listato E.3.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
101
applica polifase.m
% DESCRIPTION : Applica il filtraggio secondo lo schema polifase
function data_out_polifase=applica_polifase(data_in_polifase,SpS,coefficienti)
% n◦ di FIR che costituiscono il polifase
n_fir
= SpS
;
n_symb
= length(data_in_polifase) ;
◦
% n di coefficienti del filtro da realizzare
n_coefficienti = length(coefficienti)
;
% lunghezza massima dei FIR costituenti il polifase
max_dim_fir = ceil( n_coefficienti / n_fir) ;
% creo una matrice che in ogni riga ha i coefficienti di uno dei rami del
% filtro SRRC polifase
matrice_dei_fir = zeros(n_fir, max_dim_fir) ;
for i = 1 : n_fir
% riempio una riga alla volta
% estraggo i coefficenti dell ’ i_esimo fir
fir_i = coefficienti(i : n_fir : n_coefficienti) ;
% figure ; freqz ( fir_i ) ; figure ; impz ( fir_i ) ;
% li copio nella matrice dei fir
matrice_dei_fir(i , 1:length(fir_i) )= fir_i ;
end
% applico la sequenza dati ad ogni fir
matrice_fir_out = zeros( n_fir , n_symb );
for i = 1 : n_fir
matrice_fir_out(i,:)=filter(matrice_dei_fir(i,:),1,data_in_polifase’);
APPENDICE E. LISTATI MATLAB
102
26
27
28
29
30
31
32
33
34
35
36
end
% creo un vettore con le uscite dal filtro prese come le prenderebbe un
% multiplexer questo vettore in pratica è il risultato dell ’ interpolazione
data_out_polifase = zeros( 1 , n_symb * n_fir );
k = 0 ;
% è un puntatore per scandire il vettore da riempire
for colonna = 1 : n_symb
% considero un simbolo alla volta
for riga = 1 : n_fir
% ed un fir alla volta
k = k + 1 ;
data_out_polifase(k) = matrice_fir_out(riga , colonna);
end
end
1
2
3
4
5
6
7
8
9
10
% DESCRIPTION : Calcola la risposta in frequenza del filtro a coseno rialzato
Listato E.3.3:
RaisedCosineResponse.m
function [y] = RaisedCosineResponse(f,roll_off,T)
if (abs(f) > ((1+roll_off)/(2*T))),
y = 0;
elseif (abs(f) > ((1-roll_off)/(2*T))),
y = (T/2)*(1+cos((pi*T/roll_off)*(abs(f)-(1-roll_off)/(2*T))));
else
y = T;
end
Listato E.3.4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
CreaROM.m
% DESCRIPTION : genera i valori da inserire nella ROM del polifase mediante
%
il costrutto VHDL case oppure il Constant oppure genera un
%
file in formato . coe adatto ad essere fornito ad un Core
%
Xilinx che implementa una BlockRAM
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% vengono impostate le caratteristiche del polifase
prompt
= {’Interpolazione :’,
’N◦ di bit dopo la virgola :’};
title
= ’Caratteristiche del polifase’;
def
= {’3’, ’11’};
answer
= inputdlg(prompt, title, 1, def) ;
SpS
= str2double(answer(1));
n_bit_dopo_virgola = str2double(answer(2));
% scelta tra l ’ implementazione della ROM con il CASE o con una costante
implementazione = questdlg(’Scegliere il codice VHDL da generare ’, ...
’Selezione implementazione ROM’,’Case’,’Costante’,’BlockRAM’,’Case’);
% carico da file il vettore contenente i coefficienti del filtro gia scalati
fid
= fopen(strcat(’SRRCx’,num2str(SpS),’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% n◦ di FIR che costituiscono il polifase
n_fir
= SpS
;
% n◦ di coefficienti del filtro da realizzare
n_coefficienti = length(num_fir)
;
% lunghezza massima dei FIR costituenti il polifase
max_dim_fir = ceil( n_coefficienti / n_fir) ;
% matrice che in ogni riga ha i coefficienti di uno dei rami del filtro SRRC
% inizializzo per velocizzare il riempimento
matrice_dei_fir = zeros(n_fir, max_dim_fir) ;
for i = 1 : n_fir
% riempio una riga alla volta
% estraggo i coefficienti dell ’ i_esimo fir
fir_i = num_fir(i : n_fir : n_coefficienti) ;
% li copio nella matrice dei fir
matrice_dei_fir(i , 1:length(fir_i) )= fir_i ;
end
% indirizzo della ROM da inserire nel file
rom_addr = 0 ;
% viene aperto il file nel quale memorizzare i valori della ROM
fid = fopen(strcat(’SRRCx’,num2str(SpS),’ROM_’,implementazione,’.dat’),’w’);
switch(implementazione)
case ’BlockRAM’,
% viene richiesto se generare una RAM zero padded
RamPadded
= questdlg(’Generare una RAM zero padded ’, ...
’Selezione tipo ROM’,’Si’,’No’,’Si’);
% sintassi per il file . coe da fornire al CORE BlockRAM
fprintf(fid,’%s\n’, ’MEMORY_INITIALIZATION_RADIX=16;’) ;
fprintf(fid,’%s\n’, ’MEMORY_INITIALIZATION_VECTOR=’) ;
APPENDICE E. LISTATI MATLAB
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
103
end
% itero sui fir che costituiscono il polifase
% for i = 1 : n_fir
for i = n_fir : -1 : 1
% viene scritta sul file l ’ istruzione per l ’ assegnamento di default
% per i valori non assegnati
switch(implementazione)
case {’Case’,’Costante’},
% aggiungo al file il commento che indica il numero del FIR
fprintf(fid,’%s\n’, ’ ’) ;
fprintf(fid,’%s’, ’
-- somme per il FIR ’) ;
% fprintf ( fid ,’% s \ n ’, num2str ( i ) ) ;
fprintf(fid,’%s\n’, num2str(n_fir - i)) ;
end
% calcolo le somme da inserire nel file per il filtro i_esimo
% itero su tutte le combinazioni d ’ ingresso
for eing = 0 : 1 : 2^max_dim_fir - 1
% la sequenza d ’ ingresso attuale viene convertita in formato rz +1,0
eing_rz = bitget(eing,max_dim_fir:-1:1) ;
% la sequenza d ’ ingresso attuale viene convertita in formato nrz +1,-1
eing_nrz = ( -2 .* eing_rz )+ 1 ;
% vengono sommati i coefficienti pesati del filtro i_esimo
somma = sum( eing_nrz .* matrice_dei_fir(i,:) ) ;
% le somme vengono convertite in interi e arrotondate in modo da poter
% esser elaborate dal VHDL
somma_int = round( somma * 2^n_bit_dopo_virgola );
% calcolo l ’ intero in complemento a due corrispondente alla somma
if sign(somma_int) == -1 % coefficiente negativo
somma_int_C2 = 2^(n_bit_dopo_virgola+1) - abs(somma_int); %2^ N - | x |
else
% coefficiente positivo
somma_int_C2 = abs(somma_int) ; % | x |
end
% aggiungo al file l ’ i_esimo valore della somma del fir
switch(implementazione)
case ’Case’,
% sintassi per il costrutto VHDL Case
fprintf(fid,’%s’, ’
when ’) ;
fprintf(fid,’%3d’, rom_addr );
fprintf(fid,’%s’, ’ => SRRC_out <= X"’) ;
fprintf(fid,’%03X’, somma_int_C2) ;
fprintf(fid,’%s\n’, ’";’) ;
case ’Costante’,
% sintassi per il costrutto VHDL Constant
fprintf(fid,’%s’, ’
ROM_value’’(X"’) ;
fprintf(fid,’%03X’, somma_int_C2) ;
fprintf(fid,’%s’, ’") , -- ’) ;
fprintf(fid,’%3d’, rom_addr) ;
fprintf(fid,’%s\n’, ’ ’) ;
case ’BlockRAM’,
% sintassi per il file . coe da fornire al CORE BlockRAM
fprintf(fid,’%03X’, somma_int_C2) ;
fprintf(fid,’%s\n’, ’, ’) ;
otherwise, disp(’Unknown method.’)
end
% punto alla successiva cella di memoria da riempire
rom_addr = rom_addr + 1 ;
end
end
% viene scritta sul file l ’ istruzione per l ’ assegnamento di default
% per i valori non assegnati
switch(implementazione)
case ’Case’,
% sintassi per il costrutto VHDL Case
fprintf(fid,’%s\n’, ’
when OTHERS => SRRC_out <= X"000";’);
case ’Costante’,
% sintassi per il costrutto VHDL Constant
fprintf(fid,’%s\n’, ’ ’) ;
fprintf(fid,’%s\n’, ’
OTHERS => ROM_value’’(X"000") );’);
case ’BlockRAM’,
% se la RAM è padded aggiungo degli 0 che la occupano tutta in questo
% modo si possono mettere in un ’ unica RAM tutti e tre gli SRRC
if strcmp(RamPadded , ’Si’)
% per l ’ indirizzamento considero la ROM di dimensioni maggiori
for addr = rom_addr : 1 : 2^(max_dim_fir + round(log2(6))) - 1
fprintf(fid,’%03X’, 0) ;
fprintf(fid,’%s\n’, ’, ’) ;
end
end
fprintf(fid,’%s\n’, ’;’) ;
otherwise, disp(’Unknown method.’)
end
% viene chiuso il file contenente i valori delle somme da porre nella ROM
fclose(fid) ;
disp(’Generato file valori ROM .’) ;
APPENDICE E. LISTATI MATLAB
104
Test VHDL
Listato E.3.5:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
PolyphasePSDVHDLvsPSDMatlab.m
% DESCRIPTION : Confronta lo spettro della sequenza filtrata tramite il VHDL
%
con quello della sequenza filtrata tramite Matlab
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% ************** IMPOSTAZIONE CARATTERISTICHE DEL MODULATORE **************
% vengono impostate le caratteristiche del polifase
prompt
= {’Frequenza di clock :’,
’Symbol Rate :’,
’N◦ di bit dopo la virgola :’};
title
= ’Caratteristiche del polifase’;
def
= {’40’, ’40/3’, ’11’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
symbol_rate
= eval( char(answer(2)) )*10^6;
n_bit_dopo_virgola = str2double(answer(3));
% viene determinato il valore dell ’ interpolazione
SpS
= f_clk / symbol_rate
;
% selezione del file sorgente tra quello prodotto dalla simulazione semplice e
% quello della back - annotata
file_simulazione = questdlg(’Selezionare il nome del file sorgente VHDL :’,...
’Selezione simulazione back-annotata o semplice’,...
’data_out_SRRCxN_tx_I.dat’,’TB_data_out_SRRCxN_tx_I.dat’,...
’data_out_SRRCxN_tx_I.dat’);
% **** VIENE APPLICATA LA DECOMPOSIZIONE POLIFASE MATLAB DI RIFERIMENTO ****
% carica da file la sequenza dei dati da filtrare
fid = fopen(’data_in_SRRCxN_tx_I_nrz.dat’ , ’r’) ;
data_in_SRRCxN_tx_I = fscanf(fid,’%f’)
;
fclose(fid)
;
% carica da file i coefficienti del filtro polifase
fid
= fopen( strcat(’SRRCx’, num2str(SpS), ’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% applica il filtraggio polifase Matlab
data_out_SRRCxN_tx_I = applica_polifase(data_in_SRRCxN_tx_I, SpS , num_fir);
% con il metodo di Welch viene calcolato lo spettro della sequenza filtrata
% mediante il polifase MATLAB
[Pyy_Matlab , f_out] = pwelch(data_out_SRRCxN_tx_I, [] , [] , ’onesided’,...
length(data_out_SRRCxN_tx_I) - 1 , f_clk) ;
Pyy_dB_Matlab = 10*log10(Pyy_Matlab) ;
figure ;
plot(f_out , Pyy_dB_Matlab - max(Pyy_dB_Matlab) );
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’,num2str(SpS),’ Matlab ’,num2str(symbol_rate/1e6),’ MSpS’]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ************** VIENE APPLICATA LA DECOMPOSIZIONE POLIFASE VHDL *********
% carica da file la sequenza filtrata dal polifase VHDL
fid = fopen(file_simulazione , ’r’) ;
% viene scartato il primo numero che è un overflow
string_unuseful = fscanf(fid, ’%s’ , 1);
% vengono letti un numero di campioni pari a quelli del polifase Matlab
data_out_SRRCxN_tx_I_dec=fscanf(fid,’%f’,length(data_in_SRRCxN_tx_I)*SpS);
fclose(fid);
data_out_SRRCxN_tx_I_VHDL=data_out_SRRCxN_tx_I_dec.*2^(- n_bit_dopo_virgola);
% viene prodotta una stringa da aggiungere alla label nel caso di simulazione
% back - annotata
if strcmp(file_simulazione , ’TB_data_out_SRRCxN_tx_I.dat’)
tipo_simulazione = ’B.A. ’ ;
else
tipo_simulazione = ’’ ;
end
% con il metodo di Welch viene calcolato lo spettro della sequenza filtrata
% dal polifase VHDL
[Pyy_VHDL , f_out]=pwelch(data_out_SRRCxN_tx_I_VHDL, [] , [] , ’onesided’,...
length(data_out_SRRCxN_tx_I_VHDL) - 1 , f_clk) ;
Pyy_dB_VHDL = 10*log10(Pyy_VHDL) ;
figure ;
plot(f_out , Pyy_dB_VHDL - max(Pyy_dB_VHDL) , ’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’,num2str(SpS),’ VHDL ’,tipo_simulazione,...
num2str(symbol_rate/1e6),’ MSpS’]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ****************************** CONFRONTO SPETTRALE *********************
% visualizzazione contemporanea dei due spettri
figure ;
plot(f_out,Pyy_dB_Matlab-max(Pyy_dB_Matlab),’-b’,f_out,...
Pyy_dB_VHDL-max(Pyy_dB_VHDL),’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’, num2str(SpS), ’ Matlab ’ , num2str(symbol_rate/1e6),...
APPENDICE E. LISTATI MATLAB
84
85
86
87
88
89
90
91
’ MSpS’ ],[’Out SRRCx’, num2str(SpS),’ VHDL ’,tipo_simulazione,...
num2str(symbol_rate/1e6) , ’ MSpS’ ] );
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ******************************* CONFRONTO TEMPORALE *********************
% n_bits = length ( data_out_SRRCxN_tx_I ) ;
% N_bit_sfasamento = 8 ;
% [ data_out_SRRCxN_tx_I (( N_bit_sfasamento +1) : n_bits ) ’,...
%
data_out_SRRCxN_tx_I_VHDL (1:( n_bits - N_bit_sfasamento ) ) ]
Listato E.3.6: applica polifase.m
vedi listato(E.3.2)
Test FPGA
Listato E.3.7:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
VisualizzaPSDPolifaseVHDLFPGAout.m
% DESCRIPTION : carica da file la sequenza dati filtrata tramite l ’ FPGA e
%
ne fa l ’ analisi spettrale
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% ************ IMPOSTAZIONE CARATTERISTICHE DEL MODULATORE ************
% vengono impostate le caratteristiche del polifase
prompt
= {’Frequenza di clock :’,
’Symbol
Rate :’,
’N◦ di bit dopo la virgola :’,
’N◦ di campioni da considerare :’};
title
= ’Caratteristiche del polifase’;
def
= {’40’, ’40/3’, ’11’, ’18000’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
symbol_rate
= eval( char(answer(2)) )*10^6;
n_bit_dopo_virgola = str2double(answer(3));
n_values
= str2double(answer(4));
% viene determinato il valore dell ’ interpolazione
SpS
= f_clk / symbol_rate
;
% **** VIENE APPLICATA LA DECOMPOSIZIONE POLIFASE MATLAB DI RIFERIMENTO ****
% carica da file la sequenza dei dati da filtrare
fid = fopen(’data_in_SRRCxN_tx_I_nrz.dat’ , ’r’) ;
data_in_SRRCxN_tx_I = fscanf(fid,’%f’)
;
fclose(fid)
;
% carica da file i coefficienti del filtro polifase
fid
= fopen( strcat(’SRRCx’,num2str(SpS),’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% applica il filtraggio polifase Matlab
data_out_SRRCxN_tx_I = applica_polifase(data_in_SRRCxN_tx_I, SpS , num_fir);
% con il metodo di Welch viene calcolato lo spettro della sequenza
%
filtrata dal polifase MATLAB
[Pyy_Matlab , f_out] = pwelch(data_out_SRRCxN_tx_I, [] , [] , ’onesided’,...
length(data_out_SRRCxN_tx_I) - 1 , f_clk) ;
Pyy_dB_Matlab = 10*log10(Pyy_Matlab) ;
figure ;
plot(f_out , Pyy_dB_Matlab - max(Pyy_dB_Matlab) , ’-b’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’, num2str(SpS), ’ Matlab ’ , ...
num2str(symbol_rate/1e6) , ’ MSpS’ ]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ************ ELABORAZIONE DELLA SEQUENZA FILTRATA DALL ’ FPGA *************
% carica la sequenza proveniente dall ’ analizzatore di stati logici
fid = fopen(’file_out.txt’ , ’r’);
% vengono scartate le prime 7 stringhe
string_unuseful = fscanf(fid, ’%s’ , 7);
% viene prelevata la stringa che indica il formato
formato = fscanf(fid, ’%s’ , 1) ;
% viene scartata una stringa con tutti -
105
APPENDICE E. LISTATI MATLAB
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
106
string_unuseful = fscanf(fid, ’%s’ , 1);
% i dati vengono letti dal file nel giusto formato
switch(formato)
case ’Hex’,
value_int_C2 = fscanf(fid, ’%x’ , n_values) ;
case ’Decimal’,
value_int_C2 = fscanf(fid, ’%f’ , n_values) ;
end
fclose(fid)
;
% converte l ’ intero unsigned in complemento a due in un intero con segno
value_int = zeros(n_values,1);
for i = 1 : 1 : n_values
if bitget( value_int_C2(i) , 12) == 1 % valore negativo
% x_C2 = 2^ N - | x |
value_int(i) = -( 2^(n_bit_dopo_virgola+1) - value_int_C2(i) );
else
% coefficiente positivo
value_int(i) = value_int_C2(i) ; % x_C2 = | x |
end
end
% converte da intero con segno a numero reale con segno
value_real = value_int .* 2^(- n_bit_dopo_virgola);
data_out_SRRCxN_tx_I_FPGA = value_real ;
% con il metodo di Welch viene calcolato lo spettro della sequenza
% filtrata dal polifase VHDL e plottata
[Pyy_FPGA , f_out] = pwelch(data_out_SRRCxN_tx_I_FPGA, [] , [] , ...
’onesided’, length(data_out_SRRCxN_tx_I_FPGA) - 1 , f_clk) ;
Pyy_dB_FPGA = 10*log10(Pyy_FPGA) ;
figure ;
plot(f_out , Pyy_dB_FPGA - max(Pyy_dB_FPGA) , ’-r’ );
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’, num2str(SpS), ’ FPGA ’ , ...
num2str(symbol_rate/1e6), ’ MSpS’ ]);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ************** CONFRONTO SPETTRALE *********************************
% visualizzazione contemporanea dei due spettri
figure ;
plot(f_out , Pyy_dB_Matlab - max(Pyy_dB_Matlab) , ’-b’ , f_out , ...
Pyy_dB_FPGA - max(Pyy_dB_FPGA) , ’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-70 0]);
legend([’Out SRRCx’, num2str(SpS), ’ Matlab ’ , num2str(symbol_rate/1e6),...
’ MSpS’ ], [’Out SRRCx’, num2str(SpS), ’ FPGA ’ , ...
num2str(symbol_rate/1e6) , ’ MSpS’ ] );
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% ******************* CONFRONTO TEMPORALE *****************************
% n_bits = length ( data_out_SRRCxN_tx_I ) ;
% N_bit_sfasamento = 8 ;
% [ data_out_SRRCxN_tx_I (( N_bit_sfasamento +1) : n_bits ) ’ , ...
%
data_out_SRRCxN_tx_I_FPGA (1:( n_bits - N_bit_sfasamento ) ) ]
Listato E.3.8: applica polifase.m
vedi listato(E.3.2)
E.4 Modulatore
Tabella e grafico BER
Listato E.4.1:
1
2
3
4
5
6
7
8
CreaTabellaBER.m
% MODULE NAME : CreaTabellaBER . m
% DESCRIPTION : Crea una tabella ed un grafico del BER in funzione di Eb / N0
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% ****************************************************************************
APPENDICE E. LISTATI MATLAB
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
% ****************** IMPOSTAZIONE CARATTERISTICHE MISURA *****************
% ****************************************************************************
prompt
= {’Frequenza di clock :’,
’Data Rate :’,
’Eb/No minimo (dB) :’,
’Eb/No massimo (dB) :’,
’N◦ di ripetizioni per ogni valore di Eb/No :’};
title
= ’Impostazione della simulazione Modem QPSK’;
def
= {’165’, ’110’, ’2’, ’6’, ’2’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
data_rate
= str2double(answer(2))*10^6;
EbNo_dB_min
= str2double(answer(3));
EbNo_dB_max
= str2double(answer(4));
Repeat
= str2double(answer(5));
% messaggio per rassicurare l ’ operatore , qualcosa si muove anche se non sembra
disp(’...elaborazione della tabella dei BER in corso’)
disp(’ ’)
disp(’ ’)
% iterazione sui diversi valori di EbNo_dB
for EbNo_dB = EbNo_dB_min : 1 : EbNo_dB_max
EbNo
= 10.^(EbNo_dB/10)
;
expBER
= 0.5 .* erfc(sqrt(EbNo))
;
expBER_vect(EbNo_dB + 1 - EbNo_dB_min) = expBER
;
n_bits
= 60 * 12 .* round( [1 ./ expBER’] ./ 12)
;
if n_bits < 12000
n_bits = 12000 ;
end
for i = 1:1:Repeat
[n_bit_errati , BER] = calcolaBER(n_bits , EbNo_dB, f_clk , data_rate) ;
temp_BER(i)
= BER
;
end
BER_vect(EbNo_dB + 1 - EbNo_dB_min) = ( sum(temp_BER) )/ Repeat ;
end
% Viene plottato il BER teorico affiancato al BER sperimentale
EbNo_dB = [EbNo_dB_min : 1 : EbNo_dB_max] ;
semilogy(EbNo_dB(:), BER_vect, ’b-’, EbNo_dB(:), expBER_vect, ’r-’);
legend(’BER sperimentale ’,’BER Teorico’,0); grid on;
xlabel(’EbNo (dB)’);
ylabel(’BER’);
disp(’
Eb/No BER teorico BER sperimentale’)
[EbNo_dB’ expBER_vect’ BER_vect’]
Listato E.4.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
107
calcolaBER.m
% MODULE NAME : Modulatore QPSK con applica_polifase SRRC . m
% DESCRIPTION : Funzione per la misura del BER
% DATE
: 19-10-2001
function [n_bit_errati_Matlab , BER_Matlab] = ...
BER_sperimentale(n_bits , EbNo_dB , f_clk , data_rate)
%%%%%%%%%%%%%%%%%%%%%%%% IMPOSTAZIONE MODULATORE %%%%%%%%%%%%%%%%%%%%%%%%%
symbol_rate = data_rate / 2 ;
SpS
= f_clk / symbol_rate ;
n_symb
= n_bits / 2
;
n_sample = n_symb * SpS
;
% crea un vettore di bits randomici
bit_tx = randint(n_bits, 1, [0 1] );
n_bits_tx = length(bit_tx) ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MODULAZIONE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% carica da file i coefficienti del filtro polifase
fid
= fopen( strcat(’SRRCx’, num2str(SpS), ’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% viene creato il vettore dei bit pari e quello dei bit dispari
bit_tx_I = bit_tx(1 : 2 : n_bits_tx)
;
bit_tx_Q = bit_tx(2 : 2 : n_bits_tx)
;
% si passa dalla codifica RZ alla codifica NRZ
data_in_SRRCxN_tx_I_Matlab = -2*bit_tx_I + 1 ;
data_in_SRRCxN_tx_Q_Matlab = -2*bit_tx_Q + 1 ;
% applica il filtraggio polifase Matlab
data_out_SRRCxN_tx_I_Matlab = applica_polifase(data_in_SRRCxN_tx_I_Matlab,...
SpS , num_fir);
data_out_SRRCxN_tx_Q_Matlab = applica_polifase(data_in_SRRCxN_tx_Q_Matlab,...
SpS , num_fir);
% Vengono generati i campioni di seno e coseno considerando f_IF = f_clk / 4
% n◦ di campioni da generare per le portanti
n_sample = length(data_out_SRRCxN_tx_I_Matlab);
% periodo di campionamento
t_clk = 1 / f_clk
;
% istanti di campionamento
APPENDICE E. LISTATI MATLAB
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
t
= 0 : t_clk : (n_sample-1)*t_clk ;
% incrementi di fase
theta = 2*pi*(f_clk/4)*t
;
% generazione di un coseno
coseno = [cos(theta)]
;
% generazione di un seno
seno = [sin(theta)]
;
data_out_QPSK_Mod_Matlab = [coseno .* data_out_SRRCxN_tx_I_Matlab] - ...
[seno .* data_out_SRRCxN_tx_Q_Matlab] ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EFFETTO DEL CANALE %%%%%%%%%%%%%%%%%%%%%%%%%%%
data_in_QPSK_DeMod_Matlab = awgn(data_out_QPSK_Mod_Matlab, ...
EbNo_dB + 10*log10(2) -10*log10(0.5.*SpS), ’measured’, [], ’dB’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEMODULAZIONE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% il segnale in banda traslata viene suddiviso nelle componenti in banda base
data_in_SRRCxN_rx_I_Matlab = coseno .* data_in_QPSK_DeMod_Matlab ;
data_in_SRRCxN_rx_Q_Matlab = -seno .* data_in_QPSK_DeMod_Matlab ;
% applico il filtro adattato ad entrambe le componenti
data_out_SRRCxN_rx_I_Matlab = filter(num_fir, 1 , data_in_SRRCxN_rx_I_Matlab);
data_out_SRRCxN_rx_Q_Matlab = filter(num_fir, 1 , data_in_SRRCxN_rx_Q_Matlab);
data_I_Q_rx_Matlab = ...
[data_out_SRRCxN_rx_I_Matlab’ data_out_SRRCxN_rx_Q_Matlab’];
% viene effettuato uno sfasamento , una decimazione ed applicato il decisore
symbols_Matlab = demodmap(data_I_Q_rx_Matlab , [symbol_rate 1] , f_clk , ...
’qask’ , 4) ;
% l ’ uscita del decisore viene convertita in formato NRZ
for n = 1:length(symbols_Matlab)
switch symbols_Matlab(n)
case 0
symbols_I_Matlab(n) = 1 ; symbols_Q_Matlab(n) = 1 ;
case 1
symbols_I_Matlab(n) = -1 ; symbols_Q_Matlab(n) = 1 ;
case 2
symbols_I_Matlab(n) = 1 ; symbols_Q_Matlab(n) = -1 ;
case 3
symbols_I_Matlab(n) = -1 ; symbols_Q_Matlab(n) = -1 ;
end
end
% si passa dalla codifica NRZ alla codifica RZ
bit_rx_I_Matlab = ( symbols_I_Matlab - 1) / (-2) ;
bit_rx_Q_Matlab = ( symbols_Q_Matlab - 1) / (-2) ;
% dai simboli si riottiene la sequenza composta da bit I e Q alternati
bit_rx_Matlab = 4*ones(1 , n_bits_tx) ;
bit_rx_Matlab(1 : 2 : n_bits_tx) = bit_rx_I_Matlab ;
bit_rx_Matlab(2 : 2 : n_bits_tx) = bit_rx_Q_Matlab ;
% viene compensato lo sfasamento tra la sequenza trasmessa e quella ricevuta
N_bit_sfasamento_Matlab = 12 ;
[n_bit_errati_Matlab BER_Matlab] = ...
biterr(bit_tx(1:(n_bits_tx - N_bit_sfasamento_Matlab)), ...
bit_rx_Matlab( (N_bit_sfasamento_Matlab + 1):n_bits_tx)’) ;
Listato E.4.3: applica polifase.m
vedi listato(E.3.2)
Test VHDL
Listato E.4.4:
1
2
3
4
5
6
7
8
9
10
11
108
QPSKModemPSDeBERVHDLvsMatlab.m
% DESCRIPTION : Confronta lo spettro ed il BER della sequenza modulata
%
tramite il VHDL con quello Matlab
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% ****************************************************************************
% **************** IMPOSTAZIONE CARATTERISTICHE DEL MODEM ****************
% ****************************************************************************
prompt
= {’Frequenza di clock :’,
APPENDICE E. LISTATI MATLAB
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
109
’Symbol
Rate :’,
’N◦ di bit dopo la virgola :’
’Eb/No (dB)’ };
title
= ’Impostazione della simulazione Modem QPSK’;
def
= {’40’, ’40/3’, ’11’, ’6’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
symbol_rate
= eval( char(answer(2)) )*10^6;
n_bit_dopo_virgola = str2double(answer(3));
EbNo_dB
= str2double(answer(4));
EbNo
= 10^(EbNo_dB/10);
% viene determinato il valore dell ’ interpolazione
SpS
= f_clk / symbol_rate
;
% selezione del file sorgente tra quello prodotto dalla simulazione semplice e
%
quello della back - annotata
file_simulazione = questdlg(’Selezionare il nome del file sorgente VHDL :’,...
’Selezione simulazione back-annotata o semplice’, ...
’data_out_QPSK_modulator.dat’,’TB_data_out_QPSK_modulator.dat’,...
’data_out_QPSK_modulator.dat’);
% ****************************************************************************
% ********************* MODEM QPSK MATLAB DI RIFERIMENTO *********************
% ****************************************************************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MODULAZIONE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% carica da file i coefficienti del filtro polifase
fid
= fopen( strcat(’SRRCx’, num2str(SpS), ’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% carica da file la sequenza randomica da modulare
fid
= fopen(’bit_tx.dat’ , ’r’)
;
bit_tx = fscanf(fid,’%f’)
;
fclose(fid)
;
n_bits_tx = length(bit_tx) ;
% viene creato il vettore dei bit pari e quello dei bit dispari
bit_tx_I = bit_tx(1 : 2 : n_bits_tx)
;
bit_tx_Q = bit_tx(2 : 2 : n_bits_tx)
;
% si passa dalla codifica RZ alla codifica NRZ
data_in_SRRCxN_tx_I_Matlab = -2*bit_tx_I + 1 ;
data_in_SRRCxN_tx_Q_Matlab = -2*bit_tx_Q + 1 ;
% applica il filtraggio polifase Matlab
data_out_SRRCxN_tx_I_Matlab = applica_polifase(data_in_SRRCxN_tx_I_Matlab,...
SpS , num_fir);
data_out_SRRCxN_tx_Q_Matlab = applica_polifase(data_in_SRRCxN_tx_Q_Matlab,...
SpS , num_fir);
% Vengono generati i campioni di seno e coseno considerando f_IF = f_clk / 4
% n◦ di campioni da generare per le portanti
n_sample = length(data_out_SRRCxN_tx_I_Matlab);
% periodo di campionamento
t_clk = 1 / f_clk
;
% istanti di campionamento
t
= 0 : t_clk : (n_sample-1)*t_clk ;
% incrementi di fase
theta = 2*pi*(f_clk/4)*t
;
% generazione di un coseno
coseno = [cos(theta)]
;
% generazione di un seno
seno = [sin(theta)]
;
data_out_QPSK_Mod_Matlab = [coseno .* data_out_SRRCxN_tx_I_Matlab] - ...
[seno .* data_out_SRRCxN_tx_Q_Matlab] ;
% spettro del segnale QPSK modulato tramite Matlab
[Pyy_Mod_Matlab , f_out] = pwelch(data_out_QPSK_Mod_Matlab, [] , [] , ...
’onesided’, length(data_out_QPSK_Mod_Matlab) - 1 , f_clk) ;
Pyy_Mod_Matlab_dB = 10*log10(Pyy_Mod_Matlab) ;
figure ;
plot(f_out , Pyy_Mod_Matlab_dB - max(Pyy_Mod_Matlab_dB) );
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]);
legend([’Out QPSK Modem Matlab ’ , num2str(2*symbol_rate/1e6) , ’ MbpS’], 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EFFETTO DEL CANALE %%%%%%%%%%%%%%%%%%%%%%%%%%%
data_in_QPSK_DeMod_Matlab = awgn(data_out_QPSK_Mod_Matlab, ...
EbNo_dB + 10*log10(2) -10*log10(0.5.*SpS), ’measured’, [], ’dB’);
% viene calcolata e plottata la densità spettrale di potenza del segnale
% QPSK affetto da rumore
[Pyy_DeMod_in_Matlab , f_out] = pwelch(data_in_QPSK_DeMod_Matlab,[],[], ...
’onesided’, length(data_in_QPSK_DeMod_Matlab) - 1 , f_clk) ;
Pyy_DeMod_in_Matlab_dB = 10*log10(Pyy_DeMod_in_Matlab) ;
figure ; plot(f_out, Pyy_DeMod_in_Matlab_dB - max(Pyy_DeMod_in_Matlab_dB));
grid ; xlim([0 f_clk/2]);
legend([’In QPSK DeMod Matlab ’ , num2str(2*symbol_rate/1e6) , ’ MbpS’], 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEMODULAZIONE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% il segnale in banda traslata viene suddiviso nelle componenti in banda base
data_in_SRRCxN_rx_I_Matlab = coseno .* data_in_QPSK_DeMod_Matlab ;
data_in_SRRCxN_rx_Q_Matlab = -seno .* data_in_QPSK_DeMod_Matlab ;
% applico il filtro adattato ad entrambe le componenti
data_out_SRRCxN_rx_I_Matlab = filter(num_fir, 1 , data_in_SRRCxN_rx_I_Matlab);
data_out_SRRCxN_rx_Q_Matlab = filter(num_fir, 1 , data_in_SRRCxN_rx_Q_Matlab);
APPENDICE E. LISTATI MATLAB
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
110
% diagramma ad occhio della sequenza I ricevuta
eyediagram(data_out_SRRCxN_rx_I_Matlab(601:2400) , SpS , 1/symbol_rate , 2);
data_I_Q_rx_Matlab = ...
[data_out_SRRCxN_rx_I_Matlab’ data_out_SRRCxN_rx_Q_Matlab’];
% scatterplot del segnale ricevuto
scatterplot(data_I_Q_rx_Matlab , SpS , 2) ;
% viene effettuato uno sfasamento , una decimazione ed applicato il decisore
symbols_Matlab = demodmap(data_I_Q_rx_Matlab , [symbol_rate 1] , f_clk , ...
’qask’ , 4) ;
% l ’ uscita del decisore viene convertita in formato NRZ
for n = 1:length(symbols_Matlab)
switch symbols_Matlab(n)
case 0
symbols_I_Matlab(n) = 1 ; symbols_Q_Matlab(n) = 1 ;
case 1
symbols_I_Matlab(n) = -1 ; symbols_Q_Matlab(n) = 1 ;
case 2
symbols_I_Matlab(n) = 1 ; symbols_Q_Matlab(n) = -1 ;
case 3
symbols_I_Matlab(n) = -1 ; symbols_Q_Matlab(n) = -1 ;
end
end
% si passa dalla codifica NRZ alla codifica RZ
bit_rx_I_Matlab = ( symbols_I_Matlab - 1) / (-2) ;
bit_rx_Q_Matlab = ( symbols_Q_Matlab - 1) / (-2) ;
% dai simboli si riottiene la sequenza composta da bit I e Q alternati
bit_rx_Matlab = 4*ones(1 , n_bits_tx) ;
bit_rx_Matlab(1 : 2 : n_bits_tx) = bit_rx_I_Matlab ;
bit_rx_Matlab(2 : 2 : n_bits_tx) = bit_rx_Q_Matlab ;
% viene compensato lo sfasamento tra la sequenza trasmessa e quella ricevuta
N_bit_sfasamento_Matlab = 12 ;
[n_bit_errati_Matlab BER_Matlab] = ...
biterr(bit_tx(1:(n_bits_tx - N_bit_sfasamento_Matlab)), ...
bit_rx_Matlab( (N_bit_sfasamento_Matlab + 1):n_bits_tx)’) ;
disp([’
Risultati Modulatore Matlab -> Demodulatore Matlab ’]);
disp([’N◦ di bit di sfasamento : ’ num2str(N_bit_sfasamento_Matlab)]);
disp([’N◦ di bit errati
: ’ num2str(n_bit_errati_Matlab)]);
disp([’BER
: ’ num2str(BER_Matlab)]);
% viene calcolato il valore dello sfasamento per il quale si ha la minore BER
for N_bit_sfasamento_Matlab = 1:1:15
[n_bit_errati_Matlab(N_bit_sfasamento_Matlab) ...
BER_Matlab(N_bit_sfasamento_Matlab)] = ...
biterr(bit_tx(1:(n_bits_tx - N_bit_sfasamento_Matlab)) , ...
bit_rx_Matlab( (N_bit_sfasamento_Matlab + 1):n_bits_tx)’);
disp(’ ’);
disp([’N◦ di bit di sfasamento : ’ num2str(N_bit_sfasamento_Matlab)]);
disp([’N◦ di bit errati
: ’ ...
num2str(n_bit_errati_Matlab(N_bit_sfasamento_Matlab))]);
disp([’BER
: ’ ...
num2str(BER_Matlab(N_bit_sfasamento_Matlab))]);
end
[ber_Matlab , N_bit_sfasamento_Matlab] = min(BER_Matlab) ;
disp(’ ’);
disp(’ ’);
disp([’BER minima
: ’ num2str(ber_Matlab)]);
disp([’N◦ di bit errati : ’ ...
num2str(n_bit_errati_Matlab(N_bit_sfasamento_Matlab))]);
disp([’Sfasamento
: ’ num2str(N_bit_sfasamento_Matlab)]);
% Visualizza il valore teorico per il BER
theoretical_BER = 0.5 .* erfc(sqrt(EbNo)) ;
disp(’ ’);
disp([’BER teorico
: ’ num2str(theoretical_BER)]);
disp(’ ’);
% ****************************************************************************
% ************** MODULATORE QPSK VHDL E DEMODULATORE MATLAB ******************
% ****************************************************************************
% carica da file la sequenza modulata tramite il VHDL
fid = fopen(file_simulazione , ’r’) ;
% viene scartato il primo numero che è un overflow
string_unuseful = fscanf(fid, ’%s’ , 1);
% vengono letti un numero di campioni pari a quelli del polifase Matlab
data_out_QPSK_Mod_dec = fscanf(fid,’%f’, ...
length(data_in_SRRCxN_tx_I_Matlab) * SpS);
fclose(fid);
data_out_QPSK_Mod_VHDL = data_out_QPSK_Mod_dec .* 2^(- n_bit_dopo_virgola);
% viene prodotta una stringa da aggiungere alla label nel caso di simulazione
%
back - annotata
if strcmp(file_simulazione , ’TB_data_out_QPSK_modulator.dat’)
tipo_simulazione = ’B.A. ’ ;
else
tipo_simulazione = ’’ ;
end
% spettro del segnale QPSK modulato tramite il VHDL
[Pyy_Mod_VHDL , f_out] = pwelch(data_out_QPSK_Mod_VHDL,[],[],’onesided’,...
length(data_out_QPSK_Mod_VHDL) - 1 , f_clk) ;
Pyy_Mod_VHDL_dB = 10*log10(Pyy_Mod_VHDL) ;
figure ;
plot(f_out , Pyy_Mod_VHDL_dB - max(Pyy_Mod_VHDL_dB) , ’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]);
legend([’Out QPSK Modem VHDL ’ , tipo_simulazione , ...
APPENDICE E. LISTATI MATLAB
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
111
num2str(2*symbol_rate/1e6) , ’ MbpS’], 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EFFETTO DEL CANALE %%%%%%%%%%%%%%%%%%%%%%%%%%%%
data_in_QPSK_DeMod_VHDL = awgn(data_out_QPSK_Mod_VHDL, EbNo_dB +10*log10(2)...
-10*log10(0.5.*SpS), ’measured’, [], ’dB’);
% viene calcolata e plottata la densità spettrale di potenza del segnale QPSK
%
affetto da rumore
[Pyy_DeMod_in_VHDL , f_out] = pwelch(data_in_QPSK_DeMod_VHDL, [] , [] , ...
’onesided’, length(data_in_QPSK_DeMod_VHDL) - 1 , f_clk) ;
Pyy_DeMod_in_VHDL_dB = 10*log10(Pyy_DeMod_in_VHDL) ;
figure ; plot(f_out , Pyy_DeMod_in_VHDL_dB-max(Pyy_DeMod_in_VHDL_dB),’-r’) ;
grid ;
xlim([0 f_clk/2])
;
legend([’In QPSK DeMod VHDL ’ , num2str(2*symbol_rate/1e6) , ’ MbpS’], 3) ;
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEMODULAZIONE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PROCEDURA PER L ’ ALLINEAMENTO DEL DEMODULATORE :
% Il demodulatore è suscettibile a tre variabili :
% quadrante_iniziale , offset_demodmap , N_bit_sfasamento_VHDL
% a ) togliere il commento dal ciclo FOR che itera su N_bit_sfasamento_VHDL
% b ) assegnare quadrante_iniziale = 0
% c ) far partire la simulazione , alla fine si ha il minimo BER e il
%
corrispondente N_bit_sfasamento_VHDL
% d ) fare lo stesso variando per i valori 1, 2, 3 di quadrante_iniziale
% e ) fissando il valore minimo per quadrante_iniziale e N_bit_sfasamento_VHDL
%
ricercare il minimo di offset_demodmap
% Vengono generati i campioni di seno e coseno considerando f_IF = f_clk / 4
quadrante_iniziale = 1 ;
% incrementi di fase
theta_rx_VHDL = 2*pi*(f_clk/4)*t + quadrante_iniziale*pi/2 ;
coseno_rx_VHDL = [cos(theta_rx_VHDL)] ; % generazione del coseno
seno_rx_VHDL = [sin(theta_rx_VHDL)] ; % generazione del seno
% il segnale in banda traslata viene suddiviso nelle componenti in banda base
data_in_SRRCxN_rx_I_VHDL = coseno_rx_VHDL .* data_in_QPSK_DeMod_VHDL’ ;
data_in_SRRCxN_rx_Q_VHDL = -seno_rx_VHDL .* data_in_QPSK_DeMod_VHDL’ ;
% applico il filtro adattato ad entrambe le componenti
data_out_SRRCxN_rx_I_VHDL = filter(num_fir, 1 , data_in_SRRCxN_rx_I_VHDL);
data_out_SRRCxN_rx_Q_VHDL = filter(num_fir, 1 , data_in_SRRCxN_rx_Q_VHDL);
% diagramma ad occhio della sequenza I ricevuta
% eyediagram ( data_out_SRRCxN_rx_I_VHDL (601:2400) , SpS ,1/ symbol_rate ,3,’- r ’) ;
data_I_Q_rx_VHDL = [data_out_SRRCxN_rx_I_VHDL’ data_out_SRRCxN_rx_Q_VHDL’];
% scatterplot del segnale ricevuto
% scatterplot ( data_I_Q_rx_VHDL , SpS , 3) ;
% viene effettuato uno sfasamento , una decimazione ed applicato il decisore
offset_demodmap = 1 ;
symbols_VHDL = demodmap(data_I_Q_rx_VHDL , [symbol_rate offset_demodmap] ,...
f_clk , ’qask’ , 4) ;
% l ’ uscita del decisore viene convertita in formato NRZ
for n = 1:length(symbols_VHDL)
switch symbols_VHDL(n)
case 0
symbols_I_VHDL(n) = 1 ; symbols_Q_VHDL(n) = 1 ;
case 1
symbols_I_VHDL(n) = -1 ; symbols_Q_VHDL(n) = 1 ;
case 2
symbols_I_VHDL(n) = 1 ; symbols_Q_VHDL(n) = -1 ;
case 3
symbols_I_VHDL(n) = -1 ; symbols_Q_VHDL(n) = -1 ;
end
end
% si passa dalla codifica NRZ alla codifica RZ
bit_rx_I_VHDL = ( symbols_I_VHDL - 1) / (-2) ;
bit_rx_Q_VHDL = ( symbols_Q_VHDL - 1) / (-2) ;
% dai simboli si riottiene la sequenza composta da bit I e Q alternati
bit_rx_VHDL = 4*ones(1 , n_bits_tx) ;
bit_rx_VHDL(1 : 2 : n_bits_tx) = bit_rx_I_VHDL ;
bit_rx_VHDL(2 : 2 : n_bits_tx) = bit_rx_Q_VHDL ;
% viene compensato lo sfasamento tra la sequenza trasmessa e quella ricevuta
N_bit_sfasamento_VHDL = 16 ;
[n_bit_errati_VHDL BER_VHDL] = ...
biterr(bit_tx(1:(n_bits_tx - N_bit_sfasamento_VHDL)) , ...
bit_rx_VHDL( (N_bit_sfasamento_VHDL + 1):n_bits_tx)’) ;
disp([’
Risultati Modulatore VHDL -> Demodulatore Matlab ’]);
disp([’N◦ di bit di sfasamento : ’ num2str(N_bit_sfasamento_VHDL)]);
◦
disp([’N di bit errati
: ’ num2str(n_bit_errati_VHDL)]);
disp([’BER
: ’ num2str(BER_VHDL)]);
% viene calcolato il valore dello sfasamento per il quale si ha la minore BER
for N_bit_sfasamento_VHDL = 1:1:30
[n_bit_errati_VHDL(N_bit_sfasamento_VHDL) BER_VHDL(N_bit_sfasamento_VHDL)]...
= biterr(bit_tx(1:(n_bits_tx - N_bit_sfasamento_VHDL)) , ...
bit_rx_VHDL( (N_bit_sfasamento_VHDL + 1):n_bits_tx)’);
disp(’ ’);
disp([’N◦ di bit di sfasamento : ’ num2str(N_bit_sfasamento_VHDL)]);
disp([’N◦ di bit errati
: ’ ...
num2str(n_bit_errati_VHDL(N_bit_sfasamento_VHDL))]);
disp([’BER
: ’ num2str(BER_VHDL(N_bit_sfasamento_VHDL))]);
end
[ber_VHDL , N_bit_sfasamento_VHDL] = min(BER_VHDL) ;
APPENDICE E. LISTATI MATLAB
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
disp(’ ’);
disp(’ ’);
disp([’BER minima
: ’num2str(ber_VHDL)]);
disp([’N◦ di bit errati : ’num2str(n_bit_errati_VHDL(N_bit_sfasamento_VHDL))]);
disp([’Sfasamento
: ’num2str(N_bit_sfasamento_VHDL)]);
% Visualizza il valore teorico per il BER
theoretical_BER = 0.5 .* erfc(sqrt(EbNo)) ;
disp(’ ’);
disp([’BER teorico
: ’ num2str(theoretical_BER)]);
disp(’ ’);
% ****************************************************************************
% *************************** CONFRONTO MODULATORI *************************
% ****************************************************************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CONFRONTO SPETTRALE %%%%%%%%%%%%%%%%%%%%%%%%%%
% visualizzazione contemporanea dei due spettri
figure ;
plot(f_out , Pyy_Mod_Matlab_dB - max(Pyy_Mod_Matlab_dB),...
’-b’ , f_out , Pyy_Mod_VHDL_dB - max(Pyy_Mod_VHDL_dB) , ’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]);
legend([’Out QPSK Modem Matlab ’ , num2str(2*symbol_rate/1e6) , ’ MbpS’ ],...
[’Out QPSK Modem VHDL ’,tipo_simulazione,num2str(2*symbol_rate/1e6),...
’ MbpS’ ] , 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CONFRONTO TEMPORALE %%%%%%%%%%%%%%%%%%%%%%%%%%
% n_bits = 1000;
% N_bit_sfasamento = 7 ;
% [ data_out_QPSK_Mod_Matlab (1:( n_bits - N_bit_sfasamento ) ) ’ , ...
%
data_out_QPSK_Mod_VHDL (( N_bit_sfasamento +1) : n_bits ) ]
Listato E.4.5: applica polifase.m
vedi listato(E.3.2)
Test FPGA
Listato E.4.6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
QPSKModemPSDFPGAvsPSDMatlab.m
% DESCRIPTION : Confronta lo spettro della sequenza modulata tramite il VHDL
%
con quello della sequenza modulata tramite Matlab
% Pulizia ambiente Matlab
clear all ;
close all ;
clc
;
% ************** IMPOSTAZIONE CARATTERISTICHE DEL MODULATORE *************
% vengono impostate le caratteristiche del modulatore
prompt
= {’Frequenza di clock :’,
’Symbol
Rate :’,
’N◦ di bit dopo la virgola :’,
’N◦ di campioni da considerare :’};
title
= ’Caratteristiche del modulatore’;
def
= {’40’, ’40/3’, ’11’,’18000’};
answer
= inputdlg(prompt, title, 1, def) ;
f_clk
= str2double(answer(1))*10^6;
symbol_rate
= eval( char(answer(2)) )*10^6;
n_bit_dopo_virgola = str2double(answer(3));
n_values
= str2double(answer(4));
% viene determinato il valore dell ’ interpolazione
SpS
= f_clk / symbol_rate
;
% ********* VIENE APPLICATA LA MODULAZIONE QPSK MATLAB DI RIFERIMENTO ******
% carica da file la sequenza dei dati da filtrare sul ramo I
fid = fopen(’data_in_SRRCxN_tx_I_nrz.dat’ , ’r’) ;
data_in_SRRCxN_tx_I = fscanf(fid,’%f’)
;
fclose(fid)
;
% carica da file la sequenza dei dati da filtrare sul ramo Q
fid = fopen(’data_in_SRRCxN_tx_Q_nrz.dat’ , ’r’) ;
data_in_SRRCxN_tx_Q = fscanf(fid,’%f’)
;
fclose(fid)
;
112
APPENDICE E. LISTATI MATLAB
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
113
% carica da file i coefficienti del filtro polifase
fid
= fopen( strcat(’SRRCx’, num2str(SpS), ’_FreqSampl_scaled.dat’),’r’);
num_fir = fscanf(fid,’%f’)
;
num_fir = num_fir’
;
fclose(fid)
;
% applica il filtraggio polifase Matlab
data_out_SRRCxN_tx_I = applica_polifase(data_in_SRRCxN_tx_I, SpS , num_fir);
data_out_SRRCxN_tx_Q = applica_polifase(data_in_SRRCxN_tx_Q, SpS , num_fir);
% Vengono generati i campioni di seno e coseno considerando che f_IF = f_clk /4
% n◦ di campioni da generare per le portanti
n_sample = length(data_out_SRRCxN_tx_I) ;
% periodo di campionamento
t_clk = 1 / f_clk
;
% istanti di campionamento
t
= 0 : t_clk : (n_sample-1)*t_clk ;
% incrementi di fase per generare 41.25 MHz
theta = 2*pi*(f_clk/4)*t
;
% generazione del coseno
coseno = [cos(theta)]
;
% generazione del seno
seno = [sin(theta)]
;
data_out_QPSK_modulator = [coseno .* data_out_SRRCxN_tx_I] - ...
[seno .* data_out_SRRCxN_tx_Q] ;
% viene calcolata e plottata la densità spettrale di potenza
[Pyy_Matlab , f_out] = pwelch(data_out_QPSK_modulator, [] , [] , ...
’onesided’, length(data_out_QPSK_modulator) - 1 , f_clk) ;
Pyy_dB_Matlab = 10*log10(Pyy_Matlab) ;
figure ;
plot(f_out , Pyy_dB_Matlab - max(Pyy_dB_Matlab) );
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]);
legend([’Out QPSK Modem Matlab ’ , num2str(2*symbol_rate/1e6) , ’ MbpS’], 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% **************** VIENE APPLICATA LA MODULAZIONE QPSK VHDL **************
% ************ ELABORAZIONE DELLA SEQUENZA FILTRATA DALL ’ FPGA ************
% carica la sequenza proveniente dall ’ analizzatore di stati logici
fid = fopen(’file_out.txt’ , ’r’);
% vengono scartate le prime 7 stringhe
string_unuseful = fscanf(fid, ’%s’ , 7);
% viene prelevata la stringa che indica il formato
formato = fscanf(fid, ’%s’ , 1) ;
% viene scartata una stringa con tutti string_unuseful = fscanf(fid, ’%s’ , 1);
% i dati vengono letti dal file nel giusto formato
switch(formato)
case ’Hex’,
value_int_C2 = fscanf(fid, ’%x’ , n_values) ;
case ’Decimal’,
value_int_C2 = fscanf(fid, ’%f’ , n_values) ;
end
fclose(fid)
;
% converte l ’ intero unsigned in complemento a due in un intero con segno
value_int = zeros(n_values,1);
for i = 1 : 1 : n_values
if bitget( value_int_C2(i) , 12) == 1 % valore negativo
% x_C2 = 2^ N - | x |
value_int(i) = -( 2^(n_bit_dopo_virgola+1) - value_int_C2(i) );
else
% coefficiente positivo
value_int(i) = value_int_C2(i) ; % x_C2 = | x |
end
end
% converte da intero con segno a numero reale con segno
value_real = value_int .* 2^(- n_bit_dopo_virgola);
data_out_QPSK_modulator_FPGA = value_real ;
% viene calcolato lo spettro della sequenza modulata dal VHDL
[Pyy_FPGA , f_out] = pwelch(data_out_QPSK_modulator_FPGA, [] , [] , ...
’onesided’, length(data_out_QPSK_modulator_FPGA) - 1 , f_clk) ;
Pyy_dB_FPGA = 10*log10(Pyy_FPGA) ;
figure ;
plot(f_out , Pyy_dB_FPGA - max(Pyy_dB_FPGA) , ’-r’) ;
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]) ;
legend([’Out QPSK Modem FPGA ’ , num2str(symbol_rate*2/1e6) , ’ MbpS’], 3) ;
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% *************************** CONFRONTO SPETTRALE *************************
% visualizzazione contemporanea dei due spettri
figure ;
plot(f_out , Pyy_dB_Matlab - max(Pyy_dB_Matlab),’-b’,...
f_out , Pyy_dB_FPGA - max(Pyy_dB_FPGA) , ’-r’);
grid ;
xlim([0 f_clk/2]) ;
ylim([-60 0]);
legend([’Out QPSK Modem Matlab ’ , num2str(symbol_rate*2/1e6) , ’ MbpS’ ] , ...
[’Out QPSK Modem FPGA ’ , num2str(symbol_rate*2/1e6) , ’ MbpS’ ] , 3);
xlabel(’Frequency (Hz)’); ylabel(’dB / Hz’);
% **************************** CONFRONTO TEMPORALE ************************
% n_bits = length ( data_out_QPSK_modulator ) ;
% n_bits = 12000;
% N_bit_sfasamento = 0 ;
% [ data_out_QPSK_modulator (1:( n_bits - N_bit_sfasamento ) ) ’ , ...
%
data_out_QPSK_modulator_FPGA (( N_bit_sfasamento +1) : n_bits ) ]
APPENDICE E. LISTATI MATLAB
Listato E.4.7: applica polifase.m
vedi listato(E.3.2)
114
Appendice F
Listati VHDL
Listato F.1.1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
nco.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity NCO is
port(
clear : in STD_LOGIC;
clk
: in STD_LOGIC;
load
: in STD_LOGIC;
freq_word
: in STD_LOGIC_VECTOR (31 downto 0);
coseno : out STD_LOGIC_VECTOR (11 downto 0);
seno
: out STD_LOGIC_VECTOR (11 downto 0)
);
end NCO;
architecture NCO of NCO is
---- Signal declarations used on the diagram ---signal COS
: STD_LOGIC_VECTOR (11 downto 0);
signal CTRL : STD_LOGIC_VECTOR (1 downto 0);
signal CTRL_SEGNO_SENO : STD_LOGIC ;
signal FASE : STD_LOGIC_VECTOR (12 downto 0);
signal SIN
: STD_LOGIC_VECTOR (11 downto 0);
signal THETA : STD_LOGIC_VECTOR (31 downto 0);
signal THETA_TR
: STD_LOGIC_VECTOR (12 downto 0);
---- Component declarations ----component ACCUMULATOR
port (
clear : in STD_LOGIC;
clk
: in STD_LOGIC;
freq_word
: in STD_LOGIC_VECTOR (31 downto 0);
load
: in STD_LOGIC;
theta : inout STD_LOGIC_VECTOR (31 downto 0)
);
end component ;
component CORDIC_PIPELINED_UNROLLED
port (
clk
: in STD_LOGIC;
fase
: in STD_LOGIC_VECTOR (12 downto 0);
coseno : out STD_LOGIC_VECTOR (11 downto 0);
seno
: out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
component COSINE_REBUILD
port (
ctrl
: in STD_LOGIC_VECTOR (1 downto 0);
in_cosine_rebuild : in STD_LOGIC_VECTOR (11 downto 0);
out_cosine_rebuild : out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
component DELAY_13
port (
clk
: in STD_LOGIC;
in_delay_13 : in STD_LOGIC;
out_delay_13 : out STD_LOGIC
);
end component ;
component SINE_REBUILD
port (
ctrl
: in STD_LOGIC;
in_sine_rebuild : in STD_LOGIC_VECTOR (11 downto 0);
out_sine_rebuild : out STD_LOGIC_VECTOR (11 downto 0)
);
115
APPENDICE F. LISTATI VHDL
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
end component ;
component TO_FIRST_QUADRANT
port (
in_tfq : in STD_LOGIC_VECTOR (12 downto 0);
out_tfq : out STD_LOGIC_VECTOR (12 downto 0)
);
end component ;
component TRONCATORE_12
port (
ingresso
: in STD_LOGIC_VECTOR (31 downto 0);
uscita : out STD_LOGIC_VECTOR (12 downto 0)
);
end component ;
begin
---- Component instantiations ---U0 : CORDIC_PIPELINED_UNROLLED
port map(
clk
=> clk,
coseno => cos,
fase
=> fase,
seno
=> sin
);
U1 : DELAY_13
port map(
clk
=> clk,
in_delay_13 => Theta_tr(11),
out_delay_13 => ctrl(0)
);
U2 : DELAY_13
port map(
clk
=> clk,
in_delay_13 => Theta_tr(12),
out_delay_13 => ctrl(1)
);
U3 : DELAY_13
port map(
clk
=> clk,
in_delay_13 => Theta_tr(12),
out_delay_13 => ctrl_segno_seno
);
U5 : TRONCATORE_12
port map(
ingresso
=> Theta,
uscita
=> Theta_tr
);
U4 : ACCUMULATOR
port map(
clear
=> clear,
clk
=> clk,
freq_word
=> freq_word,
load
=> load,
theta
=> Theta
);
U6 : TO_FIRST_QUADRANT
port map(
in_tfq
=> Theta_tr,
out_tfq => fase
);
U8 : COSINE_REBUILD
port map(
ctrl
=> ctrl,
in_cosine_rebuild => cos,
out_cosine_rebuild => coseno
);
U7 : SINE_REBUILD
port map(
ctrl
=> ctrl_segno_seno,
in_sine_rebuild => sin,
out_sine_rebuild => seno
);
end NCO;
Listato F.1.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
116
accumulator.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity accumulator is
port ( freq_word
:
in std_logic_vector(31 downto 0);
clk, load, clear
:
in std_logic;
theta
: inout std_logic_vector(31 downto 0)
);
end accumulator;
architecture acc_arch of accumulator is
APPENDICE F. LISTATI VHDL
signal reg_theta
:
std_logic_vector(31 downto 0);
begin
process(load, clear, freq_word, theta)
begin
if load=’1’ then
reg_theta <= freq_word;
else if clear=’1’ then
reg_theta <= "00000000000000000000000000000000";
else
reg_theta <= freq_word + theta;
end if;
end if;
end process;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
process(clk)
begin
if clk’event and clk=’1’ then
theta <= reg_theta;
end if;
end process;
end acc_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
library IEEE;
use IEEE.std_logic_1164.all;
entity cordic_pipelined_unrolled is
port(
clk
: in STD_LOGIC;
fase
: in STD_LOGIC_VECTOR (12 downto 0);
coseno : out STD_LOGIC_VECTOR (11 downto 0);
seno
: out STD_LOGIC_VECTOR (11 downto 0)
);
end cordic_pipelined_unrolled;
architecture CORDIC_PIPELINED_UNROLLED of cordic_pipelined_unrolled is
signal A_0 : STD_LOGIC_VECTOR (12 downto 0);
signal A_1 : STD_LOGIC_VECTOR (12 downto 0);
signal A_10 : STD_LOGIC_VECTOR (12 downto 0);
signal A_11 : STD_LOGIC_VECTOR (12 downto 0);
signal A_12 : STD_LOGIC_VECTOR (12 downto 0);
signal A_2 : STD_LOGIC_VECTOR (12 downto 0);
signal A_3 : STD_LOGIC_VECTOR (12 downto 0);
signal A_4 : STD_LOGIC_VECTOR (12 downto 0);
signal A_5 : STD_LOGIC_VECTOR (12 downto 0);
signal A_6 : STD_LOGIC_VECTOR (12 downto 0);
signal A_7 : STD_LOGIC_VECTOR (12 downto 0);
signal A_8 : STD_LOGIC_VECTOR (12 downto 0);
signal A_9 : STD_LOGIC_VECTOR (12 downto 0);
signal X0 : STD_LOGIC_VECTOR (11 downto 0);
signal X1 : STD_LOGIC_VECTOR (11 downto 0);
signal X10 : STD_LOGIC_VECTOR (11 downto 0);
signal X11 : STD_LOGIC_VECTOR (11 downto 0);
signal X12 : STD_LOGIC_VECTOR (11 downto 0);
signal X13 : STD_LOGIC_VECTOR (11 downto 0);
signal X2 : STD_LOGIC_VECTOR (11 downto 0);
signal X3 : STD_LOGIC_VECTOR (11 downto 0);
signal X4 : STD_LOGIC_VECTOR (11 downto 0);
signal X5 : STD_LOGIC_VECTOR (11 downto 0);
signal X6 : STD_LOGIC_VECTOR (11 downto 0);
signal X7 : STD_LOGIC_VECTOR (11 downto 0);
signal X8 : STD_LOGIC_VECTOR (11 downto 0);
signal X9 : STD_LOGIC_VECTOR (11 downto 0);
signal Y0 : STD_LOGIC_VECTOR (11 downto 0);
signal Y1 : STD_LOGIC_VECTOR (11 downto 0);
signal Y10 : STD_LOGIC_VECTOR (11 downto 0);
signal Y11 : STD_LOGIC_VECTOR (11 downto 0);
signal Y12 : STD_LOGIC_VECTOR (11 downto 0);
signal Y13 : STD_LOGIC_VECTOR (11 downto 0);
signal Y2 : STD_LOGIC_VECTOR (11 downto 0);
signal Y3 : STD_LOGIC_VECTOR (11 downto 0);
signal Y4 : STD_LOGIC_VECTOR (11 downto 0);
signal Y5 : STD_LOGIC_VECTOR (11 downto 0);
signal Y6 : STD_LOGIC_VECTOR (11 downto 0);
signal Y7 : STD_LOGIC_VECTOR (11 downto 0);
signal Y8 : STD_LOGIC_VECTOR (11 downto 0);
signal Y9 : STD_LOGIC_VECTOR (11 downto 0);
signal Z0 : STD_LOGIC_VECTOR (12 downto 0);
signal Z1 : STD_LOGIC_VECTOR (12 downto 0);
signal Z10 : STD_LOGIC_VECTOR (12 downto 0);
signal Z11 : STD_LOGIC_VECTOR (12 downto 0);
signal Z12 : STD_LOGIC_VECTOR (12 downto 0);
signal Z2 : STD_LOGIC_VECTOR (12 downto 0);
signal Z3 : STD_LOGIC_VECTOR (12 downto 0);
signal Z4 : STD_LOGIC_VECTOR (12 downto 0);
Listato F.1.3:
cordic pipelined unrolled.vhd
117
APPENDICE F. LISTATI VHDL
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
signal Z5 : STD_LOGIC_VECTOR (12 downto 0);
signal Z6 : STD_LOGIC_VECTOR (12 downto 0);
signal Z7 : STD_LOGIC_VECTOR (12 downto 0);
signal Z8 : STD_LOGIC_VECTOR (12 downto 0);
signal Z9 : STD_LOGIC_VECTOR (12 downto 0);
---- Component declarations ----component CORDIC_BASE_J
generic( n : INTEGER );
port (
a_cost_j : in STD_LOGIC_VECTOR (12 downto 0);
clk : in STD_LOGIC;
in_x : in STD_LOGIC_VECTOR (11 downto 0);
in_y : in STD_LOGIC_VECTOR (11 downto 0);
in_z : in STD_LOGIC_VECTOR (12 downto 0);
coseno : out STD_LOGIC_VECTOR (11 downto 0);
fase_j : out STD_LOGIC_VECTOR (12 downto 0);
seno : out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
begin
x0
<= "010011011100" ;
y0
<= "000000000000" ;
a_0 <= "0010000000000" ;
a_1 <= "0001001011100" ;
a_2 <= "0000100111111" ;
a_3 <= "0000010100010" ;
a_4 <= "0000001010001" ;
a_5 <= "0000000101000" ;
a_6 <= "0000000010100" ;
a_7 <= "0000000001010" ;
a_8 <= "0000000000101" ;
a_9 <= "0000000000010" ;
a_10 <= "0000000000001" ;
a_11 <= "0000000000000" ;
a_12 <= "0000000000000" ;
---- Component instantiations ---U0 : CORDIC_BASE_J
generic map ( n => 0 )
port map(
a_cost_j
=> a_0,
clk
=> clk,
coseno => x1,
fase_j => z1,
in_x
=> x0,
in_y
=> y0,
in_z
=> z0,
seno
=> y1
);
U1 : CORDIC_BASE_J
generic map ( n => 1 )
port map(
a_cost_j
=> a_1,
clk
=> clk,
coseno => x2,
fase_j => z2,
in_x
=> x1,
in_y
=> y1,
in_z
=> z1,
seno
=> y2
);
U2 : CORDIC_BASE_J
generic map ( n => 2 )
port map(
a_cost_j
=> a_2,
clk
=> clk,
coseno => x3,
fase_j => z3,
in_x
=> x2,
in_y
=> y2,
in_z
=> z2,
seno
=> y3
);
U3 : CORDIC_BASE_J
generic map ( n => 3 )
port map(
a_cost_j
=> a_3,
clk
=> clk,
coseno => x4,
fase_j => z4,
in_x
=> x3,
in_y
=> y3,
in_z
=> z3,
seno
=> y4
);
U4 : CORDIC_BASE_J
generic map ( n => 4 )
port map(
a_cost_j
=> a_4,
clk
=> clk,
coseno => x5,
fase_j => z5,
in_x
=> x4,
in_y
=> y4,
in_z
=> z4,
118
APPENDICE F. LISTATI VHDL
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
seno
=> y5
);
U5 : CORDIC_BASE_J
generic map ( n => 5 )
port map(
a_cost_j
=> a_5,
clk
=> clk,
coseno => x6,
fase_j => z6,
in_x
=> x5,
in_y
=> y5,
in_z
=> z5,
seno
=> y6
);
U6 : CORDIC_BASE_J
generic map ( n => 6 )
port map(
a_cost_j
=> a_6,
clk
=> clk,
coseno => x7,
fase_j => z7,
in_x
=> x6,
in_y
=> y6,
in_z
=> z6,
seno
=> y7
);
U7 : CORDIC_BASE_J
generic map ( n => 7 )
port map(
a_cost_j
=> a_7,
clk
=> clk,
coseno => x8,
fase_j => z8,
in_x
=> x7,
in_y
=> y7,
in_z
=> z7,
seno
=> y8
);
U8 : CORDIC_BASE_J
generic map ( n => 8 )
port map(
a_cost_j
=> a_8,
clk
=> clk,
coseno => x9,
fase_j => z9,
in_x
=> x8,
in_y
=> y8,
in_z
=> z8,
seno
=> y9
);
U9 : CORDIC_BASE_J
generic map ( n => 9 )
port map(
a_cost_j
=> a_9,
clk
=> clk,
coseno => x10,
fase_j => z10,
in_x
=> x9,
in_y
=> y9,
in_z
=> z9,
seno
=> y10
);
U10 : CORDIC_BASE_J
generic map ( n => 10 )
port map(
a_cost_j
=> a_10,
clk
=> clk,
coseno => x11,
fase_j => z11,
in_x
=> x10,
in_y
=> y10,
in_z
=> z10,
seno
=> y11
);
U11 : CORDIC_BASE_J
generic map ( n => 11 )
port map(
a_cost_j
=> a_11,
clk
=> clk,
coseno => x12,
fase_j => z12,
in_x
=> x11,
in_y
=> y11,
in_z
=> z11,
seno
=> y12
);
U12 : CORDIC_BASE_J
generic map ( n => 12 )
port map(
a_cost_j
=> a_12,
clk
=> clk,
coseno => x13,
in_x
=> x12,
in_y
=> y12,
in_z
=> z12,
119
APPENDICE F. LISTATI VHDL
253
254
255
256
257
258
seno
=> y13
);
z0 <= FASE;
COSENO
<= x13;
SENO
<= y13;
end CORDIC_PIPELINED_UNROLLED;
Listato F.1.4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
120
cordic base j.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity cordic_base_j is
generic( n : integer );
port(
clk
: in STD_LOGIC;
a_cost_j
: in STD_LOGIC_VECTOR (12 downto 0);
in_x
: in STD_LOGIC_VECTOR (11 downto 0);
in_y
: in STD_LOGIC_VECTOR (11 downto 0);
in_z
: in STD_LOGIC_VECTOR (12 downto 0);
coseno : out STD_LOGIC_VECTOR (11 downto 0);
fase_j : out STD_LOGIC_VECTOR (12 downto 0);
seno
: out STD_LOGIC_VECTOR (11 downto 0)
);
end cordic_base_j;
architecture CORDIC_BASE_J of cordic_base_j is
signal SGN
: STD_LOGIC ;
signal SHIFTER_TO_ADDER_X : STD_LOGIC_VECTOR (11 downto 0);
signal SHIFTER_TO_ADDER_Y : STD_LOGIC_VECTOR (11 downto 0);
signal X_OUT_REG
: STD_LOGIC_VECTOR (11 downto 0);
signal Y_OUT_REG
: STD_LOGIC_VECTOR (11 downto 0);
signal Z_OUT_REG
: STD_LOGIC_VECTOR (12 downto 0);
component ADDER_12
port (
in_a
: in STD_LOGIC_VECTOR (11 downto 0);
in_b
: in STD_LOGIC_VECTOR (11 downto 0);
sgn
: in STD_LOGIC;
out_adder_12 : out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
component ADDER_13
port (
in_a
: in STD_LOGIC_VECTOR (12 downto 0);
in_b
: in STD_LOGIC_VECTOR (12 downto 0);
sgn
: in STD_LOGIC;
out_adder_13 : out STD_LOGIC_VECTOR (12 downto 0)
);
end component ;
component REG_12
port (
clk
: in STD_LOGIC;
in_reg_12
: in STD_LOGIC_VECTOR (11 downto 0);
out_reg_12 : out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
component REG_13
port (
clk
: in STD_LOGIC;
in_reg_13
: in STD_LOGIC_VECTOR (12 downto 0);
out_reg_13 : out STD_LOGIC_VECTOR (12 downto 0)
);
end component ;
component SHIFTER
generic( n : INTEGER );
port (
in_shifter : in STD_LOGIC_VECTOR (11 downto 0);
out_shifter : out STD_LOGIC_VECTOR (11 downto 0)
);
end component ;
begin
sgn <= not(z_out_reg(12)) ;
U0 : REG_12
port map(
clk
=> clk,
in_reg_12
=> in_x,
out_reg_12 => x_out_reg
);
U1 : REG_12
port map(
clk
=> clk,
in_reg_12
=> in_y,
out_reg_12 => y_out_reg
);
U2 : SHIFTER
generic map ( n => n )
APPENDICE F. LISTATI VHDL
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
121
port map(
in_shifter => x_out_reg,
out_shifter => shifter_to_adder_y
);
U4 : ADDER_12
port map(
in_a
=> x_out_reg,
in_b
=> shifter_to_adder_x,
out_adder_12 => coseno,
sgn
=> z_out_reg(12)
);
U5 : ADDER_12
port map(
in_a
=> y_out_reg,
in_b
=> shifter_to_adder_y,
out_adder_12 => seno,
sgn
=> sgn
);
U7 : ADDER_13
port map(
in_a
=> z_out_reg,
in_b
=> a_cost_j,
out_adder_13 => fase_j,
sgn
=> z_out_reg(12)
);
U6 : REG_13
port map(
clk => clk,
in_reg_13
=> in_z,
out_reg_13 => z_out_reg
);
U3 : SHIFTER
generic map ( n => n )
port map(
in_shifter => y_out_reg,
out_shifter => shifter_to_adder_x
);
end CORDIC_BASE_J;
Listato F.1.5:
adder 12.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity adder_12 is
port(in_a , in_b
:
in std_logic_vector(11 downto 0);
sgn
:
in std_logic;
out_adder_12
:
out std_logic_vector(11 downto 0));
end adder_12;
architecture adder_12_arch of adder_12 is
begin
process(in_a , in_b , sgn)
begin
if sgn = ’0’ then
out_adder_12 <= in_a - in_b ;
else
out_adder_12 <= in_a + in_b ;
end if;
end process;
end adder_12_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity adder_13 is
port(in_a , in_b
:
in std_logic_vector(12 downto 0);
sgn
:
in std_logic;
out_adder_13 : out std_logic_vector(12 downto 0));
end adder_13;
architecture adder_13_arch of adder_13 is
begin
process(in_a , in_b , sgn)
begin
if sgn = ’0’ then
out_adder_13 <= in_a - in_b ;
else
out_adder_13 <= in_a + in_b ;
end if;
Listato F.1.6:
adder 13.vhd
APPENDICE F. LISTATI VHDL
122
20
21
end process;
end adder_13_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
library ieee;
use ieee.std_logic_1164.all;
entity reg_12 is
port( in_reg_12
:
in std_logic_vector(11 downto 0);
clk
:
in std_logic;
out_reg_12 : out std_logic_vector(11 downto 0));
end reg_12;
architecture reg_12_arch of reg_12 is
begin
process(clk , in_reg_12)
begin
if rising_edge(clk) then
out_reg_12 <= in_reg_12;
end if;
end process;
end reg_12_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
library ieee;
use ieee.std_logic_1164.all;
entity reg_13 is
port( in_reg_13
:
in std_logic_vector(12 downto 0);
clk
:
in std_logic;
out_reg_13 : out std_logic_vector(12 downto 0)
);
end reg_13;
architecture reg_13_arch of reg_13 is
begin
process(clk , in_reg_13)
begin
if rising_edge(clk) then
out_reg_13 <= in_reg_13;
end if;
end process;
end reg_13_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
library ieee;
use ieee.std_logic_1164.all;
entity shifter is
generic(n:integer);
port( in_shifter : in std_logic_vector(11 downto 0);
out_shifter : out std_logic_vector(11 downto 0));
end shifter;
architecture shifter_arch of shifter is
begin
process(in_shifter)
variable i:integer;
begin
if n < 12 then
out_shifter(11-n downto 0) <= in_shifter(11
downto n);
for i in 11 downto (11-n) loop
if in_shifter(11)=’0’ then
out_shifter(11 downto 11-n) <= (
others=>’0’);
else
out_shifter(11 downto 11-n) <= (
others=>’1’);
end if;
end loop;
else out_shifter <= "000000000000" ;
end if;
end process;
Listato F.1.7:
Listato F.1.8:
Listato F.1.9:
17
18
19
20
21
22
23
24
25
26
reg 12.vhd
reg 13.vhd
shifter.vhd
APPENDICE F. LISTATI VHDL
123
27
end shifter_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
21
22
23
24
25
26
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity cosine_rebuild is
port( in_cosine_rebuild
:
in std_logic_vector(11 downto 0);
ctrl
:
in std_logic_vector(1 downto 0);
out_cosine_rebuild :
out std_logic_vector(11 downto 0));
end cosine_rebuild ;
architecture cosine_rebuild_arch of cosine_rebuild is
begin
process(in_cosine_rebuild, ctrl)
variable temp : std_logic_vector(11 downto 0);
begin
temp(11 downto 0) := in_cosine_rebuild ;
case ctrl is
when "00" => null ; -- primo quadrante
when "01" => temp := ("111111111111" xor temp)+1; -- secondo
quadrante
when "10" => temp := ("111111111111" xor temp)+1; -- terzo
quadrante
when "11" => null ; -- quarto quadrante
when others => temp := "000000000000" ;
end case;
out_cosine_rebuild(11 downto 0) <= temp(11 downto 0) ;
end process;
end cosine_rebuild_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity delay_13 is
port (
clk
: in STD_LOGIC;
in_delay_13
: in STD_LOGIC;
out_delay_13 : out STD_LOGIC
);
end delay_13;
architecture delay_13_arch of delay_13 is
signal reg_int : STD_LOGIC_VECTOR(12 downto 0);
begin
process (clk)
begin
if clk’event and clk=’1’ then
reg_int <= in_delay_13 & reg_int(12 downto 1);
end if;
end process;
out_delay_13 <= reg_int(0);
end delay_13_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity sine_rebuild is
port( in_sine_rebuild :
in std_logic_vector(11 downto 0);
ctrl
:
in std_logic;
out_sine_rebuild : out std_logic_vector(11 downto 0));
end sine_rebuild ;
architecture sine_rebuild_arch of sine_rebuild is
begin
process(in_sine_rebuild, ctrl)
variable temp : std_logic_vector(11 downto 0);
begin
temp(11 downto 0) := in_sine_rebuild ;
case ctrl is
Listato F.1.10:
20
Listato F.1.11:
Listato F.1.12:
cosine rebuild.vhd
delay 13.vhd
sine rebuild.vhd
APPENDICE F. LISTATI VHDL
124
18
19
20
21
22
23
24
when ’1’ => temp := ("111111111111" xor temp)+1 ;
when ’0’ => null ;
when others => temp := "000000000000" ;
end case;
out_sine_rebuild(11 downto 0) <= temp(11 downto 0) ;
end process;
end sine_rebuild_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
library ieee;
use ieee.std_logic_1164.all;
entity troncatore_12 is
port( ingresso :
in
std_logic_vector(31 downto 0);
uscita :
out std_logic_vector(12 downto 0)
);
end troncatore_12;
architecture tro_12_arch of troncatore_12 is
begin
process(ingresso)
begin
for i in 0 to 12 loop
uscita(i) <= ingresso(i+19);
end loop;
end process;
end tro_12_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
library IEEE;
use IEEE.std_logic_1164.all;
use work.SRRC_coeffs.all;
entity polyphase_gatedClock is
port(
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
to_SRRC_I
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
clk_sync
: out STD_LOGIC;
poly_out
: out STD_LOGIC_VECTOR(11 downto 0)
);
end polyphase_gatedClock;
architecture polyphase_gatedClock of polyphase_gatedClock is
component rate_adapter
port (
clk
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
Listato F.1.13:
to first quadrant.vhd
entity to_first_quadrant is
port( in_tfq :
in std_logic_vector(12 downto 0);
out_tfq
:
out std_logic_vector(12 downto 0));
end to_first_quadrant;
architecture to_first_quadrant_arch of to_first_quadrant is
begin
process(in_tfq)
variable temp : std_logic_vector(10 downto 0);
begin
temp(10 downto 0) := in_tfq(10 downto 0) ;
case in_tfq(11) is
when ’1’ => temp := ("11111111111" xor temp)+1 ;
when ’0’ => null ;
when others => temp := "00000000000" ;
end case;
out_tfq(10 downto 0) <= temp(10 downto 0) ;
out_tfq(12 downto 11) <= "00" ;
end process;
end to_first_quadrant_arch ;
Listato F.1.14:
Listato F.2.1:
troncatore 12.vhd
polyphase gatedClock.vhd
APPENDICE F. LISTATI VHDL
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
reset : in STD_LOGIC;
clk_div_n
: out STD_LOGIC;
coeffs_to_SRRCxN : out coeffs;
count_n : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component srrc_x_n
port (
SRRCxN_coeffs : in coeffs;
clk
: in STD_LOGIC;
clk_div_n
: in STD_LOGIC;
count_n : in STD_LOGIC_VECTOR(2 downto 0);
in_fir_MSB : in STD_LOGIC;
reset : in STD_LOGIC;
polyphase_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal clk_div_n
: STD_LOGIC;
signal coefficients : coeffs;
signal count_n
: STD_LOGIC_VECTOR (2 downto 0);
begin
U1 : srrc_x_n
port map(
SRRCxN_coeffs => coefficients,
clk => clk,
clk_div_n => clk_div_n,
count_n => count_n,
in_fir_MSB => to_SRRC_I,
polyphase_out => poly_out,
reset => reset
);
U2 : rate_adapter
port map(
clk => clk,
clk_div_n => clk_div_n,
coeffs_to_SRRCxN => coefficients,
count_n => count_n,
rate_sel => rate_sel,
reset => reset
);
clk_sync <= clk;
end polyphase_gatedClock;
Listato F.2.2:
1
2
3
4
5
6
7
8
srrc coeffs.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
package SRRC_coeffs is
subtype coeff is std_logic_vector(11 downto 0);
type coeffs is array(0 to 83) of coeff;
end SRRC_coeffs ;
Listato F.2.3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
125
rate adapter.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use work.SRRC_coeffs.all;
entity rate_adapter is
port(
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
clk_div_n
: out STD_LOGIC;
coeffs_to_SRRCxN : out coeffs;
count_n : out STD_LOGIC_VECTOR(2 downto 0)
);
end rate_adapter;
architecture rate_adapter of rate_adapter is
component coeffs_selector
port (
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
coeffs_SRRC : out coeffs
);
end component;
component counter_divider_3
port (
clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
APPENDICE F. LISTATI VHDL
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
clk_div_3 : out STD_LOGIC;
count_3 : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component counter_divider_4
port (
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
clk_div_4
: out STD_LOGIC;
count_4 : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component counter_divider_6
port (
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
clk_div_6
: out STD_LOGIC;
count_6 : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component selector
port (
clk_div_3
: in STD_LOGIC;
clk_div_4
: in STD_LOGIC;
clk_div_6
: in STD_LOGIC;
count_3 : in STD_LOGIC_VECTOR(2 downto 0);
count_4 : in STD_LOGIC_VECTOR(2 downto 0);
count_6 : in STD_LOGIC_VECTOR(2 downto 0);
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
clk_div_n
: out STD_LOGIC;
count_n : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
signal
signal
signal
signal
signal
signal
signal
SRRC_coefficients : coeffs;
to_clk_div_3 : STD_LOGIC;
to_clk_div_4 : STD_LOGIC;
to_clk_div_6 : STD_LOGIC;
count_4 : STD_LOGIC_VECTOR (2 downto 0);
to_count_3 : STD_LOGIC_VECTOR (2 downto 0);
to_count_6 : STD_LOGIC_VECTOR (2 downto 0);
begin
U0 : counter_divider_3
port map(
clk
=> clk,
clk_div_3
=> to_clk_div_3,
count_3 => to_count_3,
reset => reset
);
U1 : counter_divider_4
port map(
clk
=> clk,
clk_div_4
=> to_clk_div_4,
count_4 => count_4,
reset => reset
);
U2 : counter_divider_6
port map(
clk
=> clk,
clk_div_6
=> to_clk_div_6,
count_6 => to_count_6,
reset => reset
);
U3 : selector
port map(
clk_div_3
=> to_clk_div_3,
clk_div_4
=> to_clk_div_4,
clk_div_6
=> to_clk_div_6,
clk_div_n
=> clk_div_n,
count_3 => to_count_3,
count_4 => count_4,
count_6 => to_count_6,
count_n => count_n,
rate_sel
=> rate_sel
);
U5 : coeffs_selector
port map(
coeffs_SRRC => SRRC_coefficients,
rate_sel
=> rate_sel
);
coeffs_to_SRRCxN <= SRRC_coefficients;
end rate_adapter;
Listato F.2.4:
1
2
3
126
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
coeffs selector.vhd
APPENDICE F. LISTATI VHDL
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use work.SRRC_coeffs.all;
entity coeffs_selector is
port(
rate_sel
: in std_logic_vector(1 downto 0);
coeffs_SRR :
out coeffs
);
end coeffs_selector;
architecture coeffs_selector_arch of coeffs_selector is
-- calcolati con campionamento in frequenza e scalati
Constant coeffs_SRRCx3 : coeffs := coeffs’(
-- coefficienti del FIR 1
coeff’(X"FE0") , -- 1
coeff’(X"020") , -- 1 inverted
coeff’(X"03D") , -- 2
coeff’(X"FC3") , -- 2 inverted
coeff’(X"F94") , -- 3
coeff’(X"06C") , -- 3 inverted
coeff’(X"59E") , -- 4
coeff’(X"A62") , -- 4 inverted
coeff’(X"F94") , -- 5
coeff’(X"06C") , -- 5 inverted
coeff’(X"03D") , -- 6
coeff’(X"FC3") , -- 6 inverted
coeff’(X"FE0") , -- 7
coeff’(X"020") , -- 7 inverted
-- coefficienti del FIR 2
coeff’(X"00A") , -- 8
coeff’(X"FF6") , -- 8 inverted
coeff’(X"FB0") , -- 9
coeff’(X"050") , -- 9 inverted
coeff’(X"1B1") , -- 10
coeff’(X"E4F") , -- 10 inverted
coeff’(X"461") , -- 11
coeff’(X"B9F") , -- 11 inverted
coeff’(X"F19") , -- 12
coeff’(X"0E7") , -- 12 inverted
coeff’(X"046") , -- 13
coeff’(X"FBA") , -- 13 inverted
coeff’(X"000") , -- 14
coeff’(X"000") , -- 14 inverted
-- coefficienti del FIR 3
coeff’(X"046") , -- 15
coeff’(X"FBA") , -- 15 inverted
coeff’(X"F19") , -- 16
coeff’(X"0E7") , -- 16 inverted
coeff’(X"461") , -- 17
coeff’(X"B9F") , -- 17 inverted
coeff’(X"1B1") , -- 18
coeff’(X"E4F") , -- 18 inverted
coeff’(X"FB0") , -- 19
coeff’(X"050") , -- 19 inverted
coeff’(X"00A") , -- 20
coeff’(X"FF6") , -- 20 inverted
coeff’(X"000") , -- 21
coeff’(X"000") , -- 21 inverted
-- coefficienti del FIR 4
coeff’(X"000") , -- 22
coeff’(X"000") , -- 22 inverted
coeff’(X"000") , -- 23
coeff’(X"000") , -- 23 inverted
coeff’(X"000") , -- 24
coeff’(X"000") , -- 24 inverted
coeff’(X"000") , -- 25
coeff’(X"000") , -- 25 inverted
coeff’(X"000") , -- 26
coeff’(X"000") , -- 26 inverted
coeff’(X"000") , -- 27
coeff’(X"000") , -- 27 inverted
coeff’(X"000") , -- 28
coeff’(X"000") , -- 28 inverted
-- coefficienti del FIR 5
coeff’(X"000") , -- 29
coeff’(X"000") , -- 29 inverted
coeff’(X"000") , -- 30
coeff’(X"000") , -- 30 inverted
coeff’(X"000") , -- 31
coeff’(X"000") , -- 31 inverted
coeff’(X"000") , -- 32
coeff’(X"000") , -- 32 inverted
coeff’(X"000") , -- 33
coeff’(X"000") , -- 33 inverted
coeff’(X"000") , -- 34
coeff’(X"000") , -- 34 inverted
coeff’(X"000") , -- 35
coeff’(X"000") , -- 35 inverted
-- coefficienti del FIR 6
coeff’(X"000") , -- 36
coeff’(X"000") , -- 36 inverted
127
APPENDICE F. LISTATI VHDL
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
coeff’(X"000") , -- 37
coeff’(X"000") , -- 37 inverted
coeff’(X"000") , -- 38
coeff’(X"000") , -- 38 inverted
coeff’(X"000") , -- 39
coeff’(X"000") , -- 39 inverted
coeff’(X"000") , -- 40
coeff’(X"000") , -- 40 inverted
coeff’(X"000") , -- 41
coeff’(X"000") , -- 41 inverted
coeff’(X"000") , -- 42
coeff’(X"000") -- 42 inverted
);
-- calcolati con campionamento in frequenza e scalati
Constant coeffs_SRRCx4 : coeffs := coeffs’(
-- coefficienti del FIR 1
coeff’(X"FD8") , -- 1
coeff’(X"028") , -- 1 inverted
coeff’(X"03D") , -- 2
coeff’(X"FC3") , -- 2 inverted
coeff’(X"F9B") , -- 3
coeff’(X"065") , -- 3 inverted
coeff’(X"55D") , -- 4
coeff’(X"AA3") , -- 4 inverted
coeff’(X"F9B") , -- 5
coeff’(X"065") , -- 5 inverted
coeff’(X"03D") , -- 6
coeff’(X"FC3") , -- 6 inverted
coeff’(X"FD8") , -- 7
coeff’(X"028") , -- 7 inverted
-- coefficienti del FIR 2
coeff’(X"FF9") , -- 8
coeff’(X"007") , -- 8 inverted
coeff’(X"FDB") , -- 9
coeff’(X"025") , -- 9 inverted
coeff’(X"104") , -- 10
coeff’(X"EFC") , -- 10 inverted
coeff’(X"4AE") , -- 11
coeff’(X"B52") , -- 11 inverted
coeff’(X"F1A") , -- 12
coeff’(X"0E6") , -- 12 inverted
coeff’(X"051") , -- 13
coeff’(X"FAF") , -- 13 inverted
coeff’(X"000") , -- 14
coeff’(X"000") , -- 14 inverted
-- coefficienti del FIR 3
coeff’(X"02C") , -- 15
coeff’(X"FD4") , -- 15 inverted
coeff’(X"F57") , -- 16
coeff’(X"0A9") , -- 16 inverted
coeff’(X"2F7") , -- 17
coeff’(X"D09") , -- 17 inverted
coeff’(X"2F7") , -- 18
coeff’(X"D09") , -- 18 inverted
coeff’(X"F57") , -- 19
coeff’(X"0A9") , -- 19 inverted
coeff’(X"02C") , -- 20
coeff’(X"FD4") , -- 20 inverted
coeff’(X"000") , -- 21
coeff’(X"000") , -- 21 inverted
-- coefficienti del FIR 4
coeff’(X"051") , -- 22
coeff’(X"FAF") , -- 22 inverted
coeff’(X"F1A") , -- 23
coeff’(X"0E6") , -- 23 inverted
coeff’(X"4AE") , -- 24
coeff’(X"B52") , -- 24 inverted
coeff’(X"104") , -- 25
coeff’(X"EFC") , -- 25 inverted
coeff’(X"FDB") , -- 26
coeff’(X"025") , -- 26 inverted
coeff’(X"FF9") , -- 27
coeff’(X"007") , -- 27 inverted
coeff’(X"000") , -- 28
coeff’(X"000") , -- 28 inverted
-- coefficienti del FIR 5
coeff’(X"000") , -- 29
coeff’(X"000") , -- 29 inverted
coeff’(X"000") , -- 30
coeff’(X"000") , -- 30 inverted
coeff’(X"000") , -- 31
coeff’(X"000") , -- 31 inverted
coeff’(X"000") , -- 32
coeff’(X"000") , -- 32 inverted
coeff’(X"000") , -- 33
coeff’(X"000") , -- 33 inverted
coeff’(X"000") , -- 34
coeff’(X"000") , -- 34 inverted
coeff’(X"000") , -- 35
128
APPENDICE F. LISTATI VHDL
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
coeff’(X"000") , -- 35 inverted
-- coefficienti
coeff’(X"000") , -- 36
coeff’(X"000") , -- 36 inverted
coeff’(X"000") , -- 37
coeff’(X"000") , -- 37 inverted
coeff’(X"000") , -- 38
coeff’(X"000") , -- 38 inverted
coeff’(X"000") , -- 39
coeff’(X"000") , -- 39 inverted
coeff’(X"000") , -- 40
coeff’(X"000") , -- 40 inverted
coeff’(X"000") , -- 41
coeff’(X"000") , -- 41 inverted
coeff’(X"000") , -- 42
coeff’(X"000") -- 42 inverted
);
-- calcolati con campionamento in
Constant coeffs_SRRCx6 : coeffs
-- coefficienti
coeff’(X"FEB") , -- 1
coeff’(X"015") , -- 1 inverted
coeff’(X"04A") , -- 2
coeff’(X"FB6") , -- 2 inverted
coeff’(X"F25") , -- 3
coeff’(X"0DB") , -- 3 inverted
coeff’(X"53D") , -- 4
coeff’(X"AC3") , -- 4 inverted
coeff’(X"06E") , -- 5
coeff’(X"F92") , -- 5 inverted
coeff’(X"00B") , -- 6
coeff’(X"FF5") , -- 6 inverted
coeff’(X"FF5") , -- 7
coeff’(X"00B") , -- 7 inverted
-- coefficienti
coeff’(X"FED") , -- 8
coeff’(X"013") , -- 8 inverted
coeff’(X"03D") , -- 9
coeff’(X"FC3") , -- 9 inverted
coeff’(X"F91") , -- 10
coeff’(X"06F") , -- 10 inverted
coeff’(X"591") , -- 11
coeff’(X"A6F") , -- 11 inverted
coeff’(X"F91") , -- 12
coeff’(X"06F") , -- 12 inverted
coeff’(X"03D") , -- 13
coeff’(X"FC3") , -- 13 inverted
coeff’(X"FED") , -- 14
coeff’(X"013") , -- 14 inverted
-- coefficienti
coeff’(X"FF5") , -- 15
coeff’(X"00B") , -- 15 inverted
coeff’(X"00B") , -- 16
coeff’(X"FF5") , -- 16 inverted
coeff’(X"06E") , -- 17
coeff’(X"F92") , -- 17 inverted
coeff’(X"53D") , -- 18
coeff’(X"AC3") , -- 18 inverted
coeff’(X"F25") , -- 19
coeff’(X"0DB") , -- 19 inverted
coeff’(X"04A") , -- 20
coeff’(X"FB6") , -- 20 inverted
coeff’(X"FEB") , -- 21
coeff’(X"015") , -- 21 inverted
-- coefficienti
coeff’(X"006") , -- 22
coeff’(X"FFA") , -- 22 inverted
coeff’(X"FB9") , -- 23
coeff’(X"047") , -- 23 inverted
coeff’(X"1A7") , -- 24
coeff’(X"E59") , -- 24 inverted
coeff’(X"455") , -- 25
coeff’(X"BAB") , -- 25 inverted
coeff’(X"F1F") , -- 26
coeff’(X"0E1") , -- 26 inverted
coeff’(X"03B") , -- 27
coeff’(X"FC5") , -- 27 inverted
coeff’(X"000") , -- 28
coeff’(X"000") , -- 28 inverted
-- coefficienti
coeff’(X"020") , -- 29
coeff’(X"FE0") , -- 29 inverted
coeff’(X"F5E") , -- 30
coeff’(X"0A2") , -- 30 inverted
coeff’(X"30B") , -- 31
coeff’(X"CF5") , -- 31 inverted
coeff’(X"30B") , -- 32
coeff’(X"CF5") , -- 32 inverted
coeff’(X"F5E") , -- 33
129
del FIR 6
frequenza e scalati
:= coeffs’(
del FIR 1
del FIR 2
del FIR 3
del FIR 4
del FIR 5
APPENDICE F. LISTATI VHDL
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
coeff’(X"0A2")
coeff’(X"020")
coeff’(X"FE0")
coeff’(X"000")
coeff’(X"000")
,
,
,
,
,
-- 33 inverted
-- 34
-- 34 inverted
-- 35
-- 35 inverted
-- coefficienti del FIR 6
, -- 36
, -- 36 inverted
, -- 37
, -- 37 inverted
, -- 38
, -- 38 inverted
, -- 39
, -- 39 inverted
, -- 40
, -- 40 inverted
, -- 41
, -- 41 inverted
, -- 42
-- 42 inverted
coeff’(X"03B")
coeff’(X"FC5")
coeff’(X"F1F")
coeff’(X"0E1")
coeff’(X"455")
coeff’(X"BAB")
coeff’(X"1A7")
coeff’(X"E59")
coeff’(X"FB9")
coeff’(X"047")
coeff’(X"006")
coeff’(X"FFA")
coeff’(X"000")
coeff’(X"000")
);
begin
with rate_sel select
coeffs_SRRC <= coeffs_SRRCx3 when "00" ,
coeffs_SRRCx4 when "01" ,
coeffs_SRRCx6 when others ;
end coeffs_selector_arch;
Listato F.2.5:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
entity counter_divider_3 is
port (
clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
count_3 : out STD_LOGIC_VECTOR (2 downto 0);
clk_div_3
: out STD_LOGIC
);
end counter_divider_3;
architecture counter_divider_3_arch of counter_divider_3 is
signal int_count_3 : STD_LOGIC_VECTOR (1 downto 0) ;
signal count_0_delayed : STD_LOGIC;
begin
process (clk , reset)
begin
if reset=’1’ then
int_count_3 <= "01";
elsif falling_edge(clk) then
int_count_3 <= int_count_3(0)&not(int_count_3(0) or
int_count_3(1));
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
count_0_delayed <= int_count_3(0);
end if;
end process;
clk_div_3 <= int_count_3(0) nor count_0_delayed;
process(clk)
begin
if falling_edge(clk) then
count_3 <= ’0’ & int_count_3;
end if;
end process;
end counter_divider_3_arch;
Listato F.2.6:
1
2
3
4
5
6
7
counter divider 3.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library IEEE;
use IEEE.std_logic_1164.all;
entity counter_divider_4 is
port(
clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
counter divider 4.vhd
130
APPENDICE F. LISTATI VHDL
131
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
clk_div_4 : out STD_LOGIC;
count_4 : out STD_LOGIC_VECTOR(2 downto 0)
);
end counter_divider_4;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
library IEEE;
use IEEE.std_logic_1164.all;
entity fftr is
port (
reset : in std_logic;
clk : in std_logic;
eing : in std_logic;
aus : out std_logic
);
end entity;
architecture fftr_arch of fftr is
signal TEMP_aus: std_logic;
begin
process (clk, reset)
begin
if reset = ’1’ then
TEMP_aus <= ’0’;
elsif falling_edge(clk) then
if eing = ’1’ then
TEMP_aus <= not TEMP_AUS;
else null;
end if;
end if;
end process;
aus <= TEMP_aus;
end architecture;
architecture counter_divider_4 of counter_divider_4 is
component fftr
port (
clk : in STD_LOGIC;
eing : in STD_LOGIC;
reset : in STD_LOGIC;
aus : out STD_LOGIC
);
end component;
constant VCC_CONSTANT : STD_LOGIC := ’1’;
constant GND_CONSTANT : STD_LOGIC := ’0’;
signal GND : STD_LOGIC;
signal VCC : STD_LOGIC;
signal aus : STD_LOGIC_VECTOR (2 downto 0);
begin
U1 : fftr
port map(
aus => aus(1),
clk => clk,
eing => aus(0),
reset => reset
);
U2 : fftr
port map(
aus => aus(0),
clk => clk,
eing => VCC,
reset => reset
);
VCC <= VCC_CONSTANT;
GND <= GND_CONSTANT;
aus(2) <= GND;
clk_div_4 <= aus(1);
count_4 <= aus;
end counter_divider_4;
Listato F.2.7:
Listato F.2.8:
1
2
3
4
5
6
7
8
fftr.vhd
counter divider 6.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity counter_divider_6 is
port (
clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
APPENDICE F. LISTATI VHDL
132
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
count_6 : out STD_LOGIC_VECTOR (2 downto 0);
clk_div_6
: out STD_LOGIC
);
end counter_divider_6;
architecture counter_divider_6_arch of counter_divider_6 is
begin
process (clk, reset)
variable count_6_interno : STD_LOGIC_VECTOR (2 downto 0);
begin
if reset=’1’ then
count_6_interno := "000";
clk_div_6
<= ’0’ ;
else
if falling_edge(clk) then
if count_6_interno < 5 then
count_6_interno := count_6_interno + 1;
if count_6_interno = 3 then
clk_div_6 <= ’1’ ;
else null;
end if ;
else
count_6_interno := "000";
clk_div_6
<= ’0’ ;
end if;
end if;
end if;
count_6 <= count_6_interno;
end process;
end counter_divider_6_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
library ieee;
use ieee.std_logic_1164.all;
1
2
3
4
5
6
7
8
9
10
11
12
13
library IEEE;
use IEEE.std_logic_1164.all;
use work.SRRC_coeffs.all;
entity SRRC_x_N is
port(
SRRCxN_coeffs : in coeffs;
clk
: in STD_LOGIC;
clk_div_n
: in STD_LOGIC;
in_fir_MSB : in STD_LOGIC;
reset
: in STD_LOGIC;
count_n
: in STD_LOGIC_VECTOR(2 downto 0);
polyphase_out : out STD_LOGIC_VECTOR(11 downto 0)
Listato F.2.9:
selector.vhd
entity selector is
port( rate_sel :
in std_logic_vector( 1 downto 0);
clk_div_3 : in std_logic ;
count_3
:
in std_logic_vector(2 downto 0);
clk_div_4 : in std_logic ;
count_4
:
in std_logic_vector(2 downto 0);
clk_div_6 : in std_logic ;
count_6
:
in std_logic_vector(2 downto 0);
clk_div_n : out std_logic ;
count_n
:
out std_logic_vector(2 downto 0)
);
end selector;
architecture selector_arch of selector is
begin
process (rate_sel,clk_div_3,clk_div_4,clk_div_6,count_3,count_4,count_6)
begin
case rate_sel is
when "00" =>
clk_div_n <= clk_div_3 ;
count_n <= count_3 ;
when "01" =>
clk_div_n <= clk_div_4 ;
count_n <= count_4 ;
when "10" =>
clk_div_n <= clk_div_6 ;
count_n <= count_6 ;
when others =>
clk_div_n <= ’X’
;
count_n <= "XXX"
;
end case;
end process;
end selector_arch;
Listato F.2.10:
srrc x n.vhd
APPENDICE F. LISTATI VHDL
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
);
end SRRC_x_N;
architecture SRRC_x_N of SRRC_x_N is
component fir_1
port (
clk_div_n
: in STD_LOGIC;
coeff_a : in coeff;
coeff_b : in coeff;
coeff_c : in coeff;
coeff_d : in coeff;
coeff_e : in coeff;
coeff_f : in coeff;
coeff_g : in coeff;
in_fir_MSB : in STD_LOGIC;
n_coeff_a
: in coeff;
n_coeff_b
: in coeff;
n_coeff_c
: in coeff;
n_coeff_d
: in coeff;
n_coeff_e
: in coeff;
n_coeff_f
: in coeff;
n_coeff_g
: in coeff;
reset : in STD_LOGIC;
out_fir : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component mux_6
port (
clk
: in STD_LOGIC;
count_n : in STD_LOGIC_VECTOR(2 downto 0);
in_0
: in STD_LOGIC_VECTOR(11 downto 0);
in_1
: in STD_LOGIC_VECTOR(11 downto 0);
in_2
: in STD_LOGIC_VECTOR(11 downto 0);
in_3
: in STD_LOGIC_VECTOR(11 downto 0);
in_4
: in STD_LOGIC_VECTOR(11 downto 0);
in_5
: in STD_LOGIC_VECTOR(11 downto 0);
out_mux : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal coeff_1
: coeff;
signal coeff_2
: coeff;
signal coeff_3
: coeff;
signal coeff_4
: coeff;
signal coeff_5
: coeff;
signal coeff_6
: coeff;
signal coeff_7
: coeff;
signal coeff_8
: coeff;
signal coeff_9
: coeff;
signal coeff_10
: coeff;
signal coeff_11
: coeff;
signal coeff_12
: coeff;
signal coeff_13
: coeff;
signal coeff_14
: coeff;
signal coeff_15
: coeff;
signal coeff_16
: coeff;
signal coeff_17
: coeff;
signal coeff_18
: coeff;
signal coeff_19
: coeff;
signal coeff_20
: coeff;
signal coeff_21
: coeff;
signal coeff_22
: coeff;
signal coeff_23
: coeff;
signal coeff_24
: coeff;
signal coeff_25
: coeff;
signal coeff_26
: coeff;
signal coeff_27
: coeff;
signal coeff_28
: coeff;
signal coeff_29
: coeff;
signal coeff_30
: coeff;
signal coeff_31
: coeff;
signal coeff_32
: coeff;
signal coeff_33
: coeff;
signal coeff_34
: coeff;
signal coeff_35
: coeff;
signal coeff_36
: coeff;
signal coeff_37
: coeff;
signal coeff_38
: coeff;
signal coeff_39
: coeff;
signal coeff_40 : coeff;
signal coeff_41 : coeff;
signal coeff_42 : coeff;
signal n_coeff_1 : coeff;
signal n_coeff_2 : coeff;
signal n_coeff_3 : coeff;
signal n_coeff_4 : coeff;
signal n_coeff_5 : coeff;
signal n_coeff_6 : coeff;
signal n_coeff_7 : coeff;
signal n_coeff_8 : coeff;
signal n_coeff_9 : coeff;
signal n_coeff_10 : coeff;
signal n_coeff_11 : coeff;
signal n_coeff_12 : coeff;
signal n_coeff_13 : coeff;
signal n_coeff_14 : coeff;
133
APPENDICE F. LISTATI VHDL
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
n_coeff_15
n_coeff_16
n_coeff_17
n_coeff_18
n_coeff_19
n_coeff_20
n_coeff_21
n_coeff_22
n_coeff_23
n_coeff_24
n_coeff_25
n_coeff_26
n_coeff_27
n_coeff_28
n_coeff_29
n_coeff_30
n_coeff_31
n_coeff_32
n_coeff_33
n_coeff_34
n_coeff_35
n_coeff_36
n_coeff_37
n_coeff_38
n_coeff_39
n_coeff_40
n_coeff_41
n_coeff_42
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
134
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
coeff;
signal to_in_0 : STD_LOGIC_VECTOR (11
signal to_in_1 : STD_LOGIC_VECTOR (11
signal to_in_2 : STD_LOGIC_VECTOR (11
signal to_in_3 : STD_LOGIC_VECTOR (11
signal to_in_4 : STD_LOGIC_VECTOR (11
signal to_in_5 : STD_LOGIC_VECTOR (11
begin
coeff_1
<= SRRCxN_coeffs(0);
n_coeff_1 <= SRRCxN_coeffs(1);
coeff_2
<= SRRCxN_coeffs(2);
n_coeff_2 <= SRRCxN_coeffs(3);
coeff_3
<= SRRCxN_coeffs(4);
n_coeff_3 <= SRRCxN_coeffs(5);
coeff_4
<= SRRCxN_coeffs(6);
n_coeff_4 <= SRRCxN_coeffs(7);
coeff_5
<= SRRCxN_coeffs(8);
n_coeff_5 <= SRRCxN_coeffs(9);
coeff_6
<= SRRCxN_coeffs(10);
n_coeff_6 <= SRRCxN_coeffs(11);
coeff_7
<= SRRCxN_coeffs(12);
n_coeff_7 <= SRRCxN_coeffs(13);
coeff_8
<= SRRCxN_coeffs(14);
n_coeff_8 <= SRRCxN_coeffs(15);
coeff_9
<= SRRCxN_coeffs(16);
n_coeff_9 <= SRRCxN_coeffs(17);
coeff_10
<= SRRCxN_coeffs(18);
n_coeff_10 <= SRRCxN_coeffs(19);
coeff_11
<= SRRCxN_coeffs(20);
n_coeff_11 <= SRRCxN_coeffs(21);
coeff_12
<= SRRCxN_coeffs(22);
n_coeff_12 <= SRRCxN_coeffs(23);
coeff_13
<= SRRCxN_coeffs(24);
n_coeff_13 <= SRRCxN_coeffs(25);
coeff_14
<= SRRCxN_coeffs(26);
n_coeff_14 <= SRRCxN_coeffs(27);
coeff_15
<= SRRCxN_coeffs(28);
n_coeff_15 <= SRRCxN_coeffs(29);
coeff_16
<= SRRCxN_coeffs(30);
n_coeff_16 <= SRRCxN_coeffs(31);
coeff_17
<= SRRCxN_coeffs(32);
n_coeff_17 <= SRRCxN_coeffs(33);
coeff_18
<= SRRCxN_coeffs(34);
n_coeff_18 <= SRRCxN_coeffs(35);
coeff_19
<= SRRCxN_coeffs(36);
n_coeff_19 <= SRRCxN_coeffs(37);
coeff_20
<= SRRCxN_coeffs(38);
n_coeff_20 <= SRRCxN_coeffs(39);
coeff_21
<= SRRCxN_coeffs(40);
n_coeff_21 <= SRRCxN_coeffs(41);
coeff_22
<= SRRCxN_coeffs(42);
n_coeff_22 <= SRRCxN_coeffs(43);
coeff_23
<= SRRCxN_coeffs(44);
n_coeff_23 <= SRRCxN_coeffs(45);
coeff_24
<= SRRCxN_coeffs(46);
n_coeff_24 <= SRRCxN_coeffs(47);
coeff_25
<= SRRCxN_coeffs(48);
n_coeff_25 <= SRRCxN_coeffs(49);
coeff_26
<= SRRCxN_coeffs(50);
n_coeff_26 <= SRRCxN_coeffs(51);
coeff_27
<= SRRCxN_coeffs(52);
n_coeff_27 <= SRRCxN_coeffs(53);
downto
downto
downto
downto
downto
downto
0);
0);
0);
0);
0);
0);
APPENDICE F. LISTATI VHDL
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
coeff_28
<= SRRCxN_coeffs(54);
n_coeff_28 <= SRRCxN_coeffs(55);
coeff_29
<= SRRCxN_coeffs(56);
n_coeff_29 <= SRRCxN_coeffs(57);
coeff_30
<= SRRCxN_coeffs(58);
n_coeff_30 <= SRRCxN_coeffs(59);
coeff_31
<= SRRCxN_coeffs(60);
n_coeff_31 <= SRRCxN_coeffs(61);
coeff_32
<= SRRCxN_coeffs(62);
n_coeff_32 <= SRRCxN_coeffs(63);
coeff_33
<= SRRCxN_coeffs(64);
n_coeff_33 <= SRRCxN_coeffs(65);
coeff_34
<= SRRCxN_coeffs(66);
n_coeff_34 <= SRRCxN_coeffs(67);
coeff_35
<= SRRCxN_coeffs(68);
n_coeff_35 <= SRRCxN_coeffs(69);
coeff_36
<= SRRCxN_coeffs(70);
n_coeff_36 <= SRRCxN_coeffs(71);
coeff_37
<= SRRCxN_coeffs(72);
n_coeff_37 <= SRRCxN_coeffs(73);
coeff_38
<= SRRCxN_coeffs(74);
n_coeff_38 <= SRRCxN_coeffs(75);
coeff_39
<= SRRCxN_coeffs(76);
n_coeff_39 <= SRRCxN_coeffs(77);
coeff_40
<= SRRCxN_coeffs(78);
n_coeff_40 <= SRRCxN_coeffs(79);
coeff_41
<= SRRCxN_coeffs(80);
n_coeff_41 <= SRRCxN_coeffs(81);
coeff_42
<= SRRCxN_coeffs(82);
n_coeff_42 <= SRRCxN_coeffs(83);
U1 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_1,
coeff_b => coeff_2,
coeff_c => coeff_3,
coeff_d => coeff_4,
coeff_e => coeff_5,
coeff_f => coeff_6,
coeff_g => coeff_7,
in_fir_MSB
=> in_fir_MSB,
n_coeff_a
=> n_coeff_1,
n_coeff_b
=> n_coeff_2,
n_coeff_c
=> n_coeff_3,
n_coeff_d
=> n_coeff_4,
n_coeff_e
=> n_coeff_5,
n_coeff_f
=> n_coeff_6,
n_coeff_g
=> n_coeff_7,
out_fir => to_in_0,
reset => reset
);
U2 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_8,
coeff_b => coeff_9,
coeff_c => coeff_10,
coeff_d => coeff_11,
coeff_e => coeff_12,
coeff_f => coeff_13,
coeff_g => coeff_14,
in_fir_MSB
=> in_fir_MSB,
n_coeff_a
=> n_coeff_8,
n_coeff_b
=> n_coeff_9,
n_coeff_c
=> n_coeff_10,
n_coeff_d
=> n_coeff_11,
n_coeff_e
=> n_coeff_12,
n_coeff_f
=> n_coeff_13,
n_coeff_g
=> n_coeff_14,
out_fir => to_in_1,
reset => reset
);
U3 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_15,
coeff_b => coeff_16,
coeff_c => coeff_17,
coeff_d => coeff_18,
coeff_e => coeff_19,
coeff_f => coeff_20,
coeff_g => coeff_21,
in_fir_MSB
=> in_fir_MSB,
n_coeff_a
=> n_coeff_15,
n_coeff_b
=> n_coeff_16,
n_coeff_c
=> n_coeff_17,
n_coeff_d
=> n_coeff_18,
n_coeff_e
=> n_coeff_19,
n_coeff_f
=> n_coeff_20,
n_coeff_g
=> n_coeff_21,
out_fir => to_in_2,
reset => reset
);
135
APPENDICE F. LISTATI VHDL
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
U4 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_22,
coeff_b => coeff_23,
coeff_c => coeff_24,
coeff_d => coeff_25,
coeff_e => coeff_26,
coeff_f => coeff_27,
coeff_g => coeff_28,
in_fir_MSB
=> in_fir_MSB,
n_coeff_a
=> n_coeff_22,
n_coeff_b
=> n_coeff_23,
n_coeff_c
=> n_coeff_24,
n_coeff_d
=> n_coeff_25,
n_coeff_e
=> n_coeff_26,
n_coeff_f
=> n_coeff_27,
n_coeff_g
=> n_coeff_28,
out_fir => to_in_3,
reset => reset
);
U5 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_29,
coeff_b => coeff_30,
coeff_c => coeff_31,
coeff_d => coeff_32,
coeff_e => coeff_33,
coeff_f => coeff_34,
coeff_g => coeff_35,
in_fir_MSB => in_fir_MSB,
n_coeff_a
=> n_coeff_29,
n_coeff_b
=> n_coeff_30,
n_coeff_c
=> n_coeff_31,
n_coeff_d
=> n_coeff_32,
n_coeff_e
=> n_coeff_33,
n_coeff_f
=> n_coeff_34,
n_coeff_g
=> n_coeff_35,
out_fir => to_in_4,
reset => reset
);
U6 : fir_1
port map(
clk_div_n
=> clk_div_n,
coeff_a => coeff_36,
coeff_b => coeff_37,
coeff_c => coeff_38,
coeff_d => coeff_39,
coeff_e => coeff_40,
coeff_f => coeff_41,
coeff_g => coeff_42,
in_fir_MSB => in_fir_MSB,
n_coeff_a
=> n_coeff_36,
n_coeff_b
=> n_coeff_37,
n_coeff_c
=> n_coeff_38,
n_coeff_d
=> n_coeff_39,
n_coeff_e
=> n_coeff_40,
n_coeff_f
=> n_coeff_41,
n_coeff_g
=> n_coeff_42,
out_fir => to_in_5,
reset => reset
);
U7 : mux_6
port map(
clk => clk,
count_n => count_n,
in_0 => to_in_0,
in_1 => to_in_1,
in_2 => to_in_2,
in_3 => to_in_3,
in_4 => to_in_4,
in_5 => to_in_5,
out_mux => polyphase_out
);
end SRRC_x_N;
Listato F.2.11:
1
2
3
4
5
6
7
8
9
10
11
12
136
library IEEE;
use IEEE.std_logic_1164.all;
use work.SRRC_coeffs.all;
entity fir_1 is
port(
clk_div_n : in STD_LOGIC;
coeff_a : in coeff;
coeff_b : in coeff;
coeff_c : in coeff;
coeff_d : in coeff;
coeff_e : in coeff;
fir 1.vhd
APPENDICE F. LISTATI VHDL
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
coeff_f : in coeff;
coeff_g : in coeff;
in_fir_MSB : in STD_LOGIC;
n_coeff_a : in coeff;
n_coeff_b : in coeff;
n_coeff_c : in coeff;
n_coeff_d : in coeff;
n_coeff_e : in coeff;
n_coeff_f : in coeff;
n_coeff_g : in coeff;
reset
: in STD_LOGIC;
out_fir : out STD_LOGIC_VECTOR(11 downto 0)
);
end fir_1;
architecture fir_1 of fir_1 is
component adder_7
port (
clk_div_n : in STD_LOGIC;
in_a : in STD_LOGIC_VECTOR(11 downto 0);
in_b : in STD_LOGIC_VECTOR(11 downto 0);
in_c : in STD_LOGIC_VECTOR(11 downto 0);
in_d : in STD_LOGIC_VECTOR(11 downto 0);
in_e : in STD_LOGIC_VECTOR(11 downto 0);
in_f : in STD_LOGIC_VECTOR(11 downto 0);
in_g : in STD_LOGIC_VECTOR(11 downto 0);
reset : in STD_LOGIC;
out_adder : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component fir_multiplier
port (
clk_div_n : in STD_LOGIC;
coeff_n : in coeff;
in_a
: in STD_LOGIC;
n_coeff_n : in coeff;
reset
: in STD_LOGIC;
out_mult : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component shift_reg
port (
clk_div_n : in STD_LOGIC;
in_reg : in STD_LOGIC;
reset
: in STD_LOGIC;
out_ffd_1 : out STD_LOGIC;
out_ffd_2 : out STD_LOGIC;
out_ffd_3 : out STD_LOGIC;
out_ffd_4 : out STD_LOGIC;
out_ffd_5 : out STD_LOGIC;
out_ffd_6 : out STD_LOGIC
);
end component;
signal in_ffd_1 : STD_LOGIC;
signal out_ffd_1 : STD_LOGIC;
signal out_ffd_2 : STD_LOGIC;
signal out_ffd_3 : STD_LOGIC;
signal out_ffd_4 : STD_LOGIC;
signal out_ffd_5 : STD_LOGIC;
signal out_ffd_6 : STD_LOGIC;
signal to_add_a : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_b : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_c : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_d : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_e : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_f : STD_LOGIC_VECTOR (11 downto 0);
signal to_add_g : STD_LOGIC_VECTOR (11 downto 0);
begin
U1 : shift_reg
port map(
clk_div_n => clk_div_n,
in_reg => in_ffd_1,
out_ffd_1 => out_ffd_1,
out_ffd_2 => out_ffd_2,
out_ffd_3 => out_ffd_3,
out_ffd_4 => out_ffd_4,
out_ffd_5 => out_ffd_5,
out_ffd_6 => out_ffd_6,
reset
=> reset
);
U2 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_a,
in_a
=> in_ffd_1,
n_coeff_n => n_coeff_a,
out_mult => to_add_a,
reset
=> reset
);
U3 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_b,
in_a
=> out_ffd_1,
137
APPENDICE F. LISTATI VHDL
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
n_coeff_n => n_coeff_b,
out_mult => to_add_b,
reset
=> reset
);
U4 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_c,
in_a
=> out_ffd_2,
n_coeff_n => n_coeff_c,
out_mult => to_add_c,
reset
=> reset
);
U5 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_d,
in_a
=> out_ffd_3,
n_coeff_n => n_coeff_d,
out_mult => to_add_d,
reset
=> reset
);
U6 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_e,
in_a
=> out_ffd_4,
n_coeff_n => n_coeff_e,
out_mult => to_add_e,
reset
=> reset
);
U7 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_f,
in_a
=> out_ffd_5,
n_coeff_n => n_coeff_f,
out_mult => to_add_f,
reset
=> reset
);
U8 : fir_multiplier
port map(
clk_div_n => clk_div_n,
coeff_n => coeff_g,
in_a
=> out_ffd_6,
n_coeff_n => n_coeff_g,
out_mult => to_add_g,
reset
=> reset
);
U9 : adder_7
port map(
clk_div_n => clk_div_n,
in_a
=> to_add_a,
in_b
=> to_add_b,
in_c
=> to_add_c,
in_d
=> to_add_d,
in_e
=> to_add_e,
in_f
=> to_add_f,
in_g
=> to_add_g,
out_adder => out_fir,
reset
=> reset
);
in_ffd_1 <= in_fir_MSB;
end fir_1;
Listato F.2.12:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
138
adder 7.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity adder_7 is
port(in_a, in_b, in_c, in_d : in std_logic_vector(11 downto 0);
in_e, in_f, in_g
: in std_logic_vector(11 downto 0);
clk_div_n , reset : in std_logic;
out_adder
: out std_logic_vector(11 downto 0));
end adder_7 ;
architecture adder_7_arch of adder_7 is
begin
process(reset, clk_div_n , in_a , in_b , in_c , in_d, in_e, in_f, in_g)
begin
if reset = ’1’ then
out_adder <= "000000000000";
elsif falling_edge(clk_div_n) then
out_adder <= in_a + in_b + in_c + in_d + in_e + in_f + in_g;
end if ;
end process;
end adder_7_arch ;
APPENDICE F. LISTATI VHDL
Listato F.2.13:
139
fir multiplier.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use work.SRRC_coeffs.all;
entity fir_multiplier is
port( in_a
:
in std_logic ;
reset :
in std_logic ;
coeff_n : in coeff
;
n_coeff_n : in coeff
;
clk_div_n : in std_logic ;
out_mult
:
out std_logic_vector(11 downto 0));
end fir_multiplier;
architecture fir_multiplier_arch of fir_multiplier is
begin
process(in_a , coeff_n, n_coeff_n, clk_div_n, reset)
begin
if reset = ’1’ then
out_mult <= "000000000000" ;
elsif falling_edge(clk_div_n) then
case in_a is
when ’0’ => out_mult <= coeff_n
;
when ’1’ => out_mult <= n_coeff_n ;
when others => out_mult <= "000000000000" ;
end case;
end if;
end process;
end fir_multiplier_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
library IEEE;
use IEEE.std_logic_1164.all;
entity shift_reg is
port (
clk_div_n : in std_logic ;
reset
: in std_logic ;
in_reg : in std_logic ;
out_ffd_1 : out std_logic ;
out_ffd_2 : out std_logic ;
out_ffd_3 : out std_logic ;
out_ffd_4 : out std_logic ;
out_ffd_5 : out std_logic ;
out_ffd_6 : out std_logic
);
end entity;
Listato F.2.14:
architecture shift_reg_arch of shift_reg is
signal temp_out_reg : std_logic_vector(5 downto 0);
signal temp_go_mult : std_logic_vector(6 downto 0);
begin
process(clk_div_n, reset)
begin
if reset = ’1’ then
temp_out_reg <= "000000";
elsif falling_edge(clk_div_n) then
temp_out_reg <= in_reg & temp_out_reg(5 downto 1);
end if;
end process;
out_ffd_6 <= temp_out_reg(0);
out_ffd_5 <= temp_out_reg(1);
out_ffd_4 <= temp_out_reg(2);
out_ffd_3 <= temp_out_reg(3);
out_ffd_2 <= temp_out_reg(4);
out_ffd_1 <= temp_out_reg(5);
end architecture;
Listato F.2.15:
1
2
3
shift reg.vhd
library ieee;
use ieee.std_logic_1164.all;
mux 6.vhd
APPENDICE F. LISTATI VHDL
140
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
entity mux_6 is
port(in_0, in_1, in_2, in_3, in_4, in_5 : in std_logic_vector(11 downto 0);
count_n
:
in std_logic_vector(2 downto 0);
clk
: in std_logic;
out_mux
:
out std_logic_vector(11 downto 0));
end mux_6;
architecture mux_arch of mux_6 is
begin
process (clk, count_n, in_0, in_1, in_2, in_3, in_4, in_5)
begin
if falling_edge(clk) then
case count_n is
when "000" =>
out_mux <= in_0 ;
when "001" =>
out_mux <= in_1 ;
when "010" =>
out_mux <= in_2 ;
when "011" =>
out_mux <= in_3 ;
when "100" =>
out_mux <= in_4 ;
when "101" =>
out_mux <= in_5 ;
when others => out_mux <= "XXXXXXXXXXXX" ;
end case;
else null ;
end if;
end process;
end mux_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
library IEEE;
use IEEE.std_logic_1164.all;
entity ROM_polyphase is
port(
clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
to_SRRC_I : in STD_LOGIC;
rate_sel : in STD_LOGIC_VECTOR(1 downto 0);
clk_sync : out STD_LOGIC;
poly_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end ROM_polyphase;
architecture ROM_polyphase of ROM_polyphase is
component counter
port (
clk
: in STD_LOGIC;
rate_sel : in STD_LOGIC_VECTOR(1 downto 0);
reset : in STD_LOGIC;
clk_en : out STD_LOGIC;
count : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component srrc_x_n
port (
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
fir_sel : in STD_LOGIC_VECTOR(2 downto 0);
in_fir_MSB : in STD_LOGIC;
rate_sel : in STD_LOGIC_VECTOR(1 downto 0);
reset
: in STD_LOGIC;
out_srrc : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal clk_en : STD_LOGIC;
signal count_n : STD_LOGIC_VECTOR (2 downto 0);
begin
U1 : counter
port map(
clk
=> clk,
clk_en => clk_en,
count => count_n,
rate_sel
=> rate_sel,
reset => reset
);
U2 : srrc_x_n
port map(
clk
=> clk,
clk_en => clk_en,
fir_sel => count_n,
in_fir_MSB => to_SRRC_I,
out_srrc
=> poly_out,
rate_sel
=> rate_sel,
reset => reset
);
clk_sync <= clk;
end ROM_polyphase;
Listato F.3.1:
ROM polyphase.vhd
APPENDICE F. LISTATI VHDL
Listato F.3.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
counter.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity counter is
port (
clk
: in std_logic;
reset : in std_logic;
rate_sel : in std_logic_vector(1 downto 0);
count : out std_logic_vector(2 downto 0);
clk_en : out std_logic
);
end entity;
architecture counter_arch of counter is
type rate_table_type is array (0 to 2) of std_logic_vector (2 downto 0);
-- definisco un array con i valori dei rate diminuiti di 1
-- per migliorare l ’ implementazione
constant count_limit_table : rate_table_type := ("010","011","101");
signal TEMP_count
: std_logic_vector(2 downto 0);
signal TEMP_clk_en : std_logic;
begin
process(clk, reset)
begin
if reset = ’1’ then
TEMP_count <= "000";
TEMP_clk_en <= ’1’ ;
elsif rising_edge(clk) then
if (TEMP_count = count_limit_table(conv_integer(rate_sel))-1)
then
TEMP_clk_en <= ’1’ ;
TEMP_count <= TEMP_count + 1;
elsif (TEMP_count = count_limit_table(conv_integer(rate_sel))
)then
TEMP_clk_en <= ’0’ ;
TEMP_count <= "000";
else
TEMP_clk_en <= ’0’ ;
TEMP_count <= TEMP_count + 1;
end if;
end if;
end process;
count <= TEMP_count;
clk_en <= TEMP_clk_en;
end counter_arch;
Listato F.3.3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
141
srrc x n.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity srrc_x_n is
port(
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
in_fir_MSB : in STD_LOGIC;
reset
: in STD_LOGIC;
fir_sel : in STD_LOGIC_VECTOR(2 downto 0);
rate_sel : in STD_LOGIC_VECTOR(1 downto 0);
out_srrc : out STD_LOGIC_VECTOR(11 downto 0)
);
end srrc_x_n;
architecture srrc_x_n of srrc_x_n is
component demux_3x10
port (
clk
: in STD_LOGIC;
in_mux : in STD_LOGIC_VECTOR(9 downto 0);
sel
: in STD_LOGIC_VECTOR(1 downto 0);
out_0 : out STD_LOGIC_VECTOR(8 downto 0);
out_1 : out STD_LOGIC_VECTOR(8 downto 0);
out_2 : out STD_LOGIC_VECTOR(9 downto 0)
);
end component;
component mux_3x12
port (
clk
: in STD_LOGIC;
in_0 : in STD_LOGIC_VECTOR(11 downto 0);
in_1 : in STD_LOGIC_VECTOR(11 downto 0);
in_2 : in STD_LOGIC_VECTOR(11 downto 0);
sel
: in STD_LOGIC_VECTOR(1 downto 0);
out_mux : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
APPENDICE F. LISTATI VHDL
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
component romx3
port (
address : in STD_LOGIC_VECTOR(8 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component ROMx4
port (
address : in STD_LOGIC_VECTOR(8 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component ROMx6
port (
address : in STD_LOGIC_VECTOR(9 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component shift_reg
port (
clk
: in STD_LOGIC;
clk_en : in STD_LOGIC;
in_reg : in STD_LOGIC;
reset
: in STD_LOGIC;
out_ffd_1 : out STD_LOGIC;
out_ffd_2 : out STD_LOGIC;
out_ffd_3 : out STD_LOGIC;
out_ffd_4 : out STD_LOGIC;
out_ffd_5 : out STD_LOGIC;
out_ffd_6 : out STD_LOGIC
);
end component;
signal address : STD_LOGIC_VECTOR (9 downto 0);
signal BUS615 : STD_LOGIC_VECTOR (11 downto 0);
signal BUS619 : STD_LOGIC_VECTOR (11 downto 0);
signal BUS623 : STD_LOGIC_VECTOR (11 downto 0);
signal sel
: STD_LOGIC_VECTOR (1 downto 0);
signal to_romx3 : STD_LOGIC_VECTOR (8 downto 0);
signal to_romx4 : STD_LOGIC_VECTOR (8 downto 0);
signal to_romx6 : STD_LOGIC_VECTOR (9 downto 0);
begin
U1 : shift_reg
port map(
clk
=> clk,
clk_en => clk_en,
in_reg => address(0),
out_ffd_1 => address(1),
out_ffd_2 => address(2),
out_ffd_3 => address(3),
out_ffd_4 => address(4),
out_ffd_5 => address(5),
out_ffd_6 => address(6),
reset
=> reset
);
U2 : demux_3x10
port map(
clk
=> clk,
in_mux => address,
out_0 => to_romx3,
out_1 => to_romx4,
out_2 => to_romx6,
sel
=> sel
);
U3 : romx3
port map(
SRRC_out => BUS615,
address => to_romx3
);
U4 : ROMx4
port map(
SRRC_out => BUS619,
address => to_romx4
);
U5 : ROMx6
port map(
SRRC_out => BUS623,
address => to_romx6
);
U6 : mux_3x12
port map(
clk
=> clk,
in_0 => BUS615,
in_1 => BUS619,
in_2 => BUS623,
out_mux => out_srrc,
sel
=> sel
);
address(7) <= fir_sel(0);
address(8) <= fir_sel(1);
address(9) <= fir_sel(2);
address(0) <= in_fir_MSB;
sel <= rate_sel;
142
APPENDICE F. LISTATI VHDL
130
143
end srrc_x_n;
Listato F.3.4:
demux 3x10.vhd
library ieee;
use ieee.std_logic_1164.all;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
entity demux_3x10 is
port(in_mux
:
in std_logic_vector(9 downto 0);
clk
:
in std_logic;
sel
:
in std_logic_vector(1 downto 0);
out_0
: out std_logic_vector(8 downto 0);
out_1
: out std_logic_vector(8 downto 0);
out_2
:
out std_logic_vector(9 downto 0)
);
end demux_3x10;
architecture demux_3x10_arch of demux_3x10 is
begin
process (sel, in_mux, clk)
begin
if rising_edge(clk) then
case sel is
when "00" =>
out_0 <= in_mux(8 downto 0) ;
when "01" =>
out_1 <= in_mux(8 downto 0) ;
when "10" =>
out_2 <= in_mux ;
when others => null;
end case;
end if;
end process;
end demux_3x10_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library ieee;
use ieee.std_logic_1164.all;
entity mux_3x12 is
port(in_0, in_1, in_2 : in std_logic_vector(11 downto 0);
clk
: in std_logic ;
sel
: in std_logic_vector(1 downto 0);
out_mux
: out std_logic_vector(11 downto 0));
end mux_3x12;
architecture mux_3x12_arch of mux_3x12 is
begin
process (sel, in_0, in_1, in_2, clk)
begin
if rising_edge(clk) then
case sel is
when "00" =>
out_mux <=in_0 ;
when "01" =>
out_mux <=in_1 ;
when "10" =>
out_mux <=in_2 ;
when others => out_mux <= "XXXXXXXXXXXX" ;
end case;
end if;
end process;
end mux_3x12_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ROMx3 is
port(address : in STD_LOGIC_vector(8 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end;
architecture ROMx3_arch of ROMx3 is
begin
process(address)
variable addr : integer ;
begin
addr := conv_integer(address) ;
case addr is
Listato F.3.5:
Listato F.3.6:
mux 3x12.vhd
ROMx3.vhd
APPENDICE F. LISTATI VHDL
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
-- somme per il FIR 0
when 0
=> SRRC_out
when 1
=> SRRC_out
when 2
=> SRRC_out
when 3
=> SRRC_out
when 4
=> SRRC_out
when 5
=> SRRC_out
when 6
=> SRRC_out
when 7
=> SRRC_out
when 8
=> SRRC_out
when 9
=> SRRC_out
when 10
=> SRRC_out
when 11
=> SRRC_out
when 12
=> SRRC_out
when 13
=> SRRC_out
when 14
=> SRRC_out
when 15
=> SRRC_out
when 16
=> SRRC_out
when 17
=> SRRC_out
when 18
=> SRRC_out
when 19
=> SRRC_out
when 20
=> SRRC_out
when 21
=> SRRC_out
when 22
=> SRRC_out
when 23
=> SRRC_out
when 24
=> SRRC_out
when 25
=> SRRC_out
when 26
=> SRRC_out
when 27
=> SRRC_out
when 28
=> SRRC_out
when 29
=> SRRC_out
when 30
=> SRRC_out
when 31
=> SRRC_out
when 32
=> SRRC_out
when 33
=> SRRC_out
when 34
=> SRRC_out
when 35
=> SRRC_out
when 36
=> SRRC_out
when 37
=> SRRC_out
when 38
=> SRRC_out
when 39
=> SRRC_out
when 40
=> SRRC_out
when 41
=> SRRC_out
when 42
=> SRRC_out
when 43
=> SRRC_out
when 44
=> SRRC_out
when 45
=> SRRC_out
when 46
=> SRRC_out
when 47
=> SRRC_out
when 48
=> SRRC_out
when 49
=> SRRC_out
when 50
=> SRRC_out
when 51
=> SRRC_out
when 52
=> SRRC_out
when 53
=> SRRC_out
when 54
=> SRRC_out
when 55
=> SRRC_out
when 56
=> SRRC_out
when 57
=> SRRC_out
when 58
=> SRRC_out
when 59
=> SRRC_out
when 60
=> SRRC_out
when 61
=> SRRC_out
when 62
=> SRRC_out
when 63
=> SRRC_out
when 64
=> SRRC_out
when 65
=> SRRC_out
when 66
=> SRRC_out
when 67
=> SRRC_out
when 68
=> SRRC_out
when 69
=> SRRC_out
when 70
=> SRRC_out
when 71
=> SRRC_out
when 72
=> SRRC_out
when 73
=> SRRC_out
when 74
=> SRRC_out
when 75
=> SRRC_out
when 76
=> SRRC_out
when 77
=> SRRC_out
when 78
=> SRRC_out
when 79
=> SRRC_out
when 80
=> SRRC_out
when 81
=> SRRC_out
when 82
=> SRRC_out
when 83
=> SRRC_out
when 84
=> SRRC_out
when 85
=> SRRC_out
when 86
=> SRRC_out
when 87
=> SRRC_out
when 88
=> SRRC_out
when 89
=> SRRC_out
when 90
=> SRRC_out
when 91
=> SRRC_out
when 92
=> SRRC_out
when 93
=> SRRC_out
when 94
=> SRRC_out
when 95
=> SRRC_out
when 96
=> SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"52B";
X"52B";
X"517";
X"517";
X"5CB";
X"5CB";
X"5B6";
X"5B6";
X"1C8";
X"1C8";
X"1B4";
X"1B4";
X"268";
X"268";
X"253";
X"253";
X"C69";
X"C69";
X"C55";
X"C55";
X"D09";
X"D09";
X"CF4";
X"CF4";
X"907";
X"907";
X"8F2";
X"8F2";
X"9A6";
X"9A6";
X"992";
X"992";
X"6FA";
X"6FA";
X"6E6";
X"6E6";
X"79A";
X"79A";
X"785";
X"785";
X"397";
X"397";
X"383";
X"383";
X"437";
X"437";
X"422";
X"422";
X"E38";
X"E38";
X"E24";
X"E24";
X"ED8";
X"ED8";
X"EC3";
X"EC3";
X"AD6";
X"AD6";
X"AC1";
X"AC1";
X"B75";
X"B75";
X"B61";
X"B61";
X"49F";
X"49F";
X"48B";
X"48B";
X"53F";
X"53F";
X"52A";
X"52A";
X"13D";
X"13D";
X"128";
X"128";
X"1DC";
X"1DC";
X"1C8";
X"1C8";
X"BDE";
X"BDE";
X"BC9";
X"BC9";
X"C7D";
X"C7D";
X"C69";
X"C69";
X"87B";
X"87B";
X"866";
X"866";
X"91A";
X"91A";
X"906";
X"906";
X"66E";
144
APPENDICE F. LISTATI VHDL
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
when 97
=> SRRC_out
when 98
=> SRRC_out
when 99
=> SRRC_out
when 100 => SRRC_out
when 101 => SRRC_out
when 102 => SRRC_out
when 103 => SRRC_out
when 104 => SRRC_out
when 105 => SRRC_out
when 106 => SRRC_out
when 107 => SRRC_out
when 108 => SRRC_out
when 109 => SRRC_out
when 110 => SRRC_out
when 111 => SRRC_out
when 112 => SRRC_out
when 113 => SRRC_out
when 114 => SRRC_out
when 115 => SRRC_out
when 116 => SRRC_out
when 117 => SRRC_out
when 118 => SRRC_out
when 119 => SRRC_out
when 120 => SRRC_out
when 121 => SRRC_out
when 122 => SRRC_out
when 123 => SRRC_out
when 124 => SRRC_out
when 125 => SRRC_out
when 126 => SRRC_out
when 127 => SRRC_out
-- somme per il FIR 1
when 128 => SRRC_out
when 129 => SRRC_out
when 130 => SRRC_out
when 131 => SRRC_out
when 132 => SRRC_out
when 133 => SRRC_out
when 134 => SRRC_out
when 135 => SRRC_out
when 136 => SRRC_out
when 137 => SRRC_out
when 138 => SRRC_out
when 139 => SRRC_out
when 140 => SRRC_out
when 141 => SRRC_out
when 142 => SRRC_out
when 143 => SRRC_out
when 144 => SRRC_out
when 145 => SRRC_out
when 146 => SRRC_out
when 147 => SRRC_out
when 148 => SRRC_out
when 149 => SRRC_out
when 150 => SRRC_out
when 151 => SRRC_out
when 152 => SRRC_out
when 153 => SRRC_out
when 154 => SRRC_out
when 155 => SRRC_out
when 156 => SRRC_out
when 157 => SRRC_out
when 158 => SRRC_out
when 159 => SRRC_out
when 160 => SRRC_out
when 161 => SRRC_out
when 162 => SRRC_out
when 163 => SRRC_out
when 164 => SRRC_out
when 165 => SRRC_out
when 166 => SRRC_out
when 167 => SRRC_out
when 168 => SRRC_out
when 169 => SRRC_out
when 170 => SRRC_out
when 171 => SRRC_out
when 172 => SRRC_out
when 173 => SRRC_out
when 174 => SRRC_out
when 175 => SRRC_out
when 176 => SRRC_out
when 177 => SRRC_out
when 178 => SRRC_out
when 179 => SRRC_out
when 180 => SRRC_out
when 181 => SRRC_out
when 182 => SRRC_out
when 183 => SRRC_out
when 184 => SRRC_out
when 185 => SRRC_out
when 186 => SRRC_out
when 187 => SRRC_out
when 188 => SRRC_out
when 189 => SRRC_out
when 190 => SRRC_out
when 191 => SRRC_out
when 192 => SRRC_out
when 193 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"66E";
X"65A";
X"65A";
X"70E";
X"70E";
X"6F9";
X"6F9";
X"30C";
X"30C";
X"2F7";
X"2F7";
X"3AB";
X"3AB";
X"397";
X"397";
X"DAD";
X"DAD";
X"D98";
X"D98";
X"E4C";
X"E4C";
X"E38";
X"E38";
X"A4A";
X"A4A";
X"A35";
X"A35";
X"AE9";
X"AE9";
X"AD5";
X"AD5";
X"52B";
X"52B";
X"49F";
X"49F";
X"6FA";
X"6FA";
X"66E";
X"66E";
X"C69";
X"C69";
X"BDE";
X"BDE";
X"E38";
X"E38";
X"DAD";
X"DAD";
X"1C8";
X"1C8";
X"13D";
X"13D";
X"397";
X"397";
X"30C";
X"30C";
X"907";
X"907";
X"87B";
X"87B";
X"AD6";
X"AD6";
X"A4A";
X"A4A";
X"5CB";
X"5CB";
X"53F";
X"53F";
X"79A";
X"79A";
X"70E";
X"70E";
X"D09";
X"D09";
X"C7D";
X"C7D";
X"ED8";
X"ED8";
X"E4C";
X"E4C";
X"268";
X"268";
X"1DC";
X"1DC";
X"437";
X"437";
X"3AB";
X"3AB";
X"9A6";
X"9A6";
X"91A";
X"91A";
X"B75";
X"B75";
X"AE9";
X"AE9";
X"517";
X"517";
145
APPENDICE F. LISTATI VHDL
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
when 194 => SRRC_out
when 195 => SRRC_out
when 196 => SRRC_out
when 197 => SRRC_out
when 198 => SRRC_out
when 199 => SRRC_out
when 200 => SRRC_out
when 201 => SRRC_out
when 202 => SRRC_out
when 203 => SRRC_out
when 204 => SRRC_out
when 205 => SRRC_out
when 206 => SRRC_out
when 207 => SRRC_out
when 208 => SRRC_out
when 209 => SRRC_out
when 210 => SRRC_out
when 211 => SRRC_out
when 212 => SRRC_out
when 213 => SRRC_out
when 214 => SRRC_out
when 215 => SRRC_out
when 216 => SRRC_out
when 217 => SRRC_out
when 218 => SRRC_out
when 219 => SRRC_out
when 220 => SRRC_out
when 221 => SRRC_out
when 222 => SRRC_out
when 223 => SRRC_out
when 224 => SRRC_out
when 225 => SRRC_out
when 226 => SRRC_out
when 227 => SRRC_out
when 228 => SRRC_out
when 229 => SRRC_out
when 230 => SRRC_out
when 231 => SRRC_out
when 232 => SRRC_out
when 233 => SRRC_out
when 234 => SRRC_out
when 235 => SRRC_out
when 236 => SRRC_out
when 237 => SRRC_out
when 238 => SRRC_out
when 239 => SRRC_out
when 240 => SRRC_out
when 241 => SRRC_out
when 242 => SRRC_out
when 243 => SRRC_out
when 244 => SRRC_out
when 245 => SRRC_out
when 246 => SRRC_out
when 247 => SRRC_out
when 248 => SRRC_out
when 249 => SRRC_out
when 250 => SRRC_out
when 251 => SRRC_out
when 252 => SRRC_out
when 253 => SRRC_out
when 254 => SRRC_out
when 255 => SRRC_out
-- somme per il FIR 2
when 256 => SRRC_out
when 257 => SRRC_out
when 258 => SRRC_out
when 259 => SRRC_out
when 260 => SRRC_out
when 261 => SRRC_out
when 262 => SRRC_out
when 263 => SRRC_out
when 264 => SRRC_out
when 265 => SRRC_out
when 266 => SRRC_out
when 267 => SRRC_out
when 268 => SRRC_out
when 269 => SRRC_out
when 270 => SRRC_out
when 271 => SRRC_out
when 272 => SRRC_out
when 273 => SRRC_out
when 274 => SRRC_out
when 275 => SRRC_out
when 276 => SRRC_out
when 277 => SRRC_out
when 278 => SRRC_out
when 279 => SRRC_out
when 280 => SRRC_out
when 281 => SRRC_out
when 282 => SRRC_out
when 283 => SRRC_out
when 284 => SRRC_out
when 285 => SRRC_out
when 286 => SRRC_out
when 287 => SRRC_out
when 288 => SRRC_out
when 289 => SRRC_out
when 290 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"48B";
X"48B";
X"6E6";
X"6E6";
X"65A";
X"65A";
X"C55";
X"C55";
X"BC9";
X"BC9";
X"E24";
X"E24";
X"D98";
X"D98";
X"1B4";
X"1B4";
X"128";
X"128";
X"383";
X"383";
X"2F7";
X"2F7";
X"8F2";
X"8F2";
X"866";
X"866";
X"AC1";
X"AC1";
X"A35";
X"A35";
X"5B6";
X"5B6";
X"52A";
X"52A";
X"785";
X"785";
X"6F9";
X"6F9";
X"CF4";
X"CF4";
X"C69";
X"C69";
X"EC3";
X"EC3";
X"E38";
X"E38";
X"253";
X"253";
X"1C8";
X"1C8";
X"422";
X"422";
X"397";
X"397";
X"992";
X"992";
X"906";
X"906";
X"B61";
X"B61";
X"AD5";
X"AD5";
X"500";
X"541";
X"485";
X"4C6";
X"5D7";
X"618";
X"55D";
X"59E";
X"9C4";
X"A05";
X"94A";
X"98B";
X"A9C";
X"ADC";
X"A21";
X"A62";
X"5D7";
X"618";
X"55D";
X"59E";
X"6AF";
X"6F0";
X"634";
X"675";
X"A9C";
X"ADC";
X"A21";
X"A62";
X"B73";
X"BB4";
X"AF9";
X"B3A";
X"485";
X"4C6";
X"40B";
146
APPENDICE F. LISTATI VHDL
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
when 291 => SRRC_out <= X"44C";
when 292 => SRRC_out <= X"55D";
when 293 => SRRC_out <= X"59E";
when 294 => SRRC_out <= X"4E3";
when 295 => SRRC_out <= X"524";
when 296 => SRRC_out <= X"94A";
when 297 => SRRC_out <= X"98B";
when 298 => SRRC_out <= X"8CF";
when 299 => SRRC_out <= X"910";
when 300 => SRRC_out <= X"A21";
when 301 => SRRC_out <= X"A62";
when 302 => SRRC_out <= X"9A7";
when 303 => SRRC_out <= X"9E8";
when 304 => SRRC_out <= X"55D";
when 305 => SRRC_out <= X"59E";
when 306 => SRRC_out <= X"4E3";
when 307 => SRRC_out <= X"524";
when 308 => SRRC_out <= X"634";
when 309 => SRRC_out <= X"675";
when 310 => SRRC_out <= X"5BA";
when 311 => SRRC_out <= X"5FB";
when 312 => SRRC_out <= X"A21";
when 313 => SRRC_out <= X"A62";
when 314 => SRRC_out <= X"9A7";
when 315 => SRRC_out <= X"9E8";
when 316 => SRRC_out <= X"AF9";
when 317 => SRRC_out <= X"B3A";
when 318 => SRRC_out <= X"A7E";
when 319 => SRRC_out <= X"ABF";
when 320 => SRRC_out <= X"541";
when 321 => SRRC_out <= X"582";
when 322 => SRRC_out <= X"4C6";
when 323 => SRRC_out <= X"507";
when 324 => SRRC_out <= X"618";
when 325 => SRRC_out <= X"659";
when 326 => SRRC_out <= X"59E";
when 327 => SRRC_out <= X"5DF";
when 328 => SRRC_out <= X"A05";
when 329 => SRRC_out <= X"A46";
when 330 => SRRC_out <= X"98B";
when 331 => SRRC_out <= X"9CC";
when 332 => SRRC_out <= X"ADC";
when 333 => SRRC_out <= X"B1D";
when 334 => SRRC_out <= X"A62";
when 335 => SRRC_out <= X"AA3";
when 336 => SRRC_out <= X"618";
when 337 => SRRC_out <= X"659";
when 338 => SRRC_out <= X"59E";
when 339 => SRRC_out <= X"5DF";
when 340 => SRRC_out <= X"6F0";
when 341 => SRRC_out <= X"731";
when 342 => SRRC_out <= X"675";
when 343 => SRRC_out <= X"6B6";
when 344 => SRRC_out <= X"ADC";
when 345 => SRRC_out <= X"B1D";
when 346 => SRRC_out <= X"A62";
when 347 => SRRC_out <= X"AA3";
when 348 => SRRC_out <= X"BB4";
when 349 => SRRC_out <= X"BF5";
when 350 => SRRC_out <= X"B3A";
when 351 => SRRC_out <= X"B7B";
when 352 => SRRC_out <= X"4C6";
when 353 => SRRC_out <= X"507";
when 354 => SRRC_out <= X"44C";
when 355 => SRRC_out <= X"48D";
when 356 => SRRC_out <= X"59E";
when 357 => SRRC_out <= X"5DF";
when 358 => SRRC_out <= X"524";
when 359 => SRRC_out <= X"564";
when 360 => SRRC_out <= X"98B";
when 361 => SRRC_out <= X"9CC";
when 362 => SRRC_out <= X"910";
when 363 => SRRC_out <= X"951";
when 364 => SRRC_out <= X"A62";
when 365 => SRRC_out <= X"AA3";
when 366 => SRRC_out <= X"9E8";
when 367 => SRRC_out <= X"A29";
when 368 => SRRC_out <= X"59E";
when 369 => SRRC_out <= X"5DF";
when 370 => SRRC_out <= X"524";
when 371 => SRRC_out <= X"564";
when 372 => SRRC_out <= X"675";
when 373 => SRRC_out <= X"6B6";
when 374 => SRRC_out <= X"5FB";
when 375 => SRRC_out <= X"63C";
when 376 => SRRC_out <= X"A62";
when 377 => SRRC_out <= X"AA3";
when 378 => SRRC_out <= X"9E8";
when 379 => SRRC_out <= X"A29";
when 380 => SRRC_out <= X"B3A";
when 381 => SRRC_out <= X"B7B";
when 382 => SRRC_out <= X"ABF";
when 383 => SRRC_out <= X"B00";
when OTHERS => SRRC_out <= X"000";
end case;
end process;
end ROMx3_arch;
147
APPENDICE F. LISTATI VHDL
Listato F.3.7:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
148
ROMx4.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ROMx4 is
port(address : in STD_LOGIC_vector(8 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end;
architecture ROMx4_arch of ROMx4 is
begin
process(address)
variable addr : integer ;
begin
addr := conv_integer(address) ;
case addr is
-- somme per il FIR 0
when 0
=> SRRC_out <= X"4F1";
when 1
=> SRRC_out <= X"4F1";
when 2
=> SRRC_out <= X"500";
when 3
=> SRRC_out <= X"500";
when 4
=> SRRC_out <= X"53B";
when 5
=> SRRC_out <= X"53B";
when 6
=> SRRC_out <= X"549";
when 7
=> SRRC_out <= X"549";
when 8
=> SRRC_out <= X"2EA";
when 9
=> SRRC_out <= X"2EA";
when 10
=> SRRC_out <= X"2F9";
when 11
=> SRRC_out <= X"2F9";
when 12
=> SRRC_out <= X"334";
when 13
=> SRRC_out <= X"334";
when 14
=> SRRC_out <= X"342";
when 15
=> SRRC_out <= X"342";
when 16
=> SRRC_out <= X"B95";
when 17
=> SRRC_out <= X"B95";
when 18
=> SRRC_out <= X"BA3";
when 19
=> SRRC_out <= X"BA3";
when 20
=> SRRC_out <= X"BDE";
when 21
=> SRRC_out <= X"BDE";
when 22
=> SRRC_out <= X"BED";
when 23
=> SRRC_out <= X"BED";
when 24
=> SRRC_out <= X"98E";
when 25
=> SRRC_out <= X"98E";
when 26
=> SRRC_out <= X"99C";
when 27
=> SRRC_out <= X"99C";
when 28
=> SRRC_out <= X"9D7";
when 29
=> SRRC_out <= X"9D7";
when 30
=> SRRC_out <= X"9E6";
when 31
=> SRRC_out <= X"9E6";
when 32
=> SRRC_out <= X"6BD";
when 33
=> SRRC_out <= X"6BD";
when 34
=> SRRC_out <= X"6CB";
when 35
=> SRRC_out <= X"6CB";
when 36
=> SRRC_out <= X"706";
when 37
=> SRRC_out <= X"706";
when 38
=> SRRC_out <= X"715";
when 39
=> SRRC_out <= X"715";
when 40
=> SRRC_out <= X"4B6";
when 41
=> SRRC_out <= X"4B6";
when 42
=> SRRC_out <= X"4C4";
when 43
=> SRRC_out <= X"4C4";
when 44
=> SRRC_out <= X"4FF";
when 45
=> SRRC_out <= X"4FF";
when 46
=> SRRC_out <= X"50E";
when 47
=> SRRC_out <= X"50E";
when 48
=> SRRC_out <= X"D60";
when 49
=> SRRC_out <= X"D60";
when 50
=> SRRC_out <= X"D6E";
when 51
=> SRRC_out <= X"D6E";
when 52
=> SRRC_out <= X"DAA";
when 53
=> SRRC_out <= X"DAA";
when 54
=> SRRC_out <= X"DB8";
when 55
=> SRRC_out <= X"DB8";
when 56
=> SRRC_out <= X"B59";
when 57
=> SRRC_out <= X"B59";
when 58
=> SRRC_out <= X"B67";
when 59
=> SRRC_out <= X"B67";
when 60
=> SRRC_out <= X"BA3";
when 61
=> SRRC_out <= X"BA3";
when 62
=> SRRC_out <= X"BB1";
when 63
=> SRRC_out <= X"BB1";
when 64
=> SRRC_out <= X"44F";
when 65
=> SRRC_out <= X"44F";
when 66
=> SRRC_out <= X"45D";
when 67
=> SRRC_out <= X"45D";
when 68
=> SRRC_out <= X"499";
when 69
=> SRRC_out <= X"499";
APPENDICE F. LISTATI VHDL
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
when 70
=> SRRC_out
when 71
=> SRRC_out
when 72
=> SRRC_out
when 73
=> SRRC_out
when 74
=> SRRC_out
when 75
=> SRRC_out
when 76
=> SRRC_out
when 77
=> SRRC_out
when 78
=> SRRC_out
when 79
=> SRRC_out
when 80
=> SRRC_out
when 81
=> SRRC_out
when 82
=> SRRC_out
when 83
=> SRRC_out
when 84
=> SRRC_out
when 85
=> SRRC_out
when 86
=> SRRC_out
when 87
=> SRRC_out
when 88
=> SRRC_out
when 89
=> SRRC_out
when 90
=> SRRC_out
when 91
=> SRRC_out
when 92
=> SRRC_out
when 93
=> SRRC_out
when 94
=> SRRC_out
when 95
=> SRRC_out
when 96
=> SRRC_out
when 97
=> SRRC_out
when 98
=> SRRC_out
when 99
=> SRRC_out
when 100 => SRRC_out
when 101 => SRRC_out
when 102 => SRRC_out
when 103 => SRRC_out
when 104 => SRRC_out
when 105 => SRRC_out
when 106 => SRRC_out
when 107 => SRRC_out
when 108 => SRRC_out
when 109 => SRRC_out
when 110 => SRRC_out
when 111 => SRRC_out
when 112 => SRRC_out
when 113 => SRRC_out
when 114 => SRRC_out
when 115 => SRRC_out
when 116 => SRRC_out
when 117 => SRRC_out
when 118 => SRRC_out
when 119 => SRRC_out
when 120 => SRRC_out
when 121 => SRRC_out
when 122 => SRRC_out
when 123 => SRRC_out
when 124 => SRRC_out
when 125 => SRRC_out
when 126 => SRRC_out
when 127 => SRRC_out
-- somme per il FIR 1
when 128 => SRRC_out
when 129 => SRRC_out
when 130 => SRRC_out
when 131 => SRRC_out
when 132 => SRRC_out
when 133 => SRRC_out
when 134 => SRRC_out
when 135 => SRRC_out
when 136 => SRRC_out
when 137 => SRRC_out
when 138 => SRRC_out
when 139 => SRRC_out
when 140 => SRRC_out
when 141 => SRRC_out
when 142 => SRRC_out
when 143 => SRRC_out
when 144 => SRRC_out
when 145 => SRRC_out
when 146 => SRRC_out
when 147 => SRRC_out
when 148 => SRRC_out
when 149 => SRRC_out
when 150 => SRRC_out
when 151 => SRRC_out
when 152 => SRRC_out
when 153 => SRRC_out
when 154 => SRRC_out
when 155 => SRRC_out
when 156 => SRRC_out
when 157 => SRRC_out
when 158 => SRRC_out
when 159 => SRRC_out
when 160 => SRRC_out
when 161 => SRRC_out
when 162 => SRRC_out
when 163 => SRRC_out
when 164 => SRRC_out
when 165 => SRRC_out
when 166 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"4A7";
X"4A7";
X"248";
X"248";
X"256";
X"256";
X"292";
X"292";
X"2A0";
X"2A0";
X"AF2";
X"AF2";
X"B01";
X"B01";
X"B3C";
X"B3C";
X"B4A";
X"B4A";
X"8EB";
X"8EB";
X"8FA";
X"8FA";
X"935";
X"935";
X"943";
X"943";
X"61A";
X"61A";
X"629";
X"629";
X"664";
X"664";
X"672";
X"672";
X"413";
X"413";
X"422";
X"422";
X"45D";
X"45D";
X"46B";
X"46B";
X"CBE";
X"CBE";
X"CCC";
X"CCC";
X"D07";
X"D07";
X"D16";
X"D16";
X"AB7";
X"AB7";
X"AC5";
X"AC5";
X"B00";
X"B00";
X"B0F";
X"B0F";
X"4F5";
X"4F5";
X"49D";
X"49D";
X"647";
X"647";
X"5EF";
X"5EF";
X"F07";
X"F07";
X"EAE";
X"EAE";
X"059";
X"059";
X"000";
X"000";
X"F07";
X"F07";
X"EAE";
X"EAE";
X"059";
X"059";
X"000";
X"000";
X"918";
X"918";
X"8BF";
X"8BF";
X"A6A";
X"A6A";
X"A11";
X"A11";
X"647";
X"647";
X"5EF";
X"5EF";
X"79A";
X"79A";
X"741";
149
APPENDICE F. LISTATI VHDL
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
when 167 => SRRC_out
when 168 => SRRC_out
when 169 => SRRC_out
when 170 => SRRC_out
when 171 => SRRC_out
when 172 => SRRC_out
when 173 => SRRC_out
when 174 => SRRC_out
when 175 => SRRC_out
when 176 => SRRC_out
when 177 => SRRC_out
when 178 => SRRC_out
when 179 => SRRC_out
when 180 => SRRC_out
when 181 => SRRC_out
when 182 => SRRC_out
when 183 => SRRC_out
when 184 => SRRC_out
when 185 => SRRC_out
when 186 => SRRC_out
when 187 => SRRC_out
when 188 => SRRC_out
when 189 => SRRC_out
when 190 => SRRC_out
when 191 => SRRC_out
when 192 => SRRC_out
when 193 => SRRC_out
when 194 => SRRC_out
when 195 => SRRC_out
when 196 => SRRC_out
when 197 => SRRC_out
when 198 => SRRC_out
when 199 => SRRC_out
when 200 => SRRC_out
when 201 => SRRC_out
when 202 => SRRC_out
when 203 => SRRC_out
when 204 => SRRC_out
when 205 => SRRC_out
when 206 => SRRC_out
when 207 => SRRC_out
when 208 => SRRC_out
when 209 => SRRC_out
when 210 => SRRC_out
when 211 => SRRC_out
when 212 => SRRC_out
when 213 => SRRC_out
when 214 => SRRC_out
when 215 => SRRC_out
when 216 => SRRC_out
when 217 => SRRC_out
when 218 => SRRC_out
when 219 => SRRC_out
when 220 => SRRC_out
when 221 => SRRC_out
when 222 => SRRC_out
when 223 => SRRC_out
when 224 => SRRC_out
when 225 => SRRC_out
when 226 => SRRC_out
when 227 => SRRC_out
when 228 => SRRC_out
when 229 => SRRC_out
when 230 => SRRC_out
when 231 => SRRC_out
when 232 => SRRC_out
when 233 => SRRC_out
when 234 => SRRC_out
when 235 => SRRC_out
when 236 => SRRC_out
when 237 => SRRC_out
when 238 => SRRC_out
when 239 => SRRC_out
when 240 => SRRC_out
when 241 => SRRC_out
when 242 => SRRC_out
when 243 => SRRC_out
when 244 => SRRC_out
when 245 => SRRC_out
when 246 => SRRC_out
when 247 => SRRC_out
when 248 => SRRC_out
when 249 => SRRC_out
when 250 => SRRC_out
when 251 => SRRC_out
when 252 => SRRC_out
when 253 => SRRC_out
when 254 => SRRC_out
when 255 => SRRC_out
-- somme per il FIR 2
when 256 => SRRC_out
when 257 => SRRC_out
when 258 => SRRC_out
when 259 => SRRC_out
when 260 => SRRC_out
when 261 => SRRC_out
when 262 => SRRC_out
when 263 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"741";
X"059";
X"059";
X"000";
X"000";
X"1AB";
X"1AB";
X"152";
X"152";
X"059";
X"059";
X"000";
X"000";
X"1AB";
X"1AB";
X"152";
X"152";
X"A6A";
X"A6A";
X"A11";
X"A11";
X"BBC";
X"BBC";
X"B63";
X"B63";
X"49D";
X"49D";
X"444";
X"444";
X"5EF";
X"5EF";
X"596";
X"596";
X"EAE";
X"EAE";
X"E55";
X"E55";
X"000";
X"000";
X"FA7";
X"FA7";
X"EAE";
X"EAE";
X"E55";
X"E55";
X"000";
X"000";
X"FA7";
X"FA7";
X"8BF";
X"8BF";
X"866";
X"866";
X"A11";
X"A11";
X"9B9";
X"9B9";
X"5EF";
X"5EF";
X"596";
X"596";
X"741";
X"741";
X"6E8";
X"6E8";
X"000";
X"000";
X"FA7";
X"FA7";
X"152";
X"152";
X"0F9";
X"0F9";
X"000";
X"000";
X"FA7";
X"FA7";
X"152";
X"152";
X"0F9";
X"0F9";
X"A11";
X"A11";
X"9B9";
X"9B9";
X"B63";
X"B63";
X"B0B";
X"B0B";
X"4F1";
X"4F1";
X"44F";
X"44F";
X"6BD";
X"6BD";
X"61A";
X"61A";
150
APPENDICE F. LISTATI VHDL
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"B95";
X"B95";
X"AF2";
X"AF2";
X"D60";
X"D60";
X"CBE";
X"CBE";
X"2EA";
X"2EA";
X"248";
X"248";
X"4B6";
X"4B6";
X"413";
X"413";
X"98E";
X"98E";
X"8EB";
X"8EB";
X"B59";
X"B59";
X"AB7";
X"AB7";
X"53B";
X"53B";
X"499";
X"499";
X"706";
X"706";
X"664";
X"664";
X"BDE";
X"BDE";
X"B3C";
X"B3C";
X"DAA";
X"DAA";
X"D07";
X"D07";
X"334";
X"334";
X"292";
X"292";
X"4FF";
X"4FF";
X"45D";
X"45D";
X"9D7";
X"9D7";
X"935";
X"935";
X"BA3";
X"BA3";
X"B00";
X"B00";
X"500";
X"500";
X"45D";
X"45D";
X"6CB";
X"6CB";
X"629";
X"629";
X"BA3";
X"BA3";
X"B01";
X"B01";
X"D6E";
X"D6E";
X"CCC";
X"CCC";
X"2F9";
X"2F9";
X"256";
X"256";
X"4C4";
X"4C4";
X"422";
X"422";
X"99C";
X"99C";
X"8FA";
X"8FA";
X"B67";
X"B67";
X"AC5";
X"AC5";
X"549";
X"549";
X"4A7";
X"4A7";
X"715";
X"715";
X"672";
X"672";
X"BED";
X"BED";
151
APPENDICE F. LISTATI VHDL
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
when 362 => SRRC_out
when 363 => SRRC_out
when 364 => SRRC_out
when 365 => SRRC_out
when 366 => SRRC_out
when 367 => SRRC_out
when 368 => SRRC_out
when 369 => SRRC_out
when 370 => SRRC_out
when 371 => SRRC_out
when 372 => SRRC_out
when 373 => SRRC_out
when 374 => SRRC_out
when 375 => SRRC_out
when 376 => SRRC_out
when 377 => SRRC_out
when 378 => SRRC_out
when 379 => SRRC_out
when 380 => SRRC_out
when 381 => SRRC_out
when 382 => SRRC_out
when 383 => SRRC_out
-- somme per il FIR 3
when 384 => SRRC_out
when 385 => SRRC_out
when 386 => SRRC_out
when 387 => SRRC_out
when 388 => SRRC_out
when 389 => SRRC_out
when 390 => SRRC_out
when 391 => SRRC_out
when 392 => SRRC_out
when 393 => SRRC_out
when 394 => SRRC_out
when 395 => SRRC_out
when 396 => SRRC_out
when 397 => SRRC_out
when 398 => SRRC_out
when 399 => SRRC_out
when 400 => SRRC_out
when 401 => SRRC_out
when 402 => SRRC_out
when 403 => SRRC_out
when 404 => SRRC_out
when 405 => SRRC_out
when 406 => SRRC_out
when 407 => SRRC_out
when 408 => SRRC_out
when 409 => SRRC_out
when 410 => SRRC_out
when 411 => SRRC_out
when 412 => SRRC_out
when 413 => SRRC_out
when 414 => SRRC_out
when 415 => SRRC_out
when 416 => SRRC_out
when 417 => SRRC_out
when 418 => SRRC_out
when 419 => SRRC_out
when 420 => SRRC_out
when 421 => SRRC_out
when 422 => SRRC_out
when 423 => SRRC_out
when 424 => SRRC_out
when 425 => SRRC_out
when 426 => SRRC_out
when 427 => SRRC_out
when 428 => SRRC_out
when 429 => SRRC_out
when 430 => SRRC_out
when 431 => SRRC_out
when 432 => SRRC_out
when 433 => SRRC_out
when 434 => SRRC_out
when 435 => SRRC_out
when 436 => SRRC_out
when 437 => SRRC_out
when 438 => SRRC_out
when 439 => SRRC_out
when 440 => SRRC_out
when 441 => SRRC_out
when 442 => SRRC_out
when 443 => SRRC_out
when 444 => SRRC_out
when 445 => SRRC_out
when 446 => SRRC_out
when 447 => SRRC_out
when 448 => SRRC_out
when 449 => SRRC_out
when 450 => SRRC_out
when 451 => SRRC_out
when 452 => SRRC_out
when 453 => SRRC_out
when 454 => SRRC_out
when 455 => SRRC_out
when 456 => SRRC_out
when 457 => SRRC_out
when 458 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"B4A";
X"B4A";
X"DB8";
X"DB8";
X"D16";
X"D16";
X"342";
X"342";
X"2A0";
X"2A0";
X"50E";
X"50E";
X"46B";
X"46B";
X"9E6";
X"9E6";
X"943";
X"943";
X"BB1";
X"BB1";
X"B0F";
X"B0F";
X"4BC";
X"50D";
X"443";
X"493";
X"586";
X"5D6";
X"50D";
X"55D";
X"A02";
X"A53";
X"989";
X"9D9";
X"ACC";
X"B1C";
X"A53";
X"AA3";
X"586";
X"5D6";
X"50D";
X"55D";
X"64F";
X"6A0";
X"5D6";
X"627";
X"ACC";
X"B1C";
X"A53";
X"AA3";
X"B95";
X"BE6";
X"B1C";
X"B6D";
X"443";
X"493";
X"3CA";
X"41A";
X"50D";
X"55D";
X"494";
X"4E4";
X"989";
X"9D9";
X"910";
X"960";
X"A53";
X"AA3";
X"9DA";
X"A2A";
X"50D";
X"55D";
X"494";
X"4E4";
X"5D6";
X"627";
X"55D";
X"5AD";
X"A53";
X"AA3";
X"9DA";
X"A2A";
X"B1C";
X"B6D";
X"AA3";
X"AF3";
X"50D";
X"55D";
X"493";
X"4E4";
X"5D6";
X"626";
X"55D";
X"5AD";
X"A53";
X"AA3";
X"9D9";
152
APPENDICE F. LISTATI VHDL
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
when 459 => SRRC_out <= X"A2A";
when 460 => SRRC_out <= X"B1C";
when 461 => SRRC_out <= X"B6C";
when 462 => SRRC_out <= X"AA3";
when 463 => SRRC_out <= X"AF3";
when 464 => SRRC_out <= X"5D6";
when 465 => SRRC_out <= X"626";
when 466 => SRRC_out <= X"55D";
when 467 => SRRC_out <= X"5AD";
when 468 => SRRC_out <= X"6A0";
when 469 => SRRC_out <= X"6F0";
when 470 => SRRC_out <= X"627";
when 471 => SRRC_out <= X"677";
when 472 => SRRC_out <= X"B1C";
when 473 => SRRC_out <= X"B6C";
when 474 => SRRC_out <= X"AA3";
when 475 => SRRC_out <= X"AF3";
when 476 => SRRC_out <= X"BE6";
when 477 => SRRC_out <= X"C36";
when 478 => SRRC_out <= X"B6D";
when 479 => SRRC_out <= X"BBD";
when 480 => SRRC_out <= X"493";
when 481 => SRRC_out <= X"4E4";
when 482 => SRRC_out <= X"41A";
when 483 => SRRC_out <= X"46B";
when 484 => SRRC_out <= X"55D";
when 485 => SRRC_out <= X"5AD";
when 486 => SRRC_out <= X"4E4";
when 487 => SRRC_out <= X"534";
when 488 => SRRC_out <= X"9D9";
when 489 => SRRC_out <= X"A2A";
when 490 => SRRC_out <= X"960";
when 491 => SRRC_out <= X"9B1";
when 492 => SRRC_out <= X"AA3";
when 493 => SRRC_out <= X"AF3";
when 494 => SRRC_out <= X"A2A";
when 495 => SRRC_out <= X"A7A";
when 496 => SRRC_out <= X"55D";
when 497 => SRRC_out <= X"5AD";
when 498 => SRRC_out <= X"4E4";
when 499 => SRRC_out <= X"534";
when 500 => SRRC_out <= X"627";
when 501 => SRRC_out <= X"677";
when 502 => SRRC_out <= X"5AD";
when 503 => SRRC_out <= X"5FE";
when 504 => SRRC_out <= X"AA3";
when 505 => SRRC_out <= X"AF3";
when 506 => SRRC_out <= X"A2A";
when 507 => SRRC_out <= X"A7A";
when 508 => SRRC_out <= X"B6D";
when 509 => SRRC_out <= X"BBD";
when 510 => SRRC_out <= X"AF3";
when 511 => SRRC_out <= X"B44";
when OTHERS => SRRC_out <= X"000";
end case;
end process;
end ROMx4_arch;
Listato F.3.8:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
153
ROMx6.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ROMx6 is
port(address : in STD_LOGIC_vector(9 downto 0);
SRRC_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end;
architecture ROMx6_arch of ROMx6 is
begin
process(address)
variable addr : integer ;
begin
addr := conv_integer(address) ;
case addr is
-- somme per il FIR 0
when 0
=> SRRC_out <= X"515";
when 1
=> SRRC_out <= X"515";
when 2
=> SRRC_out <= X"509";
when 3
=> SRRC_out <= X"509";
when 4
=> SRRC_out <= X"5A3";
when 5
=> SRRC_out <= X"5A3";
when 6
=> SRRC_out <= X"597";
when 7
=> SRRC_out <= X"597";
when 8
=> SRRC_out <= X"1C7";
when 9
=> SRRC_out <= X"1C7";
when 10
=> SRRC_out <= X"1BB";
when 11
=> SRRC_out <= X"1BB";
when 12
=> SRRC_out <= X"254";
when 13
=> SRRC_out <= X"254";
APPENDICE F. LISTATI VHDL
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"248";
X"248";
X"C6C";
X"C6C";
X"C60";
X"C60";
X"CF9";
X"CF9";
X"CED";
X"CED";
X"91D";
X"91D";
X"911";
X"911";
X"9AA";
X"9AA";
X"99F";
X"99F";
X"6D8";
X"6D8";
X"6CC";
X"6CC";
X"765";
X"765";
X"759";
X"759";
X"389";
X"389";
X"37D";
X"37D";
X"416";
X"416";
X"40A";
X"40A";
X"E2E";
X"E2E";
X"E23";
X"E23";
X"EBC";
X"EBC";
X"EB0";
X"EB0";
X"AE0";
X"AE0";
X"AD4";
X"AD4";
X"B6D";
X"B6D";
X"B61";
X"B61";
X"49F";
X"49F";
X"493";
X"493";
X"52C";
X"52C";
X"520";
X"520";
X"150";
X"150";
X"144";
X"144";
X"1DD";
X"1DD";
X"1D2";
X"1D2";
X"BF6";
X"BF6";
X"BEA";
X"BEA";
X"C83";
X"C83";
X"C77";
X"C77";
X"8A7";
X"8A7";
X"89B";
X"89B";
X"934";
X"934";
X"928";
X"928";
X"661";
X"661";
X"656";
X"656";
X"6EF";
X"6EF";
X"6E3";
X"6E3";
X"313";
X"313";
X"307";
X"307";
X"3A0";
X"3A0";
X"394";
X"394";
154
APPENDICE F. LISTATI VHDL
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
when 112 => SRRC_out
when 113 => SRRC_out
when 114 => SRRC_out
when 115 => SRRC_out
when 116 => SRRC_out
when 117 => SRRC_out
when 118 => SRRC_out
when 119 => SRRC_out
when 120 => SRRC_out
when 121 => SRRC_out
when 122 => SRRC_out
when 123 => SRRC_out
when 124 => SRRC_out
when 125 => SRRC_out
when 126 => SRRC_out
when 127 => SRRC_out
-- somme per il FIR 1
when 128 => SRRC_out
when 129 => SRRC_out
when 130 => SRRC_out
when 131 => SRRC_out
when 132 => SRRC_out
when 133 => SRRC_out
when 134 => SRRC_out
when 135 => SRRC_out
when 136 => SRRC_out
when 137 => SRRC_out
when 138 => SRRC_out
when 139 => SRRC_out
when 140 => SRRC_out
when 141 => SRRC_out
when 142 => SRRC_out
when 143 => SRRC_out
when 144 => SRRC_out
when 145 => SRRC_out
when 146 => SRRC_out
when 147 => SRRC_out
when 148 => SRRC_out
when 149 => SRRC_out
when 150 => SRRC_out
when 151 => SRRC_out
when 152 => SRRC_out
when 153 => SRRC_out
when 154 => SRRC_out
when 155 => SRRC_out
when 156 => SRRC_out
when 157 => SRRC_out
when 158 => SRRC_out
when 159 => SRRC_out
when 160 => SRRC_out
when 161 => SRRC_out
when 162 => SRRC_out
when 163 => SRRC_out
when 164 => SRRC_out
when 165 => SRRC_out
when 166 => SRRC_out
when 167 => SRRC_out
when 168 => SRRC_out
when 169 => SRRC_out
when 170 => SRRC_out
when 171 => SRRC_out
when 172 => SRRC_out
when 173 => SRRC_out
when 174 => SRRC_out
when 175 => SRRC_out
when 176 => SRRC_out
when 177 => SRRC_out
when 178 => SRRC_out
when 179 => SRRC_out
when 180 => SRRC_out
when 181 => SRRC_out
when 182 => SRRC_out
when 183 => SRRC_out
when 184 => SRRC_out
when 185 => SRRC_out
when 186 => SRRC_out
when 187 => SRRC_out
when 188 => SRRC_out
when 189 => SRRC_out
when 190 => SRRC_out
when 191 => SRRC_out
when 192 => SRRC_out
when 193 => SRRC_out
when 194 => SRRC_out
when 195 => SRRC_out
when 196 => SRRC_out
when 197 => SRRC_out
when 198 => SRRC_out
when 199 => SRRC_out
when 200 => SRRC_out
when 201 => SRRC_out
when 202 => SRRC_out
when 203 => SRRC_out
when 204 => SRRC_out
when 205 => SRRC_out
when 206 => SRRC_out
when 207 => SRRC_out
when 208 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"DB8";
X"DB8";
X"DAC";
X"DAC";
X"E45";
X"E45";
X"E39";
X"E39";
X"A69";
X"A69";
X"A5D";
X"A5D";
X"AF7";
X"AF7";
X"AEB";
X"AEB";
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"513";
X"513";
X"4D3";
X"4D3";
X"656";
X"656";
X"616";
X"616";
X"EFC";
X"EFC";
X"EBD";
X"EBD";
X"040";
X"040";
X"000";
X"000";
X"EFC";
X"EFC";
X"EBD";
X"EBD";
X"040";
X"040";
X"000";
X"000";
X"8E6";
X"8E6";
X"8A6";
X"8A6";
X"A29";
X"A29";
X"9EA";
X"9EA";
X"656";
X"656";
X"616";
X"616";
X"79A";
X"79A";
X"75A";
X"75A";
X"040";
X"040";
X"000";
X"000";
X"183";
X"183";
X"143";
X"143";
X"040";
X"040";
X"000";
X"000";
X"183";
X"183";
X"143";
X"143";
X"A29";
X"A29";
X"9EA";
X"9EA";
X"B6D";
X"B6D";
X"B2D";
X"B2D";
X"4D3";
X"4D3";
X"493";
X"493";
X"616";
X"616";
X"5D7";
X"5D7";
X"EBD";
X"EBD";
X"E7D";
X"E7D";
X"000";
X"000";
X"FC0";
X"FC0";
X"EBD";
155
APPENDICE F. LISTATI VHDL
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
when 209 => SRRC_out
when 210 => SRRC_out
when 211 => SRRC_out
when 212 => SRRC_out
when 213 => SRRC_out
when 214 => SRRC_out
when 215 => SRRC_out
when 216 => SRRC_out
when 217 => SRRC_out
when 218 => SRRC_out
when 219 => SRRC_out
when 220 => SRRC_out
when 221 => SRRC_out
when 222 => SRRC_out
when 223 => SRRC_out
when 224 => SRRC_out
when 225 => SRRC_out
when 226 => SRRC_out
when 227 => SRRC_out
when 228 => SRRC_out
when 229 => SRRC_out
when 230 => SRRC_out
when 231 => SRRC_out
when 232 => SRRC_out
when 233 => SRRC_out
when 234 => SRRC_out
when 235 => SRRC_out
when 236 => SRRC_out
when 237 => SRRC_out
when 238 => SRRC_out
when 239 => SRRC_out
when 240 => SRRC_out
when 241 => SRRC_out
when 242 => SRRC_out
when 243 => SRRC_out
when 244 => SRRC_out
when 245 => SRRC_out
when 246 => SRRC_out
when 247 => SRRC_out
when 248 => SRRC_out
when 249 => SRRC_out
when 250 => SRRC_out
when 251 => SRRC_out
when 252 => SRRC_out
when 253 => SRRC_out
when 254 => SRRC_out
when 255 => SRRC_out
-- somme per il FIR 2
when 256 => SRRC_out
when 257 => SRRC_out
when 258 => SRRC_out
when 259 => SRRC_out
when 260 => SRRC_out
when 261 => SRRC_out
when 262 => SRRC_out
when 263 => SRRC_out
when 264 => SRRC_out
when 265 => SRRC_out
when 266 => SRRC_out
when 267 => SRRC_out
when 268 => SRRC_out
when 269 => SRRC_out
when 270 => SRRC_out
when 271 => SRRC_out
when 272 => SRRC_out
when 273 => SRRC_out
when 274 => SRRC_out
when 275 => SRRC_out
when 276 => SRRC_out
when 277 => SRRC_out
when 278 => SRRC_out
when 279 => SRRC_out
when 280 => SRRC_out
when 281 => SRRC_out
when 282 => SRRC_out
when 283 => SRRC_out
when 284 => SRRC_out
when 285 => SRRC_out
when 286 => SRRC_out
when 287 => SRRC_out
when 288 => SRRC_out
when 289 => SRRC_out
when 290 => SRRC_out
when 291 => SRRC_out
when 292 => SRRC_out
when 293 => SRRC_out
when 294 => SRRC_out
when 295 => SRRC_out
when 296 => SRRC_out
when 297 => SRRC_out
when 298 => SRRC_out
when 299 => SRRC_out
when 300 => SRRC_out
when 301 => SRRC_out
when 302 => SRRC_out
when 303 => SRRC_out
when 304 => SRRC_out
when 305 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"EBD";
X"E7D";
X"E7D";
X"000";
X"000";
X"FC0";
X"FC0";
X"8A6";
X"8A6";
X"866";
X"866";
X"9EA";
X"9EA";
X"9AA";
X"9AA";
X"616";
X"616";
X"5D7";
X"5D7";
X"75A";
X"75A";
X"71A";
X"71A";
X"000";
X"000";
X"FC0";
X"FC0";
X"143";
X"143";
X"104";
X"104";
X"000";
X"000";
X"FC0";
X"FC0";
X"143";
X"143";
X"104";
X"104";
X"9EA";
X"9EA";
X"9AA";
X"9AA";
X"B2D";
X"B2D";
X"AED";
X"AED";
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"515";
X"515";
X"49F";
X"49F";
X"6D8";
X"6D8";
X"661";
X"661";
X"C6C";
X"C6C";
X"BF6";
X"BF6";
X"E2E";
X"E2E";
X"DB8";
X"DB8";
X"1C7";
X"1C7";
X"150";
X"150";
X"389";
X"389";
X"313";
X"313";
X"91D";
X"91D";
X"8A7";
X"8A7";
X"AE0";
X"AE0";
X"A69";
X"A69";
X"5A3";
X"5A3";
X"52C";
X"52C";
X"765";
X"765";
X"6EF";
X"6EF";
X"CF9";
X"CF9";
X"C83";
X"C83";
X"EBC";
X"EBC";
X"E45";
X"E45";
X"254";
X"254";
156
APPENDICE F. LISTATI VHDL
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
when 306 => SRRC_out
when 307 => SRRC_out
when 308 => SRRC_out
when 309 => SRRC_out
when 310 => SRRC_out
when 311 => SRRC_out
when 312 => SRRC_out
when 313 => SRRC_out
when 314 => SRRC_out
when 315 => SRRC_out
when 316 => SRRC_out
when 317 => SRRC_out
when 318 => SRRC_out
when 319 => SRRC_out
when 320 => SRRC_out
when 321 => SRRC_out
when 322 => SRRC_out
when 323 => SRRC_out
when 324 => SRRC_out
when 325 => SRRC_out
when 326 => SRRC_out
when 327 => SRRC_out
when 328 => SRRC_out
when 329 => SRRC_out
when 330 => SRRC_out
when 331 => SRRC_out
when 332 => SRRC_out
when 333 => SRRC_out
when 334 => SRRC_out
when 335 => SRRC_out
when 336 => SRRC_out
when 337 => SRRC_out
when 338 => SRRC_out
when 339 => SRRC_out
when 340 => SRRC_out
when 341 => SRRC_out
when 342 => SRRC_out
when 343 => SRRC_out
when 344 => SRRC_out
when 345 => SRRC_out
when 346 => SRRC_out
when 347 => SRRC_out
when 348 => SRRC_out
when 349 => SRRC_out
when 350 => SRRC_out
when 351 => SRRC_out
when 352 => SRRC_out
when 353 => SRRC_out
when 354 => SRRC_out
when 355 => SRRC_out
when 356 => SRRC_out
when 357 => SRRC_out
when 358 => SRRC_out
when 359 => SRRC_out
when 360 => SRRC_out
when 361 => SRRC_out
when 362 => SRRC_out
when 363 => SRRC_out
when 364 => SRRC_out
when 365 => SRRC_out
when 366 => SRRC_out
when 367 => SRRC_out
when 368 => SRRC_out
when 369 => SRRC_out
when 370 => SRRC_out
when 371 => SRRC_out
when 372 => SRRC_out
when 373 => SRRC_out
when 374 => SRRC_out
when 375 => SRRC_out
when 376 => SRRC_out
when 377 => SRRC_out
when 378 => SRRC_out
when 379 => SRRC_out
when 380 => SRRC_out
when 381 => SRRC_out
when 382 => SRRC_out
when 383 => SRRC_out
-- somme per il FIR 3
when 384 => SRRC_out
when 385 => SRRC_out
when 386 => SRRC_out
when 387 => SRRC_out
when 388 => SRRC_out
when 389 => SRRC_out
when 390 => SRRC_out
when 391 => SRRC_out
when 392 => SRRC_out
when 393 => SRRC_out
when 394 => SRRC_out
when 395 => SRRC_out
when 396 => SRRC_out
when 397 => SRRC_out
when 398 => SRRC_out
when 399 => SRRC_out
when 400 => SRRC_out
when 401 => SRRC_out
when 402 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"1DD";
X"1DD";
X"416";
X"416";
X"3A0";
X"3A0";
X"9AA";
X"9AA";
X"934";
X"934";
X"B6D";
X"B6D";
X"AF7";
X"AF7";
X"509";
X"509";
X"493";
X"493";
X"6CC";
X"6CC";
X"656";
X"656";
X"C60";
X"C60";
X"BEA";
X"BEA";
X"E23";
X"E23";
X"DAC";
X"DAC";
X"1BB";
X"1BB";
X"144";
X"144";
X"37D";
X"37D";
X"307";
X"307";
X"911";
X"911";
X"89B";
X"89B";
X"AD4";
X"AD4";
X"A5D";
X"A5D";
X"597";
X"597";
X"520";
X"520";
X"759";
X"759";
X"6E3";
X"6E3";
X"CED";
X"CED";
X"C77";
X"C77";
X"EB0";
X"EB0";
X"E39";
X"E39";
X"248";
X"248";
X"1D2";
X"1D2";
X"40A";
X"40A";
X"394";
X"394";
X"99F";
X"99F";
X"928";
X"928";
X"B61";
X"B61";
X"AEB";
X"AEB";
X"505";
X"52F";
X"471";
X"49B";
X"6BB";
X"6E6";
X"628";
X"652";
X"A8A";
X"AB4";
X"9F6";
X"A21";
X"C41";
X"C6B";
X"BAD";
X"BD7";
X"429";
X"453";
X"395";
157
APPENDICE F. LISTATI VHDL
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
when
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"3BF";
X"5DF";
X"60A";
X"54B";
X"576";
X"9AE";
X"9D8";
X"91A";
X"944";
X"B64";
X"B8F";
X"AD1";
X"AFB";
X"4EF";
X"519";
X"45B";
X"485";
X"6A5";
X"6D0";
X"611";
X"63C";
X"A74";
X"A9E";
X"9E0";
X"A0A";
X"C2A";
X"C55";
X"B96";
X"BC1";
X"413";
X"43D";
X"37F";
X"3A9";
X"5C9";
X"5F4";
X"535";
X"560";
X"998";
X"9C2";
X"904";
X"92E";
X"B4E";
X"B79";
X"ABA";
X"AE5";
X"51B";
X"546";
X"487";
X"4B2";
X"6D2";
X"6FC";
X"63E";
X"668";
X"AA0";
X"ACB";
X"A0C";
X"A37";
X"C57";
X"C81";
X"BC3";
X"BED";
X"43F";
X"46A";
X"3AB";
X"3D6";
X"5F6";
X"620";
X"562";
X"58C";
X"9C4";
X"9EF";
X"930";
X"95B";
X"B7B";
X"BA5";
X"AE7";
X"B11";
X"505";
X"52F";
X"471";
X"49C";
X"6BC";
X"6E6";
X"628";
X"652";
X"A8A";
X"AB5";
X"9F6";
X"A21";
X"C41";
X"C6B";
X"BAD";
X"BD7";
X"429";
X"453";
X"395";
X"3BF";
X"5DF";
158
APPENDICE F. LISTATI VHDL
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
when 501 => SRRC_out
when 502 => SRRC_out
when 503 => SRRC_out
when 504 => SRRC_out
when 505 => SRRC_out
when 506 => SRRC_out
when 507 => SRRC_out
when 508 => SRRC_out
when 509 => SRRC_out
when 510 => SRRC_out
when 511 => SRRC_out
-- somme per il FIR 4
when 512 => SRRC_out
when 513 => SRRC_out
when 514 => SRRC_out
when 515 => SRRC_out
when 516 => SRRC_out
when 517 => SRRC_out
when 518 => SRRC_out
when 519 => SRRC_out
when 520 => SRRC_out
when 521 => SRRC_out
when 522 => SRRC_out
when 523 => SRRC_out
when 524 => SRRC_out
when 525 => SRRC_out
when 526 => SRRC_out
when 527 => SRRC_out
when 528 => SRRC_out
when 529 => SRRC_out
when 530 => SRRC_out
when 531 => SRRC_out
when 532 => SRRC_out
when 533 => SRRC_out
when 534 => SRRC_out
when 535 => SRRC_out
when 536 => SRRC_out
when 537 => SRRC_out
when 538 => SRRC_out
when 539 => SRRC_out
when 540 => SRRC_out
when 541 => SRRC_out
when 542 => SRRC_out
when 543 => SRRC_out
when 544 => SRRC_out
when 545 => SRRC_out
when 546 => SRRC_out
when 547 => SRRC_out
when 548 => SRRC_out
when 549 => SRRC_out
when 550 => SRRC_out
when 551 => SRRC_out
when 552 => SRRC_out
when 553 => SRRC_out
when 554 => SRRC_out
when 555 => SRRC_out
when 556 => SRRC_out
when 557 => SRRC_out
when 558 => SRRC_out
when 559 => SRRC_out
when 560 => SRRC_out
when 561 => SRRC_out
when 562 => SRRC_out
when 563 => SRRC_out
when 564 => SRRC_out
when 565 => SRRC_out
when 566 => SRRC_out
when 567 => SRRC_out
when 568 => SRRC_out
when 569 => SRRC_out
when 570 => SRRC_out
when 571 => SRRC_out
when 572 => SRRC_out
when 573 => SRRC_out
when 574 => SRRC_out
when 575 => SRRC_out
when 576 => SRRC_out
when 577 => SRRC_out
when 578 => SRRC_out
when 579 => SRRC_out
when 580 => SRRC_out
when 581 => SRRC_out
when 582 => SRRC_out
when 583 => SRRC_out
when 584 => SRRC_out
when 585 => SRRC_out
when 586 => SRRC_out
when 587 => SRRC_out
when 588 => SRRC_out
when 589 => SRRC_out
when 590 => SRRC_out
when 591 => SRRC_out
when 592 => SRRC_out
when 593 => SRRC_out
when 594 => SRRC_out
when 595 => SRRC_out
when 596 => SRRC_out
when 597 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"60A";
X"54C";
X"576";
X"9AE";
X"9D8";
X"91A";
X"945";
X"B65";
X"B8F";
X"AD1";
X"AFB";
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"508";
X"52D";
X"48E";
X"4B4";
X"5E5";
X"60B";
X"56C";
X"591";
X"9E5";
X"A0B";
X"96B";
X"991";
X"AC2";
X"AE8";
X"A49";
X"A6F";
X"5E5";
X"60B";
X"56C";
X"591";
X"6C3";
X"6E9";
X"649";
X"66F";
X"AC2";
X"AE8";
X"A49";
X"A6F";
X"BA0";
X"BC6";
X"B26";
X"B4C";
X"48E";
X"4B4";
X"414";
X"43A";
X"56C";
X"591";
X"4F2";
X"518";
X"96B";
X"991";
X"8F1";
X"917";
X"A49";
X"A6F";
X"9CF";
X"9F5";
X"56C";
X"591";
X"4F2";
X"518";
X"649";
X"66F";
X"5D0";
X"5F5";
X"A49";
X"A6F";
X"9CF";
X"9F5";
X"B26";
X"B4C";
X"AAD";
X"AD3";
X"52D";
X"553";
X"4B4";
X"4DA";
X"60B";
X"631";
X"591";
X"5B7";
X"A0B";
X"A30";
X"991";
X"9B7";
X"AE8";
X"B0E";
X"A6F";
X"A94";
X"60B";
X"631";
X"591";
X"5B7";
X"6E9";
X"70F";
159
APPENDICE F. LISTATI VHDL
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
when 598 => SRRC_out
when 599 => SRRC_out
when 600 => SRRC_out
when 601 => SRRC_out
when 602 => SRRC_out
when 603 => SRRC_out
when 604 => SRRC_out
when 605 => SRRC_out
when 606 => SRRC_out
when 607 => SRRC_out
when 608 => SRRC_out
when 609 => SRRC_out
when 610 => SRRC_out
when 611 => SRRC_out
when 612 => SRRC_out
when 613 => SRRC_out
when 614 => SRRC_out
when 615 => SRRC_out
when 616 => SRRC_out
when 617 => SRRC_out
when 618 => SRRC_out
when 619 => SRRC_out
when 620 => SRRC_out
when 621 => SRRC_out
when 622 => SRRC_out
when 623 => SRRC_out
when 624 => SRRC_out
when 625 => SRRC_out
when 626 => SRRC_out
when 627 => SRRC_out
when 628 => SRRC_out
when 629 => SRRC_out
when 630 => SRRC_out
when 631 => SRRC_out
when 632 => SRRC_out
when 633 => SRRC_out
when 634 => SRRC_out
when 635 => SRRC_out
when 636 => SRRC_out
when 637 => SRRC_out
when 638 => SRRC_out
when 639 => SRRC_out
-- somme per il FIR 5
when 640 => SRRC_out
when 641 => SRRC_out
when 642 => SRRC_out
when 643 => SRRC_out
when 644 => SRRC_out
when 645 => SRRC_out
when 646 => SRRC_out
when 647 => SRRC_out
when 648 => SRRC_out
when 649 => SRRC_out
when 650 => SRRC_out
when 651 => SRRC_out
when 652 => SRRC_out
when 653 => SRRC_out
when 654 => SRRC_out
when 655 => SRRC_out
when 656 => SRRC_out
when 657 => SRRC_out
when 658 => SRRC_out
when 659 => SRRC_out
when 660 => SRRC_out
when 661 => SRRC_out
when 662 => SRRC_out
when 663 => SRRC_out
when 664 => SRRC_out
when 665 => SRRC_out
when 666 => SRRC_out
when 667 => SRRC_out
when 668 => SRRC_out
when 669 => SRRC_out
when 670 => SRRC_out
when 671 => SRRC_out
when 672 => SRRC_out
when 673 => SRRC_out
when 674 => SRRC_out
when 675 => SRRC_out
when 676 => SRRC_out
when 677 => SRRC_out
when 678 => SRRC_out
when 679 => SRRC_out
when 680 => SRRC_out
when 681 => SRRC_out
when 682 => SRRC_out
when 683 => SRRC_out
when 684 => SRRC_out
when 685 => SRRC_out
when 686 => SRRC_out
when 687 => SRRC_out
when 688 => SRRC_out
when 689 => SRRC_out
when 690 => SRRC_out
when 691 => SRRC_out
when 692 => SRRC_out
when 693 => SRRC_out
when 694 => SRRC_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
X"66F";
X"695";
X"AE8";
X"B0E";
X"A6F";
X"A94";
X"BC6";
X"BEC";
X"B4C";
X"B72";
X"4B4";
X"4DA";
X"43A";
X"460";
X"591";
X"5B7";
X"518";
X"53E";
X"991";
X"9B7";
X"917";
X"93D";
X"A6F";
X"A94";
X"9F5";
X"A1B";
X"591";
X"5B7";
X"518";
X"53E";
X"66F";
X"695";
X"5F5";
X"61B";
X"A6F";
X"A94";
X"9F5";
X"A1B";
X"B4C";
X"B72";
X"AD3";
X"AF8";
X"505";
X"51B";
X"4EF";
X"505";
X"429";
X"43F";
X"413";
X"429";
X"A8A";
X"AA0";
X"A74";
X"A8A";
X"9AE";
X"9C4";
X"998";
X"9AE";
X"6BB";
X"6D2";
X"6A5";
X"6BC";
X"5DF";
X"5F6";
X"5C9";
X"5DF";
X"C41";
X"C57";
X"C2A";
X"C41";
X"B64";
X"B7B";
X"B4E";
X"B65";
X"471";
X"487";
X"45B";
X"471";
X"395";
X"3AB";
X"37F";
X"395";
X"9F6";
X"A0C";
X"9E0";
X"9F6";
X"91A";
X"930";
X"904";
X"91A";
X"628";
X"63E";
X"611";
X"628";
X"54B";
X"562";
X"535";
160
APPENDICE F. LISTATI VHDL
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
when 695 => SRRC_out <= X"54C";
when 696 => SRRC_out <= X"BAD";
when 697 => SRRC_out <= X"BC3";
when 698 => SRRC_out <= X"B96";
when 699 => SRRC_out <= X"BAD";
when 700 => SRRC_out <= X"AD1";
when 701 => SRRC_out <= X"AE7";
when 702 => SRRC_out <= X"ABA";
when 703 => SRRC_out <= X"AD1";
when 704 => SRRC_out <= X"52F";
when 705 => SRRC_out <= X"546";
when 706 => SRRC_out <= X"519";
when 707 => SRRC_out <= X"52F";
when 708 => SRRC_out <= X"453";
when 709 => SRRC_out <= X"46A";
when 710 => SRRC_out <= X"43D";
when 711 => SRRC_out <= X"453";
when 712 => SRRC_out <= X"AB4";
when 713 => SRRC_out <= X"ACB";
when 714 => SRRC_out <= X"A9E";
when 715 => SRRC_out <= X"AB5";
when 716 => SRRC_out <= X"9D8";
when 717 => SRRC_out <= X"9EF";
when 718 => SRRC_out <= X"9C2";
when 719 => SRRC_out <= X"9D8";
when 720 => SRRC_out <= X"6E6";
when 721 => SRRC_out <= X"6FC";
when 722 => SRRC_out <= X"6D0";
when 723 => SRRC_out <= X"6E6";
when 724 => SRRC_out <= X"60A";
when 725 => SRRC_out <= X"620";
when 726 => SRRC_out <= X"5F4";
when 727 => SRRC_out <= X"60A";
when 728 => SRRC_out <= X"C6B";
when 729 => SRRC_out <= X"C81";
when 730 => SRRC_out <= X"C55";
when 731 => SRRC_out <= X"C6B";
when 732 => SRRC_out <= X"B8F";
when 733 => SRRC_out <= X"BA5";
when 734 => SRRC_out <= X"B79";
when 735 => SRRC_out <= X"B8F";
when 736 => SRRC_out <= X"49B";
when 737 => SRRC_out <= X"4B2";
when 738 => SRRC_out <= X"485";
when 739 => SRRC_out <= X"49C";
when 740 => SRRC_out <= X"3BF";
when 741 => SRRC_out <= X"3D6";
when 742 => SRRC_out <= X"3A9";
when 743 => SRRC_out <= X"3BF";
when 744 => SRRC_out <= X"A21";
when 745 => SRRC_out <= X"A37";
when 746 => SRRC_out <= X"A0A";
when 747 => SRRC_out <= X"A21";
when 748 => SRRC_out <= X"944";
when 749 => SRRC_out <= X"95B";
when 750 => SRRC_out <= X"92E";
when 751 => SRRC_out <= X"945";
when 752 => SRRC_out <= X"652";
when 753 => SRRC_out <= X"668";
when 754 => SRRC_out <= X"63C";
when 755 => SRRC_out <= X"652";
when 756 => SRRC_out <= X"576";
when 757 => SRRC_out <= X"58C";
when 758 => SRRC_out <= X"560";
when 759 => SRRC_out <= X"576";
when 760 => SRRC_out <= X"BD7";
when 761 => SRRC_out <= X"BED";
when 762 => SRRC_out <= X"BC1";
when 763 => SRRC_out <= X"BD7";
when 764 => SRRC_out <= X"AFB";
when 765 => SRRC_out <= X"B11";
when 766 => SRRC_out <= X"AE5";
when 767 => SRRC_out <= X"AFB";
when OTHERS => SRRC_out <= X"000";
end case;
end process;
end ROMx6_arch;
Listato F.3.9:
1
2
3
4
5
6
7
8
9
10
11
12
161
library IEEE;
use IEEE.std_logic_1164.all;
entity shift_reg is
port (
clk
: in std_logic ;
clk_en : in std_logic ;
reset
: in std_logic ;
in_reg : in std_logic ;
out_ffd_1 : out std_logic ;
out_ffd_2 : out std_logic ;
out_ffd_3 : out std_logic ;
shift reg.vhd
APPENDICE F. LISTATI VHDL
out_ffd_4 : out std_logic ;
out_ffd_5 : out std_logic ;
out_ffd_6 : out std_logic
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
architecture shift_reg_arch of shift_reg is
signal temp_out_reg : std_logic_vector(5 downto 0);
begin
process(clk, clk_en, reset)
begin
if reset = ’1’ then
temp_out_reg <= "000000";
elsif rising_edge(clk) then
if clk_en = ’1’ then
temp_out_reg <= in_reg & temp_out_reg(5 downto 1);
end if;
end if;
end process;
out_ffd_6 <= temp_out_reg(0);
out_ffd_5 <= temp_out_reg(1);
out_ffd_4 <= temp_out_reg(2);
out_ffd_3 <= temp_out_reg(3);
out_ffd_2 <= temp_out_reg(4);
out_ffd_1 <= temp_out_reg(5);
end architecture;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
library IEEE;
use IEEE.std_logic_1164.all;
entity Modulator_BlockRAM is
port(
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
to_SRRC_I
: in STD_LOGIC;
to_SRRC_Q
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
clk_2_analyzer : out STD_LOGIC;
QPSK_out
: out STD_LOGIC_VECTOR(11 downto 0)
);
end Modulator_BlockRAM;
architecture Modulator_BlockRAM of Modulator_BlockRAM is
component adder_I_Q
port (
QPSK_I : in STD_LOGIC_VECTOR(11 downto 0);
QPSK_Q : in STD_LOGIC_VECTOR(11 downto 0);
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
QPSK_out
: out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component counter
port (
clk
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
reset : in STD_LOGIC;
clk_en : out STD_LOGIC;
count : out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component multiplier_I_Q
port (
clk
: in STD_LOGIC;
from_NCO
: in STD_LOGIC_VECTOR(1 downto 0);
from_SRRC
: in STD_LOGIC_VECTOR(11 downto 0);
out_mult
: out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component NCO_basic
port (
clk
: in STD_LOGIC;
reset : in STD_LOGIC;
cosine : out STD_LOGIC_VECTOR(1 downto 0);
sine
: out STD_LOGIC_VECTOR(1 downto 0)
);
end component;
component srrc_x_n
port (
clk
: in STD_LOGIC;
clk_en : in STD_LOGIC;
fir_sel : in STD_LOGIC_VECTOR(2 downto 0);
in_fir_MSB : in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
reset : in STD_LOGIC;
out_srrc
: out STD_LOGIC_VECTOR(11 downto 0)
);
end entity;
Listato F.4.1:
Modulator BlockRAM.vhd
162
APPENDICE F. LISTATI VHDL
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
);
end component;
---- Signal declarations used on the diagram ---signal clk_en : STD_LOGIC;
signal cosine : STD_LOGIC_VECTOR (1 downto 0);
signal count_n : STD_LOGIC_VECTOR (2 downto 0);
signal QPSK_I : STD_LOGIC_VECTOR (11 downto 0);
signal QPSK_Q : STD_LOGIC_VECTOR (11 downto 0);
signal sine : STD_LOGIC_VECTOR (1 downto 0);
signal to_mult_I
: STD_LOGIC_VECTOR (11 downto 0);
signal to_mult_Q
: STD_LOGIC_VECTOR (11 downto 0);
begin
U1 : srrc_x_n
port map(
clk
=> clk,
clk_en => clk_en,
fir_sel => count_n,
in_fir_MSB => to_SRRC_I,
out_srrc
=> to_mult_I,
rate_sel
=> rate_sel,
reset => reset
);
U2 : srrc_x_n
port map(
clk
=> clk,
clk_en => clk_en,
fir_sel => count_n,
in_fir_MSB => to_SRRC_Q,
out_srrc
=> to_mult_Q,
rate_sel
=> rate_sel,
reset => reset
);
U3 : counter
port map(
clk
=> clk,
clk_en => clk_en,
count => count_n,
rate_sel
=> rate_sel,
reset => reset
);
U4 : multiplier_I_Q
port map(
clk
=> clk,
from_NCO
=> sine,
from_SRRC
=> to_mult_Q,
out_mult
=> QPSK_Q
);
U5 : multiplier_I_Q
port map(
clk
=> clk,
from_NCO
=> cosine,
from_SRRC
=> to_mult_I,
out_mult
=> QPSK_I
);
U6 : NCO_basic
port map(
clk
=> clk,
cosine => cosine,
reset => reset,
sine
=> sine
);
U7 : adder_I_Q
port map(
QPSK_I => QPSK_I,
QPSK_Q => QPSK_Q,
QPSK_out
=> QPSK_out,
clk
=> clk,
reset => reset
);
clk_2_analyzer <= clk;
end Modulator_BlockRAM;
Listato F.4.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
163
adder I Q.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity adder_I_Q is
port(QPSK_I, QPSK_Q :
in std_logic_vector(11 downto 0);
clk , reset :
in std_logic;
QPSK_out
:
out std_logic_vector(11 downto 0));
end adder_I_Q ;
architecture adder_I_Q_arch of adder_I_Q is
begin
process(reset, clk , QPSK_I , QPSK_Q)
begin
if falling_edge(clk) then
APPENDICE F. LISTATI VHDL
16
17
18
19
20
21
22
23
164
if reset = ’1’ then
QPSK_out <= "000000000000";
else QPSK_out <= QPSK_I + QPSK_Q ;
end if;
else null ;
end if ;
end process;
end adder_I_Q_arch ;
Listato F.4.3: counter.vhd
vedi listato(F.3.2)
Listato F.4.4:
multiplier I Q.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity multiplier_I_Q is
port( from_SRRC :
in std_logic_vector(11 downto 0);
from_NCO : in std_logic_vector( 1 downto 0);
clk
: in std_logic ;
out_mult
:
out std_logic_vector(11 downto 0));
end multiplier_I_Q;
architecture multiplier_I_Q_arch of multiplier_I_Q is
begin
process(clk, from_SRRC ,from_NCO)
variable temp : std_logic_vector(11 downto 0);
begin
if falling_edge(clk) then
temp(11 downto 0) := from_SRRC ;
case from_NCO is
when "11"
=> temp := ("111111111111" xor temp)+1 ;
when "01"
=> null ;
when others => temp := "000000000000" ;
end case;
out_mult(11 downto 0) <= temp(11 downto 0) ;
else null;
end if;
end process;
end multiplier_I_Q_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity NCO_basic is
port( clk
: in std_logic ;
reset : in std_logic ;
cosine :
out std_logic_vector(1 downto 0);
sine :
out std_logic_vector(1 downto 0)
);
end NCO_basic;
Listato F.4.5:
NCO basic.vhd
architecture NCO_basic_arch of NCO_basic is
signal count_4 : STD_LOGIC_VECTOR (1 downto 0) ;
begin
process (clk, reset)
begin
if reset=’1’ then
count_4 <= "00";
else
if falling_edge(clk) then
count_4 <= count_4 + 1 ;
else null ;
end if;
end if;
end process;
process (clk, count_4)
APPENDICE F. LISTATI VHDL
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
begin
if falling_edge(clk) then
case count_4 is
when "00" =>
cosine <= "01" ;
sine <= "00" ;
when "01" =>
cosine <= "00" ;
sine <= "11" ;
when "10" =>
cosine <= "11" ;
sine <= "00" ;
when "11" =>
cosine <= "00" ;
sine <= "01" ;
when others =>
cosine <= "XX" ;
sine <= "XX" ;
end case;
else null;
end if;
end process;
end NCO_basic_arch;
Listato F.4.6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
165
srrc x n.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity srrc_x_n is
port(
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
in_fir_MSB : in STD_LOGIC;
reset
: in STD_LOGIC;
fir_sel : in STD_LOGIC_VECTOR(2 downto 0);
rate_sel : in STD_LOGIC_VECTOR(1 downto 0);
out_srrc : out STD_LOGIC_VECTOR(11 downto 0)
);
end srrc_x_n;
architecture srrc_x_n of srrc_x_n is
component shift_reg
port (
clk
: in STD_LOGIC;
clk_en : in STD_LOGIC;
in_reg : in STD_LOGIC;
reset : in STD_LOGIC;
out_ffd_1
: out STD_LOGIC;
out_ffd_2
: out STD_LOGIC;
out_ffd_3
: out STD_LOGIC;
out_ffd_4
: out STD_LOGIC;
out_ffd_5
: out STD_LOGIC;
out_ffd_6
: out STD_LOGIC
);
end component;
component ram
port (
addr
: in STD_LOGIC_VECTOR(11 downto 0);
clk
: in STD_LOGIC;
dout
: out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal address : STD_LOGIC_VECTOR (11 downto 0);
begin
U1 : shift_reg
port map(
clk
=> clk,
clk_en => clk_en,
in_reg => address(0),
out_ffd_1
=> address(1),
out_ffd_2
=> address(2),
out_ffd_3
=> address(3),
out_ffd_4
=> address(4),
out_ffd_5
=> address(5),
out_ffd_6
=> address(6),
reset => reset
);
U3 : ram
port map(
addr
=> address,
clk
=> clk,
dout
=> out_srrc
);
address(7)
<= fir_sel(0);
address(8)
<= fir_sel(1);
address(9)
<= fir_sel(2);
address(0)
<= in_fir_MSB;
address(10) <= rate_sel(0);
address(11) <= rate_sel(1);
APPENDICE F. LISTATI VHDL
166
66
end srrc_x_n;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
-- synopsys translate_off
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
Library XilinxCoreLib;
ENTITY ram IS
port (
addr : IN std_logic_VECTOR(11 downto 0);
clk
: IN std_logic;
dout : OUT std_logic_VECTOR(11 downto 0));
END ram;
ARCHITECTURE ram_a OF ram IS
component wrapped_ram
port (
addr : IN std_logic_VECTOR(11 downto 0);
clk
: IN std_logic;
dout : OUT std_logic_VECTOR(11 downto 0));
end component;
-- Configuration specification
for all : wrapped_ram
use entity XilinxCoreLib.blkmemsp_v3_1(behavioral)
generic map(
c_reg_inputs => 0,
c_addr_width => 12,
c_has_sinit => 0,
c_has_rdy
=> 0,
c_width
=> 12,
c_has_en
=> 0,
c_mem_init_file
=> "ram.mif",
c_depth
=> 4096,
c_has_nd
=> 0,
c_has_default_data => 0,
c_default_data => "0",
c_limit_data_pitch => 8,
c_pipe_stages => 0,
c_has_rfd
=> 0,
c_has_we
=> 0,
c_sinit_value => "0",
c_has_limit_data_pitch => 0,
c_enable_rlocs => 0,
c_has_din
=> 0,
c_write_mode => 0);
BEGIN
U0 : wrapped_ram
port map (
addr
=> addr,
clk
=> clk,
dout
=> dout);
END ram_a;
-- synopsys translate_on
Listato F.4.7:
ram.vhd
Listato F.4.8: shift reg.vhd
vedi listato(F.3.9)
Listato F.5.1:
1
2
3
4
5
6
7
8
9
10
FIFO RAM ThinModulator.vhd
library IEEE;
use IEEE.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
entity FIFO_RAM_ThinModulator is
port(
clk
: in STD_LOGIC;
count_clk_en_reset : in STD_LOGIC;
APPENDICE F. LISTATI VHDL
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
data_in_I
: in STD_LOGIC;
data_in_Q
: in STD_LOGIC;
data_in_clk
: in std_ulogic;
reset
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
data_in_clk_sync : out STD_LOGIC;
data_out_clk : out STD_LOGIC;
modulator_out : out STD_LOGIC_VECTOR(11 downto 0)
);
end FIFO_RAM_ThinModulator;
architecture FIFO_RAM_ThinModulator of FIFO_RAM_ThinModulator is
component counter
port (
clk
: in STD_LOGIC;
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
reset
: in STD_LOGIC;
clk_en
: out STD_LOGIC;
count
: out STD_LOGIC_VECTOR(2 downto 0)
);
end component;
component Data_Source_Interface
port (
I_to_fifo
: in STD_LOGIC;
Q_to_fifo
: in STD_LOGIC;
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
data_in_clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
I_from_fifo
: out STD_LOGIC;
Q_from_fifo
: out STD_LOGIC
);
end component;
component ThinModulator
port (
I_in_fir_MSB : in STD_LOGIC;
Q_in_fir_MSB : in STD_LOGIC;
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
fir_sel
: in STD_LOGIC_VECTOR(2 downto 0);
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
reset
: in STD_LOGIC;
QPSK_out
: out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component IBUFG
port (
I : in std_ulogic;
O : out std_ulogic
);
end component;
signal clk_en
: STD_LOGIC;
signal clk_to_fifo : STD_LOGIC;
signal I_data_from_fifo : STD_LOGIC;
signal Q_data_from_fifo : STD_LOGIC;
signal fir_sel
: STD_LOGIC_VECTOR (2 downto 0);
for U4 : IBUFG use entity virtex.IBUFG;
begin
U1 : Data_Source_Interface
port map(
I_from_fifo
=> I_data_from_fifo,
I_to_fifo
=> data_in_I,
Q_from_fifo
=> Q_data_from_fifo,
Q_to_fifo
=> data_in_Q,
clk
=> clk,
clk_en
=> clk_en,
data_in_clk
=> clk_to_fifo,
reset
=> reset
);
U2 : ThinModulator
port map(
I_in_fir_MSB => I_data_from_fifo,
QPSK_out
=> modulator_out,
Q_in_fir_MSB => Q_data_from_fifo,
clk
=> clk,
clk_en
=> clk_en,
fir_sel
=> fir_sel,
rate_sel
=> rate_sel,
reset
=> reset
);
U3 : counter
port map(
clk
=> clk,
clk_en
=> clk_en,
count
=> fir_sel,
rate_sel
=> rate_sel,
reset
=> count_clk_en_reset
);
U4 : IBUFG
port map(
I
=> data_in_clk,
O
=> clk_to_fifo
);
data_in_clk_sync
<= clk_en;
167
APPENDICE F. LISTATI VHDL
106
107
data_out_clk <= clk;
end FIFO_RAM_ThinModulator;
Listato F.5.2: counter.vhd
vedi listato(F.3.2)
Listato F.5.3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Data Source Interface.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity Data_Source_Interface is
port(
I_to_fifo
: in STD_LOGIC;
Q_to_fifo
: in STD_LOGIC;
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
data_in_clk
: in STD_LOGIC;
reset
: in STD_LOGIC;
I_from_fifo
: out STD_LOGIC;
Q_from_fifo
: out STD_LOGIC
);
end Data_Source_Interface;
architecture Data_Source_Interface of Data_Source_Interface is
component ffd
port (
clk
: in STD_LOGIC;
in_ffd
: in STD_LOGIC;
reset
: in STD_LOGIC;
out_ffd
: out STD_LOGIC
);
end component;
component ffd_en
port (
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
in_ffd
: in STD_LOGIC;
reset
: in STD_LOGIC;
out_ffd
: out STD_LOGIC
);
end component;
component ffs
port (
S
: in std_ulogic;
clk
: in std_ulogic;
reset
: in std_ulogic;
Q
: out std_ulogic
);
end component;
component asynch_fifo_2x15
port (
ainit
: in STD_LOGIC;
din
: in STD_LOGIC_VECTOR(1 downto 0);
rd_clk
: in STD_LOGIC;
rd_en
: in STD_LOGIC;
wr_clk
: in STD_LOGIC;
wr_en
: in STD_LOGIC;
almost_empty : out STD_LOGIC;
dout
: out STD_LOGIC_VECTOR(1 downto 0);
empty
: out STD_LOGIC;
full
: out STD_LOGIC
);
end component;
constant VCC_CONSTANT
: STD_LOGIC := ’1’;
signal data_in_clk_to_fifo : STD_LOGIC;
signal enable_reading
: STD_LOGIC;
signal fifo_out_enable
: STD_LOGIC;
signal out_enable
: STD_LOGIC;
signal read_enable
: STD_LOGIC;
signal start_rd_en
: STD_LOGIC;
signal VCC
: STD_LOGIC;
signal data_from_fifo
: STD_LOGIC_VECTOR (1 downto 0);
signal data_to_fifo
: STD_LOGIC_VECTOR (1 downto 0);
begin
U1 : asynch_fifo_2x15
168
APPENDICE F. LISTATI VHDL
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
port map(
ainit
almost_empty
din
dout
rd_clk
rd_en
wr_clk
wr_en
);
U11 : ffs
port map(
Q
S
clk
reset
);
U14 : ffd_en
port map(
clk
clk_en
in_ffd
out_ffd
reset
);
U15 : ffd
port map(
clk
in_ffd
out_ffd
reset
);
U2 : ffd
port map(
clk
in_ffd
out_ffd
reset
);
fifo_out_enable
read_enable
VCC
data_to_fifo(0)
data_to_fifo(1)
data_in_clk_to_fifo
end Data_Source_Interface;
=>
=>
=>
=>
=>
=>
=>
reset,
enable_reading,
=> data_to_fifo,
data_from_fifo,
clk,
read_enable,
data_in_clk_to_fifo,
VCC
=> start_rd_en,
=> enable_reading,
=> clk,
=> reset
=>
=>
=>
=>
=> clk,
clk_en,
start_rd_en,
out_enable,
reset
=> clk,
=> data_from_fifo(1),
=> Q_from_fifo,
=> fifo_out_enable
=> clk,
=> data_from_fifo(0),
=> I_from_fifo,
=> fifo_out_enable
<= not(out_enable);
<= start_rd_en and clk_en;
<= VCC_CONSTANT;
<= I_to_fifo;
<= Q_to_fifo;
<= data_in_clk;
Listato F.5.4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
169
asynch fifo 2x15.vhd
-- synopsys translate_off
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
Library XilinxCoreLib;
ENTITY asynch_fifo_2x15 IS
port (
din
: IN std_logic_VECTOR(1 downto 0);
wr_en
: IN std_logic;
wr_clk : IN std_logic;
rd_en
: IN std_logic;
rd_clk : IN std_logic;
ainit
: IN std_logic;
dout
: OUT std_logic_VECTOR(1 downto 0);
full
: OUT std_logic;
empty
: OUT std_logic;
almost_empty: OUT std_logic);
END asynch_fifo_2x15;
ARCHITECTURE asynch_fifo_2x15_a OF asynch_fifo_2x15 IS
component wrapped_asynch_fifo_2x15
port (
din
: IN std_logic_VECTOR(1 downto 0);
wr_en
: IN std_logic;
wr_clk : IN std_logic;
rd_en
: IN std_logic;
rd_clk : IN std_logic;
ainit
: IN std_logic;
dout
: OUT std_logic_VECTOR(1 downto 0);
full
: OUT std_logic;
empty
: OUT std_logic;
almost_empty: OUT std_logic);
end component;
-- Configuration specification
for all : wrapped_asynch_fifo_2x15
use entity XilinxCoreLib.async_fifo_v4_0(behavioral)
generic map(
c_wr_count_width
=> 2,
c_has_rd_err => 0,
c_data_width => 2,
c_has_almost_full => 0,
c_rd_err_low => 0,
c_has_wr_ack => 0,
APPENDICE F. LISTATI VHDL
170
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
c_wr_ack_low => 0,
c_fifo_depth => 15,
c_rd_count_width
=> 2,
c_has_wr_err => 0,
c_has_almost_empty => 1,
c_rd_ack_low => 0,
c_has_wr_count => 0,
c_use_blockmem => 1,
c_has_rd_ack => 0,
c_has_rd_count => 0,
c_wr_err_low => 0,
c_enable_rlocs => 0);
BEGIN
U0 : wrapped_asynch_fifo_2x15
port map (
din
=> din,
wr_en
=> wr_en,
wr_clk
=> wr_clk,
rd_en
=> rd_en,
rd_clk
=> rd_clk,
ainit
=> ainit,
dout
=> dout,
full
=> full,
empty
=> empty,
almost_empty => almost_empty);
END asynch_fifo_2x15_a;
-- synopsys translate_on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
library ieee;
use ieee.std_logic_1164.all;
entity ffd is
port(in_ffd
:
in std_logic ;
clk
:
in std_logic ;
reset :
in std_logic ;
out_ffd
:
out std_logic );
end ffd;
architecture ffd_arch of ffd is
begin
process (clk, reset)
begin
if reset=’1’ then
out_ffd <= ’0’;
elsif rising_edge(clk) then
out_ffd <= in_ffd;
end if;
end process;
end ffd_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library ieee;
use ieee.std_logic_1164.all;
entity ffd_en is
port(in_ffd
:
in std_logic ;
clk
:
in std_logic ;
clk_en
:
in std_logic ;
reset :
in std_logic ;
out_ffd
:
out std_logic );
end ffd_en;
architecture ffd_en_arch of ffd_en is
begin
process (clk, clk_en, reset)
begin
if reset=’1’ then
out_ffd <= ’0’;
elsif rising_edge(clk) then
if clk_en = ’1’ then
out_ffd <= in_ffd;
end if;
end if;
end process;
end ffd_en_arch ;
Listato F.5.5:
Listato F.5.6:
ffd.vhd
ffd en.vhd
APPENDICE F. LISTATI VHDL
171
Listato F.5.7:
ffs.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
library ieee;
use ieee.std_logic_1164.all;
entity ffs is
port (S, clk, reset : in std_ulogic;
Q : out std_ulogic);
end entity ffs;
architecture ffs_arch of ffs is
signal state : std_ulogic;
begin
process (clk, reset) is
begin
if (reset = ’1’) then
state <= ’0’;
elsif rising_edge(clk) then
case S is
when ’0’ => state <= ’1’;
when others => null;
end case;
end if;
end process ;
Q <= state;
end ffs_arch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
library IEEE;
use IEEE.std_logic_1164.all;
entity ThinModulator is
port(
I_in_fir_MSB : in STD_LOGIC;
Q_in_fir_MSB : in STD_LOGIC;
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
reset
: in STD_LOGIC;
fir_sel : in STD_LOGIC_VECTOR(2 downto 0);
rate_sel
: in STD_LOGIC_VECTOR(1 downto 0);
QPSK_out
: out STD_LOGIC_VECTOR(11 downto 0)
);
end ThinModulator;
architecture ThinModulator of ThinModulator is
component mult_C2_adder
port (
clk
: in STD_LOGIC;
in_mca
: in STD_LOGIC_VECTOR(11 downto 0);
reset
: in STD_LOGIC;
out_mca : out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
component mux_2x7
port (
clk
: in STD_LOGIC;
in_I
: in STD_LOGIC_VECTOR(6 downto 0);
in_Q
: in STD_LOGIC_VECTOR(6 downto 0);
reset
: in STD_LOGIC;
out_mux : out STD_LOGIC_VECTOR(6 downto 0)
);
end component;
component shift_reg
port (
clk
: in STD_LOGIC;
clk_en
: in STD_LOGIC;
in_reg
: in STD_LOGIC;
reset
: in STD_LOGIC;
out_ffd_1
: out STD_LOGIC;
out_ffd_2
: out STD_LOGIC;
out_ffd_3
: out STD_LOGIC;
out_ffd_4
: out STD_LOGIC;
out_ffd_5
: out STD_LOGIC;
out_ffd_6
: out STD_LOGIC
);
end component;
component ram_12x4096_rising_registered
port (
addr
: in STD_LOGIC_VECTOR(11 downto 0);
clk
: in STD_LOGIC;
dout
: out STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal address
: STD_LOGIC_VECTOR (11 downto 0);
signal I_address : STD_LOGIC_VECTOR (6 downto 0);
signal out_ram
: STD_LOGIC_VECTOR (11 downto 0);
signal Q_address
: STD_LOGIC_VECTOR (6 downto 0);
begin
Listato F.5.8:
ThinModulator.vhd
APPENDICE F. LISTATI VHDL
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
U1 : shift_reg
port map(
clk
=> clk,
clk_en => clk_en,
in_reg => I_address(0),
out_ffd_1 => I_address(1),
out_ffd_2 => I_address(2),
out_ffd_3 => I_address(3),
out_ffd_4 => I_address(4),
out_ffd_5 => I_address(5),
out_ffd_6
=> I_address(6),
reset
=> reset
);
U2 : shift_reg
port map(
clk
=> clk,
clk_en => clk_en,
in_reg => Q_address(0),
out_ffd_1
=> Q_address(1),
out_ffd_2
=> Q_address(2),
out_ffd_3
=> Q_address(3),
out_ffd_4
=> Q_address(4),
out_ffd_5
=> Q_address(5),
out_ffd_6
=> Q_address(6),
reset
=> reset
);
U3 : ram_12x4096_rising_registered
port map(
addr
=> address,
clk
=> clk,
dout
=> out_ram
);
U4 : mux_2x7
port map(
out_mux(0) => address(0),
out_mux(1) => address(1),
out_mux(2) => address(2),
out_mux(3) => address(3),
out_mux(4) => address(4),
out_mux(5) => address(5),
out_mux(6) => address(6),
clk
=> clk,
in_I
=> I_address,
in_Q
=> Q_address,
reset
=> reset
);
U6 : mult_C2_adder
port map(
clk
=> clk,
in_mca => out_ram,
out_mca => QPSK_out,
reset
=> reset
);
I_address(0) <= I_in_fir_MSB;
Q_address(0) <= Q_in_fir_MSB;
address(7)
<= fir_sel(0);
address(8)
<= fir_sel(1);
address(9)
<= fir_sel(2);
address(10) <= rate_sel(0);
address(11) <= rate_sel(1);
end ThinModulator;
Listato F.5.9:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
172
mult C2 adder.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity mult_C2_adder is
port(in_mca :
in std_logic_vector(11 downto 0);
reset : in std_logic ;
clk
: in std_logic ;
out_mca :
out std_logic_vector(11 downto 0));
end mult_C2_adder;
architecture mult_C2_adder_arch of mult_C2_adder is
signal TEMP_count : std_logic_vector(1 downto 0);
begin
process(clk, reset)
begin
if reset = ’1’ then
TEMP_count <= "11";
elsif rising_edge(clk) then
TEMP_count <= TEMP_count + 1;
end if;
end process;
process(clk, reset, TEMP_count(1), in_mca)
APPENDICE F. LISTATI VHDL
173
begin
24
25
26
27
28
29
30
31
32
33
34
if reset = ’1’ then
out_mca <= x"000" ;
elsif rising_edge(clk) then
out_mca <= in_mca ;
if TEMP_count(1) = ’1’ then
out_mca <= ( x"FFF" xor in_mca) + 1 ;
end if;
end if;
end process;
end mult_C2_adder_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library ieee;
use ieee.std_logic_1164.all;
entity mux_2x7 is
port(in_I, in_Q :
in std_logic_vector(6 downto 0);
reset
: in std_logic ;
clk
: in std_logic ;
out_mux :
out std_logic_vector(6 downto 0));
end mux_2x7;
architecture mux_2x7_arch of mux_2x7 is
signal sel : std_logic;
begin
-- processo che genera il segnale di selezione alternato
process (clk, reset)
begin
if reset = ’1’ then
sel <= ’1’;
elsif rising_edge(clk) then
sel <= not sel;
end if;
end process;
out_mux <= in_I when (sel = ’0’) else in_Q ;
end mux_2x7_arch ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
-- synopsys translate_off
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
Library XilinxCoreLib;
ENTITY ram_12x4096_rising_registered IS
port (
addr : IN std_logic_VECTOR(11 downto 0);
clk
: IN std_logic;
dout : OUT std_logic_VECTOR(11 downto 0));
END ram_12x4096_rising_registered;
ARCHITECTURE ram_12x4096_rising_registered_a OF ram_12x4096_rising_registered IS
component wrapped_ram_12x4096_rising_registered
port (
addr: IN std_logic_VECTOR(11 downto 0);
clk: IN std_logic;
dout: OUT std_logic_VECTOR(11 downto 0));
end component;
for all : wrapped_ram_12x4096_rising_registered
use entity XilinxCoreLib.blkmemsp_v4_0(behavioral)
generic map(
c_reg_inputs => 1,
c_addr_width => 12,
c_has_sinit => 0,
c_ysinit_is_high
=> 1,
c_has_rdy
=> 0,
c_width
=> 12,
c_has_en
=> 0,
c_ymake_bmm => 0,
c_yen_is_high => 1,
c_yprimitive_type => "4kx1",
c_yhierarchy => "hierarchy1",
c_mem_init_file
=> "ram_12x4096_rising_registered.mif",
c_ywe_is_high => 1,
c_yuse_single_primitive => 1,
c_depth
=> 4096,
c_has_nd
=> 0,
c_has_default_data => 0,
c_default_data => "0",
c_ytop_addr => "1024",
c_limit_data_pitch => 8,
c_pipe_stages => 1,
Listato F.5.10:
Listato F.5.11:
mux 2x7.vhd
ram 12x4096 rising registered.vhd
APPENDICE F. LISTATI VHDL
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
c_ybottom_addr => "0",
c_has_rfd
=> 0,
c_yclk_is_rising
=> 1,
c_has_we
=> 0,
c_sinit_value => "0",
c_has_limit_data_pitch => 0,
c_enable_rlocs => 0,
c_has_din
=> 0,
c_write_mode => 0);
BEGIN
U0 : wrapped_ram_12x4096_rising_registered
port map (
addr
=> addr,
clk
=> clk,
dout
=> dout);
END ram_12x4096_rising_registered_a;
-- synopsys translate_on
Listato F.5.12: shift reg.vhd
vedi listato(F.3.9)
174
Appendice G
Acronimi
ADC Analog Digital Converter
ARQ Automatic ReQuest for repeat
BER Bit Error Rate
BPSK Binary Phase Shift Keying
CIC Cascaded Integrator Comb
CLB Configurable Logic Block
CORDIC COordinate Rotate DIgital Computer
CPFSK Continuous Phase Frequency Shift Keying
CPLD Complex Programmable Logic Device
DAC Digital Analog Converter
DDS Direct Digital Synthesizer
DDFS Direct Digital Frequency Synthesizer
DLL Delay Locked Loop
DSP Digital Signal Processing
FA Full Adder
FEC Forward Error Correction
FFD Flip Flop D
FIFO First In First Out
FPGA Field Programmable Gate Array
175
APPENDICE G. ACRONIMI
FSK Frequency Shift Keying
GMSK Gaussian Minimum Shift Keying
GRM General Routing Matrix
IDFT Inverse Discrete Fourier Transform
IF Intermediate Frequency
IOB Input Output Block
ISI Inter Symbol Interference
ISP In System Programmable
LC Logic Cell
LUT Look-Up Table
MAP Maximum A Posteriori probability
ML Maximum Likelihood
MSB Most Significant Bit
MSK Minimum Shift Keying
NCO Numerical Control Oscillator
NRZ No Return to Zero
OQPSK Offset Quadrature Phase Shift Keying
OTP One Time Programmable
PAL Programmable Array Logic
PAR Place And Route
PCF Physical Constrain File
PLD Programmable Logic Device
PSK Phase Shift Keying
QAM Quadrature Amplitude Modulation
QPSK Quadrature Phase Shift Keying
RAM Random Access Memory
RTL Register Transfer Logic
176
APPENDICE G. ACRONIMI
SER Symbol Error Rate
SFDR Spurious Free Dynamic Range
SIPO Serial In Parallel Out
SNR Signal to Noise Ratio
SRAM Static Random Access Memory
SRL16 Shift Register Left 16-bit
SRRC Square Root Raised Cosine
STA Static Timing Analyzer
TWTA Travelling Wave Tube Amplifier
UCF User Constrain File
VHDL VHSIC Hardware Description Language
VHSIC Very High Speed Integrated Circuit
177
Bibliografia
[1] AN1298.
Digital modulation in communications systems, an
introduction. Technical report, Hewlett Packard, 2000. 9
[2] Dirk A. Baker. Space-time block coding with imperfect channel
estimates. Master’s thesis, West Virginia University, 2001. 5
[3] C.E.Shannon. A mathematical theory of communication. The Bell
System Technical Journal, 27, 1948. 23
[4] Annex D. Skyplex. Technical report, EUTELSAT, 1999. 2
[5] Robert D.Turney. Multirate filters and wavelets: From theory to
implementation. Xilinx. 78
[6] Hogenauer E.B. An economical class of digital filters for decimation
and interpolation. IEEE Transactions on acoustics, speech and signal
processing, 1981. 75
[7] Dr Mike Fitton. Principles of digital modulation. Technical report,
Telecommunications Research Lab Toshiba, 2000. 10
[8] John G.Proakis. Digital Communications. Prentice Hall, 1998. 15, 18
[9] J.E.Volder. The cordic trigonometric computing technique. IRE Trans.
on Electron. Comput., pages 330–334, September 1959. 63
[10] A.V. Oppenheim and R.W.Schafer. Elaborazione numerica dei segnali.
Franco Angeli, undicesima edition, 1999. 61, 71
[11] Domenico Solimini. Appunti dalle lezioni di Campi Elettromagnetici.
TeXMat, 1999. 17
[12] P.P. Vaidyanathan. Multirate Systems and Filter Banks. Prentice-Hall,
1993. 74
[13] Francesco Valdoni. Comunicazioni Elettriche. I due Ladroni, 1998. 15
[14] Jouko Vankka. Methods of mapping from phase to sine amplitude in
dds. IEEE international Frequency control symposium, 1996. 63
178
BIBLIOGRAFIA
179
[15] Xilinx. Virtex 2.5V Field Programmable Gate Arrays, July 1999. 81
Elenco dei listati
E.1.1 NCO Q.m . . . . . . . . . . . . . . . . . .
E.1.2 Imposta frequenze Q.m . . . . . . . . . .
E.1.3 Imposta NCO Q.m . . . . . . . . . . . .
E.1.4 Crea super accumulatore Q.m . . . . . .
E.1.5 Tronca Q.m . . . . . . . . . . . . . . . . .
E.1.6 Crea coseno e seno Q.m . . . . . . . . .
E.1.7 Forward cordic Q.m . . . . . . . . . . . .
E.1.8 Calcola rotazioni Cordic.m . . . . . . . .
E.1.9 Visualizza spettro e SFDR p.m . . . .
E.1.10 Calcola SFDR.m . . . . . . . . . . . . . .
E.1.11 Calcola incremento fase NCO.m . . . . .
E.1.12 Visualizza spettro NCO VHDL.m . . . .
E.2.1 CreaVettoriTest.m . . . . . . . . . . . . . .
E.2.2 CreaSequenzaPatternGenerator.m . . . . .
E.3.1 CreaCoeffsFreqSamplScaled.m . . . . . . .
E.3.2 applica polifase.m . . . . . . . . . . . . . .
E.3.3 RaisedCosineResponse.m . . . . . . . . . .
E.3.4 CreaROM.m . . . . . . . . . . . . . . . . .
E.3.5 PolyphasePSDVHDLvsPSDMatlab.m . . .
E.3.6applica polifase.m . . . . . . . . . . . . . . .
E.3.7 VisualizzaPSDPolifaseVHDLFPGAout.m .
E.3.8applica polifase.m . . . . . . . . . . . . . . .
E.4.1 CreaTabellaBER.m . . . . . . . . . . . . .
E.4.2 calcolaBER.m . . . . . . . . . . . . . . . .
E.4.3applica polifase.m . . . . . . . . . . . . . . .
E.4.4 QPSKModemPSDeBERVHDLvsMatlab.m
E.4.5applica polifase.m . . . . . . . . . . . . . . .
E.4.6 QPSKModemPSDFPGAvsPSDMatlab.m .
E.4.7applica polifase.m . . . . . . . . . . . . . . .
F.1.1 nco.vhd . . . . . . . . . . . . . . . . . . . .
F.1.2 accumulator.vhd . . . . . . . . . . . . . . .
F.1.3 cordic pipelined unrolled.vhd . . . . . . .
F.1.4 cordic base j.vhd . . . . . . . . . . . . . .
F.1.5 adder 12.vhd . . . . . . . . . . . . . . . .
180
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
94
94
94
95
95
96
96
96
97
97
97
98
100
101
102
102
104
105
105
106
106
107
108
108
112
112
114
115
116
117
120
121
ELENCO DEI LISTATI
F.1.6 adder 13.vhd . . . . . . . . . . .
F.1.7 reg 12.vhd . . . . . . . . . . . . .
F.1.8 reg 13.vhd . . . . . . . . . . . . .
F.1.9 shifter.vhd . . . . . . . . . . . . .
F.1.10 cosine rebuild.vhd . . . . . . . . .
F.1.11 delay 13.vhd . . . . . . . . . . . .
F.1.12 sine rebuild.vhd . . . . . . . . . .
F.1.13 to first quadrant.vhd . . . . . .
F.1.14 troncatore 12.vhd . . . . . . . . .
F.2.1 polyphase gatedClock.vhd . . . .
F.2.2 srrc coeffs.vhd . . . . . . . . . . .
F.2.3 rate adapter.vhd . . . . . . . . .
F.2.4 coeffs selector.vhd . . . . . . . . .
F.2.5 counter divider 3.vhd . . . . . .
F.2.6 counter divider 4.vhd . . . . . .
F.2.7 fftr.vhd . . . . . . . . . . . . . . .
F.2.8 counter divider 6.vhd . . . . . .
F.2.9 selector.vhd . . . . . . . . . . . . .
F.2.10 srrc x n.vhd . . . . . . . . . . .
F.2.11 fir 1.vhd . . . . . . . . . . . . . .
F.2.12 adder 7.vhd . . . . . . . . . . . .
F.2.13 fir multiplier.vhd . . . . . . . . .
F.2.14 shift reg.vhd . . . . . . . . . . . .
F.2.15 mux 6.vhd . . . . . . . . . . . . .
F.3.1 ROM polyphase.vhd . . . . . . .
F.3.2 counter.vhd . . . . . . . . . . . . .
F.3.3 srrc x n.vhd . . . . . . . . . . .
F.3.4 demux 3x10.vhd . . . . . . . . . .
F.3.5 mux 3x12.vhd . . . . . . . . . . .
F.3.6 ROMx3.vhd . . . . . . . . . . . .
F.3.7 ROMx4.vhd . . . . . . . . . . . .
F.3.8 ROMx6.vhd . . . . . . . . . . . .
F.3.9 shift reg.vhd . . . . . . . . . . . .
F.4.1 Modulator BlockRAM.vhd . . . .
F.4.2 adder I Q.vhd . . . . . . . . . .
F.4.3counter.vhd . . . . . . . . . . . . . .
F.4.4 multiplier I Q.vhd . . . . . . . .
F.4.5 NCO basic.vhd . . . . . . . . . .
F.4.6 srrc x n.vhd . . . . . . . . . . .
F.4.7 ram.vhd . . . . . . . . . . . . . . .
F.4.8shift reg.vhd . . . . . . . . . . . . .
F.5.1 FIFO RAM ThinModulator.vhd
F.5.2counter.vhd . . . . . . . . . . . . . .
F.5.3 Data Source Interface.vhd . . .
181
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
121
122
122
122
123
123
123
124
124
124
125
125
126
130
130
131
131
132
132
136
138
139
139
139
140
141
141
143
143
143
148
153
161
162
163
164
164
164
165
166
166
166
168
168
ELENCO DEI LISTATI
F.5.4 asynch fifo 2x15.vhd . . . . . . . .
F.5.5 ffd.vhd . . . . . . . . . . . . . . . .
F.5.6 ffd en.vhd . . . . . . . . . . . . . .
F.5.7 ffs.vhd . . . . . . . . . . . . . . . . .
F.5.8 ThinModulator.vhd . . . . . . . . .
F.5.9 mult C2 adder.vhd . . . . . . . . .
F.5.10 mux 2x7.vhd . . . . . . . . . . . .
F.5.11 ram 12x4096 rising registered.vhd
F.5.12shift reg.vhd . . . . . . . . . . . . . .
182
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
169
170
170
171
171
172
173
173
174
Indice analitico
inviluppo complesso . . . . . . . . . . . . . 5
A
accumulatore . . . . . . . . . . . . . . . . . . . 62
antifuse . . . . . . . . . . . . . . . . . . . . . . . . 82 L
LUT . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
B
base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 M
BlockRAM . . . . . . . . . . . . . . . . . . . . . 87 MAP . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
moltiplicatore . . . . . . . . . . . . . . . . . . 30
C
clock-enable . . . . . . . . . . . . . . . . . . . . 40 N
codifica Gray . . . . . . . . . . . . . . . . . . . 17 NCO . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
commutatore . . . . . . . . . . . . . . . . . . . 49
P
CORDIC . . . . . . . . . . . . . . . . . . . . . . . 63
PAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Core . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
PLD . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
costellazione . . . . . . . . . . . . . . . . . . . . . 7
portante . . . . . . . . . . . . . . . . . . . . . . . . . 7
CPLD . . . . . . . . . . . . . . . . . . . . . . . . . . 82
programmabile . . . . . . . . . . . . . . . . . 42
D
DDFS . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Q
DDS . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 quadratura . . . . . . . . . . . . . . . . . . . . . 26
DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 R
roll-off . . . . . . . . . . . . . . . . . . . . . . . . . . 33
E
efficienza spettrale . . . . . . . . . . . . . . . 9 rumore . . . . . . . . . . . . . . . . . . . . . . . . . 45
rumore gaussiano . . . . . . . . . . . . . . . 14
F
FEC . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 S
FIFO . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 sagomatura . . . . . . . . . . . . . . . . . . . . . 27
FloorPlanner . . . . . . . . . . . . . . . . . . . 91 Scheda Dini . . . . . . . . . . . . . . . . . . . . 83
segnale analitico . . . . . . . . . . . . . . . . . 5
G
Shannon . . . . . . . . . . . . . . . . . . . . . . . 22
gated-clock . . . . . . . . . . . . . . . . . . . . . 40 simbolo . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Slice . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
H
spazio segnali . . . . . . . . . . . . . . . . . . . . 6
Hilbert . . . . . . . . . . . . . . . . . . . . . . . . . . 5 spurie . . . . . . . . . . . . . . . . . . . . . . . . . . 61
SRAM . . . . . . . . . . . . . . . . . . . . . . . . . 82
I
183
INDICE ANALITICO
T
ThinModulator . . . . . . . . . . . . . . . . . 49
V
VersaBLOCK . . . . . . . . . . . . . . . . . . 86
VersaRING . . . . . . . . . . . . . . . . . . . . . 86
Virtex . . . . . . . . . . . . . . . . . . . . . . . . . . 82
184