Generalization of layout index for LayoutToNetlist

This commit is contained in:
Matthias Koefferlein 2019-03-03 18:10:52 +01:00
parent 49621aa13a
commit 604a634bf1
11 changed files with 95 additions and 76 deletions

View File

@ -481,6 +481,25 @@ DeepShapeStore::layout_for_iter (const db::RecursiveShapeIterator &si, const db:
} }
} }
void DeepShapeStore::make_layout (unsigned int layout_index, const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{
tl_assert (m_layout_map.find (std::make_pair (si, trans)) == m_layout_map.end ());
while (m_layouts.size () <= layout_index) {
m_layouts.push_back (0);
}
m_layouts[layout_index] = new LayoutHolder (trans);
db::Layout &layout = m_layouts[layout_index]->layout;
layout.hier_changed_event.add (this, &DeepShapeStore::invalidate_hier);
if (si.layout ()) {
layout.dbu (si.layout ()->dbu () / trans.mag ());
}
m_layout_map[std::make_pair (si, trans)] = layout_index;
}
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) {

View File

@ -283,6 +283,14 @@ public:
*/ */
std::pair<bool, DeepLayer> layer_for_flat (size_t region_id) const; std::pair<bool, DeepLayer> layer_for_flat (size_t region_id) const;
/**
* @brief Creates a layout with the given iterator and transformation for the given index
*
* This method is intended for classes that need more control over the layouts per index
* (LayoutToNetlist).
*/
void make_layout (unsigned int layout_index, const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans = db::ICplxTrans ());
/** /**
* @brief Inserts a polygon layer into the deep shape store * @brief Inserts a polygon layer into the deep shape store
* *

View File

@ -30,46 +30,51 @@
namespace db namespace db
{ {
static const unsigned int singular_layout_index = 0;
// the iterator provides the hierarchical selection (enabling/disabling cells etc.) // the iterator provides the hierarchical selection (enabling/disabling cells etc.)
LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter) LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter)
: m_iter (iter), m_netlist_extracted (false), m_is_flat (false) : m_iter (iter), m_layout_index (0), m_netlist_extracted (false), m_is_flat (false)
{ {
// check the iterator // check the iterator
if (iter.has_complex_region () || iter.region () != db::Box::world ()) { if (iter.has_complex_region () || iter.region () != db::Box::world ()) {
throw tl::Exception (tl::to_string (tr ("The netlist extractor cannot work on clipped layouts"))); throw tl::Exception (tl::to_string (tr ("The netlist extractor cannot work on clipped layouts")));
} }
mp_internal_dss.reset (new db::DeepShapeStore ());
mp_dss.reset (mp_internal_dss.get ());
// the dummy layer acts as a reference holder for the layout
// NOTE: this probably can be done better
db::RecursiveShapeIterator empty_iter = iter;
empty_iter.set_layers (std::vector<unsigned int> ());
m_dummy_layer = dss ().create_polygon_layer (empty_iter);
init (); init ();
} }
LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index) LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index)
: mp_dss (dss), m_netlist_extracted (false), m_is_flat (false) : mp_dss (dss), m_layout_index (layout_index), m_netlist_extracted (false), m_is_flat (false)
{ {
m_iter = db::RecursiveShapeIterator (dss->layout (layout_index), dss->initial_cell (layout_index), std::set<unsigned int> ()); if (dss->is_valid_layout_index (m_layout_index)) {
m_iter = db::RecursiveShapeIterator (dss->layout (m_layout_index), dss->initial_cell (m_layout_index), std::set<unsigned int> ());
}
init (); init ();
} }
LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss)
: mp_dss (dss), m_netlist_extracted (false), m_is_flat (false)
{
init ();
}
LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu) LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu)
: m_iter (), m_netlist_extracted (false), m_is_flat (true) : m_iter (), m_netlist_extracted (false), m_is_flat (true)
{ {
mp_internal_dss.reset (new db::DeepShapeStore (topcell_name, dbu)); mp_internal_dss.reset (new db::DeepShapeStore (topcell_name, dbu));
mp_dss.reset (mp_internal_dss.get ()); mp_dss.reset (mp_internal_dss.get ());
m_layout_index = 0 ;
init (); init ();
} }
LayoutToNetlist::LayoutToNetlist () LayoutToNetlist::LayoutToNetlist ()
: m_iter (), mp_internal_dss (new db::DeepShapeStore ()), mp_dss (mp_internal_dss.get ()), m_netlist_extracted (false), m_is_flat (false) : m_iter (), mp_internal_dss (new db::DeepShapeStore ()), mp_dss (mp_internal_dss.get ()), m_layout_index (0),
m_netlist_extracted (false), m_is_flat (false)
{ {
init (); init ();
} }
@ -86,11 +91,6 @@ LayoutToNetlist::~LayoutToNetlist ()
void LayoutToNetlist::init () void LayoutToNetlist::init ()
{ {
if (! mp_dss.get ()) {
mp_internal_dss.reset (new db::DeepShapeStore ());
mp_dss.reset (mp_internal_dss.get ());
}
dss ().set_text_enlargement (1); dss ().set_text_enlargement (1);
dss ().set_text_property_name (tl::Variant ("LABEL")); dss ().set_text_property_name (tl::Variant ("LABEL"));
} }
@ -184,7 +184,7 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
if (! mp_netlist.get ()) { if (! mp_netlist.get ()) {
mp_netlist.reset (new db::Netlist ()); mp_netlist.reset (new db::Netlist ());
} }
extractor.extract(dss (), layers, *mp_netlist, m_net_clusters); extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters);
} }
void LayoutToNetlist::connect (const db::Region &l) void LayoutToNetlist::connect (const db::Region &l)
@ -261,7 +261,7 @@ void LayoutToNetlist::extract_netlist (bool join_nets_by_label)
} }
db::NetlistExtractor netex; db::NetlistExtractor netex;
netex.extract_nets(dss (), m_conn, *mp_netlist, m_net_clusters, join_nets_by_label); netex.extract_nets (dss (), m_layout_index, m_conn, *mp_netlist, m_net_clusters, join_nets_by_label);
m_netlist_extracted = true; m_netlist_extracted = true;
} }
@ -273,30 +273,40 @@ void LayoutToNetlist::set_netlist_extracted ()
const db::Layout *LayoutToNetlist::internal_layout () const const db::Layout *LayoutToNetlist::internal_layout () const
{ {
return &dss ().const_layout (); ensure_layout ();
return &dss ().const_layout (m_layout_index);
} }
const db::Cell *LayoutToNetlist::internal_top_cell () const const db::Cell *LayoutToNetlist::internal_top_cell () const
{ {
return &dss ().const_initial_cell (); ensure_layout ();
} return &dss ().const_initial_cell (m_layout_index);
void LayoutToNetlist::ensure_internal_layout ()
{
if (dss ().layouts () == 0) {
// the dummy layer acts as a reference holder for the layout
m_dummy_layer = dss ().create_polygon_layer (db::RecursiveShapeIterator ());
}
} }
db::Layout *LayoutToNetlist::internal_layout () db::Layout *LayoutToNetlist::internal_layout ()
{ {
return &dss ().layout (); ensure_layout ();
return &dss ().layout (m_layout_index);
} }
db::Cell *LayoutToNetlist::internal_top_cell () db::Cell *LayoutToNetlist::internal_top_cell ()
{ {
return &dss ().initial_cell (); ensure_layout ();
return &dss ().initial_cell (m_layout_index);
}
void LayoutToNetlist::ensure_layout () const
{
if (! dss ().is_valid_layout_index (m_layout_index)) {
LayoutToNetlist *non_const_this = const_cast<LayoutToNetlist *> (this);
non_const_this->dss ().make_layout (m_layout_index, db::RecursiveShapeIterator ());
// the dummy layer acts as a reference holder for the layout
unsigned int dummy_layer_index = non_const_this->dss ().layout (m_layout_index).insert_layer ();
non_const_this->m_dummy_layer = db::DeepLayer (& non_const_this->dss (), m_layout_index, dummy_layer_index);
}
} }
void LayoutToNetlist::register_layer (const db::Region &region, const std::string &n) void LayoutToNetlist::register_layer (const db::Region &region, const std::string &n)
@ -317,7 +327,7 @@ void LayoutToNetlist::register_layer (const db::Region &region, const std::strin
if (! delegate) { if (! delegate) {
if (region.empty ()) { if (region.empty ()) {
dl = dss ().empty_layer (); dl = dss ().empty_layer (m_layout_index);
} else { } else {
throw tl::Exception (tl::to_string (tr ("Layer is not a deep region and cannot be registered with name: ")) + n); throw tl::Exception (tl::to_string (tr ("Layer is not a deep region and cannot be registered with name: ")) + n);
} }
@ -394,7 +404,7 @@ db::DeepLayer LayoutToNetlist::deep_layer_of (const db::Region &region) const
return lff.second; return lff.second;
} else if (region.empty ()) { } else if (region.empty ()) {
// provide a substitute empty layer for empty // provide a substitute empty layer for empty
return dss ().empty_layer (); return dss ().empty_layer (m_layout_index);
} else { } else {
throw (tl::Exception (tl::to_string (tr ("Non-hierarchical layers cannot be used in netlist extraction")))); throw (tl::Exception (tl::to_string (tr ("Non-hierarchical layers cannot be used in netlist extraction"))));
} }
@ -418,7 +428,7 @@ db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell
} }
} }
return dss ().cell_mapping_to_original (singular_layout_index, &layout, cell.cell_index (), &device_cells); return dss ().cell_mapping_to_original (m_layout_index, &layout, cell.cell_index (), &device_cells);
} }
db::CellMapping LayoutToNetlist::const_cell_mapping_into (const db::Layout &layout, const db::Cell &cell) db::CellMapping LayoutToNetlist::const_cell_mapping_into (const db::Layout &layout, const db::Cell &cell)
@ -869,10 +879,10 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
} }
db::Layout &ly = dss ().layout (); db::Layout &ly = dss ().layout (m_layout_index);
double dbu = ly.dbu (); double dbu = ly.dbu ();
db::DeepLayer dl (&dss (), singular_layout_index, ly.insert_layer ()); db::DeepLayer dl (&dss (), m_layout_index, ly.insert_layer ());
for (db::Layout::bottom_up_const_iterator cid = ly.begin_bottom_up (); cid != ly.end_bottom_up (); ++cid) { for (db::Layout::bottom_up_const_iterator cid = ly.begin_bottom_up (); cid != ly.end_bottom_up (); ++cid) {

View File

@ -93,20 +93,7 @@ public:
* NOTE: if using make_layer, these new layers will be created in the DSS * NOTE: if using make_layer, these new layers will be created in the DSS
* given in this constructor. * given in this constructor.
*/ */
LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index); LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index = 0);
/**
* @brief Alternative constructor using an external deep shape storage
*
* This constructor allows using an external DSS. It's intended to be used
* with existing DSS instances. Existing layers can be registered with
* "register_layer". The LayoutToNetlist object will hold a weak reference
* to the DSS but not own the DSS.
*
* NOTE: this version cannot create layers but just register layers
* which are present inside the DSS given as the argument.
*/
LayoutToNetlist (db::DeepShapeStore *dss);
/** /**
* @brief Alternative constructor for flat mode * @brief Alternative constructor for flat mode
@ -338,11 +325,6 @@ public:
*/ */
db::Cell *internal_top_cell (); db::Cell *internal_top_cell ();
/**
* @brief Ensures the internal layout is made
*/
void ensure_internal_layout ();
/** /**
* @brief Gets the connectivity object * @brief Gets the connectivity object
*/ */
@ -533,6 +515,7 @@ private:
db::RecursiveShapeIterator m_iter; db::RecursiveShapeIterator m_iter;
std::auto_ptr<db::DeepShapeStore> mp_internal_dss; std::auto_ptr<db::DeepShapeStore> mp_internal_dss;
tl::weak_ptr<db::DeepShapeStore> mp_dss; tl::weak_ptr<db::DeepShapeStore> mp_dss;
unsigned int m_layout_index;
db::Connectivity m_conn; db::Connectivity m_conn;
db::hier_clusters<db::PolygonRef> m_net_clusters; db::hier_clusters<db::PolygonRef> m_net_clusters;
std::auto_ptr<db::Netlist> mp_netlist; std::auto_ptr<db::Netlist> mp_netlist;
@ -560,6 +543,7 @@ private:
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const; void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const; void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
db::DeepLayer deep_layer_of (const db::Region &region) const; db::DeepLayer deep_layer_of (const db::Region &region) const;
void ensure_layout () const;
}; };
} }

View File

@ -159,8 +159,6 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
int version = 0; int version = 0;
std::string description; std::string description;
// TODO: there probably is a more efficient way to force the layout inside l2n to be made
l2n->ensure_internal_layout ();
tl_assert (l2n->internal_layout ()); tl_assert (l2n->internal_layout ());
l2n->internal_layout ()->dbu (1.0); // mainly for testing l2n->internal_layout ()->dbu (1.0); // mainly for testing

View File

@ -123,7 +123,7 @@ static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &t
region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ()))); region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ())));
} }
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters) void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters)
{ {
initialize (&nl); initialize (&nl);
@ -147,14 +147,14 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const NetlistDevi
layers.push_back (alias.second.layer ()); layers.push_back (alias.second.layer ());
} else if (l->second->empty ()) { } else if (l->second->empty ()) {
// provide a substitute empty layer // provide a substitute empty layer
layers.push_back (dss.empty_layer ().layer ()); layers.push_back (dss.empty_layer (layout_index).layer ());
} else { } else {
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: must be of deep region kind")), ld->name)); throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: must be of deep region kind")), ld->name));
} }
} else { } else {
if (&dr->deep_layer ().layout () != &dss.layout () || &dr->deep_layer ().initial_cell () != &dss.initial_cell ()) { if (&dr->deep_layer ().layout () != &dss.layout (layout_index) || &dr->deep_layer ().initial_cell () != &dss.initial_cell (layout_index)) {
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: not originating from the same source")), ld->name)); throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: not originating from the same source")), ld->name));
} }
@ -164,7 +164,7 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const NetlistDevi
} }
extract_without_initialize (dss.layout (), dss.initial_cell (), clusters, layers); extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers);
} }
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl, hier_clusters_type &clusters) void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl, hier_clusters_type &clusters)

View File

@ -266,7 +266,7 @@ public:
* named regions for input. These regions need to be of deep region type and * named regions for input. These regions need to be of deep region type and
* originate from the same layout than the DeepShapeStore. * originate from the same layout than the DeepShapeStore.
*/ */
void extract (DeepShapeStore &dss, const input_layers &layers, Netlist &netlist, hier_clusters_type &clusters); void extract (DeepShapeStore &dss, unsigned int layout_index, const input_layers &layers, Netlist &netlist, hier_clusters_type &clusters);
/** /**
* @brief Gets the error iterator, begin * @brief Gets the error iterator, begin

View File

@ -58,11 +58,11 @@ build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type
} }
void void
NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connectivity &conn, db::Netlist &nl, hier_clusters_type &clusters, bool join_nets_by_label) NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layout_index, const db::Connectivity &conn, db::Netlist &nl, hier_clusters_type &clusters, bool join_nets_by_label)
{ {
mp_clusters = &clusters; mp_clusters = &clusters;
mp_layout = &dss.const_layout (); mp_layout = &dss.const_layout (layout_index);
mp_cell = &dss.const_initial_cell (); mp_cell = &dss.const_initial_cell (layout_index);
// gets the text annotation property ID - // gets the text annotation property ID -
// this is how the texts are passed for annotating the net names // this is how the texts are passed for annotating the net names

View File

@ -82,7 +82,7 @@ public:
* @brief Extract the nets * @brief Extract the nets
* See the class description for more details. * See the class description for more details.
*/ */
void extract_nets (const db::DeepShapeStore &dss, const db::Connectivity &conn, db::Netlist &nl, hier_clusters_type &clusters, bool join_nets_by_label = true); void extract_nets (const db::DeepShapeStore &dss, unsigned int layout_index, const db::Connectivity &conn, db::Netlist &nl, hier_clusters_type &clusters, bool join_nets_by_label = true);
private: private:
hier_clusters_type *mp_clusters; hier_clusters_type *mp_clusters;

View File

@ -218,12 +218,12 @@ TEST(1_DeviceAndNetExtraction)
dl["SD"] = &rpsd; dl["SD"] = &rpsd;
dl["G"] = &rpgate; dl["G"] = &rpgate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
pmos_ex.extract (dss, dl, nl, cl); pmos_ex.extract (dss, 0, dl, nl, cl);
dl["SD"] = &rnsd; dl["SD"] = &rnsd;
dl["G"] = &rngate; dl["G"] = &rngate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
nmos_ex.extract (dss, dl, nl, cl); nmos_ex.extract (dss, 0, dl, nl, cl);
// perform the net extraction // perform the net extraction
@ -253,7 +253,7 @@ TEST(1_DeviceAndNetExtraction)
// extract the nets // extract the nets
net_ex.extract_nets (dss, conn, nl, cl); net_ex.extract_nets (dss, 0, conn, nl, cl);
// debug layers produced for nets // debug layers produced for nets
// 202/0 -> Active // 202/0 -> Active
@ -430,12 +430,12 @@ TEST(2_DeviceAndNetExtractionFlat)
dl["SD"] = &rpsd; dl["SD"] = &rpsd;
dl["G"] = &rpgate; dl["G"] = &rpgate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
pmos_ex.extract (dss, dl, nl, cl); pmos_ex.extract (dss, 0, dl, nl, cl);
dl["SD"] = &rnsd; dl["SD"] = &rnsd;
dl["G"] = &rngate; dl["G"] = &rngate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
nmos_ex.extract (dss, dl, nl, cl); nmos_ex.extract (dss, 0, dl, nl, cl);
// perform the net extraction // perform the net extraction
@ -466,7 +466,7 @@ TEST(2_DeviceAndNetExtractionFlat)
// extract the nets // extract the nets
// don't use "join_nets_by_label" because the flattened texts will spoil everything // don't use "join_nets_by_label" because the flattened texts will spoil everything
net_ex.extract_nets (dss, conn, nl, cl, false); net_ex.extract_nets (dss, 0, conn, nl, cl, false);
// debug layers produced for nets // debug layers produced for nets
// 202/0 -> Active // 202/0 -> Active
@ -664,12 +664,12 @@ TEST(3_DeviceAndNetExtractionWithImplicitConnections)
dl["SD"] = &rpsd; dl["SD"] = &rpsd;
dl["G"] = &rpgate; dl["G"] = &rpgate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
pmos_ex.extract (dss, dl, nl, cl); pmos_ex.extract (dss, 0, dl, nl, cl);
dl["SD"] = &rnsd; dl["SD"] = &rnsd;
dl["G"] = &rngate; dl["G"] = &rngate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
nmos_ex.extract (dss, dl, nl, cl); nmos_ex.extract (dss, 0, dl, nl, cl);
// perform the net extraction // perform the net extraction
@ -699,7 +699,7 @@ TEST(3_DeviceAndNetExtractionWithImplicitConnections)
// extract the nets // extract the nets
net_ex.extract_nets (dss, conn, nl, cl); net_ex.extract_nets (dss, 0, conn, nl, cl);
EXPECT_EQ (all_net_names_unique (nl), true); EXPECT_EQ (all_net_names_unique (nl), true);

View File

@ -3772,7 +3772,7 @@ CODE
# Multiple diode specifications are allowed. Just add them # Multiple diode specifications are allowed. Just add them
# to the antenna_check call. # to the antenna_check call.
# #
# The error shapes produced by the antenna check are a copy # The error shapes produced by the antenna check are copies
# of the metal shapes on the metal layers of each network # of the metal shapes on the metal layers of each network
# violating the antenna rule. # violating the antenna rule.