AdvancedQuestion 33 of 63Source: Synopsys PrimeTime User Guide: Specifying Internally Generated Clocks

How do you constrain a clock produced by a pulse generator that does not change frequency?

From PDVerse STA Mentor Guide · pdVerse Mentor Guide

Short Answer

A pulse generator that keeps the incoming clock's frequency but reshapes it into a narrow pulse can be described with the pulse_clock attribute instead of a full generated-clock definition, using one of four senses - rise_triggered_high_pulse, rise_triggered_low_pulse, fall_triggered_high_pulse, or fall_triggered_low_pulse - to say which master edge triggers which polarity of pulse. The actual pulse width is then set with set_clock_latency (SDC) rather than a waveform, because an ideal pulse-clock sense starts life with zero width by definition.

Technical Reference DiagramHow do you constrain a clock produced by a pulse generator that does not change frequency?
A shared 400MHz clock feeding roughly 3000 latch-based pulse generators, each output pin labeled with the pulse_clock attribute rise_triggered_high_pulse instead of an individual generated clock, and one shared set_clock_latency -rise 0.6 -fall 1.1 command giving all of them a 0.5ns ideal pulse width

Technical Explanation

  • A pulse generator that doesn't change frequency doesn't need a new generated clock object. Instead of create_generated_clock (SDC), you set the pulse_clock attribute on the pulse generator's output pin, naming one of the four supported senses.
  • The four senses describe which master edge starts the pulse and which polarity it produces. rise_triggered_high_pulse and rise_triggered_low_pulse both start from the master's rising edge; fall_triggered_high_pulse and fall_triggered_low_pulse both start from its falling edge - only the resulting pulse polarity differs within each pair.
  • This scales far better than generated clocks when a design has thousands of pulse generators. Specifying each one as a full generated clock with explicit edges works, but it does not scale - every one needs to be found and hand-specified, and the resulting proliferation of clock groups becomes hard to manage.
  • The ideal pulse width for any of these senses is zero, so real width comes from clock latency. set_clock_latency -rise 0.6 -fall 1.1 [get_pins PG/Z] (SDC) sets a high-pulse width of 0.5 (the difference between the rise and fall latency) for every register downstream of PG/Z.
  • A non-monotonic waveform needs create_clock -waveform (SDC) instead of the pulse-clock attribute. If the pulse generator's output has increasing edge values but is not a simple rising-then-falling shape, create_clock -waveform {0.0 0.0} -period 10 [get_ports BCK] (SDC) plus set_clock_latency -source builds the correct ideal clock for that case.
  • If two different senses of the same clock merge together at one point in the network, PrimeTime cannot resolve the ambiguity on its own. set_sense -type clock -pulse (SDC) at that specific point tells the tool explicitly which sense applies there.

Common Mistake

  • Writing a full create_generated_clock definition, with explicit edges, for every pulse generator in a design that has hundreds or thousands of them.
  • This works command by command, but the resulting proliferation of separate generated clocks and clock groups becomes unmanageable to review and maintain, compared to a handful of pulse_clock attribute settings that scale with the sense, not the instance count.
  • Cost: an SDC file that is technically correct but practically unreviewable, where a single wrong edge on one of hundreds of near-identical generated clock statements is nearly impossible to spot by inspection.

Follow-up Question & Model Response

If PrimeTime issues a warning that the requested pulse clock sense does not exist at a given pin, but a different sense at that same pin succeeds, what does that tell you about the circuit between the clock source and that pin?

Candidate Model Response: It tells me the fanout from the clock source to that pin only contains one kind of logical path - either purely positive-unate or purely negative-unate - and the sense that failed required a path polarity that simply isn't present there. If, instead, both a positive and a negative unate path reach that pin, PrimeTime can support a sense request for it by taking the rise latency from the positive-unate path and the fall latency from the negative-unate one. A pin failing on one sense but succeeding on the other is a sign the design only has a single, unambiguous path polarity feeding it, which is useful information when debugging why a pulse-clock sense request was rejected.

Practical Example

A design has roughly 3,000 latch-based pulse generators, each producing a short high pulse from the rising edge of a shared 400MHz clock, with no frequency change at any of them. Instead of writing 3,000 individual generated-clock statements, the SDC sets the pulse_clock attribute to rise_triggered_high_pulse on each generator's output pin and then a single shared set_clock_latency -rise 0.6 -fall 1.1 [get_pins PG/Z] (SDC) command, giving every one of them an identical 0.5ns ideal pulse width in one line instead of three thousand nearly-duplicate generated clock definitions.

Complete STA Handbook

Get the complete 10-chapter STA handbook covering setup/hold margins, clock modeling, OCV/POCV, crosstalk noise, and PrimeTime closure.

VLSI Physical Design Planning Handbook — fourteen chaptersDesign PlanningFourteen chapters, floorplanning through timing budgets. →