Stuck LSB in ADC samples in real-to-real mode, decimation=1

I’m using an RFSoC 4x2 board and experiencing an issue where, if the RFDC is configured in real-to-real mode with a decimation of 1, the LSB of the ADC samples appear to be stuck at 1, at least for the majority of samples. This happens with fairly minimal modifications to the base overlay:

from pynq.overlays.base import BaseOverlay
from pynq import allocate
import numpy as np
import matplotlib.pyplot as plt
import xrfdc

base = BaseOverlay('base.bit')
base.init_rf_clks()

# Configure RFDC
base.radio.receiver.channel[0].adc_block.MixerSettings = {'Freq': 0.0, 'PhaseOffset': 0.0, 'EventSource': 2, 'CoarseMixFreq': 16, 'MixerMode': xrfdc.MIXER_MODE_R2R, 'FineMixerScale': 1, 'MixerType': xrfdc.MIXER_TYPE_COARSE}
base.radio.receiver.channel[0].adc_block.UpdateEvent(1)
base.radio.receiver.channel[0].adc_block.DecimationFactor = 1

# Grab raw samples (ref: rfsystem.hierarchies.AdcChannel.transfer definition)
chan = base.radio.receiver.channel_00
transfersize = int(np.ceil(n/8))
chan._pgen.packetsize = transfersize
buffer_re = allocate(shape=(transfersize*8,), dtype=np.int16)
buffer_im = allocate(shape=(transfersize*8,), dtype=np.int16)
chan._dma_real.recvchannel.transfer(buffer_re)
chan._dma_imag.recvchannel.transfer(buffer_im)
chan._pgen.transfer = 1
chan._dma_real.recvchannel.wait()
chan._dma_imag.recvchannel.wait()
chan._pgen.transfer = 0
re_data = np.array(buffer_re) // 4 # align 14-bit samples to LSB of 16-bit words
im_data = np.array(buffer_im) // 4 # align 14-bit samples to LSB of 16-bit words
buffer_re.freebuffer()
buffer_im.freebuffer()

# Plot histogram
fig, ax = plt.subplots()
ax.hist(re_data,bins=np.arange(-50,50))
ax.set_xlabel('Counts')
ax.set_ylabel('Occurences')
ax.set_title('Histogram')
plt.show()

The resulting histogram clearly shows the bias towards odd samples (note: ADC input is terminated in 50 Ohms):


The bias also appears to depend on where each sample falls within the AXI4 stream (8 samples wide):

for i in range(8):
    print(i,np.sum(re_data[i::8] & 0b1))
0 4096
1 4096
2 4096
3 4096
4 4096
5 0
6 4096
7 2062

Note that, by modifying the above code such that

base.radio.receiver.channel[0].adc_block.DecimationFactor = 2

this problem goes away:


This doesn’t appear to be a problem exclusive to the PYNQ platform, as I’ve obtained the same results using the Casper toolflow (CASPER Toolflow — CASPER Toolflow 0.1 documentation), and have had others using that toolflow reproduce the issue on their boards. However, I’d like to cast a wider net to see if anyone within the PYNQ community has experienced the same issue and knows of a solution.