How to use this guide
Start anywhere, but read part one first
This guide assumes you have never run an engineering change order. It explains what one is, what the tool will do for you, and what it will not. Every section is built the same way, so once you have read one you know where to look in all of them.
Each section opens with the answer in one line, in a blue card like the one above. Then the explanation. Then a figure, if the idea is easier to see than to read. Then two cards side by side: what you actually do on a real block, and the mistake that catches people. Then one line telling you what to check before you move on.
Every command in this guide is a command the tool really has, and every option really exists. Where a number is an example rather than a measurement, it says so. Where a figure shows layout, it carries a small table of what the technique costs you. A picture of a fix teaches less than a picture of a fix with its price on it.
What you need before you start
A design that is placed and routed, with its clock trees built. Parasitics that carry location information. And the two files that describe the layout: Library Exchange Format (LEF) for the shape of every cell, and Design Exchange Format (DEF) for where everything sits. Part one says where each of those comes from and how to check it.
You do not need to have run an ECO before. You do need to know roughly what setup and hold mean, and to be comfortable reading a Tcl command with options on it. Everything else is explained as it comes up.
The six marks in the margin
Work the numbers. The numbers are worked in front of you, so you can put your own in their place.
Do this. The thing to do. It also marks every line of every checklist.
Do not do this. The thing not to do. It never appears on its own, always opposite a green check, so you see the fix and not just the failure.
The insight. The one sentence in a section worth carrying away. There is at most one per section.
Think about it. A question for you. The answer is in the next paragraph or two, so stop and have a go first.
Hands on. Something to type and run, rather than something to read.Contents
1A repair, not a rebuild
An engineering change order, or ECO, is a small change made to a chip that is already finished. You do not redesign anything. You size a few cells, add a few buffers, and write the list of changes out for the tool that owns the layout.
Imagine a circuit board that is built, soldered and tested. Two resistors are the wrong value. You do not start the board again. You lift those two parts, put the right ones in, and test it again. That is an ECO.
A chip is the same, with one difference. The board is in front of you, and the chip is a database. So the repair has to be written down as a list of instructions, and handed to the tool that can actually move things.
By the time anyone says the word ECO, the design is placed and routed, the clock trees are built, and the parasitics have been extracted. Timing analysis has run, and it has found something wrong. Maybe nine paths fail setup. Maybe a net has a transition time above its limit. Somebody has to fix those without disturbing the other four million cells.
PrimeTime is where the problem is found, so PrimeTime is where the fix is worked out. But PrimeTime does not own the layout. It can tell you that a buffer should go in at a particular place, and it can write that down. Putting the buffer there is somebody else's job.
An ECO is a repair to a finished design, so the smallest change that works is always the best change.
That sentence is the whole discipline. Every option you are about to meet exists to make the change smaller, or to make its side effects smaller. When you are choosing between two fixes, the one that disturbs less of the layout is almost always the one to take.
In real work. You will join a project at this stage far more often than at the start. Most of the work on a mature chip is ECO work, so this is the loop you will actually live in.
Trap. Treating an ECO like a normal optimisation run. It is not. The tool is deliberately conservative here, and if you push it to be aggressive you will get a layout nobody can close.
Check this next. Open your design in PrimeTime and run report_constraint -all_violators. Whatever it prints is the work in front of you.
Part 1 · What an ECO is · fix_eco_drc, fix_eco_timing, fix_eco_power, write_changes
2The three commands
There are three fixing commands and one writing command. fix_eco_drc fixes design rules and noise. fix_eco_timing fixes setup or hold. fix_eco_power gives power and area back. write_changes writes the result out.
Everything in this guide is those four commands and their options. Learn what each one is allowed to touch and you have most of it.
-type option. Under "how" is the mechanism it uses. The grey line at the bottom of each column says what that command is allowed to damage while it works. All three feed write_changes, which is the only command whose output leaves the tool.Notice that none of the three can change what the chip does. They size cells, they add buffers, they take buffers out. A replacement cell always has the same logical function as the cell it replaces. The logic of your design is not on the table.
Notice too that only one command produces a file. The fixing commands change the design inside the PrimeTime session. Until you run write_changes, nothing you have done can reach the layout.
In real work. You will run all three in one session, in a set order, and write the changes once at the end. The change list gathers up everything you did.
Trap. Running a fixing command, closing the session, and wondering where the work went. Without write_changes there is no file, and without a file there is no ECO.
Check this next. write_changes -format text prints the changes in plain words. Run it after any fixing command to see what you actually did.
Part 1 · The commands · fix_eco_drc, fix_eco_timing, fix_eco_power, write_changes
3Logic only, or physically aware
In logic-only mode the tool sees the netlist and the parasitics. In physically aware mode it also sees where everything is. That second mode is the one you want, because a fix that has nowhere to go is not a fix.
A buffer takes up room. If the tool does not know where there is room, it can only tell you that a buffer would help. Somebody then has to find a place for it, and where it ends up changes the delay the buffer actually adds. Sometimes it changes it enough that the fix stops working.
What it costs
| Locations written out | none, or one per change | only the physically aware change list carries them |
| Sites considered | 0, or 8 free in row 1 | the logic-only run cannot see them |
| Cells displaced | 0 either way | nothing moves in this example |
| Extra input files | LEF, DEF and located parasitics | the price of the second mode |
| Licence | PrimeTime-ADV | needed for physically aware fixing |
What physically aware mode buys you
- Cells and buffers only go where there is actually room.
- The change list carries a location for every change.
- A cell that gets bigger does not have to move far.
- Buffer insertion takes account of free space, density and wire delay.
- Buffers can be put on the route itself, not just at a pin.
- The layout is disturbed less, so the loop closes in fewer turns.
It needs a PrimeTime-ADV license, and it needs you to prepare several files. Both are worth it.
The usual physical input is LEF for the shape of every cell and DEF for where everything sits. There is a second route. If the design is in IC Compiler II, the tool can read that data directly through set_eco_options -physical_icc2_lib and -physical_icc2_blocks, and you never write LEF and DEF at all.
In real work. Almost every real signoff flow runs physically aware. Logic-only mode is for an early look, before the layout data is ready.
Trap. Assuming a logic-only fix will survive implementation. The buffer has to go somewhere, and somewhere is never exactly where the timing wanted it.
Check this next. Run report_eco_options. If the physical paths are empty, you are in logic-only mode whatever you meant to be in.
Part 1 · Physically aware ECO · set_eco_options, check_eco, write_changes -format icctcl
4Before you fix anything
Five steps, in order. Read the design. Turn on pin slack saving. Run a full timing update. Set the variables your design needs. Set the options with set_eco_options, then check them.
Skip any of these and the fixing commands still run. They just run badly, or slowly, or they quietly do less than you asked for. This is the part of the flow that is easy to hurry and expensive to get wrong.
Here is the whole sequence. Most of it you will already have in your analysis script.
read_verilog design.v.gz link_design read_parasitics design.spef.gz read_sdc design.sdc set_app_var timing_save_pin_arrival_and_slack true update_timing -full set_app_var read_parasitics_load_locations true set_app_var eco_allow_filler_cells_as_open_sites true set_eco_options \ -physical_tech_lib_path $tech_lef \ -physical_lib_path $lef_files \ -physical_design_path design.def.gz \ -log_file lef_def.log report_eco_options check_eco
Every command and option here appears in the command ledger at the back of this guide.
set_eco_options takes more than the four options above. These are the ones you will reach for:
| To specify | Options |
|---|---|
| Extra margin for design rule fixing | -drc_setup_margin, -drc_hold_margin |
| Extra margin for timing fixing | -timing_setup_margin, -timing_hold_margin |
| Extra margin for power recovery | -power_setup_margin, -power_hold_margin |
| Which cells are fillers | -filler_cell_names |
| The bottom-metal PG layer to avoid | -power_ground_net_layer |
| IC Compiler II data instead of LEF and DEF | -physical_icc2_lib, -physical_icc2_blocks |
The last row is worth knowing early. If your design is in IC Compiler II, you can point the tool straight at that data with -physical_icc2_lib and -physical_icc2_blocks. You do not have to write out LEF and DEF first.
Why step two matters
timing_save_pin_arrival_and_slack tells the tool to keep the arrival time and the slack at every pin. The fixing commands want those numbers. If they are not there, the commands work them out again, which is a lot of work for an answer you already had.
Why check_eco matters
check_eco reads your LEF and DEF files and tells you what is missing, incomplete or strange. Fix what it reports and run it again. Every minute here saves an hour of wondering why the tool refuses to place anything.
In real work. Put this block in a procedure and source it. You will run it in every ECO session for the life of the project.
Trap. Running update_timing without -full for the first update. Later updates can be incremental. The first one cannot.
Check this next. report_app_var eco* lists every ECO variable with its current value. Read it once, properly, and you will know what is available.
Part 1 · Setting up · set_eco_options, report_eco_options, reset_eco_options, check_eco
5What you are allowed to touch
By default the tool may change almost any cell. Three ideas narrow that down. dont_touch protects a piece of the design. dont_use bans a library cell. set_size_only allows a cell to be resized but not removed.
On a real chip, parts of the design are already signed off, hand-crafted, or owned by somebody else. You have to be able to say "not this". These are the commands that say it.
| Command | What it does |
|---|---|
set_dont_touch | Marks cells, nets, designs or library cells so the ECO commands leave them alone. |
set_size_only | Marks cells that may be resized but must never be deleted. |
set_dont_touch_network | Marks everything downstream of a pin, port or clock. It walks through nets and combinational cells, and stops at anything with a setup or hold check, such as a register or a latch. |
set_dont_use | Bans a library cell everywhere in the design. |
set_target_library_subset | Bans library cells in one part of the design, using -objects for a block or -top for the whole design. |
How the per-block bans stack up
A ban applies downwards through the hierarchy. If you ban a set of cells at the top, every block below inherits that ban. A ban applied lower down replaces the one above it completely. It does not add to it.
These two lines ban high threshold voltage cells everywhere, except inside SLOWBLK, where low threshold voltage cells are banned instead.
set_target_library_subset -top -dont_use */*HVT*
set_target_library_subset -objects {SLOWBLK} -dont_use */*LVT*An empty list, written -dont_use {}, blocks whatever came from above and bans nothing. These bans apply only to the fix_eco_* commands, and they beat any -buffer_list you give. They also apply only to the logic being optimised, so logic the tool is not touching is unaffected.
If a cell is banned by dont_use, can you still put it in by hand?
Yes. The bans restrict the fix_eco_* commands. They do not stop you running insert_buffer or size_cell yourself, and they do not affect get_alternative_lib_cells or report_alternative_lib_cells. The tool warns you and then does what you asked.
Power management cells are protected by default
Level shifters, isolation cells, retention registers and always-on cells are not considered for resizing unless you say so. That default is there to protect you. Turn it off only when you know why you need to.
set_app_var eco_allow_sizing_with_lib_cell_attributes "is_level_shifter"
The other values are is_isolation, is_retention and always_on. You can give more than one.
In real work. Most projects keep a dont_touch list in the setup script and grow it as blocks get signed off. Read that list before you fix anything.
Trap. Forgetting that set_dont_touch_network stops at registers. It protects the combinational logic downstream, not the whole cone past every flip-flop.
Check this next. Set timing_report_include_eco_attributes to true, then run report_timing. Protected pins now show a d or a u in the attributes column.
Part 1 · Restrictions · set_dont_touch, set_size_only, set_dont_touch_network, set_dont_use, set_target_library_subset
6The order, and why it is the order
Recover power, fix design rules, fix setup, fix hold, then recover leakage. That order comes from which step is allowed to damage which other step, and it is not arbitrary.
Two facts decide everything. Design rule fixing has the highest priority, so it is allowed to move setup and hold slack. And setup fixing is allowed to create hold violations, while hold fixing is not allowed to create setup violations.
What setup and hold actually measure
Before the rest of this part will make sense, one picture. A clock edge launches the data. The next clock edge captures it. Two checks sit around those edges, and every number in this guide is a distance measured against one of them.
Those two windows sit at opposite ends of the clock period. That is the whole reason the order of fixing is not a matter of taste, and figure 7 shows why.
Setup is allowed to break hold because setup is the harder problem to solve, and hold is the easier one to clean up afterwards.
To make a setup path faster you need a bigger cell, a shorter wire or a different route. Your options are limited and they all cost something. To make a hold path slower you add delay, and adding delay is easy. So the flow spends its freedom where it is scarce, and pays for it where it is cheap.
When to break the order up
If a step produces a very large number of changes, those changes can disturb the routing and the legalisation in the layout tool. When that happens, do the steps one at a time, in separate passes, and start with the step that produces the most changes.
When timing matters more than design rules
fix_eco_timing -ignore_drc puts timing first. The command then ignores max_transition, max_capacitance and max_fanout, and it may make them worse. Without that option, fix_eco_timing will not fix a timing violation on a path that already has a design rule violation.
In real work. Write the four steps into a script with a report between each one. You want to see what each step cost before the next one starts.
Trap. Fixing hold first because the hold violations look easier. Setup fixing afterwards will create new hold violations, and you will do the work twice.
Check this next. After each step, report_constraint -all_violators. If a number moved that you did not expect to move, stop and find out why.
Part 2 · The order of fixing · fix_eco_power, fix_eco_drc, fix_eco_timing, -ignore_drc
7Fixing design rules
fix_eco_drc fixes transition, capacitance and fanout limits, noise, crosstalk delay and cell electromigration. It works by sizing cells and adding buffers or inverter pairs, and it tries to add as little area as possible.
A design rule violation is not a timing failure. It is a statement that some signal is outside the range the library was characterised over. Once a signal is outside that range, the delay numbers for it are guesswork. That is why these get fixed first.
The command fixes what these reports complain about:
report_constraint -max_capacitancereport_constraint -max_transitionreport_constraint -max_fanoutreport_noisereport_si_bottleneckreport_cell_em_violation
By default it does not consider timing at all. It will fix your transition time and let the slack fall where it falls. If you want it to respect timing, give it margins with set_eco_options -drc_setup_margin and -drc_hold_margin. The command then leaves that much slack in hand while it fixes the design rule.
size_cell U14 INVX4. Nothing else changed. At the bottom, what the two drivers do to the edge: the weak cell takes 0.41 ns to cross the two voltages the library measures between, and the strong cell takes 0.19 ns. The short bar beneath them is the 0.25 ns limit, drawn to the same scale so the three lengths can be compared by eye.
The simplest possible call, and then a fuller one.
fix_eco_drc -type max_transition -methods {size_cell}
fix_eco_drc -type noise \
-methods {size_cell insert_buffer} \
-buffer_list {BUFX1 BUFX2 BUFX3} \
-physical_mode open_siteIt goes round more than once
The command runs several fixing passes by itself. It keeps going until every violation is fixed, or until it judges that another pass is not worth the runtime. That judgement uses the current quality of results and the options you set.
When it stops, it tells you how many violations are left and how many it could not fix. -verbose tells you why.
In real work. Fix the design rules before you look at a single timing number. A slack figure on a net with a bad transition time is not worth reading.
Trap. Expecting fix_eco_drc to protect your timing. It will not, unless you give it margins. It has the highest priority and it uses it.
Check this next. fix_eco_drc -type max_transition -verbose, then read the unfixable reasons at the end. They tell you what to change.
Part 2 · Design rule fixing · fix_eco_drc, -type, -methods, -buffer_list, -verbose
8Crosstalk and delta delay
When a neighbouring wire switches, it drags your wire with it. That extra delay is called delta delay. fix_eco_drc -type delta_delay reduces it, but you have to tell it how much delta delay is too much.
Two wires running side by side are a small capacitor. When one of them switches, some of that edge appears on the other. If both switch the same way the victim gets faster. If they switch opposite ways it gets slower. Either way the delay is not what the library said.
There is no constraint on delta delay, so there is no delta delay slack, so you must supply the threshold yourself.
Every other fixing type has a limit to work against. Transition time has max_transition. Setup has the clock period. Delta delay has nothing. So -delta_delay_threshold is not optional. Give it a positive number greater than zero, and the same number is used for both the speed-ups and the slow-downs.
Look before you fix. The bottleneck report shows you which nets the command will go after.
report_si_bottleneck -cost_type delta_delay \
-min -max -slack_lesser_than 0.0 -all_nets
fix_eco_drc -type delta_delay -verbose \
-delta_delay_threshold 0.05 \
-methods {size_cell insert_buffer} \
-buffer_list {BUFX1 BUFX2 BUFX3} \
-physical_mode open_siteThe cost column in that report is the absolute value of the delta delay. A net sped up by 0.4 ns therefore ranks alongside a net slowed by 0.4 ns. Under distributed multi-scenario analysis, or DMSA, the report merges every scenario into one list.
Which nets get considered
By default, only nets on paths that already have negative slack. -slack_lesser_than changes that. A positive value takes in paths that pass but not by much, which buys you margin. A negative value takes in fewer paths, which does less work.
This feature needs a PrimeTime-ADV-PLUS license.
In real work. Run the bottleneck report first, every time. It is cheap, and it tells you whether the threshold you picked is going to select four nets or four thousand.
Trap. Picking a threshold by feel. Look at the cost column first. A threshold below the smallest cost in the report selects everything.
Check this next. report_si_bottleneck -cost_type delta_delay -all_nets, and read the top of the list. That is where your threshold belongs.
Part 2 · Crosstalk · fix_eco_drc -type delta_delay, -delta_delay_threshold, -slack_lesser_than, report_si_bottleneck
9Cell electromigration
Electromigration inside a cell is metal wearing out. Current density pushes metal atoms along, and after long enough the metal opens or shorts. fix_eco_drc -type cell_em fixes it, but only one pass at a time.
This is not a timing problem and it is not a noise problem. It is a reliability problem, and it shows up as a design rule violation because that is the only place to put it.
PrimePower does the analysis. PrimeTime does the fixing.
set_app_var power_enable_analysis true
set_app_var power_enable_em_analysis true
update_power
report_cell_em_violation
fix_eco_drc -type cell_em -methods {size_cell insert_buffer}PrimePower finds the high-risk cells using the library data, the design data and the switching activity. If physical data is loaded it uses that too.
One pass means one pass. If violations remain, run update_power again and then fix_eco_drc -type cell_em again. Three rounds of fixing is three update_power calls, and update_power is not cheap.
This needs a PrimePower license and a PrimeTime-ADV-PLUS license.
In real work. Budget the runtime. On a large block each round of power analysis is long, so decide up front how many rounds you are willing to pay for.
Trap. Running the fixing command twice in a row without update_power in between. The second call has stale data, so it finds nothing to do.
Check this next. report_cell_em_violation after each round. If the count is not falling, more rounds will not help.
Part 2 · Electromigration · fix_eco_drc -type cell_em, update_power, report_cell_em_violation
10Fixing setup
fix_eco_timing -type setup makes a path faster. By default it only sizes cells. Add -methods insert_buffer and it can also buffer a heavy load, or split a critical load away from loads that do not matter.
You have to name the type every single time. There is no default, because setup and hold are different problems that happen to share a command.
The two calls you will use most.
fix_eco_timing -type setup
fix_eco_timing -type setup \
-methods {size_cell insert_buffer} \
-buffer_list {BUFX2 BUFX4 BUFX8} \
-physical_mode open_siteLoad buffering
A weak driver with a load far away is slow. The tool adds a buffer part way along, so the driver only has to drive as far as the buffer, as figure 11 shows. In physically aware mode it picks the site itself, and it respects placement blockages while it does.
What it costs
| Sites used | 4 of 8 free | half the gap is still available |
| Cells displaced | 0 | open_site mode moves nothing |
| Routing tracks | 1 → 2 segments | the net is cut in two |
| Path slack | -0.081 → +0.012 ns | illustrative |
| Driver size | unchanged | the driver did not need to grow |
Load shielding
Sometimes the driver is fine and the problem is company. A net with one critical load and three loads nobody cares about makes the critical load wait for all four. The tool puts a buffer in front of the ones that do not matter, and the critical load gets a net of its own. That is figure 12.
What it costs
| Sites used | 4 of 8 free | the same gap as before |
| Loads on the critical net | 3 → 1 | the point of the technique |
| Nets created | 1 | the buffer output |
| Extra delay on the other loads | +1 buffer | they were not critical, so this is free |
| Cells displaced | 0 | open_site mode again |
Side-load cell sizing
There is a third trick. size_cell_side_load first makes the cells hanging off a net smaller, which takes capacitance off it. Then it makes the cell in the critical path bigger. You can see both moves in figure 13. It only works with -type setup and -cell_type combinational.
If you use sizing and buffering separately, size first and buffer afterwards. Sizing is the cheaper change, so let it do what it can before you start adding cells.
Setup fixing is allowed to break hold, so expect new hold violations and plan the hold pass that follows.
In real work. Run setup fixing with sizing only first. Look at what is left. Then run it again with buffering for the paths that sizing could not reach.
Trap. Giving a buffer list full of enormous buffers. A large buffer is a large load for whatever drives it, and you can push the problem one stage back instead of fixing it.
Check this next. report_timing -delay_type max on the worst path. If the slack moved but the path did not change shape, sizing did the work.
Part 2 · Setup fixing · fix_eco_timing -type setup, -methods, size_cell_side_load, -cell_type
11Fixing hold
fix_eco_timing -type hold makes a path slower by adding delay. For violations of about 5 ps or less, a load cell is a better tool than a buffer, because the smallest buffer often adds far too much.
Hold fixing is the easy direction. Adding delay is simple. The difficulty is adding the right amount, because too much delay turns a hold violation into a setup violation.
Those two numbers belong to two different paths. The cell you are about to insert sits on a short path that fails hold by 2 ps. It also sits on a long path that passes setup by 6 ps. Adding delay at that point helps the short path and hurts the long one, by exactly the same amount. That is the whole reason hold fixing has a limit, and figure 15 draws it.
Work it through. The violation is 2 ps. The buffer adds 7 ps, so you end up 5 ps the right side of the hold check and 1 ps the wrong side of the setup check. The load cell adds 3 ps, so you are 1 ps the right side of hold with 3 ps of setup margin left. You needed 2 ps and the buffer gave you 7.
A load cell is a buffer without the output. It slows the net down by loading it, and it costs less area because it only has one pin.
You can use buffer cells and inverter cells as load cells too. When you do, their outputs are left unconnected. A dedicated load cell is smaller and easier to place, and figure 16 lists the attributes it reports.
eco_insert_buffer_search_distance_in_site_rows.What it costs
| Sites used, load cell | 2 | one pin, so it is narrow |
| Sites used, buffer | 3 | two pins and a drive stage |
| Area added, load cell | 1.2 | illustrative |
| Area added, buffer | 5.0 | illustrative |
| Delay added | 3 ps against 7 ps | the reason for the choice |
Two ways to run it. Split by slack, or let the tool choose.
# small violations get load cells, the rest get buffers fix_eco_timing -type hold -methods insert_buffer \ -load_cell_list $clist \ -slack_lesser_than 0.000 -slack_greater_than -0.003 fix_eco_timing -type hold -methods insert_buffer -buffer_list $bflist # or hand it both lists and let it pick per violation fix_eco_timing -type hold -methods insert_buffer \ -load_cell_list $clist -buffer_list $bflist
In the change list, a load cell comes out as three commands: create the cell, connect its pin to the net, and put it somewhere.
create_cell U_LOAD_CAP_CELL_1 CLOAD1
connect_net n231 [get_pins {U_LOAD_CAP_CELL_1/A}]
set_cell_location -coordinates {150.00 30.60} -orientation N
In real work. Ask your library team which load cells you have before you start. If there are none, buffers are all you have, and your smallest buffer sets the smallest violation you can fix cleanly.
Trap. Fixing a 2 ps violation with a 7 ps buffer and moving on. You have not fixed anything. You have swapped a hold violation for a setup violation, and setup is harder.
Check this next. After hold fixing, report_timing -delay_type max on the paths you touched. That is where an over-fix shows up.
Part 2 · Hold fixing · fix_eco_timing -type hold, -load_cell_list, -slack_lesser_than, -slack_greater_than
12Going into the clock network
By default the tool only changes data paths. -cell_type clock_network lets it change the clock instead, which moves the clock arrival time and can fix many endpoints with one change. It only works in physically aware mode.
This is the most powerful thing in the guide and the most dangerous. One buffer in the right place fixes eight registers. The same buffer in the wrong place breaks eight others.
Before you read the physical data, turn on clock data:
set_eco_options -physical_enable_clock_data ...
Then the two commands take these options:
fix_eco_timing \
-type setup | hold \
-cell_type clock_network \
[-clock_fixes_per_change integer] \
[-clock_max_level_from_reg integer] \
[-methods {size_cell | insert_buffer | insert_inverter_pair}]
fix_eco_drc \
-type max_transition | max_capacitance | max_fanout \
-cell_type clock_network \
[-methods {size_cell | insert_buffer | insert_inverter_pair}]-clock_fixes_per_change sets how many violations a change must fix, and -clock_max_level_from_reg sets how far from a register it may happen. At the bottom, the clock edge at one of those register pins, before and after the change, with the buffer delay measured between them.The two restricting options, in plain terms
-clock_fixes_per_change 4 says every change must be worth at least four fixed violations. Set it higher and you get fewer changes, and they happen higher up the tree, closer to the source. The default is 1.
-clock_max_level_from_reg 6 says no change may be more than six buffers away from a register clock pin. Set it to 1 and only the buffer directly driving the register may change. Set it to 0 and there is no limit, which is also the default.
Do all your data path fixing first, then bring the clock network in for what is left. Every clock change moves skew, and skew moves paths you were not looking at.
fix_eco_timing -type setup -cell_type combinational ... ... fix_eco_timing -type setup -cell_type clock_network ...
There is one more variable worth knowing. If a clock signal is used as data somewhere in your design, hold fixing on those paths is off until you turn it on.
set_app_var eco_enable_fixing_clock_used_as_data true
In real work. Keep the two restricting options in your script from the first run, even at their defaults, so that tightening them later is a one-number change.
Trap. Letting clock network fixing loose on a tree you did not build and do not understand. Look at what it wants to do with -estimate_unfixable_reasons and write_changes -format text before you commit.
Check this next. Compare the clock skew before and after. If it moved somewhere you were not fixing, tighten -clock_max_level_from_reg.
Part 2 · Clock network fixing · -cell_type clock_network, -clock_fixes_per_change, -clock_max_level_from_reg, -physical_enable_clock_data
13Making one path worse on purpose
-target_violation_type tns lets a clock network change make some violations worse while it fixes others. The total has to get better, and the worst one may not fall past a limit you set.
By default, no endpoint is allowed to get worse. That rule is safe, and it sometimes blocks a change that would help four registers and hurt one.
Why would you ever want a fix that makes one path worse?
Because you are not paid on the worst path alone. Total negative slack, or TNS, is the sum of every violation. Worst negative slack, or WNS, is the single worst one. A change that takes TNS from -13 to -11 while pushing one endpoint from -3 to -4 has done real work, even though something got worse.
The safety is that WNS is still capped. It either stays where it was, or it goes no further than the limit you name. Figure 18 works one real example through all three settings.
Check the arithmetic yourself. Panel A adds up to -3 -2 -4 -2 -2, which is -13. Panel B is -4 -1 -4 -1 -1, which is -11. Panel C is -5 +0 -4 +0 +0, which is -9. Each panel fixes three endpoints and pays for it at one.
fix_eco_timing -type hold \
-cell_type clock_network \
-methods {insert_buffer} \
-buffer_list {buf1 buf2 buf3} \
-target_violation_type tns \
-wns_limit -5-target_violation_type endpoint is the default and means the same as leaving the option out. You can set -wns_limit above or below the current WNS, and the tool respects it either way. TNS targeting needs a PrimeTime-ADV license.
In real work. Use it when you have a wide, shallow hold problem: many endpoints, all failing by a little. That is exactly the shape it was built for.
Trap. Turning it on for a design with one deep violation. TNS targeting trades the worst path for the total, and if the worst path is the problem you have traded the wrong way.
Check this next. Record TNS and WNS before you run it. Those two numbers are the only way to tell whether the trade was worth making.
Part 2 · TNS-driven fixing · -target_violation_type, -wns_limit
14Where a new cell is allowed to go
-physical_mode has three settings. open_site puts cells only where there is already room. occupied_site lets other cells shuffle to make room. freeze_silicon uses only spare cells.
This one option decides how much your layout is going to move, so it is the option to think hardest about.
| Setting | What it does | When to use it |
|---|---|---|
occupied_site | Places or resizes cells even when no open site is free, so neighbours move. | Early in the ECO cycle, or on a design that is very full. Higher fix rate, more disturbance. |
open_site | Places cells only where a site is already free. | Late in the cycle, or on a design with room to spare. Less movement, lower fix rate. |
freeze_silicon | Places new cells only on spare cells that are already there. | When the silicon layers must not change at all. See the freeze silicon section in part 3. |
The first two are the ones you will use every day, and figure 19 shows what the choice between them costs.
open_site. The buffer goes into the free gap in row 1 and nothing else moves, so no cell is displaced. Panel B is occupied_site. The buffer goes where the timing wanted it, next to U16, and U17, U18 and U19 all shuffle right by four sites to make room. The dashed outlines show where those three cells used to be.What it costs
| Cells displaced, open_site | 0 | nothing else moves |
| Cells displaced, occupied_site | 2 | and each one moves 4 sites |
| Buffer position | the gap, or beside U12 | the second is where the timing wanted it |
| Wire length added | more in open_site | the buffer is further from the ideal point |
| Risk to the layout | low, or moderate | displaced cells mean re-routing |
Filler cells can become free space
Filler cells fill the gaps between real cells. They do nothing. If you let the tool treat them as free space, it can remove one and use its site.
set_app_var eco_allow_filler_cells_as_open_sites true
The tool learns which cells are fillers from set_eco_options -filler_cell_names. Without that list it cannot tell a filler from a real cell, and the variable above has nothing to act on. Figure 20 shows what the difference is worth.
What it costs
| Usable sites, fillers locked | 8 | the natural gap only |
| Usable sites, fillers unlocked | 14 | the gap plus six fillers |
| Cells displaced | 0 | a filler does nothing, so removing it is free |
| Filler re-insertion | in the layout tool | create_stdcell_fillers puts them back |
| Risk | low | provided the fillers really are fillers |
How far the tool will look
When the tool wants to put a buffer somewhere and that place is full, it looks outwards for a free site. How far it looks is set by one variable, counted in site rows, and the default is eight. Figure 21 draws that reach.
set_app_var eco_insert_buffer_search_distance_in_site_rows 8
What it costs
| Search reach | 8 site rows either way | the default |
| Free sites reached | 2 of the 4 drawn | illustrative |
| Free sites missed | 2, both 9 rows away | one row beyond the default |
| Cost of raising it | a longer wire, so more delay | the buffer ends up further from where the timing wanted it |
| Cost of leaving it | an unfixable violation | which is usually the worse of the two |
Voltage areas and blockages
If your design has more than one supply, the tool has to know which region runs on which one. It also has to know where nothing may be placed. Both come from a physical constraint file.
What it costs
| Voltage areas defined | 3 plus the default | Va, Vb and Vc |
| Va, drawn as | 2 disjoint pieces | one voltage area need not be one region |
| Placement blockages | 1 | nothing may be placed there at all |
| Constraint files needed | 1 per DEF | each in its own set_eco_options call |
| Cost of getting it wrong | an ERC violation | which is slower to debug than a timing one, and illustrative here |
set_eco_options \ -physical_design_path TOP.def \ -physical_constraint_file TOP_phys_cons.tcl set_eco_options \ -physical_design_path BLOCK.def \ -physical_constraint_file BLOCK_phys_cons.tcl
One file per DEF, each in its own call. The file itself holds create_voltage_area and create_placement_blockage commands.
Get this wrong and the fix comes back as an electrical rule check violation rather than a timing one, which is a much slower thing to debug.
In real work. Start at open_site. Move to occupied_site only when the unfixable list tells you there is nowhere to put anything.
Trap. Using occupied_site late in the cycle because it fixes more. It does, and then the layout tool spends a day legalising the result.
Check this next. write_changes -format icctcl and count the -location lines. That is how many cells are about to move.
Part 2 · Placement modes · -physical_mode, eco_allow_filler_cells_as_open_sites, eco_insert_buffer_search_distance_in_site_rows
15Cells that are two rows tall
Some libraries mix single-height and double-height cells in the same region. Site-aware fixing lets you restrict a tall cell to the rows it belongs in. It needs the LEF site name and the DEF row name to match exactly, and it only works with open_site.
A double-height cell straddles a supply rail. It can only go in rows that were laid out for it. The tool has no way to know which rows those are unless the names line up.
What it costs
| Rows spanned | 2 | so it needs two free rows, not one |
| Rail straddled | VSS or VDD | depending on the row offset |
| Name match needed | LEF SITE = DEF ROW | exactly, character for character |
| Physical mode | open_site only | the feature is not available elsewhere |
| What sizing may change | width only | never height |
Physically aware sizing changes cell widths, never heights. A cell that gets stronger gets wider, and it never grows into the row above.
You can switch the feature on and off between fixing calls, which is how you do the single-height cells first and the tall ones after.
set_eco_options -keep_site_names {2Tunit}
report_eco_options
check_eco
set_app_var eco_physical_match_site_row_names false
fix_eco_timing -type setup -physical_mode open_site -verbose
set_app_var eco_physical_match_site_row_names true
fix_eco_timing -type setup -physical_mode open_site -verbose
In real work. Ask for the site names in writing from whoever built the library, and check them against the DEF with your own eyes. Do not assume.
Trap. A site name that differs by one character. The tool will not complain loudly. It will simply never place the tall cell, and you will see unfixable violations you cannot explain.
Check this next. set_eco_options -convert_sites {{unit CORE2T}} maps a DEF row name to a LEF site name when the two do not agree.
Part 2 · Site-aware fixing · eco_physical_match_site_row_names, -keep_site_names, -convert_sites
16When it will not fix
Every fixing command tells you what it could not fix and why. There are nine reason codes for timing and design rules, and eight for power. Reading them properly is the difference between a good second run and a wasted one.
You have to ask for the reasons twice. Once to set how many endpoints get reported, and once to say where the report should go.
set_app_var eco_report_unfixed_reason_max_endpoints 50 fix_eco_timing -type setup -estimate_unfixable_reasons
-estimate_unfixable_reasons works on fix_eco_timing only. It changes nothing in the design. It just tells you what would happen, and it is faster than fixing.
| To do this | Use this |
|---|---|
| Estimate the reasons without changing anything | -estimate_unfixable_reasons |
| Include the reasons in the command output | -verbose |
| Write the reasons to a file | -unfixable_reasons_prefix with an optional -unfixable_reasons_format text | csv |
| Both at once | -verbose and the prefix option together |
There are nine reasons the tool can give you. Figure 24 sorts them by what you can do about each one.
The nine codes, word for word
A - There are available library cells outside area limit B - Delay improvement is too small to fix the violation C - The violation is in clock network I - Buffer insertion with given library cells cannot fix the violation S - Cell sizing with alternative library cells cannot fix the violation T - Timing margin is too tight to fix the violation U - UPF restricts fixing the violation V - Net or cell is invalid or has dont_touch attribute W - Fixing the violation might degrade DRC violations
A pile of I and S codes means your buffer list is wrong. A pile of W codes means you have a design rule problem you have not fixed yet.
You can restrict the estimate to particular paths with -from and -to, the same way you would restrict a timing report. Estimation works with every other option the command takes.
fix_eco_timing -type setup -estimate_unfixable_reasons \ -from I_ORCA_TOP/I_PCI_CORE/pad_en_reg/Q -to pad[1]
The same idea for power
Power recovery has no violations, so the wording is different. Cells are "unusable" rather than violations being "unfixable".
set_app_var eco_power_report_max_unusable_cells 100 fix_eco_power -verbose
B - Power benefit is too small L - Physical constraints restrict sizing S - Cell has no alternate library cell with better power T - Sizing cell might degrade timing U - UPF restrictions prevent sizing V - Cell is invalid or has dont_touch attribute W - Sizing cell might degrade DRC X - Cell is unusable for ECO Z - Cell is sized
In real work. Always run the estimate before the real thing on a big block. It is fast, and it tells you whether to change the buffer list before you spend an hour finding out the hard way.
Trap. Reading the reason list as a failure report. It is a shopping list. Every code points at a setting you can change.
Check this next. Run the estimate, count the codes, change the one setting the biggest group points at, and run it again.
Part 2 · Unfixable reasons · -estimate_unfixable_reasons, -verbose, -unfixable_reasons_prefix, eco_report_unfixed_reason_max_endpoints
PnR Flow Mentor Guide
Master the Physical Design Implementation Flow
Read the complete 8-chapter PnR Flow Mentor Guide free on the web — library setup through placement, clock tree synthesis, routing, chip finishing, hierarchical implementation, and ECO, all the way to stream-out.

17Giving power back
fix_eco_power takes back what the other steps spent. It makes cells smaller on paths with positive setup slack, and it removes buffers from paths with positive hold slack. It is not allowed to create a violation while it does.
Everything before this step made the design bigger and hungrier. This is where you get some of that back, and it is free in the sense that the tool undoes anything that costs you timing.
What it costs
| Setup slack | +0.312 → +0.041 ns | illustrative |
| Area | 18.4 → 9.1 | illustrative |
| Leakage | 9.6 → 3.2 | illustrative |
| Buffers removed | 1 | from a path with positive hold slack |
| Violations created | 0 | the command is not allowed to create any |
The five ways it can choose
- Smallest area. This is the default.
- Smallest value of a numeric library cell attribute you define, through
-power_attribute. - Best name or attribute string from a list you give, through
-pattern_priority. - Least switching, leakage or total power measured by PrimePower, through
-power_mode. - Remove buffers, through
-methods {remove_buffer}.
You can only use one of these at a time. Run the command more than once with different settings if you want more than one.
Five calls, one per method.
fix_eco_power
fix_eco_power -pattern_priority {HVT MVT LVT}
fix_eco_power -pba_mode path
fix_eco_power -pattern_priority {HVT LVT} -pba_mode exhaustive
fix_eco_power -methods {remove_buffer}How it actually works
It is a loop. The tool makes the changes it wants, then checks the design for new or worsened timing and design rule violations. Where it finds one, it backs the change out. Then it looks for more changes, checks again, and keeps going until further progress is not worth the cost.
A cell is only ever replaced when all three of these hold:
- The change does not create or worsen any timing or design rule violation.
- The replacement has the same logical function and passes any restriction you set with
eco_alternative_cell_attribute_restrictionsoreco_alternative_cell_instance_based_restrictions. - The replacement is really preferred. That means less area, a smaller attribute value, a higher priority name, or less power.
Swapping threshold voltage
The commonest use of this command is swapping a fast, leaky cell for a slow, tight one where there is slack to pay for it. That works on the cell name, which has to be a variable part and then a fixed part.
-pattern_priority, drawn as an arrow from first choice to last resort. HVT leaks least, so it goes first.
List the lowest-power cells first in -pattern_priority. Get the order backwards and you will swap every cell the wrong way.
If your library does not follow a naming convention, define a string attribute on each library cell instead and give the attribute values in priority order.
define_user_attribute vt_swap_priority -type string -class lib_cell
set_user_attribute -class lib_cell lib/INV1XH vt_swap_priority INV1X_best
set_user_attribute -class lib_cell lib/INV1XN vt_swap_priority INV1X_ok
set_user_attribute -class lib_cell lib/INV1X vt_swap_priority INV1X_worst
fix_eco_power -pattern_priority {best ok worst} \
-attribute vt_swap_priorityLeakage during setup fixing
Making cells bigger for setup makes leakage worse. By default fix_eco_timing minimises the area it adds and ignores leakage entirely. If leakage matters more than area on your project, give it a leakage attribute to minimise instead.
define_user_attribute leak_attr -type float -class lib_cell set_user_attribute -class lib_cell \ [get_lib_cells LIB_H/INV1X_HVT] leak_attr 1.0 set_user_attribute -class lib_cell \ [get_lib_cells LIB_L/INV1X_LVT] leak_attr 10.0 fix_eco_timing -power_attribute leak_attr
It only replaces cells that have the attribute, with cells that also have it. Cells without it are ignored.
Using real power numbers
-power_mode takes dynamic, leakage or total, and uses data from PrimePower rather than a proxy like area. With total, the tool picks whichever action saves most power at each place in the design.
Where slack is tight it has to choose. High switching activity favours making the cell smaller, because that cuts switching power. Low switching activity favours raising the threshold voltage, because that cuts leakage. Where there is plenty of slack it does both.
-power_mode cannot be combined with -power_attribute or -pattern_priority.
The whole flow for total power recovery in a single session.
restore_session Session1 set_app_var power_enable_analysis true set_app_var power_clock_network_include_register_clock_pin_power false read_saif activity.saif update_power report_power fix_eco_power -power_mode total report_power
The two report_power calls are how you prove the saving. Run them before and after, and compare.
Under DMSA
Dynamic power data comes from exactly one scenario, and leakage data from exactly one scenario. You name them. Pick the scenario with the worst dynamic power and the one with the worst leakage. They can be the same scenario or two different ones. Every scenario is still checked for timing and design rules.
fix_eco_power -power_mode total \ -leakage_scenario S1 \ -dynamic_scenario S3
Leaving the input and output paths alone
-start_end_type reg_to_reg restricts recovery to paths that go from a register to a register. It needs path-based analysis, and reg_to_reg is the only value this command accepts.
fix_eco_power -start_end_type reg_to_reg -pba_mode exhaustive
A cell counts as internal when no path at all, constrained or not, reaches it from a port. Case analysis and disabled arcs are taken into account. Under DMSA, a cell is left alone if it reaches a port in any scenario, and it turns up with reason code V.
In real work. Run power recovery twice. Once at the start of the cycle, to clear out slack nobody is using. Once at the end, to swap threshold voltages.
Trap. Assuming the default recovers power. The default recovers area. Area and power usually move together, but not always, and not on leakage.
Check this next. report_power -groups {register combinational sequential} before and after. If the total did not move, the default was the wrong method for your library.
Part 2 · Power recovery · fix_eco_power, -pattern_priority, -power_attribute, -power_mode, -start_end_type, report_power
18Teaching it to be faster
Power recovery can save what it decided and why. Next time, it reads that back, trains a model, and reuses the decision wherever the conditions match. You turn it on by naming a directory, and nothing else.
Power recovery is slow because the tool has to look at the timing, the topology and the power around every candidate cell. If it has seen the same situation before, it can skip that work.
set_app_var training_data_directory ./train_dir
That is the whole setup. The first run gains nothing, because there is no training data yet, and it writes a file when it finishes. Every run after that reads every file in the directory and writes a new one. Figure 27 reads the coverage the run reports back.
The saved decisions include the decisions not to replace a cell, which is where most of the analysis time goes.
Training coverage is trained cells divided by eligible cells. In this report that is 4 106 599 over 4 788 129, which is 85 per cent. The remaining 15 per cent were analysed in full, exactly as they would have been with no training data at all. The run took 998 seconds against 4 280 seconds for the untrained one.
When it helps and when it does not
| Expect a large benefit | Expect little or none |
|---|---|
| The same design, or a similar type of design | A different type of design, such as a processor against a modem |
| The same or similar clock characteristics | A different clock period or different uncertainty |
| The same layout and parasitic data | Different operating conditions, voltage or temperature |
| Coverage above 90 per cent | A different technology or process node |
The best benefit comes from coverage between 90 and 100 per cent. Below 50 per cent you will see very little.
Why you may as well leave it on
It cannot hurt. If the tool cannot use the data it ignores it and does the analysis properly, and it still records what it learns for next time. The overhead of reading and writing the files is negligible, and the quality of the result is the same either way.
This feature needs a PrimeTime-ADV-PLUS license.
To cover the whole design cycle, save a session at each stage and train from each one on a separate host.
update_timing
save_session after_update
fix_eco_drc
save_session after_drc_fix
fix_eco_timing -type setup
save_session after_setup_fix
fix_eco_timing -type hold
save_session after_hold_fix
# then on four hosts, each restoring one session
set_app_var training_data_directory ./all_training_data
restore_session after_setup_fix
fix_eco_powerTraining from your own script
If you have written your own power optimisation script, the tool can learn from that instead.
record_training_data
source my_eco_changes.tcl
write_training_data -output my_training.td
# later
fix_eco_power -training_data my_training.tdThe tool does not judge your script. It accepts the changes as good and records the conditions around them. If your script was wrong, it has learned to be wrong faster.
In real work. Set the directory once in your site setup and forget about it. The data accumulates across the project and pays back on every later block.
Trap. Expecting a benefit on the first run, or on a design nothing like the one you trained on. Coverage is the number that tells you, and it is printed every time.
Check this next. Read the coverage line in the summary. Below 50 per cent, the training data you have does not match this design.
Part 2 · Machine learning · training_data_directory, -training_data, record_training_data, write_training_data
19Blocks that appear more than once
If a module is instantiated several times and they share a layout, a change to one has to be a change to all. eco_enable_mim makes the tool do that for you, and write one change list per group.
A multiply instantiated module, or MIM, is one design used in several places with the same physical implementation. You cannot change one copy without changing the others, because there is only one layout.
Turn it on, optionally group the instances, fix, then write.
set_app_var eco_enable_mim true
set_eco_options -mim_group {CPU1 CPU2}
set_eco_options -mim_group {CPU3 CPU4}
report_eco_mim_instances
fix_eco_timing -type setup ...
write_changes -format icctcl -output pteco.tclThat produces three files. pteco.tcl for the top level, CPU_pteco.tcl for CPU1 and CPU2, and CPU_0_pteco.tcl for CPU3 and CPU4. By default, without the grouping, all the changes in the CPU module go into one file.
Grouping costs runtime and memory, because each group is analysed on its own. Use it only when the instances really do need different changes.
How a group is recognised
In physically aware fixing, instances belong together when they share a DEF file. In logic-only fixing, when they share a parasitics file, as set by the -path option of read_parasitics.
Two more controls. eco_mim_preserve says whether groups are kept when eco_enable_mim is true. And the -all_mim_instances option of size_cell, insert_buffer and remove_buffer overrides eco_mim_preserve false.
One ECO on a module used four times is four changes to the netlist and one change to the layout. Count both when you are judging how big the ECO is.
In real work. Find out early whether your design has repeated modules. It changes how you read every change count for the rest of the project.
Trap. Sizing a cell inside a repeated module without turning eco_enable_mim on. The change goes to one instance, the layouts no longer match, and the block stops being repeated at all.
Check this next. report_eco_mim_instances lists the groups the tool has found. If it prints nothing, your grouping did not take.
Part 2 · Repeated modules · eco_enable_mim, -mim_group, eco_mim_preserve, -all_mim_instances, report_eco_mim_instances
20The change list
A change list is every change you made in the session, written out as a script. write_changes -format picks who it is written for. There are six formats and each one has one job.
Nothing you do inside PrimeTime reaches the design until you write this file. It is the only output of the whole exercise.
ptsh is the default and goes back to a PrimeTime shell. text is for you to read. dctcl goes to Design Compiler. icctcl, in navy because it is the one you will use most, goes to IC Compiler II and carries locations. eco is binary and is read back by read_eco_changes. aprtcl is for any other place-and-route tool.| Format | Written for | Notes |
|---|---|---|
ptsh | PrimeTime shell | the default |
text | a person | plain description, not runnable |
dctcl | Design Compiler | Tcl |
icctcl | IC Compiler or IC Compiler II | Tcl, and it carries the locations |
eco | PrimeTime again | binary, read with read_eco_changes |
aprtcl | a third-party place-and-route tool | tool-neutral pseudo-Tcl |
Only the eco format can be read back into PrimeTime, and only icctcl and aprtcl carry the placement locations.
A physically aware change list looks like this. Notice that every line that adds something carries a coordinate.
size_cell U1 AND2X
insert_buffer U2/Z BUF1X -location {212.3 753.2}
add_buffer_on_route net1 BUF2X -location {215.0 853.2} -no_legalizeTwo libraries with the same file name
If you have two libraries whose files are named the same, the tool needs to know which one a cell came from. Two variables control that, and both are false by default.
eco_write_changes_prepend_libname_to_libcelleco_write_changes_prepend_libfile_to_libcell
They affect every change list format.
In real work. Write the text format alongside whatever you are really using. It costs nothing and it is the fastest way to see what you did.
Trap. Writing the change list, then running one more fixing command, then handing over the old file. The change list is a snapshot of the session at the moment you wrote it.
Check this next. Open the change list and count the lines. If the number surprises you, find out why before anyone runs it.
Part 3 · Change lists · write_changes, -format, -output
21Replaying changes
The eco format can be read back in with read_eco_changes. That lets you try the same changes in another session, another corner, or at the top level after they were made in a block.
This is how a change made by one person on one block ends up in somebody else's top-level run, possibly on a different version of the tool.
The recommended flow for replaying in PrimeTime.
# in the original session write_changes -format eco -output my_changes # in a new or restored session restore_session ... set_eco_options ... check_eco read_eco_changes my_changes # assess, fix more if you need to, then write for implementation write_changes -format icctcl new_change_list
The point of the middle step is that you can look at the result before you commit to it. Assess it, run more ECO commands if it needs them, and only then write the file the layout tool will run.
From a block to the top
In a hierarchical flow, blocks are fixed separately and then assembled. The block writes its changes, and the top level reads them in against the module name.
# at the block level write_changes -format eco -output changesBlkA # at the top level read_eco_changes -design_name BlkA changesBlkA
The name is the Verilog module name of the block. For a repeated module it can be the reference name, and then the changes go to every instance in the group.
Different teams can fix different blocks, on different versions of the tool, and the top level can still put the result together.
In real work. Use the eco format as your internal currency and icctcl only at the very end. Then you can always reopen a change set and think again.
Trap. Replaying changes into a session whose physical data you never set up. Run set_eco_options and check_eco first, or the locations mean nothing.
Check this next. After read_eco_changes, run report_constraint -all_violators. That tells you whether the changes did in this session what they did in the last one.
Part 3 · Replaying changes · read_eco_changes, -design_name, write_changes -format eco
22Handing over to a third-party tool
write_changes -format aprtcl writes the changes as commands that belong to no particular tool. Somebody else parses them into whatever place-and-route tool you use.
The name is short for automatic place and route. Anything not listed below comes out the same as it would in the IC Compiler II format.
| Operation | Command |
|---|---|
| Insert a buffer at pins | insert_buffer with -new_net_names, -new_cell_names, -location, -orientation and optionally -inverter_pair |
| Insert a buffer on the route | the same, plus -on_route and -route_cut_location |
| Resize a cell | size_cell with -overlap, -location and -orientation |
| Create a load cell | create_cell with -location and -orientation |
| Connect a load cell | connect_net |
| Remove a buffer | remove_buffer |
A single location is a buffer. Two locations on one line is an inverter pair, and the two coordinates are where each inverter goes.
The file header carries a version string, and the only value it can have at the moment is 1.0. Whoever writes the parser should check it, so that a later change to the syntax fails loudly rather than quietly.
# aprtcl_file_syntax_version : 1.0Reading a buffer tree out of the file
The order of the insertions and the list of load pins on each one together rebuild the tree. Read them in order and the shape comes out.
current_instance
current_instance {blk/subblk3}
insert_buffer -on_route BUFFD4 \
-new_net_names {net1} -new_cell_names {BUF1} \
-location {x1 y1} -route_cut_location {x1' y1'} \
{sink1/I sink2/I sink3/I sink4/I}
insert_buffer -on_route BUFFD2 \
-new_net_names {net2} -new_cell_names {BUF2} \
-location {x2 y2} -route_cut_location {x2' y2'} \
{sink1/I sink2/I sink3/I}
create_cell {U_LOAD_CAP_CELL_1} {CLOAD1_LVT} \
-location {150.6320 61.8640} -orientation N
connect_net {design_ack_signal} {U_LOAD_CAP_CELL_1}BUF1 drives four sinks. BUF2 drives three of those four, so it sits under BUF1. Read the pin lists and the hierarchy falls out.
In real work. Agree the parser with whoever owns the layout tool before the first real ECO, not during it. The format is stable, so this is a one-off cost.
Trap. Assuming the third-party tool will accept the IC Compiler II format because it is also Tcl. The command names differ, and so do the options.
Check this next. Write both aprtcl and text, and diff what the parser understood against what the text file says you did.
Part 3 · Third-party handover · write_changes -format aprtcl, -on_route, -route_cut_location, -inverter_pair
23Implementing in Synopsys tools
Six steps. Write the change list, run it in the layout tool, place and route the new cells, extract the parasitics again, read everything back into PrimeTime, and check.
This is the bottom half of the loop from section 1, written out as commands rather than as a picture.
- In PrimeTime,
write_changes -format icctcl new_change_list. - In IC Compiler II, source the change list, then
place_eco_cells, thencreate_stdcell_fillers, thenroute_eco. - In StarRC, extract the parasitics.
- Back in PrimeTime, read the updated netlist and parasitics.
- Run timing analysis again and check the quality of results.
- Repeat if you need to.
In the older IC Compiler tool the middle step is eco_netlist to read the file, then place_eco_cells, legalize_placement and route_zrt_eco.
Step 3 is not optional. New wires mean new parasitics, and the delay numbers you had before the change no longer describe the design.
With a PrimeECO license, implementation, extraction and signoff timing can all happen in one shell instead of three tools.
In real work. Keep the change list, the log from the layout tool and the timing report from the run afterwards together. When something goes wrong three iterations later, that set of three files is what you will want.
Trap. Skipping the filler re-insertion. The fillers were removed to make room, and a row with holes in it will fail a density check later.
Check this next. Compare the cell count before and after. It should have moved by exactly the number of cells your change list adds or removes.
Part 3 · Implementation · place_eco_cells, create_stdcell_fillers, route_eco, eco_netlist, legalize_placement, route_zrt_eco
24The incremental flow
Instead of writing out the whole design every iteration, each tool writes out only what changed. The loop gets much faster. Signoff still needs one full extraction and one full timing run at the end.
On a large block, writing the netlist, extracting every net and updating every path takes hours. If you changed eleven cells, almost all of that work was wasted. Figure 30 puts the two loops side by side.
Two steps per loop
First you establish the reference, once. Then you go round.
# step 1, once icc2_shell> record_signoff_eco_changes -init -def # step 2, every iteration icc2_shell> record_signoff_eco_changes -start icc2_shell> ... implement the ECO ... icc2_shell> record_signoff_eco_changes -stop
record_signoff_eco_changes saves the design, writes the Verilog netlist and writes the DEF. At the end of the implementation step you get an incremental database for StarRC and an incremental change list for PrimeTime.
Setting the flow up, across all three tools.
# IC Compiler II open_lib Design.nlib copy_block -from_block Block -to_block Block_pre_eco open_block Block_pre_eco record_signoff_eco_changes -init -def # StarRC command file NDM_DATABASE: Design.nlib BLOCK: Block_pre_eco ECO_MODE: YES GPD: Block_pre_eco.gpd # PrimeTime read_verilog ndm_path/design.full.v.gz link_design read_parasitics Block_pre_eco.gpd read_sdc Block.sdc update_timing -full save_session eco_session1 set_eco_options -physical_design_path ndm_path/design.full.def.gz fix_eco_timing ... fix_eco_drc ... write_changes pt-eco_inc1.tcl
And then each iteration looks like this.
# IC Compiler II copy_block -from_block Block_pre_eco -to_block Block_eco1 open_block Block_eco1 record_signoff_eco_changes -start -input pt-eco_inc1.tcl ... implement, using the minimal physical impact flow ... record_signoff_eco_changes -stop -def # PrimeTime restore_session eco_session1 read_eco_changes ndm_path/design.incr.pt read_parasitics -eco Block_eco1_inc.gpd update_timing save_session eco_session2 report_timing ...
The update_timing here is incremental by default, which is the whole point.
Hierarchical designs
IC Compiler II and StarRC usually run once per block and once for the top. PrimeTime assembles everything and analyses it as one thing, so you read each block's incremental data in turn.
restore_session eco_session1 read_eco_changes ndm_path_Top/design.incr.pt read_eco_changes ndm_path_Blk1/design.incr.pt read_eco_changes ndm_path_BlkN/design.incr.pt read_parasitics -eco Top_eco1_inc.gpd read_parasitics -eco Blk1_eco1_inc.gpd read_parasitics -eco BlkN_eco1_inc.gpd update_timing

read_eco_changes and read_parasitics -eco apply the hierarchy information themselves, so you do not need current_instance or read_parasitics -path.
Under DMSA, start from a standard script and use create_scenario -image to read the incremental information at the worker level, then update incrementally.
In real work. Set this up once at the start of the ECO phase. The saving compounds over every iteration, and there will be more iterations than you expect.
Trap. Signing the chip off from an incremental run. The incremental data describes the changes, not the whole design. The last run before tapeout is a full one.
Check this next. Compare the runtime of your first incremental iteration against the full one. That ratio is what the setup bought you.
Part 3 · Incremental flow · record_signoff_eco_changes, read_eco_changes, read_parasitics -eco, create_scenario -image
25Doing the ECO in a smaller machine
The reduced-resource flow splits your script in two. The analysis half writes out a small design containing only what the failing endpoints need. The fixing half reads that and runs in a fraction of the memory.
This feature is deprecated and will stop working in a future release. The tool warns you when you use it, and points at the Hybrid timing view in PrimeECO instead. It is here because you will meet it in existing scripts.
write_eco_design. On the right, the fixing half, starting with read_eco_design, in 10 GB. The gold lines are the two commands that make the split possible.
The numbers are worth sitting with. Sixteen scenarios in the full flow need sixteen machines with 100 GB each. In the reduced flow, two machines at 100 GB build the reduced designs, and then sixteen machines at 10 GB do the fixing. That is 1600 GB of machine against 200 GB plus 160 GB.
What goes in the reduced design
Only the design data related to the constraints you say you want to fix. The more constraint types you ask for, the bigger it gets. You can also restrict which path endpoints are considered.
The reduced design may not show every possible violation, so it is for fixing and never for signoff. Always finish with a full analysis.
Swapping the hosts partway through is where the saving comes from.
create_scenario ... set_host_options -num_processes 20 \ -submit_command "bsub [mem=100G] ..." start_hosts current_session -all report_global_timing write_eco_design stop_hosts remove_host_options set_host_options -submit_command "bsub [mem=10G] ..." start_hosts read_eco_design fix_eco_timing
Across saved sessions
It is common to save a session per corner and do the ECO later from a manager session. For that to work with reduced resources, each analysis session has to save the extra endpoint information.
set_app_var eco_save_session_data_type timing save_session ./corner01
Outside DMSA you can merge the failing endpoints from several standalone sessions into one reduced design.
write_eco_design $rreco_db/FF -merge_sessions $my_sess_list
A trick with negative margins
If a scenario only matters for setup, you can tell the tool not to bother with hold there, and the other way round. A large negative margin means the check is effectively switched off.
# worst case corner: check setup, ignore hold set_eco_options -timing_hold_margin -100.0 -timing_setup_margin 0.050 # best case corner: check hold, ignore setup set_eco_options -timing_hold_margin 0.000 -timing_setup_margin -100.0
In real work. If you meet this in an existing script, leave it working but plan the move to the Hybrid timing view. Deprecated means it will stop, not that it has stopped.
Trap. Building a new flow around it today. It is on the way out, and the replacement is a different shape.
Check this next. Look for message PTECO-042 in your log. If it is there, this flow is in use and somebody should know about it.
Part 3 · Reduced resources · write_eco_design, read_eco_design, eco_save_session_data_type, -merge_sessions, -timing_setup_margin, -timing_hold_margin
26Freeze silicon
In the freeze silicon flow, only the metal and via layers change. The transistors stay exactly where they are. New cells come from spare cells already scattered through the layout, wired up by new metal.
New masks for the implant, diffusion and poly layers cost a great deal of time and money. If the change can be made in metal alone, those masks do not have to be made again.
Freeze silicon changes wires, not transistors. That is the whole idea, and every restriction in the flow follows from it.
In figure 32 the same region appears twice, before and after, and nothing in the silicon has moved between the two.
What it costs
| Silicon layers changed | 0 | the point of the flow |
| Metal and via layers changed | yes | new routes to the spare cells |
| Spare cells consumed | 2 | PSC1 and PSC2 |
| Spare cells created | 2 | PSC3 and PSC4, from the unused part |
| Cells moved | 0 | nothing may move in this flow |
A programmable spare cell
An ordinary spare cell does one job. A programmable spare cell, or PSC, is made of transistor-level parts that can be wired up in more than one way. That means one cell can become any of several functions. If a change only uses part of one, the rest is still there for next time.
What you need before you start
- Spare cells actually placed through the layout.
- Those spare cells defined in the
.liblibrary. - Their layout properties available as LEF and DEF from IC Compiler II.
- The spacing rules, from
export_advanced_technology_rules, or from a script ofset_lib_cell_spacing_labelandset_spacing_label_rulecommands, or from a Synopsys technology file.
The PrimeTime side is three commands and one long option list.
set_eco_options \
-programmable_spare_cell_names {PSC1 PSC2 PSC3 PSC4 PSC5 PSC6} \
-physical_lib_constraint_file ../tech_data/my_spacing_rules \
-physical_tech_lib_path {../phy_data/my_tech.lef} \
-physical_lib_path {../phy_data/my_lib.lef ../phy_data/my_design.def} \
-log_file my_lef_def.log
fix_eco_timing -type hold -physical_mode freeze_silicon \
-buffer_list $hold_buffer_list -verbose
write_changes -format icctcl -output pt_eco.tcl-log_file is how you check the spare cells were found. Look for the lines that name each one.
How the spare cells appear in LEF and DEF
A programmable spare cell looks much like an ordinary fill cell in LEF. The difference is that an ordinary fill cell must be CLASS CORE FEEDTHRU or CLASS CORE SPACER, and for a programmable spare cell that is optional.
In DEF, the instance must carry SOURCE DIST, because it is not in the netlist, and PLACED, because it has a location. It must not carry FIXED or COVER.
What the change list looks like
Each inserted buffer names both where it goes and which spare cell it is taking over.
insert_buffer [get_pins {U1/z}] e0hd_cap12x \
-new_net_names {eco_hold_net1} \
-new_cell_names {eco_hold_buf1} \
-location {665.4320 193.6320} -orientation FS
map_freeze_silicon \
-eco_cell [get_cells -hier " eco_hold_buf1 "] \
-spare_cell xofiller!ECO_DECAP_FILLER_!e0hd_cap12x!179638 \
-filler_map_strategy closestAnd the IC Compiler II side
# preparing the layout, before any of this add_spare_cells -cell_name ... -lib_cell ... -num_cells ... create_stdcell_fillers -lib_cells ... # implementing the change set_app_options -name design.eco_freeze_silicon_mode -value true source pt_eco.tcl set_app_options -name design.eco_freeze_silicon_mode -value false connect_pg_net -automatic set_app_options -category route.global -list {timing_driven false} set_app_options -category route.track -list {timing_driven false} set_app_options -category route.detail -list {timing_driven false} check_routes route_eco -reroute modified_nets_only -open_net_driven true
In real work. If your project might ever need a metal-only fix, the spare cells have to be in the layout from the start. Nobody can add them later.
Trap. Planning a freeze silicon ECO on a design with no spare cells. There is nothing to wire up, and the whole flow is unavailable.
Check this next. Read the log file named by -log_file and count the "Identified programmable spare cell" lines against what you expect.
Part 3 · Freeze silicon · -physical_mode freeze_silicon, -programmable_spare_cell_names, add_spare_cells, map_freeze_silicon, route_eco
27When scenarios outnumber hosts
Set eco_enable_more_scenarios_than_hosts to true and you can run more scenarios than you have machines. The hosts then take turns, which costs runtime, and you can get most of that back by writing the script differently.
Each time a host has to put one scenario down and pick another up, that is a round of swapping. Swapping is expensive, and the number of rounds is something you control.
| What you need | How much |
|---|---|
| Hosts, minimum | four |
| Hosts, recommended | at least eight, or a quarter of the number of scenarios, whichever is larger |
| Disk in the working directory | enough for the session data of every scenario |
| Runtime | it rises linearly as the number of hosts falls |
The disk requirement is easy to work out and easy to forget. Thirty-two scenarios at 1 GB each need at least 32 GB in the distributed working directory. If it is not there, the run fails part way through, which is the worst time for it to fail.
remote_execute blocks, so each host reloads scenarios four times. Each red line is one round of swapping. On the right, the same commands merged into one block, so it happens once. The work is identical.Two rules for a fast script
- Keep merged reporting commands such as
report_timingandreport_analysis_coverageto a minimum. - Merge your
remote_executeblocks. Each one costs a full round of swapping.
One block going in, one block coming out, and the changes written from a single scenario.
remote_execute {
set_dont_touch $dont_touch_list
set_dont_use $dont_use_list
set eco_alternative_area_ratio_threshold 2
update_timing
}
fix_eco_timing -type setup
remote_execute {
report_analysis_coverage
report_timing -delay_type max ...
report_timing -delay_type min ...
report_constraint -all_violators ...
}
report_constraint -all_violators ...
current_scenario scen1
remote_execute { write_changes -output my_eco.tcl }Writing the changes from one scenario rather than all of them avoids another round of swapping.
In real work. Count the remote_execute blocks in your script before you complain about runtime. Merging them is usually the largest single win available.
Trap. Adding a report in the middle of the script to see how things are going. That report costs a full round of swapping every time it runs.
Check this next. Count your remote_execute blocks. If there are more than two, there is time to be had.
Part 3 · More scenarios than hosts · eco_enable_more_scenarios_than_hosts, remote_execute, current_scenario
28Doing it by hand
You can edit the netlist yourself and see what it does to the timing. It is useful late in the cycle when only small edits are allowed. For anything larger, use the fixing commands.
Two things make this practical. The tool can tell you which cells you could swap in, and it can update the timing without redoing the whole design.
| Object | Task | Command |
|---|---|---|
| Buffer | insert or remove | insert_buffer, remove_buffer |
| Cell | resize, create, rename, remove | size_cell, create_cell, rename_cell, remove_cell |
| Net | create, connect, disconnect, rename, remove | create_net, connect_net, disconnect_net, rename_net, remove_net |
Look before you commit
report_timing costs an incremental timing update every time you run it. estimate_eco does not. It works out what a size or a buffer insertion would do from the current numbers at that stage, and it is fast. Figure 34 compares the two.
report_timing is slow and exact, so you use it to confirm.estimate_eco -type size_cell -max -rise CPU2/U93 delay type : max_rise lib cell area stage_delay arrival slack --------------------------------------------------------- mylib90/INVD24 21.17 0.0265 0.0265 0.1671 mylib90/INVD20 18.35 0.0291 0.0291 0.1645 mylib90/CKNXD8 14.11 0.0610 0.0610 0.1326 mylib90/INVD3 3.53 0.1295 0.1295 0.0212 *mylib90/INVD2 2.82 0.1936 0.1936 -0.0013 mylib90/CKNXD1 2.82 0.4271 0.4271 -0.3214
The asterisk marks the cell that is in the design now. Everything above it is faster, and everything above INVD3 is also bigger.

estimate_eco is fast but not exact. Use it to choose between options, then confirm the one you picked with report_timing.
You can widen the report with eco_estimation_output_columns, which adds transition time and the stage minimum and maximum transition, capacitance and fanout.
Neither command knows what the placement and routing will do to the parasitics. Only the next extraction knows that.
Choosing a replacement
get_alternative_lib_cells CPU2/reg318
{"class/FD2P1", "class/FD2P2", "class/FD2P3"}
report_alternative_lib_cells CPU2/reg318
Alternative Slack
Library Cells
------------------------------------------
class/FD2P3 1.88(r)
class/FD2 * -1.02(r)
class/FD2P1 -2.88(r)
class/FD2P2 -2.98(r)
size_cell CPU2/reg318 class/FD2P3FD2P3 is the only one that gives positive slack, so that is the one.
What if analysis
These commands trigger a fast incremental update, which only touches the part of the design that changed:
size_cellinsert_bufferandremove_bufferset_coupling_separationandremove_coupling_separationconnect_net,disconnect_netandremove_netcreate_cellandremove_cell
Any other netlist editing command forces update_timing to do a full update instead.
The incremental update works in four steps. It finds the nets you changed and their aggressors. It filters those nets electrically. It runs a first pass over the fanout cone, going only as deep as the slew changes reach. Then it runs a second pass, and more if it needs them, over the nets in that cone.
A what-if crosstalk result can differ a little from a full analysis. The analysis is iterative, and the timing windows and the crosstalk delay depend on each other. Signoff needs a full analysis with complete parasitics and netlist data from the layout tool.
Editing makes a block unique
If you edit one instance of a module that appears several times, that instance stops being the same as the others. PrimeTime renames it for you, and it renames every block above it too, up to the first block that only appears once.
size_cell i1/low/n1 class/NR4P Uniquifying 'i1/low' (low) as 'low_0'. Uniquifying 'i1' (inter) as 'inter_0'. Sized 'i1/low/n1' with 'class/NR4P'
Unlike other Synopsys tools, no new design is created at that moment. A placeholder is made, and the design becomes real when you relink. list_designs -all shows them. The Boolean attribute is_edited is available on a design and on hierarchical cells.
Swapping something bigger
swap_cell replaces a cell with a different design or library cell. It is meant for complex or hierarchical cells. For simple resizing use size_cell, because a swap forces a full timing update.
Before it swaps, the tool checks the pins. Every pin on the cell going out must have a pin with the same name on the cell coming in. The command always relinks the part it replaced, so do not run link_design afterwards. That often undoes the work.
The data model is instance based. Swapping U2/U0, an instance of design X, changes the instance and not the design, so an initial link brings the old design back. The change list records that the swap happened, and write_changes exports it.
If you are doing several swaps, save the constraints with write_script, use -dont_preserve_constraints, and source your script again at the end. That is much faster than letting every swap restore them.
Which library a base name comes from
A full name like mylib1/AND2 is unambiguous. A base name like AND2 has to be resolved. -current_library resolves from the library the cell is linked to. -libraries takes a list and searches it in order. Without either, the order is the link library of the current cell, then link_path_per_instance or set_link_lib_map, then link_path.
What counts as an equivalent cell
Same logical function, same number and direction of input and output pins, same timing arcs. Two variables relax the last two. eco_strict_pin_name_equivalence is false by default, so pin names need not match. eco_strict_lib_arc_equivalence is true by default, and setting it false lets the tool size cells whose timing arcs do not match.
Some complex cells need a user_function_class attribute to describe what they do. Your foundry can supply that information.
In real work. Use estimate_eco to explore and the fixing commands to do the work. Hand editing is for the last few violations, not the first hundred.
Trap. Hand editing a repeated module without realising it. You will uniquify it, and a block that was shared is now two blocks.
Check this next. write_changes -format text after any hand editing. It is the only record of what you did.
Part 3 · Manual editing · estimate_eco, size_cell, insert_buffer, swap_cell, get_alternative_lib_cells, report_alternative_lib_cells
29Making path-based ECO faster
HyperTrace speeds up path-based analysis. Turn it on with one variable and the fixing commands use it whenever you give them -pba_mode. There is nothing else to set.
Path-based analysis is more accurate than graph-based analysis and much slower. HyperTrace is what makes it affordable during an ECO.
set_app_var eco_enable_graph_based_refinement true fix_eco_timing -pba_mode exhaustive ... fix_eco_timing -pba_mode ml_exhaustive ... fix_eco_power -pba_mode path ... fix_eco_power -pba_mode exhaustive ... fix_eco_power -pba_mode ml_exhaustive ...
That variable is separate from timing_enable_graph_based_refinement, which is for reporting. Setting one does not set the other.
This needs a PrimeECO license.
Because HyperTrace is built into the fixing algorithms, the refinement threshold variables used for reporting are neither used nor needed here.
Those three are timing_refinement_max_slack_threshold, timing_refinement_min_slack_threshold and timing_refinement_maximum_critical_pin_percentage. Leave them alone unless the tool tells you otherwise.
How to tell it is working
Information: Running HyperTrace-based ECO fixing (PTECO-115)
If you see PTECO-116 instead, the integration is only partial:
Information: Using HyperTrace to accelerate PBA-based ECO fixing. (PTECO-116)
Three options cause that. When any of them is used, the refinement threshold variables do have to be set properly.
fix_eco_timing -path_selection_optionsfix_eco_power -start_end_type reg_to_regfix_eco_power -pba_path_selection_options
In real work. Turn it on and leave it on for every path-based ECO run. It changes the runtime and not the answer.
Trap. Setting timing_enable_graph_based_refinement and expecting the ECO commands to notice. They will not. They read a different variable.
Check this next. Grep the log for PTECO-115. If you see PTECO-116 instead, one of your options has dropped you into partial integration.
Part 3 · HyperTrace · eco_enable_graph_based_refinement, -pba_mode
A day in the ECO loop
One block, one morning, from nine setup failures to a clean run. Every command here has already appeared in this guide. Nothing new is introduced.
The block is called CORE. It is placed and routed, the clock tree is built, and the parasitics were extracted last night. The report that landed in your inbox says nine setup failures, four hold failures and six transition violations.
Before nine: set the session up
Nothing here is specific to today. This is the block you source every time.
read_verilog CORE.v.gz link_design read_parasitics CORE.spef.gz read_sdc CORE.sdc set_app_var timing_save_pin_arrival_and_slack true set_app_var read_parasitics_load_locations true update_timing -full set_app_var eco_allow_filler_cells_as_open_sites true set_eco_options \ -physical_tech_lib_path $tech_lef \ -physical_lib_path $lef_files \ -physical_design_path CORE.def.gz \ -log_file lef_def.log report_eco_options check_eco
check_eco reports two macro models with no LEF. You do not own those macros and nothing is going near them, so you tell the tool to ignore them and add a placement blockage over each one.
set_eco_options -allow_missing_lef {MACRO_A MACRO_B}Nine o'clock: see what you have
report_constraint -all_violators report_cell_usage
The violator list matches the mail. Cell usage says the block is 4.1 million cells, 85 per cent of them combinational. That number matters in a moment, because it tells you the block is dense.
Quarter past: take the free power first
Step one of the order. There is slack lying around that nobody is using, and giving it back now makes everything after it slightly easier.
report_power fix_eco_power report_power
Area comes down by 2.3 per cent and leakage by 4.1 per cent. Nine setup failures are still nine, because power recovery is not allowed to touch a failing path. That is the point.
Half past: design rules
Six transition violations. Sizing alone should do it, and sizing is the change that disturbs least.
fix_eco_drc -type max_transition \
-methods {size_cell} \
-physical_mode open_site -verboseFive fixed, one left. The verbose output gives it reason code S, which means no alternative library cell is strong enough. You add buffering and run the one remaining violation again.
fix_eco_drc -type max_transition \
-methods {size_cell insert_buffer} \
-buffer_list {BUFX2 BUFX4 BUFX8} \
-physical_mode open_site -verboseClean. Setup slack moved by a few picoseconds on two paths, which is design rule fixing doing what it is allowed to do.
Ten o'clock: setup
Estimate first. It costs a minute and it tells you whether your buffer list is any good before you spend an hour finding out.
set_app_var eco_report_unfixed_reason_max_endpoints 50 fix_eco_timing -type setup -estimate_unfixable_reasons
Seven of the nine come back clean. Two come back with reason code I, which means buffer insertion with the cells you gave it cannot fix them. Your buffer list has nothing above BUFX8. You add two larger cells and run it for real.
fix_eco_timing -type setup \
-methods {size_cell} \
-physical_mode open_site -verbose
fix_eco_timing -type setup \
-methods {size_cell insert_buffer} \
-buffer_list {BUFX2 BUFX4 BUFX8 BUFX12 BUFX16} \
-physical_mode open_site -verboseSizing alone fixes six. Buffering fixes two more. One is left, and it comes back with reason code A: there is a library cell that would work, but it is outside the area limit.
Would you raise the area limit, or leave one path failing?
Neither, yet. You look at the path. It is a long combinational chain through a region that check_eco already told you is dense. Raising the area limit there will push cells around and you will pay for it in the routing. You leave it and come back after hold.
Eleven: hold
Setup fixing is allowed to break hold, and it did. Four hold failures have become eleven. Seven of the new ones are tiny.
report_timing -delay_type min
Seven violations are between -1 ps and -3 ps. Your smallest buffer adds 6 ps. Using it on a 1 ps violation leaves 5 ps of over-fix on a path with 4 ps of setup margin, which is a new setup failure. Load cells add 2 ps, so they are the right tool for those seven.
# the small ones, with load cells fix_eco_timing -type hold -methods insert_buffer \ -load_cell_list $clist \ -slack_lesser_than 0.000 -slack_greater_than -0.004 \ -physical_mode open_site -verbose # the rest, with buffers fix_eco_timing -type hold -methods insert_buffer \ -buffer_list $bflist \ -physical_mode open_site -verbose
All eleven fixed. Setup did not move, because hold fixing is not allowed to move it.
Half eleven: the one that is left
One setup path, reason code A. You try the clock network, because moving the capture edge later is a different lever from making the data path faster.
set_eco_options -physical_enable_clock_data
fix_eco_timing -type setup \
-cell_type clock_network \
-methods {size_cell insert_buffer} \
-buffer_list {CKBUF2 CKBUF4} \
-clock_max_level_from_reg 2 \
-physical_mode open_site -verboseIt fixes it, with one buffer, two levels from the register. You keep -clock_max_level_from_reg 2 deliberately tight, so the change cannot reach up the tree and move skew for registers you were not looking at.
Then you look at the clock skew. It moved by 4 ps on one branch and nothing else changed. That is acceptable.
Noon: take the leakage back
Step four. Threshold voltage swapping does not change the layout at all, so it is free from the layout tool's point of view.
fix_eco_power -pattern_priority {HVT NVT LVT} -pba_mode exhaustive
report_power
Leakage comes down another 6.8 per cent. Nothing moved, no cell changed size, and every one of the swapped cells kept the same function and the same footprint.
Half past twelve: write it out and check it
report_constraint -all_violators write_changes -format text -output eco_day1.txt write_changes -format icctcl -output eco_day1.tcl
The violator list is empty. You read the text file, all 214 changes of it, and count the -location lines in the Tcl file. There are 31. Those are the cells being added or moved, and the other 183 are cells changing size where they already stand. On a block this dense, 31 is a number the layout team will accept.
The change list is the deliverable. Everything before it was working out, and only this file leaves the tool.
And then the loop
The layout team runs the change list, re-routes, and hands it to StarRC. The new parasitics land tomorrow morning. Then you read them back and find out whether the 31 changes did what the estimate said they would. Some of them will not have, because the routing is different now, and that is the second iteration.
Back matter · A worked day · fix_eco_power, fix_eco_drc, fix_eco_timing, write_changes, check_eco
Three checklists
Print these. They are the things that go wrong, in the order they go wrong.
Before your first ECO on a block
The design is fully placed and routed, and the clock trees are built.
check_legality -verbosein the layout tool reports every cell legal or fixed.
check_routereports no shorts or opens, or every one is understood.
The parasitics carry location information, with NETLIST_NODE_SECTION: YESandREDUCTION: NO_EXTRA_LOOPSin the StarRC command file.
The same StarRC script produced the parasitics you are using now.
The LEF and DEF are consistent with the netlist and the parasitics.
The Verilog netlist was written before the NDM was saved and the parasitics extracted, so every name matches.
check_ecoruns clean, or every message it prints is understood.
You have read the project dont_touchlist.
You know which buffers and load cells you are allowed to use.
Before you write the change list
Every step of the order has run, and you looked at the reports between them.
report_constraint -all_violatorsis empty, or every remaining violation has a reason code you have read.
No fixing command reported unfixable violations you have not looked at.
If you fixed in the clock network, you compared the skew before and after.
If you used occupied_site, you know how many cells will move.
If your design has repeated modules, eco_enable_mimwas set before you started fixing.
You ran report_powerbefore and after, so you can say what the ECO cost.
Before you call it closed
The layout tool ran the change list without errors.
Filler cells were put back with create_stdcell_fillers.
The routing was updated with route_ecoand checked.
The parasitics were extracted again after the change, not before.
PrimeTime read the updated netlist and the updated parasitics.
The final timing run is a full one, not an incremental one.
If you used the reduced-resource flow, the signoff run did not.
The change list, the layout log and the final timing report are stored together.
Reason codes, for looking up
Both tables on one page. The left column is what the report prints. The right column is what to do about it.
Timing and design rule fixing
| Code | What it means | What to do |
|---|---|---|
| A | There are available library cells outside area limit | Relax the area limit, or accept the violation |
| B | Delay improvement is too small to fix the violation | Relax the margin, or accept it |
| C | The violation is in clock network | Use -cell_type clock_network, carefully |
| I | Buffer insertion with given library cells cannot fix the violation | Add stronger or weaker cells to -buffer_list |
| S | Cell sizing with alternative library cells cannot fix the violation | Check dont_use, and look at report_eco_library_cells |
| T | Timing margin is too tight to fix the violation | Lower the margin in set_eco_options |
| U | UPF restricts fixing the violation | The power intent forbids it; talk to whoever owns the UPF |
| V | Net or cell is invalid or has dont_touch attribute | Check the dont_touch list |
| W | Fixing the violation might degrade DRC violations | Fix the design rules first |
Power recovery
| Code | What it means | What to do |
|---|---|---|
| B | Power benefit is too small | Nothing. The tool is right. |
| L | Physical constraints restrict sizing | Look at the voltage areas and the blockages |
| S | Cell has no alternate library cell with better power | Check the library, and the priority list order |
| T | Sizing cell might degrade timing | There is no slack there to spend |
| U | UPF restrictions prevent sizing | The power intent forbids it |
| V | Cell is invalid or has dont_touch attribute | Check the dont_touch list |
| W | Sizing cell might degrade DRC | Fix the design rules first |
| X | Cell is unusable for ECO | Often a power management cell; see eco_allow_sizing_with_lib_cell_attributes |
| Z | Cell is sized | Nothing. It worked. |
Set the report limits first, or you will get a very short list and think there is nothing wrong.
set_app_var eco_report_unfixed_reason_max_endpoints 50 set_app_var eco_power_report_max_unusable_cells 100
Back matter · Reason codes · eco_report_unfixed_reason_max_endpoints, eco_power_report_max_unusable_cells
Interview questions
Eighteen questions an interviewer actually asks about the ECO flow. Seven beginner, seven practical, four expert. Each one has a ten-second answer to lead with, then the reasoning behind it.
Because design rule fixing has the highest priority and is allowed to move setup and hold slack, while timing fixing keeps design rules clean. Fix in the other order and the design rule pass undoes your timing work.
There are two one-way relationships in the flow. Design rule fixing may damage setup and hold. Timing fixing may not damage design rules.
So if you fix timing first, the design rule pass that follows can walk all over it. If you fix design rules first, the timing pass that follows leaves them alone. Only one of those two orders converges.
There is a second reason. A net with a transition time outside the library range has a delay number that was extrapolated rather than characterised. Fixing timing against a number like that is guesswork.
In real work. The recommended order is power recovery, design rules, timing, then leakage recovery. Put it in a script with a report between each step.
Trap. Saying "because the tool documentation says so". The interviewer wants the asymmetry, not the order.
Check this next. What is the other asymmetry in that order, between setup and hold?
Part 2 · The order of fixing · fix_eco_drc, fix_eco_timing
Because setup and hold are different problems that happen to share a command, and they use different default methods. Setup fixing sizes cells. Hold fixing sizes cells and inserts buffers.
Making a path faster and making a path slower are not the same job. To speed a path up you need a stronger cell, a shorter wire or a better route, and your options are limited. To slow a path down you add delay, which is easy.
The defaults reflect that. There is no sensible default type, so the command refuses to guess.
In real work. Write both calls into your script explicitly, setup first and hold second, with a report in between.
Trap. Assuming that running it without a type does both. It does neither.
Check this next. Why is setup fixing allowed to create hold violations?
Part 2 · Timing fixing · fix_eco_timing -type
Logic-only mode sees the netlist and the parasitics. Physically aware mode also sees the placement, so it only puts cells where there is room and it writes a location for every change.
In logic-only mode the tool can tell you a buffer would help, but not where it goes. Somebody downstream has to find a site, and where the buffer ends up changes how much delay it actually adds.
Physically aware mode closes that gap. It considers available space, placement density and wire delay. It avoids large displacements when it resizes, and it can buffer on the route rather than at a pin.
It needs a PrimeTime-ADV license and several extra input files: LEF, DEF or an IC Compiler II database, and parasitics with location information.
In real work. Almost every signoff flow is physically aware. Logic-only is for an early look before the layout data exists.
Trap. Believing a logic-only fix will survive implementation unchanged. It rarely does.
Check this next. Which StarRC settings do the parasitics need for physically aware ECO?
Part 1 · Physically aware ECO · set_eco_options, check_eco
It writes every change made in the session out as a script for another tool. Forget it and nothing you did reaches the design, because the fixing commands only change the PrimeTime session.
The three fixing commands modify the design inside the session. That is enough for you to report on the result and decide whether you like it, but it is not a deliverable.
The change list is the deliverable. Six formats are available and each one has a destination. The one you will use most is icctcl, because it goes to IC Compiler II and carries the placement locations.
In real work. Write the text format as well as the one you are handing over. When a change list gets argued about later, the plain-words copy is the one everybody in the room can read.
Trap. Writing the change list and then running one more fixing command. The file is a snapshot of the moment you wrote it.
Check this next. Which formats carry the placement locations, and which can be read back in?
Part 3 · Change lists · write_changes -format
A spare cell is an unconnected cell placed in the layout on purpose. A later change can then be made by wiring it up in metal, rather than by making new silicon masks.
New masks for the implant, diffusion and poly layers are expensive and slow. If a fix can be made using cells that are already on the die, only the metal and via masks change.
A programmable spare cell goes further. It is built from transistor-level parts that can be wired several ways, so one cell can become any of a number of functions. If a change uses only part of it, the rest stays available.
In real work. The spare cells have to be in the layout from the very beginning. Nobody can add them later, so this is a decision made at floorplanning.
Trap. Planning a metal-only ECO on a design that has no spare cells. The flow simply is not available.
Check this next. What must the DEF say about a programmable spare cell instance?
Part 3 · Freeze silicon · -physical_mode freeze_silicon
Because it is not allowed to create or worsen a timing or design rule violation. It makes changes, checks, undoes whatever broke something, then looks for more.
Power recovery is an iterative loop rather than a single pass. The tool makes the changes it wants, analyses the design for new or worsened violations, and incrementally backs out of the ones that caused them.
Then it explores further changes, analyses again, and keeps going until it decides the cost of more progress is greater than the benefit.
A replacement only stands when three things hold. It breaks nothing. It has the same logical function and passes any attribute restrictions. And it is really preferred on area, attribute value, name priority or measured power.
In real work. Run it twice, once at the start to clear unused slack and once at the end for threshold voltage swapping.
Trap. Assuming the default recovers power. The default recovers area.
Check this next. What does -power_mode total do that the default does not?
Part 2 · Power recovery · fix_eco_power
It reads your LEF and DEF and reports anything missing, incomplete or inconsistent, before you waste a fixing run on bad physical data.
Physically aware fixing depends on the physical data being right. If a macro has no LEF model, or a site name in the DEF does not match the library, the tool cannot place anything sensibly.
It is far cheaper to find that out in seconds than after an hour of fixing that produced nothing.
If a hierarchical block has no LEF macro model, the tool can take its size, shape, pin locations and obstructions from the DEF instead. You can also list models to ignore entirely with -allow_missing_lef, but then the space they occupy is treated as empty, so add a placement blockage over each one.
In real work. Run it, fix what it reports, and run it again. Every message should either be gone or understood.
Trap. Ignoring -allow_missing_lef warnings. The tool now thinks those areas are free space.
Check this next. What does report_eco_options tell you about ignored macro models?
Part 1 · Setting up · check_eco, -allow_missing_lef
When the violation is about 5 ps or less. The smallest buffer often adds far more delay than you need, which turns the hold violation into a setup violation.
Work an example. The violation is -2 ps and the setup slack is +6 ps. The smallest available buffer adds 7 ps. Hold goes to +5 ps, which is fine, but setup goes to -1 ps, which is not. You have swapped an easy problem for a hard one.
A load cell that adds 3 ps takes hold to +1 ps and leaves setup at +3 ps. It also costs less area, 1.2 against 5.0 in that example, because it has only one pin.
You can use buffer cells and inverter cells as load cells, with their outputs left unconnected. A dedicated load cell is smaller and easier to place, and it reports number_of_pins of 1 and is_black_box true.
In real work. Split the fixing by slack. Give the small violations load cells with -slack_greater_than, and the rest buffers. Or hand the tool both lists and let it choose per violation.
Trap. Fixing a 2 ps violation with a 7 ps buffer and calling it done. Check the setup slack on every path you touched.
Check this next. What three commands does a load cell produce in the change list?
Part 2 · Hold fixing · fix_eco_timing -load_cell_list
Because there is no constraint on delta delay, so there is no delta delay slack for the tool to work against. You supply the limit yourself.
Every other fixing type has something to aim at. Transition time has max_transition. Setup has the clock period and the uncertainty. Delta delay has nothing, because no constraint language expresses it.
So -delta_delay_threshold is not optional. It takes a positive value greater than zero, and the same value applies to both the slow-downs and the speed-ups.
Which nets are considered is a separate question. By default only nets on paths with negative slack. -slack_lesser_than with a positive value widens that to paths that pass but not by much.
In real work. Run report_si_bottleneck -cost_type delta_delay first. The cost column tells you where to put the threshold.
Trap. Picking the threshold by feel. A value below the smallest cost in the report selects every net you have.
Check this next. Why does the bottleneck report show negative delta delays as positive?
Part 2 · Crosstalk · fix_eco_drc -type delta_delay
open_site places cells only where a site is already free, so nothing moves. occupied_site places them where the timing wants them and lets neighbouring cells shuffle to make room.
occupied_site gives a higher fix rate because it is more aggressive about placement. It suits an early-stage ECO or a design at high utilisation, where there is nowhere free anyway.
open_site gives smaller displacement because it is more conservative. It suits a late-stage ECO or a design with room to spare.
The third value, freeze_silicon, places new cells only on spare cells, to preserve the silicon layers.
In real work. Start at open_site and move to occupied_site only when the unfixable reasons tell you there is nowhere to put anything.
Trap. Using occupied_site late because it fixes more violations. The extra fixes come from moving cells that were already placed and routed, and every one of those moves lands back on the layout team as work.
Check this next. Which of the three modes does site-aware fixing work with?
Part 2 · Placement modes · -physical_mode
The buffer list. Code I means buffer insertion with the library cells you gave it cannot fix the violation, so the cells you offered are the wrong strength.
The nine codes each point at a different setting. I and S point at the cells: I at the buffer list you passed, S at the alternatives available for sizing. A points at the area limit. T and B point at the margins. C, U, V and W are telling you the violation is somewhere you have not allowed the tool to work.
Read the codes as a shopping list rather than a failure report. The biggest group tells you which single setting to change first.
Use -estimate_unfixable_reasons to get the list without changing anything. It is faster than fixing, and it works with every other option including -from and -to.
In real work. Estimate, count the codes, change the one setting the biggest group points at, and estimate again. Only then fix for real.
Trap. Treating a long reason list as a dead end. Almost every code has an action.
Check this next. Which variable decides how many endpoints appear in that list?
Part 2 · Unfixable reasons · -estimate_unfixable_reasons
Because every clock change moves arrival skew, and skew moves paths you were not looking at. Do the local work first and bring the clock in only for what is left.
Clock network fixing is powerful precisely because one change reaches many endpoints. A buffer high in the tree fixes eight registers at once.
That reach is also the danger. The same change alters the arrival time for every register downstream of it, including ones that were passing comfortably.
Two options hold it back. -clock_fixes_per_change sets the minimum number of violations a change must fix, which pushes changes higher up the tree. -clock_max_level_from_reg sets how many buffers from a register a change may happen, which keeps them low.
In real work. Keep -clock_max_level_from_reg tight, compare the clock skew before and after, and only relax it if you must.
Trap. Letting clock fixing loose on a tree you did not build. Look at what it wants to do before you commit.
Check this next. What must you set before reading physical data, for clock fixing to work at all?
Part 2 · Clock network fixing · -cell_type clock_network
It makes the tool apply the same change to every instance of a repeated module, and write one change list per group. It matters whenever a module is instantiated more than once with a shared layout.
A multiply instantiated module has one physical implementation used in several places. Change one copy and the layouts no longer match, so the block stops being shared at all.
With the variable true, the tool recognises the group and changes them together. In physically aware fixing it recognises instances by a shared DEF file. In logic-only fixing, by a shared parasitics file, as set by the -path option of read_parasitics.
You can define groups explicitly with set_eco_options -mim_group, once per group. That costs runtime and memory, because each group is analysed separately, so do it only when the groups really do need different changes.
In real work. Ask whether the design has repeated modules before you quote anyone a change count. One change inside a group of eight is eight edits in the layout, and nothing in the report says so.
Trap. Sizing a cell inside a repeated module with the variable at its default. The change goes to one instance only.
Check this next. What does -all_mim_instances do?
Part 2 · Repeated modules · eco_enable_mim, -mim_group
Because the incremental data describes the changes, not the whole design. Signoff needs one full extraction and one full timing analysis.
In the incremental flow, IC Compiler II writes out only what changed, StarRC extracts only the changed part, and PrimeTime applies the incremental parasitics to a restored session. Every iteration is much faster.
What you never get from that is a complete, self-consistent picture of the whole design at once. Every iteration is an edit applied to a baseline, and edits accumulate.
The same caution applies to the reduced-resource flow, for a different reason. There, the reduced design contains only what the failing endpoints need, so it may not reflect every possible constraint violation.
In real work. Budget the full run into the schedule from the start. It is not optional and it is not fast.
Trap. Taping out from an incremental run because the numbers looked fine. They describe the edit, not the chip.
Check this next. Which two commands read the incremental data back into PrimeTime?
Part 3 · Incremental flow · record_signoff_eco_changes
It trades total negative slack against worst negative slack. It may worsen some endpoints while fixing others, and worst negative slack is capped either at its existing value or at the value you give -wns_limit.
The default, -target_violation_type endpoint, forbids any endpoint getting worse. That rule blocks a change that would fix three registers and cost one, even when the total improves.
With tns, the tool may take that trade. In the worked example, a buffer of delay 1 takes total negative slack from -13 to -11 while one endpoint goes from -3 to -4. Worst negative slack stays at -4, because that is where it already was.
Raise the cap to -5 with -wns_limit -5 and a buffer of delay 2 goes in instead, taking the total to -9 and that endpoint to -5. You can set the limit above or below the current value and the tool respects it either way.
The mechanism suits a wide, shallow problem: many endpoints failing by a little. It is the wrong tool when a single deep violation is the issue, because then the worst path is exactly what you cannot afford to trade.
In real work. Record total and worst negative slack before you run it. Those two numbers are the only way to judge whether the trade was worth making.
Trap. Turning it on because it fixes more endpoints, without checking which endpoint paid for it.
Check this next. Which license does TNS violation targeting require?
Part 2 · TNS-driven fixing · -target_violation_type, -wns_limit
It records the cell replacement decisions, including the decisions not to replace, along with the timing and topology conditions around them. Next time it reuses those decisions where the conditions match, skipping the detailed analysis.
Power recovery is expensive because the tool must analyse the timing, the topology and the power in detail around every candidate. Where it has seen the same situation before, that analysis is redundant.
Enabling it is one variable, training_data_directory, and nothing else. The first run gains nothing and writes a file. Later runs read every file in the directory and write a new one.
The summary report gives three numbers. Training coverage is trained cells over eligible cells. Training adjustment is adjusted over eligible. Retraining scope is untrained over eligible. Coverage above 90 per cent gives the best benefit, and below 50 per cent gives very little.
It cannot make things worse. Data that does not match is ignored, the tool analyses those cells properly, and it still records what it learns. The quality of results is the same with or without.
In real work. Set the directory in your site setup and save a session at each stage of the cycle, so later blocks train against a wide range of conditions.
Trap. Expecting a benefit on a design with a different clock period, different operating conditions or a different process node. Coverage will be near zero.
Check this next. How would you make the tool learn from a script you wrote yourself?
Part 2 · Machine learning · training_data_directory
Spare cells must already be placed and defined in the library. Their layout properties must be available as LEF and DEF, along with the spacing rules. And the DEF instances must be SOURCE DIST and PLACED, but not FIXED or COVER.
The flow changes only the metal and via layers, so nothing may move and no new silicon may be created. Every new cell has to come from a spare cell that is already on the die.
That makes it a floorplanning decision rather than an ECO decision. The spare cells are placed with add_spare_cells long before anyone needs them, and if they are not there the flow is unavailable.
In LEF, a programmable spare cell resembles an ordinary fill cell, except that the CLASS CORE FEEDTHRU or CLASS CORE SPACER requirement is optional for it. In DEF, the instance must carry SOURCE DIST, because it is not in the netlist, and PLACED, because it has a location, and must not carry FIXED or COVER.
A programmable spare cell can be partly used. If one ECO takes part of it, the rest backfills as new spare cells and stays available for the next one.
In real work. Read the file named by -log_file and count the identification messages against the number of spare cells you expect.
Trap. Assuming ordinary fill cells will do. They will not. The cells have to be defined in the library as spare cells.
Check this next. What does map_freeze_silicon record in the change list?
Part 3 · Freeze silicon · -programmable_spare_cell_names
Set eco_enable_more_scenarios_than_hosts to true and check there is at least 32 GB of disk in the working directory. Then merge the remote_execute blocks and cut the merged reporting, because each block costs a full round of scenario swapping.
The minimum is four hosts, and the recommendation is at least eight or a quarter of the number of scenarios, whichever is larger. Six is workable but below the recommendation, so expect the runtime to show it.
Runtime rises linearly as the number of hosts falls. How much the turnaround suffers also depends on design size, number of violations, scenario type, network performance and available disk.
The disk requirement is the one that bites. The working directory must hold the session data of every scenario. Thirty-two scenarios at 1 GB each need at least 32 GB, and running out part way through is the worst possible time to find out.
The script changes are simple and they matter more than the host count. Each remote_execute block costs one full round of swapping, so merge them. Keep merged reporting commands to a minimum. Write the changes from a single scenario rather than all of them.
In real work. Count the remote_execute blocks before you complain about runtime. Merging them is usually the biggest single win available.
Trap. Adding a progress report in the middle of the run. It costs a full round of swapping every time it executes.
Check this next. Why does writing changes from one scenario avoid a swap?
Part 3 · More scenarios than hosts · eco_enable_more_scenarios_than_hosts
Glossary
Every term this guide uses that a junior engineer might not know, and every acronym it expands.
Aggressor — A wire whose switching drags a neighbouring wire with it. The one that gets dragged is the victim.
aprtcl — A change list format that writes tool-neutral pseudo-Tcl, for parsing into a third-party place-and-route tool.
Change list — The file that carries every change made in an ECO session out to another tool. Written by write_changes.
Corner — One combination of process, voltage and temperature that the design has to work at.
DEF — Design Exchange Format. A text description of where everything in the design is placed and how it is routed.
Delta delay — The extra delay a wire gets because a neighbouring wire switched at the same time. It can be positive or negative.
DMSA — Distributed multi-scenario analysis. Several corners and modes analysed at once across several machines.
dont_touch — An attribute that tells the ECO commands to leave an object alone entirely.
dont_use — An attribute that bans a library cell from being used in a fix.
DRC — Design rule constraint. In this guide it means the transition, capacitance and fanout limits, not the mask-level geometry rules.
ECO — Engineering change order. A small change made to a design that is already placed and routed.
Electromigration — Metal atoms drifting under high current density, which eventually opens or shorts the metal. Written EM.
Endpoint — The far end of a timing path, where the check happens. Usually a register data pin or an output port.
Filler cell — A cell that does nothing, placed to fill a gap in a row. It can be removed to make space for an ECO.
Freeze silicon — An ECO flow that changes only the metal and via layers, using spare cells that are already on the die.
GPD — One of the parasitic file formats StarRC writes. The other is SPEF.
Graph-based analysis — Timing analysis that uses the worst transition and worst load at every pin. Fast and pessimistic.
Hold check — The check that data does not arrive too early, before the capturing register has finished using the previous value.
HyperTrace — A technology that makes path-based analysis much faster, including inside the ECO fixing commands.
Inverter pair — Two inverters in series, used instead of a buffer. The pair is non-inverting, and sometimes it fits where a buffer does not.
LEF — Library Exchange Format. A text description of the physical shape, pins and obstructions of every cell.
Legalisation — Tidying a placement so every cell sits on a legal site and nothing overlaps. The layout tool does this after an ECO.
Load cell — A single-pin cell inserted to slow a net down by loading it. Better than a buffer for very small hold violations.
Logic-only mode — ECO fixing that uses the netlist and parasitics but no placement data.
Margin — Extra slack you ask the tool to leave, on top of what the constraint needs. Set with the margin options of set_eco_options.
MIM — Multiply instantiated module. One design used in several places with the same physical implementation.
NDM — The design database format used by IC Compiler II and Fusion Compiler.
Netlist — The list of cells in the design and the nets that join them. It says what the design is, not where anything sits.
occupied_site — A placement mode that lets existing cells move to make room for a new one.
open_site — A placement mode that puts new cells only where a site is already free.
Parasitics — The resistance and capacitance of the real wires, extracted from the layout. Without them, delay numbers are guesses.
PBA — Path-based analysis. Timing analysis that uses the real transition and load along each path. Accurate and slow.
Physically aware mode — ECO fixing that uses placement data as well as the netlist and parasitics, and writes a location for every change.
Placement blockage — A region where nothing may be placed, whatever the timing wants.
PrimePower — The Synopsys tool that performs power and cell electromigration analysis.
PSC — Programmable spare cell. A spare cell that can be wired up to perform any of several functions.
Reduced design — A smaller design containing only the data the failing endpoints need, used by the reduced-resource ECO flow.
Scenario swapping — What hosts do when there are more scenarios than hosts: they put one scenario down and pick another up. It is expensive.
Setup check — The check that data arrives early enough to be captured by the next clock edge.
Site — The smallest unit of width in a standard-cell row. Cell widths are always a whole number of sites.
Site row — A row in the layout that standard cells are placed in. Some libraries have rows for double-height cells too.
Skew — The difference in clock arrival time between two points in the clock tree.
Slack — How much time a check passes by. Positive slack passes, negative slack fails.
Spare cell — An unconnected cell placed in the layout on purpose, so a later change can use it.
SPEF — Standard Parasitic Exchange Format. One of the two parasitic formats StarRC writes.
StarRC — The Synopsys tool that extracts parasitic resistance and capacitance from the layout.
Threshold voltage — The gate voltage at which a transistor turns on. A high threshold cell is slow and leaks little. Written Vt.
Timing arc — A path through a cell from one pin to another, with a delay attached to it. Two cells are equivalent only if their arcs match.
TNS — Total negative slack. The sum of every violation in the design.
Training coverage — The share of eligible cells that power recovery handled from training data rather than by full analysis.
Transition time — How long a signal takes to change between levels. Also called slew.
Uniquify — To make one instance of a repeated module distinct from the others, which happens automatically when you edit it.
UPF — Unified Power Format. The language that describes power intent, such as which domain a cell belongs to.
Victim net — The wire that gets dragged by a switching neighbour. What it suffers is delta delay.
Voltage area — A region of the layout that runs on a particular supply.
WNS — Worst negative slack. The single worst violation in the design.
Back matter · Glossary · 56 entries
Free interview practice
Practise interview questions on this topic
- What are Spare Cells, and why must they be distributed uniformly pre-CTS? Beginner
- What is an ECO in physical design? Beginner
- What's the difference between a timing ECO and a functional ECO? Beginner
- What is the PrimeTime ↔ ICC2 ECO loop? Beginner
- Why must you run logic equivalence checking after every ECO? Beginner
- What is an ECO, and when do you fix timing in PrimeTime instead of redoing place-and-route? Beginner
- What does write_changes do at the end of a PrimeTime ECO session? Beginner
- Why must an ECO fix be re-verified with a full STA run before signoff, instead of trusting the ECO tool's own report? Beginner
- What is the difference between a timing ECO and a functional ECO? Beginner
- How does the tool know which programmable spare cell a given standard cell can actually be swapped into during a freeze-silicon ECO? Intermediate
Premium libraries
Go deeper with the pdVerse libraries
Free 8-stage ICC2 PnR walkthrough: library setup to GDS output, with the real command driving each stage. Plus the full 8-chapter mentor guide.
Free to read · PDF ₹199 10 chaptersSTA Library10-chapter STA handbook for VLSI engineers: setup/hold, slack, Liberty, parasitics, OCV/AOCV, crosstalk, PrimeTime reports, and interview Q&A.
Full bundle ₹199 9 chaptersTiming Constraints (SDC) LibrarySynopsys Design Constraints handbook: create_clock, generated clocks, I/O delays, clock groups, false paths, multicycle paths, and SDC linting.
Full bundle ₹179 10 chaptersMMMC LibraryMMMC / MCMM timing signoff: modes vs corners, PVT, RC parasitics, analysis views, ICC2 vs PrimeTime correlation, and scenario explosion.
Full bundle ₹179 9 chaptersLow Power LibraryLearn low-power VLSI design through practical eBooks on power domains, isolation, level shifting, retention, UPF and multivoltage implementation.
Full bundle ₹179 13 guidesSignoff Academy13 ASIC signoff guides: DRC, LVS, ERC, antenna, metal fill, extraction, STA/SI, CLP, EM/IR, LEC, and tapeout handoff evidence.
Full bundle ₹179 14 chaptersDesign Planning HandbookMaster VLSI physical design planning. Read 14 chapters free online or get the complete PDF bundle with floorplanning, power, CTS & timing budgeting.
Free to read · PDF ₹179