#### Need help understanding a line of code in ubitx_si5351.cpp (msxp2 = ...)

David Feldman

Hello,

I am trying to understand ubitx_si5351.cpp, and one line of the code has me puzzled:

In the class
void ubitx_si5351::setfreq
here is the line I need help with:
msxp2 = 128 * msb - 128 * msb / msc * msc; // msxp3 == msc;

At the end the expression I see this: "128 * msb / msc * msc"

What is the purpose of "msb / msc * msc" in this calculation?

msc is a right-shifted version of fout,
but I cannot understand what is happening in this line of code.

Thank you very much,

73 Dave WB0GAZ wb0gaz@...

Jerry Gaffke

In section 4.1.2 on page 6 of this SiLabs document about programming the si5351:
https://www.silabs.com/documents/public/application-notes/AN619.pdf
it says that to get a ratio of (a + b/c) for the  vco frequency divided by the output frequency of the msynth divider,
we load some registers with the following magical values: for MSxP1, MSxP2 and MSxP3.
(Assume that a,b,c are all non-negative integers, and b is less than c.)

MSxP1 = 128*a + Floor(128 * b/c) - 512      (18 bit result)
MSxP2 = 128*b - c*Floor(128 * b/c)             (20 bit result)
MSxP3 = c                                                    (20 bit result)

The Floor() operator means to find the integer part of the value in parenthesis.
For example the value of    Floor(23/4)  ==  Floor(5.75)  ==  5
Integer divides in the C language naturally do the floor operation,  so this C code
long int x;       x = 23/4;
results in variable x having a value of 5.

Computing
c*Floor(128 * b/c)
is performed as
Floor((128*b)/c) * c
or in C code that's
long int  a,b,c;
((128*b)/c) * c

You will have to ask SiLabs if you want to know why those registers need
these particular magical values loaded into them.

>> msc is a right-shifted version of fout,

True in this case, but that is just a consequence of how a,b,c are computed.
Most other si5351 libraries use other methods to compute a,b,c
involving floating point computations.

What you need to know is that    Fvco/Fout  =  a + b/c
where in this case we are assuming a floating point result from the b/c divide.

Jerry, KE7ER

On Sat, May 5, 2018 at 10:02 am, David Feldman wrote:
Hello,

I am trying to understand ubitx_si5351.cpp, and one line of the code has me puzzled:

In the class
void ubitx_si5351::setfreq
here is the line I need help with:
msxp2 = 128 * msb - 128 * msb / msc * msc; // msxp3 == msc;

At the end the expression I see this: "128 * msb / msc * msc"

What is the purpose of "msb / msc * msc" in this calculation?

msc is a right-shifted version of fout,
but I cannot understand what is happening in this line of code.

Thank you very much,

73 Dave WB0GAZ wb0gaz@...

David Feldman

Thank you, Jerry - that helps guide me through the code and chip documentation (I was getting puzzled at doing all of these computations in unsigned 32-bit integer space with overflows and stuff to worry about.)

Dave

Jerry Gaffke

Pretty much by nature, as the registers on the si5351 are rather obtuse.
But I convinced myself it was correct (with no overflows) before releasing it.
I doubt most users of other si5351 libraries ever manage to figure them out either.

I invented the scheme for downshifting b and c of (a+b/c) till c fits in its 20 bit register
as a way of doing these computations in 32 bit integer math.  But later found a
similar trick in apnotes for sister part si5338, so the technique has been blessed by SiLabs.
The si5338 notes were created before my re-invention.

A new set of eyes may find bugs I didn't see.
Let me know if you find anything.
Or have any further questions.

Everyone incorporating my code feels obliged to make minor changes to style.
The original code is in    https://groups.io/g/BITX20/files/KE7ER/si5351bx_0_0.ino

There are errors and inconsistencies and omissions in that AN619 doc.
In particular, the Fvco/Fout ratio of (a+b/c) is restricted to values of 8.0 through 1800.0
inclusive, it's also possible to special case integer values of 4 and 6 but we do not use that.
The PLL msynth ratio is of course restricted to those values of Fvco/Fxtal that give a Fvco
of 600-900 mhz, so for an Fxtal of 25mhz that's values between 24.0 and 36.0 inclusive.
Register 36 is shown incorrectly in the summary on page 36.
And the document does not give enough information about which registers need to be initialized.
The ClockBuilderPro software from SiLabs can help resolve some of that, but does some stuff
not documented at all in AN619, initializes registers that don't need it, and hunts for elusive
msynth register values using small integers in b and c but avoids the msynth's integer mode.

Jerry, KE7ER

On Sun, May 6, 2018 at 05:30 am, David Feldman wrote:
Thank you, Jerry - that helps guide me through the code and chip documentation (I was getting puzzled at doing all of these computations in unsigned 32-bit integer space with overflows and stuff to worry about.)

David Feldman

Thanks very much, Jerry -

The additional insight and detail is much appreciated!

Dave

David Feldman

(picking this up from a few weeks ago...)

One follow-up question regarding overflow avoidance method in the SI5351 divider calculation: What is the minimum frequency step size obtained with the ubitx si5351 driver (that is, can you tune a ubitx with 1 Hz steps, or more, or less granular?

Does the pre-shifting code in the driver impact frequency resolution (does it throw away some bits of the desired target frequencies?)

Thanks,

Dave

Jerry Gaffke

When I wrote the si5351bx code I had the Bitx40 in mind, and was testing for a high side vfo of 19mhz.
As I recall, that code was accurate to within something a bit worse than 0.1hz for arbitrary frequencies at 19mhz.

On the uBitx, our VFO can be as high as 30+45 mhz.
We lose accuracy as the frequency goes up, but the uBitx should still tune correctly to within 1 hz or so.
If accuracy is an issue, you probably want to put that 25mhz reference in an oven before worrying about the calculations.

Easy enough to set these calculations up on a full blown computer somewhere, do a comparison
between the fractional math of the si5351bx_setfreq() routine and something more straightforward
in double precision floating point.
As I recall, the si5351bx code held it's own, accuracy got a little bit better with floating point but not by much.
There's only so much precision the si5351 can give us with those 20 bit registers for b and c.

Another factor is phase noise, as we go up in frequency that becomes more of an issue.
I have no way to measure it, and no idea at what point it's a problem for the various transmission modes.
There might be minor improvements to be had with regard to si5351 phase noise.  Going to an integer mode
pll msynth divide might help a little bit but I doubt it would be anything like a factor of two.  Some weird stuff
going on with SiLab's ClockBuilderPro, it doesn't seem to bother with integer mode but does an exhaustive
hunt for low b values in the (a+b/c) selection.  I assume that is done to minimize phase noise.

There's some loose talk here about extending the uBitx to 2m and beyond.
If that takes off we may want to consider a Raduino using the si5338.
Better phase noise figures, better precision, reduced crosstalk, can hit much higher frequencies.

If you want to go crazy, there's the si5340/si5341.
Goes even higher in freq, lower in phase noise, has an spi bus option for much faster load times.
Primary downside is that it burns a watt or so of 1.8v.

Jerry, KE7ER

On Fri, May 25, 2018 at 10:23 am, David Feldman wrote:
(picking this up from a few weeks ago...)

One follow-up question regarding overflow avoidance method in the SI5351 divider calculation: What is the minimum frequency step size obtained with the ubitx si5351 driver (that is, can you tune a ubitx with 1 Hz steps, or more, or less granular?

Does the pre-shifting code in the driver impact frequency resolution (does it throw away some bits of the desired target frequencies?)

Thanks,

Terry Morris

Both the question and the response/answer are intriguing to me. Mostly the answer. I don't comprehend most of the answer but I think I get the gist of it. Regarding the latter part of Jerry's conversation speaking about the Si5338, Si5340, and Si5341 is there any other downside other than the loss of about 1 w at 1.8v? I am presuming from your explanation of these devices that there is a positive advantage to using them, not only for 2 meter capability, but for better phase noise suppression and better crosstalk reduction. In an example that I might understand better, would using any of those 3 devices be like the performance difference between an analogue HW-9 and any of the modern commercial transceivers?

Terry - KB8AMZ
Brimfield Twp, OH  USA
Linux User# 412308, Ubuntu User# 34905
OSs: LM18.2 64bit, Ubuntu 16.04, tahrPup64 64bit, Raspian
Orgs: PCL70-FOP, NTHS, ALUG, ARRL, PCARS#78, NAQCC#6668, NO-QRP-C, QRP-ARCI#8855, SKCC#14195, USN 1965-1969 AG3

I chair the PCARS CW/QRP SIG and Linux for Hams SIG, second and fifth Tuesday

my computer, my opinion

On Fri, May 25, 2018 at 3:24 PM, Jerry Gaffke via Groups.Io wrote:
When I wrote the si5351bx code I had the Bitx40 in mind, and was testing for a high side vfo of 19mhz.
As I recall, that code was accurate to within something a bit worse than 0.1hz for arbitrary frequencies at 19mhz.

On the uBitx, our VFO can be as high as 30+45 mhz.
We lose accuracy as the frequency goes up, but the uBitx should still tune correctly to within 1 hz or so.
If accuracy is an issue, you probably want to put that 25mhz reference in an oven before worrying about the calculations.

Easy enough to set these calculations up on a full blown computer somewhere, do a comparison
between the fractional math of the si5351bx_setfreq() routine and something more straightforward
in double precision floating point.
As I recall, the si5351bx code held it's own, accuracy got a little bit better with floating point but not by much.
There's only so much precision the si5351 can give us with those 20 bit registers for b and c.

Another factor is phase noise, as we go up in frequency that becomes more of an issue.
I have no way to measure it, and no idea at what point it's a problem for the various transmission modes.
There might be minor improvements to be had with regard to si5351 phase noise.  Going to an integer mode
pll msynth divide might help a little bit but I doubt it would be anything like a factor of two.  Some weird stuff
going on with SiLab's ClockBuilderPro, it doesn't seem to bother with integer mode but does an exhaustive
hunt for low b values in the (a+b/c) selection.  I assume that is done to minimize phase noise.

There's some loose talk here about extending the uBitx to 2m and beyond.
If that takes off we may want to consider a Raduino using the si5338.
Better phase noise figures, better precision, reduced crosstalk, can hit much higher frequencies.

If you want to go crazy, there's the si5340/si5341.
Goes even higher in freq, lower in phase noise, has an spi bus option for much faster load times.
Primary downside is that it burns a watt or so of 1.8v.

Jerry, KE7ER

On Fri, May 25, 2018 at 10:23 am, David Feldman wrote:
(picking this up from a few weeks ago...)

One follow-up question regarding overflow avoidance method in the SI5351 divider calculation: What is the minimum frequency step size obtained with the ubitx si5351 driver (that is, can you tune a ubitx with 1 Hz steps, or more, or less granular?

Does the pre-shifting code in the driver impact frequency resolution (does it throw away some bits of the desired target frequencies?)

Thanks,

Jerry Gaffke

I have no idea at what point phase noise will be an issue for the si5351 across
the various modes of operation, be it SSB, CW, FM,  or digital.
I do know that it works to 200mhz, you can push it to almost 300mhz.
Phase noise and resolution of the si5351 will be 10x worse at 200mhz than at 20mhz.

Bringing on an Si5340 would be a nice handy sledge hammer for prototyping,
goes up to 1028mhz, resolution of ppb, and has very low jitter.
Likely cheaper and lower power ways to do what you need, but it's a nice part.
Not many hobbyists are using it, you might be writing your own code, and that could get nasty,

The Si5338 is a bit cheaper, and lower performance.
But better than the Si5351.
Again, you might be writing your own code.

Both cost a fair bit more than the \$1 Si5351, and are surface mount with a bunch of pins.

https://www.silabs.com/products/timing/clocks/general-purpose-clock-generators/device.si5338a
https://www.silabs.com/products/timing/clocks/ultra-low-jitter-clock-generators

Jerry

On Mon, May 28, 2018 at 03:21 pm, Terry Morris wrote:
Both the question and the response/answer are intriguing to me. Mostly the answer. I don't comprehend most of the answer but I think I get the gist of it. Regarding the latter part of Jerry's conversation speaking about the Si5338, Si5340, and Si5341 is there any other downside other than the loss of about 1 w at 1.8v? I am presuming from your explanation of these devices that there is a positive advantage to using them, not only for 2 meter capability, but for better phase noise suppression and better crosstalk reduction. In an example that I might understand better, would using any of those 3 devices be like the performance difference between an analogue HW-9 and any of the modern commercial transceivers?

Jerry Gaffke

The SI5340 datasheet says a step size of 0.001 ppb  (parts per billion).
So if creating a signal at 440mhz, you can adjust it in steps of 440e6 * 0.001/1e9 = 0.00044 hz.
Better have a stable reference osc into the Si5340 to see that kind of performance.
An Si5351 on some serious steroids.

Jerry, KE7ER

On Mon, May 28, 2018 at 05:46 pm, Jerry Gaffke wrote:
resolution of ppb,

Terry Morris

Thanks for your response Jerry, but I am still snowballed.

Like I took the Extra Class License class the second time around with the same instructor, Jim Wilson, AC8NT. Jim is a scholarly guy with more degrees than I have HF rigs, sometimes he is very down to earth and speaks in terminology that I understand. I have struggled for many years trying to comprehend the magic with electronics and something is not clicking within my synapses. The other club members in my class told me after various classes that I asked really good questions that they were embarrassed to ask. Whoopie. Not the point. I did ask Jim many questions but the responses were probably geared more for EE grad students than what I comprehended. The others in my class understood the responses so I struggled along until the end of the class. I let Jim know that I didn't understand his responses but I didn't want to hold up the rest of the class. Jim advised me to study the test pool questions but continue the class (the only thing it cost me was time). At the end of the class Jim had a special VE team to test us. I didn't pass. I was more confused than before. My club was giving a scheduled test in 3 weeks, but there was a local hamfest in 2 weeks. I crammed like I was crazy and when I went to take the test I felt crazy. I did pass though. Most of the questions I answered correctly I still don't understand. Now I want to learn more than before how this magic works, I would really like to build a transceiver of my own design and know why the pieces and parts work.

Moving on the next topic...

Terry - KB8AMZ
Brimfield Twp, OH  USA
Linux User# 412308, Ubuntu User# 34905
OSs: LM18.2 64bit, Ubuntu 16.04, tahrPup64 64bit, Raspian
Orgs: PCL70-FOP, NTHS, ALUG, ARRL, PCARS#78, NAQCC#6668, NO-QRP-C, QRP-ARCI#8855, SKCC#14195, USN 1965-1969 AG3

I chair the PCARS CW/QRP SIG and Linux for Hams SIG, second and fifth Tuesday

my computer, my opinion

On Mon, May 28, 2018 at 8:46 PM, Jerry Gaffke via Groups.Io wrote:
I have no idea at what point phase noise will be an issue for the si5351 across
the various modes of operation, be it SSB, CW, FM,  or digital.
I do know that it works to 200mhz, you can push it to almost 300mhz.
Phase noise and resolution of the si5351 will be 10x worse at 200mhz than at 20mhz.

Bringing on an Si5340 would be a nice handy sledge hammer for prototyping,
goes up to 1028mhz, resolution of ppb, and has very low jitter.
Likely cheaper and lower power ways to do what you need, but it's a nice part.
Not many hobbyists are using it, you might be writing your own code, and that could get nasty,

The Si5338 is a bit cheaper, and lower performance.
But better than the Si5351.
Again, you might be writing your own code.

Both cost a fair bit more than the \$1 Si5351, and are surface mount with a bunch of pins.

https://www.silabs.com/products/timing/clocks/general-purpose-clock-generators/device.si5338a
https://www.silabs.com/products/timing/clocks/ultra-low-jitter-clock-generators

Jerry

On Mon, May 28, 2018 at 03:21 pm, Terry Morris wrote:
Both the question and the response/answer are intriguing to me. Mostly the answer. I don't comprehend most of the answer but I think I get the gist of it. Regarding the latter part of Jerry's conversation speaking about the Si5338, Si5340, and Si5341 is there any other downside other than the loss of about 1 w at 1.8v? I am presuming from your explanation of these devices that there is a positive advantage to using them, not only for 2 meter capability, but for better phase noise suppression and better crosstalk reduction. In an example that I might understand better, would using any of those 3 devices be like the performance difference between an analogue HW-9 and any of the modern commercial transceivers?

Jerry Gaffke

OK, a few more words about what's going on inside the si5351.
Perhaps more than you really want to hear.

Assume you are tuned into a CW station at 7.1mhz.
We have a  single conversion superhet such as the Bitx40, the VFO is 7.1 mhz above
our 12mhz intermediate frequency, so 19.1mhz.  The Si5351 is providing that VFO.

But the Si5351 only has an 875mhz reference oscillator, it has to do some sophisticated math inside
to create that 19.1mhz VFO.  And that math sometimes has rounding errors.
Most of the time the VFO is right at 19.1mhz, but it does occasionally jump around a little bit,
in extreme cases by a kilohertz or more.  So in addition to letting you hear that 7.1 mhz station,
your radio might also be letting through bits and pieces of other stations at 7.099 or 7.101 mhz, if only
for a millionth of a second or so.  Those bits and pieces add up, they sound like noise.
Specifically, phase noise.

To reduce that phase noise requires better computations inside the si5351, and that requires more power.

Here's a brief example of the sort of math that goes on inside the Si5351:
Assume we have a 875mhz reference, and want to generate a 19.1mhz signal.
We an get close by dividing by 46, giving 19.0217 mhz out.
We can divide by 45, to get 19.4444 mhz.
If we mostly divide by 46, and sometimes divide by 45, it can average out to exactly 19.1 mhz,
but if you look close you can still tell that it is just jumping between 19.0217 and 19.4444 mhz out.
Some serious phase noise.
This is called a fractional divider, because it is dividing by something between the integers 45 and 46.

That's what SiLabs does, except they also add a programmable delay line to the output pin.
They delay the rising and falling clock edges a few picoseconds, differently for each clock edge,
doing calculations with each clock edge to determine how much delay is needed to make the output
look like a 19.1mhz square wave.  Those calculations aren't perfect, nor is the delay line.
So we still get some residual phase noise.

The Si5351 operates in two stages, first stage brings the 25mhz crystal oscillator up to around 875mhz.
This involves a second fractional divider much like the one described above.
In this case, 875/25 = 35.0 exactly, but that figure of 875 could have been anything between 600 and 900 mhz.

Jerry

On Tue, May 29, 2018 at 12:29 pm, Terry Morris wrote:
Thanks for your response Jerry, but I am still snowballed.

Terry Morris

Jerry,

I can't say that I completely understand everything that you just described but I do have a better understanding. It is Elmer's like you that make this hobby so inaugurating. I thank you for taking the time to explain this to me. I still have a lot to learn. Your explanation was not more than I want to hear. It was perfect.

Terry - KB8AMZ

On Tue, May 29, 2018 at 5:35 PM, Jerry Gaffke via Groups.Io wrote:
OK, a few more words about what's going on inside the si5351.
Perhaps more than you really want to hear.

Assume you are tuned into a CW station at 7.1mhz.
We have a  single conversion superhet such as the Bitx40, the VFO is 7.1 mhz above
our 12mhz intermediate frequency, so 19.1mhz.  The Si5351 is providing that VFO.

But the Si5351 only has an 875mhz reference oscillator, it has to do some sophisticated math inside
to create that 19.1mhz VFO.  And that math sometimes has rounding errors.
Most of the time the VFO is right at 19.1mhz, but it does occasionally jump around a little bit,
in extreme cases by a kilohertz or more.  So in addition to letting you hear that 7.1 mhz station,
your radio might also be letting through bits and pieces of other stations at 7.099 or 7.101 mhz, if only
for a millionth of a second or so.  Those bits and pieces add up, they sound like noise.
Specifically, phase noise.

To reduce that phase noise requires better computations inside the si5351, and that requires more power.

Here's a brief example of the sort of math that goes on inside the Si5351:
Assume we have a 875mhz reference, and want to generate a 19.1mhz signal.
We an get close by dividing by 46, giving 19.0217 mhz out.
We can divide by 45, to get 19.4444 mhz.
If we mostly divide by 46, and sometimes divide by 45, it can average out to exactly 19.1 mhz,
but if you look close you can still tell that it is just jumping between 19.0217 and 19.4444 mhz out.
Some serious phase noise.
This is called a fractional divider, because it is dividing by something between the integers 45 and 46.

That's what SiLabs does, except they also add a programmable delay line to the output pin.
They delay the rising and falling clock edges a few picoseconds, differently for each clock edge,
doing calculations with each clock edge to determine how much delay is needed to make the output
look like a 19.1mhz square wave.  Those calculations aren't perfect, nor is the delay line.
So we still get some residual phase noise.

The Si5351 operates in two stages, first stage brings the 25mhz crystal oscillator up to around 875mhz.
This involves a second fractional divider much like the one described above.
In this case, 875/25 = 35.0 exactly, but that figure of 875 could have been anything between 600 and 900 mhz.

Jerry._,_._,_

David Feldman

I appreciate the continued discussion on these topics!

The document below from TI may (or may not) fully apply to the si5351 family, but I found it helpful in understanding fractional-N synthesis concepts (mainly, some of the refinements that help deal with the basic idea of jumping between two adjacent divider ratios.)

http://www.ti.com/lit/an/swra029/swra029.pdf