Conversation
…metic-python-docs bazel: take the doc build's Python from the toolchain, not the host
The penalty ramp is a feedback controller: HPWL fell, so push density
harder; HPWL rose, so ease off.
phiCoef = getPhiCoef((hpwl - prev_hpwl_) / referenceHpwl)
densityPenalty_ *= phiCoef
getPhiCoef(d) = max(minPhiCoef, d < 0 ? maxPhiCoef
: maxPhiCoef * pow(maxPhiCoef, -d))
referenceHpwl was hard-coded to 446000000 DBU, so the controller's gain
did not depend on the design at all. With maxPhiCoef 1.05 (decayed once
to 1.0395 when overflow first crosses 0.35) and minPhiCoef 0.95, the
proportional band is a wirelength change of 1.037e9 DBU. What that means
depends entirely on how big the design is:
design HPWL 4e6 DBU: band is 259x the whole HPWL -- feedback never
engages, the penalty just ramps, and that is
stable
design HPWL 8.9e10 DBU: band is 1.17% of the HPWL -- every endgame
iteration lands outside it
On the second design the controller is not proportional, it is a switch.
Endgame HPWL steps of -0.93%, -0.98%, -0.71%, +6.28% all sit outside a
1.17% band, so each iteration either ramps at the full +3.95% or is
clamped to -5%. It ramps at maximum with no easing region to warn it,
overshoots, flings cells (+6.28% HPWL in ten iterations, and overflow
gets worse), then cuts the penalty, which relaxes wirelength, which
returns it to maximum ramp. A limit cycle, and it ends in the divergence
detector reverting to a snapshot -- roughly thirty iterations short of
the target the overflow was still descending toward at 10% per ten
iterations.
Derive referenceHpwl from the design's HPWL after initial placement, and
floor it at the value it used to be hard-coded to, so the band is never
narrower than the design's own scale. Designs at or below that scale keep
exactly the controller they had: no test changes. On the design above,
the reversal stops happening and global placement converges at iteration
521 instead of diverging at 680.
-reference_hpwl still overrides it.
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Inflation is the only thing in the routability loop that grows the design, and nothing bounded it. On a design where the loop runs to its retry limit it grew the movable area by a third; with the density penalty controller fixed so global placement no longer diverges partway through, the loop gets to run its full course and the same design grows by 219%: iter 4: inflated +12.63% target density 0.5544 -> 0.6245 congestion 1.3248 iter 5: inflated +20.53% 0.6245 -> 0.7526 congestion 1.4401 iter 6: inflated +30.96% 0.7526 -> 0.9856 congestion 1.5203 iter 7: inflated +65.96% congestion 2.1237 Congestion doubles while the area triples, because inflation adds wirelength and the RUDY estimate is proportional to wirelength: past a point the loop is paying area to make its own metric worse. The two defects had been masking each other - the divergence killed the run before the inflation could compound. Give it a budget, 30% of the movable area it started from (-routability_max_inflation_total), and enforce it two ways. Before the fact, not after: a single pass can want several times the whole allowance - on the design above the first pass asked for +45.7% against a 15% ceiling - so testing the accumulated total afterwards lets it straight through. The area a cell gains is proportional to (ratio - 1), so scaling that term scales the pass's delta by the same factor and the allowance can be spent exactly. And rationed across passes, not spent all at once. The loop's worth is its feedback: measure congestion, inflate, re-place, measure again, each pass re-targeting the area at where the congestion moved to. Spending the whole allowance on the first pass throws that away, sizing the inflation from the single earliest and least informed reading. Measured with global routing on the resulting placements: one pass spending +34.93% of the movable area left 424 congested edges, where seven passes spending +29.98% left 355 and the unbounded loop's seven passes spending +30.17% left none. Also make the loop's improvement test relative. An absolute epsilon of 0.001 on a metric of order 1 let late iterations buy a fourth decimal place for the price of a full Nesterov re-run from the snapshot; 0.5% of the current minimum is progress, less is noise. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
tap/psm: geom boost
The routability loop triggers on overflow alone. Overflow says the design is spread; it does not say the cells have stopped moving, and the two come apart as soon as the density penalty schedule changes pace. Measured on one design at the same overflow of 0.30: cells moving 2.02 bins/iteration -> congestion reads 1.6447 cells moving 6.44 bins/iteration -> congestion reads 2.3458 Same overflow, same design, a faster schedule. Inflation sized from the second reading is aimed at a placement that no longer exists by the time it lands, and the whole first pass - the one that spends most of the budget - is decided on it. The estimator for this is already computed every iteration for the step length: coordiDistance_, the RMS per-cell displacement. It cannot be used as a plain threshold, because it is not monotone over a run - small while the penalty is still weak, peaking as the cells spread, falling again as the placement settles - so "settled" has to mean "down from its peak" rather than "small". Measured at the trigger, that ratio separates the two cases cleanly: 2.115/3.678 = 0.58 against 5.986/5.986 = 1.00. Gate the trigger on displacement having fallen to 60% of its peak as well as on overflow. Being a conjunct it can only ever delay the trigger, so a design already settled at its overflow gate is untouched - no test changes - and on the design above the first congestion reading comes back to 1.5771, in line with the 1.6447 the slower schedule saw. Being a ratio of the quantity to its own history, the threshold carries no bin size, no DBU constant and no dependence on the schedule's rate. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
//docs:man_pages shells out to docs/Makefile, whose pandoc rules ran `pandoc` off PATH. That makes the man and html page rendering depend on whatever pandoc version the host happens to have -- Ubuntu 24.04 ships 3.1.3, macOS/brew tracks latest, etc/DependencyInstaller.sh downloads 3.1.11.1 -- and on RHEL 8, where no pandoc package exists at all, the build simply fails with "make: pandoc: Command not found". Pin pypandoc-binary in bazel/requirements.in and hand the pandoc it bundles to make as PANDOC, declaring the binary as an action input. The wheel carries a statically linked pandoc 3.9 for linux and macOS on x86_64 and arm64, so it runs on distributions old enough to have no pandoc of their own. The Makefile keeps `pandoc` as its default so a non-Bazel `make -C docs` is unchanged. pandoc is GPL-2.0-or-later: the doc build invokes it as a separate process and never links it, and only the man pages it emits are packaged, so no OpenROAD artifact embeds it. The Bazel CI image no longer needs the pandoc package; groff and bsdextrautils (col) remain host requirements. Fixes #11291 Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…metic-pandoc bazel: take pandoc from a pinned wheel, not the host
The routability loop reads a congestion number, inflates cells, and repeats. Three things stood between that number and anything the loop could act on. Rudy folded the tile's capacity reduction straight into the RUDY value: getResourceReductions() added reduction/capacity*100 on top of the wire demand the nets deposit. The two behave nothing alike - demand follows the cells and drops when they move, while the reduction comes from obstructions and layer adjustments computed once when the global router is initialized, and no placement change touches it. Measured on one design, the reduction was 41% of the value in the tiles that set the metric, and 57% inside macro footprints. Split them, and combine as a capacity de-rate, demand / (1 - blockage), rather than a sum: a tile with no demand is then not congested however blocked it is, and the same demand in a tile that has lost half its tracks reads as twice the pressure. Inflation reaches a cell only when the cell's center lands in an inflated tile, so a congested tile holding no movable cell drives the metric while being immune to the only actuator the loop has. On the same design, 74% of the tiles setting the metric held no movable cell at all - local density 0.052 against a 0.389 target - and only 33% of tiles were ones the placer could act on. The GRT path already discarded tiles whose blockage passed ignoreEdgeRatio, with a comment saying why; the RUDY path had no equivalent, and neither looked at whether a tile held any cells. Flag the tiles with movable area, drop the heavily blocked ones, and leave the rest out of both the metric and the inflation ratios. GPL-0088 reports how many tiles are left - a large gap is the signal that a floorplan rather than a placement is what limits routability here. And a tile's demand is deposited by every net whose terminal bounding box covers it, which is mostly nets with terminals elsewhere: on that design 98% of the demand in the worst tiles came from nets spanning more than 30 tiles. Inflating the cells that happen to sit in such a tile does nothing about that, and inflation adds wirelength, which by the same model adds demand everywhere. The demand a net deposits is proportional to its own length, so the lever that works on that component is the opposite of inflation: pull the worst depositors shorter and their share of the demand leaves the region. Rudy::getNetDemandInTiles() is the inverse of the deposit the grid already accumulates, and the loop uses it to raise the wirelength weight of the top depositors through the GNet custom weight, which until now had no producer. The deposit model now has one definition, Rudy::visitNetTiles(), shared by the accumulated grid and the per-net query. -routability_net_weight_max 1.0 turns the net weighting off. Consolidates work first developed as three commits on a superseded branch; happy to split the history again if that reads better for review. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
etc/find_messages.py read sources as UTF-8 but printed with whatever
encoding the ambient locale selected, so a message string containing a
non-ASCII character aborted messages.txt generation on hosts whose
locale is not UTF-8:
bazel build //src/web:messages_txt --action_env=LANG=en_US
UnicodeEncodeError: 'latin-1' codec can't encode character '—'
The docs scripts that consume the generated messages.txt, and that read
Tcl sources and READMEs, had the same problem in the other direction:
they open() without an explicit encoding. ISO-8859-1 happens to survive
this because its decode/encode round-trip is byte-lossless, but a
multibyte locale is not so forgiving:
LC_ALL=ja_JP.eucjp -> man3_translate('src/web/messages.txt')
UnicodeDecodeError: 'euc_jp' codec can't decode byte 0xe2
Write find_messages.py's stdout and stderr as UTF-8, and name UTF-8
explicitly on every open() in the docs scripts, so neither the generated
messages.txt nor the man pages depend on the build host's locale.
This removes the need for message strings themselves to be ASCII.
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
chore(deps): update boost context and remove patch
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
With --features=thin_lto every link target gets its own LTO index and one lto_backend action per object. In the CI test sweep that is ~115 binaries (102 cc_test targets plus the python modules and tools), and the action graph grew from 54,780 to 276,627 actions, almost all of them per-test shards that redo the same optimization work once per test binary. Tests do not need cross-module inlining. Enable Bazel's built-in scoping feature thin_lto_linkstatic_tests_use_shared_nonlto_backends: statically linked test targets skip LTO indexing and link native objects produced by one shared non-LTO backend per object, reused by every test. Non-test binaries (openroad, the python modules, opensta) keep full distributed ThinLTO. The feature only applies to statically linked tests and cc_test defaults to dynamic mode, so --dynamic_mode=off is set alongside it. The hermetic-llvm toolchain does not declare the feature and Bazel silently ignores requested features the toolchain does not know, so a small module patch adds the two cc_feature declarations to its known_features (same override pattern already used for abc, bison, boost and icu). Drop the patch once hermetic-llvm declares them upstream. Measured over //src/... plus //:openroad and //:_openroadpy.so: LTO indexes 112 -> 8, lto_backend actions 143,917 -> 16,762. bazel test over utl, gpl and the odb C++ tests passes 149/149 with zero per-test shard sets; //:openroad is unchanged (1 index, 4,275 shards). Not used: features = ["-thin_lto"] on test targets, which makes lld run implicit in-process LTO on the deps' bitcode (155 s for one small test, and the code path that segfaults in lld 22.1.8). Signed-off-by: SombraSoft <sombrio@sombrasoft.dev>
Signed-off-by: Minju Kim <mkim@precisioninno.com>
OpenSTA 3a595df0 (parallaxsw/OpenSTA#470) moved ownership of the SWIG-allocated Seq containers to SWIG. It added %typemap(freearg) for InstanceSeq*, CellSeq*, PinSeq* and the other Seq pointer types in tcl/StaTclTypes.i, so the wrapper now frees the container it allocated in the (in) typemap, and it dropped the matching manual deletes in search/Search.i, verilog/Verilog.i and sdc/FilterObjects.cc. It also changed tcl/Exception.i to leave via SWIG_fail instead of return, because a plain return skips the generated fail: label where SWIG emits the argument cleanup. Three places here still assumed the old contract. 1. src/rsz/src/Resizer.i, remove_buffers_cmd(InstanceSeq *insts) 2. src/dbSta/src/dbSta.i, write_verilog_cmd(..., CellSeq *remove_cells) Both still deleted the container, so the callee and the wrapper freed it. The double free is a SIGSEGV inside free. These are the only two. Six .i files outside src/sta include tcl/StaTclTypes.i - rmp.i, pdnsim.i, dbSta.i, Resizer.i, EstimateParasitics.i and upstream's own app/StaApp.i - and only dbSta.i and Resizer.i expose a Seq* argument; rmp and psm take LibertyPort*, Scene* and dbNet* only. Scanning the generated wrappers for a fail: block that frees an argument agrees: dbStaTCL has 18, seventeen of which come from upstream %includes and were already fixed upstream, plus write_verilog_cmd; ResizerTCL has one, remove_buffers_cmd; EstimateParasiticsTCL, rmpTCL and pdnsimTCL have none. Dropping the deletes does not leak, and it cannot dangle either: the freearg block runs after $action, and neither callee retains the container. Resizer::removeBuffers takes a const InstanceSeq& and only iterates it, and VerilogWriter's constructor copies the elements into its own CellSet. write_verilog_cmd is annotated "Copied from sta/verilog/Verilog.i"; upstream fixed the original and this copy went stale. 3. src/Exception.i, the shared %exception Annotated "Copied from OpenSTA/tcl/Exception.i" and still returned TCL_ERROR directly, which is the case upstream fixed. 31 non-Python .i files include it, dbSta.i and Resizer.i among them, and dbSta.i does not include sta/tcl/Exception.i at all - it includes this one and then the upstream .i files - so every OpenSTA command reachable through dbSta ran under the old control flow. That covers 19 Seq* parameters in sdc/Sdc.i, search/Search.i and liberty/Liberty.i, including the get_filter path named in 3a595df0's own commit message. On any exception thrown out of those wrappers the container leaked. SWIG_fail is safe in every wrapper: across the 34 generated Tcl modules, 6386 wrappers use SWIG_fail and none lack a fail: label, and no wrapper has a fail: label without a SWIG_fail, so there is no unused-label warning. The 273 wrappers with no SWIG_fail are overload-dispatch trampolines that contain no %exception body. fail: returns TCL_ERROR, the same value the old return produced, and does not touch the interpreter result, so the message built by Tcl_ResetResult/Tcl_AppendResult is unchanged. The only behaviour change on the error path is that argument cleanup now runs, which is the point. Not touched, and why: - find_fanin_fanouts and insert_buffer_before_loads_cmd also delete their argument, but it is a PinSet*, and upstream added no freearg for the Set types. Their exception path still leaks, as it did before this change. - The delete in the %typemap(out) TmpNetSeq* blocks in Resizer.i and EstimateParasitics.i is an out typemap on a distinct name. freearg applies to input arguments only, so that delete is still required. - src/Exception-py.i already uses SWIG_fail and never had this defect. - src/est/src/EstimateParasitics.i returns TCL_ERROR from inside the ParasiticsSrc (in) typemap, and src/ifp and src/odb do the same elsewhere. None of those modules has a wrapper whose fail: block frees an argument, so nothing leaks today; they are the same anti-pattern and worth a separate pass. Signed-off-by: Minju Kim <mkim@precisioninno.com>
OpenSTA d2c508dd (parallaxsw/OpenSTA#489) rewrote the size parse in VerilogNetConstant::parseConstant. It used to be size_t size = std::stol(csize); which aborted read_verilog on the shapes below, and it is now stringLong plus a one-bit default with a warning: 'b0, 'd1 csize is empty -> STA-2724, "unsized constant" -1'b1 stringLong gives {-1,true}, so size_value > 0 fails -> STA-2725, "constant size is not supported" Two different branches, two different codes. Either way the reader keeps going, which invalidated five entries here. STRUCTURAL_EXPECTED_FAIL: read_verilog now accepts the input and the netlist round-trips, so the framework reports these three as unexpected passes. bx_constants_unsized_b0.v bx_constants_unsized_d1.v structural/wb_sta_reader_const_negative_width.v Dropped from both the flat and hier lists. Removing them exposes the other structural checks for those netlists for the first time, and those pass, so no replacement entries are needed. The entries left in those lists still throw, from the stoi in the attribute parser, which d2c508dd did not touch. CONFORMANCE_EXPECTED_FAIL: the two bx_constants_* cases still fail, but as "tool-error" rather than "or-error". The connection is not dropped - it is emitted naming a net the written module never declares or drives: OR2_X1 g1 (.A1(a), .A2(zero_), .ZN(y)); zero_ is an implicit, undriven 1-bit wire, so the emitted netlist is not equivalent to the input and kepler-formal reports a load error. mode is the value the framework itself derives and compares against, so it has to match; the symptom text records what actually happens. structural/wb_sta_reader_const_negative_width.v has no conformance entry because it lives in hier_cases/structural/, which the LEC path does not adjudicate. Accepting input that used to stop the reader and turning it into a floating pin is a behaviour change worth raising upstream. Recording the observed mode here does not endorse it. Signed-off-by: Minju Kim <mkim@precisioninno.com>
The viewer evaluates Tcl, so listening on every interface handed a shell to anyone who could reach the port. Bind 127.0.0.1 unless -bind (or -web_bind on the command line) asks otherwise, and warn when it does. Signed-off-by: Jorge Ferreira <jorge.ferreira@precisioninno.com>
The Sphinx path into find_messages.py had the same locale dependency as the man-page path: docs/getMessages.py decoded the child's stdout with os.popen(), which uses the ambient locale, so the WEB-0030 em dash broke MessagesFinal.md generation even with find_messages.py writing UTF-8: LC_ALL=ja_JP.eucjp -> docs/getMessages.py UnicodeDecodeError: 'euc_jp' codec can't decode byte 0xe2 conf.py's swap_prefix() failed the same way on README.md, which also carries an em dash, aborting the Sphinx build before it got that far. Read find_messages.py's output through subprocess with encoding="utf-8", leaving its stderr alone so duplicate-id diagnostics stay visible, and name UTF-8 on the remaining open() calls in getMessages.py and conf.py. conf.py's two shell-outs discard their output, so they no longer decode it at all. //docs:sphinx_build_test covers this: it fails under ja_JP.eucjp before this change and passes after, and MessagesFinal.md is now byte-identical across ja_JP.eucjp, en_US.ISO-8859-1, C, and C.UTF-8. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The wirelength weight on the nets that deposit the most demand into congested tiles costs more than it buys. On the aes_sky130hd flow test it takes clock skew from 0.363 to 0.439, setup WNS from -1.021 to -1.274, setup TNS from -139.0 to -175.6, and adds an antenna violation the routed design did not have, with no congestion recovered in exchange. Two reasons it lands that way. The weight multiplies onto the timing weight, so a net already pulled for criticality gets pulled harder still for congestion. And shortening a net packs its cells into the region that was congested to begin with, which is the opposite of what inflation in the same loop is trying to do. Keep the mechanism and its options so it can be measured per design, but stop applying it unasked. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
sys.stdout.reconfigure() broke the Rocky 8 build, whose /usr/bin/python3 is 3.6.8 -- TextIOWrapper.reconfigure() arrived in 3.7: cd src/ppl && /OpenROAD/etc/find_messages.py -l > messages.txt AttributeError: '_io.TextIOWrapper' object has no attribute 'reconfigure' gmake[2]: *** [src/ppl/.../ppl_messages.dir/build.make:73] Error 1 Merely guarding the call with hasattr() would trade that crash back for the one this branch set out to fix, since Rocky 8 with LANG=en_US picks ISO-8859-1 for stdout: LANG=en_US python3.6 find_messages.py -d src UnicodeEncodeError: 'latin-1' codec can't encode character '—' So keep reconfigure() where it exists and rewrap the stream's binary buffer as UTF-8 where it does not. Verified on Rocky 8's 3.6.8 under LANG unset, C, en_US, and en_US.iso88591: the whole-tree scan and the src/ppl command above both succeed and the WEB-0030 em dash comes out as UTF-8 in every case. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Measuring routability congestion on the tiles the placer can act on changes the routability trajectory, and on this design it lands at a clock skew of 0.363 against a limit of 0.337. Setup WNS improves in the same run, -1.049 to -1.021, so this is the placement landing elsewhere rather than getting worse. The limit had no room to absorb it. It was generated from a run whose skew was 0.280 and the metric's own margin is 1.2x, and master has since drifted to 0.334 - 83% of the way through that margin. Regenerate the limit from the new value with the same 1.2x margin. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…-message-encoding Make the messages/man-page pipeline locale-independent
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
Phase 3, second slice. Eighteen more Gui methods move to
guiDispatch.cpp and are defined once: setSelected, addSelected{Net,Inst},
removeSelectedByType, selection, getInspectorSelection, anyObjectInSet,
selectHighlightConnected{Insts,Nets,BufferTrees}, add{Inst,Net}ToHighlight
Set, selectAt, select{Next,Previous}, animateSelection, clearSelections
and clearHighlights. 29 duplicate symbols between libgui_qt.a and
libgui_stub.a become 23; libcore.a and libgui_stub.a still share none.
GuiBackend gains the fifteen calls behind them. Every default leaves
the state alone -- nothing selected, nothing highlighted, queries answer
empty -- so a backend with no selection model behaves as the stub did.
The four name-lookup methods resolve their dbNet/dbInst against Gui's
own db_ rather than the window's. Both come from ord::OpenRoad::getDb
-- Gui::init takes it, and startGui hands the same pointer to
MainWindow::setDatabase -- so this is the same block, reached without
asking the backend for a database.
Each method keeps its hasUI() guard, so these still reach only a Qt
window; the dispatch merely makes it possible for a viewer to implement
them later.
Gui::select stays behind, with filterSelectionProperties which only it
calls: its name filter is a QRegularExpression wildcard match, and
swapping that for a Qt-free matcher changes what gui::select accepts.
That belongs in its own change.
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…ckend
Phase 3, third slice. Twenty-two more Gui methods move to
guiDispatch.cpp and are defined once: zoomTo x2, zoomIn x2, zoomOut x2,
centerAt, setResolution, fit, add/delete/clearLabel(s),
add/delete/clearRuler(s), set/checkDisplayControls{Visible,Selectable},
setDisplayControlsColor and save/restoreDisplayControls. 23 duplicate
symbols between libgui_qt.a and libgui_stub.a become 18; libcore.a and
libgui_stub.a still share none.
The display controls are the interesting group. They were the one part
of Gui that already had a headless path -- each method tested hasUI()
and then asked headless_viewer_ before falling back to a literal default
-- which is what the four accessors on HeadlessViewer were for, and what
QtGuiBackend left at their defaults when it was introduced because
nothing routed through them yet. Dispatching through activeBackend()
is that same fallback with the special case gone: the Qt gui now
implements the four against DisplayControls, and the literals Gui used
with nothing installed (visible true, selectable false) stay as the
defaults on GuiBackend.
Colour and the save/restore pair get their own calls rather than
joining the four, since both are properties of a widget rather than of
the visibility model a viewer might keep.
The rest keep their hasUI() guard, so they still reach only a Qt
window.
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Phase 3, fourth slice. Eleven more Gui methods move to guiDispatch.cpp
and are defined once: the nine {add,remove,clear}{FocusNet,RouteGuides,
NetTracks} overlays, plus saveClockTreeImage and saveHistogramImage. 18
duplicate symbols between libgui_qt.a and libgui_stub.a become 12;
libcore.a and libgui_stub.a still share none.
The two image calls take width and height as std::optional across the
interface. Zero meaning "size it yourself" is the Tcl commands' wire
convention, and Gui already unpacked it before calling the widgets; now
the backend never sees it.
saveImage and the three gif methods stay behind, though the plan had
them here. They are not forwards: both saveImage and gifAddFrame
compute a die-area fallback gated on the window being offscreen, render
through LayoutViewer, and saveImage re-enters the gui through
showGui() to do it. Splitting that needs a real interface -- an
offscreen query and a pixel buffer in place of QImage -- which is worth
its own change, not a rider on eleven one-line forwards. That change is
also what lets Gui's constructor move, since it is the gif writer that
pins it to gui.cpp.
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The CTS 111 warning ID added for the dangling-inverter guard collided with an existing TechChar.cpp use of 111, tripping dup_id_test and failing the cts_readme_msgs_check build in CI. Renumber to 136, the next free CTS message ID. Also register the regression test in src/cts/test/BUILD's PASSFAIL_TESTS (mirroring the existing CMakeLists.txt entry and the rmp/gpl Bazel pattern), per review feedback. Verified locally: bazel test //src/cts/test:dangling_clock_inverter-tcl_test, //:dup_id_test, and //src/cts/test:cts_readme_msgs_check-py_test all pass. Signed-off-by: Andreas Wendleder <andreas.wendleder@proton.me>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
…n-fix bazel: fix --config=asan and instrument the binary under test
Review feedback asked for null checks on the name arguments of addSelectedNet, addSelectedInst, addInstToHighlightSet and addNetToHighlightSet. Taking the names by const std::string& removes the null case entirely and matches the neighboring Gui methods. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…a_0911 update STA to 9/11 code
pdn: account for macro orientations when placing straps and other connectivity
…nd-selection gui: dispatch selection, view and overlay commands through GuiBackend
…rgence-fixes gpl: fix four defects in the placement convergence and routability loops
cts: guard null invertedTerm in separateMacroRegSinks
gui: timing report include clock gating checks option
grt: deduplicate vias when reloading ODB guides
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
…rsioning Adjust workspace_status.sh for STA version stamping
Add watermarking module (src/wmk)
odb: add support for polygon floorplans in write_abstract_lef
bazel: make release inherit opt like ci
Elaboration errors were written to stderr and followed by abort(), so an unsupported SystemVerilog construct took the whole process down instead of surfacing as an OpenROAD error a Tcl caller could catch. The log_error/log_warning/log stubs in log_stubs.h are now declared rather than defined inline, and diagnostics.cc implements them on utl::Logger. That routes the vendored frontend's own log_error() call sites without touching third-party/slang-elab/. OpenROAD's elab sources call reportError() directly. The frontend's unimplemented_()/wire_missing_() hooks carry no backend or netlist to reach a logger through, so elaborateImpl() parks the logger and slang's source manager in an ElabDiagnosticScope for the duration of the run. unimplemented_() now also reports the offending node's kind, its file:line:col in the user's HDL, and the source text it was built from, flattened onto one line and capped. Each part is dropped when the node cannot supply it. The four log_assert() uses in backend_builder.cc become plain assert(), matching the surrounding elab code, so log_stubs.h is needed only by the vendored frontend. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
drc_update_category_visibility resolved a category with chip->findMarkerCategory(), which searches only top-level categories, while the viewer's tree sent the bare node name. Every checkbox below the top level therefore failed, e.g. check_power_grid builds PSM/<net>/<check> and toggling it reported Category not found: Unconnected shape The request now carries a path -- the chain of names from the top-level category down to the target -- and the server walks it. A path is what identifies a subcategory, because names are unique only among siblings: both PSM/VDD/Unconnected shape and PSM/VSS/Unconnected shape exist. The category field still works on its own for a top-level category. The viewer threads the path through its tree and uses it as the node-expansion key as well, so same-named siblings no longer expand and collapse together. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
macOS declares mkdtemp() in <unistd.h> rather than <stdlib.h>, so the mac build failed with "use of undeclared identifier 'mkdtemp'". Include both headers at each call site, matching src/utl/src/ScopedTemporaryFile.cpp. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
…kdtemp wmk: include unistd.h for mkdtemp() on macOS
…ategory-path web: address DRC subcategories by their full path
…logger-diagnostics syn: route slang-elab diagnostics through utl::Logger
…-wires-members odb: group tmg_conn members in sections and more renaming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
[Describe your changes here]
Type of Change
Impact
[How does this change the tool's behavior?]
Verification
./etc/Build.sh).Related Issues
[Link issues here]