@@ -33,6 +33,7 @@ void Opendp::checkPlacement(const bool verbose,
3333 std::vector<Node*> placed_failures;
3434 std::vector<Node*> in_rows_failures;
3535 std::vector<Node*> overlap_failures;
36+ std::vector<Node*> padding_failures;
3637 std::vector<Node*> one_site_gap_failures;
3738 std::vector<Node*> site_align_failures;
3839 std::vector<Node*> region_placement_failures;
@@ -69,6 +70,11 @@ void Opendp::checkPlacement(const bool verbose,
6970 if (checkOverlap (*cell)) {
7071 overlap_failures.push_back (cell.get ());
7172 }
73+ // Padding check
74+ if (!drc_engine_->checkPadding (cell.get ())) {
75+ padding_failures.emplace_back (cell.get ());
76+ }
77+ grid_->paintCellPadding (cell.get ());
7278 // EdgeSpacing check
7379 if (!drc_engine_->checkEdgeSpacing (cell.get ())) {
7480 edge_spacing_failures.emplace_back (cell.get ());
@@ -93,6 +99,7 @@ void Opendp::checkPlacement(const bool verbose,
9399 saveFailures (placed_failures,
94100 in_rows_failures,
95101 overlap_failures,
102+ padding_failures,
96103 one_site_gap_failures,
97104 site_align_failures,
98105 region_placement_failures,
@@ -108,6 +115,7 @@ void Opendp::checkPlacement(const bool verbose,
108115 overlap_failures, 5 , " Overlap" , verbose, [&](Node* cell) -> void {
109116 reportOverlapFailure (cell);
110117 });
118+ reportFailures (padding_failures, 11 , " Padding" , verbose);
111119 reportFailures (site_align_failures, 6 , " Site aligned" , verbose);
112120 reportFailures (one_site_gap_failures, 7 , " One site gap" , verbose);
113121 reportFailures (region_placement_failures, 8 , " Region placement" , verbose);
@@ -116,10 +124,11 @@ void Opendp::checkPlacement(const bool verbose,
116124 reportFailures (blocked_layers_failures, 10 , " Blocked layers" , verbose);
117125 logger_->metric (" design__violations" ,
118126 placed_failures.size () + in_rows_failures.size ()
119- + overlap_failures.size () + site_align_failures.size ());
127+ + overlap_failures.size () + padding_failures.size ()
128+ + site_align_failures.size ());
120129
121130 if (placed_failures.size () + in_rows_failures.size () + overlap_failures.size ()
122- + site_align_failures.size ()
131+ + padding_failures. size () + site_align_failures.size ()
123132 + (disallow_one_site_gaps_ ? one_site_gap_failures.size () : 0 )
124133 + region_placement_failures.size () + edge_spacing_failures.size ()
125134 + blocked_layers_failures.size ()
@@ -177,6 +186,7 @@ void Opendp::saveViolations(const std::vector<Node*>& failures,
177186void Opendp::saveFailures (const vector<Node*>& placed_failures,
178187 const vector<Node*>& in_rows_failures,
179188 const vector<Node*>& overlap_failures,
189+ const vector<Node*>& padding_failures,
180190 const vector<Node*>& one_site_gap_failures,
181191 const vector<Node*>& site_align_failures,
182192 const vector<Node*>& region_placement_failures,
@@ -185,10 +195,10 @@ void Opendp::saveFailures(const vector<Node*>& placed_failures,
185195 const vector<Node*>& blocked_layers_failures)
186196{
187197 if (placed_failures.empty () && in_rows_failures.empty ()
188- && overlap_failures.empty () && one_site_gap_failures .empty ()
189- && site_align_failures .empty () && region_placement_failures .empty ()
190- && placement_failures .empty () && edge_spacing_failures .empty ()
191- && blocked_layers_failures.empty ()) {
198+ && overlap_failures.empty () && padding_failures .empty ()
199+ && one_site_gap_failures .empty () && site_align_failures .empty ()
200+ && region_placement_failures .empty () && placement_failures .empty ()
201+ && edge_spacing_failures. empty () && blocked_layers_failures.empty ()) {
192202 return ;
193203 }
194204
@@ -212,6 +222,12 @@ void Opendp::saveFailures(const vector<Node*>& placed_failures,
212222 category->setDescription (" Cells that are overlapping with other cells." );
213223 saveViolations (overlap_failures, category, " overlap" );
214224 }
225+ if (!padding_failures.empty ()) {
226+ auto category = odb::dbMarkerCategory::createOrReplace (tool_category,
227+ " Padding_failures" );
228+ category->setDescription (" Cells that violate the padding rules." );
229+ saveViolations (padding_failures, category);
230+ }
215231 if (!one_site_gap_failures.empty ()) {
216232 auto category = odb::dbMarkerCategory::createOrReplace (
217233 tool_category, " One_site_gap_failures" );
@@ -337,32 +353,13 @@ bool Opendp::checkInRows(const Node& cell) const
337353 return true ;
338354}
339355
340- // COVER *, RING, PAD * - ignored
341-
342- // CLASSes are grouped as follows
343- // CR = {CORE, CORE FEEDTHRU, CORE TIEHIGH, CORE TIELOW, CORE ANTENNACELL}
344- // WT = CORE WELLTAP
345- // SP = CORE SPACER, ENDCAP *
346- // BL = BLOCK *
347-
348- // CR WT BL SP
349- // CR P P P O
350- // WT P O P O
351- // BL P P - O
352- // SP O O O O
353- //
354- // P = no padded overlap
355- // O = no overlap (padding ignored)
356- // - = no overlap check (overlap allowed)
357- // The rules apply to both FIXED or PLACED instances
358-
359356// Return the cell this cell overlaps.
360357const Node* Opendp::checkOverlap (Node& cell) const
361358{
362359 debugPrint (
363360 logger_, DPL, " grid" , 2 , " checking overlap for cell {}" , cell.name ());
364361 const Node* overlap_cell = nullptr ;
365- grid_->visitCellPixels (cell, true , [&](Pixel* pixel) {
362+ grid_->visitCellPixels (cell, false , [&](Pixel* pixel, bool padded ) {
366363 const Node* pixel_cell = pixel->cell ;
367364 if (pixel_cell) {
368365 if (pixel_cell != &cell && overlap (&cell, pixel_cell)) {
@@ -382,19 +379,11 @@ bool Opendp::overlap(const Node* cell1, const Node* cell2) const
382379 return false ;
383380 }
384381
385- const bool padded = padding_->havePadding () && isOverlapPadded (cell1, cell2);
386- const DbuPt ll1 = initialLocation (cell1, padded);
387- const DbuPt ll2 = initialLocation (cell2, padded);
382+ const DbuPt ll1 = initialLocation (cell1, false );
383+ const DbuPt ll2 = initialLocation (cell2, false );
388384 DbuPt ur1, ur2;
389- if (padded) {
390- ur1 = DbuPt (ll1.x + padding_->paddedWidth (cell1),
391- ll1.y + cell1->getHeight ());
392- ur2 = DbuPt (ll2.x + padding_->paddedWidth (cell2),
393- ll2.y + cell2->getHeight ());
394- } else {
395- ur1 = DbuPt (ll1.x + cell1->getWidth ().v , ll1.y + cell1->getHeight ().v );
396- ur2 = DbuPt (ll2.x + cell2->getWidth ().v , ll2.y + cell2->getHeight ().v );
397- }
385+ ur1 = DbuPt (ll1.x + cell1->getWidth ().v , ll1.y + cell1->getHeight ().v );
386+ ur2 = DbuPt (ll2.x + cell2->getWidth ().v , ll2.y + cell2->getHeight ().v );
398387 return ll1.x < ur2.x && ur1.x > ll2.x && ll1.y < ur2.y && ur1.y > ll2.y ;
399388}
400389
@@ -450,71 +439,4 @@ bool Opendp::checkRegionPlacement(const Node* cell) const
450439 return true ;
451440}
452441
453- /* static */
454- bool Opendp::isOverlapPadded (const Node* cell1, const Node* cell2)
455- {
456- return isCrWtBlClass (cell1) && isCrWtBlClass (cell2)
457- && !(isWellTap (cell1) && isWellTap (cell2));
458- }
459-
460- /* static */
461- bool Opendp::isCrWtBlClass (const Node* cell)
462- {
463- dbMasterType type = cell->getDbInst ()->getMaster ()->getType ();
464- // Use switch so if new types are added we get a compiler warning.
465- switch (type.getValue ()) {
466- case dbMasterType::CORE:
467- case dbMasterType::CORE_ANTENNACELL:
468- case dbMasterType::CORE_FEEDTHRU:
469- case dbMasterType::CORE_TIEHIGH:
470- case dbMasterType::CORE_TIELOW:
471- case dbMasterType::CORE_WELLTAP:
472- case dbMasterType::BLOCK:
473- case dbMasterType::BLOCK_BLACKBOX:
474- case dbMasterType::BLOCK_SOFT:
475- return true ;
476- case dbMasterType::CORE_SPACER:
477- case dbMasterType::ENDCAP:
478- case dbMasterType::ENDCAP_PRE:
479- case dbMasterType::ENDCAP_POST:
480- case dbMasterType::ENDCAP_TOPLEFT:
481- case dbMasterType::ENDCAP_TOPRIGHT:
482- case dbMasterType::ENDCAP_BOTTOMLEFT:
483- case dbMasterType::ENDCAP_BOTTOMRIGHT:
484- case dbMasterType::ENDCAP_LEF58_BOTTOMEDGE:
485- case dbMasterType::ENDCAP_LEF58_TOPEDGE:
486- case dbMasterType::ENDCAP_LEF58_RIGHTEDGE:
487- case dbMasterType::ENDCAP_LEF58_LEFTEDGE:
488- case dbMasterType::ENDCAP_LEF58_RIGHTBOTTOMEDGE:
489- case dbMasterType::ENDCAP_LEF58_LEFTBOTTOMEDGE:
490- case dbMasterType::ENDCAP_LEF58_RIGHTTOPEDGE:
491- case dbMasterType::ENDCAP_LEF58_LEFTTOPEDGE:
492- case dbMasterType::ENDCAP_LEF58_RIGHTBOTTOMCORNER:
493- case dbMasterType::ENDCAP_LEF58_LEFTBOTTOMCORNER:
494- case dbMasterType::ENDCAP_LEF58_RIGHTTOPCORNER:
495- case dbMasterType::ENDCAP_LEF58_LEFTTOPCORNER:
496- // These classes are completely ignored by the placer.
497- case dbMasterType::COVER:
498- case dbMasterType::COVER_BUMP:
499- case dbMasterType::RING:
500- case dbMasterType::PAD:
501- case dbMasterType::PAD_AREAIO:
502- case dbMasterType::PAD_INPUT:
503- case dbMasterType::PAD_OUTPUT:
504- case dbMasterType::PAD_INOUT:
505- case dbMasterType::PAD_POWER:
506- case dbMasterType::PAD_SPACER:
507- return false ;
508- }
509- // gcc warniing
510- return false ;
511- }
512-
513- /* static */
514- bool Opendp::isWellTap (const Node* cell)
515- {
516- dbMasterType type = cell->getDbInst ()->getMaster ()->getType ();
517- return type == dbMasterType::CORE_WELLTAP;
518- }
519-
520442} // namespace dpl
0 commit comments