Different clocks and rates need to be considered:
- The (received) chip-rate of the signal (altered by doppler)
- The sampling rate
- The clock(s) your FPGA is running on.
signal-synchronous designs
Your proposal using the internal PLL would require running part of the FPGA-logic (the code generator) with a fixed phase relation to the received chip-rate (which is variable for a moving receiver/transmitter). Since you want to modulate this code onto the received signal, the sampling process would also need to be fixed phase to the chips. Combining signals from different clock-domains in a mixer is impossible (unless you employ sample rate conversion, don't even think about this).
So basically everything is fixed to the chip-rate. I dare to say that this is not a common setup, since most systems have additional timing constraints, f.e. for memory interfaces, and GNSS receivers need to track more than one signal.
numerical controlled oscillators
To be independent from the varying observed chip-rate, you need to employ a numerical controlled oscillator. This oscillator can run on the sample-rate or the FPGA-clock. Running it on the sample-rate makes things easier since there is only one local clock error.
You may want to make sure, that the fraction between sample-rate and chip-rate is not a low-order harmonic. In fact, spurious tones cannot be avoided completely but consideration of quantization noise and its harmonics and the effect on your signal can save your day. Fractional-N is a must, dithering may help.
I daresay that this is a very common setup.
optional: FPGA-clock >> sample-rate
You may be tempted to run the FPGA-logic on the ADC-clock. This facilitates simple modules since there is valid data in every clock-cycle. However, this typically only works for a part of your design. If you have a decimating filter, your symbol rate will be lower after that filter and asynchronous signaling (Avalon ST) is mandatory.
Using asynchronous design (with logic clock > sample rate) from the very start of you signal path gives you additional value:
- You can time-multiplex some of your signal-path.
- You can stop or reconfigure the ADC without putting the FPGA on hold.
- Implicit dependency on clock is a avoided for your HDL, making it easier to understand.