Please share ideas for an integer clock divider with excellent phase preservation
Simon Merrett wrote 04/26/2022 at 09:46 • -1 pointI'm trying to divide eg single digit MHz clock by an almost arbitrary (non-power-of-2) integer and convert it to logic level pulses in the range of around 1-100 Hz. I'd like to minimise the phase lag of the rising pulse with respect to the input signal. I can condition the output signal for a faster rise time if needed but I estimate the edge needs to be launching within around 1 to 10 nanoseconds of the trigger edge arriving.
I have heard of people hand coding assembly on a PIC and feeding the reference clock into the PIC's clock input to achieve something similar but does anyone know of a good guide, specialist parts or particular IC / microcontroller peripherals that are designed to do this?
ask
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
It can be done with a binary adder clocked with the reference clock, with the proper constant added to counter every cycle. Think of it this way. 16 bit register. Add 0x8000 and watch the MSB. You get half the clock frequency. This makes a divide by 2. Add 0x4000 and you get 1/4th... With a 32 bit register and adder, one may synthesize most any frequency which will be phase aligned with the clock. There will be jitter, but it will be in phase. This is quite handy in programmable logic.
Are you sure? yes | no
[this comment has been deleted]
Thanks, have had a look at them but it's not all that easy to see which ones are a good bet for this application. I'm in the bothersome position of not knowing enough about those types of chips to home in on something that's likely to be close to the mark.
Are you sure? yes | no
Back in the 80's I was designing video circuits, and would use 74 series synchronous counters and other logic to generate waveforms. For instance, a 74163 4-bit counter, with the divider value at the counter load inputs, and carry out pin connected to load pin. The up/down input set to make it count down. Whenever the count gets to 0, it reloads the counter on the next clock pulse. Then whatever value you present at the counter load inputs will be the divisor.
Set up a comparator to decode a range of values, for generating the output waveform.
Use the fastest logic family you can find to minimize propagation delay. If you want to get the input clock in better alignment with the output, put it through a delay line.
This is of course a lot of circuitry when compared to using PICs and such. Wider counters would reduce the chip count but I don't know what is available. The digital blocks in a PSoC microcontroller could likely be used to implement this same circuit.
Are you sure? yes | no
Thanks for the psoc suggestion and your outline for a pure logic version!
Are you sure? yes | no
seems like you need a 20 bit counter with comparator. I think many simple microcontrollers (I had some succes using Arduino M0 for smth similar) have up to 16 bit counters, but you could probably link the output of a first 16 bit counter to a second (8 or 16 bit) and set both comparators to match the counter value you want and then send a pulse when this happens and also reset the both counters. This wouldnt really need assembly, but a few well chosen registers to be set to tell the counters to do what you want. This will be plenty fast and responsive as it does not rely on interrupts or programming, but will require a quite thorough read of the datasheet of the microcontroller to understand the setting up of the counters. Benefit is that you could use the same microcontroller to do plenty of other things as well (could be a benefit over a dedicated clock generator/divider) as the counters dont use any cycles once they are set up.
Are you sure? yes | no
Thanks @Jo Verbeeck . Sounds like a good approach - would you mind sharing any of the performance specs you got, if you managed to measure them? Datasheet rise times of gpios don't give much idea about likely jitter or lag from the clock. Ps, if you have any more snippets on the particular peripherals you used on the SAMD21?
Are you sure? yes | no
Jitter should depend entirely on the mcu clock quality and I would think the lag should be less than a clock period as the whole function runs in hardware so I guess <25ns. For setting up the TC counters I would have to dig into my old code. I recall that especially setting the mux to make the right signal go to the right pin was horror. A quick look at the datasheet shows that it can indeed do 32 bit counter mode.
Are you sure? yes | no
@Jo Verbeeck thanks!
Are you sure? yes | no
see for code example (beware spaghetti code)
https://github.com/joverbee/compressed_sensing/blob/main/CS_patterngenv2_latest_samd_core.ino
the functions startpwm() and startstempwm() do something with the counters which might give inspiration (or confusion).
startpwm() runs a free running counter based (TCC0 which is 24 bit so plenty for your 1e6 division) on the internal clock and toggles an output pin at a certain count value and resets the counter at another count value.
You would want to change this so that the counter uses an external pin (see startstempwm on how to connect ext interupt pin 2 to the event system which should then act as the clock source for the counter by setting that eg the rising event should tirgger a count event rather than the current start/stop event while the falling edge would do nothing ) or alternatively you might be able to choose that the clock input of the counter is an external pin rather than the internal clock (not sure if that is possible).
I would suggest you try to extract the part that makes a free running pulse divided from the clock first. Then change the source of the counter clock to an external pin.
Are you sure? yes | no
@Jo Verbeeck thanks - that's valuable affirmation of a vague plan I was scratching out while looking at the datasheet last night.
Are you sure? yes | no
Does a microcontroller's timer could do it ? You often can clock one of the timers from an external source, with optional prescaling. You should be able to have some decent precision, and fast reaction (although I don't know if that can be that fast propagation, even when running asynchronous.
Or, as proposed by Bob, you could use an FPGA. With that low pins needed, they can be quite cheap.
Are you sure? yes | no
Thanks. I have found the picDIV which almost does this, instead using assembly in the main loop to pretty much achieve the effect desired. But if there are known-good micros other than the PIC12F of picDIV, I'd like to hear about them.
Are you sure? yes | no
It is going to take some serious digging to figure out which ones will work for you (and are available this year). Try searching Digikey or Mouser for Clock Generators. My suspicion is that dividing by 1e6 may be hard to find, that is a lot of bits.
Another option would be an FPGA
Bob
Are you sure? yes | no
Sorry Bob! I don't know why I had got you down as Ben!
Thanks for the search tips - I'll get looking.
Are you sure? yes | no
Is a 50% duty cycle on the output necessary? Does the input signal run continuously?
Are you sure? yes | no
@Bharbour no, 50% duty is arbitrary but I thought it would be the easiest to achieve. Anything from 1-99% would be fine. I understand 20% is standard for many 1PPS outputs.
Are you sure? yes | no
@Bharbour ref your question on Hack Chat, I only just started pulling bits together. It is sort of for a disciplined oscillator but I'm really only at the experimenting/building blocks stage.
Are you sure? yes | no
This sounds like a standard PLL Clock generator to me.
Are you sure? yes | no
Thanks Ben - do they do eg 10^6 division too?
Are you sure? yes | no