"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:
Matthias Koefferlein 2019-10-16 00:49:41 +02:00
parent 5c44a54676
commit 991778f718
11 changed files with 515 additions and 92 deletions

View File

@ -527,7 +527,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const
db::BoolAndOrNotLocalOperation op (and_op); 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_base_verbosity (base_verbosity ());
proc.set_threads (m_deep_layer.store ()->threads ()); proc.set_threads (m_deep_layer.store ()->threads ());
proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ()); 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 ()), db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()),
const_cast<db::Cell *> (&polygons.initial_cell ()), 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 ().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_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); 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::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_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); proc.set_threads (polygons.store ()->threads ());
if (split_after) { if (split_after) {
@ -1929,7 +1931,7 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse) cons
db::InteractingWithEdgeLocalOperation op (inverse); 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_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); proc.set_threads (polygons.store ()->threads ());
if (split_after) { if (split_after) {
@ -1968,7 +1970,7 @@ DeepRegion::pull_generic (const Region &other, int mode, bool touching) const
db::PullLocalOperation op (mode, touching); 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_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); proc.set_threads (polygons.store ()->threads ());
if (split_after) { if (split_after) {
@ -2004,7 +2006,7 @@ DeepRegion::pull_generic (const Edges &other) const
db::PullWithEdgeLocalOperation op; 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_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); proc.set_threads (polygons.store ()->threads ());
proc.run (&op, polygons.layer (), other_edges.layer (), dl_out.layer ()); proc.run (&op, polygons.layer (), other_edges.layer (), dl_out.layer ());

View File

@ -81,7 +81,6 @@ DeepLayer &DeepLayer::operator= (const DeepLayer &other)
return *this; return *this;
} }
DeepLayer::~DeepLayer () DeepLayer::~DeepLayer ()
{ {
if (mp_store.get ()) { 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 void
DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const 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; static size_t s_instance_count = 0;
DeepShapeStore::DeepShapeStore () 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; ++s_instance_count;
} }
DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu) 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; ++s_instance_count;
@ -292,17 +395,17 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region &region, bool for_n
unsigned int layer = layout ().insert_layer (); unsigned int layer = layout ().insert_layer ();
if (max_area_ratio == 0.0) { 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) { 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::Shapes *shapes = &initial_cell ().shapes (layer);
db::Box world = db::Box::world (); db::Box world = db::Box::world ();
// The chain of operators for producing clipped and reduced polygon references // 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::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count);
// try to maintain the texts on top level - go through shape iterator // 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) 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) 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 bool DeepShapeStore::is_valid_layout_index (unsigned int n) const
@ -429,21 +615,6 @@ size_t DeepShapeStore::instance_count ()
return s_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) void DeepShapeStore::add_ref (unsigned int layout, unsigned int layer)
{ {
tl::MutexLocker locker (&m_lock); 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) { if ((m_layouts[layout]->refs -= 1) <= 0) {
delete m_layouts[layout]; delete m_layouts[layout];
m_layouts[layout] = 0; 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) 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) { 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) { 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); 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); builder.set_target_layer (layer_index);
// The chain of operators for producing clipped and reduced polygon references // 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::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count);
db::ClippingHierarchyBuilderShapeReceiver clip (&red); db::ClippingHierarchyBuilderShapeReceiver clip (&red);

View File

@ -40,6 +40,7 @@
namespace db { namespace db {
class DeepShapeStore; class DeepShapeStore;
class DeepShapeStoreState;
class Region; class Region;
class Edges; class Edges;
@ -132,6 +133,13 @@ public:
return m_layout; 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 * @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; 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 struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy
{ {
bool operator () (const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &a, const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &b) const 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 * @brief Gets the number of threads
*/ */
int threads () const int threads () const;
{
return m_threads;
}
/** /**
* @brief Sets the maximum vertex count default value * @brief Sets the maximum vertex count default value
@ -531,10 +582,7 @@ public:
/** /**
* @brief Gets the maximum vertex count * @brief Gets the maximum vertex count
*/ */
size_t max_vertex_count () const size_t max_vertex_count () const;
{
return m_max_vertex_count;
}
/** /**
* @brief Sets the max. area ratio for bounding box vs. polygon area * @brief Sets the max. area ratio for bounding box vs. polygon area
@ -548,10 +596,7 @@ public:
/** /**
* @brief Gets the max. area ratio * @brief Gets the max. area ratio
*/ */
double max_area_ratio () const double max_area_ratio () const;
{
return m_max_area_ratio;
}
/** /**
* @brief Sets the text property name * @brief Sets the text property name
@ -566,10 +611,7 @@ public:
/** /**
* @brief Gets the text property name * @brief Gets the text property name
*/ */
const tl::Variant &text_property_name () const const tl::Variant &text_property_name () const;
{
return m_text_property_name;
}
/** /**
* @brief Sets the text enlargement value * @brief Sets the text enlargement value
@ -584,10 +626,45 @@ public:
/** /**
* @brief Gets the text enlargement value * @brief Gets the text enlargement value
*/ */
int text_enlargement () const int text_enlargement () const;
{
return m_text_enlargement; /**
} * @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: private:
friend class DeepLayer; friend class DeepLayer;
@ -614,11 +691,8 @@ private:
std::map<size_t, std::pair<unsigned int, unsigned int> > m_layers_for_flat; 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; std::map<std::pair<unsigned int, unsigned int>, size_t> m_flat_region_id;
layout_map_type m_layout_map; layout_map_type m_layout_map;
int m_threads; DeepShapeStoreState m_state;
double m_max_area_ratio; std::list<DeepShapeStoreState> m_state_stack;
size_t m_max_vertex_count;
tl::Variant m_text_property_name;
int m_text_enlargement;
tl::Mutex m_lock; tl::Mutex m_lock;
struct DeliveryMappingCacheKey struct DeliveryMappingCacheKey

View File

@ -1117,11 +1117,11 @@ void hier_clusters<T>::clear ()
template <class T> template <class T>
void 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 (); clear ();
cell_clusters_box_converter<T> cbc (layout, *this); 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 namespace
@ -1793,7 +1793,7 @@ hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, siz
template <class T> template <class T>
void 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"))); 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); todo.push_back (*c);
} else { } else {
tl_assert (! todo.empty ()); 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 ()); done.insert (todo.begin (), todo.end ());
todo.clear (); todo.clear ();
todo.push_back (*c); 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> template <class T>
void 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) { 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; ++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> template <class T>
void 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 ())); 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) { 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); 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) { 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); 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) { 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); bs2.process (*rec, 1 /*touching*/, local_cluster_box_convert<T> (), cibc);

View File

@ -912,7 +912,7 @@ public:
/** /**
* @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity * @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 * @brief Gets the connected clusters for a given cell
@ -951,9 +951,9 @@ public:
private: 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_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 (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, tl::RelativeProgress &progress); 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 = 0); 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; std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
int m_base_verbosity; int m_base_verbosity;

View File

@ -1046,15 +1046,21 @@ template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::E
// LocalProcessor implementation // LocalProcessor implementation
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
local_processor<TS, TI, TR>::local_processor (db::Layout *layout, db::Cell *top) 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), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) : 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 .. // .. nothing yet ..
} }
template <class TS, class TI, class TR> 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) 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), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) : 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 .. // .. 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) { for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) {
unsigned int iid = ++id; 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); 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); scanner.insert2 (&i->cell_inst (), iid);
} }
} }
@ -1276,14 +1282,14 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
} else { } else {
for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) { 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); scanner.insert1 (&i->cell_inst (), ++id);
} }
} }
if (intruder_cell) { if (intruder_cell) {
for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) { 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); 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); 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) { 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); 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) { } else if (intruder_cell) {
// TODO: can we confine this search to the subject's (sized) bounding box? // 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) { 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); scanner.insert2 (&i->cell_inst (), ++inst_id);
} }
} }

View File

@ -368,8 +368,8 @@ template <class TS, class TI, class TR>
class DB_PUBLIC local_processor class DB_PUBLIC local_processor
{ {
public: public:
local_processor (db::Layout *layout, db::Cell *top); 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); 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 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_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; 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; const db::Layout *mp_intruder_layout;
db::Cell *mp_subject_top; db::Cell *mp_subject_top;
const db::Cell *mp_intruder_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; std::string m_description;
unsigned int m_nthreads; unsigned int m_nthreads;
size_t m_max_vertex_count; 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 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; 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; 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 ();
}
}; };
} }

View File

@ -75,7 +75,7 @@ std::string NetlistDeviceExtractorError::to_string () const
// NetlistDeviceExtractor implementation // NetlistDeviceExtractor implementation
NetlistDeviceExtractor::NetlistDeviceExtractor (const std::string &name) 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_name = name;
m_terminal_id_propname_id = 0; 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); initialize (nl);
extract_without_initialize (layout, cell, clusters, layers, device_scaling); extract_without_initialize (layout, cell, clusters, layers, device_scaling, breakout_cells);
} }
namespace { 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 ()); tl_assert (layers.size () == m_layer_definitions.size ());
@ -214,6 +214,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
m_layers = layers; m_layers = layers;
mp_clusters = &clusters; mp_clusters = &clusters;
m_device_scaling = device_scaling; m_device_scaling = device_scaling;
mp_breakout_cells = breakout_cells;
// terminal properties are kept in a property with the terminal_property_name name // 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 ()); 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::Connectivity device_conn = get_connectivity (layout, layers);
db::hier_clusters<shape_type> device_clusters; 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"))); tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices")));

View File

@ -263,7 +263,7 @@ public:
* *
* NOTE: The extractor expects "PolygonRef" type layers. * 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 * @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; db::properties_id_type m_terminal_id_propname_id, m_device_id_propname_id, m_device_class_propname_id;
hier_clusters_type *mp_clusters; hier_clusters_type *mp_clusters;
db::cell_index_type m_cell_index; db::cell_index_type m_cell_index;
const std::set<db::cell_index_type> *mp_breakout_cells;
double m_device_scaling; double m_device_scaling;
db::Circuit *mp_circuit; db::Circuit *mp_circuit;
db::DeviceClass *mp_device_class; db::DeviceClass *mp_device_class;
@ -553,7 +554,7 @@ private:
*/ */
void initialize (db::Netlist *nl); 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_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); void push_cached_devices (const tl::vector<Device *> &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp);
}; };

View File

@ -22,10 +22,78 @@
#include "gsiDecl.h" #include "gsiDecl.h"
#include "dbDeepShapeStore.h" #include "dbDeepShapeStore.h"
#include "tlGlobPattern.h"
namespace gsi 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", Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
gsi::method ("instance_count", &db::DeepShapeStore::instance_count, gsi::method ("instance_count", &db::DeepShapeStore::instance_count,
"@hide\n" "@hide\n"
@ -84,6 +152,82 @@ Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
) + ) +
gsi::method ("text_enlargement", &db::DeepShapeStore::text_enlargement, gsi::method ("text_enlargement", &db::DeepShapeStore::text_enlargement,
"@brief Gets the text enlargement value.\n" "@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" "@brief An opaque layout heap for the deep region processor\n"
"\n" "\n"

View File

@ -35,6 +35,8 @@
#include "tlGlobPattern.h" #include "tlGlobPattern.h"
#include <memory> #include <memory>
#include <vector>
#include <set>
namespace gsi namespace gsi
{ {
@ -801,7 +803,7 @@ Class<db::Region> decl_Region ("db", "Region",
"See \\strict_handling= for a description of this attribute.\n" "See \\strict_handling= for a description of this attribute.\n"
"\n" "\n"
"This method has been introduced in version 0.23.2." "This method has been introduced in version 0.23.2."
) + ) +
method ("min_coherence=", &db::Region::set_min_coherence, gsi::arg ("f"), method ("min_coherence=", &db::Region::set_min_coherence, gsi::arg ("f"),
"@brief Enable or disable minimum coherence\n" "@brief Enable or disable minimum coherence\n"
"If minimum coherence is set, the merge operations (explicit merge with \\merge or\n" "If minimum coherence is set, the merge operations (explicit merge with \\merge or\n"