Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
665 Views

Timequest problem: 2 clocks of different period

Hello, 

 

I have never had a firm grasp of how Timequest works, so I decided to "make things right" in a simple project an appropriately constraint all my design. 

 

The module is a simple keyboard receptor. I have two clocks: 

- One of 50 MHz, which captures the signals that the receptor gives (key pressed, valid ...) 

- The other one is the keyboard clock, which I supposo has a period of 100 us. 

 

I have been following the user guide by Ryan Scoville, and I right now my SDC file is the following: 

 

create_clock -name CLOCK_50 -period 20 create_clock -name PS2_CLK -period 100000 derive_pll_clocks derive_clock_uncertainty set_input_delay -clock PS2_CLK -max 25000 set_input_delay -clock PS2_CLK -min 5000  

 

I am assuming a data-to-clock setup time of 25 us and a clock-to-data hold time of 5 us. 

 

With this SDC I get a violation of the setup time for CLOCK_50 of -24984.187 

 

To be honest, I am really frustrated. It is a very simple design. Is there anything wrong in my file?  

 

Thank you!
0 Kudos
3 Replies
Highlighted
Valued Contributor III
4 Views

Run "report_timing -setup -detail full_path..." on the failing path/domain. I find it really important to understanding timing, since it shows you exactly how a path is being analyzed. You might want to start with the Waveform tab, which gives the high-level details(clock edges, data path, clock path, etc.). It's much easier to visualize. The Data Path tab gives the same information but in much more detail, like what logic cells and interconnect delays make up the data path. 

Note that there are three things in the timing report from your .sdc, the launch edge time, the latch edge time(these come from the clocks you've created) which make the setup relationship, and the iExt delay, which comes directly from your -max 25000.  

What you're going to find is that your setup relationship(latch edge - launch edge) is small, I'm guessing 20ns, and your external delay is 25000ns, so your external delay chews up ALL of your margin plus another 25980ns.  

 

Why is this? If I were to take a guess, PS2_DAT drives a register clocked by CLOCK_50. So your set_input_delay constraints say there is an external register clocked by PS2_CLK driving into port PS2_DAT. So there is path from this external register clocked by PS2_CLK to an internal one clocked by CLOCK_50. The default setup relationship of this will be 20ns, yet the max external delay is 25000, so it's impossible to meet timing.  

If this is the case, you can: 

a) Change the code so that PS2_DAT doesn't drive a register in the CLOCK_50 domain. 

b) Cut timing on that specific path: 

set_falst_path -from [get_ports PS2_DAT] -to [get_keepers {name_of_the_reg_or_registers_in_CLOCK_50_domain*}] 

c) Cut timing between the two clocks: 

set_clock_groups -asynchronous  

-group {CLOCK_50}  

-group {PS2_CLK} 

d) You could also multicycle it, but I don't think that's appropriate, as I'm guessing these clocks don't have any relationship. Let me know how that goes.
0 Kudos
Highlighted
Valued Contributor III
4 Views

 

--- Quote Start ---  

Run "report_timing -setup -detail full_path..." on the failing path/domain. I find it really important to understanding timing, since it shows you exactly how a path is being analyzed. You might want to start with the Waveform tab, which gives the high-level details(clock edges, data path, clock path, etc.). It's much easier to visualize. The Data Path tab gives the same information but in much more detail, like what logic cells and interconnect delays make up the data path. 

Note that there are three things in the timing report from your .sdc, the launch edge time, the latch edge time(these come from the clocks you've created) which make the setup relationship, and the iExt delay, which comes directly from your -max 25000.  

What you're going to find is that your setup relationship(latch edge - launch edge) is small, I'm guessing 20ns, and your external delay is 25000ns, so your external delay chews up ALL of your margin plus another 25980ns.  

 

Why is this? If I were to take a guess, PS2_DAT drives a register clocked by CLOCK_50. So your set_input_delay constraints say there is an external register clocked by PS2_CLK driving into port PS2_DAT. So there is path from this external register clocked by PS2_CLK to an internal one clocked by CLOCK_50. The default setup relationship of this will be 20ns, yet the max external delay is 25000, so it's impossible to meet timing.  

If this is the case, you can: 

a) Change the code so that PS2_DAT doesn't drive a register in the CLOCK_50 domain. 

b) Cut timing on that specific path: 

set_falst_path -from [get_ports PS2_DAT] -to [get_keepers {name_of_the_reg_or_registers_in_CLOCK_50_domain*}] 

c) Cut timing between the two clocks: 

set_clock_groups -asynchronous  

-group {CLOCK_50}  

-group {PS2_CLK} 

d) You could also multicycle it, but I don't think that's appropriate, as I'm guessing these clocks don't have any relationship. Let me know how that goes. 

--- Quote End ---  

 

 

 

Guau, thank you very much. You nailed it! 

 

Yes, the relationship was 20 ns. And yes, PS2_DAT drives a register in the CLOCK_50 domain. The code of the pressed key is captured in the CLOCK_50 domain once it has been decode by the module in the PS2_DAT domain (there are really two modules, one for decoding the key pressed and another one which lights some led depending on which key has been pressed) 

 

I forgot to say that I tried to set up a multicycle of 2 (thinking that it would indicate that CLOCK_50 should capture in the second edge of PS2_CLK, although now that I write it I don't think that it makes much sense). 

 

I tried to cut the timing as you said between the clocks and indeed that was the solution! I really don't know why I didn't do it at first. Maybe it is not yet clear to me when I should separate two clock domains. 

 

Again, thank you very much for your answer, really. Now I see which was the problem and the solution to it.
0 Kudos
Highlighted
Valued Contributor III
4 Views

multicycle setup has a -start/-end option that defaults to -end if not specified. Imagine drawing the waveforms and then an arrow for your default setup relationship from the launch edge to your latch edge. A multicycle -end moves the end of that arrow out, so it increases your setup relationship by the latch clock period. A multicycle -setup -end of 2 would move it from 20ns to 40ns, and it would still fail big time. A multicycle -setup -start of 2 would move the start of the arrow back, increasing the setup relationship by 10000ns to 10020ns. That would have met timing(assuming you added the multicycle -hold -start of 1 with it).  

The way I tend to think of it is to ask if there is a hard limit in time that defines pass/fail. Is there some delay on the signal coming into PS2_DAT and feeding this register in CLOCK_50 domain, whereby if it were XXns it would work but if it were 100ps later, say XX.1ns, then it would fail. That's the way synchronous relationships work and what's being analyzed. 

(There's a subset of requests I see that is more ambiguous. Users sometimes say, I don't want to cut that path, because then it could be anything. What if the delay were 100ns? 1000ns? 100us? At some point it wouldn't work. Personally, I know that's not going to happen, but understand the argument. In those cases there isn't a black-and-white line of what works and what doesn't, but they don't want to cut it completely.)
0 Kudos