|
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,27 @@ 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 | + } else if (auto* via = obs->getBlockVia()) { |
| 640 | + obs_layers.push_back( |
| 641 | + {gui->makeSelected(via), |
| 642 | + gui->makeSelected(DbBoxDescriptor::BoxWithTransform{obs, xform})}); |
| 643 | + } |
| 644 | + } |
| 645 | + if (!obs_layers.empty()) { |
| 646 | + props.push_back({"Obstructions", obs_layers}); |
| 647 | + } |
| 648 | + |
627 | 649 | return props; |
628 | 650 | } |
629 | 651 |
|
@@ -4645,4 +4667,173 @@ Descriptor::Property DbScanInstDescriptor::getScanPinProperty( |
4645 | 4667 | return property; |
4646 | 4668 | } |
4647 | 4669 |
|
| 4670 | +////////////////////////////////////////////////// |
| 4671 | + |
| 4672 | +DbBoxDescriptor::DbBoxDescriptor(odb::dbDatabase* db) |
| 4673 | + : BaseDbDescriptor<odb::dbBox>(db) |
| 4674 | +{ |
| 4675 | +} |
| 4676 | + |
| 4677 | +std::string DbBoxDescriptor::getName(std::any object) const |
| 4678 | +{ |
| 4679 | + odb::Rect box; |
| 4680 | + getBBox(object, box); |
| 4681 | + |
| 4682 | + std::string shape_text |
| 4683 | + = fmt::format("({}, {}), ({}, {})", |
| 4684 | + Property::convert_dbu(box.xMin(), false), |
| 4685 | + Property::convert_dbu(box.yMin(), false), |
| 4686 | + Property::convert_dbu(box.xMax(), false), |
| 4687 | + Property::convert_dbu(box.yMax(), false)); |
| 4688 | + |
| 4689 | + return fmt::format("Box of {}: {}", |
| 4690 | + getObject(object)->getOwnerType().getString(), |
| 4691 | + shape_text); |
| 4692 | +} |
| 4693 | + |
| 4694 | +std::string DbBoxDescriptor::getTypeName() const |
| 4695 | +{ |
| 4696 | + return "Box"; |
| 4697 | +} |
| 4698 | + |
| 4699 | +bool DbBoxDescriptor::getBBox(std::any object, odb::Rect& bbox) const |
| 4700 | +{ |
| 4701 | + bbox = getObject(object)->getBox(); |
| 4702 | + const auto xform = getTransform(object); |
| 4703 | + xform.apply(bbox); |
| 4704 | + return true; |
| 4705 | +} |
| 4706 | + |
| 4707 | +Selected DbBoxDescriptor::makeSelected(std::any object) const |
| 4708 | +{ |
| 4709 | + Selected box_selected = BaseDbDescriptor::makeSelected(object); |
| 4710 | + if (box_selected) { |
| 4711 | + return box_selected; |
| 4712 | + } |
| 4713 | + |
| 4714 | + if (auto box = std::any_cast<BoxWithTransform>(&object)) { |
| 4715 | + return Selected(*box, this); |
| 4716 | + } |
| 4717 | + return Selected(); |
| 4718 | +} |
| 4719 | + |
| 4720 | +void DbBoxDescriptor::highlight(std::any object, Painter& painter) const |
| 4721 | +{ |
| 4722 | + odb::Rect bbox = getObject(object)->getBox(); |
| 4723 | + const auto xform = getTransform(object); |
| 4724 | + xform.apply(bbox); |
| 4725 | + |
| 4726 | + painter.drawRect(bbox); |
| 4727 | +} |
| 4728 | + |
| 4729 | +bool DbBoxDescriptor::getAllObjects(SelectionSet& objects) const |
| 4730 | +{ |
| 4731 | + return false; |
| 4732 | +} |
| 4733 | + |
| 4734 | +bool DbBoxDescriptor::lessThan(std::any l, std::any r) const |
| 4735 | +{ |
| 4736 | + auto l_net = getObject(l); |
| 4737 | + auto r_net = getObject(r); |
| 4738 | + return BaseDbDescriptor::lessThan(l_net, r_net); |
| 4739 | +} |
| 4740 | + |
| 4741 | +Descriptor::Properties DbBoxDescriptor::getDBProperties(odb::dbBox* box) const |
| 4742 | +{ |
| 4743 | + Properties props; |
| 4744 | + |
| 4745 | + auto* gui = Gui::get(); |
| 4746 | + |
| 4747 | + switch (box->getOwnerType()) { |
| 4748 | + case odb::dbBoxOwner::BLOCK: |
| 4749 | + props.push_back( |
| 4750 | + {"Owner", gui->makeSelected((odb::dbBlock*) box->getBoxOwner())}); |
| 4751 | + break; |
| 4752 | + case odb::dbBoxOwner::INST: |
| 4753 | + props.push_back( |
| 4754 | + {"Owner", gui->makeSelected((odb::dbInst*) box->getBoxOwner())}); |
| 4755 | + break; |
| 4756 | + case odb::dbBoxOwner::BTERM: |
| 4757 | + props.push_back( |
| 4758 | + {"Owner", gui->makeSelected((odb::dbBTerm*) box->getBoxOwner())}); |
| 4759 | + break; |
| 4760 | + case odb::dbBoxOwner::BPIN: |
| 4761 | + props.push_back( |
| 4762 | + {"Owner", gui->makeSelected((odb::dbBPin*) box->getBoxOwner())}); |
| 4763 | + break; |
| 4764 | + case odb::dbBoxOwner::VIA: |
| 4765 | + props.push_back( |
| 4766 | + {"Owner", gui->makeSelected((odb::dbVia*) box->getBoxOwner())}); |
| 4767 | + break; |
| 4768 | + case odb::dbBoxOwner::OBSTRUCTION: |
| 4769 | + props.push_back( |
| 4770 | + {"Owner", |
| 4771 | + gui->makeSelected((odb::dbObstruction*) box->getBoxOwner())}); |
| 4772 | + break; |
| 4773 | + case odb::dbBoxOwner::BLOCKAGE: |
| 4774 | + props.push_back( |
| 4775 | + {"Owner", gui->makeSelected((odb::dbBlockage*) box->getBoxOwner())}); |
| 4776 | + break; |
| 4777 | + case odb::dbBoxOwner::SWIRE: |
| 4778 | + props.push_back( |
| 4779 | + {"Owner", gui->makeSelected((odb::dbSWire*) box->getBoxOwner())}); |
| 4780 | + break; |
| 4781 | + case odb::dbBoxOwner::MASTER: |
| 4782 | + props.push_back( |
| 4783 | + {"Owner", gui->makeSelected((odb::dbMaster*) box->getBoxOwner())}); |
| 4784 | + break; |
| 4785 | + case odb::dbBoxOwner::MPIN: |
| 4786 | + props.push_back( |
| 4787 | + {"Owner", gui->makeSelected((odb::dbMPin*) box->getBoxOwner())}); |
| 4788 | + break; |
| 4789 | + case odb::dbBoxOwner::PBOX: |
| 4790 | + props.push_back({"Owner", "PBOX"}); |
| 4791 | + break; |
| 4792 | + case odb::dbBoxOwner::TECH_VIA: |
| 4793 | + props.push_back( |
| 4794 | + {"Owner", gui->makeSelected((odb::dbTechVia*) box->getBoxOwner())}); |
| 4795 | + break; |
| 4796 | + case odb::dbBoxOwner::REGION: |
| 4797 | + props.push_back( |
| 4798 | + {"Owner", gui->makeSelected((odb::dbRegion*) box->getBoxOwner())}); |
| 4799 | + break; |
| 4800 | + case odb::dbBoxOwner::UNKNOWN: |
| 4801 | + props.push_back({"Owner", "Unknown"}); |
| 4802 | + break; |
| 4803 | + } |
| 4804 | + |
| 4805 | + if (auto* layer = box->getTechLayer()) { |
| 4806 | + props.push_back({"Layer", gui->makeSelected(layer)}); |
| 4807 | + if (box->getLayerMask() > 0) { |
| 4808 | + props.push_back({"Mask", box->getLayerMask()}); |
| 4809 | + } |
| 4810 | + props.push_back({"Design rule width", |
| 4811 | + Property::convert_dbu(box->getDesignRuleWidth(), true)}); |
| 4812 | + } else if (auto* via = box->getTechVia()) { |
| 4813 | + props.push_back({"Tech via", gui->makeSelected(via)}); |
| 4814 | + } else if (auto* via = box->getBlockVia()) { |
| 4815 | + props.push_back({"Block via", gui->makeSelected(via)}); |
| 4816 | + } |
| 4817 | + |
| 4818 | + return props; |
| 4819 | +} |
| 4820 | + |
| 4821 | +odb::dbBox* DbBoxDescriptor::getObject(const std::any& object) const |
| 4822 | +{ |
| 4823 | + odb::dbBox* const* box = std::any_cast<odb::dbBox*>(&object); |
| 4824 | + if (box != nullptr) { |
| 4825 | + return *box; |
| 4826 | + } |
| 4827 | + return std::any_cast<BoxWithTransform>(object).box; |
| 4828 | +} |
| 4829 | + |
| 4830 | +odb::dbTransform DbBoxDescriptor::getTransform(const std::any& object) const |
| 4831 | +{ |
| 4832 | + const BoxWithTransform* box_xform = std::any_cast<BoxWithTransform>(&object); |
| 4833 | + if (box_xform != nullptr) { |
| 4834 | + return box_xform->xform; |
| 4835 | + } |
| 4836 | + return odb::dbTransform(); |
| 4837 | +} |
| 4838 | + |
4648 | 4839 | } // namespace gui |
0 commit comments