So, made some more changes to the GPSDO code, and also swapped out the OCXO for one of the others (just to make sure that I'm not pandering to the peculiarities of one particular OCXO).
Left it to run for a day and a bit and here's how it's looking:
Mean frequency error 0.0000159 Hz or 1 part in 1.59 x 10
-12 (\$\tau\$ = 97,200 aka 27 hours), standard deviation 0.345 Hz (There a few large outliers included in that standard deviation as you can see from the graphs). Peak-to-peak almost everything is inside a ±0.002 Hz band (or 1 part in 2 x 10
-10). So there's room for some improvement to hit the state of the art for an OCXO - not quite timenut, but certainly time-eccentric.
However, something accurate to 2 parts in 10 billion cobbled together in a hot mess on a plugin breadboard ought to make the voltnuts weep by comparison to what's achievable in the volts/current field.
Mean phase error -17.0 ns versus UTC, with standard deviation of 490 ns (again, includes outliers). It's pretty clear that there's a bias in the phase correction and I suspect it's a downward bias due to rounding because I have a deliberate deadband built into the code that doesn't steer it if the error is less than 2 times my measurement uncertainly, which uncertainty happens to be 17.2 nanoseconds. Obviously that's up for some careful analysis, but it's possible I might have to build in a bit of deliberate dither to avoid that bias.
A few more code tweaks and some tidying required, but it looks like the hardware side is basically sound. I have connected up the scope to the 10MHz and (locally generated) 1 PPS outputs and they look horrible, stable but horrible - but that looks down to lack of decoupling and the general kind of signal integrity issues that I'd expect from a mass of wires versus SMD decoupling caps and nice fat ground and power planes. Then it's time to get an SPI LCD connected and check that that part of the hardware design is working, and then I think I can risk finalising the PCB design and sending it off for the Chinese elves to make.
The current mess that is the prototype: