Signal Path

In this section, we present a theoretical overview of the signal path. For structural information, please consult the documentation in the icecore-dfmux repository here.

Note

For now, I’m focusing on the modulator. As PFB demod progresses, I’ll document it here too. I’m trying to strike a balance between documenting things that change, documenting something that doesn’t get completed, or not finishing documentation..

Conceptual Model

We begin with A Conceptual Diagram of the Dfmux Signal Path. This is only a conceptual model – the signal path hasn’t been built this way for some time. Arguably, it never was.

../_images/signal_path_conceptual.svg

A Conceptual Diagram of the Dfmux Signal Path

Warning

This diagram anticipates PFB demod. To be correct for “current” IceBoard firmware (Feb 2015), the following changes are necessary:

  1. The demodulator decimation (CIC1) is a factor of 128 (not 32)
  2. The readout decimation (CIC2) is between 16..512 (not 64..2048)

These changes expose a sampling-rate mismatch: the DAN module updates nuller amplitudes at 156.25 kHz, while the nuller accepts them at 625 kHz. (The effect on the DAN signal path is identical to a boxcar filter of length 4.)

Modulator

Although the modulator can be visualized as shown above, it’s certainly a lot more complicated in implementation. The modulator’s structure is shown in A Conceptual Diagram of the PFB Modulator.

../_images/modulator_conceptual.svg

A Conceptual Diagram of the PFB Modulator

The modulator is a PFB with the following parameters:

Parameter Description Value
M Decimation Ratio 32
K Number of Bins 128
L Prototype FIR Length 320
TD Intrinsic Delay (L-1)/2 ÷ 20e6 ≈ 8μs

Note

The intrinsic delay describes only the delay intrinsic to the PFB, not any processing delays associated with its implementation. To a first order, this is the dominant delay (and it’s the best we can hope for without changing the design.)

In the following section, we describe each modulation stage in more detail.

Pre-Modulation

Pre-modulation occurs channel-by-channel. For each channel, we first consider the carrier, then the nuller. This time-multiplexing allows us to use the same logic (DDS, multipler, et cetera) for all 128 channels, both carrier and nuller, in a comb.

We begin by retrieving the channel’s parameters:

  • The carrier and nuller amplitude (whether static or from DAN),
  • The bin number associated with this channel, and
  • The channel’s frequency offset from this bin’s centre.

We pre-modulate the amplitude by the bin frequency offset, so that when the bin is up-converted (by FFT, later in the chain), this signal appears at the correct spot.

Important

In this PFB, the decimation ratio M does not equal the number of bins K. The pre-modulator has four times the bandwidth you’d expect by dividing the output sampling rate (20 MHz) by the number of bins (128).

../_images/pipeline_lo.svg

A Pipeline Diagram for the Modulator (synth_lo.vhd).

The modulator’s 13-stage pipeline does the following:

  1. Converts an input pulse (sig_strobe) into a full scan through all 128 channels, carrier + nuller.
  2. Looks up each channel’s current phase and adds a phase increment to move along the channel’s carrier sinusoid. This incremented phase is written back to the instantaneous phase buffer pregs.
  3. Applies each channel’s phase offset (from set_phase(), in Python) prior to passing the final phase to the DDS.
  4. Delays “channel” and “ready” flags while the DDS works, and
  5. Outputs a complete (i,q,channel,flags) set.

Carrier/Nuller Multiplexing

Although the carrier and nuller signals use the same logic in pre-modulation, they are kept distinct in time. In the multiplexing stage, we combine carrier and nuller signals so that the carrier will be emitted in the FFT’s real output, and the nuller will be emitted in the imaginary output. By multiplexing the carrier and nuller into a single FFT, we are able to avoid calculating, and then throwing away, the imaginary portion of a FFT with an output that is known to be real.

Multiplexing takes advantage of Hermitian symmetry in the Fourier domain: a purely even signal has a purely real Fourier transform, and a purely odd signal has a purely imaginary Fourier transform.

The output of the multiplexing stage is two complex numbers, associated with the two relevant FFT bins.

Bin Accumulation

Since multiple channels occupy the same bin, it is necessary to build up bins channel-by-channel. During bin accumulation, we sum bin contents from each channel into a single FFT buffer. This buffer is then passed along to the FFT.

Fast Fourier Transform (FFT)

The FFT block is a standard Xilinx module.

Windowing

During the windowing stage, we spectrally shape each bin as it is modulated and combined with other bins. The window (eqivalently, polyphase filter or FIR; each of these is correct depending on the context) determines the system’s passband linearity and alias rejection. It is also the primary driver of latency in the synthesizer. These considerations (passband linearity, alias rejection, and latency) are incompatible, so we are forced to find a compromise.

Important

In this PFB, M != K. Here, again, this adds a quirk: during windowing, we permute (rotate) the FFT outputs in a time-varying manner. This is necessary to properly phase-align the FFT outputs in the final signal. For a treatment on the topic, please see [Harris2003].

[Harris2003]Frederic J. Harris, Chris Dick, and Michael Rice, “Digital Receivers and Transmitters using Polyphase Filter Banks for Wireless Communications,” in IEEE Trans. Microwave Theory and Techniques, Vol. 51, No. 4, 2003.

Simulation

A synthesizer simulation may be found in pfb.py, available here:

This simulation is intended to be conceptual, not structural – for example, it is not bit-accurate.