|
22 | 22 | #include "db_sta/dbSta.hh" |
23 | 23 | #include "odb/db.h" |
24 | 24 | #include "odb/dbShape.h" |
| 25 | +#include "odb/dbTransform.h" |
25 | 26 | #include "options.h" |
26 | 27 | #include "sta/Liberty.hh" |
27 | 28 | #include "utl/Logger.h" |
@@ -624,6 +625,23 @@ Descriptor::Properties DbInstDescriptor::getDBProperties( |
624 | 625 | props.push_back({"Scan Inst", gui->makeSelected(scan_inst)}); |
625 | 626 | } |
626 | 627 |
|
| 628 | + Descriptor::PropertyList obs_layers; |
| 629 | + const auto xform = inst->getTransform(); |
| 630 | + for (auto* obs : inst->getMaster()->getObstructions()) { |
| 631 | + if (auto* layer = obs->getTechLayer()) { |
| 632 | + obs_layers.push_back( |
| 633 | + {gui->makeSelected(layer), |
| 634 | + gui->makeSelected(DbBoxDescriptor::BoxWithTransform{obs, xform})}); |
| 635 | + } else if (auto* via = obs->getTechVia()) { |
| 636 | + obs_layers.push_back( |
| 637 | + {gui->makeSelected(via), |
| 638 | + gui->makeSelected(DbBoxDescriptor::BoxWithTransform{obs, xform})}); |
| 639 | + } |
| 640 | + } |
| 641 | + if (!obs_layers.empty()) { |
| 642 | + props.push_back({"Obstructions", obs_layers}); |
| 643 | + } |
| 644 | + |
627 | 645 | return props; |
628 | 646 | } |
629 | 647 |
|
@@ -4186,6 +4204,19 @@ Descriptor::Properties DbSiteDescriptor::getDBProperties( |
4186 | 4204 | } |
4187 | 4205 | props.push_back({"Symmetry", symmetry}); |
4188 | 4206 |
|
| 4207 | + auto* gui = Gui::get(); |
| 4208 | + SelectionSet masters; |
| 4209 | + for (auto* lib : db_->getLibs()) { |
| 4210 | + for (auto* master : lib->getMasters()) { |
| 4211 | + if (master->getSite() == site) { |
| 4212 | + masters.insert(gui->makeSelected(master)); |
| 4213 | + } |
| 4214 | + } |
| 4215 | + } |
| 4216 | + if (!masters.empty()) { |
| 4217 | + props.push_back({"Masters", masters}); |
| 4218 | + } |
| 4219 | + |
4189 | 4220 | return props; |
4190 | 4221 | } |
4191 | 4222 |
|
@@ -4632,4 +4663,173 @@ Descriptor::Property DbScanInstDescriptor::getScanPinProperty( |
4632 | 4663 | return property; |
4633 | 4664 | } |
4634 | 4665 |
|
| 4666 | +////////////////////////////////////////////////// |
| 4667 | + |
| 4668 | +DbBoxDescriptor::DbBoxDescriptor(odb::dbDatabase* db) |
| 4669 | + : BaseDbDescriptor<odb::dbBox>(db) |
| 4670 | +{ |
| 4671 | +} |
| 4672 | + |
| 4673 | +std::string DbBoxDescriptor::getName(std::any object) const |
| 4674 | +{ |
| 4675 | + odb::Rect box; |
| 4676 | + getBBox(object, box); |
| 4677 | + |
| 4678 | + std::string shape_text |
| 4679 | + = fmt::format("({}, {}), ({}, {})", |
| 4680 | + Property::convert_dbu(box.xMin(), false), |
| 4681 | + Property::convert_dbu(box.yMin(), false), |
| 4682 | + Property::convert_dbu(box.xMax(), false), |
| 4683 | + Property::convert_dbu(box.yMax(), false)); |
| 4684 | + |
| 4685 | + return fmt::format("Box of {}: {}", |
| 4686 | + getObject(object)->getOwnerType().getString(), |
| 4687 | + shape_text); |
| 4688 | +} |
| 4689 | + |
| 4690 | +std::string DbBoxDescriptor::getTypeName() const |
| 4691 | +{ |
| 4692 | + return "Box"; |
| 4693 | +} |
| 4694 | + |
| 4695 | +bool DbBoxDescriptor::getBBox(std::any object, odb::Rect& bbox) const |
| 4696 | +{ |
| 4697 | + bbox = getObject(object)->getBox(); |
| 4698 | + const auto xform = getTransform(object); |
| 4699 | + xform.apply(bbox); |
| 4700 | + return true; |
| 4701 | +} |
| 4702 | + |
| 4703 | +Selected DbBoxDescriptor::makeSelected(std::any object) const |
| 4704 | +{ |
| 4705 | + Selected box_selected = BaseDbDescriptor::makeSelected(object); |
| 4706 | + if (box_selected) { |
| 4707 | + return box_selected; |
| 4708 | + } |
| 4709 | + |
| 4710 | + if (auto box = std::any_cast<BoxWithTransform>(&object)) { |
| 4711 | + return Selected(*box, this); |
| 4712 | + } |
| 4713 | + return Selected(); |
| 4714 | +} |
| 4715 | + |
| 4716 | +void DbBoxDescriptor::highlight(std::any object, Painter& painter) const |
| 4717 | +{ |
| 4718 | + odb::Rect bbox = getObject(object)->getBox(); |
| 4719 | + const auto xform = getTransform(object); |
| 4720 | + xform.apply(bbox); |
| 4721 | + |
| 4722 | + painter.drawRect(bbox); |
| 4723 | +} |
| 4724 | + |
| 4725 | +bool DbBoxDescriptor::getAllObjects(SelectionSet& objects) const |
| 4726 | +{ |
| 4727 | + return false; |
| 4728 | +} |
| 4729 | + |
| 4730 | +bool DbBoxDescriptor::lessThan(std::any l, std::any r) const |
| 4731 | +{ |
| 4732 | + auto l_net = getObject(l); |
| 4733 | + auto r_net = getObject(r); |
| 4734 | + return BaseDbDescriptor::lessThan(l_net, r_net); |
| 4735 | +} |
| 4736 | + |
| 4737 | +Descriptor::Properties DbBoxDescriptor::getDBProperties(odb::dbBox* box) const |
| 4738 | +{ |
| 4739 | + Properties props; |
| 4740 | + |
| 4741 | + auto* gui = Gui::get(); |
| 4742 | + |
| 4743 | + switch (box->getOwnerType()) { |
| 4744 | + case odb::dbBoxOwner::BLOCK: |
| 4745 | + props.push_back( |
| 4746 | + {"Owner", gui->makeSelected((odb::dbBlock*) box->getBoxOwner())}); |
| 4747 | + break; |
| 4748 | + case odb::dbBoxOwner::INST: |
| 4749 | + props.push_back( |
| 4750 | + {"Owner", gui->makeSelected((odb::dbInst*) box->getBoxOwner())}); |
| 4751 | + break; |
| 4752 | + case odb::dbBoxOwner::BTERM: |
| 4753 | + props.push_back( |
| 4754 | + {"Owner", gui->makeSelected((odb::dbBTerm*) box->getBoxOwner())}); |
| 4755 | + break; |
| 4756 | + case odb::dbBoxOwner::BPIN: |
| 4757 | + props.push_back( |
| 4758 | + {"Owner", gui->makeSelected((odb::dbBPin*) box->getBoxOwner())}); |
| 4759 | + break; |
| 4760 | + case odb::dbBoxOwner::VIA: |
| 4761 | + props.push_back( |
| 4762 | + {"Owner", gui->makeSelected((odb::dbVia*) box->getBoxOwner())}); |
| 4763 | + break; |
| 4764 | + case odb::dbBoxOwner::OBSTRUCTION: |
| 4765 | + props.push_back( |
| 4766 | + {"Owner", |
| 4767 | + gui->makeSelected((odb::dbObstruction*) box->getBoxOwner())}); |
| 4768 | + break; |
| 4769 | + case odb::dbBoxOwner::BLOCKAGE: |
| 4770 | + props.push_back( |
| 4771 | + {"Owner", gui->makeSelected((odb::dbBlockage*) box->getBoxOwner())}); |
| 4772 | + break; |
| 4773 | + case odb::dbBoxOwner::SWIRE: |
| 4774 | + props.push_back( |
| 4775 | + {"Owner", gui->makeSelected((odb::dbSWire*) box->getBoxOwner())}); |
| 4776 | + break; |
| 4777 | + case odb::dbBoxOwner::MASTER: |
| 4778 | + props.push_back( |
| 4779 | + {"Owner", gui->makeSelected((odb::dbMaster*) box->getBoxOwner())}); |
| 4780 | + break; |
| 4781 | + case odb::dbBoxOwner::MPIN: |
| 4782 | + props.push_back( |
| 4783 | + {"Owner", gui->makeSelected((odb::dbMPin*) box->getBoxOwner())}); |
| 4784 | + break; |
| 4785 | + case odb::dbBoxOwner::PBOX: |
| 4786 | + props.push_back({"Owner", "PBOX"}); |
| 4787 | + break; |
| 4788 | + case odb::dbBoxOwner::TECH_VIA: |
| 4789 | + props.push_back( |
| 4790 | + {"Owner", gui->makeSelected((odb::dbTechVia*) box->getBoxOwner())}); |
| 4791 | + break; |
| 4792 | + case odb::dbBoxOwner::REGION: |
| 4793 | + props.push_back( |
| 4794 | + {"Owner", gui->makeSelected((odb::dbRegion*) box->getBoxOwner())}); |
| 4795 | + break; |
| 4796 | + case odb::dbBoxOwner::UNKNOWN: |
| 4797 | + props.push_back({"Owner", "Unknown"}); |
| 4798 | + break; |
| 4799 | + } |
| 4800 | + |
| 4801 | + if (auto* layer = box->getTechLayer()) { |
| 4802 | + props.push_back({"Layer", gui->makeSelected(layer)}); |
| 4803 | + if (box->getLayerMask() > 0) { |
| 4804 | + props.push_back({"Mask", box->getLayerMask()}); |
| 4805 | + } |
| 4806 | + props.push_back({"Design rule width", |
| 4807 | + Property::convert_dbu(box->getDesignRuleWidth(), true)}); |
| 4808 | + } else if (auto* via = box->getTechVia()) { |
| 4809 | + props.push_back({"Tech via", gui->makeSelected(via)}); |
| 4810 | + } else if (auto* via = box->getBlockVia()) { |
| 4811 | + props.push_back({"Block via", gui->makeSelected(via)}); |
| 4812 | + } |
| 4813 | + |
| 4814 | + return props; |
| 4815 | +} |
| 4816 | + |
| 4817 | +odb::dbBox* DbBoxDescriptor::getObject(const std::any& object) const |
| 4818 | +{ |
| 4819 | + odb::dbBox* const* box = std::any_cast<odb::dbBox*>(&object); |
| 4820 | + if (box != nullptr) { |
| 4821 | + return *box; |
| 4822 | + } |
| 4823 | + return std::any_cast<BoxWithTransform>(object).box; |
| 4824 | +} |
| 4825 | + |
| 4826 | +odb::dbTransform DbBoxDescriptor::getTransform(const std::any& object) const |
| 4827 | +{ |
| 4828 | + const BoxWithTransform* box_xform = std::any_cast<BoxWithTransform>(&object); |
| 4829 | + if (box_xform != nullptr) { |
| 4830 | + return box_xform->xform; |
| 4831 | + } |
| 4832 | + return odb::dbTransform(); |
| 4833 | +} |
| 4834 | + |
4635 | 4835 | } // namespace gui |
0 commit comments