Quadrature subsampling result not as expected Let's suppose I have an ADC running at 81.824MHz. I am quadrature subsampling a signal that is at 143.5MHz using a sampling rate of 81.824MHz/4 = 20.456MHz = Fs. I expect the signal to appear at baseband with a small offset of 143.5MHz-7*Fs = 308KHz. But it is showing up at 320KHz when I run the code below. Why is that?

% Sampling frequency 
fs = 20.456;

% ADC frequency
fadc = 4*fs;

% ADC period
T = 1/fadc;

% Some ADC samples
n = 0:T:100;

% Received frequency
f_l1 = 143.5;
s_l1 = cos(2*pi*f_l1*n);

% Replica frequency for mixing.
f_local = 7*fs;
s_local = cos(2*pi*f_local*n);

% Mixing
sif = s_l1 .* s_local;

% Find frequency content
siffft = (fft(sif));

% Plot results
nyquist = 1;
freq_steps = (1:length(siffft))/(length(siffft))*nyquist*fadc;
figure(3);
plot(freq_steps, abs(real(siffft))), 
grid;
Your calculation is correct; sif has a harmonic at 308 kHz. Given the way you have set up the problem, you can't get that exact value using the FFT because you don't have a frequency bin at that frequency. According to my calculations, the nearest bin is at 305 kHz, and I do see a peak at that frequency. Since there is no bin at the signal's frequency, the energy will leak: bins in the neighborhood of the peak will also get some of the energy of the 308 kHz signal.

Leakage is very hard to avoid. Assuming a fixed sampling frequency, you can calculate the number of samples you need to have a bin at exactly 308 kHz. However, it's very likely that you will then have a non-integer number of cycles of sif, so you will have leakage again. This effect can be reduced by using windowing.

There are many related questions in this website (for example, this one). Search for 'fft bin leakage' to find many more.