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 (24) and (25).
\(x[n]\) is the input values.
\(y[n]\) is the output values.
\(\delta[m]\) is the mixer step size values from the instep port. When \(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_amplitudeproperty. The 1.646760258 scaling is a result of the gain of the CORDIC algorithm used in the DDS implementation of the carrier generator.
Setting carrier_amplitude at or below 14,060 is guaranteed to not overflow for any valid input. To prevent overflow (26) must hold for the real values, an equivalent expression exists for imaginary values.
In (26), \(x + jy\) is an input complex sample value. The maximum value \(A\), and so carrier_amplitude, can take occurs when the condition (26) is an equality. Maximisation of the left-hand side of (26) 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 (27).
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 needed 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 328:.
Figure 328: Block diagram of carrier mixer implementation.
The relation between the output frequency shift and \(\delta[n]\) values is given by (28).
In (28):
\(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-protOptional:
False
instep: Mixer step size samples port.Protocol:
long_timed_sample-protOptional:
False
Outputs:
output: Primary output samples port.Protocol:
complex_short_timed_sample-protOptional:
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:
boolAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
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\). The default 14,060 maps to near full-range output on a 16-bit signed value and guarantees overflow-free output for any input. Larger values risk overflow.Type:
ushortAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
14060
Implementations
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
carrier_amplitudeabove 14,060 requires users to ensure the combination of samples oninputandinstepports do not cause an overflow.
Testing
Tested platforms: None
Component testing not completed.