Skip to content

Commit 2dfc48e

Browse files
authored
Merge pull request #8099 from AcKoucher/mpl-fixed-macros-packing
mpl: add support for partial automatic macro placement
2 parents 500946e + 29d499b commit 2dfc48e

19 files changed

+1527
-59
lines changed

src/mpl/src/MplObserver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class MplObserver
7474
virtual void setFencePenalty(const PenaltyData& penalty) {}
7575
virtual void setGuidancePenalty(const PenaltyData& penalty) {}
7676
virtual void setMacroBlockagePenalty(const PenaltyData& penalty) {}
77+
virtual void setFixedMacrosPenalty(const PenaltyData& penalty) {}
7778
virtual void setNotchPenalty(const PenaltyData& penalty) {}
7879
virtual void setOutlinePenalty(const PenaltyData& penalty) {}
7980
virtual void setWirelengthPenalty(const PenaltyData& penalty) {}

src/mpl/src/SACoreSoftMacro.cpp

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ SACoreSoftMacro::SACoreSoftMacro(PhysicalHierarchy* tree,
7676
logger_ = logger;
7777
}
7878

79+
void SACoreSoftMacro::findFixedMacros()
80+
{
81+
for (const int macro_id : pos_seq_) {
82+
const SoftMacro& macro = macros_[macro_id];
83+
if (macro.isFixed()) {
84+
fixed_macros_.push_back(macro.getBBox());
85+
}
86+
}
87+
}
88+
7989
void SACoreSoftMacro::run()
8090
{
8191
if (graphics_) {
@@ -93,6 +103,15 @@ void SACoreSoftMacro::run()
93103
}
94104
}
95105

106+
bool SACoreSoftMacro::isValid() const
107+
{
108+
if (!fixed_macros_.empty() && fixed_macros_penalty_ > 0.0f) {
109+
return false;
110+
}
111+
112+
return resultFitsInOutline();
113+
}
114+
96115
// acessors functions
97116
float SACoreSoftMacro::getBoundaryPenalty() const
98117
{
@@ -152,6 +171,10 @@ float SACoreSoftMacro::calNormCost() const
152171
cost += macro_blockage_weight_ * macro_blockage_penalty_
153172
/ norm_macro_blockage_penalty_;
154173
}
174+
if (norm_fixed_macros_penalty_ > 0.0) {
175+
cost += fixed_macros_weight_ * fixed_macros_penalty_
176+
/ norm_fixed_macros_penalty_;
177+
}
155178
if (norm_notch_penalty_ > 0.0) {
156179
cost += notch_weight_ * notch_penalty_ / norm_notch_penalty_;
157180
}
@@ -167,6 +190,7 @@ void SACoreSoftMacro::calPenalty()
167190
calBoundaryPenalty();
168191
calMacroBlockagePenalty();
169192
calNotchPenalty();
193+
calFixedMacrosPenalty();
170194
if (graphics_) {
171195
graphics_->setAreaPenalty(
172196
{"Area", core_weights_.area, getAreaPenalty(), norm_area_penalty_});
@@ -268,6 +292,7 @@ void SACoreSoftMacro::restoreState()
268292
void SACoreSoftMacro::initialize()
269293
{
270294
initSequencePair();
295+
findFixedMacros();
271296

272297
std::vector<float> outline_penalty_list;
273298
std::vector<float> wirelength_list;
@@ -277,6 +302,7 @@ void SACoreSoftMacro::initialize()
277302
std::vector<float> macro_blockage_penalty_list;
278303
std::vector<float> notch_penalty_list;
279304
std::vector<float> area_penalty_list;
305+
std::vector<float> fixed_macros_penalty_list;
280306
std::vector<float> width_list;
281307
std::vector<float> height_list;
282308

@@ -298,6 +324,7 @@ void SACoreSoftMacro::initialize()
298324
boundary_penalty_list.push_back(boundary_penalty_);
299325
macro_blockage_penalty_list.push_back(macro_blockage_penalty_);
300326
notch_penalty_list.push_back(notch_penalty_);
327+
fixed_macros_penalty_list.push_back(fixed_macros_penalty_);
301328
}
302329
graphics_ = save_graphics;
303330

@@ -309,6 +336,7 @@ void SACoreSoftMacro::initialize()
309336
norm_boundary_penalty_ = calAverage(boundary_penalty_list);
310337
norm_macro_blockage_penalty_ = calAverage(macro_blockage_penalty_list);
311338
norm_notch_penalty_ = calAverage(notch_penalty_list);
339+
norm_fixed_macros_penalty_ = calAverage(fixed_macros_penalty_list);
312340

313341
// Reset penalites if lower than threshold
314342

@@ -344,6 +372,10 @@ void SACoreSoftMacro::initialize()
344372
norm_notch_penalty_ = 1.0;
345373
}
346374

375+
if (norm_fixed_macros_penalty_ <= 1e-4) {
376+
norm_fixed_macros_penalty_ = 1.0;
377+
}
378+
347379
// Calculate initial temperature
348380
std::vector<float> cost_list;
349381
for (int i = 0; i < outline_penalty_list.size(); i++) {
@@ -356,6 +388,7 @@ void SACoreSoftMacro::initialize()
356388
boundary_penalty_ = boundary_penalty_list[i];
357389
macro_blockage_penalty_ = macro_blockage_penalty_list[i];
358390
notch_penalty_ = notch_penalty_list[i];
391+
fixed_macros_penalty_ = fixed_macros_penalty_list[i];
359392
cost_list.push_back(calNormCost());
360393
}
361394
float delta_cost = 0.0;
@@ -383,12 +416,17 @@ void SACoreSoftMacro::calBoundaryPenalty()
383416
return;
384417
}
385418

386-
int tot_num_macros = 0;
419+
int number_of_movable_macros = 0;
387420
for (const auto& macro_id : pos_seq_) {
388-
tot_num_macros += macros_[macro_id].getNumMacro();
421+
const SoftMacro& soft_macro = macros_[macro_id];
422+
if (soft_macro.isFixed()) {
423+
continue;
424+
}
425+
426+
number_of_movable_macros += soft_macro.getNumMacro();
389427
}
390428

391-
if (tot_num_macros <= 0) {
429+
if (number_of_movable_macros == 0) {
392430
return;
393431
}
394432

@@ -397,23 +435,28 @@ void SACoreSoftMacro::calBoundaryPenalty()
397435
float x_dist_from_root = 0.0f, y_dist_from_root = 0.0f;
398436

399437
for (const auto& macro_id : pos_seq_) {
400-
if (macros_[macro_id].getNumMacro() > 0) {
401-
global_lx = macros_[macro_id].getX() + outline_.xMin() - root_->getX();
402-
global_ly = macros_[macro_id].getY() + outline_.yMin() - root_->getY();
403-
global_ux = global_lx + macros_[macro_id].getWidth();
404-
global_uy = global_ly + macros_[macro_id].getHeight();
438+
const SoftMacro& soft_macro = macros_[macro_id];
439+
if (soft_macro.isFixed()) {
440+
continue;
441+
}
442+
443+
if (soft_macro.getNumMacro() > 0) {
444+
global_lx = soft_macro.getX() + outline_.xMin() - root_->getX();
445+
global_ly = soft_macro.getY() + outline_.yMin() - root_->getY();
446+
global_ux = global_lx + soft_macro.getWidth();
447+
global_uy = global_ly + soft_macro.getHeight();
405448

406449
x_dist_from_root
407450
= std::min(global_lx, std::abs(root_->getWidth() - global_ux));
408451
y_dist_from_root
409452
= std::min(global_ly, std::abs(root_->getHeight() - global_uy));
410453

411454
boundary_penalty_ += std::min(x_dist_from_root, y_dist_from_root)
412-
* macros_[macro_id].getNumMacro();
455+
* soft_macro.getNumMacro();
413456
}
414457
}
415458
// normalization
416-
boundary_penalty_ = boundary_penalty_ / tot_num_macros;
459+
boundary_penalty_ = boundary_penalty_ / number_of_movable_macros;
417460
if (graphics_) {
418461
graphics_->setBoundaryPenalty({"Boundary",
419462
boundary_weight_,
@@ -474,6 +517,42 @@ void SACoreSoftMacro::calMacroBlockagePenalty()
474517
}
475518
}
476519

520+
void SACoreSoftMacro::calFixedMacrosPenalty()
521+
{
522+
if (fixed_macros_.empty()) {
523+
return;
524+
}
525+
526+
fixed_macros_penalty_ = 0.0f;
527+
528+
for (const Rect& fixed_macro : fixed_macros_) {
529+
for (const int macro_id : pos_seq_) {
530+
const SoftMacro& macro = macros_[macro_id];
531+
532+
// Skip the current fixed macro itself and unneeded computation.
533+
if (macro.isFixed()) {
534+
continue;
535+
}
536+
537+
Tiling overlap_shape = computeOverlapShape(fixed_macro, macro.getBBox());
538+
539+
// If any of the dimensions is negative, then there's no overlap.
540+
if (overlap_shape.width() < 0 || overlap_shape.height() < 0) {
541+
continue;
542+
}
543+
544+
fixed_macros_penalty_ += overlap_shape.width() * overlap_shape.height();
545+
}
546+
}
547+
548+
if (graphics_) {
549+
graphics_->setFixedMacrosPenalty({"Fixed Macros",
550+
fixed_macros_weight_,
551+
fixed_macros_penalty_,
552+
norm_fixed_macros_penalty_});
553+
}
554+
}
555+
477556
// Align macro clusters to reduce notch
478557
void SACoreSoftMacro::alignMacroClusters()
479558
{

src/mpl/src/SACoreSoftMacro.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
4747
odb::dbBlock* block);
4848

4949
void run() override;
50+
bool isValid() const override;
5051

5152
// accessors
5253
float getBoundaryPenalty() const;
@@ -87,14 +88,18 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
8788
float calSingleNotchPenalty(float width, float height);
8889
void calNotchPenalty();
8990
void calMacroBlockagePenalty();
91+
void calFixedMacrosPenalty();
9092

9193
// Only for Cluster Placement:
9294
void attemptCentralization(float pre_cost);
9395
void moveFloorplan(const std::pair<float, float>& offset);
9496

9597
Tiling computeOverlapShape(const Rect& rect_a, const Rect& rect_b) const;
9698

99+
void findFixedMacros();
100+
97101
std::vector<Rect> blockages_;
102+
std::vector<Rect> fixed_macros_;
98103

99104
Cluster* root_;
100105

@@ -111,10 +116,12 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
111116
float boundary_weight_ = 0.0;
112117
float macro_blockage_weight_ = 0.0;
113118
float notch_weight_ = 0.0;
119+
const float fixed_macros_weight_ = 100.0;
114120

115121
float boundary_penalty_ = 0.0;
116122
float notch_penalty_ = 0.0;
117123
float macro_blockage_penalty_ = 0.0;
124+
float fixed_macros_penalty_ = 0.0;
118125

119126
float pre_boundary_penalty_ = 0.0;
120127
float pre_notch_penalty_ = 0.0;
@@ -123,6 +130,7 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
123130
float norm_boundary_penalty_ = 0.0;
124131
float norm_notch_penalty_ = 0.0;
125132
float norm_macro_blockage_penalty_ = 0.0;
133+
float norm_fixed_macros_penalty_ = 0.0;
126134

127135
// action prob
128136
float resize_prob_ = 0.0;

src/mpl/src/SimulatedAnnealingCore.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ void SimulatedAnnealingCore<T>::setInitialSequencePair(
153153
template <class T>
154154
bool SimulatedAnnealingCore<T>::isValid() const
155155
{
156-
return (width_ <= std::ceil(outline_.getWidth()))
157-
&& (height_ <= std::ceil(outline_.getHeight()));
156+
return resultFitsInOutline();
158157
}
159158

160159
template <class T>
@@ -459,11 +458,13 @@ void SimulatedAnnealingCore<T>::packFloorplan()
459458
for (int i = 0; i < pos_seq_.size(); i++) {
460459
const int macro_id = pos_seq_[i];
461460
const int neg_seq_pos = sequence_pair_pos[macro_id].second;
461+
T& macro = macros_[macro_id];
462462

463-
macros_[macro_id].setX(accumulated_length[neg_seq_pos]);
463+
if (!macro.isFixed()) {
464+
macro.setX(accumulated_length[neg_seq_pos]);
465+
}
464466

465-
const float current_length
466-
= macros_[macro_id].getX() + macros_[macro_id].getWidth();
467+
const float current_length = macro.getX() + macro.getWidth();
467468

468469
for (int j = neg_seq_pos; j < neg_seq_.size(); j++) {
469470
if (current_length > accumulated_length[j]) {
@@ -494,11 +495,13 @@ void SimulatedAnnealingCore<T>::packFloorplan()
494495
for (int i = 0; i < pos_seq_.size(); i++) {
495496
const int macro_id = reversed_pos_seq[i];
496497
const int neg_seq_pos = sequence_pair_pos[macro_id].second;
498+
T& macro = macros_[macro_id];
497499

498-
macros_[macro_id].setY(accumulated_length[neg_seq_pos]);
500+
if (!macro.isFixed()) {
501+
macro.setY(accumulated_length[neg_seq_pos]);
502+
}
499503

500-
const float current_height
501-
= macros_[macro_id].getY() + macros_[macro_id].getHeight();
504+
const float current_height = macro.getY() + macro.getHeight();
502505

503506
for (int j = neg_seq_pos; j < neg_seq_.size(); j++) {
504507
if (current_height > accumulated_length[j]) {
@@ -765,6 +768,13 @@ void SimulatedAnnealingCore<T>::fastSA()
765768
}
766769
}
767770

771+
template <class T>
772+
bool SimulatedAnnealingCore<T>::resultFitsInOutline() const
773+
{
774+
return (width_ <= std::ceil(outline_.getWidth()))
775+
&& (height_ <= std::ceil(outline_.getHeight()));
776+
}
777+
768778
template <class T>
769779
void SimulatedAnnealingCore<T>::updateBestResult(const float cost)
770780
{

src/mpl/src/SimulatedAnnealingCore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class SimulatedAnnealingCore
6868
void setGuides(const std::map<int, Rect>& guides);
6969
void setInitialSequencePair(const SequencePair& sequence_pair);
7070

71-
bool isValid() const;
71+
virtual bool isValid() const;
7272
bool fitsIn(const Rect& outline) const;
7373
void writeCostFile(const std::string& file_name) const;
7474
float getNormCost() const;
@@ -102,6 +102,7 @@ class SimulatedAnnealingCore
102102
};
103103

104104
void fastSA();
105+
bool resultFitsInOutline() const;
105106

106107
void setAvailableRegionsForUnconstrainedPins(
107108
const BoundaryRegionList& regions);

0 commit comments

Comments
 (0)