public static async Task Aggregator(
            FPGA.InputSignal <bool> RXD,
            FPGA.OutputSignal <bool> TXD
            )
        {
            Sequential handler = () =>
            {
                FPU.FPUScopeNoSync();

                while (true)
                {
                    FPGA.Optimizations.AddOptimizer <DefaultOptimizer>();

                    const uint baud = 115200;
                    UART.ReadFloat(baud, RXD, out float mass);
                    UART.ReadFloat(baud, RXD, out float radius);

                    var vOrbit = FPGAOrbitalCalc.VOrbit(mass, radius);

                    UART.WriteFloat(baud, vOrbit, TXD);
                }
            };

            FPGA.Config.OnStartup(handler);
        }
        public void Quokka_VOrbit()
        {
            using (var port = new QuokkaPort())
            {
                var r0 = 6371e+3f;
                // orbit velocities around the earth
                var cases = new[]
                {
                    // low orbit
                    new
                    {
                        R = r0 + 200e+3f,
                        M = 5.972e+24f,
                        V = 7800f
                    },

                    // ISS orbit
                    new
                    {
                        R = r0 + 409e+3f,
                        M = 5.972e+24f,
                        V = 7660f
                    },

                    // geostationary orbit
                    new
                    {
                        R = r0 + 35786e+3f,
                        M = 5.972e+24f,
                        V = 3100f
                    },

                    // moon orbit
                    new
                    {
                        R = r0 + 399000e+3f,
                        M = 5.972e+24f,
                        V = 991f
                    },
                };

                foreach (var testCase in cases)
                {
                    float calculated = FPGAOrbitalCalc.VOrbit(testCase.M, testCase.R);

                    var err = Math.Abs((calculated - testCase.V) / testCase.V);
                    Assert.IsTrue(err < 0.01);

                    port.WriteFloat(testCase.M);
                    port.WriteFloat(testCase.R);

                    var actualBytes = port.Read(4, true, port.DefaultTimeout);
                    var actual      = TestConverters.FloatFromByteArray(actualBytes);

                    Assert.AreEqual(calculated, actual, $"Failed for {testCase}");
                }
            }
        }