Electrical – Constraining synchronous clocks at different frequencies in VHDL

fpgasdctiming-analysisvhdl

I have a design with a FPGA, a MCU, and other external peripherals connected together over a parallel peripheral bus.

The whole system is clocked from two synchronous clocks. The clocks are a 32 Mhz oscillator, and 16Mhz clock that is generated by dividing the 32 Mhz oscillator by two through a flip-flop.

The 16 Mhz output from the flip-flop is used to clock the MCU, furthermore a PLL in the MCU is used to recreated a 16Mhz peripheral bus clock output. And this 16 Mhz peripheral bus output, along with the original 32Mhz oscillator clock the FPGA.

So the FPGA will be driven by two clocks that are skewed by the propagation time of the flip-flop (8ns), and the phase lag of the PPL (5ns). But otherwise they are synchronous. Overall displayed here.

System

So here is the tricky part, how can i constrain these to get Quartus to consider the relationship between these two in the timing analysis. The default behaviour is to consider their internal relationship as 0.05, which isnt really true. Since the minimum would be the period of the slower clock, or the whole slower clock if multicycles of two is allowed. The default relationship will automatically cause the design to fail timing analysis and ignoring the two domains altogether with asynchronous clock group definition isnt really meaningful either is it. It feels like static timing analysis should be possible given that they are "edge synchronous" but at different frequencies.

Columns are Clock1, Clock2, relationship, Clock skew, Data delay.

enter image description here

So far i have tried grouping them together, and not together with the set clock group statement. Such as.

set_clock_groups -asynchronous \
-group { external_clock  } \
-group {    processor_clock }

In addition with using the multicycle definition

set_multicycle_path -setup -from [get_clocks {cpu_clk}] -to [get_clocks {e_clk}] 2
set_multicycle_path -hold -from [get_clocks {cpu_clk}] -to [get_clocks {e_clk}] 2   

But the result is either ignoring the cross domain interaction altogether, or unchanging relationship of 0.05.

The clocks are defined as

create_clock -name external_clock -period 31.2 [get_ports e_clk]
create_clock -name processor_clock -period 62.5 [get_ports cpu_clk]

How would you constrain this.

Best Answer

The reason for the weird 0.05 is that your period for the 32MHz clock is 31.25ns not 31.2ns. Alternatively you can specify the period as:

create_clock -name external_clock -period "32MHz" [get_ports e_clk]

However it is not as easy as just specifying the clocks, you will also need to constrain the interfaces so that Quartus knows what setup/hold times it has to work with. For this you will need to refer to the TimeQuest user manual.

In any case the easiest thing to do is treat both clocks as asynchronous, and then use dual-clock FIFOs in your design to cross the clock domains. If your clocks can be treated as asynchronous, then you can tell TimeQuest this using the command:

set_clock_groups -asynchronous -group [list processor_clock] -group [list external_clock]