Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/drt/src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,7 @@ void io::Parser::createNDR(odb::dbTechNonDefaultRule* ndr)
== odb::dbTechLayerType::CUT) {
continue;
}
if (via->getViaLayerRule(i)->getLayer()->getNumber() / 2 < z) {
z = via->getViaLayerRule(i)->getLayer()->getNumber() / 2;
}
z = std::min(via->getViaLayerRule(i)->getLayer()->getNumber() / 2, z);
}
fnd->addViaRule(getTech()->getViaRule(via->getName()), z);
}
Expand Down
9 changes: 6 additions & 3 deletions src/drt/src/pa/FlexPA.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ class FlexPA
std::map<frCoord, frAccessPointEnum>& y_coords,
frAccessPointEnum lower_type,
frAccessPointEnum upper_type,
bool is_macro_cell_pin);
bool is_macro_cell_pin,
bool is_bterm = false);

/**
* @brief Generates an OnGrid access coordinate (on or half track)
Expand Down Expand Up @@ -420,7 +421,8 @@ class FlexPA
void genAPEnclosedBoundary(std::map<frCoord, frAccessPointEnum>& coords,
const gtl::rectangle_data<frCoord>& rect,
frLayerNum layer_num,
bool is_curr_layer_horz);
bool is_curr_layer_horz,
bool is_bterm = false);

/**
* @brief Calls the other genAP functions according to the informed cost
Expand All @@ -441,7 +443,8 @@ class FlexPA
frLayerNum base_layer_num,
frLayerNum layer_num,
const gtl::rectangle_data<frCoord>& rect,
int offset = 0);
int offset = 0,
bool is_bterm = false);

bool OnlyAllowOnGridAccess(frLayerNum layer_num, bool is_macro_cell_pin);

Expand Down
177 changes: 138 additions & 39 deletions src/drt/src/pa/FlexPA_acc_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,14 @@ void FlexPA::genViaEnclosedCoords(std::map<frCoord, frAccessPointEnum>& coords,
const auto rect_width = gtl::delta(rect, gtl::HORIZONTAL);
const auto rect_height = gtl::delta(rect, gtl::VERTICAL);
frVia via(via_def);
const odb::Rect box = via.getLayer1BBox();
odb::Rect box;
if (via_def->getLayer1Num() == layer_num) {
box = via.getLayer1BBox();
} else if (via_def->getLayer2Num() == layer_num) {
box = via.getLayer2BBox();
} else {
return;
}
const auto via_width = box.dx();
const auto via_height = box.dy();
if (via_width > rect_width || via_height > rect_height) {
Expand Down Expand Up @@ -150,19 +157,39 @@ void FlexPA::genViaEnclosedCoords(std::map<frCoord, frAccessPointEnum>& coords,
void FlexPA::genAPEnclosedBoundary(std::map<frCoord, frAccessPointEnum>& coords,
const gtl::rectangle_data<frCoord>& rect,
const frLayerNum layer_num,
const bool is_curr_layer_horz)
const bool is_curr_layer_horz,
const bool is_bterm)
{
if (layer_num + 1 > getDesign()->getTech()->getTopLayerNum()) {
return;
}
// hardcode first two single vias
const int max_num_via_trial = 2;
int cnt = 0;
for (auto& [tup, via] : layer_num_to_via_defs_[layer_num + 1][1]) {
genViaEnclosedCoords(coords, rect, via, layer_num, is_curr_layer_horz);
cnt++;
if (cnt >= max_num_via_trial) {
break;

auto process_cut_layer = [&](int cut_layer_num, int& counter) {
if (layer_num_to_via_defs_.find(cut_layer_num)
== layer_num_to_via_defs_.end()) {
return;
}
for (auto& [tup, via] : layer_num_to_via_defs_[cut_layer_num][1]) {
genViaEnclosedCoords(coords, rect, via, layer_num, is_curr_layer_horz);
counter++;
if (counter >= max_num_via_trial) {
break;
}
}
};

if (layer_num + 1 <= getDesign()->getTech()->getTopLayerNum()) {
process_cut_layer(layer_num + 1, cnt);
}

if (is_bterm) {
int down_via_cnt = 0;
const int bottom_layer = getDesign()->getTech()->getBottomLayerNum();
for (int l = layer_num - 1; l >= layer_num - 3 && l >= bottom_layer; l--) {
process_cut_layer(l, down_via_cnt);
if (down_via_cnt >= max_num_via_trial) {
break;
}
}
}
}
Expand All @@ -174,7 +201,8 @@ void FlexPA::genAPCosted(
const frLayerNum base_layer_num,
const frLayerNum layer_num,
const gtl::rectangle_data<frCoord>& rect,
const int offset)
const int offset,
const bool is_bterm)
{
auto layer = getDesign()->getTech()->getLayer(layer_num);
const bool is_curr_layer_horz = layer->isHorizontal();
Expand All @@ -195,7 +223,8 @@ void FlexPA::genAPCosted(
break;

case (frAccessPointEnum::EncOpt):
genAPEnclosedBoundary(coords, rect, base_layer_num, is_curr_layer_horz);
genAPEnclosedBoundary(
coords, rect, base_layer_num, is_curr_layer_horz, is_bterm);
break;

case (frAccessPointEnum::NearbyGrid):
Expand Down Expand Up @@ -234,9 +263,10 @@ void FlexPA::createSingleAccessPoint(
}
auto ap = std::make_unique<frAccessPoint>(fpt, layer_num);

ap->setMultipleAccesses(frDirEnumPlanar, allow_planar);
bool local_allow_planar = allow_planar;
ap->setMultipleAccesses(frDirEnumPlanar, local_allow_planar);

if (allow_planar) {
if (local_allow_planar) {
const auto lower_layer = getDesign()->getTech()->getLayer(layer_num);
// rectonly forbid wrongway planar access
// rightway on grid only forbid off track rightway planar access
Expand Down Expand Up @@ -321,6 +351,27 @@ void FlexPA::createMultipleAccessPoints(
auto layer = getDesign()->getTech()->getLayer(layer_num);
bool allow_via = !isIOTerm(inst_term);
bool allow_planar = true;

if (layer->getLef58RectOnlyConstraint()) {
bool is_width_aligned = false;
const auto layer_width = layer->getWidth();
if (layer->getDir() == dbTechLayerDir::HORIZONTAL) {
if (gtl::delta(rect, gtl::VERTICAL) == layer_width) {
is_width_aligned = true;
}
} else if (layer->getDir() == dbTechLayerDir::VERTICAL) {
if (gtl::delta(rect, gtl::HORIZONTAL) == layer_width) {
is_width_aligned = true;
}
}

if (!is_width_aligned) {
allow_planar = false;
// Enable via access as fallback if planar is blocked
allow_via = true;
}
}

// only VIA_ACCESS_LAYERNUM layer can have via access
if (isStdCellTerm(inst_term)) {
if ((layer_num >= router_cfg_->VIAINPIN_BOTTOMLAYERNUM
Expand Down Expand Up @@ -371,7 +422,8 @@ void FlexPA::genAPsFromRect(const gtl::rectangle_data<frCoord>& rect,
std::map<frCoord, frAccessPointEnum>& y_coords,
const frAccessPointEnum lower_type,
const frAccessPointEnum upper_type,
const bool is_macro_cell_pin)
const bool is_macro_cell_pin,
const bool is_bterm)
{
if (OnlyAllowOnGridAccess(layer_num, is_macro_cell_pin)
&& upper_type != frAccessPointEnum::OnGrid) {
Expand Down Expand Up @@ -436,7 +488,8 @@ void FlexPA::genAPsFromRect(const gtl::rectangle_data<frCoord>& rect,
layer_num,
second_layer_num,
rect,
offset);
offset,
is_bterm);
}
}
if (!use_center_line) {
Expand All @@ -447,7 +500,9 @@ void FlexPA::genAPsFromRect(const gtl::rectangle_data<frCoord>& rect,
layer1_track_coords,
layer_num,
layer_num,
rect);
rect,
0,
is_bterm);
}
}
} else {
Expand Down Expand Up @@ -484,6 +539,7 @@ void FlexPA::genAPsFromLayerShapes(
{
// IO term is treated as the MacroCellPin as the top block
bool is_macro_cell_pin = isMacroCellTerm(inst_term) || isIOTerm(inst_term);
bool is_bterm = (inst_term == nullptr);

std::vector<gtl::rectangle_data<frCoord>> maxrects;
gtl::get_max_rectangles(maxrects, layer_shapes);
Expand All @@ -497,7 +553,8 @@ void FlexPA::genAPsFromLayerShapes(
y_coords,
lower_type,
upper_type,
is_macro_cell_pin);
is_macro_cell_pin,
is_bterm);

layer_rect_to_coords[layer_num].push_back(
{bbox_rect, {x_coords, y_coords}});
Expand Down Expand Up @@ -635,6 +692,7 @@ bool FlexPA::filterPlanarAccess(
frInstTerm* inst_term)
{
const odb::Point begin_point = ap->getPoint();

// skip viaonly access
if (!ap->hasAccess(dir)) {
return false;
Expand Down Expand Up @@ -678,6 +736,7 @@ bool FlexPA::filterPlanarAccess(

const bool no_drv
= isPlanarViolationFree(ap, pin, ps.get(), inst_term, begin_point, layer);

ap->setAccess(dir, no_drv);

return no_drv;
Expand Down Expand Up @@ -886,14 +945,35 @@ void FlexPA::filterViaAccess(

if (via_defs.empty()) { // no via map entry
// hardcode first two single vias
for (auto& [tup, via_def] : layer_num_to_via_defs_[layer_num + 1][1]) {
if (inst_term && inst_term->isStubborn()
&& avoid_via_defs_.contains(via_def)) {
continue;
// UP Vias
if (layer_num_to_via_defs_.find(layer_num + 1)
!= layer_num_to_via_defs_.end()) {
for (auto& [tup, via_def] : layer_num_to_via_defs_[layer_num + 1][1]) {
if (inst_term && inst_term->isStubborn()
&& avoid_via_defs_.contains(via_def)) {
continue;
}
via_defs.emplace_back(via_defs.size(), via_def);
if (via_defs.size() >= max_num_via_trial && !deep_search) {
break;
}
}
via_defs.emplace_back(via_defs.size(), via_def);
if (via_defs.size() >= max_num_via_trial && !deep_search) {
break;
}
// DOWN Vias (Added)
if (!inst_term
|| layer_num + 1 > getDesign()->getTech()->getTopLayerNum()) {
if (layer_num_to_via_defs_.find(layer_num - 1)
!= layer_num_to_via_defs_.end()) {
for (auto& [tup, via_def] : layer_num_to_via_defs_[layer_num - 1][1]) {
if (inst_term && inst_term->isStubborn()
&& avoid_via_defs_.contains(via_def)) {
continue;
}
via_defs.emplace_back(via_defs.size(), via_def);
if (via_defs.size() >= max_num_via_trial * 2 && !deep_search) {
break;
}
}
}
}
}
Expand All @@ -902,6 +982,7 @@ void FlexPA::filterViaAccess(
for (auto& [idx, via_def] : via_defs) {
auto via = std::make_unique<frVia>(via_def, begin_point);
const odb::Rect box = via->getLayer1BBox();

if (inst_term && !deep_search) {
odb::Rect boundary_bbox = inst_term->getInst()->getBoundaryBBox();
if (!boundary_bbox.contains(box)) {
Expand All @@ -920,7 +1001,11 @@ void FlexPA::filterViaAccess(
}
if (checkViaPlanarAccess(ap, via.get(), pin, inst_term, layer_polys)) {
ap->addViaDef(via_def);
ap->setAccess(frDirEnum::U);
if (via_def->getLayer1Num() == layer_num) {
ap->setAccess(frDirEnum::U);
} else {
ap->setAccess(frDirEnum::D);
}
valid_via_count++;
if (valid_via_count >= max_num_via_trial) {
break;
Expand Down Expand Up @@ -969,28 +1054,31 @@ bool FlexPA::checkDirectionalViaAccess(
const std::vector<gtl::polygon_90_data<frCoord>>& layer_polys,
frDirEnum dir)
{
auto upper_layer = getTech()->getLayer(via->getViaDef()->getLayer2Num());
frLayerNum target_layer_num;
if (via->getViaDef()->getLayer1Num() == ap->getLayerNum()) {
target_layer_num = via->getViaDef()->getLayer2Num();
} else {
target_layer_num = via->getViaDef()->getLayer1Num();
}
auto target_layer = getTech()->getLayer(target_layer_num);
const bool vert_dir = (dir == frDirEnum::S || dir == frDirEnum::N);
const bool wrong_dir = (upper_layer->isHorizontal() && vert_dir)
|| (upper_layer->isVertical() && !vert_dir);
auto style = upper_layer->getDefaultSegStyle();
const bool wrong_dir = (target_layer->isHorizontal() && vert_dir)
|| (target_layer->isVertical() && !vert_dir);
auto style = target_layer->getDefaultSegStyle();

if (wrong_dir) {
if (!router_cfg_->USENONPREFTRACKS || upper_layer->isUnidirectional()) {
if (!router_cfg_->USENONPREFTRACKS || target_layer->isUnidirectional()) {
return false;
}
style.setWidth(upper_layer->getWrongDirWidth());
style.setWidth(target_layer->getWrongDirWidth());
}

const odb::Point begin_point = ap->getPoint();
const bool is_block
= inst_term
&& inst_term->getInst()->getMaster()->getMasterType().isBlock();
const odb::Point end_point = genEndPoint(layer_polys,
begin_point,
via->getViaDef()->getLayer2Num(),
dir,
is_block);
const odb::Point end_point
= genEndPoint(layer_polys, begin_point, target_layer_num, dir, is_block);

if (inst_term && inst_term->hasNet()) {
via->addToNet(inst_term->getNet());
Expand All @@ -1006,7 +1094,7 @@ bool FlexPA::checkDirectionalViaAccess(
ps->setPoints(begin_point, end_point);
style.setBeginStyle(frcTruncateEndStyle, 0);
}
ps->setLayerNum(upper_layer->getLayerNum());
ps->setLayerNum(target_layer->getLayerNum());
ps->setStyle(style);
if (inst_term && inst_term->hasNet()) {
ps->addToNet(inst_term->getNet());
Expand Down Expand Up @@ -1073,7 +1161,7 @@ bool FlexPA::isViaViolationFree(frAccessPoint* ap,
design_rule_checker.initPA1();
design_rule_checker.main();

const bool no_drv = design_rule_checker.getMarkers().empty();
bool no_drv = design_rule_checker.getMarkers().empty();

if (graphics_) {
graphics_->setViaAP(ap, via, design_rule_checker.getMarkers());
Expand Down Expand Up @@ -1279,6 +1367,17 @@ bool FlexPA::genPinAccessCostBounded(
if (is_std_cell_pin) {
if (ap->getLayerNum() <= router_cfg_->VIA_ACCESS_LAYERNUM
&& !ap->hasAccess(frDirEnum::U)) {
if (inst_term) {
logger_->warn(DRT,
323,
"Filtered AP due to no via access for std cell pin "
"{}/{} at ({}, {}) layer {}",
inst_term->getInst()->getName(),
inst_term->getTerm()->getName(),
ap->getPoint().x(),
ap->getPoint().y(),
ap->getLayerNum());
}
continue;
}
}
Expand Down