3gpp fdd baseband test data generatorktt1/kalle/ktuulos_gradu_release.pdf · kalle tuulos: 3gpp fdd...
TRANSCRIPT
3GPP FDD Baseband Test Data Generator
Pro gradu -tutkielmaTurun yliopistoInformaatioteknologian laitosElektroniikka ja tietoliikennetekniikka2002Kalle Tuulos
Tarkastajat:Prof. Valery Ipatov, Turun yliopistoProf. Jouni Isoaho, Turun yliopistoDI Kaj Jansen, NokiaFil. lis. Keijo Möttönen, Nokia
Your word is a lamp to my feet
and a light for my path.
Psalm 119:105
UNIVERSITY OF TURKUDepartment of Information Technology
Kalle Tuulos: 3GPP FDD Baseband Test Data Generator
Masters Thesis, 74 p., 110 app. p.Laboratory of Electronics and Information TechnologyFebruary 2002
The 3rd Generation Partnership Project (3GPP) is a global wideband CDMA (WCDMA)cellular phone standard. In this thesis, a system was developed to generate I/Q test datafor certain downlink physical channels in the 3GPP WCDMA.The work introduces the features and definitions of the 3GPP WCDMA that are essentialfrom the point of view of test data generation. The 3GPP Release 99/June 2001 has beenused as a design reference.The test data generation system provides support for the following physical channels: Pri-mary Synchronization Channel (P-SCH), Secondary Synchronization Channel (S-SCH),Primary Common Pilot Channel (P-CPICH) and Secondary Common Pilot Channel(S-CPICH). The generated test data is oversampled and filtered with a root-raised co-sine (RRC) filter. The system supports the STTD and TSTD transmit diversity modes.In addition to test data generation, the system has simulation capabilities. The system hasa channel model to simulate multipatch propagation with AWGN. The system has alsocapabilities to simulate certain fundamental receiver procedures which are the primarysearch code search, the scrambling code group identification, the impulse response mea-surement for P-CPICH and the initial synchronization. The receiver may be simulatedwith either floating-point or bit-limited arithmetics.The system has a complete instruction manual, which is written as an independent chapterin this thesis. Examples for usage and simulation of the system are given in the end of thework.The system has been implemented in ANSI-C language. The distribution package of thesystem is available at:http://www.tuulos.net/kalle/progradu.htmlThe distribution package contains the source files for the system software and the sampleconfiguration files which have been used in the work. In addition to these, the distributionpackage contains binary executables for Microsoft Windows.
Keywords: 3GPP, WCDMA, FDD, L1, testing
TURUN YLIOPISTOInformaatioteknologian laitos
Kalle Tuulos: 3GPP FDD Baseband Test Data Generator
Pro Gradu -tutkielma, 74 s, 110 liites.Elektroniikka ja tietoliikennetekniikkaHelmikuu 2002
3GPP eli 3rd Generation Partnership Project on laajakaistaiseen CDMA-järjestelmään(WCDMA) perustuva kolmannen sukupolven maailmanlaajuinen matkapuhelinstandardi.Tässä työssä on kehitetty ohjelmisto, joka luo 3GPP WCDMA:n mukaista I/Q-tasossaolevaa testidataa tietyille laskevan siirtotien fyysisille kanaville.Työssä esitellään testidatan luontiohjelmiston kannalta keskeiset 3GPP WCDMA:n omi-naisuudet ja määritelmät. Suunnittelureferenssinä on käytetty 3GPP:n versiota Release 99(heinäkuun 2001 tilanne).Testidatan luontiohjelmisto tukee seuraavia fyysisiä kanavia: ensisijainen synkronointi-kanava (P-SCH), toissijainen synkronointikanava (S-SCH), ensisijainen yhteinen pilotti-kanava (P-CPICH) ja toissijainen yhteinen pilottikanava (S-CPICH). Luotu testidata yli-näytteistetään ja suodatetaan neliöön nostetun kosinin (RRC) suodattimella. Ohjelmistotukee STTD ja TSTD -diversiteettilähetysmuotoja.Testidatan luonnin lisäksi ohjelmistossa on simulointiominaisuuksia. Ohjelmistoon on to-teutettu kanavamalli kohinaiselle monitie-etenemiselle. Ohjelmistolla voidaan simuloidamyös tiettyjä vastaanottimessa tarvittavia keskeisiä toimintoja, jotka ovat ensimmäisenhakukoodin (PSC) haku, levityskoodiryhmän haku, P-CPICH -kanavan impulssivastemit-taus ja alkusynkronointialgoritmi. Nämä toiminnot voidaan simuloida joko liukuluvuillatai bittirajoitetusti.Testidatan luontiohjelmiston täydelliset käyttöohjeet on kirjoitettu omaksi itsenäiseksikappaleekseen. Työn lopussa on annettu järjestelmän käyttö- ja simulointiesimerkkejä.Ohjelmisto on kehitetty ANSI-standardin mukaisella C-kielellä. Ohjelmiston levityspa-ketti on saatavilla osoitteesta:http://www.tuulos.net/kalle/progradu.htmlLevityspaketti sisältää ohjelmiston lähdekoodit ja samat esimerkkiasetustiedostot, joitaon käytetty itse työssä. Näiden lisäksi levityspaketissa on valmiiksi käännetty ohjelmistoMicrosoft Windowsille.
Asiasanat: 3GPP, WCDMA, FDD, L1, testaus
Contents
List of Figures
List of Tables
List of Acronyms and Abbreviations i
1 Introduction 1
2 3GPP WCDMA Physical Layer Basics 3
2.1 Multiple access method . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Data path between BS and UE . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Introduction to codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.1 Channelization code . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.2 Scrambling code . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3.3 Primary Synchronization Code . . . . . . . . . . . . . . . . . . . 9
2.3.4 Secondary Synchronization Codes . . . . . . . . . . . . . . . . . 10
2.3.5 Modulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.6 Chip pulse-shaping . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4 Physical channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.4.1 Uplink physical channels . . . . . . . . . . . . . . . . . . . . . . 14
2.4.2 Downlink physical channels . . . . . . . . . . . . . . . . . . . . 14
2.5 Physical channels needed in this work . . . . . . . . . . . . . . . . . . . 15
2.5.1 Primary Synchronization Channel . . . . . . . . . . . . . . . . . 15
2.5.2 Secondary Synchronization Channel . . . . . . . . . . . . . . . . 16
2.5.3 Primary Common Pilot Channel . . . . . . . . . . . . . . . . . . 16
2.5.4 Secondary Common Pilot Channel . . . . . . . . . . . . . . . . . 16
2.6 Transmit diversity methods . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.7 Hard, soft and softer handover . . . . . . . . . . . . . . . . . . . . . . . 18
3 Requirements for the system 19
3.1 Data generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Channel profile utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3 Merging utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4 Receiver simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4 Implementation description 22
4.1 Data Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.1 Generation of primary synchronization code sequence . . . . . . 23
4.1.2 Generation of secondary synchronization code sequences . . . . . 24
4.1.3 Generation of channelization code sequences . . . . . . . . . . . 24
4.1.4 Generation of scrambling code sequences . . . . . . . . . . . . . 26
4.1.5 Generation of Hadamard matrix row . . . . . . . . . . . . . . . . 27
4.1.6 Creating one slotful of physical channel data . . . . . . . . . . . 28
4.1.7 Mixing samples from multiple base stations . . . . . . . . . . . . 29
4.1.8 Chip oversampling and pulse-shaping . . . . . . . . . . . . . . . 29
4.2 Channel profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.2.1 Channel profile delay line operation . . . . . . . . . . . . . . . . 32
4.2.2 Generation of Additive White Gaussian Noise . . . . . . . . . . . 33
4.3 Merging utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.4 Receiver Simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.4.1 Input data processing . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4.2 Matched filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.4.3 PSC search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.4.4 SSC search i.e. Scrambling code group detection . . . . . . . . . 39
4.4.5 Impulse response measurement for CPICH . . . . . . . . . . . . 40
4.4.6 Initial synchronization procedure . . . . . . . . . . . . . . . . . 41
4.4.7 Result data processing . . . . . . . . . . . . . . . . . . . . . . . 42
4.5 Common function library . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.6 Source code files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5 User’s Guide to System 46
5.1 Software license . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.2 Timing issues between UE and network . . . . . . . . . . . . . . . . . . 48
5.3 Data generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.3.1 Data generator specific settings . . . . . . . . . . . . . . . . . . 51
5.3.2 Base station specific settings . . . . . . . . . . . . . . . . . . . . 51
5.3.3 Command line use . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.4 Channel profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.4.1 Command line use . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.5 Merging utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.5.1 Command line use . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.6 Receiver simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.6.1 Supported procedures . . . . . . . . . . . . . . . . . . . . . . . . 57
5.6.2 Configuration of simulator . . . . . . . . . . . . . . . . . . . . . 59
5.6.3 Command line use . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.7 Simulating multiple base stations . . . . . . . . . . . . . . . . . . . . . . 62
5.8 Data formats in files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.8.1 Data format in files between components . . . . . . . . . . . . . 63
5.8.2 Data formats in files produced by receiver simulator . . . . . . . 63
6 Simulation Examples 65
6.1 PSC search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.2 SSC correlation measurement . . . . . . . . . . . . . . . . . . . . . . . . 67
6.3 P-CPICH impulse response measurement . . . . . . . . . . . . . . . . . 69
6.4 Initial synchronization procedure . . . . . . . . . . . . . . . . . . . . . . 70
7 Conclusions and further development 71
7.1 Comparing simulator software to real devices . . . . . . . . . . . . . . . 71
7.2 Further development of the data generator system . . . . . . . . . . . . . 72
7.3 Notes about this master’s thesis . . . . . . . . . . . . . . . . . . . . . . . 72
References 73
Appendices
A Flowcharts A-1
A.1 Data generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-1
A.2 Channel profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-7
A.3 Merging utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-8
A.4 Simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-9
B Allocation of SSCs for secondary SCH B-1
C Data generator configuration file C-1
D Channel profile definition file D-1
E Receiver simulator configuration file E-1
F Source code files F-1
List of Figures
2.1 Data path from UE to BS . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Frame structure of SF = 256 downlink channel . . . . . . . . . . . . . . 5
2.3 Configuration of downlink scrambling code generator . . . . . . . . . . . 9
2.4 QPSK modulation scheme . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Spectrum of non-filtered chip stream . . . . . . . . . . . . . . . . . . . . 12
2.6 Impulse response of the pulse-shape filter . . . . . . . . . . . . . . . . . 13
2.7 Pass spectrum of the pulse-shape filter . . . . . . . . . . . . . . . . . . . 13
4.1 Modules inside data generator . . . . . . . . . . . . . . . . . . . . . . . 23
4.2 Main level signal flow figure for the data generator . . . . . . . . . . . . 24
4.3 Generating test data for one base station . . . . . . . . . . . . . . . . . . 25
4.4 Example of chip sequence oversampling . . . . . . . . . . . . . . . . . . 30
4.5 Channel model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.6 Top level signal flowchart of receiver simulator . . . . . . . . . . . . . . 35
4.7 Principle of matched filter . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.1 Possible ways how to use system . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Example of timings of two base stations . . . . . . . . . . . . . . . . . . 49
5.3 Example of PSC search result with two base stations . . . . . . . . . . . 49
6.1 Impulse response measurement result (power domain) for primary
synchronization code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.2 Zoomed-in impulse response measurement result for primary synchro-
nization code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6.3 Result of secondary search code correlation measurement . . . . . . . . . 68
6.4 Correlation result (power domain) for CPICH . . . . . . . . . . . . . . . 69
6.5 Correlation result (phase domain) for CPICH . . . . . . . . . . . . . . . 70
A.1 Flowchart: data generator shell . . . . . . . . . . . . . . . . . . . . . . . A-1
A.2 Flowchart: data generation main loop . . . . . . . . . . . . . . . . . . . A-2
A.3 Flowchart: data generation for one base station . . . . . . . . . . . . . . A-3
A.4 Flowchart: data generation for one frame . . . . . . . . . . . . . . . . . . A-4
A.5 Flowchart: merging generated data with previously generated data . . . . A-5
A.6 Flowchart: chip oversampling and filtering . . . . . . . . . . . . . . . . . A-6
A.7 Flowchart: channel profile . . . . . . . . . . . . . . . . . . . . . . . . . A-7
A.8 Flowchart: merging utility . . . . . . . . . . . . . . . . . . . . . . . . . A-8
A.9 Flowchart: receiver simulator shell . . . . . . . . . . . . . . . . . . . . . A-9
A.10 Flowchart: initial synchronization procedure . . . . . . . . . . . . . . . . A-10
List of Tables
4.1 List of source code files . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
B.1 Allocation of SSCs for secondary SCH . . . . . . . . . . . . . . . . . . . B-1
List of Acronyms and Abbreviations
2G Second Generation. Digital cellular telecommunication systems developed in the
80’s or 90’s. For example, GSM, PDC, IS-95 and IS-136 belong to 2G systems.
3GPP 3rd Generation Partnership Project. See [9] for more information.
AGC Automatic Gain Control.
AICH Acquisition Indicator Channel. See chapter 2.4.2 for more information.
AP-AICH CPCH Access Preamble Acquisition Indicator Channel. See chapter 2.4.2 for
more information.
ASIC Application Specific Integrated Circuit
AWGN Additive White Gaussian Noise.
BS Base Station.
CD/CA-ICH CPCH Collision Detection/Channel Assignment Indicator Channel. See
chapter 2.4.2 for more information.
CDMA Code Division Multiple Access.
CPCH Common Packet Channel. See chapter 2.4.1 for more information.
CPICH Common Pilot Channel. See chapter 2.4.2 for more information.
CSICH CPCH Status Indicator Channel. See chapter 2.4.2 for more information.
DCH Data Channel. General term for all data channels.
DL-DPCH Downlink Dedicated Physical Channel. See chapter 2.4.2 for more informa-
tion.
DPCCH Dedicated Physical Control Channel. See chapter 2.4.1 for more information.
DPDCH Dedicated Physical Data Channel. See chapter 2.4.1 for more information.
DSP Digital Signal Processor or Digital Signal Processing, depending on the context.
FDD Frequency Division Duplex. See chapter 2.1 for more information.
FIR Finite Impulse Response.
GSM Originally Groupe Spéciale Mobile, nowadays Global System for Mobile Commu-
nications. Europe originated 2G TDMA cellular system.
IIR Infinite Impulse Response.
IRM Impulse Response Measurement.
IS-95 United States originated 2G CDMA cellular system.
IS-136 United States originated 2G TDMA cellular system.
L1 Physical layer in Open Systems Interface model.
MIPS Million Instructions Per Second.
OVSF Orthogonal Variable Spreading Factor. Channelization codes.
P-CCPCH Primary Common Control Physical Channel. See chapter 2.4.2 for more in-
formation.
P-CPICH Primary Common Pilot Channel. See chapter 2.5.3 for more information.
PDC Japanese 2G TDMA cellular system.
P-SCH Primary Synchronization Channel. See chapter 2.5.1
PCPCH Physical Common Packet Channel. See chapter 2.4.1 for more information.
PDSCH Physical Downlink Shared Channel. See chapter 2.4.2 for more information.
PICH Paging Indicator Channel. See chapter 2.4.2 for more information.
PRACH Physical Random Access Channel. See chapter 2.4.1 for more information.
PSC Primary Synchronization Code. Also known as Primary Search Code. Sometimes
P-SCH is called as PSC. See chapter 2.3.3 for more information.
QPSK Quadrature Phase Shift Keying. Modulation method, where signal is split to in-
phase and quadrature phase components. See figure 2.4 for scheme.
RRC Root Raised Cosine.
RX Reception, receiver.
S-CPICH Secondary Common Pilot Channel. See chapter 2.4.2 for more information.
S-CCPCH Secondary Common Control Physical Channel. See chapter 2.4.2 for more
information.
SCH Synchronization Channel. See chapter 2.4.2 for more information.
SSC Secondary Synchronization Code. Also known as Secondary Search code. See
chapter 2.3.4 for more information.
STTD Space Time Transmit Diversity.
TDD Time Division Duplex. See chapter 2.1 for more information.
TDMA Time Division Multiple Access.
TSTD Time Switched Transmit Diversity.
TX Transmission, transmitter.
UE User Equipment.
VHDL VHSIC Hardware Description Language.
VHSIC Very High Speed Integrated Circuits.
WCDMA Wideband CDMA.
Chapter 1
Introduction
Today, many universities give instruction about Wideband CDMA (WCDMA). The scope
of teaching is usually very theoretical, but there are usually some projects where the stu-
dents are introduced to the practical aspects of this system. However, as the WCDMA
standard is still quite new, there are usually no tools for universities to for instance gener-
ate real test data for the Physical layer in Open Systems Interface model (L1).
There are many commercial WCDMA testers and test data generators available, for
example, Anritsu’s MD8480A WCDMA Signalling Tester [16]. However, their price is
usually too high for universities. In some mathematical toolkits such as MatLab, there are
limited WCDMA test data generation abilities, but in general, there are no free (or cheap)
test data generation systems available.
The target of this thesis is to create a simple downlink test data generation and simu-
lation system which would be free to use for anyone. The system meets the requirements
of 3GPP Release 99/June 2001, which is the design reference for the first commercial
WCDMA networks. The capabilities of the system are sufficient for use in laboratory
experiments.
The purpose of this thesis is to find software implementation solutions to certain L1
procedures required by 3GPP. This paper does not include much theoretical discussion
about the WCDMA system — the facts are presented as they are given by 3GPP standards.
The software is designed to be as instructional as possible, i.e. its implementation is not
efficient what comes to the memory or cycle consumption, but the procedures are clear
and they can easily be developed further.
This work relies heavily on the L1 of 3GPP WCDMA, and therefore the basics of this
L1 are explained in chapter 2. Chapter 3 sets the requirements for the test data generation
and simulation system. Chapter 4 explains the design and implementation of the system.
Chapter 5 explains the usage of the system to such a level that along with chapter 6,
CHAPTER 1. INTRODUCTION 2
which demonstrates the capabilities of the system, it can be used as a User’s Guide. These
chapters together can be detached from the complete thesis and they may be given to the
end user.
The system is implemented completely in ANSI-C, so it is highly portable — it can
be compiled to almost any target environment having a C compiler. The system has
been verified to work in Microsoft Windows, HP-UX and SunOS. The binary executables
for Microsoft Windows, along with the sample configuration files, are available in the
distribution package.
The system is licensed under the GNU General Public License. The system may be
freely used, distributed and further developed by anyone. Please refer to the complete
license in the file copying.txt in Appendix F.
Chapter 2
3GPP WCDMA Physical Layer Basics
This chapter explains briefly the basics of 3rd Generation Partnership Project (3GPP)
WCDMA specific physical layer (L1). As it is assumed, that the reader has basic knowl-
edge about telecommunication, main principles are not explained deeply. In addition,
3GPP WCDMA system is every now and then compared to GSM, and thus basic knowl-
edge about GSM is required.
2.1 Multiple access method
The 3GPP WCDMA system uses the Code Division Multiple Access (CDMA) method.
This means that there are many simultanous users in the same frequency band. Com-
pared to Time Division Multiple Access (TDMA) used in, for example, European GSM,
Japanese PDC and in US IS-136, this multiple access method helps the radio access net-
work frequency planning because the same radio frequency can be used on the neighbor-
ing base stations.
Another major difference between CDMA and TDMA systems is that in TDMA sys-
tems, multipaths (i.e. delays produced by the radio channel) usually decrease the radio
link quality. In the CDMA systems, multipaths can be utilized much better thanks to a
different radio receiver architecture.
3GPP WCDMA consists of two subsystems, Frequency Division Duplex (FDD) and
Time Division Duplex (TDD). The difference between them is that in FDD, reception and
transmission are done simultaneously in different radio frequencies. In TDD, the same
radio frequency is used for both reception and transmission; hence TDD is a mixture of
the TDMA and CDMA systems. FDD seems to be the mainstream and TDD will be used
only by some operators in some limited areas. For example, in Finland, all WCDMA
networks will use FDD.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 4
C h a n n e lc o d i n g
S p r e a d i n gC h i p p u l s e -
s h a p e f i l t e r i n g
C h a n n e ld e c o d i n g
D e s p r e a d i n g & i n t e g r a t i n g
R Xf i l t e r i n g
U p p e rl a y e r s
U p p e rl a y e r s
B S
U E
R Fbits
sym
bo
ls
chip
s
Q P S Km o d u l a t i o n
Q P S Kd e m o d u l a t i o n
Figure 2.1: Data path from UE to BS
From this point forward, when the term WCDMA is used, it always refers to the 3GPP
FDD system.
2.2 Data path between BS and UE
Compared to the second generation systems, the data path in WCDMA differs signifi-
cantly only in L1. As the upper layers are designed to use quite similar signaling as in
GSM systems, the WCDMA networks can use the existing core networks in harmony
with GSM. Data path in downlink (i.e. from network to Base Station (BS) to User Equip-
ment (UE)) is expressed in Figure 2.1 and presented below. Because the uplink data path
has exactly the same operations as the downlink data path, it is not explained separately.
In the first step, data bits coming from upper layers are channel-coded and converted
to symbols. In downlink, one symbol represents two channel-coded data bits. In uplink,
one symbol represents one channel-coded bit. WCDMA uses partially similar convolution
coding methods as in GSM, but a new channel-coding method, Turbo coding, is used in
some channels. For more information about channel-coding, please see [5].
The next step is spreading symbols to chips. The chip rate in air interface is constant
3.84 Mcps (million chips per second) and because the data rate may vary, the spreading
factor (i.e. into how many chips one symbol is spread) also varies. Spreading factor SF
is two’s power between 4 and 512. The spreading is done by multiplying incoming the
symbols with channelization code (see chapter 2.3.1) so that every symbol is multiplied
with whole channelization code sequence. For example, if SF = 4, incoming symbol S
is spread to four chips by multiplying symbol with 4-bit long channelization code C and
the result is chip sequence K as follows:
Ki = S · Ci where i = 0 . . . 3 (2.1)
In the previous example, S, C and K were used to describe symbol, channelization
code and spread chip sequence.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 5
S l o t # 0 S l o t # 1 S l o t # i S l o t # 1 4
T f r a m e = 1 0 m s
S y m b o l # 0 S y m b o l # 1 S y m b o l # i S y m b o l # 9
T s l o t = 6 6 6 . 7 u s
T s y m b o l = 6 6 . 7 u s
C h i p # 2 5 5C h i p # 0 C h i p # 1 C h i p # i
T c h i p = 2 6 0 . 4 n s
Figure 2.2: Frame structure of SF = 256 downlink channel
In this phase, the chip rate is 3.84 Mcps i.e. the same as in the air interface. The
next step is scrambling the chip sequence by multiplying it with a scrambling code (see
chapter 2.3.2). This step ensures that the chip sequence consumes the entire bandwidht of
5 MHz [1].
The chip sequence contains now all the elements required by multiple access princi-
ples. However, for reasons explained in chapter 2.3.6, the chip sequence is pulse-shape
filtered before applying Quadrature Phase Shift Keying (QPSK) modulation and radio
transmission.
In one second, there are 100 frames which each consist of 15 slots. One slot consists
of symbols, but the number of symbols per slot varies depending of the used channel. In
channels supported by this work, spreading factor SF = 256, so the number of symbols
per slot is constant, i.e. 10 symbols per slot, and per symbol, there are 256 chips. See
Figure 2.2.
In the receiver end, the received signal is first QPSK demodulated and filtered with a
similar filter that is used in chip pulse-shape filtering. After this, the received chips are
converted to digital using fast A/D converters. Digital chip stream is typically oversam-
pled because of very strict synchronization requirements.
Digital chip stream is multiplied by the scrambling code and channelization code.
Results are integrated over period set by spreading factor and stored to symbols. On
parallel, pilot channel (see chapter 2.5.3) or channel specific-pilot symbols are constantly
being received for phase reference. The properties of radio channels can be estimated
from the received pilot symbols so the phase of a received symbol can be corrected to
nominal.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 6
The channel-estimated symbols are next sent to channel decoding. The method used
depends on the physical channel, but in any case the result is channel-decoded bit stream.
The bits are sent to the upper layers, and from this point forward, the operation of the data
path is quite similar as in GSM.
2.3 Introduction to codes
In CDMA systems, various codes are used for many purposes:
• Identification of base stations. Base stations are identified by their primary scram-
bling code which is unique to that geographical area. Similarly, UEs have different
scrambling codes.
• Separation of channels. Channelization codes preserve orthogonality between the
user’s different physical channels.
• Synchronization. Every base station transmits continuously specific synchroniza-
tion codes. UEs may deduce the base station timings and scrambling codes used by
receiving and decoding synchronization codes.
• Processing gain. (definition: Pg = 10 · log10(rchip/rbit)) By spreading the duty sig-
nal with code, smaller S/N (signal to noise ratios) i.e. smaller transmission powers
can be utilized. In the reception (simplified RX model with no multipaths), even
signals with negative S/N can be utilized — as long as S/N +Pg > target Eb/N0,
where Eb/N0 depends on the desired bit error rate.
• Privacy. Compared to GSM or analogue systems it is very difficult to intercept
transmission, if correct codes and correct timings are not known. Due to codes’
correlation properties, if code is unknown, timing is incorrect or both, the signal
received is just noise.
• Multiple access. Because of all the reasons mentioned above, many users can si-
multaneously utilize the same frequency band for communications.
2.3.1 Channelization code
As mentioned before, channelization codes are used to separate different physical chan-
nels. All channelization codes are Orthogonal Variable Spreading Factor (OVSF) codes.
Mathematically, channelization codes are Walsh codes [18] and they can be generated by
using the Walsh functions. Both uplink and downlink use the same channelization codes.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 7
There is a relation between the spreading factor SF and the set of allowed channel-
ization codes. When SF = k, the allowed codes are Cch,k,n, where 0 ≤ n < k. The
wrap-around length, i.e. length of code in chips, is also equal to k.
By the 3GPP definition, channelization codes are generated recursively by the follow-
ing method:
Cch,1,0 = [1][
Cch,2,0
Cch,2,1
]
=
[
Cch,1,0 Cch,1,0
Cch,1,0 −Cch,1,0
]
=
[
1 1
1 −1
]
Cch,2n+1,0
Cch,2n+1,1
Cch,2n+1,2
Cch,2n+1,3
...
Cch,2n+1,2n+1−2
Cch,2n+1,2n+1−1
=
Cch,2n,0 Cch,2n,0
Cch,2n,0 −Cch,2n,0
Cch,2n,1 Cch,2n,1
Cch,2n,1 −Cch,2n,1
......
Cch,2n,2n−1 Cch,2n,2n
−1
Cch,2n,2n−1 −Cch,2n,2n
−1
(2.2)
The leftmost value in each channelization code word corresponds to the chip trans-
mitted first in time.
For example, if SF = 256, there are 256 possible channelization codes. For some
physical channels, for example, Primary Common Pilot Channel (P-CPICH), 3GPP de-
fines the used channelization code, but for most channels, the code is allocated dynami-
cally.
From channelization code generation method it can be seen that channelization codes
are, in fact, Hadamard sequences of a length equal to the spreading factor SF . The
generation of Hadamard sequences is described later in this study, in chapter 2.3.4.
2.3.2 Scrambling code
Scrambling codes are used to spread the chip sequence over the whole bandwidth to
achieve a wideband signal. Channelization codes may also introduce some spreading,
but that can not be relied on because, for example, Cch,256,0 (used in Primary Common
Pilot Channel, CPICH) consists only of logical ’1’s so it does not spread the signal at all.
Downlink and uplink use scrambling codes of different kinds. Their properties, i.e.
type and wrap-around length, are not the same and they are also generated somewhat
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 8
differently.
In uplink connection, there are two kinds of scrambling codes, long and short ones.
There are altogether 224 long and 224 short scrambling codes. It depends on the physical
channel which scrambling code should be used, but in some physical channels, either long
or short scrambling code may be used. It is up to the network to decide, which scrambling
code types and which particular scrambling code number should be used. The reasons for
the base station to decide which scrambling code types (short or long) are used are beyond
the scope of this thesis. Please see [4] for more information.
In downlink connection, Gold sequences of length 218 are used for the scrambling
code. As in the uplink long scrambling codes, the sequences in downlink are truncated to
38400 chips to form a cycle of a 10 ms frame.
A total number of 218 − 1 = 262143 scrambling codes can be generated, but all of
them are not used. Scrambling codes are divided into 512 sets, each consisting of one
primary scrambling code and 15 secondary scrambling codes.
Scrambling codes are numbered 0 . . . 262142. The primary scrambling code numbers
are n = 16 ∗ i, where i = 0 . . . 511 denotes the scrambling code set number. Primary
scrambling codes are divided into 64 groups, each concisting of 8 primary scrambling
codes. The scrambling code groups are utilized for creating Secondary Search Code se-
quences for the Secondary Synchronization Channel, see chapter 2.5.2.
Secondary scrambling code numbers are n = 16∗i+k, where i denotes the scrambling
code set and k the secondary scrambling code inside that set. Quite often, scrambling code
set numbers are referred as to base station ID numbers, because to some geographical
areas, scrambling code set numbers are unique.
Every cell has one — and only one — primary scrambling code, i.e. only one scram-
bling code set. The most important downlink channels from the point of view of synchro-
nization, i.e. P-CCPCH and P-CPICH, are always transmitted using the primary scram-
bling code. Other downlink channels may be transmitted using either the primary or any
of the 15 secondary scrambling codes.
Because correlation properties of scrambling codes are very good, the timing between
BS and UE has to be very accurate. If timing is incorrect by more than 1 chip, only noise
will be decoded, i.e. radio link will be lost. Thus the UE — and also the BS — must
constantly keep track on radio link timing drifts.
Both the uplink and downlink scrambling codes are typically generated using shift
registers. Configuration of the downlink scrambling code generator is shown in Figure
2.3. The uplink scrambling code generation is not explained here, but its principles are
the same.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 9
I
Q
1
1 0
02
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
1 7
1 7
1 6
1 6
1 5
1 5
1 4
1 4
1 3
1 3
1 2
1 2
1 1
1 1
1 0
1 0Y
X
Figure 2.3: Configuration of downlink scrambling code generator
The same downlink scrambling code generator can be used to generate any scram-
bling code number, both the primary and secondary scrambling codes. First, the scram-
bling code generator (Figure 2.3) is initialized. In shift register ’X’, logical ’1’ is stored
to position 0 and logical ’0’ to positions 1 . . . 17. Next, if the desired scrambling code
number is n, the shift register ’X’ is rotated n times. Finally, logical ’1’s are stored to all
positions in the shift register ’Y’ and the contents of both registers are stored to shadow
registers for a wrap-around case.
The scrambling code generator produces one I,Q pair on every round. When one
frameful of I,Q pairs (i.e. 38400 pairs) have been generated, both shift registers need to be
initialized back to the start condition by copying the contents of shadow registers to shift
registers.
2.3.3 Primary Synchronization Code
The primary synchronization code (PSC), Cpsc is constructed as a sequence known as
generalised hierarchical Golay sequence [13]. The PSC is chosen to have good aperiodic
auto correlation properties. PSC is defined as follows:
Cpsc = (1 + j) × 〈a, a, a,−a,−a, a,−a,−a, a, a, a,−a, a,−a, a, a〉 (2.3)
where
a = 〈x1, x2, . . . x16〉 = 〈1, 1, 1, 1, 1, 1,−1,−1, 1,−1, 1,−1, 1,−1,−1, 1〉 (2.4)
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 10
The resulting bit sequence is complex-valued with identical real and imaginary com-
ponents. The generated PSC sequence is transmitted in the Primary Synchronization
Channel, see chapter 2.5.1.
2.3.4 Secondary Synchronization Codes
There are a total of 16 secondary synchronization codes (SSCs),
Cssc,1,Cssc,2, . . . ,Cssc,16 and they are constructed using the positionwise multipli-
cation of a Hadamard sequence and a sequence z which is defined as
z = 〈b, b, b, b, b, b,−b,−b, b,−b, b,−b,−b,−b,−b,−b〉
b = 〈x1, x2, x3, x4, x5, x6, x7, x8,
−x9,−x10,−x11,−x12,−x13,−x14,−x15,−x16〉
where x1, x2, . . . x16 are the same as in the definition of a in Equation 2.4.
The Hadamard sequences are obtained as rows in a matrix H8, constructed recursively
by:
H0 = [1]
Hk =
[
Hk−1 Hk−1
Hk−1 −Hk−1
]
, k ≥ 1 (2.5)
The rows are numbered from the top starting with row 0 (the all ones sequence).
Denote the nth Hadamard sequence as a row of H8 numbered from the top, n =
0, 1, 2, . . . , 255, in the sequel. Furthermore, let hn(i) and z(i) denote the ith symbol of
the sequence hn and z, respectively where i = 0, 1, 2, . . . , 255 and i = 0 corresponds to
the leftmost symbol.
The kth SSC, Cssc,k where k = 1, 2, . . . 16 is then defined as
Cssc,k = (1 + j) × 〈hm(0) × z(0), hm(1) × z(1), . . . hm(255) × z(255)〉 (2.6)
where m = 16 × (k − 1) and the leftmost chip in the sequence corresponds to the
chip transmitted first in time. Generated SSC sequences are transmitted in the Secondary
Synchronization Channel, see chapter 2.5.2.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 11
S
I m { S }
R e { S }
c o s ( w t )
C o m p l e x - v a l u e dc h i p s e q u e n c ef r o m s p r e a d i n go p e r a t i o n s
- s i n ( w t )
S p l i tr e a l &i m a g .p a r t s
P u l s e -s h a p i n g
P u l s e -s h a p i n g
Figure 2.4: QPSK modulation scheme
2.3.5 Modulation
The modulating chip rate is 3.84 million chips per second. Complex-valued chip sequence
generated by the spreading process is QPSK modulated, as shown in Figure 2.4.
2.3.6 Chip pulse-shaping
As a modulated chip stream is of a square-wave type, its spectrum is of sinc type (see
Figure 2.5). Such a spectrum is not limited and it has high harmonic distortions. If the
chip stream would be transmitted unfiltered, it would cause heavy noise on neighboring
channels. In addition, the transmitter’s frequency range is not broad enough to transmit
the entire spectrum, which would cause even more distortion and power losses.
To avoid needless interference to neighboring bands, the chip stream needs (see [1]
and [2]) to be shape-filtered with a root-raised cosine type filter. 3GPP does not require
any specific implementation for the filter, but the impulse response should be as follows:
RC0(t) =sin
(
π tTc
(1 − α))
+ 4α tTc
cos(
π tTc
(1 + α))
π tTc
(
1 −(
4α tTc
)2) (2.7)
where
Tc =1
chiprateand roll-off factor α = 0.22
See figures 2.6 and 2.7 for pulse shape filter’s impulse response and pass spectrum.
As seen from Figure 2.4, complex-valued chip stream is fed to pulse-shape filter’s
input. Inside the pulse-shape filter, the input stream in oversampled so that if the over-
sampling factor is k, every kth sample value is read from the pulse-shape filter input and
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 12
-80
-70
-60
-50
-40
-30
-20
-10
0
-15 -12.5 -10 -7.5 -5 -2.5 0 2.5 5 7.5 10 12.5 15
Spe
ctra
l pow
er le
vel [
dB]
Frequency [MHz]
Figure 2.5: Spectrum of non-filtered chip stream
all other values are zeroes. The oversampled chip stream is then filtered using Equa-
tion 2.7. Because the oversampled chip stream consists of impulses only, the resulting
spectrum is exactly the same as the pass spectrum of the pulse-shape filter (Figure 2.7).
In the receiver end, the signal is filtered again. 3GPP does not specify the exact
filter to be used — there are just minimum requirements for neighbor band blocking
capability. Reception filtering can be performed using exactly the same pulse-shape filter
as in transmission. By using the same filter, the in-band S/N ratio increases and receiver’s
dynamic range can be utilized better.
Pulse-shape filtering can be performed using either digital or analog filters. If digital
filters are used, the chip sequence has to be oversampled with a relatively high oversam-
pling factor (≥ 4), which results in very high data rates and very high data processing
needs. For example, if the oversampling factor is 8 and chip rate is 3.84 Mcps, the data
rate would be about 31 million I/Q pairs per second. If the pulse-shape filter would be
4.5 chips (i.e. 36 samples) long, the processing of one incoming I/Q pair would require
72 multiplications and 72 additions. Contemporary DSPs have one-cycle assembler com-
mands for calculating two finite impulse response filters (FIRs) in parallel, so processing
of one I/Q pair would consume roughly 40 assembler cycles. Thus, the needed processing
power would be more than 1200 Million Instructions Per Second (MIPS). This is why it
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 13
-0.4
-0.2
0
0.2
0.4
0.6
0.8
1
1.2
0 1 2 3 4 5 6 7 8
Filt
er o
utpu
t
Time [chip #]
Figure 2.6: Impulse response of the pulse-shape filter
-80
-70
-60
-50
-40
-30
-20
-10
0
-15 -12.5 -10 -7.5 -5 -2.5 0 2.5 5 7.5 10 12.5 15
Spe
ctra
l pow
er le
vel [
dB]
Frequency [MHz]
Figure 2.7: Pass spectrum of the pulse-shape filter
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 14
is practical to perform the chip pulse-shape filtering using analog components or digital
ASICs.
2.4 Physical channels
In this chapter, both uplink and downlink physical channels are explained briefly. For
more information, please see [4].
2.4.1 Uplink physical channels
CPCH Common Packet Channel is used to carry uplink packet data.
DPDCH Dedicated Physical Data Channel is used to carry the Data Channel (DCH)
transport channel, i.e. the payload data. There may be zero, one or several uplink
DPDCHs on each radio link.
DPCCH Dedicated Physical Control Channel is used to carry control information gen-
erated at L1. This control information consists of, for example, power control com-
mands. There is always one — and only one — uplink DPCCH on each radio link.
PRACH Physical Random Access Channel carries the Random Access traffic channel,
which is used in random access transmissions. Those include, for example, signing
into and out from network, starting a new call etc. In some cases, this is also used
to deliver packet data.
PCPCH Physical Common Packet Channel carries the Common Packet Channel, which
is used in delivering packet data from UE to BS.
2.4.2 Downlink physical channels
CPICH Common Pilot Channel is fixed-rate (30 kbps, SF = 256) and carries a pre-
defined symbol sequence. There are two types of common pilot channels, Primary
and Secondary. See chapters 2.5.3 and 2.5.4.
P-CCPCH Primary Common Control Physical Channel is transmitted to the entire cell
area and it carries, for example, broadcast channel, which contains cell parameters.
SCH Synchronization Channel is mandatory for the UE synchronization procedure to
network. See chapters 2.5.1 and 2.5.2.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 15
S-CCPCH Secondary Common Control Physical Channel carries, for example, paging
information.
DL-DPCH Downlink Dedicated Physical Channel is used to carry streaming payload
data which is targeted for one UE only, for example, voice data in phone calls.
PICH Paging Indicator Channel is used for power-saving purposes: for example in GSM,
paging message has to be received every paging period. However, the reception and
decoding of a paging message is time-consuming because pagings are still quite
rare. PICH contains only a very short symbol sequence which tells, whether UE
has to receive the actual paging message or not. Receiving and decoding of the
PICH sequence is very fast and UE has to receive the actual paging message only
very infrequently.
PDSCH Physical Downlink Shared Channel is used to carry the downlink shared channel
which is associated with a dedicated downlink channel.
AICH Acquisition Indicator Channel carries responses to random access preambles.
The RACH/AICH-pair is used to set transmission power to an adequate level before
starting the actual transmission.
AP-AICH CPCH Access Preamble Acquisition Indicator Channel carries responses to
packet data preambles — this procedure is similar to AICH/RACH.
CD/CA-ICH CPCH Collision Detection/Channel Assignment Indicator Channel is used
in the packet data procedure.
CSICH CPCH Status Indicator Channel carries packet data status information.
2.5 Physical channels needed in this work
2.5.1 Primary Synchronization Channel
Primary Synchronization Channel (P-SCH) is sent multiplexed with the first symbol of
the Primary Common Control Physical Channel (P-CCPCH). P-SCH always contains the
primary synchronization code (PSC, see chapter 2.3.3).
As every base station in the whole WCDMA network transmits P-SCH with the same
code, this channel is used as a starting point in the synchronization procedure. When UE
starts synchronizing into the network, it uses a matched filter to measure the correlation
between the known PSC sequence and the received chip stream. If the correlation result is
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 16
close to noise, it is likely that there are no base stations on that frequency band, and then
UE may measure the next band. If UE finds strong enough a correlation result, the timing
of this result can be used as a time reference between UE and BS, and the synchronization
procedure can continue by receiving S-SCH.
2.5.2 Secondary Synchronization Channel
Like P-SCH, the Secondary Synchronization Channel (S-SCH) is also sent multiplexed
with the first symbol of P-CCPCH. S-SCH contains a certain sequence of SSC codes (see
chapter 2.3.4). There are 64 different sequences and all are unique so that it is possible
to deduce the starting moment of the sequence. The SSC sequence number refers to the
scrambling code group to which the cell’s scrambling code set belongs.
SSC sequences are 15 codes long in the way that first code is sent in the first slot of
frame. Thus, after the sequence has been recognized, the base station frame timing is
known. The sequence depends on the base station scrambling code group. The sequences
are listed in Table B.1 in Appendix B.
2.5.3 Primary Common Pilot Channel
The Primary Common Pilot Channel (P-CPICH) has the following characteristics:
• Channelization code is predefined to Cch,256,0.
• Scrambling code is the primary scrambling code of the cell.
• There is one — and only one — P-CPICH per cell.
• P-CPICH is broadcast over the entire cell.
The P-CPICH is the default phase reference for all downlink physical channels.
2.5.4 Secondary Common Pilot Channel
A Secondary Common Pilot Channel (S-CPICH) has the following characteristics:
• Any channelization code of SF = 256 may be used for it.
• It may be scrambled either by the primary or a secondary scrambling code.
• There may be zero, one, or several S-CPICHs per cell.
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 17
• A S-CPICH may be transmitted over the entire cell or only over a part of the cell.
A S-CPICH may be used as phase reference for a secondary CCPCH and the downlink
DPCH.
2.6 Transmit diversity methods
In urban areas, there are plenty of reflections (i.e. multipaths) in the radio signal. This is
very easily detected by listening to a FM radio in the car while driving through a city cen-
ter — every now and then there are ’clicks’ in the sound. These ’clicks’ are very harmful
for UE’s radio reception because in the moment of the ’click’, the level of received signal
is very low and the signal cannot be utilized. These ’clicks’ are referred to as fast fading.
To help the situation, different transmit diversity methods have been developed. The
idea is that in BS there are two separate TX antennas at a certain distance from each
other. The transmission in antennas is also slightly different — the special TX diversity
encoding is used on second antenna.
Because TX antennas are in slightly different locations, their transmissions will have
a somewhat different multipath profile and it is likely that when another TX antenna has
a fast fade, the signal level of another antenna is still usable. By receiving transmissions
from both antennas and by decoding TX diversity code, the quality of received signal still
be very good.
There are three main modes of TX diversity:
STTD Space Time Transmit Diversity. Space time block coding based transmit antenna
diversity may be used for most of physical channels. The main idea is that the first
TX antenna transmits data as is, i.e. without any TX diversity, and the second TX
antenna transmits encoded data in parallel.
TSTD Time Switched Transmit Diversity is used only in synchronization channels. In
consecutive slots, synchronization channels are transmitted from different TX an-
tennas.
Closed-loop Mode This main mode is used only for DPCH and PDSCH. It has two sub-
modes which are otherwise similar but have different pilot patterns.
It is mandatory for UEs to support all TX diversity modes. However, it is optional for
the network to use them. For more information about TX diversity, please see [4].
CHAPTER 2. 3GPP WCDMA PHYSICAL LAYER BASICS 18
2.7 Hard, soft and softer handover
In TDMA systems such as GSM, UE is in radio connection with one cell at a time. When
UE needs to change to a different cell, i.e. perform a handover, first it has to disconnect
the radio link with the first cell, change its radio frequency and then establish a radio link
with a new cell. A problem arises, when the quality of radio link decreases quickly, for
example, when driving to a tunnel. If the network can not quickly enogh command UE to
perform a handover, the radio link is lost and the phone call may be disconnected.
In CDMA systems there is a concept called soft handover. Because many cells may
use the same radio frequency, UE may receive the signal simultaneously from many cells.
Also UE’s transmission is being received simultaneously by many cells. The advantage
of this procedure is that even if some radio links would quickly disappear, for example,
when CDMA user drives to the same tunnel as the GSM user, some other radio links may
still be valid and the phone call can continue.
There is also a concept called softer handover. To increase their capacity, some cells
are sectored. When UE is in a simultaneous connection with many sectors of the same
cell, the situation is called softer handover. From the UE point of view, it is quite a similar
situation as the soft handover — UE is just receiving many multipaths and combines them
to one payload signal.
As all cells in the WCDMA system are not at the same frequency, there are some
situations when UE must change frequencies. These situations are called hard handovers.
In a hard handover, UE has to discard old radio links, change frequencies and establish
new radio links — just like in TDMA system. Networks are, however, designed so that
hard handovers will be very rare, they will occur usually only when UE’s geographical
area has changed much.
Most of WCDMA UEs will support the dual-mode, i.e. they are able to work both in
GSM and WCDMA networks. Such phones may perform a hand-off between different
systems. In these situations, the phone call does not disconnect and the phone user does
not notice at all that the phone has changed its operation mode from WCDMA to GSM or
vice versa.
Chapter 3
Requirements for the system
The test data generation system should contain the following major components: data
generator, channel profile utility, merging utility and receiver simulator. Each of them
should be usable independently from each other and each of them should be directly
replacable by an external application, for example, MatLab or DSP application.
3.1 Data generator
The data generator should be able to generate test data for a single base station or many in-
dependent base stations. For each base station, it should be able to generate the following
physical channels:
• Primary Synchronization Channel (P-SCH): Zero or one P-SCH per cell
• Secondary Synchronization Channel (S-SCH): Zero or one S-SCH per cell
• Primary Common Pilot Channel (P-CPICH): Zero or one P-CPIH per cell
• Secondary Common Pilot Channel (S-CPICH): Number of S-CPICHs per cell
should be 0, 1, 2, . . . 14
Data generator should support the following transmit diversities: STTD and TSTD.
For each generated base station, the base station’s transmission power, timing, trans-
mit diversity settings, and properties of generated physical channels should be adjustable
independently.
For each generated physical channel, transmission power should be adjustable inde-
pendently.
CHAPTER 3. REQUIREMENTS FOR THE SYSTEM 20
For each generated Secondary Common Pilot Channel, channelization and scrambling
codes should be adjustable independently.
The data generated should be oversampled and pulse-shape filtered according to the
3GPP requirements [2]. Oversampling factor Fos should be adjustable in two’s power in
the range Fos = 1, 2, 4, . . . 16. Pulse-shape filter’s length l in chips should be adjustable
in the range l = 1, 2, 3, . . . 16. It should be possible to disable or enable pulse-shape
filtering. The oversampling factor and pulse-shape filtering settings should be common
for all the base stations generated.
The data generator should be designed and implemented in a way that allows porting
it to an embedded system and expanding the data generator’s abilities in future.
3.2 Channel profile utility
The channel profile utility should contain a stationary multipath fading AWGN channel
model with TX diversity support. For each multipath, the delay, attenuation, and phase
coefficients should be adjustable independently. The channel profile utility should support
all the oversampling factors supported by the data generator.
3.3 Merging utility
The merging utility should be able to merge multiple input data files to one output file.
Merging should be performed by summing consequtive samples in input files. Input files
do not need to be equal in lengths, but all input files should have an equal oversampling
factor. The length of the output file should be equal to the length of the longest input file.
3.4 Receiver simulator
The receiver simulator should be able to simulate the following procedures:
• Primary Synchronization Code search
• Correlation Measurement for Secondary Synchronization Codes
• Impulse Response Measurement for the Primary Common Pilot Channel
• Complete Initial Synchronization Procedure according to 3GPP [7]
CHAPTER 3. REQUIREMENTS FOR THE SYSTEM 21
The receiver simulator should support all oversampling factors supported by the data
generator. It should have the ability to simulate bit-limited mathematics or, alternatively
to use non-bit-limited floating point mathematics.
Chapter 4
Implementation description
This chapter explains how the test data generation system has been designed and im-
plemented. Structure figures are presented in this chapter, but all flowcharts are in Ap-
pendix A.
Each major component of the system is described in its own section. The components
use some common function libraries, such as functions for user interfacing and file I/O.
These common functions are described in their own section.
4.1 Data Generator
The data generator was designed to be modular (see Figure 4.1) in order to make the
sub-modules are as independent from each other as possible. Thus it is possible to take
some sub-module of the data generator and re-use it in another application, for example,
in DSP. If needed, it is possible to re-design some sub-modules or add new sub-modules
if some new functionality is wanted. The modules of the data generator are presented in
Figure 4.1.
The highest level flowchart is given Figure A.1. The highest level, “shell level”, con-
sists mainly of the user interface and the file I/O. The main functional level Figure is
presented in Figure A.2. The generation of test data for one cell is shown in Figure A.3.
The test data generation for one frame is presented in Figure A.4.
The highest level signal flow is presented in Figure 4.2. The signal flow for test data
generation for one cell is shown in Figure 4.3. In a real base station, the signal flow for
data generation is exactly the same as in this test data generator.
The “core” of the data generator consists of three nested loops running in pace of
frames, slots and symbols. Two outermost loops are used to keep account of frames and
slots. The innermost loop, running ten times per slot (i.e. in CPICH symbol pace), is used
CHAPTER 4. IMPLEMENTATION DESCRIPTION 23
to generate data samples for physical channels. See Figure A.4 for a flowchart describing
the operation of the two innermost loops.
4.1.1 Generation of primary synchronization code sequence
The primary synchronization code sequence is defined in chapter 2.3.3 as a product be-
tween two series. In this application, primary synchronization code generation is very
straightforward: every member in the first series (in Equation 2.3) is stepped through
and multiplied by all the members of the second series (in Equation 2.4). Thus, for every
member of the first series, 16 bits will be created, and as a result there will be 16·16 = 256
bits.
Because the primary synchronization code is always the same, it is created once in
application initialization and stored into memory. The difference between the real device
and this application is that in the real device, the primary synchronization code would be
pre-generated (i.e. it is generated already in the design phase and stored into the system
as a constant). This choice was made only because of instructional reasons.
G e n e r a t i o n o fH a d a m a r d m a t r i x
r o w
G e n e r a t . o f p r i m .s y n c h r o n i z a t i o nc o d e s e q u e n c e
G e n e r a t i o n o f s e c .s y n c h r o n i z a t i o nc o d e s e q u e n c e s
G e n e r a t i o n o fs c r a m b l i n g c o d e s
G e n e r a t i o n o fc h a n n e l i z a t i o n
c o d e s e q u e n c e s
D a t a g e n e r a t i o n f o r o n e B S
F r a m e o f f s e ta d j u s t i o n
M e r g e g e n e r a t e d B S ' s
O v e r s a m p l i n ga n d p u l s e - s h a p e
f i l t e r i n g
W r i t e r e s u l t st o o u t p u t f i l e
D a t a p o s t - p r o c e s s i n g
C o n f i g u r a t i o n f i l ep r o c e s s i n g
D a t a g e n e r a t o r s h e l l
C o m m a n d l i n ep r o c e s s i n g
D a t a g e n e r a t i o n
M e r g i n g o fg e n e r a t e d d a t a
U t i l i t i e s f o ru s e r i n t e r f a c e
F i l ei n p u t / o u t p u t
C o m m o n m o d u l e s
Figure 4.1: Modules inside data generator
CHAPTER 4. IMPLEMENTATION DESCRIPTION 24
G e n e r a t i n g t e s td a t a f o r B S # 1
+ P u l s e - s h a p ef i l t e r i n g
O v e r s a m p l i n gW r i t e r e s u l tt o o u t p u t f i l e
G e n e r a t i n g t e s td a t a f o r B S # 2
G e n e r a t i n g t e s td a t a f o r B S # 3
G e n e r a t i n g t e s td a t a f o r B S # n
Figure 4.2: Main level signal flow figure for the data generator
4.1.2 Generation of secondary synchronization code sequences
Secondary synchronization code sequences are defined in chapter 2.3.4: first, a product
between two series is calculated and for that result, a memberwise product between it
and the selected Hadamard matrix row is calculated. This operation is rather similar as in
the case of the primary synchronization codee. Both series are defined in Equation 2.5.
The memberwise product calculation is defined in Equation 2.6. Hadamard sequences are
generated using the method explained in chapter 4.1.5.
Analogically to the primary synchronization codes, the secondary synchronization
codes are always the same. In this application, they are created once in application initial-
ization and then stored into memory. In the real device, secondary synchronization codes
would instead be stored as a table of constants This application performs the generation
of secondary synchronization code “by the long way” only for instructional reasons.
4.1.3 Generation of channelization code sequences
As described in chapter 2.3.1, channelization codes are Walsh codes from the OVSF (Or-
thogonal Variable Spreading Factor) code tree. Between Walsh codes of a specific length
and and Hadamard matrixes, there is a relationship [10]: the row number in Hadamard
matrix corresponds to the Walsh function number in a bit-reversed natural order. Thus,
channelization codes are generated using the same method as in generating Hadamard
matrixes. See chapter 4.1.5 for more information about the implementation issues.
CH
APT
ER
4.IMPL
EM
EN
TAT
ION
DE
SCR
IPTIO
N25
G e n e r . o f p r i m .s y n c h r o n i z a t i o nc o d e s e q u e n c e
G e n e r a t i o n o fc h a n n e l i z a t i o n
c o d e s e q u e n c e s
G e n e r a t i o n o fH a d a m a r d m a t r i x
r o w
G e n e r a t i o n o fs c r a m b l i n g c o d e s
G a i n f o r P - S C H
A t t a c h m e n t o fS - S C H t o f i r s ts y m b o l o f s l o t
G a i n f o r S - S C H
A t t a c h m e n t o fP - S C H t o f i r s ts y m b o l o f s l o t
G e n e r a t i o n o f s e c .s y n c h r o n i z a t i o nc o d e s e q u e n c e s
G e n e r a t i o n o fC P I C H s y m b o l s
f o r P - C P I C H
G a i n f . 1 s t S - C P I C H
G a i n f o r P - C P I C H
+ D a t a f o r t h i sB S i s r e a d y
G a i n f o r B S
G e n e r a t i o n o fC P I C H s y m b o l s
f o r n t h S - C P I C H
G e n e r a t i o n o fC P I C H s y m b o l s
f o r 2 n d S - C P I C H
G e n e r a t i o n o fC P I C H s y m b o l s
f o r 1 s t S - C P I C H
G a i n f . 2 n d S - C P I C H
G a i n f . n t h S - C P I C H
Figure 4.3: Generating test data for one base station
CHAPTER 4. IMPLEMENTATION DESCRIPTION 26
Because this application supports a limited amount of simultaneously generated chan-
nels (i.e. synchronization channels and maximum 16 common pilot channels), it is prac-
tical to generate and store the channelization codes before starting actual data generation.
The length of one channelization code for a common pilot channel is 256 bits, and in this
application it is stored into an array whose length is 256 bytes. Memories for arrays are
reserved dynamically according to the number of the generated common pilot channels,
so the total memory consumption is up to 4 kilobytes. This large memory consumption
is justified because storing channelization codes this way facilitates following them for
instructional purpose. In the real device, channelization codes would be stored bitwise
into the memory because the channelization code consists of just ones and zeroes. This
decreases memory consumption heavily.
4.1.4 Generation of scrambling code sequences
Scrambling codes are needed in the generation of common pilot channels. Every common
pilot channel may have its own scrambling code. As the maximum amount of common
pilot channels is 16, as many as 16 different scrambling codes may need to be generated.
In this system, scrambling code sequences are generated using a shift register, as de-
scribed in chapter 2.3.2. The schematic description of the shift register structure is shown
in Figure 2.3. This structure can be used to generate both the primary and secondary
scrambling codes. In software, the shift register is implemented with four arrays of 18
integers. Two of the arrays are needed for the actual shift register and another two are
needed to memorize the start condition in case of a wrap-up. Such an implementation is
not the most cycle or memory usage optimized, but it is good for instructional purposes,
as it is easy to follow. If this ANSI-C implementation of the scrambling code genera-
tor would be compiled for, for example, Texas Instruments C54X, the calculation of one
scrambling code bit would consume roughly 80 cycles.
As the values in shift registers are just ones and zeroes, the scrambling code generator
could be implemented using only four 32-bit wide variables for shift registers and four
32-bit variables for feedback and result bit calculations. In the real device, this would be
a very feasible solution because contemporary digital signal processors have assembler
commands suitable for calculating the next scrambling code bit in just a few cycles.
The wrap-around period of downlink scrambling codes is one frame (i.e. 38400 chips);
hence, it is not practical to generate the whole scrambling code sequence at once. In real
devices, the scrambling code would be generated on-the-fly (i.e. it is not stored anywhere
before using). There would also be many independent, parallel scrambling code gener-
ators. In this application, scrambling code sequences are generated in segments whose
CHAPTER 4. IMPLEMENTATION DESCRIPTION 27
length is 256 chips (one CPICH symbol). There is only one scrambling code generator
and it is designed to be re-entrant; thus, the same generator can be used to generate all the
needed scrambling codes.
The scramling code generator needs to remember its internal state between the call
moments. Because of the re-entrancy requirement, the caller of the module has to take
care of allocating memory for shift register arrays and point this memory area for the
scrambling code generator. As the number of generated common pilot channels may
change dynamically, also memory areas for shift registers are reserved dynamically.
If the data generator is later expanded to create other physical channels, the existing
scrambling code generators can be used for new channels also.
4.1.5 Generation of Hadamard matrix row
A Hadamard matrix can be generated in many ways. If there are no memory restraints,
the easiest and most straigthforward way is to generate the matrix of desired size using
the recursive copy operation explained in Equation 2.5. However, in typical applications,
it is not feasible to use 64 kilobytes of memory for storing the entire H8-matrix. In this
application, only those rows of the Hadamard matrix that are needed are generated.
Let say the bits in the Hadamard matrix are represented so that 1 is replaced by 0 and
−1 by 1. Using this arrangement, between the Hadamard matrixes and Walsh functions,
the following relationship will exist [10] (H3 given as an example):
H3 =
0 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1
0 1 1 0 0 1 1 0
0 0 0 0 1 1 1 1
0 1 0 1 1 0 1 0
0 0 1 1 1 1 0 0
0 1 1 0 1 0 0 1
=
WAL3(0)
WAL3(4)
WAL3(2)
WAL3(6)
WAL3(1)
WAL3(5)
WAL3(3)
WAL3(7)
(4.1)
i.e. the row number in the Hadamard matrix corresponds to the Walsh function number
in a bit-reversed natural order.
Walsh functions are defined as:
WALp(t)i =
p∑
k=1
(tkik) (4.2)
CHAPTER 4. IMPLEMENTATION DESCRIPTION 28
However, in software implementation, rather than using direct calculation (as defined
above), it is more straightforward to create Walsh functions by using the Boolean synthe-
sis [12] as follows:
Let the required Walsh function number be t and the individual bit number be i. Both
of them can be expressed in binary numbers as
i = 〈i1, i2, . . . ip−1, ip〉
t = 〈tp, tp−1, . . . t2, t1〉
Note that the bits were ordered in an opposite way in i and p. An individual bit i in
the Walsh function t of order p can be expressed as
WALp(t)i =
p∑
k=1
(tk ⊕ tk+1)ik (4.3)
where ⊕ marks for the binary Boolean exclusive-OR operation and multiplication for
the binary Boolean AND operation. The whole function is calculated by calculating all
individual bits and ordering them into a sequence.
In this application, the method explained above is used to generate the desired row
from a Hadamard matrix whose size is not pre-set. For primary and secondary synchro-
nization codes and for common pilot channel specific channelization codes, some rows
are needed from the H8-matrix. However, for future expansion, the same function may
be used to generate rows for matrixes of other sizes also — those are needed to generate
channelization codes for channels with the spreading factor SF 6= 256.
4.1.6 Creating one slotful of physical channel data
As described above, the duration of the innermost loop in data generation is one slot and
it runs in the CPICH symbol pace. In each round of the loop, one symbolful of data is
created. The innermost loop operation is described in the flowchart in Figure A.4.
The PSC sequence is attached in the first symbol of slot, if P-SCH is active for the
current base station. Similarly, SSC sequences are attached in the first symbol of slot, if
S-SCH is active. Both PSC and SSC sequences are generated before starting the data gen-
eration, and thus code sequence attaching is just a simple copying-and-scaling operation.
If any of the common pilot channels are active, a 256-chip long piece of the scrambling
code needs to be generated for each symbol. If the primary CPICH is active, the primary
scrambling code needs to be generated and if any of the secondary CPICHs is active, the
secondary scrambing codes may need to be generated depending on the selected scram-
bling code numbers. Because there might be a maximum of 15 secondary CPICHs and
CHAPTER 4. IMPLEMENTATION DESCRIPTION 29
one primary CPICH, there may be situation that for every symbol, 16 different scrambling
codes are generated.
When the scrambling codes needed for common pilot channels have been generated,
they are first chipwise multiplied by the channelization code sequences. After this, the
resulting sequences are multiplied by preprogrammed CPICH symbols and by channel-
specific gain factors. The multiplication results are added to the current symbol.
After all the common pilot channels have been added, the current symbol is ready and
the next round of the innermost loop may proceed.
4.1.7 Mixing samples from multiple base stations
Let us assume that the say data generator is configured to generate n frames of test data.
Every base station may have an independent frame timing: in final output, the data for one
base station starts from chip k1, and for some another base station, the data starts from
chip k2 where both k1, k2 are in the range 0, 1, 2, . . . 38399. For reasons of simplicity,
n + 1 frames of data will be generated for every base station and the frame timings (i.e.
from which chip the data starts) are adjusted afterwards.
Let the timing offset for a base station be toffs. When all data (i.e. n + 1 frames) for
that base station has been generated, the first step is to discard k = 38400 − toffs chips
from the beginning of data. After the excess data is discarded, chips worth of n frames
are copied to a result file. The rest of data is discarded.
If data needs to be generated for multiple base stations, the results have to be merged
by using temporary files using the following procedure: The data for the first base station
is generated and frame timing adjusting is performed. The result will be saved to a tem-
porary file A. For the second base station, data is generated and frame timing adjusted.
Results are merged with the contents of the temporary file A and saved to a temporary
file B. For the next base station, the results are merged with the temporary file B and
saved to the temporary file A. For the rest of base stations, the procedure is analogous. A
flowchart describing the entire mixing operation is shown in Figure A.5.
4.1.8 Chip oversampling and pulse-shaping
At this stage, all channels for the required base stations have been generated and samples
have been summed as a chip stream. Before applying the chip stream to the QPSK mod-
ulator, the stream has to be oversampled and pulse-shape filtered, as described in chapter
2.3.6. A flowchart for the entire operation is given in Figure A.6.
Oversampling is performed as shown in Figure 4.4: if oversampling factor Fos = n,
CHAPTER 4. IMPLEMENTATION DESCRIPTION 30
every nth sample of the oversampled chip stream equals to the input chip. All other
samples in the oversampled stream equal to zero. Thus the oversampled chip stream can
be described as a stream of impulses with an amplitude equal to the incoming chip stream.
The oversampled chip stream is then used as a stimulus to the pulse-shape filter.
As described in chapter 2.3.6, the impulse response of the pulse-shape filter is a sinc
pulse (see Figure 2.6). Thus the pulse-shape filter converts a series of impulses to a series
of sinc pulses. The results are stored into an output file.
The pulse-shape filter is implemented as a delay line. The length of the delay line is
dynamic and depends of both the pulse-shape filter length in chips and the oversampling
factor, which both are user configurable. Coefficients for delay line are calculated before
the actual filtering starts, using the formula for pulse-shape filter’s impulse response (see
Equation 2.7). Because that formula has a discontinuity in zero, the coefficient value for
delay zero is extrapolated to 1.060113 .
t / c h i p s1 2 3 4 5 6 7 8 9 1 0 1 1 1 20
1
- 1
b )
c )
t / c h i p s1 2 3 4 5 6 7 8 9 1 0 1 1 1 20
1
- 1
a )t / c h i p s1 2 3 4 5 6 7 8 9 1 0 1 1 1 20
1
- 1
Figure 4.4: Example of chip sequence oversampling: a) is the original chip sequence,
b) has been oversampled using oversampling factor 1, c) has been oversampled using
oversampling factor 4.
CHAPTER 4. IMPLEMENTATION DESCRIPTION 31
4.2 Channel profile
As the focus of this thesis is the physical channel baseband test data generator, it was
decided that the channel model in the channel profile utility would be extremely simple:
it supports only the stationary multipath fading AWGN channel. Moving multipaths,
multipath birth or death, Doppler effects, or simulation of UE or BS internal oscillator
drift are not supported. However, the channel model supports simulation of TX diversity
effects which means there that are two independent delay lines, one for each TX antenna.
See Figure 4.5 for top-level view of channel profile implementation. The flowchart of
channel profile operation is given in Figure A.7.
The delay profile for the channel is created by defining the delay, attenuation and phase
coefficients for each delay profile tap. The number of multipath taps is unlimited, but the
maximum delay is 66.67µs (i.e. the duration of one symbol in common pilot channels).
This limitation was set because, in practice, delays of significant multipaths in the 2 GHz
area are much less than that. [14]
. . .
e f f 0 e f f 1 e f f 2. . . e f f n
+
T X 1 i n p u t
d e l a y l i n e c o - e f f i c i e n t c a l c u l a t i o n
. . .T X 2 i n p u t
e f f 0 e f f 1 e f f 2. . . e f f n
d e l a y l i n e c o - e f f i c i e n t c a l c u l a t i o n
A W G N
o u t p u t
x t x t + 1 x t + 2 x t + n
x t x t + 1 x t + 2 x t + n
Figure 4.5: Channel model
CHAPTER 4. IMPLEMENTATION DESCRIPTION 32
Delay line length in the channel profile is set dynamically according to the longest
multipath tap delay used. The maximum length is 256 chips (i.e. one symbol in common
pilot channels). Delay line length depends also on the used oversampling factor Fos =
1, 2, 4, . . . 16 which means that the actual delay line length equals to the maximum delay
multiplied by the oversampling factor used.
Delay line coefficients are complex (i.e. each coefficient consists of an attenuation part
and a phase part). In addition, delay units in the delay line are complex and, therefore, I
is stored to the real and Q to the imaginary part of delay unit.
In the channel profile, there is an Additive White Gaussian Noise (AWGN) generator.
AWGN is added to the channel-profiled data and its level may be adjusted freely within
the range −64.0 . . . 20.0 dB, where −64.0 dB expresses that no AWGN is added.
Channel profiles for TX antennas are independent for delay profile part. TheAWGN
level is common for both TX antennas. Both TX antennas may have independent delay
settings (i.e. the number of delay profile taps and their contents may be different). If TX
diversity is used, the delay profiles for TX antennas should be (at least slightly) different.
Channel profile settings are stored in the configuration file. As the name of the con-
figuration file can be defined from the command line, the user may have many channel
profiles defined and one of them can be selected into use. For more information about
using the command line commands or the configuration file, please see chapter 5.4.
4.2.1 Channel profile delay line operation
Before actual channel profiling can be started, coefficients for the delay line must be
initialized. As described above, resolution of the delay line is dynamic and depends on
the oversampling factor Fos. Channel profile definition is read from the configuration
file and delays, specified in nanoseconds, are converted to delay line tap positions. The
corresponding attenuation and phase coefficients are also stored. Contents of delay units
in the delay line are zeroed.
In actual channel profiling, contents of the delay line are complex-multiplied by the
corresponding coefficients and results of all complex products are summed. White Gaus-
sian Noise is added to this result.
After multiplication, all contents of the delay line are shifted to right by one position
(as in Figure 4.5) (i.e. xt = xt+1 where t = 0, 1, 2, . . . (256 · Fos − 2)). New I and Q
samples are read from source files and stored into the first position (i.e. x0) of delay line.
CHAPTER 4. IMPLEMENTATION DESCRIPTION 33
4.2.2 Generation of Additive White Gaussian Noise
Additive White Gaussian Noise (AWGN) is generated by adding scaled samples from a
Gaussian-distributed random number generator to the channel data. The process is quite
straightforward but has two particular pitfalls:
1. Generation of Gaussian-distributed random numbers. If the distribution of gen-
erated random numbers is not pure Gaussian, or the randomness of the random
number sequence is not good enough, simulation results may be biased. This can
be avoided by using a well-proven random-number generation technique.
2. Setting of the noise power level. The channel data includes independent I and Q
samples. Thus, also noise will need two independent samples. When calculating
manually the scaling factors for independent noise samples, quite often — by ac-
cident — the resulting noise power is 3 dB too high. This can be avoided just by
being careful and by double-checking the results.
In this application, the Box-Muller method [11] is used to generated Gaussian-
distributed random numbers. In this method, a pair of independent, uniformly dis-
tributed random variables is mapped to a pair of Gaussian random variables. The Box-
Muller method is just a way to process uniformly distributed random variables to become
Gaussian-distributed, thus, a well-behaving uniformly distributed random-number gener-
ator is still needed. Because this channel model is rather simple, not much effort was put
in generating random numbers, and, a plain rand() system call from stdlib.h was
used. If more accuracy is needed, it is very easy to replace the call to rand() with a call
to any other random-number generator.
The noise power level PN is set in decibels. In calculating scaling factors for individ-
ual I and Q noise samples, there are four steps:
1. Because there are two independent noise samples, their power level is 3 dB less
than the total noise power.
2. Convert noise power level for I ,Q noise samples to linear.
3. Because noise sample scaling is performed in the amplitude domain, power must
be changed to amplitude by calculating a square root.
4. Use the calculated value as a standard deviation in the Box-Muller method.
CHAPTER 4. IMPLEMENTATION DESCRIPTION 34
Thus, the whole calculation for calculating the standard deviation s to the Box-Muller
method from the desired power level PN is:
s =
√
10
PN − 3 [dB]10 (4.4)
4.3 Merging utility
If multiple base stations are simulated by running the data generator and the channel
profiler many times, the result files need to be merged to one file before using them in the
receiver simulator or an external application. The merging utility offers this functionality:
it very straightforwardly reads all the input data files, sums the consequtive input samples
together and writes the result to the output file. Input files do not need to have equal
lengths — the output file will be as long as is the longest input file.
A flowchart for merging utility is given in Figure A.8.
For information about the merging utility command line usage, please see chapter 5.5.
4.4 Receiver Simulator
Because the focus of this thesis is the physical channel baseband test data generator, it
was decided that the receiver simulator could be very simple: its main purpose is to verify
that the test data generator works as intended. If better receiver simulation capabilities
(e.g. a more accurate simulation model, more functionalities) are required, simulation can
be performed in an external application, for example, in Matlab.
A top level, “shell level”, flowchart for the receiver simulator is presented in Figure
A.9. The top level consists mainly of control parts (procedure selection and user interfac-
ing), thus forming a shell around the receiver simulator’s functional blocks, which have
been designed to be as modular as possible. The top level signal flow is presented in Fig-
ure 4.6. It is possible to add new functionalities to the receiver simulator by adding new
functional blocks to it or by enhancing the existing ones.
Bit-limited mathematics is simulated by using pre- and post-scalers consisting of pro-
grammable scalers and bit limiters. In internal calculations, functional blocks use floating-
point mathematics. This should not cause much problems because in also practical de-
vices, internal calculations are performed using ahigher number of bits than in input or
output.
CH
APT
ER
4.IMPL
EM
EN
TAT
ION
DE
SCR
IPTIO
N35
P S C s e a r c h
I R M f o r C P I C H
S C R C c o r r e l a t i o n
P r e - s c a l e r
A G C
B i t - a c c u r a t e m a t h e m a t i c s s i m u l a t i o n o n / o f f
P r o c e d u r e s e l e c t i o n
S a m p l e s f r o mi n p u t d a t a f i l e
b i t l i m i ts c a l i n g
P o s t - s c a l e r
b i t l i m i ts c a l i n g
R e s u l t s t oo u t p u t f i l e
S S C c o r r e l a t i o n
Figure 4.6: Top level signal flowchart of receiver simulator
CHAPTER 4. IMPLEMENTATION DESCRIPTION 36
Because of top level limitations, only one functional block (i.e. one procedure) may
be used at one run. Exception to this rule is the initial synchronization procedure which
utilizes many blocks in one run. Top level and functional blocks are explained in the
following sub-chapters.
The results from procedures are written to output files. The formats for result files are
explained in chapter 5.8.
4.4.1 Input data processing
In real devices, the received radio frequency signal is first QPSK demodulated. In the
next steps, the input signal is amplified, filtered (baseband filtering), and the DC offset
is removed. Finally, the analog input signal is converted to digital. A/D converters have
a very limited dynamic range, and therefore the dynamics of the input signal has to be
matched to the range of the A/D converter as carefully as possible. If the input signal
level is observed over a long period, usually it is noticed that it is not stable and thus, no
fixed amplification setting cannot be determined. Variable amplification is used and it is
controlled by an automatic gain control (AGC) unit.
The chip rate in the 3GPP WCDMA system is 3.84 million chips per second. Accord-
ing to the Nyquist criteria, the lowest possible sampling rate is twice the chip rate (i.e.
7.68 MHz). Usually the sampling rate is higher, for example, four times the chip rate.
After the analog-to-digital convertersion, the input signal is represented with a fixed
number of bits (e.g. 10 bits). Of course, a higher number of bits give better accuracy, but
the more resolution an A/D converter has, the more it costs. Also in practical system’s
internal calculations, some predefined bit quantities are used. Thus it is not reasonable to
use more accuracy in the A/D converter than the internal calculations require.
In the receiver simulator, there is no baseband filtering. Analog-to-digital conver-
sion is simulated by artificially limiting the input data resolution. A/D converter’s maxi-
mum usable amplitude value Amax and the used operation range RADC = 0 . . . 1 (i.e. if
RADC = 0.95, five percent of operation range is left unused as a safety margin) are set by
the user.
Automatic Gain Control (AGC) is implemented by using the following procedure:
Sliding average amplitude Aavg for input signal is calculated over the time period tavg.
Time period length can be adjusted (within one CPICH symbol duration). Averaging is
performed by using a one-tap infinite impulse response (IIR) filter as follows:
Aavg(n) =tavg − 1[chip]
tavg
Aavg(n − 1) +1
tavg
A(n) (4.5)
CHAPTER 4. IMPLEMENTATION DESCRIPTION 37
where A(n) is the amplitude of nth imput sample. Input samples are then scaled with
the gain factor GAGC , which is calculated by following formula:
GAGC =Amax · RADC
Aavg
(4.6)
When reception is started, AGC is initialized by storing the A(n) (i.e. amplitude of the
first received sample) to the sliding average, A(n− 1). This causes some noise in the first
moments of reception until the sliding average value stabilizes according to the received
data and until the GAGC factor settles down. However, this does not affect simulation
results very much, because the simulation period tsim is usually much longer than tavg.
If source data contained long “silent” periods (i.e. zero data), GAGC would adjust to
a very high value. When the “silence” ends and non-zero data is received, data would be
scaled with an unreasonably high GAGC and the signal would most likely be distorted.
To avoid this, an automatic AGC initialization feature is implemented. If automatic AGC
initialization is enabled, it will compare the amplitude of the current sample to the sliding
average and if the current amplitude is K times higher than the sliding average, AGC will
be initialized as described above. Value K may be tuned by the user.
Bit-limited arithmetics can be simulated by a pre-scaler, which first scales input sam-
ples by a user-set pre-scaling factor and then limits their dynamics by converting the
scaled samples to Q numbers and back to floating point numbers. In the Q conversion,
decimal and integer parts are extracted from a floating point number. Both the integer and
decimal parts are saturated to the user defined bit quantity. Finally, the Q number is con-
verted back to a floating-point number. If bit-limited arithmetics is not to be simulated,
the pre-scaler may be by-passed.
4.4.2 Matched filter
The basic principle of the matched filter is to correlate the input signal with a known
reference sequence. It is assumed that the reader has some knowledge about the matched
filter, so the basics are not explained. For a WCDMA application, the principle of matched
filter is described in Figure 4.7.
The length of the known reference sequence varies according to the usage of the
matched filter. In the Primary Synchronization Code (PSC) search or scrambling code
group detection (i.e. SSC, Secondary Synchronization Code search), it is always 256 chips
long. In impulse response measurement for common pilot channels (CPICH IRM), the
reference sequence length is equal to the measurement window length, which then is de-
termined by performance requirements [1]. In this work, the window length is selected to
CHAPTER 4. IMPLEMENTATION DESCRIPTION 38
be 256 chips (i.e. the duration of one CPICH symbol).
Depending on the usage of the matched filter, the reference sequence may be either
constant (in PSC or SSC search) or the sequence may be updated after each measurement
window (in CPICH IRM).
In real applications, there are several matched filters for different uses. Matched filters
are usually implemented using the ASIC technology and, thus, several matched filters
may run in parallel. Besides, matched filters for different purposes may require different
implementation due to their different requirements. Such application-specific matched
filters are discussed more in the following chapters.
4.4.3 PSC search
Primary Synchronization Code (PSC) search is performed to detect the slot structure tim-
ing of the base station. The PSC is transmitted in the Primary Synchronization Channel.
For more information about the Primary Synchronization Channel, please see chapter
2.5.1 and for timing issues, please see chapter 5.2.
The length of PSC is 256 chips (one CPICH symbol) and it is transmitted once per
slot, so the length of the measurement window needs to be equal to the length of one slot
(i.e. 2560 chips). Because the PSC sequence is constant, it may be “hard-wired” to the
matched filter.
In this application, for PSC search the length of the matched filter delay line is fixed
to 256 · k (where k equals to the oversampling factor) samples. Results are stored into a
buffer whose length is 2560 · k. Correlation between the delay line and the PSC sequence
is calculated using a common correlation calculation utility which is shared between the
PSC search, the SSC search (see next chapter) and the scrambling code identification
. . .
e f f 0 e f f 1 e f f 2. . . e f f n
+
i n p u t c h i ps t r e a m
k n o w n s e q u e n c e
c o r r e l a t i o n r e s u l t
x t x t + 1 x t + 2 x t + n
Figure 4.7: Principle of matched filter
CHAPTER 4. IMPLEMENTATION DESCRIPTION 39
(performed in the initial synchronization procedure).
PSC search is performed as follows: First, the delay line is filled with input data
and the result buffer is cleared. Correlation between the delay line and the reference
sequence (PSC) is calculated and the correlation result in power domain is stored to the
first position in the result buffer. Contents of the delay line are shifted to the right (as
expressed in Figure 4.7) and a new input data sample is fetched to the leftmost position
of the delay line. The correlation result (in power domain) of the next correlation round
is stored into the second result buffer position, and so on. This cycle is performed as
many times as is the measurement window length (i.e. duration of one slot). On cycles in
the second measurement window (and also later ones), the results are added to the result
buffer, starting from the first position.
Measurements expressed above are performed for as many measurement windows as
the user has specified. After all the measurements have been completed, the result buffer
is searched for high correlation values, or peaks. If any considerable peaks (i.e. the peak’s
height is considerably over the noise level) are found, those express that base stations are
“available”. The result buffer positions for the peaks found are used as slot timing for the
SSC search procedure.
In this application, the PSC search procedure produces only the result file in power
domain so it does not search for any peaks. If the contents of the result file are plotted to
a graph, it can be easily seen if there are any considerable peaks and what are their slot
timings. An example is given in Figure 6.1, page 66.
4.4.4 SSC search i.e. Scrambling code group detection
Second Synchronization Code (SSC) search is performed for two reasons: first, to detect
the scrambling code group used and second, to detect base station’s frame timing. SSC is
transmitted in the Secondary Synchronization Channel. Please see chapter 2.5.2 for more
information about it.
SSC is transmitted in the first symbol of the slot. There are 16 different Secondary
Synchronization Codes and their sequence expresses both the frame timing and the scram-
bling code group used. To detect the SSC sequence, the correlation between the input data
and all 16 SSCs has to be measured.
In the real device, the correlation measurements for every SSC has to be done during
one slot. The duration of the SSC burst is 1/10 of the slot, a new burst is transmitted at
every slot and for each burst, 16 measurements have to be performed, so at least some
parallelism has to be introduced. However, because this application does not work in real
time, the correlation measurements do not need to be performed in parallel. Instead, the
CHAPTER 4. IMPLEMENTATION DESCRIPTION 40
input data is buffered and correlation measurements are done in sequence.
The length of the SSC sequence is one frame (i.e. 15 slots). Thus the minimum mea-
surement time is one frame, but it may be required to average correlation results from
several frames. In this application the user may select how many frames are measured.
After all the measurements have been performed, scrambling code group and frame
timing are acquired by comparing the maximum correlation results of each SSC to the
SSC sequence allocation table (see table B.1 in Appendix B). However, this application
does not perform these steps in the SSC procedure. Those steps are performed only in the
initial synchronization procedure. An example of the SSC search results is plotted to a
graph in Figure 6.3, page 68.
The correlation results are written to a file. The result file consists of correlation
powers for every SSC per each slot, i.e. there are 15 lines and 16 floating-point numbers
per line. For more information about the result file, please see chapter 5.8.2.
4.4.5 Impulse response measurement for CPICH
Impulse response measurement (IRM) for the Common Pilot Channel is performed to
obtain information about the channel multipath properties used. CPICH is transmitted
continuously and its scrambling code is deduced in the initial synchronization procedure.
Please see chapter 2.5.3 for more information about CPICH.
Most real WCDMA devices use a rake [17] receiver architecture. Before starting
reception, the channel multipath profile needs to be extracted from the Common Pilot
Channel by performing an IRM by using the matched filter. Rake fingers are assigned to
the most important multipaths. The data received from each multipath is equalized (using
again CPICH as a reference) and summed. For having an optimal rake finger allocation,
IRMs have to be performed every now and then.
As described earlier, in this work the measurement window length was selected to be
256 chips (i.e. one CPICH symbol). The delay line length is then 256 · k (where k is
the oversampling factor). Because both power and phase domain results are required, the
correlation is calculated with a built-in calculation unit instead of using the common unit.
The result is stored into a result buffer of the same length than the measurement window.
The impulse response measurement procedure is similar to the PSC search procedure
(described in chapter 4.4.3 on page 39) with two major differences: First, a known locally
generated scrambling code is used as a reference sequence. Because the scrambling code
sequence is not constant, a new sequence has to be generated for each measurement win-
dow. The second difference is that correlation results are obtained in the complex domain
and the results are averaged over measurement windows in a coherent fashion (i.e. results
CHAPTER 4. IMPLEMENTATION DESCRIPTION 41
are kept in the complex domain). After all the correlation calculations have been com-
pleted, the results are written to two files, one consisting of the power domain and another
of the phase domain results.
If the results of the IRM procedure are plotted to a graph, the channel multipath prop-
erties can be easily seen from the power domain graph. The phase domain graph is not
that informative, because correlation peaks cannot be distinguished from noise if the exact
locations of peaks are not first read from the power domain graph. Example graphs are
given in figures 6.4 and 6.5 in chapter 6.3.
4.4.6 Initial synchronization procedure
The purpose of the initial synchronization procedure is to detect both the scrambling code
number and the exact timing of the base station. This procedure is defined by 3GPP [7]
and it consists of multiple subprocedures. Please see Figure A.10 for a flowchart.
In this application, the initial synchronization procedure is performed by calling sub-
procedures, described in previous chapters, and by analyzing their results in the very
straightforward and simple manner. The cycle consumption of the procedure is not opti-
mized in any way, neither is the performance. The procedure works best with simple chan-
nel models — if the channel model is configured to have many multipaths with closely
the same power levels, it is very likely that the initial synchronization procedure fails to
identify the used scrambling code.
If started from the top of the initial synchronization procedure flowchart, the first step
is labeled as the “PSC search”. It also includes base station slot timing detection. After
this step it has to be determined whether PSC search was successful or not. In current
implementation, PSC search has no threshold level so if the input data files have enough
data, the PSC search will always be successful. Due to a lack of thresholding, if the
channel has much noise and only weak multipaths, the PSC search may identify some
strong noise peak as a base station.
After a successful PSC search, the next step is labeled as “Scrambling code group
identification”. Also frame timing is identified. This step is performed simply by search-
ing for the maximum correlation result between the input data and all the 16 secondary
synchronization codes in all 15 slots during measurement window length (one frame).
When the maximum correlation results are found, the result is a sequence of SSCs which
is then compared to Table B.1 “Allocation of SSCs for secondary SCH” in Appendix B. If
the sequence does not match with any of the rows in the table, the sequence is shifted one
position to “right” and compared again. If after 14 (i.e. slots in frame minus one) shifts
there is still no match, SSC detection fails. If the sequence matched with a row in table,
CHAPTER 4. IMPLEMENTATION DESCRIPTION 42
matching row identifies the scrambling code group and the number of shifts identifies the
used frame timing.
Note that if the multipath profile is unstable, the SSC identification method such as
the one described above is very unreliable. For example, fast fading may cause SSC
correlation results for some slot to be distorted and this leads to either false recognizition
of the scrambling code group or to scrambling code group not being recognized at all.
Real devices utilize, most likely, much more complicated SSC identification methods.
After a successful scrambling code group identification, the next step is scrambling
code identification. In each scrambling code group, there are 8 scrambling code candi-
dates. For identifying the used scrambling code, the correlation between the input data
and the locally generated scrambling code must be measured for each scrambling code
candidate. When all correlations have been calculated, the best correlation Cormax is
searched and compared to the average correlation level Coravg. The certain threshold
level N is used to guarantee that the scrambling code found is the correct one and not
noise: if Cormax ≥ N · Coravg, scrambling code identification was successful. If the
threshold level is set high enough (a good guess is N = 4), this step will trap all false
detections.
The scrambling code candidate correlation measurement has not been explained sepa-
rately in above chapters. It is a very simple operation and it is performed using a common
correlator with the SSC correlation calculation procedure. Unlike other steps of the initial
synchronization procedure, this step can not be run individually.
If all initial synchronization procedure steps were successful, the results are written to
the final result data file. If any of the steps fails, the entire procedure is aborted immedi-
atelly. In any event, the already finished subresults are written to subresult data files.
4.4.7 Result data processing
If bit-limited arithmetics needs to be simulated, the result samples are processed in the
post-scaler which works exactly the same way as the pre-scaler. Please see chapter 4.4.1
for a description of the pre-scaler operation.
4.5 Common function library
Certain procedures need to be implemented the same way in all components of the system,
and thus it is practical to create a common function library. This approach costs some
time in the design phase, but it will save a lot in the testing and debugging phases. These
CHAPTER 4. IMPLEMENTATION DESCRIPTION 43
common procedures are:
• Reading of input data files
• Writing of results to files
• Complex number calculations
• Configuration file processing
• Conversions between radians and degrees
• Conversions between decibel and linear “domains”
• Printing of copyright text
3GPP system definitions (e.g. chip rate and every other 3GPP-defined constant) and
the internal restrictions of the data generation system (e.g. the highest supported oversam-
pling factor) are also defined in the header file of the common function library.
4.6 Source code files
The entire software is written in ANSI-C. Makefiles are written for the GNU make and
therefore they may need some changes if used with any weird compiler (e.g. Microsoft
Visual C++). Compilation has been tested with the GNU make and GCC compiler in Cyg-
win (GNU environment for Microsoft’s “operating systems”) v. 1.3.6, in HP-UX 10.20
and in SunOS 5.7.
Source code files are listed in Appendix F and they are described in the following
table.
File name Description
chan_conf.c Channel model configuration file read utility
chan_conf.h Header file for above
chan_conf_keywords.h Configuration file keywords definitions
chan_mod.c Channel model main file
copying.txt GNU General Public License
gauss_rand.c Gaussian deviated random number generator
gauss_rand.h Header file for above
continues on next page
CHAPTER 4. IMPLEMENTATION DESCRIPTION 44
File name Description
gen_common.h Common function prototypes and common defini-
tions for data generator
gen_conf.c Configuration file read utility
gen_conf.h Header file for above
gen_conf_keywords.h Configuration file keywords definitions
gen_filter_chips.c Chip oversampling and filtering utility
gen_filter_chips.h Header file for above
gen_generate_data.c Actual test data generation
gen_generate_data.h Header file for above
gen_matrix_row.c Hadamard matrix row generator
gen_matrix_row.h Header file for above
gen_psc.c Primary synchronization code generator
gen_psc.h Header file for above
gen_scrc.c Scrambling code generator
gen_scrc.h Header file for above
gen_shell.c Test data generator user’s interface and file I/O
gen_ssc.c Secondary synchronization code generator
gen_ssc.h Header file for above
global.c Common utilities
global.h Global definitions and header files for common utili-
ties
readme.txt Latest notes about software and Software license
merge_main.c Main file for data file merging utility
simu_agc.c Automatic gain control
simu_agc.h Header file for above
simu_common.h Common function prototypes and common defini-
tions for receiver simulator
simu_conf.c Configuration file read utility
simu_conf.h Header file for above
simu_conf_keywords.h Configuration file keywords definitions
simu_isync.c Initial synchronization procedure
simu_isync.h Header file for above
continues on next page
CHAPTER 4. IMPLEMENTATION DESCRIPTION 45
File name Description
simu_main.c Main file for receiver simulator
simu_mf.c Matched filter related procedures
simu_mf.h Header file for above
simu_ssc.c Secondary synchronization channel related proce-
dures
simu_ssc.h Header file for above
typedef.h Definitions of basic types and basic constants
Table 4.1: List of source code files
Chapter 5
User’s Guide to System
This chapter is intended to serve as a user’s guide to the3GPP WCDMA FDD L1 baseband
test data generation system. The main focus point is to explain how the system is used
and hence there are not many theoretical or implementation-specific considerations. For
information about the basics of 3GPP WCMDA FDD L1, please see chapter 2.
This system consists of the following components:
• Data generator (DG) — generates test data containing P-SCH, S-SCH and CPICH
channels. TX diversity is supported. In one run, test data can be generated for
many base stations which have independent channel configurations. The output is
two data files, one for each TX antenna.
• Channel model (CH) — simulates the radio channel between the base station and
the UE. Supports TX diversity, i.e. both TX antennas may have independent channel
profiles. The output is one data file.
• Merger (MG) — merges results from many channel models to one data file.
• Receiver simulator (RX) — examines the generated and channel-modeled data.
Contains matched filters and correlators. Identifies the used scrambling codes and
reveals the channel profile. May be used either in the floating-point or bit-accurate
mode.
Different configurations (see Figure 5.1), or, how the system may be used, are ex-
plained in the following list:
a) Data produced by DG is used in another application (e.g. in Matlab or in DSP)
b) Data produced by DG is first channel-modeled by CH and then used in another
application (e.g. in Matlab or in DSP)
CHAPTER 5. USER’S GUIDE TO SYSTEM 47
D G
M G
R Xa )
D Gb )
D Gc )
D Gd )
D Ge )C H
C H
D G C H
D G C H
C H R X
M GD Gf ) C H
D G C H
D G C H
R X
R Xg ) h ) C H R X
Figure 5.1: Possible ways how to use system
c) Multiple DGs are used to produce data. Their outputs are first channel-modeled
using CHs and then merged to single output using MG.
d) Data produced by DG is examined directly by using RX.
e) Data produced by DG is first channel-modeled by CH and then examined by using
RX.
f) Multiple DGs are used to produce data. Their outputs are first channel-modeled
using CHs and then merged to single output using MG. This result is examined by
using RX.
g) Data produced by another application (e.g. Matlab or DSP) is examined using RX.
h) Data produced by another application (e.g. Matlab or DSP) is first channel-modeled
using CH and then examined using RX.
Modules may be used from Matlab by creating special m-functions. Those functions
are not produced in this work. For example, three different m-functions might be created:
one function consisting of the use cases a–c, second one of the use cases d–f and third one
of the use cases g–h.
All data produced by DG, processed by CP, merged by MG, or examined by RX uses
the same format which is explained in chapter 5.8. This format is supported by Matlab.
CHAPTER 5. USER’S GUIDE TO SYSTEM 48
5.1 Software license
This chapter is a direct quote from the GNU General Public License. Please refer to the
file copying.txt in Appendix F for the complete license. In the license, the word
program refers to the whole data generation system. When this system is distributed,
the license file should always be attached to the distribution, whether the distribution is
internal or external.
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but without any warranty;
without even the implied warranty of merchantability or fitness for a particular purpose.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this
program; if not, write to the Free Software Foundation, Inc. 59 Temple Place, Suite 330,
Boston, MA 02111-1307, USA.
5.2 Timing issues between UE and network
Before going into details of how different components in the system are used, it is manda-
tory to understand how UE keeps track of networks, i.e. base stations’ timings. This
section explains it briefly — for more information, please see for example [4].
To be able to achieve and maintain synchronization to the network, UE needs to have
an internal clock. Of course, the clock’s frequency can be anything but it is practical to
have the clock tick on the same or multiple pace as the frame structure in 3GPP. Thus
we can say that UE’s internal clock has an imaginary frame structure and by reading the
clock’s current time, it is possible to say what is the current frame number, slot number
and chip in slot. This imaginary frame structure is presented in Figure 5.2 as “UE timing”.
Similar internal clocks exist also in the data generator and the receiver simulator.
Let Tslot ≈ 667µs be duration of one slot and Tframe = 10 ms be duration of one
frame. In Figure 5.2, toffs,1 is defined as an offset of frame timing between UE and the
first base station. This means that in the first base station, the frame starts toffs,1 later than
in UE. The definition of toffs,2 is analogous.
Figure 5.3 shows an example of a result from the PSC search procedure. There are
two base stations available and their timings were defined above. Between tn and bsoffs,n
(where n is the base station identifier) the following relation exists:
CHAPTER 5. USER’S GUIDE TO SYSTEM 49
U Et i m i n g
B S # 1t i m i n g
B S # 2t i m i n gt o f f s , 1
t o f f s , 2
F r a m e b o r d e r S l o t b o r d e r
Figure 5.2: Example of timings of two base stations
t i m e
corr
ela
tion
B S # 1
B S # 2
t 1t 2
Figure 5.3: Example of PSC search result with two base stations
tn = bsoffs,n MOD Tslot (5.1)
i.e. slot offset between UE and the base station can be acquired using the PSC search
procedure. To acquire a frame offset, further actions are needed.
In the data generator’s configuration file, every base station has a setting BS_OFFSET
in the chips and that is equivalent to toffs,n defined above. Note that the range is 0 ≤
toffsn< Tframe.
5.3 Data generator
The data generator utility generates test data which can be directly consumed with, for
example, receiver simulator or with any external software or device, such as Matlab or
DSP. The test data can also be channel-profiled before it is consumed. On those channels
which the data generator supports, it works exactly like a WCDMA base station. The data
generator produces I and Q data streams which could be fed to the QPSK modulator (like
in Figure 2.4). Both data streams are oversampled and chip pulse-shape filtered.
The data generator supports the generation of the following physical channels:
CHAPTER 5. USER’S GUIDE TO SYSTEM 50
• Primary Synchronization Channel (P-SCH)
• Secondary Synchronization Channel (S-SCH)
• Primary Common Pilot Channel (P-CPICH)
• Secondary Common Pilot Channel (S-CPICH)
Data generator supports the following transmit diversity methods:
• Time Switched Transmit Diversity (TSTD) for P-SCH and S-SCH
• Space Time block coding based Transmit antenna Diversity (STTD) for P-CPICH
and S-CPICH
In a base station belonging to the WCDMA network, transmit power levels for phys-
ical channels are specified by 3GPP. There will be no situation that a base station would
transmit only, for example, Primary Synchronization Channel. Unlike this, in the data
generator the generation of physical channels can be adjusted very flexibly. Every phys-
ical channel has its own individual gain setting, i.e. it is possible to transmit only those
channels which are necessary for testing.
The data generator supports generation of test data for either one or several base sta-
tions simultaneously. Base stations may have timings that differ from each other, but the
length of test data will be same for all base stations, i.e. if the user has selected the data
generator to generate n frames of test data, it will generate the same quantity of data for
all base stations.
After test data has been generated at the chip level, it is oversampled and pulse-shape
filtered with a 3GPP compliant pulse-shape filter (see chapter 2.3.6). Output values are
written to two separate result files, one for the I and one for the Q branch. In output files,
the decimal number 1 represents the amplitude level of 0 dB.
All data generator settings, i.e. settings for individual channels, individual base sta-
tions and settings for oversampling and chip pulse-shaping, are done into the configuration
file. A sample data generator configuration file is provided in Appendix C. Configuration
directives are explained in the following three subchapters.
It is possible to have many configuration files for many data generation schemes. The
configuration file can be selected from command line, but if no selection is made, the
default configuration file named datagen.cfg will be used.
Configuration directives are case-sensitive and their order should not be changed. The
configuration file should end to the END_OF_FILE directive. If one creates her/his own
configuration file, it is safest to make a copy from the example configuration file and
modify the copy to suit her/his needs.
CHAPTER 5. USER’S GUIDE TO SYSTEM 51
5.3.1 Data generator specific settings
In the following, all data generator specific settings are listed according to the keyword
used:
• BS_NUMBER For how many base stations data is generated.
Valid values are 1, 2, 3, . . . 63 .
• FRAME_NUMBER How many frames test data is generated. Note that the data gen-
erator internally always generates one frame more data than defined in this option.
This behavior is needed for the offset generation. However, the quantity of data in
the result file is exactly same as defined here. Valid values are 1, 2, 3, . . . 65535 .
• OVERSAMPLING Oversampling factor. If value is 1, data is not oversampled at
all. Simulation accuracy depends on oversampling, i.e. the bigger oversampling,
the more accurate simulation. However, a higher oversampling value also means
a longer simulation time. Suggested value for oversampling is 4. Valid values are
1, 2, 3, . . . 16 .
• CHIP_FILTERING Selects whether chip pulse-shape filtering is used or not. Valid
values are ON or OFF.
• CHIP_FILTER_LEN Sets chip filter length in chips. Suggested length for filter is
4 chips. Valid values are 1, 2, 3, . . . 16 .
• VERBOSITY Selects, how many prints the data generator produces to screen while
producing data. If set to zero, only possible error messages are printed. If set to
1, the number of prints remains relatively low. If set to 2, there will be a flood of
prints. Suggested level of verbosity is 1. Valid values are 0, 1 and 2.
5.3.2 Base station specific settings
Let us say n equals to the setting of BS_NUMBER in the data generator specific settings.
If n > 1, data will be generated for many base stations and base station specific settings
have to be defined for each base station independently. In the sample configuration file
provided in Appendix C, there are two base stations. It can be seen that both base stations
have independent values in their settings. If there is need to have more base stations,
settings may be added to the end of the configuration file.
Keywords for base station definitions are as follows:
CHAPTER 5. USER’S GUIDE TO SYSTEM 52
• PRI_CODE Primary Scrambling Code of base station. This is quite often referred
to as the base station ID. This value should be unique for each base station — if
it is not, the data generator will work without problems but the receiver may have
problems in distinguishing base stations with same primary scrambling codes. In
real networks, there will never be a situation where two base stations in same ge-
ographical area would have the same primary scrambling codes. See chapter 2.3.2
for more information about scrambling codes. Valid values for primary scrambling
code are 0, 1, 2, . . . 511 .
• START_SFN Start System Frame Number for data generation. Currently this has
no effect, because the generated channels are similar from frame to frame. However,
this may be used in future if additional channels will be added to the data generator.
Currently, it is safe to leave the value to 0. Valid values are 0, 1, 2, . . . 4095 .
• BS_OFFSET Offset in chips between the data generator’s internal timing and base
station’s timing. Please see chapter 5.2 for more information. If two base stations
have exactly the same offset, then their P-SCH peaks will overlap and it is difficult
to distinguish them. It is good to have at least a few chips between different base
stations. Of course such tricky situations, where two base stations overlap, may be
experimented — these situations may happen in a real network also. Valid values
are 0, 1, 2, . . . 38399 .
• STTD Space time block coding based transmit antenna diversity. This TX diversity
mode affects the generation of CPICH channels, i.e. P-CPICH and S-CPICHs. Valid
values are ON or OFF.
• TSTD Time switched transmit diversity. This TX diversity mode affects the gener-
ation of SCH channels, i.e. P-SCH and S-SCH. Valid values are ON or OFF.
• GAIN_BS Base station power in dB. When all channels have been generated and
summed, result is scaled with this gain factor. This can be used to simulate distances
between the UE and the base stations. It is safe to leave this value to 0. Valid values
are −64.0 . . . 20.0 . If the value is −64.0, data for this base station will not be
generated.
• GAIN_P_SCH Primary SCH power in dB. Suggested value = −15 (see [3]). Valid
values are −64.0 . . . 20.0 . If the value is −64.0, this channel will not be generated.
• GAIN_S_SCH Secondary SCH power in dB. Suggested value = −15 (see [3]).
Valid values are −64.0 . . . 20.0 . If the value is −64.0, this channel will not be
CHAPTER 5. USER’S GUIDE TO SYSTEM 53
generated.
• GAIN_P_CPICH Primary CPICH power in dB. Suggested value = −10 (see [3]).
Valid values are −64.0 . . . 20.0 . If the value is −64.0, this channel will not be
generated.
• S_CPICH_NUMBER Number of secondary CPICHs. If the value is non-zero,
each secondary CPICH has to be defined separately (see below). Valid values are
0, 1, 2, . . . 14.
If the value for keyword S_CPICH_NUMBER is non-zero, each secondary CPICH has
to be defined separately. Keywords for S-CPICH definitions are as follows:
• SECONDARY_CODE Secondary scrambling code. See chapter 2.3.2 for more infor-
mation about scrambling codes. Valid values are 1, 2, 3, . . . 15.
• CHAN_CODE Channelization code. See chapter 2.3.1 for more information about
channelization codes. Valid values are 0, 1, 2, . . . 255.
• GAIN_S_CPICH Secondary CPICH power in dB. Suggested value = −10 (see
[3]). Valid values are −64.0 . . . 20.0 . If the value is −64.0, this channel will not be
generated.
There should be no S-CPICHs with identical secondary scrambling and channelization
codes. The data generator will generate channels without problems, but the receiver can
not distinguish between channels with identical codes.
CHAPTER 5. USER’S GUIDE TO SYSTEM 54
5.3.3 Command line use
datagen [OPTS] <tx1_output_file> <tx2_output_file>
Mandatory parameters are:
• <tx1_output_file> Result file name for samples generated for the first TX
antenna.
• <tx2_output_file> Result file name for samples generated for the second TX
antenna.
There is only one optional setting in [OPTS]:
• -conffile=<conf_file_name> Do not use the default configuration file,
use <conf_file_name> instead.
If there were any errors in data generation, the program will terminate with a non-
zero exit value. In case of error-free operation, the exit value will be zero. This can be
examined, for example, in batch files.
5.4 Channel profile
This utility applies the simulated channel profile to input data. There may be either two or
one input files, depending if TX diversity is used or not. The result is stored to one output
file. Result data is not scaled or normalized in any way except by user defined channel
profile.
Only the stationary multipath fading AWGN channel is supported. Channel model
does not support moving multipaths, multipath birth or death, Doppler effects, or simula-
tion of UE or BS internal oscillator drift. If a more complex channel model is needed, any
external channel model (e.g. one created with Matlab) can be used instead of this model.
For more information about channel models suitable for simulations, see for example
[14].
Channel model applying requires heavy processing. If there is even one very long
delay (e.g. tens of microseconds) in the channel profile, it may take minutes to apply
channel profile. Processing time can be decreased very radically by removing the farmost
multipaths from the channel profile.
Channel profile is defined separately for both TX antennas and following keywords
are used:
CHAPTER 5. USER’S GUIDE TO SYSTEM 55
• OVERSAMPLING Oversampling factor. If the value is 1, incoming data is not over-
sampled at all. This value should equal to the setting in data generator — otherwise
the channel profile does not work. Valid values are 1, 2, 3, . . . 16 .
• NOISE_PWR Noise power is defined in desibels. White gaussian noise is added
after multipath profiling has been completed. Noise power value depends on desired
S/N ratios for physical channels. Valid values are −64.0 . . . + 20.0 . If the value is
−64.0, no noise will be generated. This parameter affects the whole channel.
• MPATH_NUMBER Number of multipaths for this TX antenna.
• MPATH_DELAY Multipath’s delay in nanoseconds. Valid values are 0 . . . 66666 ns.
This parameter is specific to each multipath.
• MPATH_GAIN Multipath’s amplitude gain. This value is defined in decibels. Valid
values are −64.0 . . . 20.0 . If the value is −64.0, multipath’s gain will be interpreted
as zero in decimal units. This parameter is specific to each multipath.
• MPATH_PHASE Multipath’s phase rotation. This value is given clockwise in de-
grees. Valid values are −180 . . . 180 degrees. This parameter is specific to each
multipath.
A sample channel profile definition file is provided in Appendix D. Also 3GPP defines
some channel profiles for type approval test cases, see [1]. If, however, the channel profile
is created manually, gains for multipaths can easily be calculated using, for example, a
free-space propagation loss formula [14]:
Lp = 20 log10
4 R f
π c(5.2)
where R is the distance between BS and UE in kilometers and f is the frequency in
Hz.
5.4.1 Command line use
chanprof <channel_profile_file> <output_file> \
<tx1_input_file> [tx2_input_file]
(where \ denotes the continuation of command line)
Parameters are as follows:
CHAPTER 5. USER’S GUIDE TO SYSTEM 56
• channel_profile_file Channel profile definition file name. This is a
mandatory parameter.
• output_file Output file name. This is a mandatory parameter.
• tx1_input_file File name for TX antenna 1 input data. This is a mandatory
parameter.
• tx2_input_file File name for TX antenna 2 input data. This parameter is
mandatory, if TX diversity is selected from the channel profile definition file. If TX
diversity is not selected, this parameter will be disregarded.
If any errors occurred when applying the channel profile, the program will terminate
with a non-zero exit value. In case of error-free operation, the exit value will be zero. This
can be examined, for example, in batch files.
5.5 Merging utility
This utility merges input files in a chipwise manner and saves the result to the output file.
The result is not scaled in any way, so the user will have to take care that the output file is
within the desired dynamic range by adjusting parameters in the data generator.
5.5.1 Command line use
merge <output_file> <input_file_1> [... <input_file_n>]
Parameters are as follows:
• <output_file> Output file name. This is a mandatory parameter.
• <input_file_1> First input file name. This is a mandatory parameter.
• <input_file_n> Other input file names. There may be zero, one or several
other input file names. This is an optional parameter.
Lengths of input files do not have to be equivalent. The output file will be as long
as the longest input file. The data in all input files have to be in the format specified in
chapter 5.8. The same format will be used also in the output file.
If any errors occurred in file merging, the program will terminate with a non-zero exit
value. In case of error-free operation, the exit value will be zero. This can be examined,
for example, in batch files.
CHAPTER 5. USER’S GUIDE TO SYSTEM 57
5.6 Receiver simulator
This part of the system simulates some procedures mandatory for all WCDMA UEs. In
general, these L1 procedures are essential for acquiring and maintaining synchroniza-
tion to network and in network level measurements. In WCDMA UE, these procedures
are performed frequently — specially if UE is in active mode (i.e. phone call is active),
they are performed continuously. Because these procedures may spend a huge amount of
computation power, they must be very well optimized, and optimization is not possible
without comprehensive simulations.
Components implemented in this receiver simulator offer some possibilities for opti-
mizing implementation of procedures. It is possible to simulate fixed bit-length mathe-
matics. Automatic Gain Control (AGC) may be used to scale input samples. Using results
from this receiver simulator, in principle it is possible to create, for example, VHDL im-
plementation of matched filter suitable to impulse response measurement for a common
pilot channel.
Individual procedures may be adjusted separately using a configuration file. A sample
configuration file is provided in Appendix E. It is possible to have many configuration files
for many simulation schemes. The configuration file can be selected from the command
line but if no selection is made, the default configuration file named simu.cfg will be
used.
After all, this receiver simulator is a very much simplified model of real world devices.
For example, it does not work using real data streams but it uses files; it assumes there are
no limits on used memory or computing capacity and so on. For more information about
designing more realistic simulators, please see, for example, [14].
5.6.1 Supported procedures
Primary Synchronization Code Search This procedure is used mainly for determining
base station slot timing in the Initial Synchronization procedure. Result is a file con-
taining correlation results between input data and Primary Synchronization Code
(PSC). The results are in the power domain. Individual base stations cannot be
directly identified from the measurement result, but base stations found can be ex-
amined further, for example, their scrambling code groups and scrambling codes
can be identified. An example measurement is performed in chapter 6.1.
Impulse Response Measurement for Common Pilot Channel This procedure is used
for two main reasons: first, for determining the channel profile and second, for
CHAPTER 5. USER’S GUIDE TO SYSTEM 58
defining the exact timing difference between the base station and the UE. Impulse
Response Measurement (IRM) can be performed from the Primary Common Pilot
Channel or any of Secondary Common Pilot Channels, if those exist. The informa-
tion needed for performing IRM are base station timing and used scrambling code.
IRM will always be performed over one CPICH symbol (i.e. 256 chips). Measure-
ment may be averaged over many symbols in a coherent fashion. The result is two
files containing correlation results, in the power and phase domain. This proce-
dure is explained more detailed in [8] and an example measurement is performed
in chapter 6.3.
Correlation measurement for Secondary Synchronization Codes This procedure is
used for frame synchronization and scrambling code group identification. The in-
formation needed for performing this procedure is base stations slot timing. The
result is a file containing correlation results for individual secondary synchroniza-
tion codes, one result for every slot during one frame. The results are in the power
domain. Both the frame synchronization and the scrambling code group can be
identified from the correlation results. An example measurement is performed in
chapter 6.2.
Initial Synchronization Procedure In this procedure, all the procedures needed for ac-
quiring synchronization to base station are performed in a series: first, slot synchro-
nization of the most powerful available base station is acquired. Next, frame syn-
chronization and scrambling code idenfitication are performed. The last procedure
is the identification of scrambling code which is done by checking the correlation
of all primary scrambling codes in an identified code-group and selecting the best
correlating one. As the result of the whole synchronization procedure, four dif-
ferent files are obtained, i.e. results for all intermediate steps, found base station’s
primary scrambling code and timing offset. The initial synchronization procedure
is explained in [7] and an example measurement is performed in chapter 6.4.
If bit-limited mathematics is simulated, input data samples are scaled and converted
to user-selected Q format numbers before simulations. Also results are scaled and con-
verted to user-selected Q format. The user may select the number of bits used for integer
and decimal parts. However, actual calculations are implemented using floating point
mathematics. Please note that altough results are converted to Q format (i.e. bit-limited),
numbers in result files are plain floating-point numbers.
CHAPTER 5. USER’S GUIDE TO SYSTEM 59
5.6.2 Configuration of simulator
Behavior of simulated procedures can be defined in the configuration file using the fol-
lowing keywords:
• OVERSAMPLING Oversampling factor. If value is 1, input data is not oversampled
at all. This value should be equal to the setting in the data generator — otherwise
the simulator does not produce correct results. Valid values are 1, 2, 3, . . . 16 .
• AGC_IN_USE Selects whether Automatic Gain Control (AGC) is used to scale
input values. Valid values are ON or OFF.
• AGC_AVERAGING_TIME Averaging time in chips for calculating the scaling fac-
tor of Automatic Gain Control. This setting has no effect, if option AGC_IN_USE
is set OFF. Valid values are 1, 2, 3, . . . 256.
• AGC_ADC_MAX_AMPLITUDE A/D converter’s maximum usable input amplitude
value. This setting has no effect, if option AGC_IN_USE is set OFF. There is no
specific range, any 32-bit floating point number is valid. It is safe to set this to 10.0.
• AGC_ADC_RANGE A/D converter’s usable operation range. This setting has no
effect, if option AGC_IN_USE is set OFF. Valid values are 0 . . . 1. It is safe to set
this to 0.95, which leaves five percent of operation range as a safety margin.
• AGC_AUTOMATIC_INIT_ENABLED Selects whether AGC is allowed to auto-
matically initialize itself. See the next keyword for more explanation. This setting
has no effect, if option AGC_IN_USE is set OFF. Valid values are ON or OFF.
• AGC_AUTOMATIC_INIT_TRIGGER If AGC automatic initialization is set ON
(previous keyword) and the amplitude of incoming signal suddenly increases by
the factor defined by this value, AGC initializes itself. This setting has no effect,
if option AGC_IN_USE or ON is set OFF. Valid values are 0, . . . 99999. Suggested
value is 100.
• BIT_LIMIT Select whether input and output values are bit-limited, i.e. bit-
accurate device is simulated. Valid values are ON or OFF.
• PRE_INT_BIT_NUMBER Number of integer bits for Q conversion used in pre-
scaler. This setting has no effect, if option BIT_LIMIT is set OFF. Valid values
are 0, 1, 2, . . . 32.
CHAPTER 5. USER’S GUIDE TO SYSTEM 60
• PRE_DEC_BIT_NUMBER Number of decimal bits for Q conversion used in pre-
scaler. This setting has no effect, if option BIT_LIMIT is set OFF. Valid values
are 0, 1, 2, . . . 32.
• PRE_SCALING Selects how the prescaler scales input data before Q conversion.
This setting has no effect, if option BIT_LIMIT is set OFF. Valid values are
0.001 . . . 1000 .
• POST_INT_BIT_NUMBER Number of integer bits for Q conversion used in post-
scaler. This setting has no effect, if option BIT_LIMIT is set OFF. Valid values
are 0, 1, 2, . . . 32.
• POST_DEC_BIT_NUMBER Number of decimal bits for Q conversion used in post-
scaler. This setting has no effect, if option BIT_LIMIT is set OFF. Valid values
are 0, 1, 2, . . . 32.
• POST_SCALING Selects how the post-scaler scales input data before Q conver-
sion. This setting has no effect, if option BIT_LIMIT is set OFF. Valid values are
0.001 . . . 1000 .
• OFFSET Selects how many input data samples are discarded before starting calcu-
lations. Note that the number of samples equals to the number of chips multiplied
by oversampling. Valid values are 0, 1, 2, . . . 65535.
• PSC_AVG_LEN Averaging period length for PSC search in slots.
Valid values are 1, 2, 3, . . . 60.
• CPICH_AVG_LEN Averaging period length for impulse response measurement for
CPICH in symbols. Valid values are 1, 2, 3, . . . 60.
• CPICH_SCRAMBLINB_CODE Selects the scrambling code used for CPICH IRM.
Valid values are any scrambling code numbers (see chapter 2.3.2 for more informa-
tion), i.e. 0, 1, 2, ...262142.
• SSC_MEAS_LEN This parameter specifies for how many frames SSC correlation
measurement is performed. Valid values are 1, 2, 3, . . . 10.
• ISYNC_SCRC_THRESHOLD Threshold for scrambling code detection in initial
synchronization algorithm. If this treshold value is k, correlation of the best code
candidate has to be at least k times the average correlation of all candidates in the
group evaluated.
CHAPTER 5. USER’S GUIDE TO SYSTEM 61
5.6.3 Command line use
simu <PROC> [OPTS] <input_file> <result_filename_base>
One <PROC>, i.e. procedure, has to be selected. They are as follows:
• ISYNC Perform initial synchronization procedure.
• PSC Perform primary synchronization code search.
• IRM Perform impulse response measurement for the common pilot channel.
• SSC Perform correlation measurement for secondary synchronization codes.
Optional settings in [OPTS] are:
• -conffile=<conf_file_name> Do not use the default configuration file,
use <conf_file_name> instead.
• -offset=n Before starting simulation, ignore the first n input data samples. This
option is practical if initial synchronization steps are performed manually. If this
option is set, it overrides the setting of OFFSET in the configuration file.
About other parameters: <input_file> is the name of the input file. Depending on
selected procedure, the simulator may produce one or several result files which are named
by using <result_filename_base> as a body and adding procedure-specific suf-
fixes after the body. Suffixes are:
• _psc.asc Primary synchronization code search results in power domain.
• _cpich_power.asc Impulse response measurement for common pilot channel
results in power domain.
• _cpich_phase.asc Impulse response measurement for common pilot channel
results in phase domain.
• _ssc.asc Results from correlation measurement for secondary synchronization
codes.
• _isync.asc Final results from initial synchronization procedure.
If there were any errors in simulation, the program will terminate with a non-zero exit
value. In case of error-free operation, the exit value will be zero. This can be examined,
for example, in batch files.
CHAPTER 5. USER’S GUIDE TO SYSTEM 62
5.7 Simulating multiple base stations
Sometimes it is necessary to produce test data containing data from many base stations.
It depends on case, whether is is enough to produce data from all base stations using one
data generator run or is it needed to produce data for different base stations separately and
merge them afterwards.
Let us take some examples. In the first example, main focus is to examine correlation
properties of synchronization codes. Let us assume that the data generator is set to pro-
duce test data for three independent base stations with different timings and scrambling
codes. There is no need to apply any channel profile to generated data so if no trans-
mit diversities are used, the data generator produces only one file which can be directly
examined with the receiver simulator. It is rather fast to change, for example, timing pa-
rameters in data generator configuration file, re-generate the data and examine it again
with receiver simulator. Thus, in this example, only the data generator and the receiver
simulator were needed.
In the second example, main focus point is to examine how Time Switched Transmit
Diversity (TSTD) affects the detection of primary synchronization code when there are
many base stations. Again, the data generator is set to produce test data for three in-
dependent base stations with different timings and scrambling codes. Because transmit
diversity is used, the channel profile has to be defined. Channel profiling is quite a heavy
operation due to very long (length = oversampling × 256) delay lines. Thus it may
be reasonable to use exactly the same channel profile for all base stations and hence only
one channel profiling run is needed. Channel-profiled data may now be examined with
receiver simulator. It may be interesting to change, for example, channel profile values so
it is not necessary to re-generate the test data, only a new channel profiling is required.
In this example, the following components were needed: the data generator, the channel
profiler and the receiver simulator.
In the third example, initial synchronization procedure is examined. Simulation re-
quires as realistic channel profiles as possible, and therefore different base stations can
not use the same channel profile definitions. The data generator needs to be configured to
generate data for only one base station at a time and the channel profile is applied to re-
sult data. This procedure, data generation + channel profile applying, is performed for all
simulated base stations and finally, all channel profile result files are merged into one file
by using the merging utility. Now the result may be examined using receiver simulation.
If every base station has a different channel profile, it may take quite a long time to
regenerate and channel profile the test data. In this case, it might be wise to create a
batch file or a makefile to perform the actual work. If there are several Unix computers
CHAPTER 5. USER’S GUIDE TO SYSTEM 63
available, it might be practical to use parallel make utilities, which enable running parallel
batch jobs in many computers. For more information, see, for example, lmake [15].
5.8 Data formats in files
5.8.1 Data format in files between components
In a data file, consequtive samples are in separate rows. There must not be blank rows
between samples. Each sample consists of separate I and Q parts which are on the same
line separated by a space-character. In one sample, the I part is given first, then the Q part.
Both the I and Q parts are expressed with floating-point numbers using 32-bits accuracy
per part. Here is an example:
Contents of Samples
data file I -part Q -part...
0.106011 -0.106011 0.106011 −0.106011
0.093861 -0.093861 0.093861 −0.093861
0.062512 -0.062512 0.062512 −0.062512
0.019623 0.016645 0.019623 0.016645...
5.8.2 Data formats in files produced by receiver simulator
In the result files produced by the receiver simulator, three different data formats are used.
The data format depends on what procedure receiver simulator performed.
If the selected procedure was Primary Synchronization Code search, the result file
contains correlation results in the power domain. Each line in the result file contains the
result for one correlation point as a 32-bit floating-point number. The result file length
equals to the measurement window length (256 chips) multiplied by the used oversam-
pling factor i.e. if oversampling factor is 4, there will be 1024 samples in the result file.
If the selected procedure was impulse response measurement of CPICH, there are two
result files: one file containing results in the power domain and another in the phase do-
main. Values are expressed as 32-bit floating-point numbers. The lengths of the result
files equal to measurement window length (256 chips) multiplied by the used oversam-
pling factor, i.e. if the oversampling factor was 8, there will be 2048 samples in the result
file.
CHAPTER 5. USER’S GUIDE TO SYSTEM 64
If the selected procedure was a SSC correlation measurement, the result file contains
correlation powers for every SSC per each slot i.e. there are 15 lines and 16 floating-point
numbers per line. Each line corresponds to slots and each individual number on a line
corresponds to the correlation power of SSC as follows:
Cssc,1,n Cssc,2,n . . . Cssc,k,n . . . Cssc,16,n
where n corresponds to the slot number (n = 0 . . . 14) and Cssc,k,n to the correlation
result for kth SSC in nth slot. Values are separated by space-characters.
If the selected procedure was initial synchronization, four different result files are
produced. The first result file contains the result from the PSC search. The second result
file contains the result from the SSC correlation measurement. Formats of these were
described above.
The third result file contains the result from the scrambling code identification proce-
dure, i.e. there are correlation results for all primary scrambling code candidates inside
scrambling code group in consequtive rows — the first row equals to the correlation result
for the first candidate and so on. There are a total of 64 values (i.e. there are 64 primary
scrambling codes in one group).
The fourth result file contains only two values, both in separate lines: the first one
is the base station ID detected (i.e. primary scrambling code) and the second one is the
base station’s timing offset, in chips. See chapter 5.3.2 for more information about these
values.
Chapter 6
Simulation Examples
This chapter demonstrates briefly the capabilities of the data generation system. One
set of test data is generated and channel-modeled. A receiver simulator is then used to
determine the base station timing, scrambling code and channel multipath properties.
Configuration files used for simulation are attached in appendixes of this work.
The configuration file for the baseband test data generator (datagen.cfg) is in Ap-
pendix C, for channel model (chanmod.cfg) in Appendix D and for receiver simulator
(simu.cfg) in Appendix E.
Current configuration simplified is as follows: the data generator generates data for
one base station with a 100-chip timing delay. The channel model has 6 multipaths with
delays of 0, 5, 10, 15, 20, 25 µs delays and attenuations of 0,−3,−6,−9,−12,−15 dB.
All data is oversampled with factor 4.
The following command sequence was used to perform the data generation, channel
modeling and simulations:
datagen tx1.txt tx2.txt
chanmod chanmod.cfg test_data.txt tx1.txt
simu isync test_data.txt test_data
simu irm test_data.txt test_data
Of this command sequence, the first row produces the test data. The second row ap-
plies the channel profile to the test data. The third row performs the complete initial
synchronization procedure in the receiver simulator, and the last row performs the im-
pulse response measurement for the common pilot channel. Results of the simulations
are discussed in the following chapters.
CHAPTER 6. SIMULATION EXAMPLES 66
6.1 PSC search
Results of the PSC search (i.e. Primary Synchronization Code impulse response measure-
ment) are the in file test_data_psc.asc. The file contents are printed in Figure
6.1.
From the correlation result Figure it can be seen that all significant correlation peaks
( i.e. peaks noticeably above noise level) are in the beginning of timescale. To clarify
this more, samples in range 0 . . . 1023 (duration of one symbol with SF = 256, on over-
sampling 4) are zoomed in to another Figure 6.2. From this Figure it can be seen that the
highest peak is in position 400. The following peaks are spaced with approximate 75 sam-
ples which equals to approximately 5 µs (with oversampling 4, there are 15360 samples
in one nanosecond). Heights of peaks follow the shape of exponential curve. Both the
timings and the power levels of multipaths are in harmony with the programmed channel
model.
The phase domain results are not stored from the primary synchronization code im-
pulse response measurement. This is due to the properties of both the primary synchro-
0
500000
1e+006
1.5e+006
2e+006
2.5e+006
3e+006
0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000
Cor
rela
tion
Delay [sample #]
Figure 6.1: Impulse response measurement result (power domain) for primary synchro-
nization code
CHAPTER 6. SIMULATION EXAMPLES 67
nization code and primary synchronization channel: because the length of the primary
synchronization code is only 256 chips and because in primary synchronization channel,
it is transmitted only as the first symbol of the slot, it does not produce any feasible in-
formation which could be used for channel equalization. Channel’s phase properties are
detected by measuring the correlation between a locally generated scrambling code and
the common pilot channel which is transmitted continuously.
6.2 SSC correlation measurement
Results from the scrambling code group detection (i.e. secondary search code correlation
measurement) are in the file test_data_ssc.asc. The results are printed in Figure
6.3 in the way that for each slot in frame, the correlation of each secondary synchroniza-
tion code is expressed.
The sequence of the secondary scrambling codes with the highest correlation values
in each slot is as follows: 1, 3, 4, 7, 4, 1, 5, 5, 3, 6, 2, 8, 7, 6, 8. When this sequence is com-
pared to secondary scrambling code allocation table (Table B.1 in appendix B), it can be
0
500000
1e+006
1.5e+006
2e+006
2.5e+006
3e+006
0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000
Cor
rela
tion
Delay [sample #]
Figure 6.2: Zoomed-in impulse response measurement result for primary synchronization
code
CH
APT
ER
6.SIMU
LA
TIO
NE
XA
MPL
ES
68
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
�
� � � � �
� � � � � �
� � � � � �
� � � � � �
� � � � � �
� � � � � � � � � � � � � � � �
�� � � �� � �� �
����
����
�!
"# "$ "% "& "' "( ") "* "+ "# , "# # "# $ "# % "# & "# ' "# (
Figure 6.3: Result of secondary search code correlation measurement
CHAPTER 6. SIMULATION EXAMPLES 69
seen that the detected scrambling code group is 5, and that the sequence starts with a zero
frame offset, i.e. the secondary scrambling code sequence is not cyclically shifted.
6.3 P-CPICH impulse response measurement
Results from the primary common pilot channel impulse response measurement are stored
in the power domain in the file test_data_cpich_power.asc, and printed in Fig-
ure 6.4, and stored in phase domain in file test_data_cpich_phase.asc, and
printed in Figure 6.5.
If the power domain Figure 6.4 is compared to the zoomed-in PSC search result, it
can be seen that both results contain the same multipaths with the same levels — also
the accuracy of multipath positions is approximately the same. The only major difference
is that P-CPICH IRM result contains less noise than the PSC search result. Thus if the
PSC search is first used to detect the timing of the strongest multipath of the base station,
P-CPICH IRM can be used to detect the rest of the base station’s multipaths.
As it can be easily seen from Figure 6.5, this phase-domain figure does not provide any
0
5e+006
1e+007
1.5e+007
2e+007
2.5e+007
0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000
Cor
rela
tion
Delay [sample #]
Figure 6.4: Correlation result (power domain) for CPICH
CHAPTER 6. SIMULATION EXAMPLES 70
useful information. The IRM phase-domain result consists mainly of noise. The positions
of the multipaths can be found in the power-domain result data file; consequently, their
phases can be read very accurately from the phase-domain result data file.
In this example, multipaths are in sample positions 400, 477, 554, 630, 707, 784. From
the phase-domain result file, their phases are read as 2.1, 31.3, 59.2, 86.9, 4.5,−42.4 de-
grees which agree with multipaths defined in the channel model configuration file.
6.4 Initial synchronization procedure
Overall results of the initial synchronization procedure are in the file
test_data_isync.asc. The results consist of the detected base station pri-
mary scrambling code number and its frame offset i.e. how many samples there are
between the start of the data file and the start of base station frame structure.
In this example, the detected primary scrambling code is 640 and frame offset 400.
When compared to the data generator configuration file, these are exactly correct results.
-180
-150
-120
-90
-60
-30
0
30
60
90
120
150
180
0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000
Pha
se [d
egre
es]
Delay [sample #]
Figure 6.5: Correlation result (phase domain) for CPICH
Chapter 7
Conclusions and further development
This thesis focused on developing and documenting a baseband test data generation soft-
ware. A channel model and a receiver simulator were developed to support and verify the
actual test data generator.
It was shown in chapter 6 that the test data generator works according to the require-
ments which were set in chapter 3. The data generator was verified using the simulator.
This kind of testimony requires that the code generators in both the data generator and
the simulator work as specified. Common code generator modules were used and their
operation was verified by comparing the code generated by them to a manually generated
code.
7.1 Comparing simulator software to real devices
Real world devices work in real time and use streaming input data, so they must be
able to perform all calculations in almost real time. The simulator software in this sys-
tem works with stored data. Simulations are performed in a PC whose clockspeed is
200 . . . 2000 MHz. Still, it takes seconds to perform, for example, just one PSC search.
The major reason for this is that the software was implemented in ANSI-C which does
not have any optimization support for writing FIR filters. Another reason is that the input
data is read from file. Thus it can be clearly seen that this approach would not work at all
in a real device. In those, procedures are implemented in ASICs, or if software is used,
they would have to be implemented with a totally different architecture.
CHAPTER 7. CONCLUSIONS AND FURTHER DEVELOPMENT 72
7.2 Further development of the data generator system
It is relatively simple to add generation of new downlink channels (e.g. P-CCPCH) to
the data generator system. New channels can use the existing services (e.g. generation of
channelization and scrambling codes). However, as the architecture of the data generator
system does not allow it to support any uplink channels, a new main level architecture
would have to be developed.
The merging utility might be developed to contain a wideband power estimator. Re-
sults from the estimator could be used to calculate Ec/Io (energy of chip divided by
wideband power) from the IRM results. For more information about this, see [14].
The channel model is extremely simple. If this system were used for any serious
purpose, a channel model would have to be developed to contain support for moving mul-
tipaths, multipath birth and death, Doppler effects, and simulation of UE or BS internal
oscillator drift.
The simulator system has a simple initial synchronization algorithm. If any compli-
cated channel profiles are examined, a better algorithm needs to be developed — at least
the scrambling code group detection procedure does not handle the multipath birth and
death situation.
In general, it is worthwhile to develop the data generator, but other components of the
system are already available (or may be implemented with small effort) in other tools, for
example, in Matlab, so their further development may not be so profitable.
7.3 Notes about this master’s thesis
This M.Sc. thesis work is much more a software project than a “conventional” thesis.
There are approx. 7700 lines of C source code and 10 pages of flowcharts in this work.
Compared to the amount of actual text in the thesis work, it can be seen that the relation
of software and text is approx. 70/30.
The total work time used for the thesis was about 800 man hours. From the total time,
developing of software took about 600 man hours from which the design phase accounted
for 5 %, implementation 20 %, module testing 30 %, testing and verifying of the complete
system 40 % and correction of bugs 5 %. Thus the time spent for testing and debugging
made up 75 % of the whole “project” duration. This was a surprise to me — when I
started the work, I planned the testing phase to be much shorter. These figures are, again,
a reminder of that the proper testing of software requires plenty of time.
References
[1] 3GPP 25.101: UE Radio transmission and reception (FDD), v3.7.0 (Release
99/June 2001).
[2] 3GPP 25.104: UTRA (BS) FDD Radio transmission and reception (FDD), v3.8.0
(Release 99/June 2001).
[3] 3GPP 25.133: Requirements for support of radio resource management (FDD),
v3.6.0 (Release 99/June 2001).
[4] 3GPP 25.211: Physical channels and mapping of transport channels onto physical
channels (FDD), v3.7.0 (Release 99/June 2001).
[5] 3GPP 25.212: Multiplexing and channel coding (FDD), v3.6.0 (Release 99/June
2001).
[6] 3GPP 25.213: Spreading and modulation(FDD), v3.6.0 (Release 99/June 2001).
[7] 3GPP 25.214: Physical layer procedures (FDD), v3.7.0 (Release 99/June 2001).
[8] 3GPP 25.215: Physical layer — measurements (FDD), v3.7.0 (Release 99/June
2001).
[9] 3rd Generation Partnership Project (3GPP), http://www.3gpp.org/.
[10] K. G. Beauchamp. Walsh Functions and Their Applications. Academic, London,
1975.
[11] G.E.P. Box and M.E. Muller. A note on the generation of random normal deviates.
Annals Math. Stat, 29:610–611, 1958.
[12] J. E. Gibbs. Discrete complex walsh transforms. In Applications of Walsh
Functions. Washington, 1970.
[13] M. J. E. Golay. Note on digital coding. Proc. IRE, 37:657, June 1949.
REFERENCES 74
[14] Michel C. Jeruchim, Philip Balaban, and K. Sam Shanmugan. Simulation of
Communication Systems. Kluwer Academic/Plenum Publishers, New York, 2000.
[15] Martin Loitz. Lmake – Entwurf und Implementierung eines parallelen
Make-Programms. Master’s thesis, Institut für Betriebssysteme und
Rechnerverbund, TU Braunschweig,
ftp://ftp.ibr.cs.tu-bs.de/pub/local/lmake-0.6.tar.gz,
1993.
[16] Anritsu Ltd. MD8480A W-CDMA Signaling Tester Datasheet.
http://www.eu.anritsu.com/downloads/MD8480A_E1200.pdf,
doc. code: MD8480A-E-A-1-(2.00) 2001-8 20 KL/M, August 2001.
[17] R. Price and P.E. Green Jr. A communication technique for multipath channels.
Proc. IRE, 46:555–570, March 1958.
[18] J. L. Walsh. A closed set of orthogonal functions. In Amer. J. of Math. 45, 1923.
Appendix A
Flowcharts
A.1 Data generator
S T A R T
R E A DC O N F I G U R A T I O N
F I L E
O V E R S A M P L I N G A N DP U L S E - S H A P E
F I L T E R I N G
E N D
G E N E R A T EA L L D A T A
Figure A.1: Flowchart: data generator shell
APPENDIX A. FLOWCHARTS A-2
C R E A T E D A T A F O RT H I S B A S E S T A T I O N
N
YM O R E B A S ES T A T I O N S ?
M E R G E D A T AW I T H P R E V I O U S L Y
C R E A T E D D A T A
S T A R T
E N D
Figure A.2: Flowchart: data generation main loop
APPENDIX A. FLOWCHARTS A-3
N
YM O R E F R A M E S ?
G E N E R A T EP S C S E Q U E N C E
S T A R T
E N D
G E N E R A T ES S C S E Q U E N C E S
G E N E R A T EC H A N . C O D E S E Q U E N C E S
G E N E R A T EO N E F R A M E F U L O F
P H Y S I C A L C H A N N E LD A T A
Figure A.3: Flowchart: data generation for one base station
APPENDIX A. FLOWCHARTS A-4
A T T A C H P S CS E Q U E N C E I F
S E L E C T E D
E N D
A T T A C H S S CS E Q U E N C E I F
S E L E C T E D
I F S E L E C T E D ,G E N E R A T E S C R .
C O D E S F O R C P I C H SA N D A T T A C H C P I C H s
Y
N L A S T S Y M B O LI N S L O T ?
Y
NL A S T S L O TI N F R A M E ?
N E X T S Y M B O L N E X T S L O T
S T A R T
S T A R T F R O MF I R S T S Y M B O L
I N S L O T
S T A R T F R O MF I R S T S L O T
I N F R A M E
Figure A.4: Flowchart: data generation for one frame
APPENDIX A. FLOWCHARTS A-5
N
YM O R E S A M P L E ST O S U M ?
D I S C A R D N E E D E DA M O U N T O F C H I P Si . e . A D J U S T B A S ES T A T I O N O F F S E T
S T A R T
E N D
R E A D O N E S A M P L EF R O M J U S T
G E N E R A T E D D A T A
S U M S C A L E D S A M P L ET O P R E V I O U S L Y
G E N E R A T E D D A T A
S C A L E S A M P L EA C C O R D I N G T OB A S E S T A T I O NG A I N F A C T O R
Figure A.5: Flowchart: merging generated data with previously generated data
APPENDIX A. FLOWCHARTS A-6
Y
Nn = 1 ?
S T A R T
S E T n = 0
n = n + 1
R E A D C H I PF R O M I N P U T
S E N D C H I P V A L U ET O P U L S E - S H A P E
F I L T E R
S E N D V A L U E Z E R OT O P U L S E - S H A P E
F I L T E R
Y
N n = O V E R S A M P .F A C T O R ?
N
Y M O R E C H I P SI N I N P U T ?
E N D
Figure A.6: Flowchart: chip oversampling and filtering
APPENDIX A. FLOWCHARTS A-7
A.2 Channel profile
S T A R T
R E A D C H A N N E LP R O F I L E S E T T I N G S
F R O MC O N F I G U R A T I O N F I L E
E N D
C A L C U L A T E D E L A YP R O F I L E S A N D S T O R E
C O E F F I C I E N T SF O R D E L A Y L I N E S
I N I T I A L I Z ED E L A Y L I N E S W I T H
Z E R O E S
R E A D N E W S A M P L E SF R O M I N P U T F I L E S ;
S T O R E T O F I R S T P O S . I N D E L A Y L I N E
M U L T I P L Y C O N T E N T SO F D E L A Y L I N E S
W I T H C O E F F I C I E N T SA N D S U M R E S U L T S
A D D W H I T E G A U S S I A NN O I S E T O R E S U L T S
A N D S T O R E T OO U T P U T F I L E
S H I F T C O N T E N T SO F D E L A Y L I N E S
Y
NE N D O FI N P U T F I L E ?
Figure A.7: Flowchart: channel profile
APPENDIX A. FLOWCHARTS A-8
A.3 Merging utility
S T A R T
C R E A T E T E M P O R A R YF I L E S A A N D B
N
YE N D O FI N P U T F I L E ?
R E A D S A M P L E IF R O M I N P U T F I L E
O P E N I N P U T F I L E
YE N D O FT E M P F I L E A ?
R E A D S A M P L E AF R O M T E M P F I L E A
S E T S A M P L E IT O Z E R O
S E T S A M P L E AT O Z E R O
A D D S A M P L E S A A N D I . W R I T E
R E S U L T T OT E M P F I L E B .
N
Y
NE N D O FB O T H I N P U T
F I L E S ?
N
YA R E T H E R EM O R E F I L E S ?
O P E N N E X T I N P U TF I L E . S W A P T E M P
F I L E S A A N D B .R E W I N D T E M P F I L E S .
C L O S E A L L I N P U TF I L E S . R E S U L T
I S I N T E M P F I L E B .
E N D
Figure A.8: Flowchart: merging utility
APPENDIX A. FLOWCHARTS A-9
A.4 Simulator
S T A R T
E N D
P R I M A R YS Y N C H R O N I Z A T I O N
C O D E S E A R C H
P R O C E D U R ES E L E C T I O N
C O R R . M E A S .F O R S E C O N D A R YS Y N C H R . C O D E S
I M P U L S E R E S P O N S EM E A S . F O R C O M M . P I L O T C H A N N E L S
C O M P L E T E I N I T I A LS Y N C H R O N I Z A T I O N
P R O C E D U R E
Figure A.9: Flowchart: receiver simulator shell
APPENDIX A. FLOWCHARTS A-10
S T A R T
P E R F O R MP S C S E A R C H
E N D
I D E N T I F YS C R A M B L I N G C O D E
G R O U P
I D E N T I F YS C R A M B L I N G
C O D E
I N I T I A LS Y N C H R O N I Z A T I O N
S U C C E E D E D
Y
NS U C C E S S ?
I N I T I A LS Y N C H R O N I Z A T I O N
F A I L E D
Y
NS U C C E S S ?
Y
NS U C C E S S ?
Figure A.10: Flowchart: initial synchronization procedure according to [7]
Appendix B
Allocation of SSCs for secondary SCH
Following table (source: [6]) describes the sequences of SSCs used to encode the 64
different scrambling code groups. The entries in table denote what SSC to use in the
different slots for the different scrambling code groupt, e.g. the entry “7” means that SSC
CSSC,7 shall be used for the corresponding scrambling code group and slot.
Table B.1: Allocation of SSCs for secondary SCH
Scrambling Slot number
code group #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14
Group 0 1 1 2 8 9 10 15 8 10 16 2 7 15 7 16
Group 1 1 1 5 16 7 3 14 16 3 10 5 12 14 12 10
Group 2 1 2 1 15 5 5 12 16 6 11 2 16 11 15 12
Group 3 1 2 3 1 8 6 5 2 5 8 4 4 6 3 7
Group 4 1 2 16 6 6 11 15 5 12 1 15 12 16 11 2
Group 5 1 3 4 7 4 1 5 5 3 6 2 8 7 6 8
Group 6 1 4 11 3 4 10 9 2 11 2 10 12 12 9 3
Group 7 1 5 6 6 14 9 10 2 13 9 2 5 14 1 13
Group 8 1 6 10 10 4 11 7 13 16 11 13 6 4 1 16
Group 9 1 6 13 2 14 2 6 5 5 13 10 9 1 14 10
Group 10 1 7 8 5 7 2 4 3 8 3 2 6 6 4 5
Group 11 1 7 10 9 16 7 9 15 1 8 16 8 15 2 2
Group 12 1 8 12 9 9 4 13 16 5 1 13 5 12 4 8
Group 13 1 8 14 10 14 1 15 15 8 5 11 4 10 5 4
Group 14 1 9 2 15 15 16 10 7 8 1 10 8 2 16 9
Group 15 1 9 15 6 16 2 13 14 10 11 7 4 5 12 3
Group 16 1 10 9 11 15 7 6 4 16 5 2 12 13 3 14
Group 17 1 11 14 4 13 2 9 10 12 16 8 5 3 15 6
Group 18 1 12 12 13 14 7 2 8 14 2 1 13 11 8 11
Group 19 1 12 15 5 4 14 3 16 7 8 6 2 10 11 13
Group 20 1 15 4 3 7 6 10 13 12 5 14 16 8 2 11
continues on next page
APPENDIX B. ALLOCATION OF SSCS FOR SECONDARY SCH B-2
continued from previous page
Scrambling Slot number
code group #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14
Group 21 1 16 3 12 11 9 13 5 8 2 14 7 4 10 15
Group 22 2 2 5 10 16 11 3 10 11 8 5 13 3 13 8
Group 23 2 2 12 3 15 5 8 3 5 14 12 9 8 9 14
Group 24 2 3 6 16 12 16 3 13 13 6 7 9 2 12 7
Group 25 2 3 8 2 9 15 14 3 14 9 5 5 15 8 12
Group 26 2 4 7 9 5 4 9 11 2 14 5 14 11 16 16
Group 27 2 4 13 12 12 7 15 10 5 2 15 5 13 7 4
Group 28 2 5 9 9 3 12 8 14 15 12 14 5 3 2 15
Group 29 2 5 11 7 2 11 9 4 16 7 16 9 14 14 4
Group 30 2 6 2 13 3 3 12 9 7 16 6 9 16 13 12
Group 31 2 6 9 7 7 16 13 3 12 2 13 12 9 16 6
Group 32 2 7 12 15 2 12 4 10 13 15 13 4 5 5 10
Group 33 2 7 14 16 5 9 2 9 16 11 11 5 7 4 14
Group 34 2 8 5 12 5 2 14 14 8 15 3 9 12 15 9
Group 35 2 9 13 4 2 13 8 11 6 4 6 8 15 15 11
Group 36 2 10 3 2 13 16 8 10 8 13 11 11 16 3 5
Group 37 2 11 15 3 11 6 14 10 15 10 6 7 7 14 3
Group 38 2 16 4 5 16 14 7 11 4 11 14 9 9 7 5
Group 39 3 3 4 6 11 12 13 6 12 14 4 5 13 5 14
Group 40 3 3 6 5 16 9 15 5 9 10 6 4 15 4 10
Group 41 3 4 5 14 4 6 12 13 5 13 6 11 11 12 14
Group 42 3 4 9 16 10 4 16 15 3 5 10 5 15 6 6
Group 43 3 4 16 10 5 10 4 9 9 16 15 6 3 5 15
Group 44 3 5 12 11 14 5 11 13 3 6 14 6 13 4 4
Group 45 3 6 4 10 6 5 9 15 4 15 5 16 16 9 10
Group 46 3 7 8 8 16 11 12 4 15 11 4 7 16 3 15
Group 47 3 7 16 11 4 15 3 15 11 12 12 4 7 8 16
Group 48 3 8 7 15 4 8 15 12 3 16 4 16 12 11 11
Group 49 3 8 15 4 16 4 8 7 7 15 12 11 3 16 12
Group 50 3 10 10 15 16 5 4 6 16 4 3 15 9 6 9
Group 51 3 13 11 5 4 12 4 11 6 6 5 3 14 13 12
Group 52 3 14 7 9 14 10 13 8 7 8 10 4 4 13 9
Group 53 5 5 8 14 16 13 6 14 13 7 8 15 6 15 7
Group 54 5 6 11 7 10 8 5 8 7 12 12 10 6 9 11
Group 55 5 6 13 8 13 5 7 7 6 16 14 15 8 16 15
Group 56 5 7 9 10 7 11 6 12 9 12 11 8 8 6 10
Group 57 5 9 6 8 10 9 8 12 5 11 10 11 12 7 7
Group 58 5 10 10 12 8 11 9 7 8 9 5 12 6 7 6
Group 59 5 10 12 6 5 12 8 9 7 6 7 8 11 11 9
Group 60 5 13 15 15 14 8 6 7 16 8 7 13 14 5 16
Group 61 9 10 13 10 11 15 15 9 16 12 14 13 16 14 11
Group 62 9 11 12 15 12 9 13 13 11 14 10 16 15 14 16
Group 63 9 12 10 15 13 14 9 14 15 11 11 13 12 16 10
Appendix C
Data generator configuration file
# Data generator configuration file
#
# Order of directives is accurate. There may not be any
# blank lines between directives. However, comment lines
# are allowed if they begin with ’#’.
#
# System-wide settings
BS_NUMBER: 1
FRAME_NUMBER: 2
OVERSAMPLING: 4
CHIP_FILTERING: ON
CHIP_FILTER_LEN: 16
VERBOSITY: 2
# End of system-wide settings
#
# Settings are for each base station
#
# Base station settings
SCRAMBLING_CODE: 640
START_SFN: 0
BS_OFFSET: 100
STTD: OFF
TSTD: OFF
GAIN_BS: 0
GAIN_P_SCH: -13
GAIN_S_SCH: -13
GAIN_P_CPICH: -10
S_CPICH_NUMBER: 1
# Secondary CPICH settings
SECONDARY_CODE: 7
CHAN_CODE: 20
GAIN_S_CPICH: -10
# End of this base station settings
#
# Base station settings
SCRAMBLING_CODE: 16
START_SFN: 2
BS_OFFSET: 1000
APPENDIX C. DATA GENERATOR CONFIGURATION FILE C-2
STTD: OFF
TSTD: OFF
GAIN_BS: -1.5
GAIN_P_SCH: -13
GAIN_S_SCH: -13
GAIN_P_CPICH: -10
S_CPICH_NUMBER: 1
# Secondary CPICH settings
SECONDARY_CODE: 4
CHAN_CODE: 2
GAIN_S_CPICH: -10
# End of this base station settings
#
END_OF_FILE
#
Appendix D
Channel profile definition file
# Channel model definition file
#
# Order of directives is accurate. There may not be any
# blank lines between directives. However, comment lines
# are allowed if they begin with ’#’.
#
# Oversampling factor
OVERSAMPLING: 4
#
# AWGN power in decibels, range = -64.0 ... +20.0
NOISE_PWR: -40
#
#
# Channel profile definition for TX antenna 1
# Profile is defined by giving following parameters:
# MPATH_DELAY: multipath’s delay in nanoseconds
# MPATH_GAIN: multipath’s attenuation in dBs
# MPATH_PHASE: multipath’s phase rotation in degrees
#
# Total amount of multipaths for TX antenna 1
MPATH_NUMBER: 6
#
# First tap: direct multipath with no fading
MPATH_DELAY: 0
MPATH_GAIN: 0
MPATH_PHASE: 0
#
# Other taps:
MPATH_DELAY: 5000
MPATH_GAIN: -3
MPATH_PHASE: 30
#
MPATH_DELAY: 10000
MPATH_GAIN: -6
MPATH_PHASE: 60
#
MPATH_DELAY: 15000
MPATH_GAIN: -9
APPENDIX D. CHANNEL PROFILE DEFINITION FILE D-2
MPATH_PHASE: 90
#
MPATH_DELAY: 20000
MPATH_GAIN: -12
MPATH_PHASE: 0
#
MPATH_DELAY: 25000
MPATH_GAIN: -15
MPATH_PHASE: -45
#
# Next channel profile definition for TX antenna 2
#
# Total amount of multipaths for TX antenna 2
MPATH_NUMBER: 1
#
# First tap: direct multipath with no fading
MPATH_DELAY: 10
MPATH_GAIN: 0
MPATH_PHASE: 30
#
# End of file.
Appendix E
Receiver simulator configuration file
# Simulator configuration file
#
# RCS history information:
#
# $Log: $
#
#
# Order of directives is accurate. There may not be any
# blank lines between directives. However, comment lines
# are allowed if they begin with ’#’.
#
OVERSAMPLING: 4
AGC_IN_USE: OFF
AGC_AVERAGING_TIME: 256
AGC_ADC_MAX_AMPLITUDE: 1.41
AGC_ADC_RANGE: 0.95
AGC_AUTOMATIC_INIT_ENABLED: ON
AGC_AUTOMATIC_INIT_TRIGGER: 100
BIT_LIMIT: OFF
PRE_INT_BIT_NUMBER: 0
PRE_DEC_BIT_NUMBER: 3
PRE_SCALING: 1
POST_INT_BIT_NUMBER: 8
POST_DEC_BIT_NUMBER: 0
POST_SCALING: 0.1
OFFSET: 0
PSC_AVG_LEN: 15
CPICH_AVG_LEN: 10
CPICH_SCRAMBLING_CODE: 640
SSC_MEAS_LEN: 2
ISYNC_SCRC_THRESHOLD: 4
#
END_OF_FILE
#
Appendix F
Source code files
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.5 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble10
The licenses for most software are designed to take away yourfreedom to share and change it. By contrast, the GNU General PublicLicense is intended to guarantee your freedom to share and change freesoftware−−to make sure the software is free for all its users. This
15 General Public License applies to most of the Free SoftwareFoundation’s software and to any other program whose authors commit tousing it. (Some other Free Software Foundation software is covered bythe GNU Library General Public License instead.) You can apply it toyour programs, too.
20
When we speak of free software, we are referring to freedom, notprice. Our General Public Licenses are designed to make sure that youhave the freedom to distribute copies of free software (and charge forthis service if you wish), that you receive source code or can get it
25 if you want it, that you can change the software or use pieces of itin new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbidanyone to deny you these rights or to ask you to surrender the rights.
30 These restrictions translate to certain responsibilities for you if youdistribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whethergratis or for a fee, you must give the recipients all the rights that
35 you have. You must make sure that they, too, receive or can get thesource code. And you must show them these terms so they know theirrights.
We protect your rights with two steps: (1) copyright the software, and40 (2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author’s protection and ours, we want to make certainthat everyone understands that there is no warranty for this free
45 software. If the software is modified by someone else and passed on, wewant its recipients to know that what they have is not the original, sothat any problems introduced by others will not reflect on the originalauthors’ reputations.
50 Finally, any free program is threatened constantly by softwarepatents. We wish to avoid the danger that redistributors of a freeprogram will individually obtain patent licenses, in effect making theprogram proprietary. To prevent this, we have made it clear that anypatent must be licensed for everyone’s free use or not licensed at all.
55
The precise terms and conditions for copying, distribution andmodification follow.
Page 1/6copying.txt GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which containsa notice placed by the copyright holder saying it may be distributedunder the terms of this General Public License. The "Program", below,
65 refers to any such program or work, and a "work based on the Program"means either the Program or any derivative work under copyright law:that is to say, a work containing the Program or a portion of it,either verbatim or with modifications and/or translated into anotherlanguage. (Hereinafter, translation is included without limitation in
70 the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are notcovered by this License; they are outside its scope. The act ofrunning the Program is not restricted, and the output from the Program
75 is covered only if its contents constitute a work based on theProgram (independent of having been made by running the Program).Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program’s80 source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriatecopyright notice and disclaimer of warranty; keep intact all thenotices that refer to this License and to the absence of any warranty;and give any other recipients of the Program a copy of this License
85 along with the Program.
You may charge a fee for the physical act of transferring a copy, andyou may at your option offer warranty protection in exchange for a fee.
90 2. You may modify your copy or copies of the Program or any portionof it, thus forming a work based on the Program, and copy anddistribute such modifications or work under the terms of Section 1above, provided that you also meet all of these conditions:
95 a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
Page 2/6copying.txt
These requirements apply to the modified work as a whole. If115 identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works inthemselves, then this License, and its terms, do not apply to thosesections when you distribute them as separate works. But when youdistribute the same sections as part of a whole which is a work based
120 on the Program, the distribution of the whole must be on the terms ofthis License, whose permissions for other licensees extend to theentire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest125 your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative orcollective works based on the Program.
In addition, mere aggregation of another work not based on the Program130 with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work underthe scope of this License.
3. You may copy and distribute the Program (or a work based on it,135 under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine−readable source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete
145 machine−readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer150 to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
155 The source code for a work means the preferred form of the work formaking modifications to it. For an executable work, complete sourcecode means all the source code for all modules it contains, plus anyassociated interface definition files, plus the scripts used tocontrol compilation and installation of the executable. However, as a
160 special exception, the source code distributed need not includeanything that is normally distributed (in either source or binaryform) with the major components (compiler, kernel, and so on) of theoperating system on which the executable runs, unless that componentitself accompanies the executable.
165
If distribution of executable or object code is made by offeringaccess to copy from a designated place, then offering equivalentaccess to copy the source code from the same place counts asdistribution of the source code, even though third parties are not
170 compelled to copy the source along with the object code.
Page 3/6copying.txt 4. You may not copy, modify, sublicense, or distribute the Programexcept as expressly provided under this License. Any attemptotherwise to copy, modify, sublicense or distribute the Program is
175 void, and will automatically terminate your rights under this License.However, parties who have received copies, or rights, from you underthis License will not have their licenses terminated so long as suchparties remain in full compliance.
180 5. You are not required to accept this License, since you have notsigned it. However, nothing else grants you permission to modify ordistribute the Program or its derivative works. These actions areprohibited by law if you do not accept this License. Therefore, bymodifying or distributing the Program (or any work based on the
185 Program), you indicate your acceptance of this License to do so, andall its terms and conditions for copying, distributing or modifyingthe Program or works based on it.
6. Each time you redistribute the Program (or any work based on the190 Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject tothese terms and conditions. You may not impose any furtherrestrictions on the recipients’ exercise of the rights granted herein.You are not responsible for enforcing compliance by third parties to
195 this License.
7. If, as a consequence of a court judgment or allegation of patentinfringement or for any other reason (not limited to patent issues),conditions are imposed on you (whether by court order, agreement or
200 otherwise) that contradict the conditions of this License, they do notexcuse you from the conditions of this License. If you cannotdistribute so as to satisfy simultaneously your obligations under thisLicense and any other pertinent obligations, then as a consequence youmay not distribute the Program at all. For example, if a patent
205 license would not permit royalty−free redistribution of the Program byall those who receive copies directly or indirectly through you, thenthe only way you could satisfy both it and this License would be torefrain entirely from distribution of the Program.
210 If any portion of this section is held invalid or unenforceable underany particular circumstance, the balance of the section is intended toapply and the section as a whole is intended to apply in othercircumstances.
215 It is not the purpose of this section to induce you to infringe anypatents or other property right claims or to contest validity of anysuch claims; this section has the sole purpose of protecting theintegrity of the free software distribution system, which isimplemented by public license practices. Many people have made
220 generous contributions to the wide range of software distributedthrough that system in reliance on consistent application of thatsystem; it is up to the author/donor to decide if he or she is willingto distribute software through any other system and a licensee cannotimpose that choice.
225
This section is intended to make thoroughly clear what is believed tobe a consequence of the rest of this License.
Page 4/6copying.txt
8. If the distribution and/or use of the Program is restricted in230 certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this Licensemay add an explicit geographical distribution limitation excludingthose countries, so that distribution is permitted only in or amongcountries not thus excluded. In such case, this License incorporates
235 the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versionsof the General Public License from time to time. Such new versions willbe similar in spirit to the present version, but may differ in detail to
240 address new problems or concerns.
Each version is given a distinguishing version number. If the Programspecifies a version number of this License which applies to it and "anylater version", you have the option of following the terms and conditions
245 either of that version or of any later version published by the FreeSoftware Foundation. If the Program does not specify a version number ofthis License, you may choose any version ever published by the Free SoftwareFoundation.
250 10. If you wish to incorporate parts of the Program into other freeprograms whose distribution conditions are different, write to the authorto ask for permission. For software which is copyrighted by the FreeSoftware Foundation, write to the Free Software Foundation; we sometimesmake exceptions for this. Our decision will be guided by the two goals
255 of preserving the free status of all derivatives of our free software andof promoting the sharing and reuse of software generally.
NO WARRANTY
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTYFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIESPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSEDOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK ASTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THEPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,REPAIR OR CORRECTION.
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/ORREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISINGOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BYYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHERPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THEPOSSIBILITY OF SUCH DAMAGES.
280 END OF TERMS AND CONDITIONS
Page 5/6copying.txt How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest285 possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safestto attach them to the start of each source file to most effectively
290 convey the exclusion of warranty; and each file should have at leastthe "copyright" line and a pointer to where the full notice is found.
<one line to give the program’s name and a brief idea of what it does.> Copyright (C) <year> <name of author>
295
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
300
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
305
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA
310
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like thiswhen it starts in an interactive mode:
315
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistribute it under certain conditions; type ‘show c’ for details.
320
The hypothetical commands ‘show w’ and ‘show c’ should show the appropriateparts of the General Public License. Of course, the commands you use maybe called something other than ‘show w’ and ‘show c’; they could even bemouse−clicks or menu items−−whatever suits your program.
325
You should also get your employer (if you work as a programmer) or yourschool, if any, to sign a "copyright disclaimer" for the program, ifnecessary. Here is a sample; alter the names:
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program ‘Gnomovision’ (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice
335
This General Public License does not permit incorporating your program intoproprietary programs. If your program is a subroutine library, you mayconsider it more useful to permit linking proprietary applications with thelibrary. If this is what you want to do, use the GNU Library General
340 Public License instead of this License.
Page 6/6copying.txt
/*
Title: Configuration file reading utility for channel model Kalle Tuulos’ M.Sc. Thesis Work
5 File name: chan_conf.c
$Date: 2002−01−14 15:01:29+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/7chan_conf.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <string.h>#include <malloc.h>
35 #include <math.h>
#include "typedef.h" /* This has to be the first one */#include "chan_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */
40
#include "chan_conf.h"
const char * conf_keyword[] ={
45 "", "OVERSAMPLING", "NOISE_PWR", "MPATH_NUMBER", "MPATH_NUMBER",
50 "MPATH_DELAY", "MPATH_GAIN", "MPATH_PHASE", "END_OF_FILE", ""
55 };
static uint16 store_chan_val(FILE * input_file, CHANPROF_CFG_T * cfg, CONF_ITEMS keyword, uint16 * current_line);
60 static uint16 store_tap_val(FILE * input_file, TAP_PROPS_T * tap, CONF_ITEMS keyword, uint16 * current_line, fl32 samples_in_nanosecond);
static uint16 fetch_tap_vals(FILE * input_file, TAP_PROPS_T * tap,65 uint16 oversampling, uint32 * max_delay,
uint16 * current_line);
uint16 chan_conf_read(FILE * conf_file, CHANPROF_CFG_T * cfg, uint16 * current_line)
70 { uint16 mpath; /* First read common settings */ *current_line = 0;
Page 2/7chan_conf.c
75 /* Oversampling factor */ if (store_chan_val(conf_file, cfg, CONF_OVERSAMPLING, current_line) != SUCCESS) {
80 return(FAIL); }
/* Noise power */ if (store_chan_val(conf_file, cfg, CONF_NOISE_PWR, current_line)
85 != SUCCESS) { return(FAIL); }
90 /* Multipath amount */ if (store_chan_val(conf_file, cfg, CONF_MPATH_NUMBER_TX1, current_line) != SUCCESS) { return(FAIL);
95 }
/* Allocate memory for multipaths in TX antenna 1 */ cfg−>tx1 = malloc( sizeof(TAP_PROPS_T) * cfg−>tx1_taps); if (cfg−>tx1 == NULL)
100 { return(FAIL); }
/* Clear the maximum delay value in cfg structure */105 cfg−>max_delay = 0;
/* Next read multipaths for TX antenna 1 */ for (mpath = 0; mpath < cfg−>tx1_taps; mpath++) {
110 if (fetch_tap_vals(conf_file, &(cfg−>tx1[mpath]), cfg−>oversampling, &(cfg−>max_delay), current_line) != SUCCESS) { return(FAIL); }
115 } /* for (mpath ...) */
if (cfg−>tx2_active == TRUE) { /* TX2 antenna is active − read also its taps */
120
/* Multipath amount */ if (store_chan_val(conf_file, cfg, CONF_MPATH_NUMBER_TX2, current_line) != SUCCESS) {
125 return(FAIL); }
/* Allocate memory for multipaths in TX antenna 2 */ cfg−>tx2 = malloc( sizeof(TAP_PROPS_T) * cfg−>tx2_taps);
130 if (cfg−>tx2 == NULL) { return(FAIL); }
Page 3/7chan_conf.c135 /* Next read multipaths for TX antenna 2 */
for (mpath = 0; mpath < cfg−>tx2_taps; mpath++) { if (fetch_tap_vals(conf_file, &(cfg−>tx2[mpath]), cfg−>oversampling, &(cfg−>max_delay), current_line) != SUCCESS)
140 { return(FAIL); } } /* for (mpath ...) */ } /* if (tx2 antenna active) */
145 debug_print("Configuration file read OK.\n", DEBUG_PRINT); /* Return success */ return(SUCCESS);
150 }
static uint16 store_chan_val( FILE * input_file, CHANPROF_CFG_T * cfg, CONF_ITEMS keyword, uint16 * current_line){
155 uint32 temp_value; fl32 temp_float; char * value_ptr; char conf_line[100];
160 value_ptr = fetch_val_from_file(input_file, keyword, conf_keyword, current_line, &conf_line[0]);
if (value_ptr == NULL) {
165 return(FAIL); } switch(keyword) {
170 case CONF_OVERSAMPLING: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value > 0) && (temp_value <= MAX_OVERSAMPLING) ) { cfg−>oversampling = temp_value;
175 } else { return(FAIL); }
180 break;
case CONF_NOISE_PWR: sscanf(value_ptr, "%f", &temp_float); if ( (temp_float >= MIN_NOISE_GAIN) &&
185 (temp_float <= MAX_NOISE_GAIN) ) { /* First decrement 3 dB */ temp_float −= 3;
190 /* Convert decibel value to linear and perform square root */ cfg−>noise_deviation = sqrt(db2lin(temp_float)); } else {
Page 4/7chan_conf.c
195 return(FAIL); } break;
case CONF_MPATH_NUMBER_TX1:200 sscanf(value_ptr, "%u", &temp_value);
if ( (temp_value > 0) && (temp_value <= MAX_MPATH_NUMBER) ) { cfg−>tx1_taps = temp_value; }
205 else { return(FAIL); } break;
210 case CONF_MPATH_NUMBER_TX2: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value > 0) && (temp_value <= MAX_MPATH_NUMBER) ) {
215 cfg−>tx2_taps = temp_value; } else { return(FAIL);
220 } break; default: /* Illegal case! */
225 return(FAIL); break; } /* switch(keyword) */
return(SUCCESS);230 }
uint16 store_tap_val( FILE * input_file, TAP_PROPS_T * tap, CONF_ITEMS keyword, uint16 * current_line, fl32 samples_in_nanosecond)
235 { fl32 temp_float; char * value_ptr; char conf_line[100];
240 value_ptr = fetch_val_from_file(input_file, keyword, conf_keyword, current_line, &conf_line[0]);
if (value_ptr == NULL) {
245 return(FAIL); }
sscanf(value_ptr, "%f", &temp_float);
250 switch(keyword) { case CONF_MPATH_DELAY: if ( (temp_float >= 0) && (temp_float <= MAX_MPATH_DELAY) ) {
Page 5/7chan_conf.c255 tap−>delay =
( uint32)floor(temp_float * samples_in_nanosecond + 0.5); } else {
260 return(FAIL); } break; case CONF_MPATH_GAIN:
265 if ( (temp_float >= MIN_MPATH_GAIN) && (temp_float <= MAX_MPATH_GAIN) ) { tap−>gain = db2lin(temp_float); }
270 else { return(FAIL); } break;
275 case CONF_MPATH_PHASE: if ( (temp_float >= MIN_MPATH_PHASE) && (temp_float <= MAX_MPATH_PHASE) ) {
280 tap−>phase = degree_to_radian(temp_float); } else { return(FAIL);
285 } break; default: /* This is illegal case. */
290 return(FAIL); break; } /* switch */ return(SUCCESS);
295 }
static uint16 fetch_tap_vals( FILE * input_file, TAP_PROPS_T * tap, uint16 oversampling, uint32 * max_delay, uint16 * current_line)
300 { fl32 samples_in_nanosecond;
samples_in_nanosecond = ( fl32)oversampling * CHIPS_IN_NANOSECOND;
305 if (store_tap_val(input_file, tap, CONF_MPATH_DELAY, current_line, samples_in_nanosecond) != SUCCESS) { return(FAIL); }
310
if (store_tap_val(input_file, tap, CONF_MPATH_GAIN, current_line, samples_in_nanosecond) != SUCCESS) { return(FAIL);
Page 6/7chan_conf.c
315 }
if (store_tap_val(input_file, tap, CONF_MPATH_PHASE, current_line, samples_in_nanosecond) != SUCCESS) {
320 return(FAIL); } /* Next update maximum delay value */ if (*(max_delay) < tap−>delay)
325 { *(max_delay) = tap−>delay; } return(SUCCESS);
330 }
/* End of file. */
Page 7/7chan_conf.c
/*
Title: Configuration file reading utility for channel model Header file
5 Kalle Tuulos’ M.Sc. Thesis Work File name: chan_conf.h
$Date: 2002−01−14 15:01:28+02 $10
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/15
Page 1/3chan_conf.h/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify20 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful,25 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License30 along with 3WTG; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Maximum oversampling factor */35 #define MAX_OVERSAMPLING 16
/* Minimum and maximum noise power level in decibels */#define MIN_NOISE_GAIN −64.0#define MAX_NOISE_GAIN 20.0
40
/* Multipath limits */
/* Maximum amount of multipaths */#define MAX_MPATH_NUMBER 64
45
/* Maximum delay in nanoseconds. Currently this is set to duration of one CPICH symbol. */#define MAX_MPATH_DELAY 66666
50 /* Minimum and maximum gain in decibels */#define MIN_MPATH_GAIN −64.0#define MAX_MPATH_GAIN 20.0
/* Minimum and maximun phase rotation factors in degrees */55 #define MIN_MPATH_PHASE −180.0
#define MAX_MPATH_PHASE 180.0
typedef struct{
60 uint32 delay; fl32 gain; fl32 phase;}TAP_PROPS_T;
65
typedef struct{ uint16 oversampling; fl32 noise_deviation;
70
char conf_file_name[FILENAME_LENGTH];
uint32 max_delay;
75 char tx1_input_file_name[FILENAME_LENGTH];
Page 2/3chan_conf.h
uint32 tx1_taps; TAP_PROPS_T * tx1;
uint16 tx2_active;80
char tx2_input_file_name[FILENAME_LENGTH]; uint32 tx2_taps; TAP_PROPS_T * tx2;
85 char output_file_name[FILENAME_LENGTH];}CHANPROF_CFG_T;
uint16 chan_conf_read(FILE * conf_file, CHANPROF_CFG_T * gen_conf,90 uint16 * line_number);
/* End of file. */
Page 3/3chan_conf.h
/*
Title: Configuration file keywords for data generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_conf_keywords.h
$Date: 2002−01−14 15:01:27+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2chan_conf_keywords.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef GEN_CONF_KEYWORDS_H#define GEN_CONF_KEYWORDS_H
35
typedef enum{ CONF_FIRST_ITEM, CONF_OVERSAMPLING,
40 CONF_NOISE_PWR, CONF_MPATH_NUMBER_TX1, CONF_MPATH_NUMBER_TX2, CONF_MPATH_DELAY, CONF_MPATH_GAIN,
45 CONF_MPATH_PHASE, CONF_END_OF_FILE, CONF_LAST_ITEM}CONF_ITEMS;
50
#endif/* End of file */
Page 2/2chan_conf_keywords.h
/*
Title: Channel model Kalle Tuulos’ M.Sc. Thesis Work
5 File name: chan_mod.c
$Date: 2002−01−14 15:01:26+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/9chan_mod.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <stdio.h>#include <malloc.h>
35 #include <time.h>#include <math.h>
#include "typedef.h" /* This has to be the first one */#include "chan_conf_keywords.h" /* This has to be second */
40 #include "global.h" /* This has to be third */
#include "chan_conf.h"#include "gauss_rand.h"
45 #define DELAYLINE_MAX_LENGTH_IN_CHIPS 256
typedef struct{ COMPLEX_FLOAT sample;
50 COMPLEX_FLOAT coeff;}SAMPLE_AND_COEFFICIENT_T;
typedef struct55 {
uint16 length; SAMPLE_AND_COEFFICIENT_T * tx1; SAMPLE_AND_COEFFICIENT_T * tx2;}
60 DELAYLINE;
int main(int argc, char * argv[]);uint16 read_cfgfile(FILE * conf_file, CHANPROF_CFG_T * cfg);uint16 init_delayline(const CHANPROF_CFG_T * cfg, DELAYLINE * delayline);
65 uint16 apply_chanprof(FILE * input_tx1, FILE * input_tx2, FILE * output, const CHANPROF_CFG_T * cfg, DELAYLINE * delayline);uint16 deallocate_delayline(uint16 tx2_active, DELAYLINE * delayline);void chan_usage(const char * file_name);
70 int main(int argc, char * argv[]){ uint16 return_status = SUCCESS; uint16 line_number; uint16 show_license = FALSE;
Page 2/9chan_mod.c
75
FILE * conf_file; FILE * input_tx1; FILE * input_tx2; FILE * output;
80
CHANPROF_CFG_T cfg; DELAYLINE delayline;
debug_value = ERROR_PRINT;85
/* Handle command line arguments */ switch(argc) { case 2:
90 /* Did user ask for license? */ if (strcmp(argv[1], "−license") == 0) { show_license = TRUE; }
95 else { return_status = FALSE; } break;
100 case 4: /* One TX antenna used */ cfg.tx2_active = FALSE; break;
105 case 5: /* Two TX antennas used */ cfg.tx2_active = TRUE;
110 /* Copy fourth parameter as TX2 antenna source data file name */ return_status = copy_filename(argv[4], cfg.tx2_input_file_name); break; default:
115 /* Illegal amount of parameters. Just print usage information. */ return_status = FALSE; /* break */ } /* switch(argc) */
120 /* Print copyright information etc stuff */ print_header(CHANMOD, show_license);
if (show_license) {
125 exit(EXIT_WITH_FAILURE); } else if (return_status != SUCCESS) { chan_usage(argv[0]);
130 exit(EXIT_WITH_FAILURE); } /* Copy first parameter as configuration file name */ return_status = copy_filename(argv[1], cfg.conf_file_name);
Page 3/9chan_mod.c135 if (return_status != SUCCESS)
{ /* Failure copying file name! */ printf("Problems with the first parameter!\n"); printf("Please see user’s instructions.\n");
140 exit(EXIT_WITH_FAILURE); }
/* Copy second parameter as output file name */ return_status = copy_filename(argv[2], cfg.output_file_name);
145 if (return_status != SUCCESS) { /* Failure copying file name! */ printf("Problems with the second parameter!\n"); printf("Please see user’s instructions.\n");
150 exit(EXIT_WITH_FAILURE); } /* Copy third parameter as TX1 antenna source data file name */ return_status = copy_filename(argv[3], cfg.tx1_input_file_name);
155 if (return_status != SUCCESS) { /* Failure copying file name! */ printf("Problems with the third parameter!\n"); printf("Please see user’s instructions.\n");
160 exit(EXIT_WITH_FAILURE); }
conf_file = fopen(cfg.conf_file_name, "r"); if (conf_file == NULL)
165 { printf("Did not succeed in opening configuration file!\n"); exit(EXIT_WITH_FAILURE); }
170 /* Read channel profile configuration file */ return_status = chan_conf_read(conf_file, &cfg, &line_number); if (return_status != SUCCESS) { printf("Error reading configuration file at line %d\n",
175 line_number); exit(EXIT_WITH_FAILURE); }
/* Close configuration file */180 fclose(conf_file);
printf("Initialize channel profile\n"); /* Initialize channel profile */
185 init_delayline(&cfg, &delayline);
/* Initialize random number generator */ rand_init(time( NULL));
190 /* Open input and output files */ input_tx1 = fopen(cfg.tx1_input_file_name, "r"); if (input_tx1 == NULL) { printf("Did not succeed in opening TX1 antenna source data file!\n");
Page 4/9chan_mod.c
195 exit(EXIT_WITH_FAILURE); } output = fopen(cfg.output_file_name, "w"); if (output == NULL)
200 { printf("Did not succeed in creating output file!\n"); exit(EXIT_WITH_FAILURE); }
205 if (cfg.tx2_active == TRUE) { input_tx2 = fopen(cfg.tx2_input_file_name, "r"); if (input_tx2 == NULL) {
210 printf("Did not succeed in opening TX2 antenna source data file!\n"); exit(EXIT_WITH_FAILURE); } } else
215 { input_tx2 = NULL; }
printf("Start apply channel profile to data\n");220
/* Apply channel profile to data */ return_status = apply_chanprof(input_tx1, input_tx2, output, &cfg, &delayline); if (return_status != SUCCESS)
225 { printf("Failure in applying channel profile!\n"); exit(EXIT_WITH_FAILURE); }
230 /* Finally, release allocated memories */ return_status = deallocate_delayline(cfg.tx2_active, &delayline);
if (return_status != SUCCESS) {
235 printf("Failure in de−allocating channel profile delay line!\n"); exit(EXIT_WITH_FAILURE); }
exit(EXIT_WITH_SUCCESS);240 }
uint16 init_delayline( const CHANPROF_CFG_T * cfg, DELAYLINE * delayline){
245 uint32 pos; uint32 coeff_pos; SAMPLE_AND_COEFFICIENT_T * dline_ptr; /* Calculate delay line length. */
250 delayline−>length = (cfg−>max_delay + 1); /* First, allocate memories */ delayline−>tx1 = malloc( sizeof(SAMPLE_AND_COEFFICIENT_T) * delayline−>length);
Page 5/9chan_mod.c255 if (delayline−>tx1 == NULL)
{ return(FAIL); }
260 dline_ptr = delayline−>tx1;
printf("Clear delay line\n");
265 /* Clear delay line samples and coefficients */ for (pos = 0; pos < delayline−>length; pos++) { complex_zero(&(dline_ptr[pos].sample)); complex_zero(&(dline_ptr[pos].coeff));
270 }
printf("Calculate TX1 coefficients\n");
275 /* Calculate coefficients for TX1 delay line */ for (coeff_pos = 0; coeff_pos < cfg−>tx1_taps; coeff_pos++) { pos = cfg−>tx1[coeff_pos].delay; delayline−>tx1[pos].coeff.i =
280 cfg−>tx1[coeff_pos].gain * cos(cfg−>tx1[coeff_pos].phase); delayline−>tx1[pos].coeff.q = cfg−>tx1[coeff_pos].gain * sin(cfg−>tx1[coeff_pos].phase); }
285 printf("Free TX1 tap list memory...\n"); /* Free TX1 tap list memory from cfg structure */ free(cfg−>tx1);
290
printf("done!\n"); if (cfg−>tx2_active == TRUE)
295 { /* Allocate memories */ delayline−>tx2 = malloc( sizeof(SAMPLE_AND_COEFFICIENT_T) * delayline−>length);
300 if (delayline−>tx2 == NULL) { return(FAIL); }
305 /* Clear delay line samples and coefficients */ for (pos = 0; pos < delayline−>length; pos++) { complex_zero(&(delayline−>tx2[pos].sample)); complex_zero(&(delayline−>tx2[pos].coeff));
310 } /* Calculate coefficients for TX2 delay line */ for (coeff_pos = 0; coeff_pos < cfg−>tx2_taps; coeff_pos++) {
Page 6/9chan_mod.c
315 pos = cfg−>tx2[coeff_pos].delay;
dline_ptr = &(delayline−>tx2[pos]); dline_ptr−>coeff.i =
320 cfg−>tx2[coeff_pos].gain * cos(cfg−>tx2[coeff_pos].phase); dline_ptr−>coeff.q = cfg−>tx2[coeff_pos].gain * sin(cfg−>tx2[coeff_pos].phase); }
325 /* Free TX2 tap list memory from cfg structure */ free(cfg−>tx2); }
printf("Return\n");330
return (SUCCESS);}
335 uint16 apply_chanprof( FILE * input_tx1, FILE * input_tx2, FILE * output, const CHANPROF_CFG_T * cfg, DELAYLINE * delayline){ uint16 return_status; uint16 pos;
340 COMPLEX_FLOAT noise_sample; COMPLEX_FLOAT output_sample; /* Start processing */ for (;;)
345 { /* Clear output sample */ complex_zero(&output_sample); /* Read new sample from input file */
350 return_status = read_from_file(input_tx1, &(delayline−>tx1[0].sample)); if (return_status != SUCCESS) { /* End of file reached */ break;
355 }
/* Multiply first sample by coefficient and add result to output */ complex_product_and_add(delayline−>tx1[0].sample, delayline−>tx1[0].coeff,
360 &output_sample);
/* Go through delay line */ for (pos = delayline−>length − 1; pos > 0; pos−−) {
365 /* Multiply sample by coefficient and add result to output */ complex_product_and_add(delayline−>tx1[pos].sample, delayline−>tx1[pos].coeff, &output_sample);
370 /* Shift samples */ delayline−>tx1[pos].sample = delayline−>tx1[pos−1].sample; }
/* Perform same tricks for TX2 also if needed */
Page 7/9chan_mod.c375 if (cfg−>tx2_active == TRUE)
{ /* Read new sample from input file */ return_status = read_from_file(input_tx2, &(delayline−>tx2[0].sample));
380 if (return_status != SUCCESS) { /* End of file reached */ break; }
385
/* Multiply first sample by coefficient and add result to output */ complex_product_and_add(delayline−>tx2[0].sample, delayline−>tx2[0].coeff, &output_sample);
390
/* Go through delay line */ for (pos = delayline−>length − 1; pos > 0; pos−−) { /* Multiply sample by coefficient and add result to output */
395 complex_product_and_add(delayline−>tx2[pos].sample, delayline−>tx2[pos].coeff, &output_sample); /* Shift samples */
400 delayline−>tx2[pos].sample = delayline−>tx2[pos−1].sample; }
}
405 /* Add noise to output sample */ noise_sample = gauss_random(cfg−>noise_deviation); complex_add(&output_sample, noise_sample); /* Write result to output file */
410 write_to_file(output, output_sample); /* All done, process next samples in delay line */ }
415 return (SUCCESS);}
uint16 deallocate_delayline( uint16 tx2_active, DELAYLINE * delayline){
420 free(delayline−>tx1);
if (tx2_active == TRUE) { free(delayline−>tx2);
425 } return (SUCCESS);}
430 void chan_usage( const char * file_name){ printf("Command line usage:\n"); printf("−−−−−−−−−−−−−−−−−−−\n\n"); printf(file_name);
Page 8/9chan_mod.c
435 printf(" <channel_profile_file> <output_file> <tx1_input_file>\n"); printf("\t\t[tx2_input_file]\n\nwhere:\n"); printf(" − <channel_profile_file> is the channel profile definition "); printf("file\n"); printf(" − <output_file> is the result file name\n");
440 printf(" − <tx1_input_file> is the input file name for TX antenna 1\n"); printf(" − [tx2_input_file] is the input file name for TX antenna 2\n\n"); printf("All other parameters except [tx2_input_file] are mandatory.\n");}
445 /* End of file. */
Page 9/9chan_mod.c
/*
Title: Gaussian random I/Q sample generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gauss_rand.c
$Date: 2002−01−14 15:01:24+02 $
10 Author: Kalle Tuulos
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
15 */
Page 1/4gauss_rand.c/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
20 3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
25 3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
35 #include <math.h>#include <stdlib.h>
#include "typedef.h" /* This has to be the first one */
40 /* Following dummy type definition is needed, because in global.h one function needs that */typedef enum{ CONF_FIRST_ITEM,
45 CONF_LAST_ITEM}CONF_ITEMS;
#include "global.h" /* This has to be second */50
static fl64 norm_rand();
/* Following function generates random gaussian complex numbers with
55 required AMPLITUDE deviation e.g. if deviation == 1, deviation of i and q are sqrt(2) / 2. Function uses Box−Muller transformation of two uniform random numbers to generate two independent gaussian random numbers.
60 */COMPLEX_FLOAT gauss_random(fl32 deviation){ fl64 rand_x; fl64 rand_y;
65 fl64 radius; fl64 factor; COMPLEX_FLOAT ret_val; static COMPLEX_FLOAT stored_val; static uint16 stored_val_exists = 0;
70
if (stored_val_exists) { /* Just return stored random values */ ret_val = stored_val;
75 /* Stored value does not exist any more */
Page 2/4gauss_rand.c
stored_val_exists = 0; } else
80 { /* Generate new random values */
/* First, values for I */ do
85 { /* Fetch two random numbers in range [−1, 1] */ rand_x = norm_rand(); rand_y = norm_rand();
90 radius = rand_x * rand_x + rand_y * rand_y; } while (radius >= 1.0); /* Radius should be less than 1 */
factor = sqrt((−2.0 * log(radius))/radius);95 factor *= 2 * deviation / sqrt(2);
ret_val.i = rand_x * factor; stored_val.i = rand_y * factor;
100 /* Then, generate values for Q */ do { /* Fetch two random numbers in range [−1, 1] */ rand_x = norm_rand();
105 rand_y = norm_rand(); radius = rand_x * rand_x + rand_y * rand_y; } while (radius >= 1.0); /* Radius should be less than 1 */
110
factor = sqrt((−2.0 * log(radius))/radius); factor *= 2 * deviation / sqrt(2); ret_val.q = rand_x * factor;
115 stored_val.q = rand_y * factor;
/* Stored values exist */ stored_val_exists = TRUE; }
120
return(ret_val);}
/*125 Following function returns a random number in range [−1, 1].
If rand() does not produce good enough random numbers, it can be replaced with any other random number generator. */fl64 norm_rand()
130 { fl64 rand_val;
/* Fetch a random number and scale it to range [0, 1] */ rand_val = ( fl64 )rand() / ( fl64 )RAND_MAX;
135
/* Scale range to [0,2] */
Page 3/4gauss_rand.c rand_val *= 2;
/* Change range to [−1, 1] */140 rand_val −= 1;
return(rand_val);}
145 /* Following function initializes random number generator.*/void rand_init( uint32 seed){
150 srand(seed);}
/* End of file. */
Page 4/4gauss_rand.c
/*
Title: Gaussian random I/Q sample generator, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gauss_rand.h
$Date: 2002−01−14 15:01:22+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gauss_rand.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Following function returns complex random gaussian number with required AMPLITUDE deviation i.e. if deviation == 1,
35 deviation of i and q are sqrt(2) / 2. */COMPLEX_FLOAT gauss_random(fl32 deviation);
/* Function to initialize random number generator. Seed is any unsigned integer. */
40 void rand_init(uint32 seed);
/* End of file. */
Page 2/2gauss_rand.h
/*
Title: Common definitions for data generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_common.h
$Date: 2002−01−14 15:01:22+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/3gen_common.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef GEN_COMMON_H#define GEN_COMMON_H
35
#ifndef TYPEDEF_H#error "typedef.h must be included before including this file!"#endif
40 /* Data generator limitations */#define MAX_NUMBER_OF_BS 4#define MAX_NUMBER_OF_FRAMES 4000#define MAX_OVERSAMPLING 16#define MIN_GAIN −64
45 #define MAX_GAIN 20#define MAX_CHIP_FILTER_LEN 64
/* Default configuration file name */#define DEFAULT_CONF_FILE_NAME "datagen.cfg"
50
/* Base station specific settings */typedef struct{ uint16 scrambling_code; /* 0, 16, 32, ... 8176 */
55 uint16 scrambling_code_group; /* 0, 1, 2, ... 63 */ uint16 start_sfn; /* 0, 1, 2, ... 4095 */ uint16 start_chip; /* 0, 1, 2, ... 38399 */ uint16 sttd_active; /* TRUE / FALSE */ uint16 tstd_active; /* TRUE / FALSE */
60 fl32 gain_bs; /* > 0 */ fl32 gain_p_sch; /* >= 0 */ fl32 gain_s_sch; /* >= 0 */ uint16 cpich_amount; /* 1, 2, ... 16 */ fl32 gain_cpich[CPICH_NUMBER];
65 uint16 cpich_s_scr_code[CPICH_NUMBER]; uint16 cpich_chan_code_nr[CPICH_NUMBER];}BS_CONF_T;
70 /* Whole data generator specific settings */typedef struct{ uint16 amount_of_frames; /* 1, 2, ... MAX_NUMBER_OF_FRAMES */ uint16 oversampling; /* 1, 2, ... MAX_OVERSAMPLING */
Page 2/3gen_common.h
75 uint16 chip_filtering; /* TRUE / FALSE */ uint16 chip_filter_length; /* 1, 2, ... MAX_FILTER_LENGTH */ char conf_file_name[FILENAME_LENGTH]; /* Configuration file name */ char tx1_output_file_name[FILENAME_LENGTH]; /* Output file name */
80 char tx2_output_file_name[FILENAME_LENGTH]; /* Output file name */ uint16 amount_of_bs; /* 1, 2, ... MAX_NUMBER_OF_BS */ BS_CONF_T bs[MAX_NUMBER_OF_BS];}
85 GEN_CONF_T;
#define add_sequence_to_complex(_cplx_, _seq_, _gain_) \{ \ (*_cplx_).i += (_gain_) * (_seq_); \
90 (*_cplx_).q += (_gain_) * (_seq_); \}
#endif95 /* End of file */
Page 3/3gen_common.h
/*
Title: Configuration file reading utility for channel generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_conf.h
$Date: 2002−01−14 15:01:21+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/10gen_conf.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <string.h>
35 #include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
40 #include "gen_conf.h"
/* These must match to keywords in gen_conf_keywords.h */const char * conf_keyword[] ={
45 "", "BS_NUMBER", "FRAME_NUMBER", "OVERSAMPLING", "CHIP_FILTERING",
50 "CHIP_FILTER_LEN", "VERBOSITY", "SCRAMBLING_CODE", "START_SFN", "BS_OFFSET",
55 "STTD", "TSTD", "GAIN_BS", "GAIN_P_SCH", "GAIN_S_SCH",
60 "GAIN_P_CPICH", "S_CPICH_NUMBER", "SECONDARY_CODE", "CHAN_CODE", "GAIN_S_CPICH",
65 "OFF", "ON", "END_OF_FILE", ""};
70
/* Local function prototypes */static uint16 store_gen_val(FILE * input_file, GEN_CONF_T * gen_conf, CONF_ITEMS keyword, uint16 * current_line);
Page 2/10gen_conf.c
75 static uint16 store_bs_val( FILE * input_file, BS_CONF_T * bs_conf, CONF_ITEMS keyword, uint16 * current_line, uint16 s_cpich_nr);
uint16 gen_conf_read(GEN_CONF_T * gen_conf, uint16 * current_line)80 {
FILE * conf_file; uint16 bs; uint16 secondary_cpich;
85 printf("Using configuration file: "); printf(gen_conf−>conf_file_name); printf("\n\n"); conf_file = fopen(gen_conf−>conf_file_name, "r");
90 if (conf_file == NULL) { debug_print("Error opening configuration file!\n", ERROR_PRINT); exit(EXIT_WITH_FAILURE); }
95
*current_line = 0; /* First read system−wide settings */ /* Amount of base stations */
100 if (store_gen_val(conf_file, gen_conf, CONF_BS_NUMBER, current_line) != SUCCESS) { return(FAIL); }
105
if (store_gen_val(conf_file, gen_conf, CONF_FRAME_NUMBER, current_line) != SUCCESS) { return(FAIL);
110 }
if (store_gen_val(conf_file, gen_conf, CONF_OVERSAMPLING, current_line) != SUCCESS) {
115 return(FAIL); }
if (store_gen_val(conf_file, gen_conf, CONF_CHIP_FILTERING, current_line) != SUCCESS)
120 { return(FAIL); }
if (store_gen_val(conf_file, gen_conf, CONF_CHIP_FILTER_LEN, current_line)125 != SUCCESS)
{ return(FAIL); }
130 if (store_gen_val(conf_file, gen_conf, CONF_VERBOSITY, current_line) != SUCCESS) { return(FAIL); }
Page 3/10gen_conf.c135
/* Then read base station specific settings */ for (bs = 0; bs < gen_conf−>amount_of_bs; bs++) { if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_SCRAMBLING_CODE,
140 current_line, 0) != SUCCESS) { return(FAIL); }
145 if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_START_SFN, current_line, 0) != SUCCESS) { return(FAIL); }
150
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_BS_OFFSET, current_line, 0) != SUCCESS) { return(FAIL);
155 }
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_STTD, current_line, 0) != SUCCESS) {
160 return(FAIL); }
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_TSTD, current_line, 0) != SUCCESS)
165 { return(FAIL); }
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_GAIN_BS,170 current_line, 0) != SUCCESS)
{ return(FAIL); }
175 if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_GAIN_P_SCH, current_line, 0) != SUCCESS) { return(FAIL); }
180
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_GAIN_S_SCH, current_line, 0) != SUCCESS) { return(FAIL);
185 }
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_GAIN_P_CPICH, current_line, 0) != SUCCESS) {
190 return(FAIL); }
if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_S_CPICH_NUMBER, current_line, 0) != SUCCESS)
Page 4/10gen_conf.c
195 { return(FAIL); }
for (secondary_cpich = 1;200 secondary_cpich < gen_conf−>bs[bs].cpich_amount;
secondary_cpich++) { if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_SECONDARY_CODE, current_line, secondary_cpich) != SUCCESS)
205 { return(FAIL); } if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_CHAN_CODE,
210 current_line, secondary_cpich) != SUCCESS) { return(FAIL); }
215 if (store_bs_val(conf_file, &(gen_conf−>bs[bs]), CONF_GAIN_S_CPICH, current_line, secondary_cpich) != SUCCESS) { return(FAIL); }
220 } /* for (secondary_cpich ...) */ } /* for (bs ...) */ debug_print("Configuration file read OK.\n", DEBUG_PRINT);
225 /* Return success */ return(SUCCESS);}
uint16 store_gen_val( FILE * input_file, GEN_CONF_T * gen_conf,230 CONF_ITEMS keyword, uint16 * current_line)
{ uint32 temp_value; char * value_ptr; char conf_line[100];
235
value_ptr = fetch_val_from_file(input_file, keyword, conf_keyword, current_line, &conf_line[0]);
if (value_ptr == NULL)240 {
return(FAIL); } switch(keyword)
245 { case CONF_BS_NUMBER: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value > 0) && (temp_value <= MAX_NUMBER_OF_BS) ) {
250 gen_conf−>amount_of_bs = temp_value; } else { return(FAIL);
Page 5/10gen_conf.c255 }
break;
case CONF_FRAME_NUMBER: sscanf(value_ptr, "%u", &temp_value);
260 if ( (temp_value > 0) && (temp_value <= MAX_NUMBER_OF_FRAMES) ) { gen_conf−>amount_of_frames = temp_value; } else
265 { return(FAIL); } break;
270 case CONF_OVERSAMPLING: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value > 0) && (temp_value <= MAX_OVERSAMPLING) ) { gen_conf−>oversampling = temp_value;
275 } else { return(FAIL); }
280 break;
case CONF_CHIP_FILTERING: /* values are ON or OFF */ if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ N’) )
285 { gen_conf−>chip_filtering = TRUE; } else if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ F’) && (value_ptr[2] == ’ F’) )
290 { gen_conf−>chip_filtering = FALSE; } else {
295 return(FAIL); } break;
case CONF_CHIP_FILTER_LEN:300 sscanf(value_ptr, "%u", &temp_value);
if ( (temp_value > 0) && (temp_value <= MAX_CHIP_FILTER_LEN) ) { gen_conf−>chip_filter_length = temp_value; }
305 else { return(FAIL); } break;
310 case CONF_VERBOSITY: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value > 0) && (temp_value <= 2) ) {
Page 6/10gen_conf.c
315 debug_value = temp_value; } else { return(FAIL);
320 } break; default: /* Illegal case! */
325 return(FAIL); break; } /* switch(keyword) */
return(SUCCESS);330 }
uint16 store_bs_val( FILE * input_file, BS_CONF_T * bs_conf, CONF_ITEMS keyword, uint16 * current_line, uint16 s_cpich_nr)
335 { uint32 temp_value; fl32 temp_float; char * value_ptr; char conf_line[100];
340
value_ptr = fetch_val_from_file(input_file, keyword, conf_keyword, current_line, &conf_line[0]);
if (value_ptr == NULL)345 {
return(FAIL); } switch(keyword)
350 { case CONF_SCRAMBLING_CODE: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value <= MAX_PRI_SCRAMBLING_CODE_NR) && /* Verify, that this code is primary code */
355 (temp_value % MAX_SEC_SCRAMBLING_CODE == 0)) { bs_conf−>scrambling_code = temp_value; bs_conf−>scrambling_code_group = temp_value / SCRAMBLING_CODES_PER_GROUP;
360 } else { return(FAIL); }
365 break;
case CONF_START_SFN: sscanf(value_ptr, "%u", &temp_value); if ( temp_value < MAX_SFN )
370 { bs_conf−>start_sfn = temp_value; } else {
Page 7/10gen_conf.c375 return(FAIL);
} break;
case CONF_BS_OFFSET:380 sscanf(value_ptr, "%u", &temp_value);
if ( temp_value < CHIPS_IN_FRAME ) { bs_conf−>start_chip = CHIPS_IN_FRAME − temp_value; }
385 else { return(FAIL); } break;
390
case CONF_STTD: /* values are ON or OFF */ if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ N’) ) {
395 bs_conf−>sttd_active = TRUE; } else if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ F’) && (value_ptr[2] == ’ F’) ) {
400 bs_conf−>sttd_active = FALSE; } else { return(FAIL);
405 } break;
case CONF_TSTD: /* values are ON or OFF */
410 if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ N’) ) { bs_conf−>tstd_active = TRUE; } else if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ F’)
415 && (value_ptr[2] == ’ F’) ) { bs_conf−>tstd_active = FALSE; } else
420 { return(FAIL); } break;
425 case CONF_GAIN_BS: sscanf(value_ptr, "%f", &temp_float); if ( (temp_float >= MIN_GAIN) && (temp_float <= MAX_GAIN) ) { bs_conf−>gain_bs = db2lin(temp_float);
430 } else { return(FAIL); }
Page 8/10gen_conf.c
435 break;
case CONF_GAIN_P_SCH: sscanf(value_ptr, "%f", &temp_float); if ( (temp_float >= MIN_GAIN) && (temp_float <= MAX_GAIN) )
440 { bs_conf−>gain_p_sch = db2lin(temp_float); } else {
445 return(FAIL); } break;
case CONF_GAIN_S_SCH:450 sscanf(value_ptr, "%f", &temp_float);
if ( (temp_float >= MIN_GAIN) && (temp_float <= MAX_GAIN) ) { bs_conf−>gain_s_sch = db2lin(temp_float); }
455 else { return(FAIL); } break;
460
case CONF_GAIN_P_CPICH: sscanf(value_ptr, "%f", &temp_float); if ( (temp_float >= MIN_GAIN) && (temp_float <= MAX_GAIN) ) {
465 bs_conf−>gain_cpich[0] = db2lin(temp_float); bs_conf−>cpich_s_scr_code[0] = 0; bs_conf−>cpich_chan_code_nr[0] = 0; } else
470 { return(FAIL); } break;
475 case CONF_S_CPICH_NUMBER: sscanf(value_ptr, "%u", &temp_value); if ( temp_value < CPICH_NUMBER ) { bs_conf−>cpich_amount = temp_value + 1;
480 } else { return(FAIL); }
485 break;
case CONF_SECONDARY_CODE: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value <= MAX_SEC_SCRAMBLING_CODE) &&
490 (s_cpich_nr > 0) && (s_cpich_nr <= bs_conf−>cpich_amount) ) { bs_conf−>cpich_s_scr_code[s_cpich_nr] = temp_value; } else
Page 9/10gen_conf.c495 {
return(FAIL); } break;
500 case CONF_CHAN_CODE: sscanf(value_ptr, "%u", &temp_value); if ( (temp_value <= MAX_CHAN_CODE_NR) && (s_cpich_nr > 0) && (s_cpich_nr <= bs_conf−>cpich_amount) ) {
505 bs_conf−>cpich_chan_code_nr[s_cpich_nr] = temp_value; } else { return(FAIL);
510 } break;
case CONF_GAIN_S_CPICH: sscanf(value_ptr, "%f", &temp_float);
515 if ( (temp_float >= MIN_GAIN) && (temp_float <= MAX_GAIN) && (s_cpich_nr > 0) && (s_cpich_nr <= bs_conf−>cpich_amount) ) { bs_conf−>gain_cpich[s_cpich_nr] = db2lin(temp_float); }
520 else { return(FAIL); } break;
525 default: /* This is illegal case. */ return(FAIL); break;
530 } /* switch */ return(SUCCESS);}
535 /* End of file. */
Page 10/10gen_conf.c
/*
Title: Configuration file reading utility for channel generator Header file
5 Kalle Tuulos’ M.Sc. Thesis Work File name: gen_conf.h
$Date: 2002−01−14 15:01:30+02 $10
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/15
Page 1/2gen_conf.h/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify20 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful,25 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License30 along with 3WTG; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Function returns either SUCCESS or FAIL. */35 uint16 gen_conf_read(GEN_CONF_T * gen_conf, uint16 * line_number);
/* End of file. */
Page 2/2gen_conf.h
/*
Title: Configuration file keywords for data generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_conf_keywords.h
$Date: 2002−01−14 15:01:20+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_conf_keywords.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef GEN_CONF_KEYWORDS_H#define GEN_CONF_KEYWORDS_H
35
typedef enum{ CONF_FIRST_ITEM, CONF_BS_NUMBER,
40 CONF_FRAME_NUMBER, CONF_OVERSAMPLING, CONF_CHIP_FILTERING, CONF_CHIP_FILTER_LEN, CONF_VERBOSITY,
45 CONF_SCRAMBLING_CODE, CONF_START_SFN, CONF_BS_OFFSET, CONF_STTD, CONF_TSTD,
50 CONF_GAIN_BS, CONF_GAIN_P_SCH, CONF_GAIN_S_SCH, CONF_GAIN_P_CPICH, CONF_S_CPICH_NUMBER,
55 CONF_SECONDARY_CODE, CONF_CHAN_CODE, CONF_GAIN_S_CPICH, CONF_OFF, CONF_ON,
60 CONF_END_OF_FILE, CONF_LAST_ITEM}CONF_ITEMS;
65 #endif/* End of file */
Page 2/2gen_conf_keywords.h
/*
Title: Chip filtering Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_filter_chips.c
$Date: 2002−01−14 15:01:19+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/4gen_filter_chips.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <math.h>
35 #include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
40 #include "gen_filter_chips.h"
#define ALPHA 0.22#define PI 3.14159265358979323846
45 static fl32 calc_tap( uint16 tap, uint16 taps_per_chip);
uint16 filter_chips( FILE * input_file, FILE * output_file, const GEN_CONF_T * gen_conf){
50 uint16 return_status = SUCCESS; COMPLEX_FLOAT delay_line[MAX_CHIP_FILTER_LEN]; fl32 filter_tap[MAX_CHIP_FILTER_LEN]; uint16 oversample_round;
55 uint16 tap; COMPLEX_FLOAT output_sample;
/* Bail out with error, if input or output file is invalid */60 if ( (input_file == NULL) || (output_file == NULL) )
{ return(FAIL); }
65 /* Generate taps for delay line and wipe its contents */ for (tap = 0; tap < gen_conf−>chip_filter_length; tap++) { filter_tap[tap] = calc_tap(tap, gen_conf−>oversampling); delay_line[tap].i = 0;
70 delay_line[tap].q = 0; }
oversample_round = 0;
Page 2/4gen_filter_chips.c
75 debug_print("Starting filtering chips.\n", DEBUG_PRINT); /* Start filtering */ do {
80 oversample_round++; if (oversample_round == 1) { /* Fetch new sample from input file.
85 Note that new sample is fetched only in first round of oversampling. Other rounds use existing data. */ return_status = read_from_file(input_file, &delay_line[0]); } else
90 { /* Store zero to current sample */ delay_line[0].i = 0; delay_line[0].q = 0; }
95 if (oversample_round == gen_conf−>oversampling) { /* This is now last round. Fetch fresh data on next round. */ oversample_round = 0;
100 }
if (return_status != SUCCESS) { /* No new sample available − stop filtering. */
105 break; } if (gen_conf−>chip_filtering == TRUE) {
110 /* Filtering is active − calculate new sample from delay line */ output_sample.i = 0; output_sample.q = 0;
for (tap = (gen_conf−>chip_filter_length − 1); tap > 0; tap−−)115 {
output_sample.i += delay_line[tap].i * filter_tap[tap]; output_sample.q += delay_line[tap].q * filter_tap[tap]; /* Shift samples in delay line */ delay_line[tap] = delay_line[tap − 1];
120 } /* Last sample has to be calculated outside loop */ output_sample.i += delay_line[0].i * filter_tap[0]; output_sample.q += delay_line[0].q * filter_tap[0];
125 } else { /* Filtering is not active − use read sample */ output_sample = delay_line[0];
130 }
/* Write sample to work file */ write_to_file(output_file, output_sample); }
Page 3/4gen_filter_chips.c135 while (return_status == SUCCESS);
return(SUCCESS); }
140
static fl32 calc_tap( uint16 tap, uint16 taps_per_chip){ fl64 upper; fl64 lower;
145 fl32 result;
fl64 k; if (tap == 0)
150 return(1.060113);
k = (( fl32 )tap / ( fl32 )taps_per_chip); upper = sin(PI * k * (1 − ALPHA))
155 + 4 * ALPHA * k * cos(PI * k * (1 + ALPHA));
lower = PI * k * (1 − (4 * ALPHA * k) * (4 * ALPHA * k));
result = upper / lower;160
return(result);}
/* End of file. */
Page 4/4gen_filter_chips.c
/*
Title: Chip filtering, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_filter_chips.h
$Date: 2002−01−14 15:01:18+02 $
10
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/15
Page 1/2gen_filter_chips.h/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify20 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful,25 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License30 along with 3WTG; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/*35 Module for applying root raised cosine filter to transmitted chips
*/
uint16 filter_chips(FILE * input_file, FILE * output_file, const GEN_CONF_T * gen_conf);
40
/* End of file. */
Page 2/2gen_filter_chips.h
/*
Title: Chip generation Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_generate_data.c
$Date: 2002−01−14 15:01:17+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/11gen_generate_data.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <malloc.h>
35 #include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
40 #include "gen_generate_data.h"#include "gen_psc.h"#include "gen_ssc.h"#include "gen_matrix_row.h"#include "gen_conf.h"
45 #include "gen_scrc.h"
static void add_sch_seq_to_symbol(COMPLEX_FLOAT * target, const int16 * source, fl32 gain);
50
static void add_cpich_seq_to_symbol(COMPLEX_FLOAT * target, const int16 * source_i, const int16 * source_q, const int16 * chan_code,
55 fl32 gain, uint16 symbol_in_frame, uint16 tx_div_active);
static uint16 generate_data_for_bs(FILE * output_file_tx1,60 FILE * output_file_tx2,
const BS_CONF_T * bs_conf, uint16 frames_to_generate);
static uint16 merge_bs(uint32 amount_of_frames, uint32 chips_to_discard,65 fl32 gain_bs, FILE * bs_file, FILE * work_file,
FILE * result_file, uint16 bs);
uint16 generate_data(FILE * output_file_tx1, FILE * output_file_tx2, const GEN_CONF_T * gen_conf)
70 { /* This function goes through all basestations and generates their data. It sums all data together and adjusts base station offsets. */
uint16 bs;
Page 2/11gen_generate_data.c
75 uint32 i; uint16 amount_of_frames_to_generate; uint16 return_status = FAIL; COMPLEX_FLOAT sample; FILE * bs_work_file_tx1;
80 FILE * bs_work_file_tx2; FILE * dg_work_file_r_tx1; FILE * dg_work_file_r_tx2; FILE * dg_work_file_w_tx1; FILE * dg_work_file_w_tx2;
85 FILE * temp_file_ptr_tx1; FILE * temp_file_ptr_tx2;
/* Generate temporary files for generated base station data */ bs_work_file_tx1 = tmpfile();
90 bs_work_file_tx2 = tmpfile(); dg_work_file_r_tx1 = tmpfile(); dg_work_file_r_tx2 = tmpfile(); dg_work_file_w_tx1 = tmpfile(); dg_work_file_w_tx2 = tmpfile();
95
/* Generate always one extra frame of data */ amount_of_frames_to_generate = gen_conf−>amount_of_frames + 1; for (bs = 0; bs < gen_conf−>amount_of_bs; bs++)
100 { debug_print_w_val("Creating data for bs %d\n", bs, DEBUG_PRINT); debug_print_w_val("Scrambling code group: %d\n", gen_conf−>bs[bs].scrambling_code_group, DEBUG_PRINT);
105 /* Generate data for this base station */ return_status = generate_data_for_bs(bs_work_file_tx1, bs_work_file_tx2, &(gen_conf−>bs[bs]), amount_of_frames_to_generate);
110 if (return_status != SUCCESS) { /* Error, bail out! */ break; }
115
/* Swap dg read and write file pointers. */ temp_file_ptr_tx1 = dg_work_file_r_tx1; dg_work_file_r_tx1 = dg_work_file_w_tx1; dg_work_file_w_tx1 = temp_file_ptr_tx1;
120
temp_file_ptr_tx2 = dg_work_file_r_tx2; dg_work_file_r_tx2 = dg_work_file_w_tx2; dg_work_file_w_tx2 = temp_file_ptr_tx2;
125 rewind(bs_work_file_tx1); rewind(bs_work_file_tx2);
/* Now remove needless chips from beginning of generated bs data and sum generated BS data with existing data. */
130 /* First merge data for TX antenna 1 */ return_status = merge_bs(gen_conf−>amount_of_frames, gen_conf−>bs[bs].start_chip, gen_conf−>bs[bs].gain_bs, bs_work_file_tx1, dg_work_file_r_tx1, dg_work_file_w_tx1, bs);
Page 3/11gen_generate_data.c135
if (return_status != SUCCESS) { /* Error, bail out! */ break;
140 } /* Then merge data for TX antenna 2 */ return_status = merge_bs(gen_conf−>amount_of_frames, gen_conf−>bs[bs].start_chip,
145 gen_conf−>bs[bs].gain_bs, bs_work_file_tx2, dg_work_file_r_tx2, dg_work_file_w_tx2, bs); if (return_status != SUCCESS) {
150 /* Error, bail out! */ break; } /* All done for this bs. Rewind work files and proceed for next bs. */
155 rewind(bs_work_file_tx1); rewind(bs_work_file_tx2); rewind(dg_work_file_r_tx1); rewind(dg_work_file_r_tx2); rewind(dg_work_file_w_tx1);
160 rewind(dg_work_file_w_tx2); } /* for (bs = 0; ... */ if (return_status != SUCCESS) {
165 /* There was error in data generation */ debug_print("Error generating data!\n", ERROR_PRINT); fclose(bs_work_file_tx1); fclose(bs_work_file_tx2); fclose(dg_work_file_r_tx1);
170 fclose(dg_work_file_r_tx2); fclose(dg_work_file_w_tx1); fclose(dg_work_file_w_tx2); return(FAIL); }
175 /* All base stations processed. Copy data from work file to output file. */ for (i = 0; i < (gen_conf−>amount_of_frames * CHIPS_IN_FRAME); i++) {
180 return_status = read_from_file(dg_work_file_w_tx1, &sample); if (return_status != SUCCESS) { /* There was an error, bail out. */
185 debug_print("Error generating data!\n", ERROR_PRINT); break; } write_to_file(output_file_tx1, sample);
190 return_status = read_from_file(dg_work_file_w_tx2, &sample); if (return_status != SUCCESS) {
Page 4/11gen_generate_data.c
195 /* There was an error, bail out. */ debug_print("Error generating data!\n", ERROR_PRINT); break; }
200 write_to_file(output_file_tx2, sample); }
/* Close temporary work files. */ fclose(bs_work_file_tx1);
205 fclose(bs_work_file_tx2); fclose(dg_work_file_r_tx1); fclose(dg_work_file_r_tx2); fclose(dg_work_file_w_tx1); fclose(dg_work_file_w_tx2);
210
return(return_status);}
static uint16 generate_data_for_bs( FILE * output_file_tx1,215 FILE * output_file_tx2,
const BS_CONF_T * bs_conf, uint16 frames_to_generate){
220 uint16 chip_in_symbol; uint16 symbol_in_slot; uint16 slot_in_frame; uint16 current_sfn; uint16 current_frame;
225 uint16 i; uint16 temp_return_value; uint16 ssc_seq_nr; uint16 symbol_in_frame;
230 int16 psc_sequence[CHIPS_IN_SF256_SYMBOL]; int16 ssc_sequence[SSC_GROUPS][CHIPS_IN_SF256_SYMBOL]; /* Pointers to common pilot channel memory area − they are reserved dynamically. */
235 SCRC_GEN_T * scrc_gen_reg[CPICH_NUMBER]; int16 * scrc_i[CPICH_NUMBER]; int16 * scrc_q[CPICH_NUMBER]; int16 * cpich_chan_code[CPICH_NUMBER];
240 COMPLEX_FLOAT output_symbol_tx1[CHIPS_IN_SF256_SYMBOL]; COMPLEX_FLOAT output_symbol_tx2[CHIPS_IN_SF256_SYMBOL];
if ((output_file_tx1 == NULL) || (output_file_tx2 == NULL)) {
245 debug_print("Invalid output file!\n", ERROR_PRINT); return(FAIL); } /* Generate PSC symbols */
250 temp_return_value = gen_psc(&psc_sequence[0]); if (temp_return_value != SUCCESS) { debug_print("Error in PSC sequene generation!\n", ERROR_PRINT); return(FAIL);
Page 5/11gen_generate_data.c255 }
printf("\n"); /* Generate SSC sequences */
260 for (i = 0; i < 16; i++) { temp_return_value = gen_ssc(i+1, &ssc_sequence[i][0]); if (temp_return_value != SUCCESS) {
265 debug_print("Error in S−SCH sequence generation!\n", ERROR_PRINT); return(FAIL); } }
270 if ( bs_conf−>start_sfn > (MAX_SFN − 1) ) { debug_print("Error − start SFN not in range [0,4095]\n", ERROR_PRINT); }
275 /* Are there active pilot channels? */ for (i = 0; i < bs_conf−>cpich_amount; i++) { if (bs_conf−>gain_cpich[i] != 0) {
280 /* Reserve dynamic memories */ scrc_gen_reg[i] = malloc( sizeof(SCRC_GEN_T)); scrc_i[i] = malloc( sizeof( int16 ) * CHIPS_IN_SF256_SYMBOL); scrc_q[i] = malloc( sizeof( int16 ) * CHIPS_IN_SF256_SYMBOL); cpich_chan_code[i] = malloc( sizeof( int16 ) * CHIPS_IN_SF256_SYMBOL);
285
/* Generate channelization code sequence */ gen_matrix_row(bs_conf−>cpich_chan_code_nr[i], HADAMARD_MATRIX_SIZE, cpich_chan_code[i]);
290 /* Initialize scrambling code generator */ gen_scrc_init(bs_conf−>scrambling_code + bs_conf−>cpich_s_scr_code[i], scrc_gen_reg[i]); } }
295 current_sfn = bs_conf−>start_sfn;
debug_print("Starting data generating.\n", DEBUG_PRINT);
300 for (current_frame = 0; current_frame < frames_to_generate; current_frame++) { symbol_in_frame = 0;
305 for (slot_in_frame = 0; slot_in_frame < SLOTS_IN_FRAME; slot_in_frame++) { for (symbol_in_slot = 0; symbol_in_slot < SF256_SYMBOLS_IN_SLOT; symbol_in_slot++)
310 { /* First, erase buffer for current symbol. */ for (chip_in_symbol = 0; chip_in_symbol < CHIPS_IN_SF256_SYMBOL; chip_in_symbol++) {
Page 6/11gen_generate_data.c
315 output_symbol_tx1[chip_in_symbol].i = 0; output_symbol_tx1[chip_in_symbol].q = 0; output_symbol_tx2[chip_in_symbol].i = 0; output_symbol_tx2[chip_in_symbol].q = 0; }
320
/* P−SCH and S−SCH are transmitted only in the first symbol of slot. */ if (symbol_in_slot == 0) {
325 /* Calculate SSC sequence number */ ssc_seq_nr = fdd_ssc_allocation[bs_conf−>scrambling_code_group] [slot_in_frame] − 1;
330 /* Is TSTD active? */ if (bs_conf−>tstd_active) { /* TSTD active */ if ((slot_in_frame%2) == 0)
335 { /* On even slots (0,2,4,...), SCH is attached to TX antenna 1. */ add_sch_seq_to_symbol(&output_symbol_tx1[0], &psc_sequence[0],
340 bs_conf−>gain_p_sch); add_sch_seq_to_symbol(&output_symbol_tx1[0], &ssc_sequence[ssc_seq_nr][0], bs_conf−>gain_s_sch); }
345 else { /* On odd slots (1,3,5,...), SCH is attached to TX antenna 2. */ add_sch_seq_to_symbol(&output_symbol_tx2[0],
350 &psc_sequence[0], bs_conf−>gain_p_sch); add_sch_seq_to_symbol(&output_symbol_tx2[0], &ssc_sequence[ssc_seq_nr][0], bs_conf−>gain_s_sch);
355 } } else { /* No TSTD − SCH is transmitted on both antennas */
360 add_sch_seq_to_symbol(&output_symbol_tx1[0], &psc_sequence[0], bs_conf−>gain_p_sch); add_sch_seq_to_symbol(&output_symbol_tx2[0], &psc_sequence[0],
365 bs_conf−>gain_p_sch); add_sch_seq_to_symbol(&output_symbol_tx1[0], &ssc_sequence[ssc_seq_nr][0], bs_conf−>gain_s_sch); add_sch_seq_to_symbol(&output_symbol_tx2[0],
370 &ssc_sequence[ssc_seq_nr][0], bs_conf−>gain_s_sch); } } /* Attachment of SCH */
Page 7/11gen_generate_data.c375 /* Common pilot channels are transmitted continuously */
/* Go through CPICHs and send active ones */ for (i = 0; i < bs_conf−>cpich_amount; i++) { if (bs_conf−>gain_cpich[i] != 0)
380 { /* Generate symbolful of scrambling code. */ gen_scrc(CHIPS_IN_SF256_SYMBOL, scrc_gen_reg[i], scrc_i[i], scrc_q[i]);
385 add_cpich_seq_to_symbol(&output_symbol_tx1[0], scrc_i[i], scrc_q[i], cpich_chan_code[i], bs_conf−>gain_cpich[i], symbol_in_frame,
390 FALSE); add_cpich_seq_to_symbol(&output_symbol_tx2[0], scrc_i[i], scrc_q[i], cpich_chan_code[i],
395 bs_conf−>gain_cpich[i], symbol_in_frame, bs_conf−>sttd_active); } }
400 /* Save generated symbol to output file */ for (chip_in_symbol = 0; chip_in_symbol < CHIPS_IN_SF256_SYMBOL; chip_in_symbol++) {
405 write_to_file(output_file_tx1, output_symbol_tx1[chip_in_symbol]); write_to_file(output_file_tx2, output_symbol_tx2[chip_in_symbol]); }
410 debug_print("One symbol of channel data generated.\n", DEBUG_PRINT_SPAM);
symbol_in_frame++;415 /* Now go to next symbol. */
} /* for (symbol_in_slot = ...) */
debug_print("One slot of channel data created.\n", DEBUG_PRINT_SPAM);
420 } /* for (slot_in_frame = ...) */
debug_print_w_val("One frame generated. SFN was %d\n", current_sfn, DEBUG_PRINT);
425 current_sfn++;
if (current_sfn == MAX_SFN) {
430 current_sfn = 0; }
} /* for (current_frame = ...) */
Page 8/11gen_generate_data.c
435 /* Before returning, de−allocate dynamic memories */ for (i = 0; i < bs_conf−>cpich_amount; i++) { if (bs_conf−>gain_cpich != 0) {
440 free(scrc_gen_reg[i]); free(scrc_i[i]); free(scrc_q[i]); free(cpich_chan_code[i]); }
445 }
return(SUCCESS);}
450 static void add_sch_seq_to_symbol(COMPLEX_FLOAT * target, const int16 * source, fl32 gain){ uint16 chip_in_symbol;
455
if (gain != 0) { /* If gain is non−zero, add source chips to target */ for (chip_in_symbol = 0; chip_in_symbol < CHIPS_IN_SF256_SYMBOL;
460 chip_in_symbol++) { target[chip_in_symbol].i += gain * source[chip_in_symbol]; target[chip_in_symbol].q += gain * source[chip_in_symbol]; }
465 }}
static void add_cpich_seq_to_symbol(COMPLEX_FLOAT * target, const int16 * source_i,
470 const int16 * source_q, const int16 * chan_code, fl32 gain, uint16 symbol_in_frame, uint16 tx_div_active)
475 { uint16 chip_in_symbol; uint16 symbol_in_group; fl32 tx_div_gain;
480 symbol_in_group = symbol_in_frame % 4; tx_div_gain = gain; /* If tx diversity is active, inverse second and third symbol in groups of four */
485 if ((tx_div_active != 0) && ((symbol_in_group == 1) || (symbol_in_group == 2))) { tx_div_gain *= (−1); }
490 for (chip_in_symbol = 0; chip_in_symbol < CHIPS_IN_SF256_SYMBOL; chip_in_symbol++) { target[chip_in_symbol].i +=
Page 9/11gen_generate_data.c495 tx_div_gain * source_i[chip_in_symbol] *
chan_code[chip_in_symbol]; target[chip_in_symbol].q += tx_div_gain * source_q[chip_in_symbol] * chan_code[chip_in_symbol];
500 }}
static uint16 merge_bs( uint32 amount_of_frames, uint32 chips_to_discard, fl32 gain_factor, FILE * bs_file, FILE * work_file,
505 FILE * result_file, uint16 bs){ uint32 i; uint16 return_status = FAIL; COMPLEX_FLOAT input_sample_bs;
510 COMPLEX_FLOAT input_sample_work; COMPLEX_FLOAT output_sample;
/* First discard needed amount of chips */ for (i = 0; i < chips_to_discard; i++)
515 { return_status = read_from_file(bs_file, &input_sample_bs); if (return_status != SUCCESS) {
520 /* Error, bail out! */ return(return_status); } }
525 /* Sum generated BS data with existing data. */ for (i = 0; i < amount_of_frames * CHIPS_IN_FRAME; i++) { /* Read BS data sample. */ return_status = read_from_file(bs_file, &input_sample_bs);
530 if (return_status != SUCCESS) { /* Error, bail out! */ return(return_status); }
535
/* Read sample from dg work file. On first time, dg file is empty so it must not be read. */ if (bs == 0) {
540 input_sample_work.i = 0; input_sample_work.q = 0; } else {
545 return_status = read_from_file(work_file, &input_sample_work); if (return_status != SUCCESS) { /* Error, bail out! */ break;
550 } }
output_sample.i = input_sample_work.i + gain_factor * input_sample_bs.i;
Page 10/11gen_generate_data.c
555 output_sample.q = input_sample_work.q + gain_factor * input_sample_bs.q; write_to_file(result_file, output_sample); } /* for (i = 0; ... */
560 return(return_status);
}
565 /* End of file */
Page 11/11gen_generate_data.c
/*
Title: Chip generation, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_generate_data.h
$Date: 2002−01−14 15:01:17+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_generate_data.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
uint16 generate_data(FILE * work_file_tx1, FILE * work_file_tx2, const GEN_CONF_T * gen_conf);
35
/* End of file */
Page 2/2gen_generate_data.h
/*
Title: Matrix row generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_matrix_row.c
$Date: 2002−01−14 15:00:52+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/3gen_matrix_row.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */
35 #include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
#include "gen_matrix_row.h"
40 /* This module generates required matrix row */
uint16 gen_matrix_row(uint16 row, uint16 matrix_size, int16 * output_array){
45
uint16 i; uint16 k; uint32 t; uint16 w;
50 uint16 i_r; uint16 real_row; uint16 result;
55 uint16 mt;
if ( (row >= matrix_size ) || (matrix_size > MAX_MATRIX_SIZE) ) { return(1);
60 }
for (mt = 0; mt < (matrix_size / 2); mt++) { if ((matrix_size >> mt) == 1)
65 { break; } }
70 /* Bit inverse row number */
real_row = 0; for (k = 0; k < mt; k++)
Page 2/3gen_matrix_row.c
75 { real_row |= get_bit(row, (mt−1−k)) << k; }
w = real_row;80
for (i = 0; i < matrix_size; i++) { /* Calculate result for this bit */ result = 0;
85
/* Bit inverse i */ i_r = 0;
for (k = 0; k < mt; k++)90 {
i_r |= get_bit(i, (mt−1−k)) << k; } t = i_r & w;
95 for (k = 0; k < mt; k++) { if (get_bit(t, k)) {
100 result += 1; } }
result %= 2;105
output_array[i] = (1 − 2 * result); }
/* Return with success */110 return(0);
}
/* End of file. */
Page 3/3gen_matrix_row.c
/*
Title: Matrix row generator, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_matrix_row.h
$Date: 2002−01−14 15:01:16+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_matrix_row.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* If bigger matrixes needed, uint16’s inside function have to be changed to uint32 */
35 #define MAX_MATRIX_SIZE 65536
/* S−SCH sequence generator prototype */uint16 gen_matrix_row( uint16 row, /* Which row is generated */
40 uint16 matrix_size, /* How many rows in matrix */ int16 * output_array /* Pointer to output array */ );
/* End of file. */
Page 2/2gen_matrix_row.h
/*
Title: PSC sequence generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_psc.c
$Date: 2002−01−14 15:01:15+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/3gen_psc.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */
35 #include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
#include "gen_psc.h"
40 /* Following definition is from 3GPP 25.213 v3.3.0 chapter 5.2.3.1 (FDD) and 25.223 v3.4.0 chapter 7.10 (TDD). Note that definition is idential for both FDD and TDD, so same PSC generator can be used for both systems. */
45 /* PSC "repetition" sequence: <a, a, a, −a, −a, a, −a, −a, a, a, a, −a, a, −a, a, a> MSB equals the first sent group In following constant, (bit == 0) −−> a and (bit == 1) −−> −a*/
50 #define PSC_SEQ 0x1B14
/* Weighting factor for P−SCH */fl32 g_p = 1.0;
55 /* P−SCH sequence generator */uint16 gen_psc(int16 * output_array){ uint16 i; uint16 j;
60
int16 psc_a; int16 psc_seq = PSC_SEQ;
if (output_array == NULL)65 {
debug_print("PSC generation: invalid output array!\n", ERROR_PRINT); return(FAIL); }
70 for (i = 0; i < 16; i++) { if (get_bit(psc_seq, MSB)) { psc_a = ~PSC_A;
Page 2/3gen_psc.c
75 } else { psc_a = PSC_A; }
80 for (j = 0; j < 16; j++) { output_array[16*i + j] = 1 − 2 * get_bit(psc_a, MSB); /* Next rotate psc_a left one bit */
85 psc_a <<= 1; } /* Next rotate psc_seq left one bit */ psc_seq <<= 1;
90 }
/* All ok, return with success */ return(SUCCESS);}
95
/* End of file. */
Page 3/3gen_psc.c
/*
Title: PSC sequence generator, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_psc.h
$Date: 2002−01−14 15:01:14+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_psc.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Following definition is from 3GPP 25.213 v3.6.0 chapter 5.2.3.1 (FDD) and 25.223 v3.4.0 chapter 7.10 (TDD). Note that definition is
35 identical for both FDD and TDD, so same PSC generator can be used for both systems. */
/* PSC "root" sequence (used also in SSC generation): <1, 1, 1, 1, 1, 1, −1, −1, 1, −1, 1, −1, 1, −1, −1, 1>
40 MSB equals the first sent chip In following constant, (bit == 0) −−> 1 and (bit == 1) −−> −1*/#define PSC_A 0x0356
45 /* P−SCH weight factor */extern fl32 g_p;
/* P−SCH sequence generator prototype */uint16 gen_psc(int16 * output_array);
50
/* End of file. */
Page 2/2gen_psc.h
/*
Title: Scrambling code generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_scrc.c
$Date: 2002−01−14 15:01:13+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/4gen_scrc.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */
35 #include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
#include "gen_scrc.h"
40 static void shift_reg(SCRC_GEN_T * scrc_reg, uint32 amount_of_shifts);
void gen_scrc_init( uint32 scrc_number, SCRC_GEN_T * scrc_reg){ uint16 ii;
45 uint16 * x; uint16 * y;
x = &(scrc_reg−>reg_x[0]); y = &(scrc_reg−>reg_y[0]);
50 /* Initial conditions */ x[0] = 1; y[1] = 1;
55 for (ii = 1; ii < 18; ii++) { x[ii] = 0; y[ii] = 1; }
60
/* Set scrambling code number */ shift_reg(scrc_reg, scrc_number);
/* Now reset y−reg back to start state */65 for (ii = 0; ii < 18; ii++)
{ y[ii] = 1; }
70 /* Set chip counter to zero */ scrc_reg−>chip_in_frame = 0; /* Copy start−of−frame conditions to wrap registers */ for (ii = 0; ii < 18; ii++)
Page 2/4gen_scrc.c
75 { scrc_reg−>wrap_reg_x[ii] = x[ii]; scrc_reg−>wrap_reg_y[ii] = y[ii]; }}
80
/* Following function is a direct implementation of scrambling code generator explained in 3GPP 25.213 v3.3.0 chapter 5.2.2 */
void gen_scrc( uint16 amount_of_chips, SCRC_GEN_T * scrc_reg,85 int16 * output_i, int16 * output_q)
{ uint16 ii; uint16 jj; uint16 out_i;
90 uint16 out_q_x; uint16 out_q_y; uint16 * x; uint16 * y;
95 x = &(scrc_reg−>reg_x[0]); y = &(scrc_reg−>reg_y[0]); for (ii = 0; ii < amount_of_chips; ii++) {
100 out_i = (x[0] + y[0]) % 2;
output_i[ii] = 1 − 2 * out_i; out_q_x = (x[4] + x[6] + x[15]) % 2;
105 out_q_y = (y[5] + y[6] + y[8] + y[9] + y[10] + y[11] + y[12] + y[13] + y[14] + y[15]) % 2;
output_q[ii] = 1 − 2 * ((out_q_x + out_q_y) % 2);
110 /* Perform one shift to register */ shift_reg(scrc_reg, 1); /* Increase chip counter */ scrc_reg−>chip_in_frame++;
115
if (scrc_reg−>chip_in_frame == CHIPS_IN_FRAME) { /* Set registers back to start state */ for (jj = 0; jj < 18; jj++)
120 { x[jj] = scrc_reg−>wrap_reg_x[jj]; y[jj] = scrc_reg−>wrap_reg_y[jj]; }
125 /* Set chip counter to zero */ scrc_reg−>chip_in_frame = 0; } }}
130
static void shift_reg(SCRC_GEN_T * scrc_reg, uint32 amount_of_shifts){ uint32 ii; uint16 jj;
Page 3/4gen_scrc.c135 uint16 * x;
uint16 * y; uint16 feedback_bit_x; uint16 feedback_bit_y;
140 x = &(scrc_reg−>reg_x[0]); y = &(scrc_reg−>reg_y[0]); for (ii = 0; ii < amount_of_shifts; ii++) {
145 feedback_bit_x = (x[0] + x[7]) % 2; feedback_bit_y = (y[0] + y[5] + y[7] + y[10]) % 2;
for (jj = 0; jj < (SCRC_SHIFT_REG_LEN − 1); jj++) {
150 x[jj] = x[jj+1]; y[jj] = y[jj+1]; }
x[17] = feedback_bit_x;155 y[17] = feedback_bit_y;
}}
/* End of file. */
Page 4/4gen_scrc.c
/*
Title: Scrambling code generator, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_scrc.h
$Date: 2002−01−14 15:00:53+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_scrc.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Shift register length */#define SCRC_SHIFT_REG_LEN 18
35
typedef struct{ uint16 chip_in_frame; uint16 reg_x[SCRC_SHIFT_REG_LEN];
40 uint16 reg_y[SCRC_SHIFT_REG_LEN]; uint16 wrap_reg_x[SCRC_SHIFT_REG_LEN]; uint16 wrap_reg_y[SCRC_SHIFT_REG_LEN];}SCRC_GEN_T;
45
void gen_scrc_init(uint32 scrc_number, /* 0...262142 */ SCRC_GEN_T * scrc_reg); void gen_scrc(uint16 amount_of_chips, /* 0...38399 */
50 SCRC_GEN_T * scrc_reg, int16 * output_i, int16 * output_q);
/* End of file. */
Page 2/2gen_scrc.h
/*
Title: Test data generator User interface and I/O related functions
5 Kalle Tuulos’ M.Sc. Thesis Work File name: gen_shell.c
$Date: 2002−01−14 15:01:12+02 $10
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/15
Page 1/5gen_shell.c/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify20 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful,25 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License30 along with 3WTG; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */35 #include "gen_conf_keywords.h" /* This has to be second */
#include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */#include "gen_conf.h"#include "gen_generate_data.h"
40 #include "gen_filter_chips.h"
/* Local function prototypes */int main(int argc, const char * argv[]);static void datagen_usage(const char * file_name);
45
int main(int argc, const char * argv[]){
uint16 temp_return_value;50 uint16 show_license = FALSE;
uint16 line_number;
FILE * tx1_work_file; FILE * tx2_work_file;
55 FILE * tx1_output_file; FILE * tx2_output_file;
GEN_CONF_T gen_conf;60
debug_value = ERROR_PRINT;
switch(argc) {
65 case 4: /* Three parameters i.e. tx1&tx2 output file names and configuration file name are given */ temp_return_value = fetch_cfg_file_name(gen_conf.conf_file_name, argv[1]);
70 strcpy(gen_conf.tx1_output_file_name, argv[2]); strcpy(gen_conf.tx2_output_file_name, argv[3]); break;
case 3:75 /* Two parameters i.e. tx1&tx2 output file names */
Page 2/5gen_shell.c
/* Check whether first parameter contains some additional parameters, which is not allowed in this case */ if (argv[1][0] != ’ −’) {
80 strcpy(gen_conf.conf_file_name, DEFAULT_CONF_FILE_NAME); strcpy(gen_conf.tx1_output_file_name, argv[1]); strcpy(gen_conf.tx2_output_file_name, argv[2]); temp_return_value = SUCCESS; }
85 else { temp_return_value = FAIL; } break;
90
case 2: /* Most likely user wished just to see license information. */ if (strcmp(argv[1], "−license") == 0) {
95 show_license = TRUE; } temp_return_value = FAIL; break;
100 case 1: /* No parameters at all */ temp_return_value = FAIL; break;
105 default: /* Invalid amount of parameters */ temp_return_value = FAIL; printf("Illegal amount of parameters!\n\n"); break;
110
} /* switch */
print_header(DATAGEN, show_license);
115 if (temp_return_value != SUCCESS) { if (show_license == FALSE) { /* Problems in command line parsing or opening files */
120 datagen_usage(argv[0]); } exit(EXIT_WITH_FAILURE); }
125 /* Read channel generator configuration values from configuration file */ temp_return_value = gen_conf_read(&gen_conf, &line_number); if (temp_return_value != SUCCESS) { printf("Error reading configuration file at line %d\n",
130 line_number); exit(EXIT_WITH_FAILURE); }
/* Open work files */135 tx1_work_file = tmpfile();
Page 3/5gen_shell.c tx2_work_file = tmpfile(); if ((tx1_work_file == NULL) || (tx2_work_file == NULL)) {
140 debug_print("Error creating work file!\n", ERROR_PRINT); exit(EXIT_WITH_FAILURE); }
debug_print("Work file created.\n", DEBUG_PRINT);145
/* Create output files */ printf("Output file names: "); printf(gen_conf.tx1_output_file_name); printf(" ");
150 printf(gen_conf.tx2_output_file_name); printf("\n"); tx1_output_file = fopen(gen_conf.tx1_output_file_name, "w"); tx2_output_file = fopen(gen_conf.tx2_output_file_name, "w");
155 if ((tx1_output_file == NULL) || (tx2_output_file == NULL)) { debug_print("Error creating output files!\n", ERROR_PRINT); exit(EXIT_WITH_FAILURE); }
160 /* Generate channel data. Output is stored to work file. */ temp_return_value = generate_data(tx1_work_file, tx2_work_file, &gen_conf); if (temp_return_value != SUCCESS)
165 { debug_print("Error creating test data!\n", ERROR_PRINT); exit(EXIT_WITH_FAILURE); }
170 /* Change mode of work files from reading to writing */ rewind(tx1_work_file); rewind(tx2_work_file);
/* Filter channel data. Filtering performs also oversampling. */175 temp_return_value = filter_chips(tx1_work_file, tx1_output_file,
&gen_conf); if (temp_return_value != SUCCESS) { debug_print("Error filtering test data!\n", ERROR_PRINT);
180 exit(EXIT_WITH_FAILURE); } temp_return_value = filter_chips(tx2_work_file, tx2_output_file, &gen_conf);
185 if (temp_return_value != SUCCESS) { debug_print("Error filtering test data!\n", ERROR_PRINT); exit(EXIT_WITH_FAILURE); }
190 /* Close work files */ fclose(tx1_work_file); fclose(tx2_work_file);
195 /* Close output files. */
Page 4/5gen_shell.c
fclose(tx1_output_file); fclose(tx2_output_file);
debug_print("All done.\n", DEBUG_PRINT);200
/* Everything ok, exit from program */ exit(EXIT_WITH_SUCCESS);}
205 static void datagen_usage( const char * file_name){ printf("Command line usage:\n"); printf("−−−−−−−−−−−−−−−−−−−\n\n"); printf(file_name);
210 printf(" [−conffile=<conf_file_name>] <tx1_output_file> "); printf("<tx2_output_file>\n\n"); printf("where <tx1_output_file> and <tx2_output_file> are result file"); printf("names for samples\ngenerated for first and second TX antennas.\n\n"); printf("Optional −conffile can be selected if some other configuration");
215 printf(" file than the\ndefault "); printf(DEFAULT_CONF_FILE_NAME); printf(" is to be used.\n"); printf("\n");}
220
/* End of file. */
Page 5/5gen_shell.c
/*
Title: Second search code sequence generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_ssc.c
$Date: 2002−01−14 15:01:12+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/4gen_ssc.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */#include "gen_conf_keywords.h" /* This has to be second */
35 #include "global.h" /* This has to be third */#include "gen_common.h" /* This has to be fourth */
#include "gen_ssc.h"#include "gen_psc.h"
40 #include "gen_matrix_row.h"
/* Following definitions are from 3GPP 25.213 v3.3.0 chapter 5.2.3.1
z = <b, b, b, −b, b, b, −b, −b, b, −b, b, −b, −b, −b, −b, −b>, where45 b = <x1, x2, x3, x4, x5, x6, x7, x8, −x9, −x10, −x11, −x12, −x13,
−x14, −x15, −x16> and x1, x2 ,..., x15, x16, are same as in the definition of the PSC_A sequence. Mapping is (bit == 0) −−> 1 and (bit == 1) −−> −1
50
*/#define SSC_Z 0x135F#define SSC_B 0x00FF
55 /* Following table is copied from 3GPP 25.213 v3.3.0 chapter 5.2.3.2 *//* From following table, current sent SSC is selected by using <scrambling code group #>,<current slot #> −pair. */const uint16 fdd_ssc_allocation[SCRAMBLING_CODE_GROUPS][SSC_GROUPS] ={
60 { 1,1,2,8,9,10,15,8,10,16,2,7,15,7,16 }, { 1,1,5,16,7,3,14,16,3,10,5,12,14,12,10 }, { 1,2,1,15,5,5,12,16,6,11,2,16,11,15,12 }, { 1,2,3,1,8,6,5,2,5,8,4,4,6,3,7 }, { 1,2,16,6,6,11,15,5,12,1,15,12,16,11,2 },
65 { 1,3,4,7,4,1,5,5,3,6,2,8,7,6,8 }, { 1,4,11,3,4,10,9,2,11,2,10,12,12,9,3 }, { 1,5,6,6,14,9,10,2,13,9,2,5,14,1,13 }, { 1,6,10,10,4,11,7,13,16,11,13,6,4,1,16 }, { 1,6,13,2,14,2,6,5,5,13,10,9,1,14,10 },
70 { 1,7,8,5,7,2,4,3,8,3,2,6,6,4,5 }, { 1,7,10,9,16,7,9,15,1,8,16,8,15,2,2 }, { 1,8,12,9,9,4,13,16,5,1,13,5,12,4,8 }, { 1,8,14,10,14,1,15,15,8,5,11,4,10,5,4 }, { 1,9,2,15,15,16,10,7,8,1,10,8,2,16,9 },
Page 2/4gen_ssc.c
75 { 1,9,15,6,16,2,13,14,10,11,7,4,5,12,3 }, { 1,10,9,11,15,7,6,4,16,5,2,12,13,3,14 }, { 1,11,14,4,13,2,9,10,12,16,8,5,3,15,6 }, { 1,12,12,13,14,7,2,8,14,2,1,13,11,8,11 }, { 1,12,15,5,4,14,3,16,7,8,6,2,10,11,13 },
80 { 1,15,4,3,7,6,10,13,12,5,14,16,8,2,11 }, { 1,16,3,12,11,9,13,5,8,2,14,7,4,10,15 }, { 2,2,5,10,16,11,3,10,11,8,5,13,3,13,8 }, { 2,2,12,3,15,5,8,3,5,14,12,9,8,9,14 }, { 2,3,6,16,12,16,3,13,13,6,7,9,2,12,7 },
85 { 2,3,8,2,9,15,14,3,14,9,5,5,15,8,12 }, { 2,4,7,9,5,4,9,11,2,14,5,14,11,16,16 }, { 2,4,13,12,12,7,15,10,5,2,15,5,13,7,4 }, { 2,5,9,9,3,12,8,14,15,12,14,5,3,2,15 }, { 2,5,11,7,2,11,9,4,16,7,16,9,14,14,4 },
90 { 2,6,2,13,3,3,12,9,7,16,6,9,16,13,12 }, { 2,6,9,7,7,16,13,3,12,2,13,12,9,16,6 }, { 2,7,12,15,2,12,4,10,13,15,13,4,5,5,10 }, { 2,7,14,16,5,9,2,9,16,11,11,5,7,4,14 }, { 2,8,5,12,5,2,14,14,8,15,3,9,12,15,9 },
95 { 2,9,13,4,2,13,8,11,6,4,6,8,15,15,11 }, { 2,10,3,2,13,16,8,10,8,13,11,11,16,3,5 }, { 2,11,15,3,11,6,14,10,15,10,6,7,7,14,3 }, { 2,16,4,5,16,14,7,11,4,11,14,9,9,7,5 }, { 3,3,4,6,11,12,13,6,12,14,4,5,13,5,14 },
100 { 3,3,6,5,16,9,15,5,9,10,6,4,15,4,10 }, { 3,4,5,14,4,6,12,13,5,13,6,11,11,12,14 }, { 3,4,9,16,10,4,16,15,3,5,10,5,15,6,6 }, { 3,4,16,10,5,10,4,9,9,16,15,6,3,5,15 }, { 3,5,12,11,14,5,11,13,3,6,14,6,13,4,4 },
105 { 3,6,4,10,6,5,9,15,4,15,5,16,16,9,10 }, { 3,7,8,8,16,11,12,4,15,11,4,7,16,3,15 }, { 3,7,16,11,4,15,3,15,11,12,12,4,7,8,16 }, { 3,8,7,15,4,8,15,12,3,16,4,16,12,11,11 }, { 3,8,15,4,16,4,8,7,7,15,12,11,3,16,12 },
110 { 3,10,10,15,16,5,4,6,16,4,3,15,9,6,9 }, { 3,13,11,5,4,12,4,11,6,6,5,3,14,13,12 }, { 3,14,7,9,14,10,13,8,7,8,10,4,4,13,9 }, { 5,5,8,14,16,13,6,14,13,7,8,15,6,15,7 }, { 5,6,11,7,10,8,5,8,7,12,12,10,6,9,11 },
115 { 5,6,13,8,13,5,7,7,6,16,14,15,8,16,15 }, { 5,7,9,10,7,11,6,12,9,12,11,8,8,6,10 }, { 5,9,6,8,10,9,8,12,5,11,10,11,12,7,7 }, { 5,10,10,12,8,11,9,7,8,9,5,12,6,7,6 }, { 5,10,12,6,5,12,8,9,7,6,7,8,11,11,9 },
120 { 5,13,15,15,14,8,6,7,16,8,7,13,14,5,16 }, { 9,10,13,10,11,15,15,9,16,12,14,13,16,14,11 }, { 9,11,12,15,12,9,13,13,11,14,10,16,15,14,16 }, { 9,12,10,15,13,14,9,14,15,11,11,13,12,16,10 }};
125
uint16 gen_ssc( uint16 number, int16 * output_array){
uint16 i;130 uint16 k;
uint16 temp_return_value;
uint16 ssc_z = SSC_Z; uint16 ssc_b;
Page 3/4gen_ssc.c135 uint16 ssc_b_org = SSC_B;
uint16 psc_a = PSC_A; if ( (number == 0) || (number > SSC_GROUPS) ) {
140 return(FAIL); }
/* Fetch Hadamard sequence */ temp_return_value = gen_matrix_row(SSC_GROUPS * (number − 1),
145 HADAMARD_MATRIX_SIZE, output_array); for (i = 0; i < 16; i++) { if (get_bit(ssc_z, MSB))
150 { ssc_b = ~(ssc_b_org ^ psc_a); } else {
155 ssc_b = (ssc_b_org ^ psc_a); } for (k = 0; k < 16; k++) { output_array[16*i + k] *= 1 − 2*get_bit(ssc_b, MSB);
160 ssc_b <<= 1; } ssc_z <<= 1; }
165 /* Return with success */ return(SUCCESS);}
/* End of file. */
Page 4/4gen_ssc.c
/*
Title: Second search code sequence generator, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: gen_ssc.h
$Date: 2002−01−14 15:01:11+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2gen_ssc.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* In SSC and channelization code generation, following sized Hadamard matrix is used: */
35 #define HADAMARD_MATRIX_SIZE 256
/* From following table, current sent SSC # is selected by using <scrambling code group #>,<current slot #> −pair. */extern const uint16 fdd_ssc_allocation[SCRAMBLING_CODE_GROUPS][SSC_GROUPS];
40
/* S−SCH sequence generator prototype */uint16 gen_ssc(uint16 number, int16 * output_array);
/* End of file. */
Page 2/2gen_ssc.h
/*
Title: Common utilities for whole thesis work Kalle Tuulos’ M.Sc. Thesis Work
5 File name: global.c
$Date: 2002−01−14 15:00:51+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/9global.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <stdio.h>#include <math.h>
35 #include <string.h>
#include "typedef.h" /* Standard type definitions, keep first */
/* Following type has to be defined before including global.h */40 typedef enum
{ CONF_FIRST_ITEM, CONF_LAST_ITEM}
45 CONF_ITEMS;
#include "global.h"
/* Print license information */50 static void print_license(void );
DEBUG_PRINT_LEVEL debug_value;
void debug_print(const char * message, DEBUG_PRINT_LEVEL debug_level)55 {
if (debug_value >= debug_level) { printf(message); }
60 }
void debug_print_w_val(const char * message, uint32 value, DEBUG_PRINT_LEVEL debug_level){
65 if (debug_value >= debug_level) { printf(message, value); }}
70
void write_to_file(FILE * output_file, COMPLEX_FLOAT value){ fprintf(output_file, "%f %f\n", value.i, value.q);}
Page 2/9global.c
75
uint16 read_from_file( FILE * input_file, COMPLEX_FLOAT * value){ if (feof(input_file)) {
80 return(FAIL); } /* else */ fscanf(input_file, "%f %f", &((*value).i), &((*value).q));
85 return(SUCCESS);}
void complex_add(COMPLEX_FLOAT * a, COMPLEX_FLOAT b){
90 fl32 sum;
sum = (*a).i + b.i; (*a).i = sum;
95 sum = (*a).q + b.q; (*a).q = sum;}
COMPLEX_FLOAT complex_product(COMPLEX_FLOAT a, COMPLEX_FLOAT b)100 {
COMPLEX_FLOAT c;
c.i = (a.i * b.i) − (a.q * b.q); c.q = (a.i * b.q) + (a.q * b.i);
105
return (c); }
110 void complex_product_and_add(COMPLEX_FLOAT a, COMPLEX_FLOAT b, COMPLEX_FLOAT * c){ (*c).i += (a.i * b.i) − (a.q * b.q);
115 (*c).q += (a.i * b.q) + (a.q * b.i); }
fl32 complex_to_ampl(COMPLEX_FLOAT a)120 {
return(sqrt(a.i * a.i + a.q * a.q));
}125
fl32 complex_to_power(COMPLEX_FLOAT a){
return(a.i * a.i + a.q * a.q);130
}
/* Calculate complex number phase in degrees */fl32 complex_to_phase(COMPLEX_FLOAT a)
Page 3/9global.c135 {
fl32 phase; /* Note: atan returns values −pi/2 ... pi/2, so correct range needs to be selected first. */
140
if (a.i > 0) { /* ]−90,90[ degrees */ phase = atan(a.q / a.i);
145 } else if ((a.i < 0) && (a.q >= 0)) { /* ]90,180] degrees */ phase = PI − atan(a.q / −a.i);
150 } else if ((a.i < 0) && (a.q < 0)) { /* ]−180,−90[ degrees */ phase = −(PI − atan(−a.q / −a.i));
155 } else if (a.q > 0) { /* 90 degrees */ phase = PI_2;
160 } else /* if (a.q <= 0) */ { /* −90 degrees */ phase = −PI_2;
165 }
return(radian_to_degree(phase));
}170
/* Convert degree to radian */fl32 degree_to_radian( fl32 a){
175 return((a / ( fl32 )180) * PI); }
/* Convert radian to degree */180 fl32 radian_to_degree( fl32 a)
{
return((a / PI) * 180);
185 }
void print_header(MODULES module, uint16 show_license){
190 printf("\n"); switch(module) { case DATAGEN:
Page 4/9global.c
195 printf("Baseband test data generator\n"); printf("============================\n"); break;
case MERGE:200 printf("Merging utility\n");
printf("===============\n"); break; case CHANMOD:
205 printf("Channel profiler\n"); printf("================\n"); break; case SIMU:
210 printf("Receiver simulator\n"); printf("==================\n"); break; } /* switch */
215 printf("\n"); printf("Version 1.0 Copyright 2002 Kalle Tuulos\n"); printf("Homepage: http://www.tuulos.net/kalle/progradu.html\n"); printf("\n");
220 if (show_license == FALSE) { printf("Licensed under the terms of the GNU General Public License.\n"); printf("Start program with only argument ’−license’ for more information.\n"); }
225 else { print_license(); } printf("\n");
230 }
static void print_license( void){ printf("This program is free software; you can redistribute it and/or modify\n");
235 printf("it under the terms of the GNU General Public License as published by\n"); printf("the Free Software Foundation; either version 2 of the License, or\n"); printf("(at your option) any later version.\n"); printf("\n"); printf("This program is distributed in the hope that it will be useful,\n");
240 printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU General Public License for more details.\n"); printf("\n"); printf("You should have received a copy of the GNU General Public License\n");
245 printf("along with this program; if not, write to the Free Software\n"); printf("Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA\n");}
/* Convert power decibel to linear value */250 fl32 db2lin( fl32 db_value)
Page 5/9global.c{ fl32 lin_value;
lin_value = pow(10, (db_value / ( fl32)20) );255
return(lin_value);}
/* Copy string from source buffer to target and verify,260 that source fits to target */
uint16 copy_filename( const char * source, char * target){ uint16 return_value;
265 if (strlen(source) > FILENAME_LENGTH) { return_value = FAIL; } else
270 { strcpy(target, source); return_value = SUCCESS; }
275 return(return_value);}
char * fetch_val_from_file( FILE * input_file, CONF_ITEMS keyword,280 const char * conf_keyword[],
uint16 * line_number, char * conf_line){ char * stat_fgets; char * value_ptr;
285 uint16 may_continue; uint16 keyword_found; uint16 i;
may_continue = TRUE;290 keyword_found = FALSE;
do { (*line_number)++;
295 stat_fgets = fgets(conf_line, 100, input_file); if (stat_fgets == NULL) { break;
300 }
if (conf_line[0] == ’ #’) { continue;
305 }
for (i = 0; i < strlen(conf_keyword[keyword]); i++) { if (conf_keyword[keyword][i] != conf_line[i])
310 {
Page 6/9global.c
may_continue = FALSE; keyword_found = FALSE; break; }
315 keyword_found = TRUE; }
if (keyword_found) {
320 break; } } while (may_continue);
325 if (keyword_found == FALSE) { /* For some reason, keyword was not found. */ return( NULL); }
330
/* OK, keyword was found. Now search the start of argument. */ value_ptr = strchr(conf_line, ’ ’);
/* Verify, that we are in correct place i.e. semicolon is left of335 pointed place */
if (value_ptr[−1] != ’ :’) { return( NULL); }
340
value_ptr++;
return value_ptr;
345 }
uint16 fetch_cfg_file_name( char * conf_file_name, const char * input_string){ uint16 return_value = SUCCESS;
350 uint16 pos; char keyword[] = "−conffile=";
if (strlen(input_string) >= strlen(keyword)) {
355 for (pos = 0; pos < strlen(keyword); pos++) { if (keyword[pos] != input_string[pos]) { return_value = FAIL;
360 break; } }
if (return_value == SUCCESS)365 {
/* Now input string pointer points to correct position. Let’s copy configuration file name. */ return_value = copy_filename(&input_string[pos], conf_file_name); }
370 }
Page 7/9global.c else { return_value = FAIL; }
375
return(return_value);}
uint16 search_keyword( const char * source, const char * keyword,380 char ** result)
{ uint16 return_value = SUCCESS; uint16 pos;
385 /* Source string has to be longer than keyword */ if (strlen(source) > strlen(keyword)) { *result = ( char *)source; for (pos = 0; pos < strlen(keyword); pos++)
390 { if (source[pos] != keyword[pos]) { /* Keyword did not match. */ *result = NULL;
395 return_value = FAIL; break; } (*result)++; }
400 /* If this point is reached by going through the whole for loop, keyword was matched. Result points to source string in position after keyword. In the other case, return_value is FAIL which indicates that keyword was not found. */
405 } else { return_value = FAIL; *result = NULL;
410 } return(return_value);}
415 uint16 check_boolean_keyword( char * value_ptr, uint16 * var){ uint16 success = SUCCESS;
if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ N’) )420 {
*var = TRUE; } else if ( (value_ptr[0] == ’ O’) && (value_ptr[1] == ’ F’) && (value_ptr[2] == ’ F’) )
425 { *var = FALSE; } else {
430 success = FAIL;
Page 8/9global.c
}
return(success);}
435
/* End of file. */
Page 9/9global.c
/*
Title: Common utilities and settings for whole thesis work Kalle Tuulos’ M.Sc. Thesis Work
5 File name: global.h
$Date: 2002−01−14 15:01:10+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/4global.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef GLOBAL_H#define GLOBAL_H
35
#include <stdio.h>
/* Global environment settings *//* #define SCREEN_HEIGHT 25 */
40 #define FILENAME_LENGTH 80
#define PI 3.14159265358979323846#define PI_2 1.57079632679489661923
45 /* 3GPP specific definitions */#define SF256_SYMBOLS_IN_SLOT 10#define SLOTS_IN_FRAME 15#define MAX_SFN 4096
50 #define CHIPS_IN_SF256_SYMBOL 256#define CHIPS_IN_SLOT (CHIPS_IN_SF256_SYMBOL * SF256_SYMBOLS_IN_SLOT)#define CHIPS_IN_FRAME (SLOTS_IN_FRAME * CHIPS_IN_SLOT)#define FRAMES_IN_SECOND 100
55 #define CHIPS_IN_SECOND (CHIPS_IN_FRAME * FRAMES_IN_SECOND)#define CHIPS_IN_NANOSECOND ((fl32 )(CHIPS_IN_SECOND)*0.000000001)
#define SCRAMBLING_CODE_GROUPS 64#define SCRAMBLING_CODES_PER_GROUP (8*16)
60 #define PRIMARY_SCRAMBLING_CODES_IN_GROUP 8#define MAX_SEC_SCRAMBLING_CODE 16#define MAX_PRI_SCRAMBLING_CODE_NR 8176#define MAX_SCRAMBLING_CODE_NR 262142#define SSC_GROUPS 16
65 #define MAX_CHAN_CODE_NR 255#define CPICH_NUMBER 16
/* Debug print levels */typedef enum
70 { NO_PRINT, ERROR_PRINT,/* UI_PRINT, */ DEBUG_PRINT,
Page 2/4global.h
75 DEBUG_PRINT_SPAM} DEBUG_PRINT_LEVEL;
/* For header printing: list different modules */typedef enum
80 { DATAGEN, MERGE, CHANMOD, SIMU
85 } MODULES;
/* Macro to return value of certain bit in variable */#define get_bit(_var_, _bitno_) \ (( (_var_) & ( 1 << (_bitno_) )) >> (_bitno_))
90
/* Macro to make I and Q parts of complex variable to zero */#define complex_zero(_cplx_) \{ \ (*_cplx_).i = 0; \
95 (*_cplx_).q = 0; \}
/* External variable definition which shows current output level */extern DEBUG_PRINT_LEVEL debug_value;
100
/* Function prototypes */void debug_print(const char * message, DEBUG_PRINT_LEVEL debug_level);void debug_print_w_val(const char * message, uint32 value, DEBUG_PRINT_LEVEL debug_level);
105 void write_to_file(FILE * output_file, COMPLEX_FLOAT value);
/* Following function reads one value pair from input file. Returns either SUCCESS or FAIL. */uint16 read_from_file(FILE * input_file, COMPLEX_FLOAT * value);
110
/* Add a and b together and store result to a */void complex_add(COMPLEX_FLOAT * a, COMPLEX_FLOAT b);
/* Multiply a with b and return result */115 COMPLEX_FLOAT complex_product(COMPLEX_FLOAT a, COMPLEX_FLOAT b);
/* Multiply a with b and add result to c */void complex_product_and_add(COMPLEX_FLOAT a, COMPLEX_FLOAT b, COMPLEX_FLOAT * c);
120
/* Calculate complex number amplitude */fl32 complex_to_ampl(COMPLEX_FLOAT a);
/* Calculate complex number power */125 fl32 complex_to_power(COMPLEX_FLOAT a);
/* Calculate complex number phase in degrees */fl32 complex_to_phase(COMPLEX_FLOAT a);
130 /* Convert degree to radian */fl32 degree_to_radian(fl32 a);
/* Convert radian to degree */fl32 radian_to_degree(fl32 a);
Page 3/4global.h135
/* Convert desibel value to linear */fl32 db2lin(fl32 db_value);
/* Print common header containing copyright information etc */140 /* First parameter is module ID, second whether complete license should
be printed or not (TRUE/FALSE) */void print_header(MODULES module, uint16 show_license);
/* Copy string from source buffer to target and verify,145 that source fits to target. Return values are SUCCESS or FAIL. */
uint16 copy_filename(const char * source, char * target);
/* Following function finds keyword from input file. Function returns character pointer to parameter just after keyword. If no keyword
150 or wrong keyword is found, NULL is returned. */char * fetch_val_from_file(FILE * input_file, CONF_ITEMS keyword, const char * conf_keyword[], uint16 * current_line, char * conf_line);
155 /* Function to fetch configuration file name. Assumption is, that configuration file name is in input string after "−conffile=" sequence. If file name is found, returns SUCCESS, otherwise FAIL. */uint16 fetch_cfg_file_name(char * conf_file_name, const char * input_string);
160 /* Following function searches "source" string for "keyword". If found, return value equals to SUCCESS and "result" points to position after keyword in source. Otherwise return value equals to FAIL. */uint16 search_keyword(const char * source, const char * keyword, char ** result);
165
/* Check for boolean ON or OFF in value pointer. Set variable to TRUE/FALSE. If either ON/OFF was not found, return FAIL otherwise SUCCESS. */uint16 check_boolean_keyword(char * value_ptr, uint16 * var);
170 #endif/* End of file */
Page 4/4global.h
/*
Title: Main file for merging utility Kalle Tuulos’ M.Sc. Thesis Work
5 File name: merge_main.c
$Date: 2002−01−14 15:01:08+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/5merge_main.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Following needed for file operations */#include <stdio.h>
35
#include "typedef.h" /* This has to be the first one */
/* Following dummy type definition is needed, because in global.h one function needs that */
40 typedef enum{ CONF_FIRST_ITEM, CONF_LAST_ITEM}
45 CONF_ITEMS;
#include "global.h" /* This has to be second */
int main( int argc, char * argv[]);50
void merge_two_files( FILE * input_file_1, FILE * input_file_2, FILE * result_file);
void copy_file( FILE * input_file, FILE * result_file);55
void merge_usage( const char * file_name);
int main( int argc, char * argv[]){
60 FILE * input_file; FILE * temp_file; FILE * result_file; FILE * swap_file_ptr;
65 uint16 current_input_file; uint16 error_in_parameters = FALSE; uint16 total_input_files; uint16 show_license = FALSE;
70 /* Set print level to "Errors only" */ debug_value = ERROR_PRINT;
/* Did user ask for license? */ if ((argc == 2) && (strcmp(argv[1], "−license") == 0))
Page 2/5merge_main.c
75 { show_license = TRUE; } /* If not, check amount of input files. There should be at least 1. */ else if (argc < 3)
80 { error_in_parameters = TRUE; } /* Print header information */
85 print_header(MERGE, show_license);
/* Two possible cases for abandonding the program in this step */ if (show_license) {
90 /* License already printed, now exit. */ exit(1); } else if (error_in_parameters) {
95 /* Not enough arguments − print user’s instructions. */ printf("ERROR: not enough arguments!\n\n"); merge_usage(argv[0]); /* Exit with error. */
100 exit(1); }
total_input_files = argc − 2;
105 /* Create temporary file */ temp_file = tmpfile();
/* Create result file which is then used as temporary file */ result_file = fopen(argv[1], "rw");
110
/* Now merge all input files to one result file */ for (current_input_file = 0; current_input_file < total_input_files; current_input_file++) {
115 input_file = fopen(argv[current_input_file + 2], "r");
if (input_file == NULL) { /* Did not succeed in opening input file */
120 debug_print("Did not succeed in opening input file!\nExiting...\n\n", ERROR_PRINT); exit(1); }
125 merge_two_files(input_file, temp_file, result_file);
/* Close input file */ fclose(input_file);
130 /* Rewind temp files */ rewind(temp_file); rewind(result_file);
/* Swap temp file pointers */
Page 3/5merge_main.c135 swap_file_ptr = temp_file;
temp_file = result_file; result_file = swap_file_ptr; }
140 /* If amount of rounds is odd, results are written to correct file, otherwise we’ll have to copy results from temp file to final result file */ if ((current_input_file % 2) == 0)
145 { copy_file(temp_file, result_file); } /* Close all open files */
150 fclose(temp_file); fclose(result_file);
/* Exit with success */ exit(0);
155 }
/* Function to merge two input files to one result file */void merge_two_files( FILE * input_file, FILE * temp_file,
160 FILE * result_file){ COMPLEX_FLOAT input_sample; COMPLEX_FLOAT temp_sample; COMPLEX_FLOAT result_sample;
165
uint16 input_file_status = SUCCESS; uint16 temp_file_status = SUCCESS;
/* Loop until both files are exhausted */170 while((input_file_status == SUCCESS) || (temp_file_status == SUCCESS))
{ input_file_status = read_from_file(input_file, &input_sample); if (input_file_status != SUCCESS)
175 { input_sample.i = 0; input_sample.q = 0; }
180 temp_file_status = read_from_file(temp_file, &temp_sample); if (temp_file_status != SUCCESS) { temp_sample.i = 0;
185 temp_sample.q = 0; }
/* Result is written, if at least either of samples (input file or temp file) was available */
190 if ((input_file_status == SUCCESS) || (temp_file_status == SUCCESS)) { result_sample.i = input_sample.i + temp_sample.i; result_sample.q = input_sample.q + temp_sample.q; write_to_file(result_file, result_sample);
Page 4/5merge_main.c
195 } }}
/* Function to copy one file to another */200 void copy_file( FILE * input_file, FILE * result_file)
{ COMPLEX_FLOAT input_sample;
while (read_from_file(input_file, &input_sample) == SUCCESS)205 {
write_to_file(result_file, input_sample); }}
210 /* Print command line use instructions */void merge_usage( const char * file_name){ printf("Command line usage:\n"); printf("−−−−−−−−−−−−−−−−−−−\n\n");
215 printf(file_name); printf(" <output_file> <input_file_1> [... <input_file_n>]\n\n"); printf("where <input_file_1> is name of the first input file. There may "); printf("be one or\nseveral input files.\n\nContents of all input files "); printf("will be merged to <output_file>.\n\n");
220 }
/* End of file. */
Page 5/5merge_main.c
/*
Title: Simulator: AGC Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_agc.c
$Date: 2002−01−14 15:01:07+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/4simu_agc.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include "typedef.h" /* This has to be the first one */#include "simu_conf_keywords.h" /* This has to be second */
35 #include "global.h" /* This has to be third */#include "simu_common.h" /* This has to be fourth */
#include "simu_agc.h"
40 typedef struct{ uint16 in_use; /* TRUE/FALSE */ uint16 first_call; /* TRUE/FALSE */ uint16 automatic_init; /* TRUE/FALSE */
45 fl32 sample_gain; fl32 last_sample_gain; fl32 adc_max_amplitude; fl32 adc_range; fl32 last_ampl_avg;
50 fl32 automatic_init_trigger;} AGC_T;
AGC_T agc_state;
55 /* Initialize AGC IIR filter */void agc_init(SIMU_CONF_T * simu_conf){ fl32 avg_length;
60 agc_state.in_use = simu_conf−>agc_in_use; if (simu_conf−>agc_in_use == TRUE) { /* Calculate gain factors */
65 avg_length = simu_conf−>agc_t_avg * CHIPS_IN_SF256_SYMBOL; agc_state.sample_gain = (( fl32 )1)/(avg_length * simu_conf−>oversampling); agc_state.last_sample_gain = ( fl32 )1 − (( fl32 )1)/(avg_length * simu_conf−>oversampling);
70
/* Set A/D converter properties */ agc_state.adc_max_amplitude = simu_conf−>agc_adc_max_amplitude; agc_state.adc_range = simu_conf−>agc_adc_range;
Page 2/4simu_agc.c
75 /* Automatic initialization properties */ agc_state.automatic_init = simu_conf−>agc_automatic_init_enabled; agc_state.automatic_init_trigger = simu_conf−>agc_automatic_init_trigger;
/* AGC will be initialized on next call */80 agc_state.first_call = TRUE;
}}
/* Perform AGC to single sample */85 void agc_main(COMPLEX_FLOAT * sample)
{ fl32 ampl_avg = 0; fl32 curr_sample_ampl; fl32 gain;
90
if (agc_state.in_use == TRUE) { /* Perform tricks only if AGC is in use */
95 /* Calculate amplitude for current sample */ curr_sample_ampl = complex_to_ampl(*sample); /* Automatic initialization detection */ if (agc_state.automatic_init == TRUE)
100 { if (curr_sample_ampl > agc_state.automatic_init_trigger * agc_state.last_ampl_avg) { /* Automatic initialization has triggered */
105 agc_state.last_ampl_avg = curr_sample_ampl; } }
if (agc_state.first_call == TRUE)110 {
/* In first call, initialize IIR filter */ ampl_avg = curr_sample_ampl; agc_state.first_call = FALSE; }
115 else { /* Calculate sliding average */ ampl_avg = agc_state.last_sample_gain * agc_state.last_ampl_avg +
120 agc_state.sample_gain * curr_sample_ampl; }
125 /* Store amplitude average for next call */ agc_state.last_ampl_avg = ampl_avg; /* Sliding average of amplitude is calculated. Now calculate G_AGC (formula 4.5 in book). */
130 gain = agc_state.adc_max_amplitude * agc_state.adc_range / ampl_avg;
/* Apply AGC to sample */ (*sample).i *= gain; (*sample).q *= gain;
Page 3/4simu_agc.c135 }
/* All done! */}
140 /* End of file. */
Page 4/4simu_agc.c
/*
Title: Simulator: AGC, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_agc.h
$Date: 2002−01−14 15:01:06+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2simu_agc.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef SIMU_AGC_H#define SIMU_AGC_H
35
#define AGC_MAX_AVERAGING_TIME CHIPS_IN_SF256_SYMBOL#define AGC_ADC_MAX_AMPL_MIN 0#define AGC_ADC_MAX_AMPL_MAX 999999#define AGC_ADC_RANGE_MIN 0
40 #define AGC_ADC_RANGE_MAX 1#define AGC_AUTOMATIC_INIT_TRIGGER_MIN 0#define AGC_AUTOMATIC_INIT_TRIGGER_MAX 99999
45 /* Initialize AGC IIR filter */void agc_init(SIMU_CONF_T * simu_conf);
/* Perform AGC to single sample */void agc_main(COMPLEX_FLOAT * sample);
50
#endif/* End of file. */
Page 2/2simu_agc.h
/*
Title: Configuration file reading utility for receiver simulator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_conf.h
$Date: 2002−01−14 15:01:04+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/9simu_conf.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <string.h>
35 #include "typedef.h" /* This has to be the first one */#include "simu_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */#include "simu_common.h" /* This has to be fourth */
40 #include "simu_conf.h"#include "simu_agc.h"
/* These must match to keywords in simu_conf_keywords.h */const char * conf_keyword[] =
45 { "", "OVERSAMPLING", "AGC_IN_USE", "AGC_AVERAGING_TIME",
50 "AGC_ADC_MAX_AMPLITUDE", "AGC_ADC_RANGE", "AGC_AUTOMATIC_INIT_ENABLED", "AGC_AUTOMATIC_INIT_TRIGGER", "BIT_LIMIT",
55 "PRE_INT_BIT_NUMBER", "PRE_DEC_BIT_NUMBER", "PRE_SCALING", "POST_INT_BIT_NUMBER", "POST_DEC_BIT_NUMBER",
60 "POST_SCALING", "OFFSET", "PSC_AVG_LEN", "CPICH_AVG_LEN", "CPICH_SCRAMBLING_CODE",
65 "SSC_MEAS_LEN", "ISYNC_SCRC_THRESHOLD", "END_OF_FILE", ""};
70
/* Local function prototypes */static uint16 store_simu_val(FILE * input_file, SIMU_CONF_T * simu_conf, CONF_ITEMS keyword, uint16 * current_line);
Page 2/9simu_conf.c
75
uint16 simu_conf_read(SIMU_CONF_T * simu_conf, uint16 * current_line){ FILE * conf_file;
80 printf("Using configuration file: "); printf(simu_conf−>conf_file_name); printf("\n\n"); conf_file = fopen(simu_conf−>conf_file_name, "r");
85 if (conf_file == NULL) { debug_print("Error opening configuration file!\n", ERROR_PRINT); exit(1); }
90
*current_line = 0; /* Oversampling factor */ if (store_simu_val(conf_file, simu_conf, CONF_OVERSAMPLING,
95 current_line) != SUCCESS) { return(FAIL); }
100 /* AGC ON/OFF */ if (store_simu_val(conf_file, simu_conf, CONF_AGC_IN_USE, current_line) != SUCCESS) { return(FAIL);
105 } /* AGC averaging time */ if (store_simu_val(conf_file, simu_conf, CONF_AGC_AVERAGING_TIME, current_line) != SUCCESS)
110 { return(FAIL); } /* AGC A/D converter maximum amplitude */
115 if (store_simu_val(conf_file, simu_conf, CONF_AGC_ADC_MAX_AMPLITUDE, current_line) != SUCCESS) { return(FAIL); }
120 /* AGC A/D converter range */ if (store_simu_val(conf_file, simu_conf, CONF_AGC_ADC_RANGE, current_line) != SUCCESS) {
125 return(FAIL); } /* AGC automatic initialization enable */ if (store_simu_val(conf_file, simu_conf, CONF_AGC_AUTOMATIC_INIT_ENABLED,
130 current_line) != SUCCESS) { return(FAIL); }
Page 3/9simu_conf.c135 /* AGC automatic initialization trigger */
if (store_simu_val(conf_file, simu_conf, CONF_AGC_AUTOMATIC_INIT_TRIGGER, current_line) != SUCCESS) { return(FAIL);
140 } /* Bit limited simulation ON or OFF */ if (store_simu_val(conf_file, simu_conf, CONF_BIT_LIMIT, current_line) != SUCCESS)
145 { return(FAIL); } /* Bit limited simulation: prescaler integer bit amount */
150 if (store_simu_val(conf_file, simu_conf, CONF_PRE_INT_BIT_NUMBER, current_line) != SUCCESS) { return(FAIL); }
155 /* Bit limited simulation: prescaler decimal bit amount */ if (store_simu_val(conf_file, simu_conf, CONF_PRE_DEC_BIT_NUMBER, current_line) != SUCCESS) {
160 return(FAIL); } /* Bit limited simulation: prescaler scaling factor */ if (store_simu_val(conf_file, simu_conf, CONF_PRE_SCALING,
165 current_line) != SUCCESS) { return(FAIL); }
170 /* Bit limited simulation: postscaler integer bit amount */ if (store_simu_val(conf_file, simu_conf, CONF_POST_INT_BIT_NUMBER, current_line) != SUCCESS) { return(FAIL);
175 } /* Bit limited simulation: postscaler decimal bit amount */ if (store_simu_val(conf_file, simu_conf, CONF_POST_DEC_BIT_NUMBER, current_line) != SUCCESS)
180 { return(FAIL); } /* Bit limited simulation: postscaler scaling factor */
185 if (store_simu_val(conf_file, simu_conf, CONF_POST_SCALING, current_line) != SUCCESS) { return(FAIL); }
190 /* Offset in start of input data file */ if (store_simu_val(conf_file, simu_conf, CONF_OFFSET, current_line) != SUCCESS) {
Page 4/9simu_conf.c
195 return(FAIL); } /* Averaging period length for PSC search */ if (store_simu_val(conf_file, simu_conf, CONF_PSC_AVG_LEN,
200 current_line) != SUCCESS) { return(FAIL); }
205 /* Averaging period length for CPICH IRM */ if (store_simu_val(conf_file, simu_conf, CONF_CPICH_AVG_LEN, current_line) != SUCCESS) { return(FAIL);
210 } /* Scrambling code for CPICH IRM */ if (store_simu_val(conf_file, simu_conf, CONF_CPICH_SCRAMBLING_CODE, current_line) != SUCCESS)
215 { return(FAIL); } /* Length of SSC measurement */
220 if (store_simu_val(conf_file, simu_conf, CONF_SSC_MEAS_LEN, current_line) != SUCCESS) { return(FAIL); }
225 /* SCRC detection threshold in initial synchronization procedure */ if (store_simu_val(conf_file, simu_conf, CONF_ISYNC_SCRC_THRESHOLD, current_line) != SUCCESS) {
230 return(FAIL); } debug_print("Configuration file read OK.\n", DEBUG_PRINT);
235 return(SUCCESS);}
uint16 store_simu_val( FILE * input_file, SIMU_CONF_T * simu_conf, CONF_ITEMS keyword, uint16 * current_line)
240 { uint16 success = SUCCESS; uint32 input_uint;/* int32 input_int; */ fl32 input_float;
245 char * value_ptr; char conf_line[100];
value_ptr = fetch_val_from_file(input_file, keyword, conf_keyword, current_line, &conf_line[0]);
250
if (value_ptr == NULL) { return(FAIL); }
Page 5/9simu_conf.c255
switch(keyword) { case CONF_OVERSAMPLING: sscanf(value_ptr, "%u", &input_uint);
260 if ( (input_uint > 0) && (input_uint <= MAX_OVERSAMPLING) ) { simu_conf−>oversampling = input_uint; } else
265 { success = FAIL; } break;
270 case CONF_AGC_IN_USE: success = check_boolean_keyword(value_ptr, &(simu_conf−>agc_in_use)); break;
case CONF_AGC_AVERAGING_TIME:275 sscanf(value_ptr, "%u", &input_uint);
if ( (input_uint > 0) && (input_uint <= AGC_MAX_AVERAGING_TIME) ) { simu_conf−>agc_t_avg = input_uint; }
280 else { success = FAIL; } break;
285
case CONF_AGC_ADC_MAX_AMPLITUDE: sscanf(value_ptr, "%f", &input_float); if ( (input_float >= AGC_ADC_MAX_AMPL_MIN) && (input_float <= AGC_ADC_MAX_AMPL_MAX) )
290 { simu_conf−>agc_adc_max_amplitude = input_float; } else {
295 success = FAIL; } break;
case CONF_AGC_ADC_RANGE:300 sscanf(value_ptr, "%f", &input_float);
if ( (input_float >= AGC_ADC_RANGE_MIN) && (input_float <= AGC_ADC_RANGE_MAX) ) { simu_conf−>agc_adc_range = input_float;
305 } else { success = FAIL; }
310 break;
case CONF_AGC_AUTOMATIC_INIT_ENABLED: success = check_boolean_keyword( value_ptr, &(simu_conf−>agc_automatic_init_enabled));
Page 6/9simu_conf.c
315 break;
case CONF_AGC_AUTOMATIC_INIT_TRIGGER: sscanf(value_ptr, "%f", &input_float); if ( (input_float >= AGC_AUTOMATIC_INIT_TRIGGER_MIN) &&
320 (input_float <= AGC_AUTOMATIC_INIT_TRIGGER_MAX) ) { simu_conf−>agc_automatic_init_trigger = input_float; } else
325 { success = FAIL; } break;
330 case CONF_BIT_LIMIT: success = check_boolean_keyword(value_ptr, &(simu_conf−>bit_limit)); break;
case CONF_PRE_INT_BIT_NUMBER:335 sscanf(value_ptr, "%u", &input_uint);
if ( input_uint <= MAX_SCALER_BIT_NUMBER ) { simu_conf−>pre_scaler.int_bit_amount = input_uint; }
340 else { success = FAIL; } break;
345
case CONF_PRE_DEC_BIT_NUMBER: sscanf(value_ptr, "%u", &input_uint); if ( input_uint <= MAX_SCALER_BIT_NUMBER ) {
350 simu_conf−>pre_scaler.dec_bit_amount = input_uint; } else { success = FAIL;
355 } break;
case CONF_PRE_SCALING: sscanf(value_ptr, "%f", &input_float);
360 if ( (input_float >= MIN_SCALING) && (input_float <= MAX_SCALING) ) { simu_conf−>pre_scaler.scaling = input_float; }
365 else { success = FAIL; } break;
370
case CONF_POST_INT_BIT_NUMBER: sscanf(value_ptr, "%u", &input_uint); if ( input_uint <= MAX_SCALER_BIT_NUMBER ) {
Page 7/9simu_conf.c375 simu_conf−>post_scaler.int_bit_amount = input_uint;
} else { success = FAIL;
380 } break;
case CONF_POST_DEC_BIT_NUMBER: sscanf(value_ptr, "%u", &input_uint);
385 if ( input_uint <= MAX_SCALER_BIT_NUMBER ) { simu_conf−>post_scaler.dec_bit_amount = input_uint; } else
390 { success = FAIL; } break;
395 case CONF_POST_SCALING: sscanf(value_ptr, "%f", &input_float); if ( (input_float >= MIN_SCALING) && (input_float <= MAX_SCALING) ) {
400 simu_conf−>post_scaler.scaling = input_float; } else { success = FAIL;
405 } break;
case CONF_OFFSET: sscanf(value_ptr, "%u", &input_uint);
410 if ( input_uint <= MAX_OFFSET ) { if (simu_conf−>offset_in_use == FALSE) { simu_conf−>offset = input_uint;
415 } } else { success = FAIL;
420 } break;
case CONF_PSC_AVG_LEN: sscanf(value_ptr, "%u", &input_uint);
425 if ( (input_uint > 0) && (input_uint <= MAX_PSC_AVG_LEN) ) { simu_conf−>irm_psc_avg_len = input_uint; } else
430 { success = FAIL; } break;
Page 8/9simu_conf.c
435 case CONF_CPICH_AVG_LEN: sscanf(value_ptr, "%u", &input_uint); if ( (input_uint > 0) && (input_uint <= MAX_CPICH_AVG_LEN) ) { simu_conf−>irm_cpich_avg_len = input_uint;
440 } else { success = FAIL; }
445 break;
case CONF_CPICH_SCRAMBLING_CODE: sscanf(value_ptr, "%u", &input_uint); if ( input_uint <= MAX_SCRAMBLING_CODE_NR )
450 { simu_conf−>irm_scrc = input_uint; } else {
455 success = FAIL; } break; case CONF_SSC_MEAS_LEN:
460 sscanf(value_ptr, "%u", &input_uint); if ( (input_uint > 0) && (input_uint <= MAX_SSC_MEAS_LEN) ) { simu_conf−>ssc_meas_len = input_uint; }
465 else { success = FAIL; } break;
470
case CONF_ISYNC_SCRC_THRESHOLD: sscanf(value_ptr, "%f", &input_float); if ( input_float <= MAX_ISYNC_SCRC_THRESHOLD ) {
475 simu_conf−>isync_scrc_threshold = input_float; } else { success = FAIL;
480 } break;
default: /* Illegal case! */
485 success = FAIL; break; } /* switch(keyword) */
return(success);490 }
/* End of file. */
Page 9/9simu_conf.c
/*
Title: Configuration file reading utility for receiver simulator Header file
5 Kalle Tuulos’ M.Sc. Thesis Work File name: simu_conf.h
$Date: 2002−01−14 15:01:03+02 $10
Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/15
Page 1/2simu_conf.h/* This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify20 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful,25 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License30 along with 3WTG; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef SIMU_CONF_H35 #define SIMU_CONF_H
/* Configuration file read utility. If file is read successfully, returns SUCCESS. Otherwise returns FAIL. Second parameter contains line number of failed line. */uint16 simu_conf_read(SIMU_CONF_T * simu_conf, uint16 * line_number);
40
#endif/* End of file. */
Page 2/2simu_conf.h
/*
Title: Configuration file keywords for data generator Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_conf_keywords.h
$Date: 2002−01−14 15:01:03+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2simu_conf_keywords.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef GEN_CONF_KEYWORDS_H#define GEN_CONF_KEYWORDS_H
35
typedef enum{ CONF_FIRST_ITEM, CONF_OVERSAMPLING,
40 CONF_AGC_IN_USE, CONF_AGC_AVERAGING_TIME, CONF_AGC_ADC_MAX_AMPLITUDE, CONF_AGC_ADC_RANGE, CONF_AGC_AUTOMATIC_INIT_ENABLED,
45 CONF_AGC_AUTOMATIC_INIT_TRIGGER, CONF_BIT_LIMIT, CONF_PRE_INT_BIT_NUMBER, CONF_PRE_DEC_BIT_NUMBER, CONF_PRE_SCALING,
50 CONF_POST_INT_BIT_NUMBER, CONF_POST_DEC_BIT_NUMBER, CONF_POST_SCALING, CONF_OFFSET, CONF_PSC_AVG_LEN,
55 CONF_CPICH_AVG_LEN, CONF_CPICH_SCRAMBLING_CODE, CONF_SSC_MEAS_LEN, CONF_ISYNC_SCRC_THRESHOLD, CONF_END_OF_FILE,
60 CONF_LAST_ITEM}CONF_ITEMS;
#endif65 /* End of file. */
Page 2/2simu_conf_keywords.h
/*
Title: Simulator: Initial synchronization procedure Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_isync.c
$Date: 2002−01−14 15:01:02+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/7simu_isync.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <stdio.h>#include <malloc.h>
35 #include <string.h>#include <math.h>
#include "typedef.h" /* This has to be the first one */#include "simu_conf_keywords.h" /* This has to be second */
40 #include "global.h" /* This has to be third */#include "simu_common.h" /* This has to be fourth */#include "simu_ssc.h"#include "simu_mf.h"
45 #include "gen_scrc.h"
#include "simu_isync.h" /* Own header */
static uint16 simu_isync_psc(FILE * input_file, char * result_filename_base,50 SIMU_CONF_T * simu_conf,
uint16 * found_slot_offset);
static uint16 simu_isync_ssc(FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf,
55 uint16 * identification_succeeded, uint16 * found_code_group, uint16 * found_frame_offset);
static uint16 simu_isync_scrc(FILE * input_file, char * result_filename_base,60 SIMU_CONF_T * simu_conf,
uint16 * synchronization_found, uint16 code_group, uint16 * found_pri_scrambling_code);
65 /* Initial synchronization procedure. If there is nothing to complain, return SUCCESS. In case of errors, return FAIL. */uint16 simu_isync(FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf,
70 uint16 * synchronization_found, /* TRUE/FALSE */ uint16 * found_pri_scrambling_code, /* 0...511 */ uint16 * frame_offset /* Offset to start of frame */ ){
Page 2/7simu_isync.c
75 FILE * result_file; uint16 status = SUCCESS; uint16 offset; uint16 code_group;
80 /* Perform PSC search */ status = simu_isync_psc(input_file, result_filename_base, simu_conf, &offset); if (status != SUCCESS) {
85 /* Initial synchronization failed! */ return(FAIL); } /* Adjust slot offset */ simu_conf−>offset = offset;
90 *frame_offset = offset; printf("Slot offset: %d\n", offset);
rewind(input_file);
95 status = simu_isync_ssc(input_file, result_filename_base, simu_conf, synchronization_found, &code_group, &offset); /* Identify scrambling code group */ if ((status != SUCCESS) || (synchronization_found == FALSE)) {
100 /* Initial synchronization failed! */ return(status); }
/* Adjust frame offset */105 (*frame_offset) += CHIPS_IN_SLOT * simu_conf−>oversampling * offset;
simu_conf−>offset = *frame_offset; rewind(input_file);
/* Identify scrambling code */110 status = simu_isync_scrc(input_file, result_filename_base, simu_conf,
synchronization_found, code_group, found_pri_scrambling_code);
if ((status != SUCCESS) || (synchronization_found == FALSE))115 {
/* Initial synchronization failed! */ } else {
120 /* Create result file and print results */ status = create_result_file(&result_file, F_ISYNC, result_filename_base); if (status != SUCCESS) { return(FAIL);
125 } fprintf(result_file, "%d\n", *found_pri_scrambling_code); fprintf(result_file, "%d\n", *frame_offset); fclose(result_file); }
130 return(status);}
static uint16 simu_isync_psc( FILE * input_file, char * result_filename_base,
Page 3/7simu_isync.c135 SIMU_CONF_T * simu_conf,
uint16 * found_slot_offset){ FILE * result_file; fl32 * result_buffer;
140 uint16 result_buffer_size; uint16 pos_in_buffer; fl32 max_peak = 0; uint16 max_pos = 0; uint16 success;
145
success = create_result_file(&result_file, F_PSC, result_filename_base); if (success != SUCCESS) { fclose(input_file);
150 return(FAIL); }
result_buffer_size = CHIPS_IN_SLOT * simu_conf−>oversampling; result_buffer = malloc( sizeof( fl32) * result_buffer_size);
155 success = simu_mf_psc(input_file, result_file, result_buffer, simu_conf);
if (success != SUCCESS) {
160 free(result_buffer); fclose(result_file); return(success); } /* Search for peak */
165 for (pos_in_buffer = 0; pos_in_buffer < result_buffer_size; pos_in_buffer++) { if (result_buffer[pos_in_buffer] > max_peak) { max_peak = result_buffer[pos_in_buffer];
170 max_pos = pos_in_buffer; } }
*found_slot_offset = max_pos;175
/* Done */ free(result_buffer); fclose(result_file);
180 return(SUCCESS);}
static uint16 simu_isync_ssc( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf,
185 uint16 * identification_succeeded, uint16 * found_code_group, uint16 * found_frame_offset){ FILE * result_file;
190 uint16 success;
success = create_result_file(&result_file, F_SSC, result_filename_base); if (success != SUCCESS) {
Page 4/7simu_isync.c
195 fclose(input_file); return(FAIL); }
success = simu_ssc(input_file, result_file, simu_conf,200 identification_succeeded, found_code_group,
found_frame_offset);
fclose(result_file);205 return(success);
}
static uint16 simu_isync_scrc( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf,
210 uint16 * synchronization_found, uint16 code_group, uint16 * found_pri_scrambling_code){ FILE * result_file;
215 uint16 success = SUCCESS; uint16 scrc; fl32 scrc_correlation[PRIMARY_SCRAMBLING_CODES_IN_GROUP]; fl32 max_correlation; fl32 average_correlation;
220 uint16 max_code; SCRC_GEN_T scrc_reg; int16 scrc_i[CHIPS_IN_SF256_SYMBOL]; int16 scrc_q[CHIPS_IN_SF256_SYMBOL]; COMPLEX_FLOAT * ref_seq;
225 COMPLEX_FLOAT * test_seq; uint16 seq_len; uint16 seq_count; uint16 sample_count;
230 printf("Start scrambling code search ... ");
/* Set response to FALSE */ *synchronization_found = FALSE;
235 /* Allocate sequence memories */ seq_len = CHIPS_IN_SF256_SYMBOL * simu_conf−>oversampling; ref_seq = malloc( sizeof(COMPLEX_FLOAT) * seq_len); test_seq = malloc( sizeof(COMPLEX_FLOAT) * seq_len);
240 success = create_result_file(&result_file, F_ISYNC, result_filename_base); if (success != SUCCESS) { fclose(input_file); return(FAIL);
245 } /* Skip offset */ for (seq_count = 0; (seq_count < simu_conf−>offset) && (success == SUCCESS); seq_count++)
250 { success = get_new_value(input_file, &test_seq[0], simu_conf); }
/* Fetch test sequence from file */
Page 5/7simu_isync.c255 for (seq_count = 0; (seq_count < seq_len) && (success == SUCCESS);
seq_count++) { success = get_new_value(input_file, &test_seq[seq_count], simu_conf); }
260
if (success != SUCCESS) { free(ref_seq); free(test_seq);
265 return(FAIL); } /* Start testing scrambling code sequences */ max_correlation = 0;
270 average_correlation = 0; max_code = 0; for (scrc = 0; scrc < PRIMARY_SCRAMBLING_CODES_IN_GROUP; scrc++) { /* Initialize scrambling code generator for candidate */
275 gen_scrc_init(code_group * SCRAMBLING_CODES_PER_GROUP + scrc * MAX_SEC_SCRAMBLING_CODE, &scrc_reg);
/* Generate one symbolful of scrambling code */280 gen_scrc(CHIPS_IN_SF256_SYMBOL, &scrc_reg,
&scrc_i[0], &scrc_q[0]);
/* Oversample scrambling code */ for (seq_count = 0; seq_count < CHIPS_IN_SF256_SYMBOL; seq_count++)
285 { for (sample_count = 0; sample_count < simu_conf−>oversampling; sample_count++) { ref_seq[seq_count * simu_conf−>oversampling + sample_count].i =
290 scrc_i[seq_count]; ref_seq[seq_count * simu_conf−>oversampling + sample_count].q = −scrc_q[seq_count]; } }
295
/* Calculate correlation between reference sequence i.e. scrambling code candidate and test sequence */ scrc_correlation[scrc] = correlate(test_seq, ref_seq,
300 CHIPS_IN_SF256_SYMBOL * simu_conf−>oversampling);
average_correlation += scrc_correlation[scrc];
/* Was this correlation result maximum? */305 if (max_correlation < scrc_correlation[scrc])
{ max_correlation = scrc_correlation[scrc]; max_code = scrc; }
310 }
/* Calculate average correlation */ average_correlation /= PRIMARY_SCRAMBLING_CODES_IN_GROUP;
Page 6/7simu_isync.c
315 if (max_correlation > simu_conf−>isync_scrc_threshold * average_correlation) { *found_pri_scrambling_code = code_group * SCRAMBLING_CODES_PER_GROUP + max_code * MAX_SEC_SCRAMBLING_CODE;
320 *synchronization_found = TRUE; } else { *synchronization_found = FALSE;
325 }
printf("done.\n"); free(test_seq);
330 free(ref_seq); return(SUCCESS);}
/* End of file. */
Page 7/7simu_isync.c
/*
Title: Simulator: Initial synchronization procedure, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_isync.h
$Date: 2002−01−14 15:01:01+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2simu_isync.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef SIMU_ISYNC_H#define SIMU_ISYNC_H
35
/* Initial synchronization procedure. If there is nothing to complain, return SUCCESS. In case of errors, return FAIL. */uint16 simu_isync(FILE * input_file, char * result_filename_base,
40 SIMU_CONF_T * simu_conf, uint16 * synchronization_found, /* TRUE/FALSE */ uint16 * found_pri_scrambling_code, /* 0...511 */ uint16 * frame_offset /* Offset to start of frame */ );
45
#endif/* End of file. */
Page 2/2simu_isync.h
/*
Title: Simulator, main file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_main.c
$Date: 2002−01−14 15:01:00+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/11simu_main.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <stdio.h>#include <malloc.h>
35 #include <string.h>#include <math.h>
#include "typedef.h" /* This has to be the first one */#include "simu_conf_keywords.h" /* This has to be second */
40 #include "global.h" /* This has to be third */#include "simu_common.h" /* This has to be fourth */
#include "simu_conf.h"#include "simu_mf.h"
45 #include "simu_ssc.h"#include "simu_agc.h"#include "simu_isync.h"
#define START_MOMENT 050 /* Measurement window is one symbol */
#define MEAS_WINDOW CHIPS_IN_SF256_SYMBOL#define RESULT_WINDOW (MEAS_WINDOW * 10)/* Two frames */#define MEASUREMENTS (15 * 10 * 2)
55 #define MEAS_TIME (MEASUREMENTS * MEAS_WINDOW)
const char * result_filename_ending[] ={ "_isync.asc",
60 "_psc.asc", "_cpich_power.asc", "_cpich_phase.asc", "_ssc.asc"};
65
#define MAX_OPERS 8
const char * operations_strings[] ={
70 "psc", "PSC", "irm", "IRM", "ssc",
Page 2/11simu_main.c
75 "SSC", "isync", "ISYNC"};
80 const SIMU_OPERATION operations_opers[] ={ DO_PSC, DO_PSC, DO_IRM,
85 DO_IRM, DO_SSC, DO_SSC, DO_ISYNC, DO_ISYNC
90 };
int main( int argc, char * argv[]);static SIMU_OPERATION get_operation( const char * param);static void simu_usage( const char * file_name);
95 void bit_limit( fl32 * value, SCALER_T * scaler);void pre_scaler(COMPLEX_FLOAT * value, SIMU_CONF_T * conf);
uint16 simu_do_psc( FILE * input_file, char * result_filename_base,100 SIMU_CONF_T * simu_conf);
uint16 simu_do_ssc( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf);uint16 simu_do_irm( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf);
105 uint16 simu_do_isync( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf);
int main( int argc, char * argv[])110 {
SIMU_CONF_T simu_conf;
FILE * input_file; char * result_filename_base;
115 char * param; char * found_opt_param; uint16 param_count; uint16 conf_file_line; uint16 success;
120 uint16 show_license = FALSE; SIMU_OPERATION operation;
/* Initialize simulator configuration structure */125 simu_conf.opt_conffile = FALSE;
simu_conf.offset_in_use = FALSE; simu_conf.offset = 0; strcpy(simu_conf.conf_file_name, "simu.cfg");
130 debug_value = DEBUG_PRINT;
/* First, get operation. */ if (argc > 3) {
Page 3/11simu_main.c135 operation = get_operation(argv[1]);
} else { operation = PARAM_FAILURE;
140 }
if ((argc == 2) && (strcmp(argv[1], "−license") == 0)) { show_license = TRUE;
145 }
/* Print header information */ print_header(SIMU, show_license);
150 if (show_license) { exit(1); } else if (operation == PARAM_FAILURE)
155 { simu_usage(argv[0]); exit(1); }
160 /* If there are optional parameters, evaluate them. */ if (argc > 4) { for (param_count = 2; param_count < (argc−2); param_count++) {
165 param = argv[param_count];
if ((simu_conf.opt_conffile == FALSE) && (search_keyword(param, "−conffile=", &found_opt_param) == SUCCESS))
170 { simu_conf.opt_conffile = TRUE; if (copy_filename(found_opt_param, simu_conf.conf_file_name) != SUCCESS) {
175 /* Did not succeed in copying filename. */ operation = PARAM_FAILURE; break; } }
180 else if ((simu_conf.offset_in_use == FALSE) && (search_keyword(param, "−offset=", &found_opt_param) == SUCCESS)) { simu_conf.offset_in_use = TRUE;
185 sscanf(found_opt_param, "%u", &simu_conf.offset); if (simu_conf.offset > MAX_OFFSET) { /* Too big offset. */ operation = PARAM_FAILURE;
190 break; } } else {
Page 4/11simu_main.c
195 /* Optional parameter was invalid. */ operation = PARAM_FAILURE; break; } }
200 }
if (operation == PARAM_FAILURE) { printf("Invalid parameters! Please execute ’");
205 printf(argv[0]); printf("’ to get list of parameters.\n"); exit(1); }
210 /* Get input file name. */ input_file = fopen(argv[argc−2], "r"); if (input_file == NULL) { printf("Error opening input file. Aborting...\n\n");
215 exit(1); }
/* Get resuit file name base. */ result_filename_base = argv[argc−1];
220
/* Read configuration file. */ success = simu_conf_read(&simu_conf, &conf_file_line); if (success != SUCCESS) {
225 printf("Error reading configuration file at line %u.\n", conf_file_line); printf("Aborting...\n\n"); exit(0); }
230 /* Initialize AGC */ agc_init(&simu_conf);
/* Start simulation. */ switch(operation)
235 { case DO_PSC: /* Primary synchronization code search i.e. slot synchronization detection */ success = simu_do_psc(input_file, result_filename_base, &simu_conf);
240 break; case DO_SSC: /* Secondary synchronization code search i.e. scrambling code group & frame synchronization detection */
245 success = simu_do_ssc(input_file, result_filename_base, &simu_conf); break; case DO_IRM: /* Impulse response measurement from CPICH */
250 success = simu_do_irm(input_file, result_filename_base, &simu_conf); break; case DO_ISYNC:
Page 5/11simu_main.c255 /* Complete initial synchronization */
success = simu_do_isync(input_file, result_filename_base, &simu_conf); break;
260 default: printf("Illegal params.\n"); success = FAIL; break; }
265
fclose(input_file);
if (success != FAIL) {
270 printf("All simulations done.\n\n"); } else { printf("Error in simulations.\n\n");
275 } exit(0);
}280
static SIMU_OPERATION get_operation( const char * param){ uint16 i; SIMU_OPERATION operation = PARAM_FAILURE;
285
for (i = 0; i < MAX_OPERS; i++) { if (strcmp(param, operations_strings[i]) == 0) {
290 operation = operations_opers[i]; break; } }
295 return(operation);}; /* Print command line use instructions */static void simu_usage( const char * file_name)
300 { printf("Command line usage:\n"); printf("−−−−−−−−−−−−−−−−−−−\n\n"); printf(file_name); printf(" <PROC> [OPTS] <input_file> <result_filename_base>\n\n");
305 printf("where <PROC> is one of following:\n"); printf(" ISYNC Perform initial synchronization procedure.\n"); printf(" PSC Perform primary synchronization code search.\n"); printf(" IRM Perform impulse response measurement for common pilot channel.\n"); printf(" SSC Perform correlation measurement for secondary synchronization codes.\n\n");
310 printf("For information about optional settings and naming of output "); printf("files,\nplease see User’s manual.\n");
Page 6/11simu_main.c
}
315 uint16 get_new_value( FILE * input_file, COMPLEX_FLOAT * value, SIMU_CONF_T * conf){ uint16 return_value;
320 /* Fetch value from file */ return_value = read_from_file(input_file, value); if (return_value != SUCCESS) { return(return_value);
325 } /* AGC */ agc_main(value);
330 /* Pre−scaler: run if bit limitation is on */ if (conf−>bit_limit == TRUE) { pre_scaler(value, conf); }
335 /* All done! */ return(SUCCESS);}
340 void pre_scaler(COMPLEX_FLOAT * value, SIMU_CONF_T * conf){ if (conf−>bit_limit) { /* Scale input value */
345 (*value).i *= conf−>pre_scaler.scaling; (*value).q *= conf−>pre_scaler.scaling; /* Apply bit limitation */ bit_limit(&((*value).i), &(conf−>pre_scaler));
350 bit_limit(&((*value).q), &(conf−>pre_scaler)); }}
fl32 post_scaler( fl32 value, SIMU_CONF_T * conf)355 {
fl32 result;
result = value;
360 /* If bit limitation is off, do not modify result */ if (conf−>bit_limit > 0) { /* Post−scaling is active */
365 /* Scale result */ result *= conf−>post_scaler.scaling;
/* Apply bit limitation */ bit_limit(&result, &(conf−>post_scaler));
370 } return(result);
Page 7/11simu_main.c}
375 void bit_limit( fl32 * value, SCALER_T * scaler){ fl32 result; uint32 result_int; uint32 result_dec;
380 fl32 value_dec; int16 sign_bit; uint32 ref_int; uint32 ref_dec;
385 /* Extract sign bit and separate float number to integer and decimal parts */ if (*value < 0) { sign_bit = −1; /* Change sign of value for calculations */
390 *value *= −1; } else { sign_bit = 1;
395 } result_int = floor(*value); value_dec = *value − result_int;
400 /* Calculate saturate reference for integer part */ if (scaler−>int_bit_amount == 0) { ref_int = 0; }
405 else { ref_int = (1 << scaler−>int_bit_amount) − 1; }
410 /* Apply bit limitation to integer part. Saturate if needed. */ if (result_int > ref_int) { result_int = ref_int; }
415
result = result_int;
/* Calculate multiplication factor for decimal part. */ if (scaler−>dec_bit_amount > 0)
420 { ref_dec = 1 << scaler−>dec_bit_amount; value_dec *= ref_dec; result_dec = floor(value_dec); result += ( fl32 )result_dec/( fl32 )ref_dec;
425 } /* Apply sign bit */ result *= sign_bit;
430 /* Bit limitation done */ *value = result;}
Page 8/11simu_main.c
uint16 simu_do_psc( FILE * input_file, char * result_filename_base,435 SIMU_CONF_T * simu_conf)
{ FILE * result_file;
uint16 success = SUCCESS;440 fl32 * result_buffer;
success = create_result_file(&result_file, F_PSC, result_filename_base); if (success != SUCCESS) {
445 fclose(input_file); return(FAIL); } result_buffer = malloc( sizeof( fl32)*CHIPS_IN_SLOT * simu_conf−>oversampling);
450 success = simu_mf_psc(input_file, result_file, result_buffer, simu_conf); free(result_buffer); fclose(result_file);
455 return(success);}
uint16 simu_do_ssc( FILE * input_file, char * result_filename_base,460 SIMU_CONF_T * simu_conf)
{ FILE * result_file; uint16 success; uint16 identified_scrc_group;
465 uint16 group_identified; uint16 frame_sync;
success = create_result_file(&result_file, F_SSC, result_filename_base); if (success != SUCCESS)
470 { fclose(input_file); return(FAIL); }
475 success = simu_ssc(input_file, result_file, simu_conf, &group_identified, &identified_scrc_group, &frame_sync); fclose(result_file); return(success);
480 }
uint16 simu_do_irm( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf){
485 uint16 success = SUCCESS; uint16 meas_win_len; uint16 result_pos; fl32 power; fl32 phase;
490 FILE * power_file; FILE * phase_file;
Page 9/11simu_main.c COMPLEX_FLOAT * output_data;
495 success = create_result_file(&power_file, F_CPICH_POWER, result_filename_base); if (success != SUCCESS) { fclose(input_file);
500 return(FAIL); } success = create_result_file(&phase_file, F_CPICH_PHASE, result_filename_base);
505 if (success != SUCCESS) { fclose(input_file); fclose(power_file); return(FAIL);
510 }
meas_win_len = CHIPS_IN_SF256_SYMBOL * simu_conf−>oversampling; output_data = malloc( sizeof(COMPLEX_FLOAT) * meas_win_len);
515 success = simu_mf_irm(input_file, simu_conf, output_data);
if (success == SUCCESS) { /* Print result data */
520 for (result_pos = 0; result_pos < meas_win_len; result_pos++) { power = complex_to_power(output_data[result_pos]); phase = complex_to_phase(output_data[result_pos]); fprintf(power_file, "%f\n", post_scaler(power, simu_conf));
525 fprintf(phase_file, "%f\n", post_scaler(phase, simu_conf)); } }
fclose(power_file);530 fclose(phase_file);
free(output_data); return(success);}
535
uint16 simu_do_isync( FILE * input_file, char * result_filename_base, SIMU_CONF_T * simu_conf){ uint16 success;
540 uint16 synchronization_found; uint16 found_pri_scrambling_code; uint16 frame_offset;
success = simu_isync(input_file, result_filename_base, simu_conf,545 &synchronization_found,
&found_pri_scrambling_code, &frame_offset);
if ((success == SUCCESS) && (synchronization_found == TRUE))550 {
printf("Synchronization found. Primary scrambling code: %d ", found_pri_scrambling_code);
Page 10/11simu_main.c
printf("Frame offset: %d\n", frame_offset); }
555 return(success);}
uint16 create_result_file(FILE ** result_file,560 SIMU_FILENAME_ENDINGS filetype,
char * result_filename_base){ uint16 success; char result_file_name[FILENAME_LENGTH];
565
strcpy(result_file_name, result_filename_base); strcat(result_file_name, result_filename_ending[filetype]);
*result_file = fopen(result_file_name, "w");570 if (*result_file == NULL)
{ printf("Error creating result file.\n"); success = FAIL; }
575 else { success = SUCCESS; }
580 return(success);}
/* End of file. */
Page 11/11simu_main.c
/*
Title: Simulator: matched filter Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_mf.c
$Date: 2002−01−14 15:00:58+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/7simu_mf.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <math.h>#include <malloc.h>
35 #include <string.h> /* for memset */
#include "typedef.h" /* This has to be the first one */#include "simu_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */
40 #include "simu_common.h" /* This has to be fourth */
#include "simu_mf.h"#include "gen_psc.h"#include "gen_scrc.h"
45
uint16 simu_mf_psc( FILE * input_file, FILE * result_file, fl32 * output_data, SIMU_CONF_T * simu_conf){ uint32 start_moment;
50 uint16 oversampling; uint16 avg_len; int16 psc_seq[CHIPS_IN_SF256_SYMBOL]; COMPLEX_FLOAT * ref_seq; COMPLEX_FLOAT * shift_reg;
55 COMPLEX_FLOAT current_result; uint16 success = SUCCESS; uint16 offset; uint16 sample_in_symbol;
60 uint16 data_pos;#if 0 uint16 ref_seq_pos;#endif uint16 total_symbols;
65 uint16 symbols_to_go; uint16 meas_win_len; uint16 ref_seq_len;
start_moment = simu_conf−>offset;70 avg_len = simu_conf−>irm_psc_avg_len;
oversampling = simu_conf−>oversampling;
printf("Start PSC processing ...");
Page 2/7simu_mf.c
75 /* Check input pointers */ if ((input_file == NULL) || (output_data == NULL)) { debug_print("MF: null pointers as parameters.\n", ERROR_PRINT); return(FAIL);
80 }
/* Check averaging length */ if (avg_len == 0) {
85 debug_print("MF: zero averaging length.\n", ERROR_PRINT); return(FAIL); } /* Generate PSC sequence */
90 success = gen_psc(&psc_seq[0]); if (success != SUCCESS) { debug_print("MF: error generating PSC sequence.\n", ERROR_PRINT); return(FAIL);
95 }
/* Search start moment */ for (offset = 0; offset < start_moment; offset++) {
100 success = get_new_value(input_file, ¤t_result, simu_conf); if (success != SUCCESS) { debug_print("MF: error reading input data.\n", ERROR_PRINT);
105 return(FAIL); } }
/* Allocate sequence memories */110 ref_seq_len = CHIPS_IN_SF256_SYMBOL * oversampling;
ref_seq = malloc( sizeof(COMPLEX_FLOAT) * ref_seq_len); shift_reg = malloc( sizeof(COMPLEX_FLOAT) * ref_seq_len); meas_win_len = CHIPS_IN_SLOT * oversampling;
115
for (offset = 0; offset < CHIPS_IN_SF256_SYMBOL; offset++) { for (data_pos = 0; data_pos < oversampling; data_pos++) {
120 ref_seq[offset * oversampling + data_pos].i = psc_seq[offset]; ref_seq[offset * oversampling + data_pos].q = −psc_seq[offset]; } }
125 /* Clear result buffer */ memset(output_data, 0, sizeof( fl32) * meas_win_len); /* Read shift register full of data */ for (offset = 0; offset < ref_seq_len; offset++)
130 { success = get_new_value(input_file, &shift_reg[offset], simu_conf); if (success != SUCCESS) { debug_print("MF: Error reading source data!\n",
Page 3/7simu_mf.c135 ERROR_PRINT);
free(shift_reg); free(ref_seq); return(FAIL); }
140 }
/* NOTE: From this point forward, new data samples should be read to last position in shift register. Shift register should be moved so, that the oldest sample is in position 0.
145 */
data_pos = 0; offset = 0;
150 total_symbols = avg_len * 15;
for (symbols_to_go = total_symbols; symbols_to_go > 0; symbols_to_go−−) { /* Update progress indicator */
155 printf("."); for (sample_in_symbol = 0; sample_in_symbol < (CHIPS_IN_SF256_SYMBOL * oversampling); sample_in_symbol++) {
160 current_result.i = 0; current_result.q = 0;
/* Calculate correlation between shift register and known sequence */
165 output_data[offset] += correlate(shift_reg, ref_seq, ref_seq_len); /* Shift register */ for (data_pos = 0; data_pos < (ref_seq_len − 1); data_pos++) {
170 shift_reg[data_pos] = shift_reg[data_pos + 1]; }
/* Fetch new sample */ success = get_new_value(input_file,
175 &shift_reg[ref_seq_len − 1], simu_conf);
if (success != SUCCESS) {
180 debug_print("Error reading input data file!\n", ERROR_PRINT); break; } offset++;
185 if (offset == meas_win_len) { offset = 0; } }
190 }
printf("\n"); /* All done, print results to file. */
Page 4/7simu_mf.c
195 for (offset = 0; offset < meas_win_len; offset++) { fprintf(result_file, "%f\n", post_scaler(output_data[offset], simu_conf)); }
200 free(ref_seq); free(shift_reg); return(SUCCESS);
205 }
uint16 simu_mf_irm( FILE * input_file, SIMU_CONF_T * simu_conf,
210 COMPLEX_FLOAT * output_data){ uint16 success = SUCCESS; uint32 start_moment; uint16 oversampling;
215 uint32 result_pos; uint16 scrc_pos; uint16 ref_pos; uint16 average_count; uint16 i; /* Misc. loop counters */
220 COMPLEX_FLOAT current_result; uint32 meas_win_len;
COMPLEX_FLOAT * ref_seq;225 COMPLEX_FLOAT * shift_reg;
SCRC_GEN_T scrc_reg; int16 scrc_i[CHIPS_IN_SF256_SYMBOL]; int16 scrc_q[CHIPS_IN_SF256_SYMBOL];
230
start_moment = simu_conf−>offset; oversampling = simu_conf−>oversampling; meas_win_len = CHIPS_IN_SF256_SYMBOL * oversampling;
235 /* Check input pointers */ if ((input_file == NULL) || (output_data == NULL)) { debug_print("MF: null pointers as parameters.\n", ERROR_PRINT); return(FAIL);
240 } /* Check averaging amount */ if (simu_conf−>irm_cpich_avg_len == 0) {
245 debug_print("MF: zero averaging amount.\n", ERROR_PRINT); return(FAIL); } /* Search start moment */
250 for (result_pos = 0; result_pos < start_moment; result_pos++) { success = get_new_value(input_file, ¤t_result, simu_conf);
Page 5/7simu_mf.c255 if (success != SUCCESS)
{ debug_print("MF: error reading input data.\n", ERROR_PRINT); return(FAIL); }
260 }
/* Allocate memories and clear result buffer */ ref_seq = malloc( sizeof(COMPLEX_FLOAT) * meas_win_len); shift_reg = malloc( sizeof(COMPLEX_FLOAT) * meas_win_len);
265 memset(output_data, 0, sizeof(COMPLEX_FLOAT) * meas_win_len); /* Initialize scrambling code generator */ gen_scrc_init(simu_conf−>irm_scrc, &scrc_reg);
270 /* Read shift register full of data */ for (result_pos = 0; result_pos < meas_win_len; result_pos++) { success = get_new_value(input_file, &(shift_reg[result_pos]), simu_conf); if (success != SUCCESS)
275 { break; } }
280 /* NOTE: From this point forward, new data samples should be read to last position in shift register. Shift register should be moved so, that the oldest sample is in position 0. */ for (average_count = 0; average_count < simu_conf−>irm_cpich_avg_len;
285 average_count++) { if (success != SUCCESS) { break;
290 } /* Generate first symbol to shift register */ gen_scrc(CHIPS_IN_SF256_SYMBOL, &scrc_reg, &scrc_i[0], &scrc_q[0]);
295
/* Copy symbol as reference sequence and apply oversampling */ ref_pos = 0; for (scrc_pos = 0; scrc_pos < CHIPS_IN_SF256_SYMBOL; scrc_pos++) {
300 for (i = 0; i < oversampling; i++) { /* Conjugate imaginary of scrambling code is loaded to reference sequence */ ref_seq[ref_pos].i = scrc_i[scrc_pos];
305 ref_seq[ref_pos].q = −scrc_q[scrc_pos]; ref_pos++; } }
310 /* Correlate one measurement window */ for (result_pos = 0; result_pos < meas_win_len; result_pos++) { if (success != SUCCESS) {
Page 6/7simu_mf.c
315 break; }
for (ref_pos = 0; ref_pos < (meas_win_len−1); ref_pos++) {
320 complex_product_and_add(ref_seq[ref_pos], shift_reg[ref_pos], &(output_data[result_pos]));
/* Shift contents of shift register */325 shift_reg[ref_pos] = shift_reg[ref_pos+1];
}
complex_product_and_add(ref_seq[meas_win_len−1], shift_reg[meas_win_len−1],
330 &(output_data[result_pos]));
/* Get new datasample to shift register */ success = get_new_value(input_file, &(shift_reg[meas_win_len−1]), simu_conf);
335 } /* Correlation of one measurement window done */ }
if (success != SUCCESS)340 {
debug_print("MF: Error reading source data!\n", ERROR_PRINT); } free(ref_seq);
345 free(shift_reg); return(success);}
350 fl32 correlate(COMPLEX_FLOAT * data, COMPLEX_FLOAT * ref, uint32 len){ uint32 pos;
355 fl32 result_abs; COMPLEX_FLOAT result; result.i = 0; result.q = 0;
360
for (pos = 0; pos < len; pos++) { complex_product_and_add(data[pos], ref[pos], &result); }
365
result_abs = complex_to_power(result); return(result_abs);}
370 /* End of file. */
Page 7/7simu_mf.c
/*
Title: Simulator: matched filter, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_mf.h
$Date: 2002−01−14 15:00:57+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2simu_mf.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
typedef enum{
35 COHERENT, NONCOHERENT}COHERENCE;
40 uint16 simu_mf_irm(FILE * input_file, SIMU_CONF_T * simu_conf, COMPLEX_FLOAT * output_data);
uint16 simu_mf_psc(FILE * input_file, FILE * result_file, fl32 * output_data, SIMU_CONF_T * simu_conf);
45
fl32 correlate(COMPLEX_FLOAT * data, COMPLEX_FLOAT * ref, uint32 ref_len);
50 /* End of file. */
Page 2/2simu_mf.h
/*
Title: Simulator: SSC identification Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_ssc.c
$Date: 2002−01−14 15:00:56+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/6simu_ssc.c15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#include <malloc.h>#include "typedef.h" /* This has to be the first one */
35 #include "simu_conf_keywords.h" /* This has to be second */#include "global.h" /* This has to be third */#include "simu_common.h" /* This has to be fourth */
#include "simu_ssc.h"40 #include "gen_ssc.h"
#include "simu_mf.h"
static COMPLEX_FLOAT * ssc_sequence[SSC_GROUPS];
45 static void init_ssc_sequences( uint16 oversampling);static void deallocate_sequences( void );
uint16 simu_ssc( FILE * input_file, FILE * result_file, SIMU_CONF_T * simu_conf,
50 uint16 * group_identified, /* TRUE/FALSE */ uint16 * identified_scrc_group, /* 0...63 */ uint16 * frame_sync /* 0...14 */ ){
55 uint16 oversampling; uint32 start_moment; uint16 ssc_result_seq[SLOTS_IN_FRAME]; fl32 max_result; uint16 ssc_group;
60 uint16 scrc_group; uint16 slot_in_frame; uint16 symbol_in_slot; uint32 sample_in_symbol; uint16 status = SUCCESS;
65 uint16 seq_len; fl32 correlation_result[SLOTS_IN_FRAME][SSC_GROUPS];
COMPLEX_FLOAT * symbol;70
*group_identified = FALSE; start_moment = simu_conf−>offset; oversampling = simu_conf−>oversampling;
Page 2/6simu_ssc.c
75
printf("Start SSC search ... "); init_ssc_sequences(oversampling);
80 seq_len = CHIPS_IN_SF256_SYMBOL * oversampling; symbol = malloc(sizeof(COMPLEX_FLOAT) * seq_len); /* Search for start moment */ for (sample_in_symbol = 0; sample_in_symbol < start_moment;
85 sample_in_symbol++) { status = get_new_value(input_file, &symbol[0], simu_conf); if (status != SUCCESS) {
90 break; } } if (status != SUCCESS)
95 { free(symbol); deallocate_sequences(); return (FAIL); }
100 for (slot_in_frame = 0; slot_in_frame < SLOTS_IN_FRAME; slot_in_frame++) { for (symbol_in_slot = 0; symbol_in_slot < SF256_SYMBOLS_IN_SLOT; symbol_in_slot++)
105 { for (sample_in_symbol = 0; sample_in_symbol < seq_len; sample_in_symbol++) {
110 status = get_new_value(input_file, &symbol[sample_in_symbol], simu_conf); if (status != SUCCESS) { break;
115 } } if (status != SUCCESS) { break;
120 }
if (symbol_in_slot == 0) { /* Now calculate correlations */
125 for (ssc_group = 0; ssc_group < SSC_GROUPS; ssc_group++) { /* Correlate one symbol of data */ correlation_result[slot_in_frame][ssc_group] = correlate(symbol, ssc_sequence[ssc_group], seq_len);
130 fprintf(result_file, "%f ", post_scaler(correlation_result[slot_in_frame] [ssc_group], simu_conf)); } }
Page 3/6simu_ssc.c135 } /* symbol in slot */
fprintf(result_file, "\n"); if (status != SUCCESS)
140 { break; } } /* slot in frame */
145 /* One frameful of data correlated. Search maximum correlation values. */ for (slot_in_frame = 0; slot_in_frame < SLOTS_IN_FRAME; slot_in_frame++) { max_result = 0; for (ssc_group = 0; ssc_group < SSC_GROUPS; ssc_group++)
150 { if (max_result < correlation_result[slot_in_frame][ssc_group]) { max_result = correlation_result[slot_in_frame][ssc_group]; ssc_result_seq[slot_in_frame] = ssc_group+1;
155 } } }
for (*frame_sync = 0; *frame_sync < SLOTS_IN_FRAME; (*frame_sync)++)160 {
for (scrc_group = 0; scrc_group < SCRAMBLING_CODE_GROUPS; scrc_group++) { for (slot_in_frame = 0; slot_in_frame < SLOTS_IN_FRAME; slot_in_frame++)
165 { if (ssc_result_seq[slot_in_frame] != fdd_ssc_allocation[scrc_group][(slot_in_frame + *frame_sync) % SLOTS_IN_FRAME]) {
170 break; } }
if (slot_in_frame == SLOTS_IN_FRAME)175 {
*group_identified = TRUE; break; } }
180 if (*group_identified) { break; } }
185 /* Now, if scrc_group equals to SCRAMBLING_CODE_GROUPS, scrc_group was not identified. Otherwise group was identified. */ *identified_scrc_group = scrc_group; if (*group_identified)
190 { printf("Identified group: %d ", scrc_group); printf("Frame sync: %d\n", *frame_sync); } else
Page 4/6simu_ssc.c
195 { printf("Group not identified.\n"); } /* All done. */
200 deallocate_sequences(); free(symbol); if (status != SUCCESS) {
205 return(FAIL); } else { return(SUCCESS);
210 }}
/* Function for creating table of oversampled SSC sequences. This function has to be called before starting simulations. */
215 static void init_ssc_sequences( uint16 oversampling){ uint16 seq_nr; uint16 chip_in_seq; uint16 sample;
220 int16 seq[CHIPS_IN_SF256_SYMBOL];
for (seq_nr = 0; seq_nr < SSC_GROUPS; seq_nr++) {
225 /* SSC sequence tables are stored in dynamically allocated memory */ ssc_sequence[seq_nr] = malloc( sizeof(COMPLEX_FLOAT) * CHIPS_IN_SF256_SYMBOL * oversampling);
/* Generate SSC sequence by using function from data generator */230 gen_ssc(seq_nr + 1, &seq[0]);
/* Copy each chip of SSC */ for (chip_in_seq = 0; chip_in_seq < CHIPS_IN_SF256_SYMBOL; chip_in_seq++)
235 { /* Perform oversampling */ for (sample = 0; sample < oversampling; sample++) { /* SSC sequence tables are conjugate imaginaries of
240 real SSC sequences */ ssc_sequence[seq_nr][chip_in_seq*oversampling + sample].i = seq[chip_in_seq]; ssc_sequence[seq_nr][chip_in_seq*oversampling + sample].q = −seq[chip_in_seq];
245 } } }}
250 /* Function for destroying table of oversampled SSC sequences. This function has to be called after simulations are complete. */static void deallocate_sequences( void){ uint16 seq_nr;
Page 5/6simu_ssc.c255
for (seq_nr = 0; seq_nr < SSC_GROUPS; seq_nr++) { free(ssc_sequence[seq_nr]); }
260 }
/* End of file. */
Page 6/6simu_ssc.c
/*
Title: Simulator: SSC identification, interface file Kalle Tuulos’ M.Sc. Thesis Work
5 File name: simu_ssc.c
$Date: 2002−01−14 15:00:55+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2simu_ssc.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
/* Identify scrambling code group. Returns SUCCESS if nothing to complain, but if there are errors, return value is FAIL. */
35 uint16 simu_ssc(FILE * input_file, FILE * result_file, SIMU_CONF_T * simu_conf, uint16 * group_identified, /* TRUE/FALSE */ uint16 * identified_scrc_group, /* 0...63 */ uint16 * frame_sync /* 0...14 */
40 );
/* End of file. */
Page 2/2simu_ssc.h
/*
Title: Basic type definitions Kalle Tuulos’ M.Sc. Thesis Work
5 File name: typedef.h
$Date: 2002−01−14 15:00:54+02 $
10 Copyright (C) 2001, 2002 Kalle Tuulos, [email protected] under the terms of the GNU General Public License
*/
Page 1/2typedef.h15 /*
This file is part of 3WTG − 3GPP WCDMA Testdata Generator.
3WTG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
3WTG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with 3WTG; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111−1307 USA*/
#ifndef TYPEDEF_H#define TYPEDEF_H
35
/* Boolean definitions */#define TRUE 1#define FALSE 0
40 /* Success definitions */#define SUCCESS 1#define FAIL 0
/* Executable exit value definitions */45 #define EXIT_WITH_SUCCESS 0
#define EXIT_WITH_FAILURE 1
/* Most significant bit number in 16 bit digit */#define MSB 15
50
/* Standard types */typedef unsigned short int uint16 ;typedef signed short int int16 ;typedef unsigned int uint32 ;
55 typedef signed int int32 ;typedef float fl32 ;typedef double fl64 ;
/* Complex I and Q type */60 typedef struct
{ fl32 i; fl32 q;}
65 COMPLEX_FLOAT;
#endif/* End of file */
Page 2/2typedef.h