Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ppl: use constraints, mirrored pins and pin groups stored in odb #6824

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
28 changes: 28 additions & 0 deletions src/odb/include/odb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,24 @@ class dbBlock : public dbObject
///
void addBTermGroup(const std::vector<dbBTerm*>& bterms, bool order);

///
/// Find the rectangle corresponding to the constraint region in a specific
/// edge of the die area.
///
Rect findConstraintRegion(const std::string& edge, int begin, int end);

///
/// Add region constraint for dbBTerms according to their IO type.
///
void addBTermDirectionConstraint(const std::string& direction,
const Rect& constraint_region);

///
/// Add region constraint for dbBTerms according to their names.
///
void addBTermNamesConstraint(const std::vector<dbBTerm*>& bterms,
const Rect& constraint_region);

///
/// Get all the instance-terminals of this block.
///
Expand Down Expand Up @@ -1867,6 +1885,11 @@ class dbBTerm : public dbObject
///
std::optional<Rect> getConstraintRegion();

///
/// Reset constraint region.
///
void resetConstraintRegion();

///
/// Set the bterm which position is mirrored to this bterm
///
Expand All @@ -1876,6 +1899,11 @@ class dbBTerm : public dbObject
/// Get the bterm that is mirrored to this bterm
///
dbBTerm* getMirroredBTerm();

///
/// Returns true if the current BTerm has a mirrored BTerm.
///
bool hasMirroredBTerm();
};

///////////////////////////////////////////////////////////////////////////////
Expand Down
12 changes: 12 additions & 0 deletions src/odb/src/db/dbBTerm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,12 @@ std::optional<Rect> dbBTerm::getConstraintRegion()
return bterm->_constraint_region;
}

void dbBTerm::resetConstraintRegion()
{
_dbBTerm* bterm = (_dbBTerm*) this;
bterm->_constraint_region.mergeInit();
}

void dbBTerm::setMirroredBTerm(dbBTerm* mirrored_bterm)
{
_dbBTerm* bterm = (_dbBTerm*) this;
Expand All @@ -988,4 +994,10 @@ dbBTerm* dbBTerm::getMirroredBTerm()
return (dbBTerm*) mirrored_bterm;
}

bool dbBTerm::hasMirroredBTerm()
{
_dbBTerm* bterm = (_dbBTerm*) this;
return bterm->_mirrored_bterm != 0;
}

} // namespace odb
55 changes: 55 additions & 0 deletions src/odb/src/db/dbBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,61 @@ void dbBlock::addBTermGroup(const std::vector<dbBTerm*>& bterms, bool order)
block->_bterm_groups.push_back(std::move(group));
}

Rect dbBlock::findConstraintRegion(const std::string& edge, int begin, int end)
{
Rect constraint_region;
const Rect& die_bounds = getDieArea();
if (edge == "bottom") {
constraint_region = Rect(begin, die_bounds.yMin(), end, die_bounds.yMin());
} else if (edge == "top") {
constraint_region = Rect(begin, die_bounds.yMax(), end, die_bounds.yMax());
} else if (edge == "left") {
constraint_region = Rect(die_bounds.xMin(), begin, die_bounds.xMin(), end);
} else if (edge == "right") {
constraint_region = Rect(die_bounds.xMax(), begin, die_bounds.xMax(), end);
}

return constraint_region;
}

void dbBlock::addBTermDirectionConstraint(const std::string& direction,
const Rect& constraint_region)
{
odb::dbIoType dir;
if (direction == "input") {
dir = odb::dbIoType::INPUT;
} else if (direction == "output") {
dir = odb::dbIoType::OUTPUT;
} else if (direction == "inout") {
dir = odb::dbIoType::INOUT;
} else {
dir = odb::dbIoType::FEEDTHRU;
}

for (dbBTerm* bterm : getBTerms()) {
if (bterm->getIoType().getValue() == dir.getValue()) {
bterm->setConstraintRegion(constraint_region);
}
}
}

void dbBlock::addBTermNamesConstraint(const std::vector<dbBTerm*>& bterms,
const Rect& constraint_region)
{
for (dbBTerm* bterm : bterms) {
const auto& bterm_constraint = bterm->getConstraintRegion();
if (bterm_constraint && bterm_constraint.value() != constraint_region) {
getImpl()->getLogger()->error(
utl::ODB,
239,
"Pin {} is assigned to multiple constraints.",
bterm->getName());
} else {
bterm->setConstraintRegion(constraint_region);
}
}
}

dbSet<dbITerm> dbBlock::getITerms()
{
_dbBlock* block = (_dbBlock*) this;
Expand Down
185 changes: 185 additions & 0 deletions src/odb/src/db/odb.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -676,4 +676,189 @@ proc design_is_routed { args } {
set block [$chip getBlock]

return [$block designIsRouted [info exists flags(-verbose)]]
}

sta::define_cmd_args "set_io_pin_constraint" {[-direction direction] \
[-pin_names names] \
[-region region] \
[-mirrored_pins pins] \
[-group]
[-order]}

proc set_io_pin_constraint { args } {
sta::parse_key_args "set_io_pin_constraint" args \
keys {-direction -pin_names -region -mirrored_pins} \
flags {-group -order}

sta::check_argc_eq0 "set_io_pin_constraint" $args

set tech [ord::get_db_tech]
set block [ord::get_db_block]
set lef_units [$tech getLefUnits]

if { [info exists keys(-region)] && [info exists keys(-mirrored_pins)] } {
utl::error PPL 83 "Both -region and -mirrored_pins constraints not allowed."
}

if { [info exists keys(-mirrored_pins)] && [info exists flags(-group)] } {
utl::error PPL 87 "Both -mirrored_pins and -group constraints not allowed."
}

if { [info exists keys(-region)] } {
set region $keys(-region)
if { [regexp -all {(top|bottom|left|right):(.+)} $region - edge interval] } {
if { [regexp -all {([0-9]+[.]*[0-9]*|[*]+)-([0-9]+[.]*[0-9]*|[*]+)} $interval - begin end] } {
if { $begin == "*" } {
set begin [ppl::get_edge_extreme "-region" 1 $edge]
} else {
set begin [ord::microns_to_dbu $begin]
}

if { $end == "*" } {
set end [ppl::get_edge_extreme "-region" 0 $edge]
} else {
set end [ord::microns_to_dbu $end]
}
} elseif { $interval == "*" } {
set begin [ppl::get_edge_extreme "-region" 1 $edge]
set end [ppl::get_edge_extreme "-region" 0 $edge]
}

if { [info exists keys(-direction)] && [info exists keys(-pin_names)] } {
utl::error PPL 16 "Both -direction and -pin_names constraints not allowed."
}

if { [info exists keys(-direction)] } {
set direction $keys(-direction)
odb::add_direction_constraint $direction $edge $begin $end
}

if { [info exists keys(-pin_names)] } {
set names $keys(-pin_names)
odb::add_names_constraint $names $edge $begin $end
}
} elseif { [regexp -all {(up):(.*)} $region - edge box] } {
if { $box == "*" } {
set die_area [$block getDieArea]
set llx [$die_area xMin]
set lly [$die_area yMin]
set urx [$die_area xMax]
set ury [$die_area yMax]
} elseif {
[regexp -all \
{([0-9]+[.]*[0-9]*) ([0-9]+[.]*[0-9]*) ([0-9]+[.]*[0-9]*) ([0-9]+[.]*[0-9]*)} \
$box - llx lly urx ury]
} {
set llx [ord::microns_to_dbu $llx]
set lly [ord::microns_to_dbu $lly]
set urx [ord::microns_to_dbu $urx]
set ury [ord::microns_to_dbu $ury]
} else {
utl::error PPL 59 "Box at top layer must have 4 values (llx lly urx ury)."
}

if { [info exists keys(-pin_names)] } {
set names $keys(-pin_names)
ppl::add_pins_to_top_layer "set_io_pin_constraint" $names $llx $lly $urx $ury
}
} else {
utl::warn PPL 73 "Constraint with region $region has an invalid edge."
}
}

if { [info exists flags(-group)] } {
if { [info exists keys(-pin_names)] } {
set group $keys(-pin_names)
} else {
utl::error PPL 58 "The -pin_names argument is required when using -group flag."
}

set pin_list [ppl::parse_pin_names "place_pins -group_pins" $group]
if { [llength $pin_list] != 0 } {
odb::add_pin_group $pin_list [info exists flags(-order)]
}
} elseif { [info exists flags(-order)] } {
utl::error PPL 95 "-order cannot be used without -group."
}

if { [info exists keys(-mirrored_pins)] } {
set mirrored_pins $keys(-mirrored_pins)
if { [llength $mirrored_pins] % 2 != 0 } {
utl::error PPL 81 "List of pins must have an even number of pins."
}

foreach {pin1 pin2} $mirrored_pins {
set bterm1 [ppl::parse_pin_names "set_io_pin_constraint -mirrored_pins" $pin1]
set bterm2 [ppl::parse_pin_names "set_io_pin_constraint -mirrored_pins" $pin2]
odb::add_mirrored_pins $bterm1 $bterm2
}
}
}

sta::define_cmd_args "clear_io_pin_constraints" {}

proc clear_io_pin_constraints { args } {
sta::parse_key_args "clear_io_pin_constraints" args keys {} flags {}
ppl::clear_constraints
}

namespace eval odb {

proc add_direction_constraint { dir edge begin end } {
set block [get_block]

set direction [parse_direction "add_direction_constraint" $dir]
set constraint_region [$block findConstraintRegion $edge $begin $end]
$block addBTermDirectionConstraint $direction $constraint_region
}

proc add_names_constraint { names edge begin end } {
set block [get_block]

set pin_list [ppl::parse_pin_names "set_io_pin_constraints" $names]
set constraint_region [$block findConstraintRegion $edge $begin $end]
$block addBTermNamesConstraint $pin_list $constraint_region
}

proc add_pin_group {pin_list order} {
set block [get_block]

$block addBTermGroup $pin_list $order
}

proc add_mirrored_pins {bterm1 bterm2} {
if {$bterm1 != "NULL" && $bterm2 != "NULL"} {
$bterm1 setMirroredBTerm $bterm2
$bterm2 setMirroredBTerm $bterm1
}
}

proc parse_direction { cmd direction } {
if {
[regexp -nocase -- {^INPUT$} $direction] ||
[regexp -nocase -- {^OUTPUT$} $direction] ||
[regexp -nocase -- {^INOUT$} $direction] ||
[regexp -nocase -- {^FEEDTHRU$} $direction]
} {
return [string tolower $direction]
} else {
utl::error ODB 12 "$cmd: Invalid bterm direction."
}
}

proc check_edge { edge } {
if {
$edge != "top" && $edge != "bottom" &&
$edge != "left" && $edge != "right"
} {
utl::error ODB 11 "$cmd: $edge is an invalid edge. Use top, bottom, left or right."
}
return $edge
}

proc get_block {} {
set db [ord::get_db]
set chip [$db getChip]
return [$chip getBlock]
}
}
1 change: 0 additions & 1 deletion src/ppl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ If you are a developer, you might find these useful. More details can be found i
| `parse_pin_names` | Parse pin names. |
| `get_edge_extreme` | Get extremes of edge. |
| `exclude_intervals` | Set exclude interval. |
| `add_pins_to_constraint` | Add pins to constrained region. |
| `add_pins_to_top_layer` | Add pins to top layer. |

## Example scripts
Expand Down
22 changes: 3 additions & 19 deletions src/ppl/include/ppl/IOPlacer.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ using utl::Logger;
// A list of pins that will be placed together in the die boundary
using PinSet = std::set<odb::dbBTerm*>;
using PinList = std::vector<odb::dbBTerm*>;
using MirroredPins = std::unordered_map<odb::dbBTerm*, odb::dbBTerm*>;

struct PinGroup
{
PinList pins;
bool order;
};

struct PinGroupByIndex
{
Expand Down Expand Up @@ -131,16 +124,9 @@ class IOPlacer
Parameters* getParameters() { return parms_.get(); }
int64 computeIONetsHPWL();
void excludeInterval(Edge edge, int begin, int end);
void addNamesConstraint(PinSet* pins, Edge edge, int begin, int end);
void addDirectionConstraint(Direction direction,
Edge edge,
int begin,
int end);
void addTopLayerConstraint(PinSet* pins, const odb::Rect& region);
void addMirroredPins(odb::dbBTerm* bterm1, odb::dbBTerm* bterm2);
void addHorLayer(odb::dbTechLayer* layer);
void addVerLayer(odb::dbTechLayer* layer);
void addPinGroup(PinList* group, bool order);
void addTopLayerPinPattern(odb::dbTechLayer* layer,
int x_step,
int y_step,
Expand Down Expand Up @@ -197,9 +183,7 @@ class IOPlacer
bool is_group);
std::string getSlotsLocation(Edge edge, bool top_layer);
int placeFallbackPins(bool random);
void assignMirroredPins(IOPin& io_pin,
MirroredPins& mirrored_pins,
std::vector<IOPin>& assignment);
void assignMirroredPins(IOPin& io_pin, std::vector<IOPin>& assignment);
int getSlotIdxByPosition(const odb::Point& position,
int layer,
std::vector<Slot>& slots);
Expand All @@ -223,6 +207,8 @@ class IOPlacer
std::vector<Section> createSectionsPerConstraint(Constraint& constraint);
void getPinsFromDirectionConstraint(Constraint& constraint);
void initMirroredPins(bool annealing = false);
Interval findIntervalFromRect(const odb::Rect& rect);
void getConstraintsFromDB();
void initConstraints(bool annealing = false);
void sortConstraints();
void checkPinsInMultipleConstraints();
Expand Down Expand Up @@ -313,8 +299,6 @@ class IOPlacer

std::vector<Interval> excluded_intervals_;
std::vector<Constraint> constraints_;
std::vector<PinGroup> pin_groups_;
MirroredPins mirrored_pins_;
FallbackPins fallback_pins_;
std::map<int, std::vector<odb::Rect>> layer_fixed_pins_shapes_;

Expand Down
Loading