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 \
|
dbLayoutToNetlistWriter.h \
|
||||||
dbLayoutToNetlistFormatDefs.h \
|
dbLayoutToNetlistFormatDefs.h \
|
||||||
dbDeviceAbstract.h \
|
dbDeviceAbstract.h \
|
||||||
dbLocalOperationUtils.h
|
dbLocalOperationUtils.h \
|
||||||
|
dbDeepRegion.h
|
||||||
|
|
||||||
!equals(HAVE_QT, "0") {
|
!equals(HAVE_QT, "0") {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -772,6 +772,23 @@ LocalProcessorResultComputationTask::perform ()
|
||||||
// erase the contexts we don't need any longer
|
// erase the contexts we don't need any longer
|
||||||
{
|
{
|
||||||
tl::MutexLocker locker (& mp_contexts->lock ());
|
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);
|
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);
|
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);
|
cell_context = cell_contexts.find_context (intruders);
|
||||||
if (cell_context) {
|
if (cell_context) {
|
||||||
// we already have a context for this intruder scheme
|
// 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;
|
std::vector<db::cell_index_type> next_cells_bu;
|
||||||
next_cells_bu.reserve (cells_bu.size ());
|
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) {
|
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));
|
rc_job->schedule (new LocalProcessorResultComputationTask (this, contexts, cpc->first, &cpc->second, op, output_layer));
|
||||||
any = true;
|
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:
|
public:
|
||||||
typedef std::pair<const db::Cell *, db::ICplxTrans> parent_inst_type;
|
typedef std::pair<const db::Cell *, db::ICplxTrans> parent_inst_type;
|
||||||
|
typedef std::vector<LocalProcessorCellDrop>::const_iterator drop_iterator;
|
||||||
|
|
||||||
LocalProcessorCellContext ();
|
LocalProcessorCellContext ();
|
||||||
LocalProcessorCellContext (const LocalProcessorCellContext &other);
|
LocalProcessorCellContext (const LocalProcessorCellContext &other);
|
||||||
|
|
@ -130,6 +131,18 @@ public:
|
||||||
return m_lock;
|
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:
|
private:
|
||||||
std::unordered_set<db::PolygonRef> m_propagated;
|
std::unordered_set<db::PolygonRef> m_propagated;
|
||||||
std::vector<LocalProcessorCellDrop> m_drops;
|
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
|
// count the number of gate shapes attached to this shape and distribute the area of the
|
||||||
// diffusion region to the number of gates
|
// diffusion region to the number of gates
|
||||||
int n = rgates.selected_interacting (db::Region (*d)).size ();
|
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);
|
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));
|
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