Forum Discussion
19 Replies
- Altera_Forum
Honored Contributor
Thanks for the tutorial!
Do you happen to still have the complete demo-design with the tested SDC file(s)? I am one of those who never had timing issues with their small/medium designs before, but now have... I am especially interested in properly constraining SDRAM/SRAM with Timequest - I followed your tutorial closely but for some reason my design fails all setup requirements for my SDRAM/SRAM input paths by a slack of about -5ns. This is @60MHz on a CycloneII quite much. Additionally there are setup violations for the ssram_clk_pin and sdram_clk_pin nodes - is this supposed to be not analyzed by a falsepath setting? Snippets from my SDC file (my SDRAM has the same characteristics as used in the tutorial):
TOP failing paths:# ************************************************************** # Create Clock # ************************************************************** # both clock inputs are from the same crystal # feeds PLL for system clock and SDRAM create_clock -name {INCLK0} -period 30.518 # feeds PLL for SSRAM create_clock -name {INCLK1} -period 30.518 # ************************************************************** # Create Generated Clock # ************************************************************** derive_pll_clocks create_generated_clock -name {sdram_clk_pin} -source {clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk} -offset 0.500 create_generated_clock -name {ssram_clk_pin} -source {clkgen1|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk} -offset 0.500 derive_pll_c # ************************************************************** # Set Input Delay # ************************************************************** set_input_delay -max -clock sdram_clk_pin 6.100 }] set_input_delay -min -clock sdram_clk_pin 2.900 }] . . # ************************************************************** # Set Output Delay # ************************************************************** set_output_delay -max -clock sdram_clk_pin 2.600 }] set_output_delay -min -clock sdram_clk_pin -0.400 }] . .
Thanks for any hints or answers - and yes, I probably shouldn't follow blindly tutorials, but actually read the QII handbook to get my constraints right...slack From Node To Node Launch Clock Latch Clock -5.750 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.750 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.739 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.739 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.732 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.732 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.730 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.730 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.730 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.725 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.725 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.722 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.722 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.720 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.714 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.714 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.712 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.709 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.706 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.706 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.705 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.705 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.702 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.702 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.702 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.702 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.702 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.701 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.701 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.701 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.690 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk -5.680 DRAM_DB sdctrl:\sdc:sdc|r.hrdata sdram_clk_pin clkgen0|\alt:v|sdclk_pll|\nosd:altpll0|pll|clk - Altera_Forum
Honored Contributor
If you are seeing setup violation and no hold violations on your SSRAM and/or SDRAM timing then it would suggest that the PLL used to offset the clocks to these devices is not set up correctly.
- Altera_Forum
Honored Contributor
Thanks for the hint!
I couldn't get back earlier, but now I should have tuned the PLL phaseshift correctly and I get no violations in the slow model. The fast model on the other hand has hold violations of about -2ns on all data (inout) lines and I seem to have no margin to get rid of this -2ns slack. All timing optimizations are already turned on. Well I better get started with the documentation... - Altera_Forum
Honored Contributor
The two related clocks (clk_a and clk_b) are created at page 4 of the document attached to the 1st post.
These clocks have periods of 10 and 20 ns respectively as shown at the picture. --- Quote Start --- These can be assigned with the following commands: create_clock –period 10 –waveform {0 5} [get_ports {clk_a}] create_clock –period 10 –waveform {3 13} [get_ports {clk_b}] --- Quote End --- Is it correct? - Altera_Forum
Honored Contributor
This is an amazing resource! Timing constraints is probably the least understood aspect of FPGA development... and the most likely to get you banging your head against a wall asking god why nothing's working. And this document is the best, most clear explanation that I've found. (Which is to say: Altera, why don't you have any good docs on TimeQuest ?!?!) I also love the sheer style and organization.
However, I'm pretty sure page 9 is all wrong. I.e., using datasheet timing data to constrain an external interface. First of all, it is the max output delay (ie input setup time) that is negative, not the min output delay (the hold time). Reason for this is simple. The max output delay should be a large number, just like the max input delay. However, "setup time" is usually quoted as time _to_ the clock edge (eg 2ns) not from it (eg 18ns). So you have to negate it. Hold time, meanwhile, is quote _from_ the clock edge just like other delays. The SDC should look like this: create_generated_clock -name sdram_clk_pin -source $sdram_clk -offset 0.5 [get_ports {sdram_clk}] set_input_delay -clock sdram_clk_pin -max [expr 5.5 + 0.6] <ports> set_input_delay -clock sdram_clk_pin -min [expr 2.5 + 0.4] <ports> set_output_delay -clock sdram_clk_pin -max [expr -2.0 - 0.6] <ports> set_output_delay -clock sdram_clk_pin -min [expr 1.0 - 0.4] <ports> - Altera_Forum
Honored Contributor
I've been thinking a bit more about this and realized the stuff about board delay is off too.
Quartus II already compensates for pcb delay! Both in the clock and in the signals. It uses either capacitive load or a board model to calculate pcb delay and include it along with logic and fabric delay when meeting timing. (Of course you have to fill in all the data correctly first.) However it does this half-assedly. Literally. It only does this on the output pins, not the input puts. If relying on Quartus's internal simulation and not using third-party SI tools, then the section of the SDC file should look like this. Note that neither the clock nor the output_delay is explicitly corrected while input_delay is corrected only for the trip back.
If you ARE using third-party SI tools, set capacitive load for each pin to zero (and disable all the resistors and capacitors in the board model) to turn off Quartus' corrections. Then plug your precise board delay figures (or your conservative estimates) into the following. Keep in mind what the meaning of "longest" and "shortest" is. It could be you're putting several different signals in one command. But even a single signal will take a different time on a low-to-high transition than a high-to-low (not counting general randomness). Also remember that a signal hasn't transitioned until the voltage reaches the appropriate threshold. If you're jerry-rigging 3.3v TTL to 5v TTL, for example, then you have to keep this in mind when using your SI tools.create_generated_clock -name sdram_clk_at_the_sdram -source $sdram_clk set_output_delay -clock sdram_clk_at_the_sdram -max <ports> set_output_delay -clock sdram_clk_at_the_sdram -min <ports> set_input_delay -clock sdram_clk_at_the_sdram -max <ports> set_input_delay -clock sdram_clk_at_the_sdram -min <ports>
Note that you still have to create_generated_clock. Even with the pcb delay compensations turned off, it still calculates the fabric delay of the clock getting to that pin. If you use "zero delay buffer" and a dedicated PLL out then you can probably do without it. But I'm not sure you even need a zero delay buffer if you build your SDC file like this.create_generated_clock -name sdram_clk_at_the_fpga_pin -source $sdram_clk set_output_delay -clock sdram_clk_at_the_fpga_pin -max <ports># sometimes the signal lags behind the clock. the max is lowered. set_output_delay -clock sdram_clk_at_the_fpga_pin -min <ports># sometimes it speeds ahead. the min is raised. set_input_delay -clock sdram_clk_at_the_fpga_pin - max <ports> set_input_delay -clock sdram_clk_at_the_fpga_pin -min <ports> - Altera_Forum
Honored Contributor
Oh, and the .doc should explain what exactly pcb delay is. It's not just the time that electricity takes to go through a wire, like a wave spreading down a canal. It's the time to actually send enough electrons into all the capacitors that are connected to that wire. If you load up a lot of components onto the same tristate bridge or if you turn the driving current way down, you will have a big pcb delay. That's what the "pin capacitive load" means.
But modeling the load as just one big capacitor isn't too accurate (well, it's still a hell lot better than nothing!). Use Advanced I/O Timing to simulate terminations if you're at all using them. Yet for all its additions Advanced I/O still assumes that the far-end load is just a capacitor. If you read DDR2 datasheets, for example, they'll often not tell you the capacitive load at all and instead print a warning that it's not so simple and that you should go use an IBIS file (which essentially replaces a single number with a graph). Third-party SI tools aren't that hard to use. HyperLynx in particular has a very easy interface. But if you're not tight in your timing budget, don't get anal about things. Just insert safe guesstimates. If you don't even want to specify an Advanced I/O Timing model or dig through datasheets, you don't really have to. You don't need to spend the time to do that, but you DO have to follow template# 2 and insert appropriate guesstimates. - Altera_Forum
Honored Contributor
Oh, one more thing. Template# 2 assumes that the target is pipelined. Ie, you give it a command on one clock cycle, you get the response on the next. If the target works more like a combinational circuit, use this:
set_input_delay -clock sdram_clk_at_the_fpga_pin - max <ports> set_input_delay -clock sdram_clk_at_the_fpga_pin -min <ports> - Altera_Forum
Honored Contributor
--- Quote Start --- The two related clocks (clk_a and clk_b) are created at page 4 of the document attached to the 1st post. These clocks have periods of 10 and 20 ns respectively as shown at the picture. Is it correct? --- Quote End --- The waveforms show 10 ns and 20 ns period but the example SDC commands do not reflect this. The correct SDC commands are: create_clock –period 10 –waveform {0 5} [get_ports {clk_a}] create_clock –period 20 –waveform {3 13} [get_ports {clk_b}] - Altera_Forum
Honored Contributor
--- Quote Start --- This is an amazing resource! Timing constraints is probably the least understood aspect of FPGA development... and the most likely to get you banging your head against a wall asking god why nothing's working. And this document is the best, most clear explanation that I've found. (Which is to say: Altera, why don't you have any good docs on TimeQuest ?!?!) I also love the sheer style and organization. However, I'm pretty sure page 9 is all wrong. I.e., using datasheet timing data to constrain an external interface. First of all, it is the max output delay (ie input setup time) that is negative, not the min output delay (the hold time). Reason for this is simple. The max output delay should be a large number, just like the max input delay. However, "setup time" is usually quoted as time _to_ the clock edge (eg 2ns) not from it (eg 18ns). So you have to negate it. Hold time, meanwhile, is quote _from_ the clock edge just like other delays. The SDC should look like this: create_generated_clock -name sdram_clk_pin -source $sdram_clk -offset 0.5 [get_ports {sdram_clk}] set_input_delay -clock sdram_clk_pin -max [expr 5.5 + 0.6] <ports> set_input_delay -clock sdram_clk_pin -min [expr 2.5 + 0.4] <ports> set_output_delay -clock sdram_clk_pin -max [expr -2.0 - 0.6] <ports> set_output_delay -clock sdram_clk_pin -min [expr 1.0 - 0.4] <ports> --- Quote End --- I have done some experimentation and believe that it IS the minimum output delay that should be negated. This is something I was told when I first start using TimeQuest. I am not sure why but I have given up trying to understand this long ago and now I just accept it. For my experiment I implemented a D type FF in Quartus and ran TimeQuest with the following commands: create_clock -period 20 [get_ports {clk}] set_output_delay -clock clk -min -1.0 [get_ports {q}] You can see from the diagram attached that the effect of the output delay is to push the data required time out to the right which equates to a hold time of a device whose input is conected to the output of my FPGA. There is a typo in the doc though as the example: set_output_delay -clock sdram_clk_pin -min [expr 1 – (1.0 + 0.4)] <ports> should read set_output_delay -clock sdram_clk_pin -min [expr 0 – (1.0 + 0.4)] <ports>