Hi,

Guest

D

dwp@md1tech.co.uk

Wed, Jan 24, 2024 4:22 PM

Hi,

I want to use the carrier_mixer_us in `ocpi.comp.sdr.dsp`

component to down convert a signal.

Ideally I would want the input wave to have the same amplitude as the output wave however this does not seem to be possible due to the `carrier_amplitude`

property having a maximum allowed value of 14,060.

Since the property is scaled by 1.646760258, this brings the amplitude of the mixer wave to 23170.475 or roughly sqrt(2) * 2^15. I would understand if the amplitude was limited to 2^15 to prevent overflow but what is the reason for this sqrt(2) factor?

Before outputting, the result of each multiplication is shifted right by 15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of the input wave.

It is also quite counterintuitive that the input amplitude of the carrier wave is being scaled this way. Would it not be possible to provide the true amplitude to the `carrier_amplitude`

property and have the worker do the necessary scaling? If not, renaming the property to indicate that it is not the actual amplitude would be useful.

Thanks,

Dan

Hi,
I want to use the carrier_mixer_us in `ocpi.comp.sdr.dsp` component to down convert a signal.
Ideally I would want the input wave to have the same amplitude as the output wave however this does not seem to be possible due to the `carrier_amplitude` property having a maximum allowed value of 14,060.
Since the property is scaled by 1.646760258, this brings the amplitude of the mixer wave to 23170.475 or roughly sqrt(2) \* 2^15. I would understand if the amplitude was limited to 2^15 to prevent overflow but what is the reason for this sqrt(2) factor?
Before outputting, the result of each multiplication is shifted right by 15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of the input wave.
It is also quite counterintuitive that the input amplitude of the carrier wave is being scaled this way. Would it not be possible to provide the true amplitude to the `carrier_amplitude` property and have the worker do the necessary scaling? If not, renaming the property to indicate that it is not the actual amplitude would be useful.
Thanks,\
Dan

DW

Dominic Walters

Tue, Jan 30, 2024 9:35 PM

Hi,

Apologies for the delayed response to this.

I asked this question to several people who were / are involved with the

creation and maintenance of this worker / component.

These are their responses, which I have slightly edited to fix formatting

and remove names, etc.

I hope the formatting is retained or this might be quite hard to read :D

*--- First Response ---*

This is explained in the documentation:

However, the term carrier_amplitude may be misleading, carrier_gain would

be better.

In (9) we are looking to define the gain A for some given complex sample -

the gain is relative to the input so we consider the input on a unit

circle, i.e. x and y are in the range -1 to 1.

Substituting in (9) for the point where the term multiplying A is maximal

(x = x_max and y = -x_max):

A ( x_max * cos (theta) – (-x_max) * sin( theta) )

----------------------------------------------------------------- < x_max

```
2^15
```

As x_max is 1 and the largest value of cos(theta) + sin(theta) is sqrt(2)

we then get:

A * sqrt(2)

-------------- < 1

2^15

Solving for A:

A * sqrt(2)

-------------- = 1

```
2^15
```

A * sqrt(2) = 1 * 2^15 = 2^15

A = 2^15 / sqrt(2) = 23170.475….

A is scaled by 1.64…. and so carrier_amplitude should be set to 14070 for a

gain of 1 through the component.

However, the underlying cordic can over/under-shoot so we recommend using

the value 14,060.

There is (in my opinion) an unnecessary limitation in the C++

implementation which sets an upper bound of the carrier_amplitude value to

14,060 – it is perfectly reasonable to use this component as a gain block –

i.e. setting the value to 28,000 would double the output amplitude relative

to the input.

(if you consider the input to be half scale (x = 0.5, y = 0.5, x_max = 1)

and substitute in (9) you get 28,140).

I did test the RCC implementation and the above holds, I believe the RCC

and HDL implementations are both tested against the same Python based model

– so have no reason to expect the HDL version is any different.

*--- **Second Response ---*

I have been doing some thinking on this also and I think I see what Dan is

getting at…but also understand why it is designed as is.

The issue Dan is bringing up is specifically with this bit -> “A is maximal

(x = x_max and y = -x_max)”. If the carrier mixer input is a “perfect” iq

tone, as it is in Dan case, with sin and cos waveforms 90 degrees apart the

condition “x = x_max and y = -x_max” never occurs (see below that there is

never a point in time where x is 1 and y is 1 (or -1)).

[image: cid:image003.png@01DA5377.D1D769A0]

Euler’s formula is the easiest way to understand this (I reckon…):

When frequency shifting, Dan wants to realise the below formula, where is

the input signal and is the generated signal.

However, what is currently done is an acknowledgment that the input

waveform might not be a “perfect” since wave and therefore is accounting

for the “x = x_max and y = -x_max)” condition occurring.

So the term is reduced to , since the magnitude of gives 1, which ensures

whatever the input is there is no overflow. To be clear, the is and (the

amplitude of the generated waveform).

In summary, I think how we have it implemented now is correct since it

ensures a messy input waveform never overflows on the output when it is

mixed. But a good compromise to allow for Dan’s “perfect” input waveform

use case is as the first reply says: adding the ability to set the

carrier_amplitude to a value such that an amplitude of 32767 instead of

23170 is achieved for the generated waveform.

I will relay this information onto the ocpi.comp.sdr developers to add to

their backlog.

I hope this was helpful.

Kind Regards,

Dom Walters

On Wed, Jan 24, 2024 at 4:22 PM dwp@md1tech.co.uk wrote:

Hi,

I want to use the carrier_mixer_us in ocpi.comp.sdr.dsp component to down

convert a signal.

Ideally I would want the input wave to have the same amplitude as the

output wave however this does not seem to be possible due to the

carrier_amplitude property having a maximum allowed value of 14,060.

Since the property is scaled by 1.646760258, this brings the amplitude of

the mixer wave to 23170.475 or roughly sqrt(2) * 2^15. I would understand

if the amplitude was limited to 2^15 to prevent overflow but what is the

reason for this sqrt(2) factor?

Before outputting, the result of each multiplication is shifted right by

15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer

amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of

the input wave.

It is also quite counterintuitive that the input amplitude of the carrier

wave is being scaled this way. Would it not be possible to provide the true

amplitude to the carrier_amplitude property and have the worker do the

necessary scaling? If not, renaming the property to indicate that it is not

the actual amplitude would be useful.

Thanks,

Dan

discuss mailing list -- discuss@lists.opencpi.org

To unsubscribe send an email to discuss-leave@lists.opencpi.org

Hi,
Apologies for the delayed response to this.
I asked this question to several people who were / are involved with the
creation and maintenance of this worker / component.
These are their responses, which I have slightly edited to fix formatting
and remove names, etc.
I hope the formatting is retained or this might be quite hard to read :D
*--- First Response ---*
This is explained in the documentation:
https://opencpi.gitlab.io/releases/develop/rst/comp_sdr/components/dsp/carrier_mixer_xs.comp/carrier_mixer_xs-index.html
However, the term carrier_amplitude may be misleading, carrier_gain would
be better.
In (9) we are looking to define the gain A for some given complex sample -
the gain is relative to the input so we consider the input on a unit
circle, i.e. x and y are in the range -1 to 1.
Substituting in (9) for the point where the term multiplying A is maximal
(x = x_max and y = -x_max):
A ( x_max * cos (theta) – (-x_max) * sin( theta) )
----------------------------------------------------------------- < x_max
2^15
As x_max is 1 and the largest value of cos(theta) + sin(theta) is sqrt(2)
we then get:
A * sqrt(2)
-------------- < 1
2^15
Solving for A:
A * sqrt(2)
-------------- = 1
2^15
A * sqrt(2) = 1 * 2^15 = 2^15
A = 2^15 / sqrt(2) = 23170.475….
A is scaled by 1.64…. and so carrier_amplitude should be set to 14070 for a
gain of 1 through the component.
However, the underlying cordic can over/under-shoot so we recommend using
the value 14,060.
There is (in my opinion) an unnecessary limitation in the C++
implementation which sets an upper bound of the carrier_amplitude value to
14,060 – it is perfectly reasonable to use this component as a gain block –
i.e. setting the value to 28,000 would double the output amplitude relative
to the input.
(if you consider the input to be half scale (x = 0.5, y = 0.5, x_max = 1)
and substitute in (9) you get 28,140).
I did test the RCC implementation and the above holds, I believe the RCC
and HDL implementations are both tested against the same Python based model
– so have no reason to expect the HDL version is any different.
*--- **Second Response ---*
I have been doing some thinking on this also and I think I see what Dan is
getting at…but also understand why it is designed as is.
The issue Dan is bringing up is specifically with this bit -> “A is maximal
(x = x_max and y = -x_max)”. If the carrier mixer input is a “perfect” iq
tone, as it is in Dan case, with sin and cos waveforms 90 degrees apart the
condition “x = x_max and y = -x_max” never occurs (see below that there is
never a point in time where x is 1 and y is 1 (or -1)).
[image: cid:image003.png@01DA5377.D1D769A0]
Euler’s formula is the easiest way to understand this (I reckon…):
When frequency shifting, Dan wants to realise the below formula, where is
the input signal and is the generated signal.
However, what is currently done is an acknowledgment that the input
waveform might not be a “perfect” since wave and therefore is accounting
for the “x = x_max and y = -x_max)” condition occurring.
So the term is reduced to , since the magnitude of gives 1, which ensures
whatever the input is there is no overflow. To be clear, the is and (the
amplitude of the generated waveform).
In summary, I think how we have it implemented now is correct since it
ensures a messy input waveform never overflows on the output when it is
mixed. But a good compromise to allow for Dan’s “perfect” input waveform
use case is as the first reply says: adding the ability to set the
carrier_amplitude to a value such that an amplitude of 32767 instead of
23170 is achieved for the generated waveform.
I will relay this information onto the ocpi.comp.sdr developers to add to
their backlog.
---
I hope this was helpful.
Kind Regards,
Dom Walters
On Wed, Jan 24, 2024 at 4:22 PM <dwp@md1tech.co.uk> wrote:
> Hi,
>
> I want to use the carrier_mixer_us in ocpi.comp.sdr.dsp component to down
> convert a signal.
>
> Ideally I would want the input wave to have the same amplitude as the
> output wave however this does not seem to be possible due to the
> carrier_amplitude property having a maximum allowed value of 14,060.
>
> Since the property is scaled by 1.646760258, this brings the amplitude of
> the mixer wave to 23170.475 or roughly sqrt(2) * 2^15. I would understand
> if the amplitude was limited to 2^15 to prevent overflow but what is the
> reason for this sqrt(2) factor?
>
> Before outputting, the result of each multiplication is shifted right by
> 15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer
> amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of
> the input wave.
>
> It is also quite counterintuitive that the input amplitude of the carrier
> wave is being scaled this way. Would it not be possible to provide the true
> amplitude to the carrier_amplitude property and have the worker do the
> necessary scaling? If not, renaming the property to indicate that it is not
> the actual amplitude would be useful.
>
> Thanks,
> Dan
> _______________________________________________
> discuss mailing list -- discuss@lists.opencpi.org
> To unsubscribe send an email to discuss-leave@lists.opencpi.org
>

DW

Dominic Walters

Tue, Jan 30, 2024 9:38 PM

Looks like a lot of the embedded images got stripped out or added as

attachments, which is unfortunate.

If you struggle to read the second part of this, I can try screen grab it

and upload the image somewhere. Or something like that.

On Tue, Jan 30, 2024 at 9:35 PM Dominic Walters waltersdom@googlemail.com

wrote:

Hi,

Apologies for the delayed response to this.

I asked this question to several people who were / are involved with the

creation and maintenance of this worker / component.

These are their responses, which I have slightly edited to fix formatting

and remove names, etc.

I hope the formatting is retained or this might be quite hard to read :D

*--- First Response ---*

This is explained in the documentation:

However, the term carrier_amplitude may be misleading, carrier_gain would

be better.

In (9) we are looking to define the gain A for some given complex sample -

the gain is relative to the input so we consider the input on a unit

circle, i.e. x and y are in the range -1 to 1.

Substituting in (9) for the point where the term multiplying A is maximal

(x = x_max and y = -x_max):

A ( x_max * cos (theta) – (-x_max) * sin( theta) )

----------------------------------------------------------------- < x_max

```
2^15
```

As x_max is 1 and the largest value of cos(theta) + sin(theta) is sqrt(2)

we then get:

A * sqrt(2)

-------------- < 1

```
2^15
```

Solving for A:

A * sqrt(2)

-------------- = 1

```
2^15
```

A * sqrt(2) = 1 * 2^15 = 2^15

A = 2^15 / sqrt(2) = 23170.475….

A is scaled by 1.64…. and so carrier_amplitude should be set to 14070 for

a gain of 1 through the component.

However, the underlying cordic can over/under-shoot so we recommend using

the value 14,060.

There is (in my opinion) an unnecessary limitation in the C++

implementation which sets an upper bound of the carrier_amplitude value to

14,060 – it is perfectly reasonable to use this component as a gain block –

i.e. setting the value to 28,000 would double the output amplitude relative

to the input.

(if you consider the input to be half scale (x = 0.5, y = 0.5, x_max = 1)

and substitute in (9) you get 28,140).

I did test the RCC implementation and the above holds, I believe the RCC

and HDL implementations are both tested against the same Python based model

– so have no reason to expect the HDL version is any different.

*--- **Second Response ---*

I have been doing some thinking on this also and I think I see what Dan is

getting at…but also understand why it is designed as is.

The issue Dan is bringing up is specifically with this bit -> “A is

maximal (x = x_max and y = -x_max)”. If the carrier mixer input is a

“perfect” iq tone, as it is in Dan case, with sin and cos waveforms 90

degrees apart the condition “x = x_max and y = -x_max” never occurs (see

below that there is never a point in time where x is 1 and y is 1 (or -1)).

[image: cid:image003.png@01DA5377.D1D769A0]

Euler’s formula is the easiest way to understand this (I reckon…):

When frequency shifting, Dan wants to realise the below formula, where is

the input signal and is the generated signal.

However, what is currently done is an acknowledgment that the input

waveform might not be a “perfect” since wave and therefore is accounting

for the “x = x_max and y = -x_max)” condition occurring.

So the term is reduced to , since the magnitude of gives 1, which

ensures whatever the input is there is no overflow. To be clear, the is

and (the amplitude of the generated waveform).

In summary, I think how we have it implemented now is correct since it

ensures a messy input waveform never overflows on the output when it is

mixed. But a good compromise to allow for Dan’s “perfect” input waveform

use case is as the first reply says: adding the ability to set the

carrier_amplitude to a value such that an amplitude of 32767 instead of

23170 is achieved for the generated waveform.

I will relay this information onto the ocpi.comp.sdr developers to add to

their backlog.

I hope this was helpful.

Kind Regards,

Dom Walters

On Wed, Jan 24, 2024 at 4:22 PM dwp@md1tech.co.uk wrote:

Hi,

I want to use the carrier_mixer_us in ocpi.comp.sdr.dsp component to

down convert a signal.

Ideally I would want the input wave to have the same amplitude as the

output wave however this does not seem to be possible due to the

carrier_amplitude property having a maximum allowed value of 14,060.

Since the property is scaled by 1.646760258, this brings the amplitude of

the mixer wave to 23170.475 or roughly sqrt(2) * 2^15. I would understand

if the amplitude was limited to 2^15 to prevent overflow but what is the

reason for this sqrt(2) factor?

Before outputting, the result of each multiplication is shifted right by

15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer

amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of

the input wave.

It is also quite counterintuitive that the input amplitude of the carrier

wave is being scaled this way. Would it not be possible to provide the true

amplitude to the carrier_amplitude property and have the worker do the

necessary scaling? If not, renaming the property to indicate that it is not

the actual amplitude would be useful.

Thanks,

Dan

discuss mailing list -- discuss@lists.opencpi.org

To unsubscribe send an email to discuss-leave@lists.opencpi.org

Looks like a lot of the embedded images got stripped out or added as
attachments, which is unfortunate.
If you struggle to read the second part of this, I can try screen grab it
and upload the image somewhere. Or something like that.
On Tue, Jan 30, 2024 at 9:35 PM Dominic Walters <waltersdom@googlemail.com>
wrote:
> Hi,
>
> Apologies for the delayed response to this.
> I asked this question to several people who were / are involved with the
> creation and maintenance of this worker / component.
>
> These are their responses, which I have slightly edited to fix formatting
> and remove names, etc.
>
> I hope the formatting is retained or this might be quite hard to read :D
>
> *--- First Response ---*
>
> This is explained in the documentation:
>
>
>
>
> https://opencpi.gitlab.io/releases/develop/rst/comp_sdr/components/dsp/carrier_mixer_xs.comp/carrier_mixer_xs-index.html
>
>
>
> However, the term carrier_amplitude may be misleading, carrier_gain would
> be better.
>
>
>
> In (9) we are looking to define the gain A for some given complex sample -
> the gain is relative to the input so we consider the input on a unit
> circle, i.e. x and y are in the range -1 to 1.
>
>
>
> Substituting in (9) for the point where the term multiplying A is maximal
> (x = x_max and y = -x_max):
>
>
>
> A ( x_max * cos (theta) – (-x_max) * sin( theta) )
>
> ----------------------------------------------------------------- < x_max
>
> 2^15
>
>
>
> As x_max is 1 and the largest value of cos(theta) + sin(theta) is sqrt(2)
> we then get:
>
>
>
> A * sqrt(2)
>
> -------------- < 1
>
> 2^15
>
>
>
> Solving for A:
>
>
>
> A * sqrt(2)
>
> -------------- = 1
>
> 2^15
>
>
>
> A * sqrt(2) = 1 * 2^15 = 2^15
>
>
>
> A = 2^15 / sqrt(2) = 23170.475….
>
>
>
> A is scaled by 1.64…. and so carrier_amplitude should be set to 14070 for
> a gain of 1 through the component.
>
>
>
> However, the underlying cordic can over/under-shoot so we recommend using
> the value 14,060.
>
>
>
> There is (in my opinion) an unnecessary limitation in the C++
> implementation which sets an upper bound of the carrier_amplitude value to
> 14,060 – it is perfectly reasonable to use this component as a gain block –
> i.e. setting the value to 28,000 would double the output amplitude relative
> to the input.
>
>
>
> (if you consider the input to be half scale (x = 0.5, y = 0.5, x_max = 1)
> and substitute in (9) you get 28,140).
>
>
>
> I did test the RCC implementation and the above holds, I believe the RCC
> and HDL implementations are both tested against the same Python based model
> – so have no reason to expect the HDL version is any different.
>
> *--- **Second Response ---*
>
> I have been doing some thinking on this also and I think I see what Dan is
> getting at…but also understand why it is designed as is.
>
>
>
> The issue Dan is bringing up is specifically with this bit -> “A is
> maximal (x = x_max and y = -x_max)”. If the carrier mixer input is a
> “perfect” iq tone, as it is in Dan case, with sin and cos waveforms 90
> degrees apart the condition “x = x_max and y = -x_max” never occurs (see
> below that there is never a point in time where x is 1 and y is 1 (or -1)).
>
>
>
> [image: cid:image003.png@01DA5377.D1D769A0]
>
>
>
> Euler’s formula is the easiest way to understand this (I reckon…):
>
>
>
>
>
> When frequency shifting, Dan wants to realise the below formula, where is
> the input signal and is the generated signal.
>
>
>
>
>
> However, what is currently done is an acknowledgment that the input
> waveform might not be a “perfect” since wave and therefore is accounting
> for the “x = x_max and y = -x_max)” condition occurring.
>
>
>
> So the term is reduced to , since the magnitude of gives 1, which
> ensures whatever the input is there is no overflow. To be clear, the is
> and (the amplitude of the generated waveform).
>
>
>
> In summary, I think how we have it implemented now is correct since it
> ensures a messy input waveform never overflows on the output when it is
> mixed. But a good compromise to allow for Dan’s “perfect” input waveform
> use case is as the first reply says: adding the ability to set the
> carrier_amplitude to a value such that an amplitude of 32767 instead of
> 23170 is achieved for the generated waveform.
>
>
>
> I will relay this information onto the ocpi.comp.sdr developers to add to
> their backlog.
>
>
> ---
>
>
> I hope this was helpful.
>
>
> Kind Regards,
> Dom Walters
>
> On Wed, Jan 24, 2024 at 4:22 PM <dwp@md1tech.co.uk> wrote:
>
>> Hi,
>>
>> I want to use the carrier_mixer_us in ocpi.comp.sdr.dsp component to
>> down convert a signal.
>>
>> Ideally I would want the input wave to have the same amplitude as the
>> output wave however this does not seem to be possible due to the
>> carrier_amplitude property having a maximum allowed value of 14,060.
>>
>> Since the property is scaled by 1.646760258, this brings the amplitude of
>> the mixer wave to 23170.475 or roughly sqrt(2) * 2^15. I would understand
>> if the amplitude was limited to 2^15 to prevent overflow but what is the
>> reason for this sqrt(2) factor?
>>
>> Before outputting, the result of each multiplication is shifted right by
>> 15 (both I and Q) i.e scaled by 1 / 2^15. Therefore with the maximum mixer
>> amplitude, the resulting wave’s amplitude will be roughly 1/sqrt(2) that of
>> the input wave.
>>
>> It is also quite counterintuitive that the input amplitude of the carrier
>> wave is being scaled this way. Would it not be possible to provide the true
>> amplitude to the carrier_amplitude property and have the worker do the
>> necessary scaling? If not, renaming the property to indicate that it is not
>> the actual amplitude would be useful.
>>
>> Thanks,
>> Dan
>> _______________________________________________
>> discuss mailing list -- discuss@lists.opencpi.org
>> To unsubscribe send an email to discuss-leave@lists.opencpi.org
>>
>

D

dwp@md1tech.co.uk

Wed, Jan 31, 2024 10:14 AM

Hi Dom,

Thankyou for looking into this and please pass on thanks to the people you had these replies from.

This has cleared things up for me.

I have been looking at the component .rst files for documentation up to now however the online documentation linked is much clearer and the equations and displayed correctly. I will make sure to refer to this in future as well as the .rst files.

Hi Dom,
Thankyou for looking into this and please pass on thanks to the people you had these replies from.\
This has cleared things up for me.
I have been looking at the component .rst files for documentation up to now however the online documentation linked is much clearer and the equations and displayed correctly. I will make sure to refer to this in future as well as the .rst files.

Replying to:

Empathy v1.0
2024 ©Harmonylists.com