Carrier mixer (carrier_mixer_xs)

Multiplies the input with a complex carrier wave.

Design

Mixes a complex input with a carrier wave generated by the component.

The mathematical representation of the implementation is given in (6) and (7).

(6)\[g[n] = A \exp{\left(j 2 \pi \frac{\sum_{m=0}^{n-1} \delta[m]}{2^{32}} \right)} * x[n]\]
(7)\[y[n] = \left \lfloor \frac{g[n]}{2^{15}} \right \rfloor\]

In (6) and (7):

  • \(x[n]\) is the input values.

  • \(y[n]\) is the output values.

  • \(\delta[m]\) is the mixer step size values from the instep port. \(n\) is zero then the instep delta sum will be from zero to \(-1\), in this case this sum is zero.

  • \(A\) is the amplitude of the mixer wave, equal to 1.646760258 * carrier_amplitude property. The 1.646760258 scaling is a result of the gain of the CORDIC algorithm used in the DDS implementation of the carrier generator.

If carrier_amplitude is set too large an overflow will occur. As the scaling is a bit mapping an overflow of this signed value will lead to unstable output. To prevent overflow carrier_amplitude must not be set above 14,060. To prevent overflow (8) must hold for the real values, an equivalent expression exists for imaginary values.

(8)\[\frac{A \left(x \cos{ 2 \pi \frac{\sum_{m=0}^{n-1} \delta[m]}{2^{32}}} - j y \sin{ 2 \pi \frac{\sum_{m=0}^{n-1} \delta[m]}{2^{32}}} \right)}{2^{15}} < x_{max}\]

In (8), * \(x + jy\) is an input complex sample value. The maximum value \(A\), and so carrier_amplitude, can take occurs when the condition (8) is an equality. Maximisation of the left-hand side of (8) occurs when \(x=x_{max}\), \(y=-x_{max}\), and the input phase maximises \(\cos{\theta} + \sin{\theta}\) which has a maximum of \(\sqrt{2}\). This results in (9).

(9)\[A = \frac{2^{15}}{\sqrt{2}} = 23170.475...\]

As the carrier_amplitude property is scaled by 1.646760258, the limit to carrier_amplitude is \(23170.475... / 1.646760258 = 14070.33...\). As the carrier generator uses an approximation an empirically determined margin is need for the theoretical maximum to give a tested and supported maximum of 14,060.

\(\delta[m]\) must have an input value for each value on \(x[n]\). Therefore, for a fixed frequency carrier to be multiplied by the input \(x[n]\), then \(\delta[m]\) must have a constant input of the same value.

A block diagram representation of the implementation is given in Figure 6:.

Block diagram outlining carrier mixer implementation.

Figure 6: Block diagram of carrier mixer implementation.

The relation between the output frequency shift and \(\delta[n]\) values is given by (10).

(10)\[ \delta[n] = \frac{2^{32} f}{F_s}\]

In (6):

  • \(f\) is the desired frequency shift.

  • \(F_s\) is the sample rate of the system.

Interface

<?xml version="1.0"?>
<componentspec>
  <property name="instep_opcode_passthrough" type="bool" writable="false" parameter="true" default="false" description="When true opcodes from the instep port are passed to the output, when false opcodes from the input port are passed to the output."/>
  <property name="carrier_amplitude" type="ushort" writable="true" default="14060" description="Amplitude of the carrier mixed with the input signal. Set to :math:`\left \lfloor \frac{\text{desired_maximum}}{1.646760258} \right \rfloor`."/>
  <port name="input" producer="false" protocol="complex_short_timed_sample-prot"/>
  <port name="instep" producer="false" protocol="long_timed_sample-prot"/>
  <port name="output" producer="true" protocol="complex_short_timed_sample-prot"/>
</componentspec>

Ports

Inputs:

  • input: Primary input samples port.

    • Protocol: complex_short_timed_sample-prot

    • Optional: False

  • instep: Mixer step size.

    • Protocol: long_timed_sample-prot

    • Optional: False

Outputs:

  • output: Primary output samples port.

    • Protocol: complex_short_timed_sample-prot

    • Optional: False

Opcode handling

Only values in a sample opcode messages are multiplied together.

Non-sample opcodes from a single input are forwarded onto the output interface. The instep_opcode_passthrough parameter selects which input interface is used for non-sample opcode forwarding. Non-sample opcodes on the other input to what instep_opcode_passthrough is set to are discarded.

Properties

  • instep_opcode_passthrough: When true opcodes from the instep port are passed to the output, when false opcodes from the input port are passed to the output.

    • Type: bool

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

    • Default value: false

  • carrier_amplitude: Amplitude of the carrier mixed with the input signal. Set to \(\left \lfloor \frac{\text{desired_maximum}}{1.646760258} \right \rfloor\). This should not be set to greater than 14,060 - this value maps to near full range output on a 16-bit signed value.

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: False

    • Default value: 14060

Parameters

Implementations

  • carrier_mixer_xs (HDL)

    HDL implementation using a numerically controlled oscillator (NCO) for the carrier generator, which used the CORDIC algorithm to generate an approximation of sine and cosine.

  • carrier_mixer_xs (RCC)

Example application

<?xml version="1.0"?>
<application done="file_write">
  <instance component="ocpi.core.file_read" connect="carrier_mixer_xs" to="input">
    <property name="filename" value="input.bin"/>
  </instance>
  <instance component="ocpi.core.file_read" connect="carrier_mixer_cs_cs" to="instep">
    <property name="filename" value="instep.bin"/>
  </instance>
  <instance component="ocpi.comp.sdr.dsp.carrier_mixer_xs" connect="file_write">
    <property name="carrier_amplitude" value="14060"/>
  </instance>
  <instance component="ocpi.core.file_write">
    <property name="filename" value="output.bin"/>
  </instance>
</application>

Dependencies

The dependencies to other elements in OpenCPI are:

There is also a dependency on:

  • ieee.std_logic_1164

  • ieee.numeric_std

  • ieee.math_real

Limitations

Limitations of carrier_mixer_xs are:

  • Setting of carrier_amplitude above 14,060 is untested behaviour and will result in unpredictable behaviour.

Testing

Component testing not completed.