GNSS-SDR  0.0.19
An Open Source GNSS Software Defined Receiver
fpga_multicorrelator.h
Go to the documentation of this file.
1 /*!
2  * \file fpga_multicorrelator.h
3  * \brief FPGA vector correlator class
4  * \authors <ul>
5  * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
6  * <li> Javier Arribas, 2019. jarribas(at)cttc.es
7  * </ul>
8  *
9  * Class that controls and executes a highly optimized vector correlator
10  * class in the FPGA
11  *
12  * -----------------------------------------------------------------------------
13  *
14  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
15  * This file is part of GNSS-SDR.
16  *
17  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  *
20  * -----------------------------------------------------------------------------
21  */
22 
23 #ifndef GNSS_SDR_FPGA_MULTICORRELATOR_H
24 #define GNSS_SDR_FPGA_MULTICORRELATOR_H
25 
26 #include <gnuradio/block.h>
27 #include <volk_gnsssdr/volk_gnsssdr_alloc.h>
28 #include <cstdint>
29 #include <string>
30 
31 /** \addtogroup Tracking
32  * \{ */
33 /** \addtogroup Tracking_libs
34  * \{ */
35 
36 
37 /*!
38  * \brief Class that implements carrier wipe-off and correlators.
39  */
41 {
42 public:
43  /*!
44  * \brief Constructor
45  */
46  Fpga_Multicorrelator_8sc(int32_t n_correlators,
47  int32_t *ca_codes,
48  int32_t *data_codes,
49  uint32_t code_length_chips,
50  bool track_pilot,
51  uint32_t code_samples_per_chip);
52 
53  /*!
54  * \brief Destructor
55  */
57 
58  /*!
59  * \brief Configure pointers to the FPGA multicorrelator results
60  */
61  void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data);
62 
63  /*!
64  * \brief Configure the local code in the FPGA multicorrelator
65  */
67  float *shifts_chips, float *prompt_data_shift, int32_t PRN);
68 
69  /*!
70  * \brief Configure code phase and code rate parameters in the FPGA
71  */
72  void update_local_code();
73 
74  /*!
75  * \brief Perform a multicorrelation
76  */
78  float rem_carrier_phase_in_rad,
79  float phase_step_rad,
80  float carrier_phase_rate_step_rad,
81  float rem_code_phase_chips,
82  float code_phase_step_chips,
83  float code_phase_rate_step_chips,
84  int32_t signal_length_samples);
85 
86  /*!
87  * \brief Stop the correlation process in the FPGA and free code phase and code rate parameters
88  */
89  bool free();
90 
91  /*!
92  * \brief Open the FPGA device driver
93  */
94  void open_channel(const std::string &device_io_name, uint32_t channel);
95 
96  /*!
97  * \brief Set the initial sample number where the tracking process begins
98  */
99  void set_initial_sample(uint64_t samples_offset);
100 
101  /*!
102  * \brief Read the sample counter in the FPGA
103  */
104  uint64_t read_sample_counter();
105 
106  /*!
107  * \brief Start the tracking process in the FPGA
108  */
109  void lock_channel();
110 
111  /*!
112  * \brief finish the tracking process in the FPGA
113  */
114  void unlock_channel();
115 
116  /*!
117  * \brief Set the secondary code length in the FPGA. This is only used when extended coherent integration
118  * is enabled in the FPGA. If tracking the pilot is enabled then secondary_code_0_length is the length of the pilot
119  * secondary code and secondary_code_1_length is the length of the data secondary code. If tracking the pilot is disabled
120  * then secondary_code_0_length is the length of the data secondary code, and secondary_code_1_length must be set to zero.
121  */
122  void set_secondary_code_lengths(uint32_t secondary_code_0_length, uint32_t secondary_code_1_length);
123 
124  /*!
125  * \brief Initialize the secondary code in the FPGA. If tracking the pilot is enabled then the pilot secondary code is
126  * configured when secondary_code = 0 and the data secondary code is configured when secondary_code = 1. If tracking the
127  * pilot is disabled then the data secondary code is configured when secondary code = 0.
128  */
129  void initialize_secondary_code(uint32_t secondary_code, std::string *secondary_code_string);
130 
131  /*!
132  * \brief Set the PRN length in the FPGA in number of samples. This function is only used then extended coherent integration is enabled in the
133  * FPGA. The FPGA allows for the configuration of two PRN lengths. When the length of the extended coherent integration is bigger than the
134  * length of the PRN code, the FPGA uses the first_length_secondary_code as the length of the PRN code immediately following the beginning
135  * of the extended coherent integration, and the next_length_secondary_code as the length of the remaining PRN codes.
136  * The purpose of this is to have the option to allow the FPGA to compensate for a possible deviation between the nominal value of the PRN
137  * code length and the measured PRN code length in the PRN immediately following the start of the coherent integration only.
138  * If this option is not used then write the same value to first_length_secondary_code and next_length_secondary_code.
139  */
140  void update_prn_code_length(uint32_t first_prn_length, uint32_t next_prn_length);
141 
142  /*!
143  * \brief Enable the use of secondary codes in the FPGA
144  */
145  void enable_secondary_codes();
146 
147  /*!
148  * \brief Disable the use of secondary codes in the FPGA
149  */
151 
152 private:
153  // FPGA register addresses
154  // write addresses
155  static const uint32_t code_phase_step_chips_num_reg_addr = 0;
156  static const uint32_t initial_index_reg_base_addr = 1;
157  static const uint32_t initial_interp_counter_reg_base_addr = 7;
158  static const uint32_t nsamples_minus_1_reg_addr = 13;
159  static const uint32_t code_length_minus_1_reg_addr = 14;
160  static const uint32_t rem_carr_phase_rad_reg_addr = 15;
161  static const uint32_t phase_step_rad_reg_addr = 16;
162  static const uint32_t prog_mems_addr = 17;
163  static const uint32_t drop_samples_reg_addr = 18;
164  static const uint32_t initial_counter_value_reg_addr_lsw = 19;
165  static const uint32_t initial_counter_value_reg_addr_msw = 20;
166  static const uint32_t code_phase_step_chips_rate_reg_addr = 21;
167  static const uint32_t phase_step_rate_reg_addr = 22;
168  static const uint32_t stop_tracking_reg_addr = 23;
169  static const uint32_t secondary_code_lengths_reg_addr = 25;
170  static const uint32_t prog_secondary_code_0_data_reg_addr = 26;
171  static const uint32_t prog_secondary_code_1_data_reg_addr = 27;
172  static const uint32_t first_prn_length_minus_1_reg_addr = 28;
173  static const uint32_t next_prn_length_minus_1_reg_addr = 29;
174  static const uint32_t start_flag_addr = 30;
175  // read-write addresses
176  static const uint32_t test_reg_addr = 31;
177  // read addresses
178  static const uint32_t result_reg_real_base_addr = 1;
179  static const uint32_t result_reg_imag_base_addr = 7;
180  static const uint32_t sample_counter_reg_addr_lsw = 13;
181  static const uint32_t sample_counter_reg_addr_msw = 14;
182  // FPGA-related constants
183  static const uint32_t secondary_code_word_size = 20; // the secondary codes are written in to the FPGA in words of secondary_code_word_size bits
184  static const uint32_t secondary_code_wr_strobe = 0x800000; // write strobe position in the secondary code write register
185  static const uint32_t secondary_code_addr_bits = 0x100000; // memory address position in the secondary code write register
186  static const uint32_t drop_samples = 1; // bit 0 of drop_samples_reg_addr
187  static const uint32_t enable_secondary_code = 2; // bit 1 of drop_samples_reg_addr
188  static const uint32_t init_secondary_code_addresses = 4; // bit 2 of drop_samples_reg_addr
189  static const uint32_t FPGA_PAGE_SIZE = 0x1000;
190  static const uint32_t max_code_resampler_counter = 1 << 31; // 2^(number of bits of precision of the code resampler)
191  static const uint32_t local_code_fpga_clear_address_counter = 0x10000000;
192  static const uint32_t test_register_track_writeval = 0x55AA;
193 
194  // private functions
195  uint32_t fpga_acquisition_test_register(uint32_t writeval);
196  void fpga_configure_tracking_gps_local_code(int32_t PRN);
197  void fpga_compute_code_shift_parameters();
198  void fpga_configure_code_parameters_in_fpga();
199  void fpga_compute_signal_parameters_in_fpga();
200  void fpga_configure_signal_parameters_in_fpga();
201  void fpga_launch_multicorrelator_fpga();
202  void read_tracking_gps_results();
203  void close_device(void);
204  void write_secondary_code(uint32_t secondary_code_length, std::string *secondary_code_string, uint32_t reg_addr);
205 
206  volk_gnsssdr::vector<uint32_t> d_initial_index;
207  volk_gnsssdr::vector<uint32_t> d_initial_interp_counter;
208 
209  uint64_t d_initial_sample_counter;
210 
211  gr_complex *d_corr_out;
212  gr_complex *d_Prompt_Data;
213 
214  float *d_shifts_chips;
215  float *d_prompt_data_shift;
216 
217  float d_rem_code_phase_chips;
218  float d_code_phase_step_chips;
219  float d_code_phase_rate_step_chips;
220  float d_rem_carrier_phase_in_rad;
221  float d_phase_step_rad;
222  float d_carrier_phase_rate_step_rad;
223 
224  uint32_t d_code_length_samples;
225  uint32_t d_n_correlators; // number of correlators
226 
227  // data related to the hardware module and the driver
228  int32_t d_device_descriptor; // driver descriptor
229  volatile uint32_t *d_map_base; // driver memory map
230 
231  // configuration data received from the interface
232  uint32_t d_correlator_length_samples;
233 
234  uint32_t d_code_phase_step_chips_num;
235  uint32_t d_code_phase_rate_step_chips_num;
236  int32_t d_rem_carr_phase_rad_int;
237  int32_t d_phase_step_rad_int;
238  int32_t d_carrier_phase_rate_step_rad_int;
239 
240  // PRN codes
241  int32_t *d_ca_codes;
242  int32_t *d_data_codes;
243 
244  // secondary code configuration
245  uint32_t d_secondary_code_0_length;
246  uint32_t d_secondary_code_1_length;
247 
248  bool d_track_pilot;
249  bool d_secondary_code_enabled;
250 };
251 
252 
253 /** \} */
254 /** \} */
255 #endif // GNSS_SDR_FPGA_MULTICORRELATOR_H
bool free()
Stop the correlation process in the FPGA and free code phase and code rate parameters.
Fpga_Multicorrelator_8sc(int32_t n_correlators, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t code_samples_per_chip)
Constructor.
void set_local_code_and_taps(float *shifts_chips, float *prompt_data_shift, int32_t PRN)
Configure the local code in the FPGA multicorrelator.
void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data)
Configure pointers to the FPGA multicorrelator results.
void set_initial_sample(uint64_t samples_offset)
Set the initial sample number where the tracking process begins.
void update_local_code()
Configure code phase and code rate parameters in the FPGA.
void set_secondary_code_lengths(uint32_t secondary_code_0_length, uint32_t secondary_code_1_length)
Set the secondary code length in the FPGA. This is only used when extended coherent integration is en...
void disable_secondary_codes()
Disable the use of secondary codes in the FPGA.
void initialize_secondary_code(uint32_t secondary_code, std::string *secondary_code_string)
Initialize the secondary code in the FPGA. If tracking the pilot is enabled then the pilot secondary ...
uint64_t read_sample_counter()
Read the sample counter in the FPGA.
void open_channel(const std::string &device_io_name, uint32_t channel)
Open the FPGA device driver.
void unlock_channel()
finish the tracking process in the FPGA
Class that implements carrier wipe-off and correlators.
void Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float carrier_phase_rate_step_rad, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, int32_t signal_length_samples)
Perform a multicorrelation.
void enable_secondary_codes()
Enable the use of secondary codes in the FPGA.
~Fpga_Multicorrelator_8sc()
Destructor.
void update_prn_code_length(uint32_t first_prn_length, uint32_t next_prn_length)
Set the PRN length in the FPGA in number of samples. This function is only used then extended coheren...
void lock_channel()
Start the tracking process in the FPGA.