mirror of https://github.com/KLayout/klayout.git
Fixed a hierarchy traversal bug in the hier processor.
This commit is contained in:
parent
74b6341425
commit
863c6ba8de
|
|
@ -292,7 +292,8 @@ HEADERS = \
|
|||
dbLayoutToNetlistWriter.h \
|
||||
dbLayoutToNetlistFormatDefs.h \
|
||||
dbDeviceAbstract.h \
|
||||
dbLocalOperationUtils.h
|
||||
dbLocalOperationUtils.h \
|
||||
dbDeepRegion.h
|
||||
|
||||
!equals(HAVE_QT, "0") {
|
||||
|
||||
|
|
|
|||
|
|
@ -772,6 +772,23 @@ LocalProcessorResultComputationTask::perform ()
|
|||
// erase the contexts we don't need any longer
|
||||
{
|
||||
tl::MutexLocker locker (& mp_contexts->lock ());
|
||||
|
||||
#if defined(ENABLE_DB_HP_SANITY_ASSERTIONS)
|
||||
std::set<const db::LocalProcessorCellContext *> td;
|
||||
for (db::LocalProcessorCellContexts::iterator i = mp_cell_contexts->begin (); i != mp_cell_contexts->end (); ++i) {
|
||||
td.insert (&i->second);
|
||||
}
|
||||
for (db::LocalProcessorContexts::contexts_per_cell_type::iterator pcc = mp_contexts->context_map ().begin (); pcc != mp_contexts->context_map ().end (); ++pcc) {
|
||||
for (db::LocalProcessorCellContexts::iterator i = pcc->second.begin (); i != pcc->second.end (); ++i) {
|
||||
for (db::LocalProcessorCellContext::drop_iterator j = i->second.begin_drops (); j != i->second.end_drops (); ++j) {
|
||||
if (td.find (j->parent_context) != td.end ()) {
|
||||
tl_assert (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_contexts->context_map ().erase (mp_cell);
|
||||
}
|
||||
}
|
||||
|
|
@ -892,6 +909,23 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
|||
|
||||
db::LocalProcessorCellContexts &cell_contexts = contexts.contexts_per_cell (subject_cell, intruder_cell);
|
||||
|
||||
#if defined(ENABLE_DB_HP_SANITY_ASSERTIONS)
|
||||
if (subject_parent) {
|
||||
db::LocalProcessorContexts::contexts_per_cell_type::iterator pcc = contexts.context_map ().find (subject_parent);
|
||||
if (pcc == contexts.context_map ().end ()) {
|
||||
tl_assert (false);
|
||||
}
|
||||
tl_assert (pcc->first == subject_parent);
|
||||
bool any = false;
|
||||
for (db::LocalProcessorCellContexts::iterator pcci = pcc->second.begin (); pcci != pcc->second.end () && !any; ++pcci) {
|
||||
any = (&pcci->second == parent_context);
|
||||
}
|
||||
if (!any) {
|
||||
tl_assert (false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cell_context = cell_contexts.find_context (intruders);
|
||||
if (cell_context) {
|
||||
// we already have a context for this intruder scheme
|
||||
|
|
@ -1087,23 +1121,24 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp
|
|||
std::vector<db::cell_index_type> next_cells_bu;
|
||||
next_cells_bu.reserve (cells_bu.size ());
|
||||
|
||||
std::list<LocalProcessorResultComputationTask *> tasks;
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator bu = cells_bu.begin (); bu != cells_bu.end (); ++bu) {
|
||||
|
||||
if (later.find (*bu) == later.end ()) {
|
||||
LocalProcessorContexts::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu));
|
||||
if (cpc != contexts.context_map ().end ()) {
|
||||
|
||||
if (later.find (*bu) == later.end ()) {
|
||||
|
||||
LocalProcessorContexts::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu));
|
||||
if (cpc != contexts.context_map ().end ()) {
|
||||
rc_job->schedule (new LocalProcessorResultComputationTask (this, contexts, cpc->first, &cpc->second, op, output_layer));
|
||||
any = true;
|
||||
for (db::Cell::parent_cell_iterator pc = cpc->first->begin_parent_cells (); pc != cpc->first->end_parent_cells (); ++pc) {
|
||||
later.insert (*pc);
|
||||
}
|
||||
|
||||
} else {
|
||||
next_cells_bu.push_back (*bu);
|
||||
}
|
||||
|
||||
for (db::Cell::parent_cell_iterator pc = cpc->first->begin_parent_cells (); pc != cpc->first->end_parent_cells (); ++pc) {
|
||||
later.insert (*pc);
|
||||
}
|
||||
|
||||
} else {
|
||||
next_cells_bu.push_back (*bu);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ class DB_PUBLIC LocalProcessorCellContext
|
|||
{
|
||||
public:
|
||||
typedef std::pair<const db::Cell *, db::ICplxTrans> parent_inst_type;
|
||||
typedef std::vector<LocalProcessorCellDrop>::const_iterator drop_iterator;
|
||||
|
||||
LocalProcessorCellContext ();
|
||||
LocalProcessorCellContext (const LocalProcessorCellContext &other);
|
||||
|
|
@ -130,6 +131,18 @@ public:
|
|||
return m_lock;
|
||||
}
|
||||
|
||||
// used for debugging purposes only
|
||||
drop_iterator begin_drops () const
|
||||
{
|
||||
return m_drops.begin ();
|
||||
}
|
||||
|
||||
// used for debugging purposes only
|
||||
drop_iterator end_drops () const
|
||||
{
|
||||
return m_drops.end ();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<db::PolygonRef> m_propagated;
|
||||
std::vector<LocalProcessorCellDrop> m_drops;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,11 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
// count the number of gate shapes attached to this shape and distribute the area of the
|
||||
// diffusion region to the number of gates
|
||||
int n = rgates.selected_interacting (db::Region (*d)).size ();
|
||||
if (n == 0) { // @@@@
|
||||
printf("@@@ p=%s\n", p->box().to_string().c_str());
|
||||
printf("@@@ rdiff=%s\n", rdiff.to_string().c_str());
|
||||
printf("@@@ rgates=%s\n", rgates.to_string().c_str()); fflush(stdout);
|
||||
}
|
||||
tl_assert (n > 0);
|
||||
|
||||
device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, dbu () * dbu () * d->area () / double (n));
|
||||
|
|
|
|||
Loading…
Reference in New Issue