SDC timing exception cmd
- Details
- Last Updated: Thursday, 19 December 2024 20:02
- Published: Wednesday, 14 October 2020 21:49
- Hits: 1398
Timing Exceptions: These are cmds that adjust the required time of path or disable/enable paths for timing. So, these paths are not analyzed for timing or are analyzed with new modified timing if the cmd specifies so. These cmds are used in synthesis flow also (they are part of SDC cmds) to force synthesis tool to optimize for new timing specified via these cmds. These cmds can be of 2 types.
A. point to point timing exceptions cmds: (from node A to node B in timing path). 5 of them. All have options as below:
- -setup/-hold => cmd applies to setup or hold timing path only. By default, these cmds apply to both both setup and hold timing for specified paths.
- -from/-rise_from/-fall_from => specifies list of timing path startpoint objects (clock, PI, Seq_cell, clk pin of seq cell, data pin of level sensitive latch, or pin that has i/p delay specified). _rise/_fall specify that path must rise or fall from object specified (if clk is specified, then rise/fall refers to only the paths launched by rising/falling edge of the clock at the clock source, not at flop. if flop is specified, then rise/fall refers to startpoint/endpoint of flop). If clk is specified as starpoint, all registers and primary inputs related to that clock are used as path startpoints. If a cell is specified, one path startpoint on that cell is affected. Only one of 3 options can be used.
- -to/-rise_to/-fall_to => specifies list of timing path endpoint objects (clock, PO, Seq_cell, data pin of seq cell, or pin that has o/p delay specified). _rise/_fall specify that path must rise or fall to object specified (if clk is specified, then rise/fall meaning same as shown in above option). If clk is specified as endpoint, all registers and primary outputs related to that clock are used as path endpoints. If a cell is specified, one path endpoint on that cell is affected. Only one of 3 options can be used.
- -through/-rise_through/-fall_through => Specifies a list of pins, ports, cells, and nets through which the paths must pass. rise/fall applies to path with rise or fall at specified objects.
- -rise/-fall => applies timing exception only to paths having a rising or falling signal at timing endpoint. This looks similar to -rise_to/-fall_to ?? (except that you do not specify endpoint explicitly). NOT to be used, as it's confusing (may befor le gacy purpose)
- -comment <string> => specifies comment for our understanding. This -comment section may be used by your custom scripts to apply custom things to these cmds (i.e some keywords in -comment section may be used to indicate that this exception is only to be applied when running at particular PVT, your internal script can then handle such cases efficiently)
NOTE:
- All startpoint or endpoint in -from/-to have to be pins (of leaf cells) or ports of design (with the exception that clocks and sequential cells may be specified). They can't be nets or pins of sub modules. -through is where we can specify nets.
- We can specify pins or ports directly in start/end points (i.e -from top_a/b_reg/Din). Although it's good practise to enclose that as get_pins, get_cells, get_nets etc (i.e -from [get_pins top_a/b_reg/Din]).
- Patterns may be used is startpoint/endpoint object names to specify multiple paths in same exception cmd. However, PT issues a warning a saying that wildcards are being used in these cmds. It's strongly discouraged to use patterns in start/end points, as timing tool won't tell us to which all places these timing exception got applied. It will apply to all eligible points based on a pattern matching, and it may get applied wrongly to points you never intended to. You will never know about it, until the path shows up in silicon, and then you report timing on that path only to find out that the path has timing exception on it. If you do have to apply wildcard pattern, create a for loop and go thru each element of the for loop. Within the loop, apply each of the expanded element to timing exception cmd explicitly.
1. set_false_path: sets false path on the timing path specified. This timing path is not checked for timing at all. Both pins/cells may be used in from/to list. Most used cmd in soecifying exceptions. Read detailed syntax in PT manual.
set_false_path -from [list [get_cells Ireg/trim_reg_0] ... [get_pinss Ireg/trim_reg_2/CLK]] -to [list [get_cells Ispi/sreg_reg_1] ... [get_pins Ispi/U49/A]]
see "reset_path" cmd for resetting this exception.
2. set_multicycle_path: sets multi cycle path.on the timing path specified. This timing path is still checked for timing, but the default behaviour is altered. By default, PT/DC exhibit single-cycle behavior for any path. This means that when data is launched at a particular clock-edge, the tool performs a setup check at the very next clock-edge. There are 2 Hold checks that are performed for each setup check as discussed in "setup/hold" section. For simplest designs based on single freq clocks, where the flops are fired every cycle, setup check is performed on next edge (one clock cycle apart), while hold check is performed on the same edge (zero clock cycle apart). MCP changes this default behaviour. We can specify any number of cycles for setup and any number of cycles for hold, and the tool will now honor these new cycle requirements (the old requirements are removed)
To change default behaviour, we can do it in 2 ways via MCP:
- move the capture edge (or end-point clock) to the right (moving clk edge backward or allowing more time), or to the left (moving clk edge forward or allowing less time)
- move the launch edge (or start-point clock) to the left (moving clk edge forward or allowing less time), or to the right (moving clk edge backward or allowing more time)
By default, when we move edges by applying MCP, capture edge is moved to the right (backward) for setup and to the left (forward) for hold. Launch edge is left untouched. We can change this behaviour by using -start/-end option. We'll discuss that later below. First we talk about "multipler" which we specify to get multicycle behaviour.
Multiplier: Multiplier is a little confusing term to get thru. Multiplier specifies the number of cycles the data path must have for setup or hold, relative to the startpoint or endpoint clock, before data is required at the endpoint. Assume a single freq clk at both launch and capture. Then startpoint and endpoint clocks have same clk freq. Here "setup of n cycles of MCP" implies "n cycles" b/w launch and capture. But for hold, "hold of n cycles of MCP" doesn't imply "n cycles" b/w launch and capture. By default, hold check is always automatically moved to 1 cycle before setup. So, "setup of n cycles" changes hold to "n-1" cycles. This is the default hold behaviour, and we specify it by saying "hold of 0 cycles of MCP", which means hold has to meet a timing requirement of "n-1" cycles. This is a very difficult hold requirement to meet as data has to be held constant for "n-1" cycles, i.e data can change only between (n-1) cycles to n cycles, sp path will need to be buffered up (min delay is > (n-1) cycles, max delay < n cycles). If we want to relax hold timing, then we need to move hold capture edge inwards (to the left) to get it closer to capture edge. If we move the hold requirement to be for "n-2" cycles, then we specify it as "hold of 1 cycle of MCP". So, you can see as to why timing tools by default have "hold of n-1 cycles" => It's most pessimistic hold requirement to meet, so risk is lowest.
setup/hold: These extra 2 options of -setup or -hold implies if MCP is for setup paths or hold paths. If no setup/hold specified, then Multiplier is for setup (hold is assigned a multiplier of 0). If only setup multiplier is specified, hold is automatically moved to 1 cycle before setup (for both the hold checks). If we want to change this hold behaviour, then we should specify multiplier for hold also. Specifying multiplier for setup only (no hold multiplier), changes both setup and hold behaviour. But specifying multiplier for hold changes hold behaviour only, and doesn't affect setup behaviour. Using -hold with MCP is more confusing, and set_min_delay cmd (see next section) may be preferred to set hold requirement.
- set_multicycle_path 4 -from ... -to ... => Here no setup/hold specified. So, this multiplier is for setup (as no -setup or -hold specified). Setup check is now 4 cycles instead of 1 cycle. Hold multiplier is kept at default value of 0, so hold check is 3 cycle, instead of 0 cycle (i.e same as adding this MCP: set_multicycle_path -hold 0 -from ... -to ...)
- set_multicycle_path -setup 4 ... => Here -setup option used, so setup check is same as above (as setup check is assumed by default). There is no difference b/w this and the above MCP (assuming we don't specify any other MCP with -hold for this path)
- set_multicycle_path -setup 4 ...; set_multicycle_path -hold 0 ...; => This is again same behaviour as above, as we kept default value of hold to 0. So, setup check=4 cycles, hold check = 3 cycles. This is most stringent hold requirement as data can't change before 3 cycles, and can't change after 4 cycles, so effectively only 1 cycle (the 4th cycle) available for data to change. A lot of buffers will be added on the data path, so that there is enough delay to met these requirements.
- set_multicycle_path -setup 4 ...; set_multicycle_path -hold 1 ...; => Here setup behaviour is same as above, but hold check is moved in by 1 cycle compared to it's default of 0 cycle. So, setup check=4 cycles, hold check = 2 cycles.
- set_multicycle_path -setup 4 ...; set_multicycle_path -hold 2 ...; => Here setup behaviour is same as above, but hold check is moved in by 2 cycles compared to it's default of 0 cycle. So, setup check=4 cycles, hold check = 1 cycle.
- set_multicycle_path -setup 4 ...; set_multicycle_path -hold 3 ...; => Here setup behaviour is same as above, but hold check is moved in by 3 cycles compared to it's default of 0 cycle. So, setup check=4 cycles, hold check = 0 cycles. So, hold check is now on same clock edge, as what we used to have in simple designs with flops firing on every clk cycle. This is most relaxed hold requirement as data can't change before 0 cycles, and can't change after 4 cycles, so effectively 4 cycles available for data to change. This is most likely what we want in design, as MCP implies existence of clk gating or something similar that prevents other clk from firing during that time, so there's no risk of capturing newer data on subsequent capture clk edges, before the correct capture clk edge arrives.
In report_timing cmd, when we report_timing for MCP using "report_timing -from <> -to <> -exceptions all", we'll see it report setup cycles and hold cycles as whatever was specified in the MCP cmd. So, if MCP has "-setup 5 -hold 2", then report_timing will report "5 setup cycles and 2 hold cycles".
start/end: Other extra 2 options for MCP are -start/-end.
If you note above, we specified the multiplier but we never said which clock does that multiplier apply on - is it the start clk or the end clk? Generally for single clk designs, both start clk and end clk have same freq and we don't need that. But if launch clk and capture clk are at diff freq (i.e paths crossing clk domains for multi freq design or divided versions of sync clks) and have paths which are valid (usually paths crossing clk domains are marked as invalid, but paths b/w divided clks are still valid), then we need to specify the freq of the clk too. Usually for regular timing runs, we see that Capture clk is relevant for setup, and launch clk for hold. Well, PT follows the same principle for MCP and has default assignment for the multiplier => it uses the multiplier wrt end clock (capture clk) for setup, and wrt start clock (launch clk) for hold. To change this default behavior, we can specify -start for setup, and -end for hold. By specifying this option, we control 2 things:
- Launch/Capture edge: By using -start for setup, we move the start (launch) edge forward/backward. By using -end for hold, we move the end (capture) edge forward/backward. I don't know if this is true, as timing runs on PT_SHELL show capture clk as always moving left/right. I need to run more experiments to find that.
- Launch/Capture freq: By using -start, we specify that multiplier should use freq of start (launch) clk. By using -end, we specify that multiplier should use freq of end (capture) clk.
4 cases possible:
- A setup multiplier of 2 with -start moves the relation backward one cycle of the start clock. i.e start clk moves 1 cycle to left.
- A hold multiplier of 1 with -start moves the relation forward one cycle of the start clock. i.e start clk moves 1 cycle to right. Here we are reducing hold check by 1 cycle, i.e making it less stringent.
- A setup multiplier of 2 with -end moves the relation forward one cycle of the end clock. i.e end clk moves 1 cycle to right. This is what happens by default for setup checks when MCP is applied => capture edge gets moved.
- A hold multiplier of 1 with -end moves the relation backward one cycle of the end clock.
Very good explanation on solvent: https://solvnetplus.synopsys.com/s/article/Setup-and-Hold-Checks-Between-Fast-and-Slow-Clock-Domains-1576007257628
Ex:
set_multicycle_path -setup 2 -fall_from [get_clock auto_sden_scanclk] -rise_to [get_clock SCLK] => implies setup check is now 2 cycles instead of 1 cycle. Here capture edge is moved to right by 1 cycle. In order to move launch edge to the left, we have to use -start (use -end to move capture edge to right, which is default anyway). By moving setup check, hold check also got moved by 1 cycle (i.e instead of checking hold time in same cycle, tool checks it against next cycle). If we want to change this behaviour and keep the original behaviour of hold, we need to move hold by 1 cycle (MCP -hold 1 ...).
set_multicycle_path -hold 1 -to u2/D -end => implies hold is moved in by 1 cycle inwards to the left, so it's back to how it was before we set multicycle for setup. (if we had -setup 5, then we needed to have -hold 4 to get default behaviour back for hold). here hold capture edge is moved to left (use -start to move launch edge to right which is default anyway)
set_multicycle_path 18 -hold -from clock_in -to ModeSelects -start => -start/-end Specifies whether the multicycle information is relative to the period of the start clock or the end clock. These options are only needed for multifrequency designs; otherwise start and end are equivalent. The start clock is the clock source related to the register or primary input at the path startpoint. The end clock is the clock source related to the register or primary output at the path endpoint. The default is to move the setup check relative to the end clock, and the hold check relative to the start clock. A setup multiplier of 2 with -end moves the relation forward one cycle of the end clock. A setup multiplier of 2 with -start moves the relation backward one cycle of the start clock.
NOTE: FP takes precedence over MCP (since for timing exceptions, FP paths imply path is not to be considered for timing). Also, specific SMD cmd (in bullet 3 below) overides a general MCP cmd .
see "reset_path" cmd for resetting this exception.
3. set_max_delay/set_min_delay (SMD) => Specifies the desired maximum(setup)/minimum(hold) delay for paths in the current design. It is timing exception command; i.e.it overrides the default single-cycle timing relationship (derived from clk waveform and i/o delays) for one or more timing paths. set_max_delay has the side effect of breaking the timing graph at the 2 endpoints of the constraint (similar to set_disable_timing constraint). So, be very careful when using this cmd, as the only constraint that remains on the path specified via this cmd is the delay check for the endpoints specified. All other checks that were there on this path are deleted, i.e there's no setup/hold arc anymore. SMD work only on valid paths. If the path is invalid, then SMD will just be ignored. This solvnet article on synopsys website states that SMD cmds don't work for False paths (or paths b/w clocks defined as async clks). Link: https://solvnetplus.synopsys.com/s/article/Constraining-Paths-Between-Asynchronous-Clock-Domains-1576092601595
Sometimes, SMD cmd is useful compared to setting muticycle path cmd. We don't usually use SMD cmds in synthesis flow, as they are mostly used for controlling delays. Sometimes, designers do use them in synthesis flow to balance skew between multiple signals (achieved via using min delay of 1ns and max delay of 1.2ns for all bits of a bus to keep all bits within 0.2ns of each other). SMD cmds are most useful when running a hier design, where lower level blocks are placed/routed separately and then integrated in chip level. There if we have feed through path thru the lower level partition, then we would want to constrain the feed thru path within a certain range at block level, so that the path can meet timing at full chip level. Then block level synthesis and PnR will try to meet that delay requirement. Now when we run full chip level STA, with that block level partition as a black box, then we'll be able to meet timing at top level w/o touching the block level placement or route. One other place where MSD are used are in constraining the delay from pad of the chip to some internal capture node, when we don't want the different bits of a bus to skew too much.
NOTE: SMD should never be used in regular STA flow in functional mode. Since SMD only work on synchronous paths (i.e valid paths), they remove setup/hold time requirement of original valid path, and replace it with these SMD requirements. This will result in tool not even checking for setup/hold requirement of the original synchronous path, thus causing silicon failure. If we do have to use SMD, we should create a separate mode just for SMD purpose, put all SMD that we want to honor, and let tool optimize the path for SMD. Then when we merge modes (Functional mode and this other mode) during PnR, then both requirements will be tried to be met (i.e setup/hold requirement of Func mode and SMD requirement from this other mode). set_data_check cmd (explained below) should always be used instead of SMD, as set_data_check can do everything that SMD cmd does, without breaking the original timing graph. set_data_check is very well suited for bounding skew of different bits of a bus within a certain limit. set_data_check also works on async paths, so no reason to use SMD at all.
SMD cmds should be used in pair, i.e both set_max_delay and set_min_delay should be used on a given path, so that we meet pseudo setup as well as pseudo hold requirement for this segment of path.
NOTE: SMD cmds are different than set_input_delay and set_output_delay soecified in SDC and used in synthesis flow. Look in SDC section for details on those.
options:
- -from/-to/-through (and all other variations as-rise_from, -fall, etc) => Synopsys manual states that -from/-to need to be valid start/end points (i.e flop CP or D pin, clocks, etc). However, when we specify invalid start/end points, then it causes timing path segmentation, and PT issues UITE-217 warning. One of -from or -to is needed. -through is needed to force the cmd thru certain cells, etc.
- -ignore_clock_latency => When path startpoint or endpoint is on a seq cell, max_delay cmd includes clk skew in computed delay. This option allows us to ignore the launch/capture clk latencies and treat the paths as clockless. When reporting paths (report_timing) by clocks which have been ignored this cmd will result in unconstrained paths.
- <delay> => This is a number provided in same units as that specified in library. input/output external delay are included in path delay if path start/emd points are ports. Also, unless clk skew is ignore with cmd above, launch/capture clks are included if start/end point are on seq device. Also, c2q of launch flop and setup time of capture flop are included in delay for start/end points on seq cells.
report_timing on SMD paths: When doing "report_timing" on these paths, we have to use -from/-to to be the points that we used as -from/-to in the SMD cmd. This is because the original path is gone, and the only path that remains now is the path from the starting point in "-from" of SMD to the endpoint in "-to" of SMD. When seq points are included in SMD (or valid start/end points), then report_timing should have -from as clk pin of launch flop and -to should be data pin of capture flop (or valid start/end points).
ex: set_min_delay 0.5 -from ff1/CP -to ff2/D => sets hold delay to 0.5 units from CP->D. Here the original 0 cycle hold timing path that existed b/w CP->D is broken, and replaced by this min delay. We should also use a set_max_delay to constrain the max delay of this path too, else we miss the pseudo setup time requirement.
ex: set_max_delay 1.5 -from [get_clocks clk_A] -to [get_clocks clk_B] => This sets a max delay of 1.5 units for all paths from startpoint=clk_A to endpoint=clk_B. But if clk_A and clk_B are async, then this cmd doesn't work. In such cases, we should use some switch that still allows timing analysis on those paths. For set_clock_groups -asynchronous -group {clk_A} -group {clk_B}" cmd, where two clocks are defined asynchronous, we may use "-allow_paths" switch. The switch enables the timing analysis between the paths and preserves SI analysis using an infinite arrival window. So, SMD will work now on such paths.
USAGE SCENARIO: We need SMD like the one shown in example above where we use "-allow_paths" when we want to constraint the delay b/w these 2 clocks (for ex, may be for data bus of a load ctrl synchronizer where we want to keep data bus delay to less than 2 clock period of capture clock. This may be needed if we have a 2 sync flop synchronizer on ctrl bus). There is no other way to constrain the delay for the data bus. We can always use "set_data_check" instead of SMD.
see "reset_path" cmd for resetting this exception.
4. set_data_check (SDC) => usual checks are data or set/reset wrt clock. However sometimes, we need 1 data signal to be stable before other data signal. A good example of this would be some sort of gater (similar to nand/nor clock gater) where one signal is Data and other signal is En. We might want En to be stable while Data is changing. This will require a data check. Data check should only be applied to data signals, and never to clk signals (i.e for checking skew b/w diff clock, this check not allowed). The data check is treated as non-sequential; that is, the path goes through the related and constrained pins and is not broken at these pins (seq arcs break the data path). So, original timing graphs remain intact. So, this cmd is always preferred over SMD as we don't risk removing valid paths. By using SDC, we are only adding more constraints on top of what was already there. SDC has same precedence as regular reg2reg timing, so it will be overridden or masked by other constraints or exceptions like set_false_path/set_multicycle_path/set_max_delay, etc.
options:
- -from/-rise_from/-fall_from, -to/-rise_to/-fall_to,etc: behaves same way as other exception cmds
- -from is always CLK(related pin, startpoint), while -to is always DATA (constrained pin, endpoint) for any path. This is the same convention as an arc for En pin wrt CLK pin in a clk gater, where En is constrained pin, and CLK is related pin. We write arc as "-from CLK -to En". Or in a flop, the setup/hold arc is always written as "-from CLK -to D". In summary, SDC creates a non-sequential setup/hold check from the related pin to the constrained pin
- -setup/-hold => If no -setup/hold specified, then that value is for both setup and hold. If we specify -setup, then setup check done. If we specify -hold, then hold check done. If don't specify -hold option in other cmd statement for the same path for which we defined for -setup, then only setup check is done.
- -clock => In general. paths to constrained and related pins may come from multiple clocks. Multiple clks at startpoints may be due to 2 reasons => either each of these startpoints have single flop but multiple clks reaching them, or they have multiple flops as startpoints with single clk on each of the startpoint. -clock option is used in both cases (though PT manual says it's only for latter case) and it specifies clks for related pins only (NOT for clks on constrained pins). As such, there's no way to specify clks for constrained pins as sdc cmd line options don't support it (In short, all the clks reaching constrained pins will be checked with SDC constraints applied). If there are multiple clocks on related pin and if we don't force particular clock using this option, then sdc constraints are set with all possible clocks, and put in their respective clock groups (Remember that clk grps are always based on destination clk, and in data to data check, related pin is the destination clk). This is the default behaviour (when not using -clock). Usually, we don't need to use -clock option, as there's only 1 clk, or even if there are multiple clks, we want to have sdc cmd apply for all clks. This option is useful only if we want to exclude certain clks for SDC cmd.
- A side effect of this is that we may have unintended SDC cmds applied to paths we never intended. Imagine 2 flops (flop A1 and flop B) driving the constrained pin each having a different clk (clk_A and clk_B). Now we have 3rd flop (flop_A2) which is also driven by clk_A and driving the related pin. Now we set SDC cmd as => set_data_check -clock clk_A -from flop_A2/D -to flop_A1/D -setup 2 => Here we have wanted to set SDC on the real data/ctrl path, but SDC will get set on the constrained pin starting from flop_B too, as there's nothing in the SDC cmd to prevent this from happening. Whether the SDC will get set or get overwritten with some other constraints as clk_grp, FP, etc is dependent on other constraints.
set_data_check -from Data -to En -setup 2 => En must arrive 2ns before Data. If no -setup/hold specified, then that value is for both setup and hold. If we don't specify -hold option below, then only setup check is done. options -from/-from_rise/-from_fall, similarly -to/-to_rise/-to_fall.
set_data_check -from Data -to En -hold 10 => En must be stable for 10ns after Data
In examples above, -from (Data) is the related pin, and -to (En) is the constrained pin. So, Data acts as CLK in our example.
report_timing => When running report_timing to check these SDC paths, we have to use "rt -to <constrained_pin>". This will report normal R2R path as well as the SDC path depending on which one is the worst violater. We don't use "-from <related_pin>" as that is not a valid start point (even though we use -from <related_pin> in the SDC cmd). Valid startpoint is the start flop that fires the constrained pin. This is similar to how we report-timing for reg2reg paths. Since rt will show both R2R and SDC paths, we should consider putting all sdc paths into a separate clock_group, so that's easy to filter and see only the SDC path by specifying the clk grp. The way to know if path being reported is one with sdc or not, is to look at the bottom of the report for "data check setup/hold time".
Normal flop-to-flop paths in the design are inferred with a multicycle multiplier of 1. This means that setup captures a cycle later than launch, and that hold captures on the same cycle as launch. However, data to data check is inferred with a multicycle multiplier of 0, which pulls the capture one cycle to the left for both setup and hold checking. So, setup checks happen on same cycle, while hold checks happen 1 cycle earlier. The reason why we do this is simple to understand. Both related and constrained signals are fired in same cycle. We can think of related signal as clk going into a flop, which is being used to capture constrained signal which is data. It's all happening in same cycle, so setup check has to be in same cycle. Hold is always 1 cycle earlier than setup so that new value doesn't get captured in earlier cycle (but only in this cycle). The primary usage model of set_data_check was meant to be as setup checks applied to the design. Hold checks existed for symmetry reasons, but the resulting zero-cycle hold check behavior is much less intuitive than the zero-cycle setup check behavior. Most of the times, hold check isn't really meaningful, so we specify data to data check with -setup option only (which does the check for setup only, no hold check).
A very good link explaining this: https://vlsiuniverse.blogspot.com/2013/07/data-to-data-checks-constraining.html
Data to data checks can be specified using "set_data_check" in PT, or can be put in .lib files as "non-seq setup/hold check" for that cell. Advantage of putting it in .lib is that we can specify diff values for setup/hold based on transition of i/p signals. However, for data to data checks that are needed for pins which are not in same lib cell, we can't put such arcs in .lib, so we'll need to put it in PT script as "set_data_check".
A very good solvnet article on synopsys website is here (you can only access it if you have an account with synopsys):
Most of the times, set_data_check are used for constraining skew requirements on different signals (i.e we may want different bits of a bus to be within few ps of each other, in such cases, set_data_check with -ve values allow us to specify such requirement. More in diagram below. We could have used set_max_delay for skew check too,but set_data_check is preferred for skew check amongst bits of a bus, since it doesn't break the timing graph.
FIXME: Attach hand made diagram
5. set_path_margin => specifies margin to adjust for data required time. +ve margin means tighter check, while -ve margin means relaxed check. This helps to see paths which we are historically very tight in silicon, but always shows +ve slack on PT runs. For such paths, we can add extra margin of let's say 50ps, so that they will show up in reports as failing even if they have slack of up to 50ps. It's a point-to-point exception cmd, so it adjusts the time of individual paths, and has same options as other exception cmds (i.e -to, -thr, -from, -setup, -hold etc). By default, margin applies to both setup and hold. We need to apply this cmd in Synthesis/PnR tool too, so that they can tighten the path. PT is just for checking, and can't fix the path.
IMP: Most of the times, we only need to tighten/relax setup paths, and NOT hold paths. So use -setup with this cmd. Hold paths are usually 0 cycle paths, and relaxing hold paths is dangerous. Tightening hold paths is still ok, but you should try to get to the root cause of why hold tightening is needed on these paths. Maybe our models etc are not in line with silicon. A very small hold tightening is OK.
ex: set_path_margin 10 -to [get_clocks CLK] => all paths to endpoints clocked by CLK must be tightened by 10 units (applies to both setup and hold paths). When we do "report_timing", we'll a extra line for "path margin" at the very end, which will reduce the data required time by 10 units (i.e subtract 10), similar to how we reduce "clock uncertainty" from required time.
This cmd may be used to tighten hold paths by a certain fixed number. "-hold 10 -to [all_clocks]" will add 10ps hold time to all paths in design. We also use "set_clock_uncertainty" cmd to add extra hold margin to all paths. "set_annotated_*" cmds are also used to annotate delays on to nets, cells, etc, which may be used to add extra margin on paths (see in annotated cmds section).
ex: set_path_margin -5 -from u_top/ff_1 -to ff_2 => This relaxes path by 5 units from ff_1 to ff_2.
6. reset_path => this resets the specified path to it's default single cycle behaviour of 1 cycle setup and 0 cycle hold, i.e this command undoes the effect of the set_multicycle_path, set_false_path, set_max_delay and set_min_delay commands. It has same options as timing exception cmds as -from, -to, -thr, -setup, -hold, -rise, -from, etc. By default, both setup and hold are reset for the given path. This cmd is useful in cases where we are debugging a path, and want to try few different FP for the path. In such a case, we can try 1 FP, then do reset_path -option <path>, do report_timing to make sure we see original timing again, then try another FP and so on.
NOTE: reset_path has to be applied the same way as original MCP/FP, etc. i.e if MCP is put as "-rise_to clk1", then reset_path also needs to be "-rise_to clk1". We can't do something like "-to clk1" or "-to flop1", even though flop1 is one of the paths on that clk that was MCPed. PT won't complain (it'll return status code as 1), but it just won't reset the paths.
ex: reset_path -from clk1 => resets all paths launched by clk1 to single cycle (there has to be some MCP/FP used earlier with option "-from clk1" for this reset to take effect).
ex: reset_path -from { ff1/CP } -to { ff2/D } => resets path from ff1 to ff2 to single cycle
B. timing enable/disable cmds: Other exception that disables timing arcs within cells (i.e CLK->Q path for a flop may be disabled).
1. set_disable_timing: this Disables timing thru list of cells, ports, pins, or timing_arcs if specified. Compile applies min sizing on them, since no timing constraints here.
options: Only options are -from/-to which must be pins on the specified cells (disables all arcs b/w these 2 pins on the cell). If no -from/to specifed, then all arcs on specified cells are disabled for timing. Names of objects must be instance names, and not design names. If we specify lib cell name, then arcs are disabled for that cell, implying all instaces of that cell will have their timing arc disabled.
set_disable_timing [get_cells Idigital_mux/U179] => disables all timing thru this mux
report_disable_timing -nosplit => By default, this reports all disabled timing arcs in design. Since this would be long list, we can provide a collection or list of cells/ports. set_disable_timing is not the only way to disable timing arcs. This report_* cmd shows the reason for the disabled timing arc by showing a flag column with a 1 letter code. It's important to check for that flag when analyzing why certain arc is disabled. Below are the various flags shown:
- flag=c: case analysis: propagation of set_case_analysis cause arcs to be disabled.
- flag=C: presence of conditional arc in library (i.e stmt "when (A&B):" etc defined in library)
- flag=f: disabled due to false net arcs (i.e due to set_false_path??)
- flag=l or L: PT does loop breaking automatically where it finds loops in design, so such arcs get disabled
- flag=m: This disabling of arc happens due to the current mode of design being different than the modes specified in lib files for those timing arcs (FIXME ??)
- flag=p: propagation of constant values disables the arcs here
- flag=u or U: This disabling is due to set_disable_timing. "u" implies arcs disabled due to set_disable_timing on cell instance arcs, while "U" implies arcs disabled due to set_disable_timing on lib cell arcs,
ex: report_disable_timing [get_cells { o_reg4 }] => this reports all disabled timing arcs for cell inst "o_reg4", with a flag and a reason for that flag.
2. set_max_time_borrow:
C. Forcing pins to constant values:
Here, we force certain pins to a constant value 0 or 1. This may be because certain pins are actually constant in some modes, so for those modes, you may want to mimic how the chip state is going to be in silicon. You don't want to unnecessarily time those paths which are not even valid in that mode.
1. set_case_analysis (SCA): needed to set force a certain value 0/1 on ports or pins. However, be careful since once a pin is forced to a particular value, there is no more timing path thru that pin (as it has a constant value, doesn't change). So, all such paths are removed from timing analysis. In normal runs, if such pins do toggle then we won't be able to catch timing violations if we do this. In theory, we never need to set_case_analysis, but we have different modes of operation (functional, scan, etc). If we run w/o any case analysis, all modes will run in same run, causing a lot of bogus timing paths. So, we use case analysis on quasi static pins (pins which only change once when switching modes, but otherwise remain constant), and run different modes in different timing runs. However if we need to time the path, where we set SCA, we'll need to remove SCA in a separate run, and just do report_timing for all paths thru that pin/net. This will guarantee that we covered this timing path too (in case it turns out be toggling and there's no way user is able to control the signal on silicon).
report_case_analysis used to report all pins/ports which have case analysis set. Useful for debugging.
syntax: report_case_analysis <options> <pin_or_port_list> => If no options provided then all pins/ports in design that have SCA on them are reported. In this case, it doesn't show pins/ports where these constant values set by SCA propagate to. But if we provide pin/port list, then propagated SCA values are shown. Many times we want to know the source pin that causes this case value. That's done using -to option:
ex: report_case_analysis -to mod1/I_clkmux2/S => This will report case value on the given pin, and also show the source pin in the path where this propagated value came from, as well as the intermediate gates in the path and their case value.
remove_case_analysis used to remove case-analysis set on the pin.
D misc set_* cmds:
1. set_mode: In liberty files for cells, we can specify an optional mode for timing arcs (see liberty section).
syntax: set_mode -type (cell|design) <mode_list> <instance-list> => instance-list is the instances (not instance definition) on which this mode is to be applied. When we use the set_mode cmd, only the modes explicitly specified are set, all other modes are unset. if we don't use this cmd at all to set any modes, then all modes are enabled (NOT disabled) by default. This behavior may look confusing, but it's to ensure that the tool will still read all timing arcs even if no mode is set. mode type may be of 2 types:
- cell (default) => modes are defined on library cells in design, which is the most common case, or
- design => these are user specified modes using few other mode cmds. We won't look at this option at all.
ex: set_mode func1 block1/u_sram => Here, in liberty file for sram.lib, we have modes defined for certain arcs using stmt "mode(my_mode, func1)". Using the PT cmd "set_mode" in PT script, we are setting the mode to be func1 for particular instance (block1/u_sram) of sram.lib. NOTE: the name of mode group "my_mode" is not specified here, so not sure how multiple mode groups would work?
report_mode: Using this cmd, we can see all modes that are enabled or disabled. Good to use this cmd to check for all modes set.
pt_shell> report_mode => both modes are enabled by default
Cell Mode(Group) Status Condition Reason
--------------------------------------------------------------------------------
block1/u_sram(sram_180nm_lib)
scan_shift (my_mode) ENABLED - cell
func2 (my_mode) ENABLED - cell
pt_shell> set_mode func2 block1/u_sram => Here we are explicitly setting mode for u_sram
1
pt_shell> report_mode => Now, the func2 is enabled, but all modes modes get disabled.
Cell Mode(Group) Status Condition Reason
--------------------------------------------------------------------------------
block1/u_sram(sram_180nm_lib)
scan_shift (my_mode) disabled - cell
func2 (my_mode) ENABLED - cell
2. set_annotated_*: These cmds are used to override the default delay or checks applied by the tool, and instead annotate them by user provided values. We can either override the tool calculated value, or may add on top of that (using increment option). This is a useful cmd to use in Synthesis and Timing analysis tools to add extra margin to the design or to specific paths. Usual -from/-to, -rise/-fall etc are supported. remove_annotated_* and report_annotated_* may be used to remove or report such annotations.
- set_annotated_check: Sets the setup, hold, recovery, removal, or nochange timing check value between two pins on a cell or net. -increment Specifies that the delay value is to be added to the calculated check value of the specified timing arc. If an annotated incremental value already exist, then the new value will be added on the existing one.
- ex: set_annotated_check -setup -from ff/CP -to ff/D 1.0 => 1 unit is annotated on the setup time between the clock pin and the data pin of a cell instance. If there was already a value provided by lib or calculated by tool, that value is overwritten with 1 unit delay.
- ex: set_annotated_check -increment -setup -from ff/CP -to ff/D 0.5 => Now, we add an increment of 0.5, so total setup value is 1.0+0.5=1.5 units.
- set_annotated_delay: Sets the cell or net delays (instead of check delays as seen in cmd above). Cell delays exist between pins of the same leaf cell. Net delays exist between leaf-cell pins or top-level ports connected by a net. The specified delay value overrides the internally-estimated cell and net delay value. There's an extra load_delay option which specifies whether dely resulting from cpacitive load of the net should be considered part of net delay or cell delay. This will affect annotation.
- ex: set_annotated_delay -net -rise 1.4 -load_delay cell -from U1/Z -to U2/A => annotates a rise net delay of 1.4 units between output pin U1/Z and input pin U2/A. delay value for this net does not include load delay.
- set_annotated_transition: Sets the the transition time that is annotated on pins in the current design. The specified transition time value
overrides the internally-estimated transition time value.
- set_annotated_transition -rise 0.5 [get_pins U1/U2/U3/A] => sets rise tran time of 0.5 units on pin A
- set_annotated_power: annotates the internal and leakage power on the specified cells and annotates the switching power on the specified nets. No -increment option available, it always overwrites tool calculated value.
- ex: set_annotated_power -internal_power 0.1 -leakage_power 0.2 U0/U1 =>
- set_annotated_clock_network_power: annotate the power values on the clock networks. No -increment option available, it always overwrites tool calculated value.
- ex: set_annotated_clock_network_power -internal 1.0e-03 -switching 2.0e-03 -clock CKA => internal and switching pwr annotated for clock CKA only.