Skip to content

Commit b4a7133

Browse files
committed
Merge remote-tracking branch 'origin/master' into secure-reduce-escape-slash-reg
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
2 parents 4ca0d18 + 299f301 commit b4a7133

65 files changed

Lines changed: 7593 additions & 3439 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/github-actions-clang-tidy-bazel-post.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,40 @@ jobs:
125125
with:
126126
reviewdog_version: latest
127127

128+
- name: Dump reviewdog-visible env and event payload
129+
# Gated on debug re-runs. Reviewdog emits "this is not PullRequest
130+
# build" and posts nothing for fork PRs even though the synthesized
131+
# pull_request payload is well-formed (verified locally against
132+
# reviewdog v0.21.0). Suspect: step-level `env:` cannot override
133+
# runner-protected GITHUB_EVENT_PATH / GITHUB_EVENT_NAME, so reviewdog
134+
# reads the runner's workflow_run event payload instead of our synth.
135+
# This step proves what reviewdog actually sees on the next debug
136+
# re-run.
137+
if: runner.debug == '1'
138+
env:
139+
GITHUB_EVENT_NAME: pull_request
140+
GITHUB_EVENT_PATH: ${{ steps.event.outputs.event_path }}
141+
GITHUB_SHA: ${{ steps.meta.outputs.head_sha }}
142+
GITHUB_REPOSITORY: ${{ steps.meta.outputs.base_repo }}
143+
run: |
144+
echo "::group::GITHUB_* env visible to next step"
145+
env | grep -E '^(GITHUB_|RUNNER_|REVIEWDOG_)' | sort
146+
echo "::endgroup::"
147+
echo "::group::Synth event file location and content"
148+
echo "steps.event.outputs.event_path = ${{ steps.event.outputs.event_path }}"
149+
echo "Effective GITHUB_EVENT_PATH = ${GITHUB_EVENT_PATH}"
150+
if [ -f "${GITHUB_EVENT_PATH}" ]; then
151+
echo "--- file exists, content: ---"
152+
cat "${GITHUB_EVENT_PATH}"
153+
else
154+
echo "::warning::GITHUB_EVENT_PATH file does not exist"
155+
fi
156+
echo "::endgroup::"
157+
echo "::group::Synth file at literal path (should match above)"
158+
SYNTH="${{ steps.event.outputs.event_path }}"
159+
[ -f "${SYNTH}" ] && cat "${SYNTH}" || echo "missing"
160+
echo "::endgroup::"
161+
128162
- name: Run reviewdog
129163
env:
130164
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -133,7 +167,14 @@ jobs:
133167
GITHUB_SHA: ${{ steps.meta.outputs.head_sha }}
134168
GITHUB_REPOSITORY: ${{ steps.meta.outputs.base_repo }}
135169
run: |
170+
# On debug re-runs add reviewdog's own -log-level=debug so the
171+
# cienv detection trace is visible alongside the env dump above.
172+
LOG_FLAGS=()
173+
if [ "${RUNNER_DEBUG}" = "1" ]; then
174+
LOG_FLAGS+=(-log-level=debug)
175+
fi
136176
reviewdog \
177+
"${LOG_FLAGS[@]}" \
137178
-efm="%E%f:%l:%c: error: %m" \
138179
-efm="%W%f:%l:%c: warning: %m" \
139180
-name="clang-tidy" \

src/dbSta/include/db_sta/dbSta.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ class dbSta : public Sta, public odb::dbDatabaseObserver
206206
bool exclude_buffers,
207207
bool exclude_inverters) const;
208208

209+
// Get the levels of logic for all endpoints.
210+
std::vector<int> levelsOfLogic(bool exclude_buffers,
211+
bool exclude_inverters) const;
212+
209213
utl::Logger* getLogger() { return logger_; }
210214

211215
// Sanity checkers

src/dbSta/src/dbSta.cc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,11 @@ void dbSta::reportTimingHistogram(int num_bins,
817817
histogram.report(/*precision=*/3);
818818
}
819819

820-
void dbSta::reportLogicDepthHistogram(int num_bins,
821-
bool exclude_buffers,
820+
std::vector<int> dbSta::levelsOfLogic(bool exclude_buffers,
822821
bool exclude_inverters) const
823822
{
824-
utl::Histogram<int> histogram(logger_);
825-
823+
std::vector<int> depths;
824+
depths.reserve(sta_->endpoints().size());
826825
sta_->worstSlack(MinMax::max()); // Update timing.
827826
for (sta::Vertex* vertex : sta_->endpoints()) {
828827
int path_length = 0;
@@ -843,9 +842,19 @@ void dbSta::reportLogicDepthHistogram(int num_bins,
843842
}
844843
path = path->prevPath();
845844
}
846-
histogram.addData(path_length);
845+
depths.push_back(path_length);
847846
}
847+
return depths;
848+
}
848849

850+
void dbSta::reportLogicDepthHistogram(int num_bins,
851+
bool exclude_buffers,
852+
bool exclude_inverters) const
853+
{
854+
utl::Histogram<int> histogram(logger_);
855+
for (int depth : levelsOfLogic(exclude_buffers, exclude_inverters)) {
856+
histogram.addData(depth);
857+
}
849858
histogram.generateBins(num_bins);
850859
histogram.report();
851860
}

src/est/src/EstimateParasitics.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,31 +1017,49 @@ void EstimateParasitics::insertViaResistances(odb::dbTechLayer* pin_layer,
10171017
if (cut_layer->getType() != odb::dbTechLayerType::CUT) {
10181018
continue;
10191019
}
1020-
sta::ParasiticNode* mid_node = parasitics->ensureParasiticNode(
1021-
parasitic, net, ++max_node_index, network_);
1022-
10231020
const double cut_res
10241021
= std::max(layer_res_[layer_idx][corner->index()], 1.0e-3);
10251022

1023+
// Resolve from/to endpoints first, so we only allocate a new mid_node
1024+
// when this iteration actually needs one. On the terminal iteration the
1025+
// resistor connects directly to the pin or tree anchor; if we had
1026+
// pre-allocated a mid_node here it would never be wired up and would
1027+
// become a floating ParasiticNode (singular row in the conductance
1028+
// matrix for Prima/CCS).
10261029
sta::ParasiticNode* from_node = prev_node;
1027-
sta::ParasiticNode* to_node = mid_node;
1030+
sta::ParasiticNode* to_node = nullptr;
1031+
bool need_new_mid = true;
10281032
if (pin_is_below) {
10291033
if (layer_idx - 1 == pin_layer_idx) {
10301034
from_node = pin_node;
1031-
} else if (layer_idx + 1 == tree_layer_idx) {
1035+
}
1036+
if (layer_idx + 1 == tree_layer_idx) {
10321037
to_node = node;
1038+
need_new_mid = false;
10331039
}
10341040
} else {
10351041
if (layer_idx - 1 == tree_layer_idx) {
10361042
from_node = node;
1037-
} else if (layer_idx + 1 == pin_layer_idx) {
1043+
}
1044+
if (layer_idx + 1 == pin_layer_idx) {
10381045
to_node = pin_node;
1046+
need_new_mid = false;
10391047
}
10401048
}
10411049

1050+
sta::ParasiticNode* mid_node = nullptr;
1051+
if (need_new_mid) {
1052+
mid_node = parasitics->ensureParasiticNode(
1053+
parasitic, net, ++max_node_index, network_);
1054+
to_node = mid_node;
1055+
}
1056+
10421057
parasitics->makeResistor(
10431058
parasitic, resistor_id++, cut_res, from_node, to_node);
10441059

1060+
// On the terminal iteration mid_node is nullptr and prev_node is unused
1061+
// by the next iteration (there is none); on every other iteration we
1062+
// chain through the freshly allocated mid_node.
10451063
prev_node = mid_node;
10461064
}
10471065
}

src/est/src/MakeWireParasitics.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33

44
#include "MakeWireParasitics.h"
55

6+
#include <algorithm>
67
#include <cmath>
78
#include <cstddef>
9+
#include <iterator>
10+
#include <map>
811
#include <string>
12+
#include <utility>
913
#include <vector>
1014

1115
#include "db_sta/SpefWriter.hh"
@@ -242,6 +246,67 @@ void MakeWireParasitics::makeRouteParasitics(sta::Parasitics* parasitics,
242246
parasitics->makeResistor(parasitic, resistor_id_++, res, n1, n2);
243247
parasitics->incrCap(n2, cap / 2.0);
244248
}
249+
250+
// Workaround: implicit-via post-pass.
251+
//
252+
// GRT does not always emit an explicit isVia=true segment at every
253+
// layer transition along a route; coincident endpoints on adjacent
254+
// routing levels are treated as implicitly connected. EST has historically
255+
// taken GRoute literally, so any layer transition without an explicit via
256+
// segment ends up as two distinct ParasiticNodes at the same (x, y) with
257+
// no resistor between them -- a disconnected island in the parasitic
258+
// network. That goes unnoticed by pi-Elmore-based delay calculators but
259+
// produces a singular conductance matrix in Prima/CCS.
260+
//
261+
// Close the contract gap here: scan node_map for coincident endpoints on
262+
// adjacent routing levels and, when no resistor already bridges them,
263+
// insert one with the appropriate cut-layer resistance.
264+
std::vector<std::pair<sta::ParasiticNode*, sta::ParasiticNode*>>
265+
connected_pairs;
266+
for (sta::ParasiticResistor* r : parasitics->resistors(parasitic)) {
267+
sta::ParasiticNode* a = parasitics->node1(r);
268+
sta::ParasiticNode* b = parasitics->node2(r);
269+
connected_pairs.emplace_back(std::minmax(a, b));
270+
}
271+
std::ranges::sort(connected_pairs);
272+
273+
if (!node_map.empty()) {
274+
auto prev_it = node_map.begin();
275+
for (auto it = std::next(prev_it); it != node_map.end();
276+
prev_it = it, ++it) {
277+
const auto& prev_pt = prev_it->first;
278+
const auto& curr_pt = it->first;
279+
if (prev_pt.x() != curr_pt.x() || prev_pt.y() != curr_pt.y()) {
280+
continue;
281+
}
282+
if (curr_pt.layer() != prev_pt.layer() + 1) {
283+
// Not adjacent routing levels -- skipping signals that an
284+
// intermediate routing-level node is missing entirely, which is a
285+
// different bug worth surfacing rather than silently bridging.
286+
continue;
287+
}
288+
sta::ParasiticNode* lo_node = prev_it->second;
289+
sta::ParasiticNode* hi_node = it->second;
290+
const std::pair<sta::ParasiticNode*, sta::ParasiticNode*> pair
291+
= std::minmax(lo_node, hi_node);
292+
auto bound_it = std::ranges::lower_bound(connected_pairs, pair);
293+
if (bound_it != connected_pairs.end() && *bound_it == pair) {
294+
continue;
295+
}
296+
odb::dbTechLayer* lower_routing
297+
= tech_->findRoutingLayer(prev_pt.layer());
298+
odb::dbTechLayer* cut_layer
299+
= lower_routing ? lower_routing->getUpperLayer() : nullptr;
300+
if (cut_layer == nullptr) {
301+
// Top of stack or unresolved -- do not silently invent a resistor.
302+
continue;
303+
}
304+
const float via_R = getCutLayerRes(cut_layer, corner);
305+
parasitics->makeResistor(
306+
parasitic, resistor_id_++, via_R, lo_node, hi_node);
307+
connected_pairs.insert(bound_it, pair);
308+
}
309+
}
245310
}
246311

247312
void MakeWireParasitics::makeParasiticsToPins(

0 commit comments

Comments
 (0)