mirror of https://github.com/KLayout/klayout.git
"breakout cells": attempt to provide a solution for SRAM
Breakout cells can be specified to shortcut hierarchy evaluation for some cells. This allows treating SRAM cells as isolated entities - specifically when it comes to extracting devices.
This commit is contained in:
parent
5c44a54676
commit
991778f718
|
|
@ -527,7 +527,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const
|
|||
|
||||
db::BoolAndOrNotLocalOperation op (and_op);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), m_deep_layer.breakout_cells (), other->deep_layer ().breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (m_deep_layer.store ()->threads ());
|
||||
proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ());
|
||||
|
|
@ -1501,7 +1501,9 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
|||
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()),
|
||||
const_cast<db::Cell *> (&polygons.initial_cell ()),
|
||||
other_deep ? &other_deep->deep_layer ().layout () : const_cast<db::Layout *> (&polygons.layout ()),
|
||||
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&polygons.initial_cell ()));
|
||||
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&polygons.initial_cell ()),
|
||||
m_deep_layer.breakout_cells (),
|
||||
other_deep ? other_deep->deep_layer ().breakout_cells () : 0);
|
||||
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
|
|
@ -1892,7 +1894,7 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to
|
|||
|
||||
db::InteractingLocalOperation op (mode, touching, inverse);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
if (split_after) {
|
||||
|
|
@ -1929,7 +1931,7 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse) cons
|
|||
|
||||
db::InteractingWithEdgeLocalOperation op (inverse);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::Edge, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
|
||||
db::local_processor<db::PolygonRef, db::Edge, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
if (split_after) {
|
||||
|
|
@ -1968,7 +1970,7 @@ DeepRegion::pull_generic (const Region &other, int mode, bool touching) const
|
|||
|
||||
db::PullLocalOperation op (mode, touching);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
if (split_after) {
|
||||
|
|
@ -2004,7 +2006,7 @@ DeepRegion::pull_generic (const Edges &other) const
|
|||
|
||||
db::PullWithEdgeLocalOperation op;
|
||||
|
||||
db::local_processor<db::PolygonRef, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell ());
|
||||
db::local_processor<db::PolygonRef, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell (), polygons.breakout_cells (), other_edges.breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
proc.run (&op, polygons.layer (), other_edges.layer (), dl_out.layer ());
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ DeepLayer &DeepLayer::operator= (const DeepLayer &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DeepLayer::~DeepLayer ()
|
||||
{
|
||||
if (mp_store.get ()) {
|
||||
|
|
@ -139,6 +138,12 @@ DeepLayer::add_from (const DeepLayer &dl)
|
|||
}
|
||||
}
|
||||
|
||||
const std::set<db::cell_index_type> *
|
||||
DeepLayer::breakout_cells () const
|
||||
{
|
||||
return store ()->breakout_cells (layout_index ());
|
||||
}
|
||||
|
||||
void
|
||||
DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
|
|
@ -251,16 +256,114 @@ struct DeepShapeStore::LayoutHolder
|
|||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
DeepShapeStoreState::DeepShapeStoreState ()
|
||||
: m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void DeepShapeStoreState::set_text_enlargement (int enl)
|
||||
{
|
||||
m_text_enlargement = enl;
|
||||
}
|
||||
|
||||
int DeepShapeStoreState::text_enlargement () const
|
||||
{
|
||||
return m_text_enlargement;
|
||||
}
|
||||
|
||||
void DeepShapeStoreState::set_text_property_name (const tl::Variant &pn)
|
||||
{
|
||||
m_text_property_name = pn;
|
||||
}
|
||||
|
||||
const tl::Variant &
|
||||
DeepShapeStoreState::text_property_name () const
|
||||
{
|
||||
return m_text_property_name;
|
||||
}
|
||||
|
||||
const std::set<db::cell_index_type> *
|
||||
DeepShapeStoreState::breakout_cells (unsigned int layout_index) const
|
||||
{
|
||||
const std::set<db::cell_index_type> &boc = (const_cast<DeepShapeStoreState *> (this))->ensure_breakout_cells (layout_index);
|
||||
if (boc.empty ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return &boc;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::clear_breakout_cells (unsigned int layout_index)
|
||||
{
|
||||
ensure_breakout_cells (layout_index).clear ();
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc)
|
||||
{
|
||||
ensure_breakout_cells (layout_index) = boc;
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci)
|
||||
{
|
||||
ensure_breakout_cells (layout_index).insert (ci);
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::add_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &cc)
|
||||
{
|
||||
ensure_breakout_cells (layout_index).insert (cc.begin (), cc.end ());
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::set_threads (int n)
|
||||
{
|
||||
m_threads = n;
|
||||
}
|
||||
|
||||
int
|
||||
DeepShapeStoreState::threads () const
|
||||
{
|
||||
return m_threads;
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::set_max_area_ratio (double ar)
|
||||
{
|
||||
m_max_area_ratio = ar;
|
||||
}
|
||||
|
||||
double
|
||||
DeepShapeStoreState::max_area_ratio () const
|
||||
{
|
||||
return m_max_area_ratio;
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStoreState::set_max_vertex_count (size_t n)
|
||||
{
|
||||
m_max_vertex_count = n;
|
||||
}
|
||||
|
||||
size_t
|
||||
DeepShapeStoreState::max_vertex_count () const
|
||||
{
|
||||
return m_max_vertex_count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
static size_t s_instance_count = 0;
|
||||
|
||||
DeepShapeStore::DeepShapeStore ()
|
||||
: m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1)
|
||||
{
|
||||
++s_instance_count;
|
||||
}
|
||||
|
||||
DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu)
|
||||
: m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1)
|
||||
{
|
||||
++s_instance_count;
|
||||
|
||||
|
|
@ -292,17 +395,17 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n
|
|||
unsigned int layer = layout ().insert_layer ();
|
||||
|
||||
if (max_area_ratio == 0.0) {
|
||||
max_area_ratio = m_max_area_ratio;
|
||||
max_area_ratio = m_state.max_area_ratio ();
|
||||
}
|
||||
if (max_vertex_count == 0) {
|
||||
max_vertex_count = m_max_vertex_count;
|
||||
max_vertex_count = m_state.max_vertex_count ();
|
||||
}
|
||||
|
||||
db::Shapes *shapes = &initial_cell ().shapes (layer);
|
||||
db::Box world = db::Box::world ();
|
||||
|
||||
// The chain of operators for producing clipped and reduced polygon references
|
||||
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), m_text_enlargement, m_text_property_name);
|
||||
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), text_enlargement (), text_property_name ());
|
||||
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count);
|
||||
|
||||
// try to maintain the texts on top level - go through shape iterator
|
||||
|
|
@ -399,12 +502,95 @@ const db::Cell &DeepShapeStore::const_initial_cell (unsigned int n) const
|
|||
|
||||
void DeepShapeStore::set_text_enlargement (int enl)
|
||||
{
|
||||
m_text_enlargement = enl;
|
||||
m_state.set_text_enlargement (enl);
|
||||
}
|
||||
|
||||
int DeepShapeStore::text_enlargement () const
|
||||
{
|
||||
return m_state.text_enlargement ();
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_text_property_name (const tl::Variant &pn)
|
||||
{
|
||||
m_text_property_name = pn;
|
||||
m_state.set_text_property_name (pn);
|
||||
}
|
||||
|
||||
const tl::Variant &DeepShapeStore::text_property_name () const
|
||||
{
|
||||
return m_state.text_property_name ();
|
||||
}
|
||||
|
||||
const std::set<db::cell_index_type> *
|
||||
DeepShapeStore::breakout_cells (unsigned int layout_index) const
|
||||
{
|
||||
return m_state.breakout_cells (layout_index);
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStore::clear_breakout_cells (unsigned int layout_index)
|
||||
{
|
||||
m_state.clear_breakout_cells (layout_index);
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStore::set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc)
|
||||
{
|
||||
m_state.set_breakout_cells (layout_index, boc);
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStore::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci)
|
||||
{
|
||||
m_state.add_breakout_cell (layout_index, ci);
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeStore::add_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &cc)
|
||||
{
|
||||
m_state.add_breakout_cells (layout_index, cc);
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_threads (int n)
|
||||
{
|
||||
m_state.set_threads (n);
|
||||
}
|
||||
|
||||
int DeepShapeStore::threads () const
|
||||
{
|
||||
return m_state.threads ();
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_max_area_ratio (double ar)
|
||||
{
|
||||
m_state.set_max_area_ratio (ar);
|
||||
}
|
||||
|
||||
double DeepShapeStore::max_area_ratio () const
|
||||
{
|
||||
return m_state.max_area_ratio ();
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_max_vertex_count (size_t n)
|
||||
{
|
||||
m_state.set_max_vertex_count (n);
|
||||
}
|
||||
|
||||
size_t DeepShapeStore::max_vertex_count () const
|
||||
{
|
||||
return m_state.max_vertex_count ();
|
||||
}
|
||||
|
||||
void DeepShapeStore::push_state ()
|
||||
{
|
||||
m_state_stack.push_back (m_state);
|
||||
}
|
||||
|
||||
void DeepShapeStore::pop_state ()
|
||||
{
|
||||
if (! m_state_stack.empty ()) {
|
||||
m_state = m_state_stack.back ();
|
||||
m_state_stack.pop_back ();
|
||||
}
|
||||
}
|
||||
|
||||
bool DeepShapeStore::is_valid_layout_index (unsigned int n) const
|
||||
|
|
@ -429,21 +615,6 @@ size_t DeepShapeStore::instance_count ()
|
|||
return s_instance_count;
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_threads (int n)
|
||||
{
|
||||
m_threads = n;
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_max_area_ratio (double ar)
|
||||
{
|
||||
m_max_area_ratio = ar;
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_max_vertex_count (size_t n)
|
||||
{
|
||||
m_max_vertex_count = n;
|
||||
}
|
||||
|
||||
void DeepShapeStore::add_ref (unsigned int layout, unsigned int layer)
|
||||
{
|
||||
tl::MutexLocker locker (&m_lock);
|
||||
|
|
@ -474,6 +645,7 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer)
|
|||
if ((m_layouts[layout]->refs -= 1) <= 0) {
|
||||
delete m_layouts[layout];
|
||||
m_layouts[layout] = 0;
|
||||
clear_breakout_cells (layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -542,10 +714,10 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter
|
|||
DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans)
|
||||
{
|
||||
if (max_area_ratio == 0.0) {
|
||||
max_area_ratio = m_max_area_ratio;
|
||||
max_area_ratio = m_state.max_area_ratio ();
|
||||
}
|
||||
if (max_vertex_count == 0) {
|
||||
max_vertex_count = m_max_vertex_count;
|
||||
max_vertex_count = m_state.max_vertex_count ();
|
||||
}
|
||||
|
||||
unsigned int layout_index = layout_for_iter (si, trans);
|
||||
|
|
@ -557,7 +729,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
|
|||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing clipped and reduced polygon references
|
||||
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, m_text_enlargement, m_text_property_name);
|
||||
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, text_enlargement (), text_property_name ());
|
||||
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count);
|
||||
db::ClippingHierarchyBuilderShapeReceiver clip (&red);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
namespace db {
|
||||
|
||||
class DeepShapeStore;
|
||||
class DeepShapeStoreState;
|
||||
class Region;
|
||||
class Edges;
|
||||
|
||||
|
|
@ -132,6 +133,13 @@ public:
|
|||
return m_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the list of breakout cells if there are some
|
||||
* "breakout cells" are cells which are not considered to participate in hierarchical operations,
|
||||
* neither as sibling nor in parent-child relationships.
|
||||
*/
|
||||
const std::set<db::cell_index_type> *breakout_cells () const;
|
||||
|
||||
/**
|
||||
* @brief Inserts the layer into the given layout, starting from the given cell and into the given layer
|
||||
*/
|
||||
|
|
@ -200,6 +208,52 @@ private:
|
|||
unsigned int m_layer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An object holding the state of a DeepShapeStore
|
||||
*/
|
||||
class DB_PUBLIC DeepShapeStoreState
|
||||
{
|
||||
public:
|
||||
DeepShapeStoreState ();
|
||||
|
||||
void set_threads (int n);
|
||||
int threads () const;
|
||||
|
||||
void set_max_vertex_count (size_t n);
|
||||
size_t max_vertex_count () const;
|
||||
|
||||
void set_max_area_ratio (double ar);
|
||||
double max_area_ratio () const;
|
||||
|
||||
void set_text_property_name (const tl::Variant &pn);
|
||||
const tl::Variant &text_property_name () const;
|
||||
|
||||
void set_text_enlargement (int enl);
|
||||
int text_enlargement () const;
|
||||
|
||||
const std::set<db::cell_index_type> *breakout_cells (unsigned int layout_index) const;
|
||||
void clear_breakout_cells (unsigned int layout_index);
|
||||
void set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc);
|
||||
void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci);
|
||||
void add_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &cc);
|
||||
|
||||
private:
|
||||
int m_threads;
|
||||
double m_max_area_ratio;
|
||||
size_t m_max_vertex_count;
|
||||
tl::Variant m_text_property_name;
|
||||
std::vector<std::set<db::cell_index_type> > m_breakout_cells;
|
||||
int m_text_enlargement;
|
||||
|
||||
std::set<db::cell_index_type> &ensure_breakout_cells (unsigned int layout_index)
|
||||
{
|
||||
if (m_breakout_cells.size () <= size_t (layout_index)) {
|
||||
m_breakout_cells.resize (layout_index + 1, std::set<db::cell_index_type> ());
|
||||
}
|
||||
return m_breakout_cells [layout_index];
|
||||
}
|
||||
};
|
||||
|
||||
struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy
|
||||
{
|
||||
bool operator () (const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &a, const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &b) const
|
||||
|
|
@ -514,10 +568,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the number of threads
|
||||
*/
|
||||
int threads () const
|
||||
{
|
||||
return m_threads;
|
||||
}
|
||||
int threads () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum vertex count default value
|
||||
|
|
@ -531,10 +582,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the maximum vertex count
|
||||
*/
|
||||
size_t max_vertex_count () const
|
||||
{
|
||||
return m_max_vertex_count;
|
||||
}
|
||||
size_t max_vertex_count () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the max. area ratio for bounding box vs. polygon area
|
||||
|
|
@ -548,10 +596,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the max. area ratio
|
||||
*/
|
||||
double max_area_ratio () const
|
||||
{
|
||||
return m_max_area_ratio;
|
||||
}
|
||||
double max_area_ratio () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the text property name
|
||||
|
|
@ -566,10 +611,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the text property name
|
||||
*/
|
||||
const tl::Variant &text_property_name () const
|
||||
{
|
||||
return m_text_property_name;
|
||||
}
|
||||
const tl::Variant &text_property_name () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the text enlargement value
|
||||
|
|
@ -584,10 +626,45 @@ public:
|
|||
/**
|
||||
* @brief Gets the text enlargement value
|
||||
*/
|
||||
int text_enlargement () const
|
||||
{
|
||||
return m_text_enlargement;
|
||||
}
|
||||
int text_enlargement () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the breakout cells for a given layout
|
||||
* Returns 0 if there are no breakout cells for this layout.
|
||||
*/
|
||||
const std::set<db::cell_index_type> *breakout_cells (unsigned int layout_index) const;
|
||||
|
||||
/**
|
||||
* @brief Clears the breakout cell list for a given layout
|
||||
*/
|
||||
void clear_breakout_cells (unsigned int layout_index);
|
||||
|
||||
/**
|
||||
* @brief Sets the breakout cell list for a given layout
|
||||
*/
|
||||
void set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc);
|
||||
|
||||
/**
|
||||
* @brief Adds a breakout cell for a given layout
|
||||
*/
|
||||
void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci);
|
||||
|
||||
/**
|
||||
* @brief Adds breakout cells for a given layout
|
||||
*/
|
||||
void add_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &cc);
|
||||
|
||||
/**
|
||||
* @brief Pushes the state on the state stack
|
||||
* The state involves threads, max_area_ratio, max_vertex_count, the breakout cells and
|
||||
* the text representation properties (enlargement, property name).
|
||||
*/
|
||||
void push_state ();
|
||||
|
||||
/**
|
||||
* @brief Pops the state (see @ref push_state)
|
||||
*/
|
||||
void pop_state ();
|
||||
|
||||
private:
|
||||
friend class DeepLayer;
|
||||
|
|
@ -614,11 +691,8 @@ private:
|
|||
std::map<size_t, std::pair<unsigned int, unsigned int> > m_layers_for_flat;
|
||||
std::map<std::pair<unsigned int, unsigned int>, size_t> m_flat_region_id;
|
||||
layout_map_type m_layout_map;
|
||||
int m_threads;
|
||||
double m_max_area_ratio;
|
||||
size_t m_max_vertex_count;
|
||||
tl::Variant m_text_property_name;
|
||||
int m_text_enlargement;
|
||||
DeepShapeStoreState m_state;
|
||||
std::list<DeepShapeStoreState> m_state_stack;
|
||||
tl::Mutex m_lock;
|
||||
|
||||
struct DeliveryMappingCacheKey
|
||||
|
|
|
|||
|
|
@ -1117,11 +1117,11 @@ void hier_clusters<T>::clear ()
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence)
|
||||
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
clear ();
|
||||
cell_clusters_box_converter<T> cbc (layout, *this);
|
||||
do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence);
|
||||
do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence, breakout_cells);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -1793,7 +1793,7 @@ hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, siz
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence)
|
||||
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters")));
|
||||
|
||||
|
|
@ -1835,7 +1835,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
|
|||
todo.push_back (*c);
|
||||
} else {
|
||||
tl_assert (! todo.empty ());
|
||||
build_hier_connections_for_cells (cbc, layout, todo, conn, progress);
|
||||
build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress);
|
||||
done.insert (todo.begin (), todo.end ());
|
||||
todo.clear ();
|
||||
todo.push_back (*c);
|
||||
|
|
@ -1845,7 +1845,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
|
|||
|
||||
}
|
||||
|
||||
build_hier_connections_for_cells (cbc, layout, todo, conn, progress);
|
||||
build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1865,10 +1865,10 @@ hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, tl::RelativeProgress &progress)
|
||||
hier_clusters<T>::build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, tl::RelativeProgress &progress)
|
||||
{
|
||||
for (std::vector<db::cell_index_type>::const_iterator c = cells.begin (); c != cells.end (); ++c) {
|
||||
build_hier_connections (cbc, layout, layout.cell (*c), conn);
|
||||
build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells);
|
||||
++progress;
|
||||
}
|
||||
}
|
||||
|
|
@ -1950,9 +1950,14 @@ private:
|
|||
|
||||
}
|
||||
|
||||
static bool is_breakout_cell (const std::set<db::cell_index_type> *breakout_cells, db::cell_index_type ci)
|
||||
{
|
||||
return breakout_cells && breakout_cells->find (ci) != breakout_cells->end ();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn)
|
||||
hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
std::string msg = tl::to_string (tr ("Computing hierarchical clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ()));
|
||||
if (tl::verbosity () >= m_base_verbosity + 20) {
|
||||
|
|
@ -1992,7 +1997,9 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
db::box_scanner<db::Instance, unsigned int> bs (true, desc);
|
||||
|
||||
for (std::vector<db::Instance>::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) {
|
||||
bs.insert (inst.operator-> (), 0);
|
||||
if (! is_breakout_cell (breakout_cells, inst->cell_index ())) {
|
||||
bs.insert (inst.operator-> (), 0);
|
||||
}
|
||||
}
|
||||
|
||||
bs.process (*rec, 1 /*touching*/, cibc);
|
||||
|
|
@ -2026,7 +2033,9 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
}
|
||||
|
||||
for (std::vector<db::Instance>::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) {
|
||||
bs2.insert2 (inst.operator-> (), 0);
|
||||
if (! is_breakout_cell (breakout_cells, inst->cell_index ())) {
|
||||
bs2.insert2 (inst.operator-> (), 0);
|
||||
}
|
||||
}
|
||||
|
||||
bs2.process (*rec, 1 /*touching*/, local_cluster_box_convert<T> (), cibc);
|
||||
|
|
|
|||
|
|
@ -912,7 +912,7 @@ public:
|
|||
/**
|
||||
* @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity
|
||||
*/
|
||||
void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence = 0);
|
||||
void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Gets the connected clusters for a given cell
|
||||
|
|
@ -951,9 +951,9 @@ public:
|
|||
|
||||
private:
|
||||
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence);
|
||||
void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn);
|
||||
void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, tl::RelativeProgress &progress);
|
||||
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence = 0);
|
||||
void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells);
|
||||
void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, tl::RelativeProgress &progress);
|
||||
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, const std::set<cell_index_type> *breakout_cells);
|
||||
|
||||
std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
|
||||
int m_base_verbosity;
|
||||
|
|
|
|||
|
|
@ -1046,15 +1046,21 @@ template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::E
|
|||
// LocalProcessor implementation
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
local_processor<TS, TI, TR>::local_processor (db::Layout *layout, db::Cell *top)
|
||||
: mp_subject_layout (layout), mp_intruder_layout (layout), mp_subject_top (top), mp_intruder_top (top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0)
|
||||
local_processor<TS, TI, TR>::local_processor (db::Layout *layout, db::Cell *top, const std::set<db::cell_index_type> *breakout_cells)
|
||||
: mp_subject_layout (layout), mp_intruder_layout (layout),
|
||||
mp_subject_top (top), mp_intruder_top (top),
|
||||
mp_subject_breakout_cells (breakout_cells), mp_intruder_breakout_cells (breakout_cells),
|
||||
m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
local_processor<TS, TI, TR>::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top)
|
||||
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), mp_subject_top (subject_top), mp_intruder_top (intruder_top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0)
|
||||
local_processor<TS, TI, TR>::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top, const std::set<cell_index_type> *subject_breakout_cells, const std::set<cell_index_type> *intruder_breakout_cells)
|
||||
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout),
|
||||
mp_subject_top (subject_top), mp_intruder_top (intruder_top),
|
||||
mp_subject_breakout_cells (subject_breakout_cells), mp_intruder_breakout_cells (intruder_breakout_cells),
|
||||
m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -1265,10 +1271,10 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
|
|||
|
||||
for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) {
|
||||
unsigned int iid = ++id;
|
||||
if (! inst_bcs (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert1 (&i->cell_inst (), iid);
|
||||
}
|
||||
if (! inst_bci (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert2 (&i->cell_inst (), iid);
|
||||
}
|
||||
}
|
||||
|
|
@ -1276,14 +1282,14 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
|
|||
} else {
|
||||
|
||||
for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) {
|
||||
if (! inst_bcs (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert1 (&i->cell_inst (), ++id);
|
||||
}
|
||||
}
|
||||
|
||||
if (intruder_cell) {
|
||||
for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) {
|
||||
if (! inst_bci (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert2 (&i->cell_inst (), ++id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1306,7 +1312,7 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
|
|||
interaction_registration_inst2shape<TI> rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions);
|
||||
|
||||
for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) {
|
||||
if (! inst_bcs (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert1 (&i->cell_inst (), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1701,7 +1707,7 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
|
|||
} else if (intruder_cell) {
|
||||
// TODO: can we confine this search to the subject's (sized) bounding box?
|
||||
for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) {
|
||||
if (! inst_bci (i->cell_inst ()).empty ()) {
|
||||
if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) {
|
||||
scanner.insert2 (&i->cell_inst (), ++inst_id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,8 +368,8 @@ template <class TS, class TI, class TR>
|
|||
class DB_PUBLIC local_processor
|
||||
{
|
||||
public:
|
||||
local_processor (db::Layout *layout, db::Cell *top);
|
||||
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell);
|
||||
local_processor (db::Layout *layout, db::Cell *top, const std::set<db::cell_index_type> *breakout_cells = 0);
|
||||
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0);
|
||||
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer);
|
||||
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer) const;
|
||||
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int output_layer) const;
|
||||
|
|
@ -427,6 +427,8 @@ private:
|
|||
const db::Layout *mp_intruder_layout;
|
||||
db::Cell *mp_subject_top;
|
||||
const db::Cell *mp_intruder_top;
|
||||
const std::set<db::cell_index_type> *mp_subject_breakout_cells;
|
||||
const std::set<db::cell_index_type> *mp_intruder_breakout_cells;
|
||||
std::string m_description;
|
||||
unsigned int m_nthreads;
|
||||
size_t m_max_vertex_count;
|
||||
|
|
@ -445,6 +447,16 @@ private:
|
|||
void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set<TR> &result) const;
|
||||
void compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::unordered_set<TR> &result) const;
|
||||
std::pair<bool, db::CellInstArray> effective_instance (local_processor_contexts<TS, TI, TR> &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const;
|
||||
|
||||
bool subject_cell_is_breakout (db::cell_index_type ci) const
|
||||
{
|
||||
return mp_subject_breakout_cells && mp_subject_breakout_cells->find (ci) != mp_subject_breakout_cells->end ();
|
||||
}
|
||||
|
||||
bool intruder_cell_is_breakout (db::cell_index_type ci) const
|
||||
{
|
||||
return mp_intruder_breakout_cells && mp_intruder_breakout_cells->find (ci) != mp_intruder_breakout_cells->end ();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ std::string NetlistDeviceExtractorError::to_string () const
|
|||
// NetlistDeviceExtractor implementation
|
||||
|
||||
NetlistDeviceExtractor::NetlistDeviceExtractor (const std::string &name)
|
||||
: mp_layout (0), m_cell_index (0), m_device_scaling (1.0), mp_circuit (0)
|
||||
: mp_layout (0), m_cell_index (0), mp_breakout_cells (0), m_device_scaling (1.0), mp_circuit (0)
|
||||
{
|
||||
m_name = name;
|
||||
m_terminal_id_propname_id = 0;
|
||||
|
|
@ -184,13 +184,13 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo
|
|||
|
||||
}
|
||||
|
||||
extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling);
|
||||
extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling, dss.breakout_cells (layout_index));
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling)
|
||||
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
initialize (nl);
|
||||
extract_without_initialize (layout, cell, clusters, layers, device_scaling);
|
||||
extract_without_initialize (layout, cell, clusters, layers, device_scaling, breakout_cells);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -203,7 +203,7 @@ struct ExtractorCacheValueType {
|
|||
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers, double device_scaling)
|
||||
void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers, double device_scaling, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
tl_assert (layers.size () == m_layer_definitions.size ());
|
||||
|
||||
|
|
@ -214,6 +214,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
m_layers = layers;
|
||||
mp_clusters = &clusters;
|
||||
m_device_scaling = device_scaling;
|
||||
mp_breakout_cells = breakout_cells;
|
||||
|
||||
// terminal properties are kept in a property with the terminal_property_name name
|
||||
m_terminal_id_propname_id = mp_layout->properties_repository ().prop_name_id (terminal_id_property_name ());
|
||||
|
|
@ -246,7 +247,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
|
||||
db::Connectivity device_conn = get_connectivity (layout, layers);
|
||||
db::hier_clusters<shape_type> device_clusters;
|
||||
device_clusters.build (layout, cell, shape_iter_flags, device_conn);
|
||||
device_clusters.build (layout, cell, shape_iter_flags, device_conn, 0, breakout_cells);
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices")));
|
||||
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ public:
|
|||
*
|
||||
* NOTE: The extractor expects "PolygonRef" type layers.
|
||||
*/
|
||||
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0);
|
||||
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Extracts the devices from a list of regions
|
||||
|
|
@ -533,6 +533,7 @@ private:
|
|||
db::properties_id_type m_terminal_id_propname_id, m_device_id_propname_id, m_device_class_propname_id;
|
||||
hier_clusters_type *mp_clusters;
|
||||
db::cell_index_type m_cell_index;
|
||||
const std::set<db::cell_index_type> *mp_breakout_cells;
|
||||
double m_device_scaling;
|
||||
db::Circuit *mp_circuit;
|
||||
db::DeviceClass *mp_device_class;
|
||||
|
|
@ -553,7 +554,7 @@ private:
|
|||
*/
|
||||
void initialize (db::Netlist *nl);
|
||||
|
||||
void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers, double device_scaling);
|
||||
void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers, double device_scaling, const std::set<cell_index_type> *breakout_cells);
|
||||
void push_new_devices (const Vector &disp_cache);
|
||||
void push_cached_devices (const tl::vector<Device *> &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,10 +22,78 @@
|
|||
|
||||
#include "gsiDecl.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
static void set_or_add_breakout_cells (db::DeepShapeStore *dss, const std::string &pattern, bool add, unsigned int layout_index = std::numeric_limits<unsigned int>::max ())
|
||||
{
|
||||
// set or add for all
|
||||
if (layout_index == std::numeric_limits<unsigned int>::max ()) {
|
||||
for (unsigned int l = 0; l < dss->layouts (); ++l) {
|
||||
set_or_add_breakout_cells (dss, pattern, add, l);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<db::cell_index_type> cc;
|
||||
|
||||
if (! pattern.empty ()) {
|
||||
tl::GlobPattern p (pattern);
|
||||
const db::Layout &ly = dss->layout (layout_index);
|
||||
for (db::Layout::const_iterator ci = ly.begin (); ci != ly.end (); ++ci) {
|
||||
if (p.match (ly.cell_name (ci->cell_index ()))) {
|
||||
cc.insert (ci->cell_index ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! add) {
|
||||
dss->clear_breakout_cells (layout_index);
|
||||
}
|
||||
if (! cc.empty ()) {
|
||||
dss->add_breakout_cells (layout_index, cc);
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_breakout_cells (db::DeepShapeStore *dss)
|
||||
{
|
||||
set_or_add_breakout_cells (dss, std::string (), false);
|
||||
}
|
||||
|
||||
static void set_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector<db::cell_index_type> &cc)
|
||||
{
|
||||
std::set<db::cell_index_type> cs (cc.begin (), cc.end ());
|
||||
dss->set_breakout_cells (layout_index, cs);
|
||||
}
|
||||
|
||||
static void set_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern)
|
||||
{
|
||||
set_or_add_breakout_cells (dss, pattern, false, layout_index);
|
||||
}
|
||||
|
||||
static void set_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern)
|
||||
{
|
||||
set_or_add_breakout_cells (dss, pattern, false);
|
||||
}
|
||||
|
||||
static void add_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector<db::cell_index_type> &cc)
|
||||
{
|
||||
std::set<db::cell_index_type> cs (cc.begin (), cc.end ());
|
||||
dss->add_breakout_cells (layout_index, cs);
|
||||
}
|
||||
|
||||
static void add_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern)
|
||||
{
|
||||
set_or_add_breakout_cells (dss, pattern, true, layout_index);
|
||||
}
|
||||
|
||||
static void add_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern)
|
||||
{
|
||||
set_or_add_breakout_cells (dss, pattern, true);
|
||||
}
|
||||
|
||||
Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
|
||||
gsi::method ("instance_count", &db::DeepShapeStore::instance_count,
|
||||
"@hide\n"
|
||||
|
|
@ -84,6 +152,82 @@ Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
|
|||
) +
|
||||
gsi::method ("text_enlargement", &db::DeepShapeStore::text_enlargement,
|
||||
"@brief Gets the text enlargement value.\n"
|
||||
) +
|
||||
gsi::method ("clear_breakout_cells", &db::DeepShapeStore::clear_breakout_cells, gsi::arg ("layout_index"),
|
||||
"@brief Clears the breakout cells\n"
|
||||
"Breakout cells are a feature by which hierarchy handling can be disabled for specific cells. "
|
||||
"If cells are specified as breakout cells, they don't interact with neighbor or parent cells, hence "
|
||||
"are virtually isolated. Breakout cells are useful to shortcut hierarchy evaluation for cells which "
|
||||
"are otherwise difficult to handle. An example are memory array cells with overlaps to their neighbors: "
|
||||
"a precise handling of such cells would generate variants and the boundary of the array. Although precise, "
|
||||
"this behavior leads to partial flattening and propagation of shapes. In consequence, this will also "
|
||||
"result in wrong device detection in LVS applications. In such cases, these array cells can be declared "
|
||||
"'breakout cells' which makes them isolated entities and variant generation does not happen.\n"
|
||||
"\n"
|
||||
"See also \\set_breakout_cells and \\add_breakout_cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("clear_breakout_cells", &clear_breakout_cells,
|
||||
"@brief Clears the breakout cells\n"
|
||||
"See the other variant of \\clear_breakout_cells for details.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("set_breakout_cells", &set_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"),
|
||||
"@brief Sets the breakout cell list (as cell indexes) for the given layout inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("set_breakout_cells", &set_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"),
|
||||
"@brief Sets the breakout cell list (as cell name pattern) for the given layout inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("set_breakout_cells", &set_breakout_cells3, gsi::arg ("pattern"),
|
||||
"@brief Sets the breakout cell list (as cell name pattern) for the all layouts inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("add_breakout_cells", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"),
|
||||
"@brief Adds cell indexes to the breakout cell list for the given layout inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("add_breakout_cell", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cell_index"),
|
||||
"@brief Adds a cell indexe to the breakout cell list for the given layout inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("add_breakout_cells", &add_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"),
|
||||
"@brief Adds cells (given by a cell name pattern) to the breakout cell list for the given layout inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method_ext ("add_breakout_cells", &add_breakout_cells3, gsi::arg ("pattern"),
|
||||
"@brief Adds cells (given by a cell name pattern) to the breakout cell list to all layouts inside the store\n"
|
||||
"See \\clear_breakout_cells for an explanation of breakout cells.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method ("push_state", &db::DeepShapeStore::push_state,
|
||||
"@brief Pushes the store's state on the state state\n"
|
||||
"This will save the stores state (\\threads, \\max_vertex_count, \\max_area_ratio, breakout cells ...) on "
|
||||
"the state stack. \\pop_state can be used to restore the state.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
) +
|
||||
gsi::method ("pop_state", &db::DeepShapeStore::pop_state,
|
||||
"@brief Restores the store's state on the state state\n"
|
||||
"This will restore the state pushed by \\push_state.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26.1\n"
|
||||
),
|
||||
"@brief An opaque layout heap for the deep region processor\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "tlGlobPattern.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
|
@ -801,7 +803,7 @@ Class<db::Region> decl_Region ("db", "Region",
|
|||
"See \\strict_handling= for a description of this attribute.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.2."
|
||||
) +
|
||||
) +
|
||||
method ("min_coherence=", &db::Region::set_min_coherence, gsi::arg ("f"),
|
||||
"@brief Enable or disable minimum coherence\n"
|
||||
"If minimum coherence is set, the merge operations (explicit merge with \\merge or\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue