Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16597 Discussions

How to constrain the phase shift to synchronized/generated non-overlapping clocks in SDC?

frwo
Beginner
1,380 Views

Hello!

I'm currently struggling to properly set up my SDC file for a non-overlapping clock generator:

 

What I have is a 100Mhz clock for the FPGA (used for the synchronizer) and an external 0,987Mhz clock:

// Synchronizer for external clock always @(posedge clk_100MHz_i) begin phi0_del0 <= clk_phi0_i; phi0_del1 <= phi0_del0; phi0_del2 <= phi0_del1; end

using this now synchronized external clock I create two NEW non-overlapping clock signals clk_phi1+clk_phi2:

// Generate non overlapping clocks reg clk_phi1 = 1'bX; reg clk_phi2 = 1'bX;   always @(negedge clk_100MHz_i) begin clk_phi1 <= ~phi0_del0 & ~phi0_del2;   clk_phi2 <= phi0_del1; end

The clock "clk_phi2" is basically the external clock shifted by ~20ns.

 

Now I tried to constrain these signals:

# Constrain clock port clk_100MHz_i create_clock -name {clk_100MHz_i} -period 10.000 [get_ports {clk_100MHz_i}]   # Define external base clock create_clock -name clk_phi0 -period 1013 [get_ports {clk_phi0_i}] create_clock -name clk_phi0_virt -period 1013   # Constrain derived non-overlapping clocks create_generated_clock -name clk_phi1 -source clk_100MHz_i -edges {103 199 303} [get_pins {clock_gen|clk_phi1|q}] create_generated_clock -name clk_phi2 -source clk_100MHz_i -edges {1 101 201} [get_pins {clock_gen|clk_phi2|q}]   # Make clk_phi0/1/2 asynchronous to 100Mhz base clock set_clock_groups -asynchronous -group [get_clocks {clk_phi0 clk_phi0_virt clk_phi1 clk_phi2}] -group [get_clocks {clk_100MHz_i}]   # Define delays for slow input clock and generated output clocks set_input_delay -clock clk_phi0_virt -min 0.0 [get_ports {clk_phi0_i}] set_input_delay -clock clk_phi0_virt -max 3.0 [get_ports {clk_phi0_i}]   set_output_delay -clock clk_100MHz_i -min -1.0 [get_ports {clk_phi1_o}] set_output_delay -clock clk_100MHz_i -max 3.0 [get_ports {clk_phi1_o}]   set_output_delay -clock clk_100MHz_i -min -1.0 [get_ports {clk_phi2_o}] set_output_delay -clock clk_100MHz_i -max 3.0 [get_ports {clk_phi2_o}]   ################################################# set_input_delay -clock clk_phi0_virt -min 0.0 [get_ports {tst_signal}] set_input_delay -clock clk_phi0_virt -max 3.0 [get_ports {tst_signal}]

Now the problem where I'm stuck: I get a setup/hold violation for tst_signal.

tst_signal is launched with "clk_phi0" and should be latched with the

falling edge of "clk_phi2":

always @(negedge clk_phi2) begin tst <= tst_signal; end

Can someone point me to the mistake?

Is my usage of virtual clock clk_phi0 correct?

 

Thanks,

Frank

 

PS: The question is somewhat related to an earlier question I asked but.....

0 Kudos
3 Replies
sstrell
Honored Contributor III
1,152 Views

You're essentially creating source synchronous-like interfaces here. A few things:

 

1) You don't need set_input_delay for clock inputs (clk_phi0_i). Once an input is defined as a clock, it's not a data path so this is not necessary.

2) Output clocks should not have set_output_delay constraints. They should have generated clock constraints where the source is some internal clock pin (like the output of a PLL or the output of your clock generation logic), the target is the output clock port (clk_phi1_o, clk_phi2_0), and the relationship to the source is a multiply_by 1. This makes the tool look at the output as a clock path instead of a data path. Once you've created the generated clock constraints, false path the clock output paths (ex.: set_false_path -to [get_ports clk_phi1_o]), so they are not analyzed as data paths. Data outputs that are clocked at a "downstream" device by these output clocks should have set_output_delay constraints and reference the generated output clock.

3) For tst_signal, you need to tell the tool to only analyze on the rising edge of clk_phi0_virt (launch edge) and the falling edge of clk_phi2 (latch edge). To do this, you need false path timing exceptions to indicate when the tool should not perform an analysis:

 

set_false_path -rise_to [get_clocks clk_phi2]

 

I'd recommend checking out the online training about constraining single data rate source synchronous interfaces, which is essentially what you're doing here:

 

https://www.intel.com/content/www/us/en/programmable/support/training/course/ocss1000.html

 

#iwork4intel

0 Kudos
frwo
Beginner
1,152 Views

Hello sstrell,

thanks for your answer. Why isn't it a system-synchronous design? I have an external clock (phi0; ~1MHz) which is used as a basis for some of the external signals and at the same time

also my generated (but still synchronous) clocks that are also used as launch and latch clocks for some signals!?

 

And did I get that right:

I need to constrain the INTERNAL output of the clock generation logic pins via create_generated_clock (more or less as posted) BUT additionally also

the output ports again via set_generated_clock with multiply_by 1?

 

In other words: 2x create_generated_clock commands per generated clock? (1x Internal pin + 1x external port)?

 

BTW: I constrained the output port as data port because the whole design is a multi-mode device:

// Assign outputs assign devPort_o[0] = (cfg == 4'h0) ? clk_phi1 : data_enable; assign devPort_o[1] = (cfg == 4'h0) ? clk_phi2 : clk_phi1;

As you can see I'm muxing signals and clocks to a signal output port! (BTW: It's a pity that TimeQuest doesn't support set_case_analysis which seems to be made for this as I'll have 6 different operating

configuration 4'h0 <= cfg <= 4'h5).

 

How to do that one correctly?

 

Thanks,

Frank

0 Kudos
sstrell
Honored Contributor III
1,152 Views

"I need to constrain the INTERNAL output of the clock generation logic pins via create_generated_clock (more or less as posted) BUT additionally also

the output ports again via set_generated_clock with multiply_by 1?"

 

Correct.

 

"In other words: 2x create_generated_clock commands per generated clock? (1x Internal pin + 1x external port)?"

 

Correct.

 

For devPort_o, that is tricky. You can't false path devPort_o[0] because you do have it as a data output in one case, so you should be OK with clk_phi1 as a generated clock on that output port and data_enable constrained with set_output_delay to the same port. For devPort_o[1], you would have the 2 output clocks as generated clocks targeted to that output port (use -add for the second generated clock since it is targeted to the same port) and use set_clock_groups with the -exclusive option. You should false path that output since there is no data output on it.

 

#iwork4intel

0 Kudos
Reply