1
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ 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 -period "32MHz" \$\endgroup\$ – Tom Carpenter Apr 12 '17 at 7:49
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Tom Carpenter Apr 12 '17 at 7:52
  • 1
    \$\begingroup\$ Also could you add arrows on to your diagram, it's not entirely clear which clock is going where from your description \$\endgroup\$ – Tom Carpenter Apr 12 '17 at 7:53
  • 1
    \$\begingroup\$ In any case the easiest thing to do is treat both clocks as asynchronous (set_clock_groups -asynchronous -group [list processor_clock] -group [list external_clock]), and then use dual-clock FIFOs in your design to cross the clock domains. \$\endgroup\$ – Tom Carpenter Apr 12 '17 at 7:55
  • \$\begingroup\$ Thank you for the pointer regarding the 0.05 artifact Tom. There are may be synchronizers across the domain i believe but i am not exactly sure. This is not my code actually, it is a porting assignment and i should modify as little as possible. I will add arrows. Original system worked, but now some additional delays are added due to level translators (not shown). But i wish to constrain the clocks so cross domain interaction is included. \$\endgroup\$ – Stonie Apr 12 '17 at 8:13
3
\$\begingroup\$

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]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.