02-25-2019 09:49 AM - edited 02-25-2019 10:22 AM
I have an interesting problem with clock generation, and I thought others might have some clever ideas for how to deal with it.
I've got an SPI controller with specific timing requirements on the chip select, it must follow the clock falling edge by 1/10th of a period.
Currently the way I'm doing this is to generate a 20x SPI clock with an MMCM. Then in VHDL divide this down (div-by 2 and div-by 20) so that I have a 10x SPI clock and an SPI clock. Then both of those clocks are connected through a BUFG before being used anywhere. This works OK, but the need for a 20x clock seems like overkill.
Some of the other ideas I've tried or considered.
Use just 10x SPI clock: This is how I started, but I believe the issue was that because the slow (div-by 10) SPI clock went through a Flip-Flop this caused skew with the 10x SPI clock that led to timing failures. This is why the incoming clock was increased to 20x so that both the 10x SPI clock and the SPI clock could be generated form the logic with standard Flip-Flops. A DDR Flip-Flop would also allow just a 10x clock, but it seems ODDRE1 is only available for output pins.
Use BUFGCE_DIV: Using a divide by 2 and a divide by 5 BUFGCE_DIV can generate the SPI clock from just a 10x SPI clock, but is unable to generate a 50% duty cycle needed on the actual SPI clock.
Generate both clocks with an MMCM: This would work OK. There are a few small issues here. Using CLKOUT1 means the fractional divide isn't available and limits the available frequencies. There is a certain elegance in feeding a single clock to the IP block that would be lost with this.
For a rough idea of the frequencies the SPI clock is ~25Mhz so the 20x clock is ~500Mhz, and this clock directly controls the data-rate from the ADC so needs to be precisely controlled depending on the application.
Thanks in advance for any ideas.
02-25-2019 10:12 AM
Just a thought,
SPI clocks are typicaly MHz , whilst the MMCM runs at 100 of Mhz.
The typical way to make spi clocks, is to do a divider in the logic, and use the DDR outputs of the FPGA to send the clock and dat aout syncronised together.