Yes, it looks like the biggest contributor to the problem was the modulo math. I should have known! Thanks for the quick response. I see the correct number of counts (when measuring over 60 seconds) when FLEXI_RATE is 25000 and 50000. However, when I get to FLEXI_RATE=75000 I start to see the problem, e.g. with FLEXIRATE=100000, I see 83,333 ticks in 60 seconds when I expect 100,000.
So is the problem specifically caused by the simulatePWM() function taking longer to run than the base rate interval, effectively causing it to overrun the interval? If so, then it sounds like the fastest I will be able to run and execute a small amount of instructions is probably 50,000Hz, and the instructions will likely need to be simple direct port writing operations to keep it quick.