Generally there's a ±1% tolerance in baud rate. But that could be a 1% error one way in the transmitter, and 1% the opposite way in the receiver, and you can't tell which it is without specifically measuring. If we then assume we need to correctly receive 12 bits in sequence (start bit, 8 data bits, parity, and two stop bits), we could drift by as much as 24% of a bit period, and the slew rate and voltage-converter characteristics could mean we don't have the full 50% margin from the ideal starting position in the first place. Based on that, 4x sampling isn't enough to find the middle of the start bit with sufficient accuracy. I think 8x sampling would just about be adequate, but there's presumably a reason why existing designs adopted 16x sampling. Voting logic would help to improve noise margin but wouldn't help with this sort of timing problem.
And sure, we could adopt 8x sampling and double-clock the counter, and thus gain a 4x improvement in divisor resolution. That's feasible in the CPLD layouts I've seen. But now, from a source in the vicinity of 2MHz, we need a 14-bit divisor to get down to 45.45 baud (presently we need 12 bits). I can't fit that into the register map, even if I combine the two Config registers (dedicating the whole of one of them to the low-order bits of the divisor). Something else would have to give. All so that someone can avoid including a second crystal in their design. I'm not interested in that kind of compromise. The divisor table I quoted is meant to cover all the common use cases I could think of, in a manner consistent with the 6551 and most other devices I could find.
If you truly want to have arbitrary baud rate divisors from some random crystal frequency, then you can of course set up an external baud rate generator and use that as the clock source, using the all-zeroes selector which drives the 16x clock directly. It doesn't even need to have a 50% duty cycle, so long as the pulse width meets the CPLD's requirement. I'm pretty sure you can rig up a VIA to do something appropriate.
|