Professional Documents
Culture Documents
FACOLTÁ DI INGEGNERIA
DIPARTIMENTO DI INFORMATICA E SISTEMISTICA
Implementazione
della sezione digitale
di un modulatore LINC
per la trasmissione
di segnali GSM-EDGE
Relatore:
Prof. Carla Vacchi
Correlatore:
Dott.ssa Paola Uggetti
Tesi di Laurea di
Marco Rossi
1 Introduzione 6
2
INDICE 3
2.2.1 Struttura . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.3 Vantaggi . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.2 Interpolazione . . . . . . . . . . . . . . . . . . . . . . . 21
2.4.2 EVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3 Implementazione Matlab 36
3.3 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4 Implementazione VHDL 48
4.5 Il Separatore . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5 Conclusione 66
5.1 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
B L’algoritmo CORDIC 73
INDICE 5
C Acronimi 80
D Codice vhdl 82
Capitolo
Introduzione 1
Il primo capitolo introduce al lettore l’argomento dell’elaborato, assieme ad
alcune considerazioni personali dell’autore sullo stato attuale della comuni-
cazione mobile.
6
1.1. LAVORO SVOLTO 7
10
11
Sorgente Ricevente
• modulazione
• mixing
• amplificazione
2.1. ANALOGICO O DIGITALE? 12
Questo errore dipende dall’accuratezza, cioè dal numero di bit del processo
di conversione A/D.
2.2. IL TRASMETTITORE LINC 14
2.2.1 Struttura
PA
PA
DATI
S1(t)
PA
PA
S2(t)
3. Limita la banda del segnale che verrà trasmesso, per eliminare fre-
quenze che non possono-non devono essere trasmesse.
2.2. IL TRASMETTITORE LINC 16
1. Modula i segnali S1 (t) e S2 (t) con una portante di equazione cos(ω0 t),
in modo da portarlo alla reale frequenza di trasmissione. Questa ope-
razione viene effettuata da un circuito chiamato PLL (Phase Locked
Loop). Matematicamente equivale a moltiplicare il segnale con la
sinusoide di frequenza ω0
Sia
S(t) = E(t)cos(ω0 t + φ(t)) con 0 < E(t) < Emax (2.2)
S1 (t) + S2 (t)
S(t) = (2.4)
2
Dove
S1 (t) = Emax ejφ(t) ejα ejω0 t S2 (t) = Emax ejφ(t) e−jα ejω0 t (2.5)
e
E(t)
α = arccos (2.6)
Emax
2.2.3 Vantaggi
S2(t)
S(t)
S1(t)
MODULATORE LINC
1
3
0.8
2 1
0.6
0.4
0.2
Im
0 6 0
-0.2
-0.4
-0.6
7 4
-0.8
5
-1
Nella figura 2.5 ogni punto in rosso rappresenta il momento in cui viene scan-
dito il clock del segnale d’ingresso. Al tempo zero ci troviamo al punto 1, e ci
2.3. LA SEZIONE DIGITALE 21
2.3.2 Interpolazione
Mappatura M-PSK
1.5
1
3
2 1
0.5
Im
0 6 0
-0.5
7 4
5
-1
-1.5
Bisogna porre attenzione alla classe di filtro utilizzato e alla scelta dei pa-
rametri, dato che un filtro troppo ‘aggressivo’ modificherebbe la traiettoria
del segnale, causando un overshoot: fenomeno per cui il modulo dell’invi-
luppo raggiunge valori molto maggiori di quelli ammissibili, determinando
uno spreco di potenza e/o cadendo in zone di non linearità (vedi figura 2.7).
Inoltre il filtraggio può portare a interferenza intersimbolica (InterSymbol
2.3. LA SEZIONE DIGITALE 23
Mappatura M-PSK
1.5
1
3
2 1
0.5
Im
0 6 0
-0.5
7 4
5
-1
-1.5
Diversi studi teorici2 hanno dimostrato che il filtro indicato per questo tipo di
modulazione è un filtro FIR (Finite Impulse Response) con risposta impul-
2
Mashhour (1999),Schell (2000)
2.3. LA SEZIONE DIGITALE 24
1 -1 -1 -1 -1
z z z z
Input1
K K K K K
b(1) b(2) b(3) b(4) b(5)
1
Output
1.5
0.5
−0.5
−1
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
Indichiamo con cn il segnale che esce dal codificatore 8-PSK e inoltre sia
3πn
pn = e 8
1.5
5
6 4
1
C
7 3
D B
0.5 8 2
0 9 E A 1
−0.5 10 16
F H
−1 11 15
G
12 14
13
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
1.5
5
6 4
1
C
7 3
D B
0.5 8 2
0 9 E A 1
−0.5 10 16
F H
−1 11 15
G
12 14
13
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
Il segnale CPSK (in blu), parte correttamente dal simbolo 11 (che coincide
3π
con F), il primo valore cade su 6, ovvero sarebbe il simbolo 3 ruotato di 8
,
6π
il secondo su 15 (ovvero E-9 ruotato di 8
) e il terzo simbolo su 8 (ossia H-15
9π
ruotato di 8
) ).
5
p(t) = c0 t + T (2.8)
2
2.3. LA SEZIONE DIGITALE 28
1.5
0.5
−0.5
−1
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
1
dove T = fL
ovvero il tempo di arrivo di ogni simbolo.
Si ha che
Q
3 f (t + iT ) per 0 ≤ t ≤ 5T
i=0
c0 (t) = (2.9)
0 altrimenti
Rt
sinπ 0 g(u)du per 0 ≤ t ≤ 4T
R t−4T
f (t) = cosπ 0 g(u)du per 4T ≤ t ≤ 8T (2.10)
0 altrimenti
1
g(t) = gGSM K (t − 2T ) (2.11)
2
1 t 1 t 1
gGSM K (t) = erfcα − − erfcα + (2.12)
2T T 2 T 2
2.3. LA SEZIONE DIGITALE 29
√
α = 2π(0.3)/ 2ln (2.13)
−50
Magnitude (dB)
−100
−150
−200
−250
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
Normalized Frequency (×π rad/sample)
Phase Response
0
−200
−400
−600
Phase (degrees)
−800
−1000
−1200
−1400
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
Normalized Frequency (×π rad/sample)
Impulse Response
1
0.9
0.8
0.7
0.6
Amplitude
0.5
0.4
0.3
0.2
0.1
0
0 10 20 30 40 50 60 70 80
Samples
Step Response
30
25
20
Amplitude
15
10
0
0 10 20 30 40 50 60 70 80
Samples
Dopo l’applicazione del filtro, la traiettoria del segnale non è più rettilinea a
tratti ma segue un cammino meno diretto.
1.5
0.5
−0.5
−1
−1.5
−2
−2 −1.5 −1 −0.5 0 0.5 1 1.5 2
MODULO
S2(t)
S(t)
S1(t)
Dato che α = arccos |ρ∗ | , dove ρ∗ è il modulo normalizzato, per ρ∗ che tende
a zero, il valore di α non può superare 90◦ .
2.4. VALUTAZIONE DEI RISULTATI 33
Lo spettro del segnale in uscita deve essere contenuto in una maschera, de-
scritta con rigore dallo standard GSM EDGE, per non interferire con altri
canali adiacenti.
10
MASK
Matlab
0
−10
Spettro di potenza [dBc] − Maschera EDGE
−20
−30
−40
−50
−60
−70
−80
−8 −6 −4 −2 0 2 4 6 8
Frequenza [Hz] x 10
6
2.4.2 EVM
segnale trasmesso
Implementazione Matlab 3
Per lo studio teorico del circuito digitale è stato utilizzato l’ambiente di si-
mulazione Matlab-Simulink. Attraverso un semplice linguaggio di scripting,
progettato per il calcolo scientifico, è stato possibile ottenere da subito dei ri-
sultati concreti, senza doversi preoccupare delle funzioni di base (es. gestione
delle matrici, calcolo numerico approssimato, ecc)
36
3.1. LO SCHEMA SIMULINK 37
Grazie al lavoro svolto dalla Dott.ssa Uggetti, buona parte della modelliz-
zazione del progetto era già pronta. Come prima cosa, ho investito un pò
di tempo nel comprenderne il funzionamento e ho riorganizzato la struttura
secondo lo stile adottato nel resto del progetto.
O_SEP1 I_AN1
Integer to Bit
Random I_PSK O_FIR I_SEP O_ANT output
Converter
Integer O_SEP2 I_AN2
Signal To
Psk, Interpolazione, Separazione del Trasmissione Workspace
FIR Segnale
Lo schema è molto simile alla figura 2.4, per semplicità sono state raggruppate
alcune sezioni. Per simulare il flusso di dati GSM-EDGE si è utilizzato un
blocco che genera interi casuali da 0 a 7, convertiti poi in numeri binari.
1 M-PSK
x[n/16] 1
I_PSK
O_FIR
Product
FIR
Interpolation
exp(jx)
Ramp Zero-Order
Hold
3πn
pendenza pari a 8
; il mantenitore di ordine zero (‘Zero-Order Hold’) cam-
piona il segnale, sincronizzandolo al tempo di simbolo. L’esponenziale calcola
il valore dell’espressione l(z) = eik(z) dove k(z) è l’output del mantenitore e
√
i = −1; utilizzo z come variabile perchè il sistema è a tempo discreto. Si
nota che ogni sedici iterazioni la successione si ripete. Questo coefficiente
(che mantiene una sorta di informazione di stato) viene moltiplicato con il
simbolo di ingresso, modulato con la codifica gray-PSK e il risultato viene
passato al blocco di interpolazione-filtraggio.
acos
Divide Trigonometric
Function
1.6
Constant
1
O_SEP1
|u|
1 u 2
I_SEP
Complex to O_SEP2
Magnitude-Angle
1.6
Constant2
1 exp(jx)
I_AN1 Product1
UnwrapA
1
O_ANT
2 exp(jx) Divide1
I_AN2 Product
UnwrapB
Constant1
Matlab effettua tutti i suoi calcoli utilizzando tipi di dati ad alta precisione
(a seconda del processore utilizzato) in virgola mobile. Implementare quel
genere di operazioni su un circuito hardware richiede un notevole sforzo di
progettazione ma soprattutto un notevole dispendio in termini di area del
3.3. RISULTATI 40
3.3 Risultati
1.5
1.4
1.3
1.2
1.1
0.9
0.8
−1.3 −1.2 −1.1 −1 −0.9 −0.8 −0.7 −0.6 −0.5 −0.4 −0.3
Come si può notare, 8 bit non sono sufficienti per immagazzinare tutte le
informazioni. 10 e 12 bit potrebbero andare bene, ma si sta valutando una
3.3. RISULTATI 42
1.5
1.4
1.3
1.2
1.1
0.9
0.8
−1.3 −1.2 −1.1 −1 −0.9 −0.8 −0.7 −0.6 −0.5 −0.4 −0.3
1.5
1.4
1.3
1.2
1.1
0.9
0.8
−1.3 −1.2 −1.1 −1 −0.9 −0.8 −0.7 −0.6 −0.5 −0.4 −0.3
10
MASK
matlab
0 matlab 12 bit
matlab 8 bit
−10
−30
−40
−50
−60
−70
−80
−90
−8 −6 −4 −2 0 2 4 6 8
Frequenza [Hz] x 10
6
• il valore dei coefficienti del filtro FIR; questi coefficienti dovranno essere
moltiplicati per i dati di ingresso
Per quanto riguarda la struttura interna del FIR, ho notato che dando un va-
lore basso alla dinamica dei moltiplicatori (16-18 bit) comparivano in output
alcuni ‘artefatti’.
MASK
matlab
−70 matlab16−16
−75
Spettro di potenza [dBc] − Maschera EDGE
−80
−85
−90
−95
−5 0 5 10 15 20 25
Frequenza [Hz] x 10
5
minimo e il valore massimo della potenza trasmessa, che in questo caso varia
da 1.3 a 0.5; nel complesso è compreso ta 0.2 e 1.6.
1.5
F
1 A
0.5
C E
−0.5
D B
−1
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
1.5
F
1 A
0.5
C E
−0.5
A
D B
−1
−1.5
−1.5 −1 −0.5 0 0.5 1 1.5
Implementazione VHDL 4
Il passo finale del lavoro è l’implementazione delle funzionalità del modula-
tore LINC in un Hardware Description Language (linguaggio di descrizione
dell’hardware) in modo da poter sintetizzare con semplicità il modulatore
in un circuito reale. É stato scelto il VHDL come linguaggio, per la sua
semplicità d’uso, l’elevata standardizzazione e il notevole supporto tecnico
disponibile in rete e all’interno dell’università.
48
49
TOP
SEPARAZION
FIR
E
PSK CORDIC
COR_N (16)
FPFF (4)
FPFF(4)
MOLTIPL(5)
ADDER
ARCOSENO
COEFF
ADDERMOD1
ADDERMOD2
COEFF
Nello sviluppo del progetto è stata utilizzata una libreria, dedicata alla gestio-
ne delle variabili di tipo fixed point. Questa libreria contiene macroistruzioni
4.2. LA LIBRERIA FIX-STD 52
La libreria è solo una ‘maschera’, per gestire con più semplicità le operazioni
in virgola mobile e renderle trasparenti al programmatore. Per il compila-
tore e (successivamente) per il sintetizzatore non crea problemi, dato che si
appoggia alle librerie standard IEEE.
http://www.geocities.com/bromley_jonathan/fix_std_02.zip
4.3. DESCRIZIONE GENERALE 53
clk
clk_cordic
clk_diviso
reset
U2 U1 U4 U10
clk_cordic
reset
clkd
clk
reset
Clk
Clk
clk
Wr
Reset
Reset
Reset
Reset
Clk
Clk
Clk
Clk
Clk
ff ff ff ff ff
L’entità ‘top’ è necessaria per simulare l’ambiente nel quale il vero e proprio
circuito lavorerà. Per il funzionamente del sistema sono necessari tre segnali
di clock.
clk
Reset
Reset
Reset
Reset
Reset
Clk
Clk
Clk
Clk
R_out R_in R_out R_in R_out R_in R_out R_in R_out
sym(2:0) Symbol(2:0)
I_out I_in I_out I_in I_out I_in I_out I_in I_out
psk
fpff fpff fpff fpff
clk
U8 Reset
U9
Reset
R_in
clk
I_in
c0 coeff_in
R_out
I_out
clk
U10
moltip
Reset
R_in
clk
I_in
c1 coeff_in
R_out
I_out
U11
moltip
Reset
R_in
I_in
clk
coeff_in
R_out
c2
I_out
moltip U12
Reset
R_in
clk
I_in
c3 coeff_in
R_out
I_out
U13
moltip
Reset
R_in
I_in
clk
c4 coeff_in
R_out
I_out
moltip
coeff
U14
Reset
R_M0
I_M0
R_M1
I_M1
R_M2
I_M2
R_M3
I_M3
R_M4
I_M4
clk
R_Ris R_output
I_Ris I_output
adder
55
4.4. IL FILTRO FIR 56
QPONMLIHGFEDCBA
.... H 0 0 G 0 0 F 0 0 E 0 0 D 0 0 C 0 0 B 0 0 A
Questo entrerà in un filtro FIR di ordine 5*Os =15 quindi avrà 16 coefficienti,
che dovranno essere moltiplicati con il segnale di ingresso.
I successivi cicli:
e cosi via...
4.4. IL FILTRO FIR 58
Come si può notare è possibile mettere in un cella di memoria i dati (ad esem-
pio F) e moltiplicarli consecutivamente per il C1, C2, C3, ad ogni periodo del
clock ad alta frequenza. All’arrivo del nuovo dato, (clock lento) il simbolo F
verrà spostato nella seconda cella di memoria, per esser poi moltiplicato per
i coefficienti C4, C5, C6.
4.5 Il Separatore
reset
clk
U1 U4
clk
Clk_slow
Reset
Reset
U2
cos
arcoseno
clk_cordic Clk Fase fase
cordic addermod1
U3
cos
fase
addermod2
Dalle specifiche del filtro FIR si evidenzia che il segnale in uscita ha una
dinamica pari a 16 bit per la parte reale e 16 bit per la parte immaginaria.
Il risultato (modulo e fase), secondo le simulazioni Matalb, deve avere dina-
mica pari a 13 bit e a 15 bit rispettivamente. E’ possibile tramite semplici
calcoli verificare che lo spazio occupato dalla loookup table è enorme e quin-
di, per il calcolo del modulo e della fase, questa soluzione è stata scartata
a priori. Dopo ricerche su internet e studio di articoli scientifici ho scelto
di utilizzare l’algoritmo di CORDIC per effettuare i calcoli. Per i principi
teorici sull’algoritmo CORDIC si rimanda all’appendice B. Per il blocco ‘ar-
cocoseno’, invece, ho deciso di utilizzare una look-up table. Grazie ad alcune
simulazioni ho notato che il metodo CORDIC avrebbe richiesto molto più
delle otto iterazioni concesse3 , ed, allo stesso tempo, il numero di possibili
input era limitato (ricordiamo che il modulo è un valore compreso tra 0.2 e
1.6). La tabella è stata costruita con uno script Matlab, che genera il codice
3
Il metodo CORDIC per calcolare l’arcocoseno si basa sull’approssimazione di Taylor
della funzione, pertanto introduce ulteriori errori di approssimazione
4.5. IL SEPARATORE 61
Per i che va da 1 a 16
Dato il numero complesso z
Se im(z) > 0
//calcolo del modulo
4.5. IL SEPARATORE 62
dove Sh (numero, indice) è una funzione che effettua lo shift aritmetico del
numero e Ffase (indice) restituisce un valore precalcolato da aggiungere o
sottrarre al valore attuale della fase. La tabella contiene i valori dell’espres-
sione atan(2−k ), con k = 1, 2, 3, ... Le simulazioni hanno dimostrato che il
calcolo della fase deve avvenire a massima precisione possibile per portare
risultati soddisfacenti, per cui questi valori sono stati quantizzati a 32 bit.
Sono tutti valori minori di uno. La variabile di accumulazione, pertanto,
necessita di 3 bit aggiuntivi per evitare overflow. Il valore del modulo è
correttamente calcolato dopo otto iterazioni di CORDIC ovvero dopo
otto cicli di clock a fC , e quindi un ciclo di clock a fM ; la successiva unità
(‘arcocoseno’) leggerà il valore ed effettuerà le necessarie operazioni. Il va-
lore della fase, invece è correttamente calcolato dopo sedici iterazioni di
CORDIC ovvero dopo sedici cicli di clock a fC , e quindi due ciclo di clock
a fM ; le unità di somma leggeranno il valore e lo combineranno in maniera
corretta con il valore in output dal blocco (‘arcocoseno’). Il segnale SIGN,
calcolato in ‘corin’ e l’input della sezione ‘CORDIC’, ovvero ‘R In’ e ‘I In’
vengono propagati all’interno dell’entità attraverso quattro flip-flop; Le unità
‘corout a’ e ‘corout b’ si occupano di effettuare le correzioni della fase e del
modulo, come descritto nella teoria, utilizzando il valore di quei segnali di
4.5. IL SEPARATORE 63
Clk_slow Clk
Reset
U7
Clk
Reset
U8 U1 U2 U3 U4 U5 U6 R_in R_out Modulo
Clk
Reset
Clk
Reset
Clk
Reset
Clk
Reset
Clk
Reset
Clk
Reset
Clk
Reset
R_in R_in R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out fpff2
I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out
I_in I_in Phase Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out
SIGN
cor_in cor_2 cor_3 U20 cor_4 cor_5 cor_6 cor_7
S_in S_out
Clk
U9 U18
ff
R_in R_out R_in R_out
I_in I_out I_in I_out
Reset Reset
Clk Clk
U21
fpff fpff
S_in S_out
Reset
Clk
ff
64
4.5. IL SEPARATORE
Figura 4.6: VHDL - Data Flow - Entity CORDIC.VHD - seconda parte
Reset
Reset
Reset
Reset
Reset
Reset
Clk
Clk
Clk
Clk
Clk
Clk
Clk
Clk
Reset
Clk
Reset
R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp R_out R_tmp Fase Fase
I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp I_out I_tmp
Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase Phase_out Phase
R_in
Sign
I_in
cor_8 cor_9 cor_10 cor_11 cor_12 cor_13 cor_14 cor_15
cor_out
65
Capitolo
Conclusione 5
L’ultimo capitolo riporta i risultati più importanti di questa esperienza di
progettazione e indica i possibili svliuppi futuri per questo progetto.
66
5.1. RISULTATI 67
5.1 Risultati
Lunghe sessioni di progettazione e simulazione hanno portato ad un risultato
soddisfacente, in termini sia di spettro che di EVM. Lo spettro del segnale
risiede all’interno della maschera, ed in alcuni punti tende ad i valori del-
lo spettro calcolati utilizzando i modelli Matlab senza quantizzazione. Le
sezioni laterali dello spettro, infatti, offrono un margine di errore rispetto
alla maschera di quasi 20 dB. L’EVM risulta essere pari a 3,208% Grazie
20
MASK
matlab
VHDL
0
Spettro di potenza [dBc] − Maschera EDGE
−20
−40
−60
−80
−100
−8 −6 −4 −2 0 2 4 6 8
Frequenza [Hz] x 10
6
20
MASK
matlab
VHDL
0
Spettro di potenza [dBc] − Maschera EDGE
−20
−40
−60
−80
−100
−8 −6 −4 −2 0 2 4 6 8
Frequenza [Hz] x 10
6
69
70
v_q = fi(v,s,w,f)
>> pi
ans =
3.1416
pi_q =
3.1416
DataTypeMode: Fixed-point: binary point scaling
Signed: true
WordLength: 16
FractionLength: 13
RoundMode: round
OverflowMode: saturate
ProductMode: FullPrecision
MaxProductWordLength: 128
SumMode: FullPrecision
MaxSumWordLength: 128
CastBeforeSum: true
>> pi_q.bin
ans =
0110010010001000
>> pi_q.double-pi
ans =
8.9089e-006
Facendo ulteriori prove si può vedere come sia semplice valutare gli effetti di
quantizzazione su una serie di operazioni aritmetiche.
pi_q_8 =
3.1563
>> pi_q_8.double-pi
ans =
0.0147
Per ipotesi, il blocco X non accetta in input dati di tipo ‘fi’, per cui all’entrata
del blocco si è dovuto convertire il segnale da fi a double e, all’uscita, da
double a ‘fi’. Questo significa che l’operazione viene calcolata a ‘precisione
macchina’, e poi viene quantizzato il risultato e ciò è differente da quello
che avviene nell’implementazione VHDL (e quindi nella realtà), dove tutto
il sistema è quantizzato.
Appendice
L’algoritmo CORDIC B
Il metodo Cordic e’ uno dei modi piu’ validi per calcolare velocemente fun-
zioni trigonometriche come seni, coseni, esponenziali, coseni iperbolici, seni
iperbolici. E’ particolarmente impiegato nelle unità di calcolo o nelle cal-
colatrici tascabili per la sua velocita’ di esecuzione e semplicità di realizza-
zione pratica sia a livello hardware che software. Il suo nome è l’acronimo
di ‘COordinate Rotation DIgital Computer algorithm’. L’aspetto più rile-
vante di questo algoritmo è la possibilità di realizzarlo unicamente tramite
73
74
Im
b
ρ
a Re
Dato
avremo che
zk+1 = zk ∗ (1 + αk 2−k i)
75
dove
+1 se Im(zk ) > 0
αk =
−1 se Im(zk ) < 0
Graficamente:
Im
Re
1
più precisamente equivale a 1.64676025812107. La motivazione per questa correzione
risiede nel fatto che i vettori per i quali il numero è moltiplicato non hanno modulo uguale
a zero.
76
Dato
z1 = a + bi e z2 = c + di
allora
z1 ∗ z2 = (a + bi)(c + di)
ma
c=1
e naturalmente
i2 = −1
quindi l’algoritmo diventa
(a + b ∗ d) + (b − a ∗ d) ∗ i se Im(zk ) > 0
zk+1 =
(a − b ∗ d) + (b + a ∗ d) ∗ i se Im(zk ) < 0
dove d = 2−k
Im
Re
input
z=a+ib
no z è nel 1' si
quadrante?
sposta z
nel 1'
quadrante
memorizza lo
spostamento
calcola n
iterazioni di
cordic
no z è nel 1' si
quadrante?
effettua le
correzioni di
fase
output:
abs(z),angle(z)
input
z(k)=a+ib
si no
im(z(k)) > 0
re(z(k+1)) = re( z(k)) + shift( im(z(k))) re(z(k+1)) = re( z(k)) - shift( im(z(k)))
k=k+1
si
k<KMAX?
no
output:
modulo=re(z(k)),
fase
Acronimi C
80
81
Sigla Significato.
WAP Wireless Application Protocol.
SMS Short Message Service.
LINC Linear Amplification using Non linear Components.
ADC Analog to Digital Converter.
VHDL Very high speed integrated circuit Hardware Description Language.
AM Amplitude Modulation.
RF Radio Frequenza.
PLL Phase locked Loop.
UMTS Universal Mobile Telecommunications System.
PA Power Amplifiers.
ISI InterSymbol Interference.
SPS Subtractive Phase Shifting.
CPS Cumulative Phase Shifting.
EVM Error Vector Magnitude.
GSM Global System for Mobile Communications.
EDGE Enhanced Data rates for GSM Evolution.
Appendice
Codice vhdl D
La presente appendice contiene i listati in codice VHDL dei blocchi più im-
portanti progettati in questo lavoro. Sono stati omessi quelli che non saranno
oggetto di sintesi. Le entity che descrivono una struttura (ad esempio FIR)
non sono state incluse, ma possono essere ricavate dalle figure.
82
83
Adder.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
entity Adder is
port(
R_M0 : in FP_S_3_18;
I_M0 : in FP_S_3_18;
R_M1 : in FP_S_3_18;
I_M1 : in FP_S_3_18;
R_M2 : in FP_S_3_18;
I_M2 : in FP_S_3_18;
R_M3 : in FP_S_3_18;
I_M3 : in FP_S_3_18;
R_M4 : in FP_S_3_18;
I_M4 : in FP_S_3_18;
clk : in std_logic;
Reset : in std_logic;
R_Ris : out FP_S_1_14;
I_Ris : out FP_S_1_14
);
end Adder;
architecture AdderA of Adder is
begin
process (Clk,Reset)
begin
if(Reset = ’0’)then
R_Ris <= (others => ’0’);
I_Ris <= (others => ’0’);
elsif (Clk’event AND Clk=’1’) then
Copy_S(R_Ris,R_M0+R_M1+R_M2+R_M3+R_M4);
Copy_S(I_Ris,I_M0+I_M1+I_M2+I_M3+I_M4);
end if;
end process;
end AdderA;
Addermod1.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
entity Addermod1 is
port(
cos : in FP_S_1_12;
fase : in FP_S_3_12;
clk : in std_logic;
Reset : in std_logic;
Ris : out FP_S_3_12
);
end Addermod1;
architecture Addermod1A of Addermod1 is
begin
process (Clk,Reset)
begin
if(Reset = ’0’)then
Ris <= (others => ’0’);
elsif (Clk’event AND Clk=’1’) then
Copy_S(Ris,cos+fase);
end if;
end process;
end Addermod1A;
Addermod2.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
entity Addermod2 is
port(
cos : in FP_S_1_12;
fase : in FP_S_3_12;
clk : in std_logic;
Reset : in std_logic;
Ris : out FP_S_3_12
);
end Addermod2;
architecture Addermod2A of Addermod2 is
begin
process (Clk,Reset)
begin
if(Reset = ’0’)then
Ris <= (others => ’0’);
85
Arcocoseno.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.fix_std.all;
entity arcocoseno is
port(
prodotto : in FP_S_1_12;
clk : in STD_LOGIC;
Reset : in STD_LOGIC;
acos : out FP_S_1_12
);
end arcocoseno;
architecture arcocosenoA of arcocoseno is
begin
process (Clk,Reset)
begin
if(Reset = ’0’)then
acos <= (others => ’0’);
elsif (Clk’event AND Clk=’1’) then
case prodotto is
when "00000000000000" =>
acos <= "01100100100010";
when "00000000000001" =>
acos <= "01100100100001";
when "00000000000010" =>
acos <= "01100100100000";
.....
when "00111111111111" =>
acos <= "00000001011011";
when "01111111111111" =>
acos <= "00000000000010";
when "11111111111111" =>
acos <= "01100100100010";
86
end case;
end if;
end process;
end arcocosenoA;
coeff.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.fix_std.all;
entity coeff is
port(
clk : in STD_LOGIC;
Reset : in STD_LOGIC;
c0 : out FP_S_1_13;
c1 : out FP_S_1_13;
c2 : out FP_S_1_13;
c3 : out FP_S_1_13;
c4 : out FP_S_1_13
);
end coeff;
architecture coeffA of coeff is
begin
process (Clk,Reset)
variable Cnt: std_logic_vector(3 downto 0);
begin
if(Reset = ’0’)then
Cnt := "0000";
elsif (Clk’event AND Clk=’1’) then
Cnt := Cnt + "0001";
case Cnt is
when "0000" =>
c0 <= "000000000000000";
c1 <= "000000100010110";
c2 <= "001100001011101";
c3 <= "001100001011110";
c4 <= "000000100010111";
....
when "1111" =>
c0 <= "000000011000000";
c1 <= "001011010000110";
87
c2 <= "001101000010001";
c3 <= "000000110001001";
c4 <= "000000000000000";
end case;
end if;
end process;
end coeffA;
complfunc.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use WORK.fix_std.all;
package compl_func is
function fffase(n: integer) return FP_S_0_31;
function Smi(n: integer; Ing: FP_S_3_14) return FP_S_3_14;
end;
package body compl_func is
function fffase(n: integer) return FP_S_0_31 is
variable b : FP_S_0_31;
begin
case n is
when 0 => b := ("01100100100001111110110101010001");
when 1 => b := ("00111011010110001100111000001011");
when 2 => b := ("00011111010110110111010111111001");
when 3 => b := ("00001111111010101101110101001101");
when 4 => b := ("00000111111111010101011011101110");
when 5 => b := ("00000011111111111010101010110111");
when 6 => b := ("00000001111111111111010101010110");
when 7 => b := ("00000000111111111111111010101011");
when 8 => b := ("00000000011111111111111111010101");
when 9 => b := ("00000000001111111111111111111011");
when 10 => b := ("00000000000111111111111111111111");
when 11 => b := ("00000000000100000000000000000000");
when 12 => b := ("00000000000010000000000000000000");
when 13 => b := ("00000000000001000000000000000000");
when 14 => b := ("00000000000000100000000000000000");
when 15 => b := ("00000000000000010000000000000000");
when others => b := (others => ’0’);
end case;
return b;
end fffase;
function Smi(n: integer; Ing: FP_S_3_14) return FP_S_3_14 is
88
corin.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
use WORK.compl_func.all;
entity cor_in is
port(
R_in : in FP_S_1_14;
I_in : in FP_S_1_14;
Clk : in std_logic;
Reset : in std_logic;
R_out : out FP_S_3_14;
I_out : out FP_S_3_14;
Phase : out FP_S_3_31;
SIGN : out std_logic
);
end cor_in;
architecture cor_ina of cor_in is
begin
process (Clk,Reset)
variable Zero : FP_S_1_14 := (others => ’0’);
variable Zero2 : FP_S_3_14 := (others => ’0’);
variable R_sh : FP_S_3_14;
variable I_sh : FP_S_3_14;
variable R_next : FP_S_3_14;
variable I_next : FP_S_3_14;
variable R_tmp : FP_S_3_14;
variable I_tmp : FP_S_3_14;
begin
if(Reset = ’0’)then
Copy_S(R_out,Zero);
Copy_S(I_out,Zero);
Copy_S(Phase,Zero);
Sign<=’0’;
elsif (Clk’event AND Clk=’1’) then
Copy_V (Phase_Tmp, Zero);
if (R_in>=Zero) then
Copy_V (R_tmp, R_in);
else
Copy_V (R_tmp, -R_in);
end if;
if (I_in>=Zero) then
Copy_V (I_tmp, I_in);
else
Copy_V (I_tmp, -I_in);
end if;
if (I_tmp>R_tmp) then
Copy_V (R_next, I_tmp);
Copy_V (I_next, R_tmp);
Sign<=’0’;
else
Copy_V (R_next, R_tmp);
90
end if;
end process;
end cor_ina;
cor2.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
use WORK.compl_func.all;
entity cor_2 is
port(
R_tmp : in FP_S_3_14;
I_tmp : in FP_S_3_14;
Phase : in FP_S_3_31;
Clk : in std_logic;
Reset : in std_logic;
R_out : out FP_S_3_14;
I_out : out FP_S_3_14;
Phase_out : out FP_S_3_31
);
end cor_2;
architecture cor_2a of cor_2 is
begin
process (Clk,Reset)
variable Zero : FP_S_3_14 := (others => ’0’);
variable R_sh : FP_S_3_14;
variable I_sh : FP_S_3_14;
variable R_next : FP_S_3_14;
variable I_next : FP_S_3_14;
begin
if(Reset = ’0’)then
Copy_S(R_out,Zero);
Copy_S(I_out,Zero);
Copy_S(Phase_out,Zero);
elsif (Clk’event AND Clk=’1’) then
91
if (I_tmp>=Zero) then
Copy_V( R_next , R_tmp + Smi(2,I_tmp));
Copy_V( I_next , I_tmp - Smi(2,R_tmp));
Copy_S( Phase_out,Phase+fffase(2));
else
Copy_V( R_next , R_tmp - Smi(2,I_tmp));
Copy_V( I_next , I_tmp + Smi(2,R_tmp));
Copy_S( Phase_out,Phase-fffase(2));
end if;
Copy_S( R_out , R_next);
Copy_S( I_out , I_next);
end if;
end process;
end cor_2a;
corout.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
use WORK.compl_func.all;
entity cor_out is
port(
R_in : in FP_S_1_14;
I_in : in FP_S_1_14;
R_tmp : in FP_S_3_14;
Phase : in FP_S_3_31;
Sign : in std_logic;
Clk : in std_logic;
Reset : in std_logic;
Fase : out FP_S_3_12
);
end cor_out;
architecture cor_outa of cor_out is
begin
process (Clk,Reset)
variable Zero : FP_S_1_14 := (others => ’0’);
variable Und : FP_S_1_14 := (others => ’U’);
variable Ics : FP_S_1_14 := (others => ’X’);
variable Zero2 : FP_S_3_14 := (others => ’0’);
variable Phase_Tmp : FP_S_3_31;
variable Pi : FP_S_3_14:= "001100100100010000"; --pigreco
92
moltip.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.fix_std.all;
entity moltip is
port(
clk : in std_logic;
Reset : in std_logic;
R_in : in FP_S_1_14;
I_in : in FP_S_1_14;
coeff_in : in FP_S_1_13;
93
psk.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.fix_std.all;
entity psk is
port(
clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Symbol :in std_logic_vector(2 downto 0);
R_out : out FP_S_1_14;
I_out : out FP_S_1_14
);
end psk;
architecture psk_a of psk is
begin
process (Clk,Reset)
variable Cnt: std_logic_vector(3 downto 0);
begin
if(Reset = ’0’)then
94
Cnt := "0000";
elsif (Clk’event AND Clk=’1’) then
Cnt := Cnt + "0001";
case Cnt is
when "0000" =>
case Symbol is
when "000" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
when "001" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
.....
end case;
when "0001" =>
case Symbol is
when "000" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
when "001" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
.....
end case;
........
when "1111" =>
case Symbol is
when "000" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
when "001" =>
R_out <= "0000000000000000";
I_out <= "0000001000101100";
.......
end case;
end case;
end if;
end process;
end psk_a;
Elenco delle figure
95
ELENCO DELLE FIGURE 96
99
BIBLIOGRAFIA 100