mirror of https://github.com/KLayout/klayout.git
WIP: More testcases, better test coverage, some bug fixes
This commit is contained in:
parent
d7099edcae
commit
c1b0892641
|
|
@ -322,7 +322,10 @@ public:
|
||||||
|
|
||||||
void add (const db::CellInstArray *inst1, int, const db::CellInstArray *inst2, int)
|
void add (const db::CellInstArray *inst1, int, const db::CellInstArray *inst2, int)
|
||||||
{
|
{
|
||||||
(*mp_result) [inst1].first.insert (inst2);
|
// @@@ TODO: always insert, if both instances come from different layouts
|
||||||
|
if (*inst1 != *inst2) {
|
||||||
|
(*mp_result) [inst1].first.insert (inst2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -361,21 +364,8 @@ LocalProcessor::LocalProcessor (db::Layout *layout, db::Cell *top, LocalOperatio
|
||||||
|
|
||||||
void LocalProcessor::run ()
|
void LocalProcessor::run ()
|
||||||
{
|
{
|
||||||
try {
|
compute_contexts ();
|
||||||
|
compute_results ();
|
||||||
mp_layout->update ();
|
|
||||||
mp_layout->start_changes ();
|
|
||||||
|
|
||||||
std::pair<std::set<db::CellInstArray>, std::set<db::PolygonRef> > intruders;
|
|
||||||
compute_contexts (0, 0, mp_top, db::ICplxTrans (), intruders);
|
|
||||||
compute_results ();
|
|
||||||
|
|
||||||
mp_layout->end_changes ();
|
|
||||||
|
|
||||||
} catch (...) {
|
|
||||||
mp_layout->end_changes ();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalProcessor::push_results (db::Cell *cell, const std::set<db::PolygonRef> &result)
|
void LocalProcessor::push_results (db::Cell *cell, const std::set<db::PolygonRef> &result)
|
||||||
|
|
@ -385,6 +375,14 @@ void LocalProcessor::push_results (db::Cell *cell, const std::set<db::PolygonRef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalProcessor::compute_contexts ()
|
||||||
|
{
|
||||||
|
m_contexts_per_cell.clear ();
|
||||||
|
|
||||||
|
std::pair<std::set<db::CellInstArray>, std::set<db::PolygonRef> > intruders;
|
||||||
|
compute_contexts (0, 0, mp_top, db::ICplxTrans (), intruders);
|
||||||
|
}
|
||||||
|
|
||||||
void LocalProcessor::compute_contexts (db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders)
|
void LocalProcessor::compute_contexts (db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders)
|
||||||
{
|
{
|
||||||
db::LocalProcessorCellContexts &contexts = m_contexts_per_cell [cell];
|
db::LocalProcessorCellContexts &contexts = m_contexts_per_cell [cell];
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,11 @@ public:
|
||||||
return m_propagated;
|
return m_propagated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t size () const
|
||||||
|
{
|
||||||
|
return m_drops.size ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<db::PolygonRef> m_propagated;
|
std::set<db::PolygonRef> m_propagated;
|
||||||
std::vector<LocalProcessorCellDrop> m_drops;
|
std::vector<LocalProcessorCellDrop> m_drops;
|
||||||
|
|
@ -98,6 +103,8 @@ class DB_PLUGIN_PUBLIC LocalProcessorCellContexts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > key_type;
|
typedef std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > key_type;
|
||||||
|
typedef std::map<key_type, db::LocalProcessorCellContext> map_type;
|
||||||
|
typedef map_type::const_iterator iterator;
|
||||||
|
|
||||||
LocalProcessorCellContexts ();
|
LocalProcessorCellContexts ();
|
||||||
|
|
||||||
|
|
@ -105,6 +112,16 @@ public:
|
||||||
db::LocalProcessorCellContext *create (const key_type &intruders);
|
db::LocalProcessorCellContext *create (const key_type &intruders);
|
||||||
void compute_results (db::Cell *cell, LocalProcessor *proc);
|
void compute_results (db::Cell *cell, LocalProcessor *proc);
|
||||||
|
|
||||||
|
iterator begin () const
|
||||||
|
{
|
||||||
|
return m_contexts.begin ();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end () const
|
||||||
|
{
|
||||||
|
return m_contexts.end ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<key_type, db::LocalProcessorCellContext> m_contexts;
|
std::map<key_type, db::LocalProcessorCellContext> m_contexts;
|
||||||
};
|
};
|
||||||
|
|
@ -112,12 +129,20 @@ private:
|
||||||
class DB_PLUGIN_PUBLIC LocalProcessor
|
class DB_PLUGIN_PUBLIC LocalProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::map<db::Cell *, LocalProcessorCellContexts> contexts_per_cell_type;
|
||||||
|
|
||||||
LocalProcessor (db::Layout *layout, db::Cell *top, LocalOperation *op, unsigned int scope_layer, unsigned int intruder_layer, unsigned int output_layer);
|
LocalProcessor (db::Layout *layout, db::Cell *top, LocalOperation *op, unsigned int scope_layer, unsigned int intruder_layer, unsigned int output_layer);
|
||||||
void run ();
|
void run ();
|
||||||
|
void compute_contexts ();
|
||||||
|
void compute_results ();
|
||||||
|
|
||||||
|
const contexts_per_cell_type &contexts_per_cell () const
|
||||||
|
{
|
||||||
|
return m_contexts_per_cell;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class LocalProcessorCellContexts;
|
friend class LocalProcessorCellContexts;
|
||||||
typedef std::map<db::Cell *, LocalProcessorCellContexts> contexts_per_cell_type;
|
|
||||||
|
|
||||||
db::Layout *mp_layout;
|
db::Layout *mp_layout;
|
||||||
db::Cell *mp_top;
|
db::Cell *mp_top;
|
||||||
|
|
@ -126,7 +151,6 @@ private:
|
||||||
LocalOperation *mp_op;
|
LocalOperation *mp_op;
|
||||||
|
|
||||||
void compute_contexts (db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders);
|
void compute_contexts (db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders);
|
||||||
void compute_results ();
|
|
||||||
void push_results (db::Cell *cell, const std::set<db::PolygonRef> &result);
|
void push_results (db::Cell *cell, const std::set<db::PolygonRef> &result);
|
||||||
void compute_local_cell (db::Cell *cell, const std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > &intruders, std::set<db::PolygonRef> &result) const;
|
void compute_local_cell (db::Cell *cell, const std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > &intruders, std::set<db::PolygonRef> &result) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -56,7 +56,26 @@ void normalize_layer (db::Layout &layout, unsigned int layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num)
|
|
||||||
|
std::string contexts_to_s (db::Layout *layout, const db::LocalProcessor::contexts_per_cell_type &contexts)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
for (db::Layout::top_down_const_iterator i = layout->begin_top_down (); i != layout->end_top_down(); ++i) {
|
||||||
|
db::LocalProcessor::contexts_per_cell_type::const_iterator cc = contexts.find (&layout->cell (*i));
|
||||||
|
if (cc != contexts.end ()) {
|
||||||
|
int index = 1;
|
||||||
|
for (db::LocalProcessorCellContexts::iterator j = cc->second.begin (); j != cc->second.end (); ++j) {
|
||||||
|
res += tl::sprintf ("%s[%d] %d insts, %d shapes (%d times)\n", layout->cell_name (*i), index, int (j->first.first.size ()), int (j->first.second.size ()), int (j->second.size ()));
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc = 0)
|
||||||
{
|
{
|
||||||
db::Layout layout_org;
|
db::Layout layout_org;
|
||||||
|
|
||||||
|
|
@ -96,7 +115,14 @@ void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int ou
|
||||||
|
|
||||||
db::BoolAndOrNotLocalOperation op (mode == TMAnd);
|
db::BoolAndOrNotLocalOperation op (mode == TMAnd);
|
||||||
db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ()), &op, l1, l2, lout);
|
db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ()), &op, l1, l2, lout);
|
||||||
proc.run ();
|
|
||||||
|
if (! context_doc) {
|
||||||
|
proc.run ();
|
||||||
|
} else {
|
||||||
|
proc.compute_contexts ();
|
||||||
|
*context_doc = contexts_to_s (&layout_org, proc.contexts_per_cell ());
|
||||||
|
proc.compute_results ();
|
||||||
|
}
|
||||||
|
|
||||||
db::compare_layouts (_this, layout_org, testdata (file), lmap, false /*skip other layers*/, db::AsPolygons);
|
db::compare_layouts (_this, layout_org, testdata (file), lmap, false /*skip other layers*/, db::AsPolygons);
|
||||||
}
|
}
|
||||||
|
|
@ -184,3 +210,34 @@ TEST(BasicNot7)
|
||||||
// Context replication - direct and indirect, NOT
|
// Context replication - direct and indirect, NOT
|
||||||
run_test_bool (_this, "hlp7.oas", TMNot, 101);
|
run_test_bool (_this, "hlp7.oas", TMNot, 101);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BasicAnd8)
|
||||||
|
{
|
||||||
|
// Mixed sibling-parent contexts, AND
|
||||||
|
run_test_bool (_this, "hlp8.oas", TMAnd, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicNot8)
|
||||||
|
{
|
||||||
|
// Mixed sibling-parent contexts, NOT
|
||||||
|
run_test_bool (_this, "hlp8.oas", TMNot, 101);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicAnd9)
|
||||||
|
{
|
||||||
|
// Top-level ring structure, AND
|
||||||
|
std::string doc;
|
||||||
|
run_test_bool (_this, "hlp9.oas", TMAnd, 100, &doc);
|
||||||
|
EXPECT_EQ (doc,
|
||||||
|
"TOP[1] 0 insts, 0 shapes (1 times)\n"
|
||||||
|
"RING[1] 0 insts, 12 shapes (1 times)\n"
|
||||||
|
"CHILD1[1] 1 insts, 6 shapes (1 times)\n"
|
||||||
|
"CHILD1[2] 1 insts, 6 shapes (1 times)\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicNot9)
|
||||||
|
{
|
||||||
|
// Top-level ring structure, NOT
|
||||||
|
run_test_bool (_this, "hlp9.oas", TMNot, 101);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue