Menu

Floating Point Math Revisit

Help
2022-08-28
2022-08-28
  • Jeff Weinmann

    Jeff Weinmann - 2022-08-28

    I know the variable types : Single, Double and Float are 'experimental' in GCB. Has there been any further thought of implementing them for math operations (Multiplication, Division)?

    Below is code that works in VisualBasic.NET that derives the registers for the SI5351a clock generator. Mostly Unsigned 32 bit integers which GCB can handle, and a float variable (currently N/A in GCB).

    I have been told I could use Integer math to do the same thing, but at a loss on how to do it.

     ' Calc Output Multisynth Divider and R with e = 0 and f = 1 => msx_p2 = 0 and msx_p3 = 1
            Dim d As UInteger = 4
            Dim msx_p1 As UInteger = 0 ' If fout > 150 MHz then MSx_P1 = 0 and MSx_DIVBY4 = 0xC0, see datasheet 4.1.3
            Dim msx_divby4 As Integer = 0
            Dim rx_div As Integer = 0
            Dim r As Integer = 1
    
            If fout > 150000000UI Then
                msx_divby4 = &HC ' MSx_DIVBY4[1:0] = 0b11, see datasheet 4.1.3
            ElseIf fout < 292969UI Then ' If fout < 500 kHz then use R divider, see datasheet 4.2.2. In reality this means > 292 968,75 Hz when d = 2048
                Dim rd As Integer = 0
                Do While (r < 128) AndAlso (r * fout < 292969UI)
                    r <<= 1
                    rd += 1
                Loop
                rx_div = rd << 4
    
                d = CUInt(600000000UI \ (r * fout)) ' Use lowest VCO frequency but handle d minimum
                If (d Mod 2) <> 0 Then ' Make d even to reduce spurious and phase noise/jitter, see datasheet 4.1.2.1.
                    d += 1
                End If
    
                If d * r * fout < 600000000UI Then ' VCO frequency to low check and maintain an even d value
                    d += 2
                End If
            Else ' 292968 Hz <= fout <= 150 MHz
                d = 600000000UI \ fout ' Use lowest VCO frequency but handle d minimum
                If d < 6 Then
                    d = 6
                ElseIf (d Mod 2) <> 0 Then ' Make d even to reduce phase noise/jitter, see datasheet 4.1.2.1.
                    d += 1
                End If
    
                If d * fout < 600000000UI Then ' VCO frequency to low check and maintain an even d value
                    d += 2
                End If
            End If
            msx_p1 = CUInt(128 * d - 512)
    
            Dim fvco As UInteger = CUInt(d) * r * fout
    
            ' Calc Feedback Multisynth Divider
            Dim fmd As Double = CDbl(fvco) / fref ' The FMD value has been found
            Dim a As Integer = CInt(Math.Truncate(fmd)) ' a is the integer part of the FMD value
    
            Dim b_c As Double = CDbl(fmd) - a ' Get b/c
            Dim c As UInteger = 1048575UI
            Dim b As UInteger = CUInt(Math.Truncate(CDbl(b_c) * c))
            If b > 0 Then
                c = CUInt(Math.Truncate(CDbl(b) / b_c + 0.5)) ' Improves frequency precision in some cases
                If c > 1048575UI Then
                    c = 1048575UI
                End If
            End If
    
            Dim msnx_p1 As UInteger = CUInt(128 * a + 128 * b \ c - 512) ' See datasheet 3.2
            Dim msnx_p2 As UInteger = CUInt(128 * b - c * (128 * b \ c))
    
            Global_msnx_p2 = msnx_p2 'For fine tuning WSPR channels
    
            Dim msnx_p3 As UInteger = c
    

    Currently I have to let my VB.NET do the calculation, then I have to store the answers to EEPROM.

    I hear floating point math is slow, but speed isn't concern.

    Just let me know if GCB will possibly have this capability in the future!

    regards,

    Jeff

     
  • Anobium

    Anobium - 2022-08-28

    The current focus is to get the release out and that does not include an enhancement to floats. We know the issues with floats and we dont know when or how to fix yet.

    Jon one. Get the release out and that will be a few weeks away. :-)


     

Log in to post a comment.