WIP: debugging, tests.

This commit is contained in:
Matthias Koefferlein 2025-05-04 13:11:46 +02:00
parent bc10bb6b14
commit f83cd61843
11 changed files with 220 additions and 42 deletions

View File

@ -373,7 +373,7 @@ PropertiesRepository::prop_name_id (const tl::Variant &name)
}
}
property_names_id_type
property_values_id_type
PropertiesRepository::prop_value_id (const tl::Variant &value)
{
tl::MutexLocker locker (&m_lock);
@ -383,9 +383,9 @@ PropertiesRepository::prop_value_id (const tl::Variant &value)
m_property_values_heap.push_back (value);
const tl::Variant &new_value = m_property_values_heap.back ();
m_propvalues.insert (&new_value);
return property_names_id_type (&new_value);
return property_values_id_type (&new_value);
} else {
return property_names_id_type (*pi);
return property_values_id_type (*pi);
}
}

View File

@ -358,7 +358,7 @@ public:
* This method will assign a new ID to the given value if required and
* return the ID associated with it.
*/
property_names_id_type prop_value_id (const tl::Variant &name);
property_values_id_type prop_value_id (const tl::Variant &name);
/**
* @brief Get the ID for a name

View File

@ -33,6 +33,7 @@
#include "dbRegionProcessors.h"
#include "dbCompoundOperation.h"
#include "dbPolygonNeighborhood.h"
#include "dbPropertiesRepository.h"
namespace pex
{
@ -121,10 +122,11 @@ class ViaAggregationVisitor
: public db::PolygonNeighborhoodVisitor
{
public:
ViaAggregationVisitor (const RExtractorTechVia *via_tech, std::vector<std::pair<double, db::Point> > *conductances, double dbu)
: mp_via_tech (via_tech), mp_conductances (conductances), m_dbu (dbu)
ViaAggregationVisitor (const RExtractorTechVia *via_tech, double dbu)
: mp_via_tech (via_tech), m_dbu (dbu)
{
// .. nothing yet ..
// this is just for consistency - we actually do not produce output
set_result_type (db::CompoundRegionCheckOperationNode::Region);
}
virtual void neighbors (const db::Layout * /*layout*/, const db::Cell * /*cell*/, const db::PolygonWithProperties &polygon, const neighbors_type &neighbors)
@ -145,15 +147,44 @@ public:
}
}
mp_conductances->push_back (std::make_pair (c, polygon.box ().center ()));
db::PropertiesSet ps;
ps.insert (prop_name_id, tl::Variant (c));
output_polygon (db::PolygonWithProperties (polygon, db::properties_id (ps)));
}
static db::property_names_id_type prop_name_id;
private:
const RExtractorTechVia *mp_via_tech;
std::vector<std::pair<double, db::Point> > *mp_conductances;
db::property_names_id_type m_prop_name_id;
double m_dbu;
};
db::property_names_id_type ViaAggregationVisitor::prop_name_id = db::property_names_id (tl::Variant ());
}
void
RNetExtractor::create_via_port (const pex::RExtractorTechVia &tech,
double conductance,
const db::Polygon &poly,
unsigned int &port_index,
std::map<unsigned int, std::vector<ViaPort> > &vias,
RNetwork &rnetwork)
{
RNode *a = rnetwork.create_node (RNode::Internal, port_index++);
RNode *b = rnetwork.create_node (RNode::Internal, port_index++);
db::CplxTrans to_um (m_dbu);
db::Box box = poly.box ();
b->location = a->location = to_um * box;
rnetwork.create_element (conductance, a, b);
vias[tech.bottom_conductor].push_back (ViaPort (box.center (), a));
vias[tech.top_conductor].push_back (ViaPort (box.center (), b));
}
void
@ -162,7 +193,7 @@ RNetExtractor::create_via_ports (const RExtractorTech &tech,
std::map<unsigned int, std::vector<ViaPort> > &vias,
RNetwork &rnetwork)
{
std::vector<std::pair<double, db::Point> > via_conductances;
unsigned int port_index = 0;
for (auto v = tech.vias.begin (); v != tech.vias.end (); ++v) {
@ -171,8 +202,6 @@ RNetExtractor::create_via_ports (const RExtractorTech &tech,
continue;
}
via_conductances.clear ();
if (v->merge_distance > db::epsilon) {
// with merge, follow this scheme:
@ -189,32 +218,23 @@ RNetExtractor::create_via_ports (const RExtractorTech &tech,
children.push_back (new db::CompoundRegionOperationPrimaryNode ());
children.push_back (new db::CompoundRegionOperationSecondaryNode (const_cast<db::Region *> (&g->second)));
ViaAggregationVisitor visitor (v.operator-> (), &via_conductances, m_dbu);
ViaAggregationVisitor visitor (v.operator-> (), m_dbu);
db::PolygonNeighborhoodCompoundOperationNode en_node (children, &visitor, 0);
merged_vias.cop_to_region (en_node);
auto aggregated = merged_vias.cop_to_region (en_node);
for (auto p = aggregated.begin (); ! p.at_end (); ++p) {
double c = db::properties (p.prop_id ()).value (ViaAggregationVisitor::prop_name_id).to_double ();
create_via_port (*v, c, *p, port_index, vias, rnetwork);
}
} else {
for (auto p = g->second.begin_merged (); ! p.at_end (); ++p) {
via_conductances.push_back (std::make_pair (via_conductance (*v, *p, m_dbu), p->box ().center ()));
create_via_port (*v, via_conductance (*v, *p, m_dbu), *p, port_index, vias, rnetwork);
}
}
// create the via resistor elements
unsigned int port_index = 0;
for (auto vc = via_conductances.begin (); vc != via_conductances.end (); ++vc) {
RNode *a = rnetwork.create_node (RNode::Internal, port_index++);
RNode *b = rnetwork.create_node (RNode::Internal, port_index++);
rnetwork.create_element (vc->first, a, b);
vias[v->bottom_conductor].push_back (ViaPort (vc->second, a));
vias[v->top_conductor].push_back (ViaPort (vc->second, b));
}
}
}

View File

@ -30,6 +30,7 @@ namespace pex
{
class RExtractorTech;
class RExtractorTechVia;
class RExtractorTechConductor;
class RNetwork;
class RNode;
@ -37,7 +38,7 @@ class RNode;
/**
* @brief Implementation of the R extractor for a multi-polygon/multi-layer net
*/
class RNetExtractor
class PEX_PUBLIC RNetExtractor
{
public:
/**
@ -74,9 +75,7 @@ public:
RNode *node;
};
private:
double m_dbu;
protected:
void create_via_ports (const RExtractorTech &tech,
const std::map<unsigned int, db::Region> &geo,
std::map<unsigned int, std::vector<ViaPort> > &vias,
@ -90,6 +89,16 @@ private:
unsigned int polygon_ports_index_offset,
const std::vector<ViaPort> &via_ports,
RNetwork &rnetwork);
private:
double m_dbu;
void create_via_port (const RExtractorTechVia &tech,
double conductance,
const db::Polygon &poly,
unsigned int &port_index,
std::map<unsigned int, std::vector<ViaPort> > &vias,
RNetwork &rnetwork);
};
}

View File

@ -30,9 +30,10 @@ namespace pex
// -----------------------------------------------------------------------------
std::string
RNode::to_string () const
RNode::to_string (bool with_coords) const
{
std::string res;
switch (type) {
default:
res += "$" + tl::to_string (port_index);
@ -44,24 +45,29 @@ RNode::to_string () const
res += "P" + tl::to_string (port_index);
break;
}
if (with_coords) {
res += location.to_string ();
}
return res;
}
// -----------------------------------------------------------------------------
std::string
RElement::to_string () const
RElement::to_string (bool with_coords) const
{
std::string na;
if (a ()) {
na = a ()->to_string ();
na = a ()->to_string (with_coords);
} else {
na = "(nil)";
}
std::string nb;
if (b ()) {
nb = b ()->to_string ();
nb = b ()->to_string (with_coords);
} else {
nb = "(nil)";
}
@ -88,14 +94,14 @@ RNetwork::~RNetwork ()
}
std::string
RNetwork::to_string () const
RNetwork::to_string (bool with_coords) const
{
std::string res;
for (auto e = m_elements.begin (); e != m_elements.end (); ++e) {
if (! res.empty ()) {
res += "\n";
}
res += e->to_string ();
res += e->to_string (with_coords);
}
return res;
}

View File

@ -91,7 +91,7 @@ public:
/**
* @brief Returns a string representation of the node
*/
std::string to_string () const;
std::string to_string (bool with_coords = false) const;
/**
* @brief Gets the network the node lives in
@ -180,7 +180,7 @@ struct PEX_PUBLIC RElement
/**
* @brief Returns a string representation of the element
*/
std::string to_string () const;
std::string to_string (bool with_coords = false) const;
/**
* @brief Gets the network the node lives in
@ -357,7 +357,7 @@ public:
/**
* @brief Returns a string representation of the graph
*/
std::string to_string () const;
std::string to_string (bool with_coords = false) const;
private:
node_list m_nodes;

View File

@ -29,6 +29,9 @@
namespace pex
{
// Value used for number of squares for width 0 (should not happen)
const double infinite_squares = 1e10;
namespace
{
@ -103,7 +106,7 @@ double calculate_squares (db::Coord x1, db::Coord x2, const std::set<db::Edge> &
// integrate the resistance along the axis x1->x2 with w=w1->w2
if (w1 < db::epsilon) {
return 1e9; // @@@
return infinite_squares;
} else if (fabs (w1 - w2) < db::epsilon) {
return (x2 - x1) / w1;
} else {

View File

@ -0,0 +1,139 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2025 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pexRNetExtractor.h"
#include "pexRExtractorTech.h"
#include "pexRNetwork.h"
#include "dbReader.h"
#include "dbLayout.h"
#include "tlUnitTest.h"
class TestableRNetExtractor
: public pex::RNetExtractor
{
public:
TestableRNetExtractor (double dbu) : pex::RNetExtractor (dbu) { }
using pex::RNetExtractor::create_via_ports;
};
TEST(netex_viagen1)
{
db::Layout ly;
{
std::string fn = tl::testdata () + "/pex/netex_viagen1.gds";
tl::InputStream is (fn);
db::Reader reader (is);
reader.read (ly);
}
TestableRNetExtractor rex (ly.dbu ());
auto tc = ly.cell_by_name ("TOP");
tl_assert (tc.first);
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
std::map<unsigned int, db::Region> geo;
geo.insert (std::make_pair (l2, db::Region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l2))));
pex::RNetwork network;
pex::RExtractorTech tech;
pex::RExtractorTechVia via1;
via1.bottom_conductor = l1;
via1.cut_layer = l2;
via1.top_conductor = l3;
via1.resistance = 2.0;
tech.vias.push_back (via1);
std::map<unsigned int, std::vector<pex::RNetExtractor::ViaPort> > via_ports;
rex.create_via_ports (tech, geo, via_ports, network);
EXPECT_EQ (via_ports [l1].size (), size_t (4));
EXPECT_EQ (via_ports [l2].size (), size_t (0));
EXPECT_EQ (via_ports [l3].size (), size_t (4));
EXPECT_EQ (network.to_string (true),
"R $0(1.7,0.1;1.9,0.3) $1(1.7,0.1;1.9,0.3) 50\n"
"R $2(0.4,0.5;0.6,0.7) $3(0.4,0.5;0.6,0.7) 50\n"
"R $4(0.8,0.5;1,0.7) $5(0.8,0.5;1,0.7) 50\n"
"R $6(2.9,0.5;3.1,0.7) $7(2.9,0.5;3.1,0.7) 50"
);
}
TEST(netex_viagen2)
{
db::Layout ly;
{
std::string fn = tl::testdata () + "/pex/netex_viagen2.gds";
tl::InputStream is (fn);
db::Reader reader (is);
reader.read (ly);
}
TestableRNetExtractor rex (ly.dbu ());
auto tc = ly.cell_by_name ("TOP");
tl_assert (tc.first);
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
std::map<unsigned int, db::Region> geo;
geo.insert (std::make_pair (l2, db::Region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l2))));
pex::RNetwork network;
pex::RExtractorTech tech;
pex::RExtractorTechVia via1;
via1.bottom_conductor = l1;
via1.cut_layer = l2;
via1.top_conductor = l3;
via1.resistance = 2.0;
via1.merge_distance = 0.2;
tech.vias.push_back (via1);
std::map<unsigned int, std::vector<pex::RNetExtractor::ViaPort> > via_ports;
rex.create_via_ports (tech, geo, via_ports, network);
EXPECT_EQ (via_ports [l1].size (), size_t (6));
EXPECT_EQ (via_ports [l2].size (), size_t (0));
EXPECT_EQ (via_ports [l3].size (), size_t (6));
EXPECT_EQ (network.to_string (true),
"R $0(4.6,2.8;4.8,3) $1(4.6,2.8;4.8,3) 50\n"
"R $2(2.5,3.7;2.7,3.9) $3(2.5,3.7;2.7,3.9) 50\n"
"R $4(3,3.7;3.2,3.9) $5(3,3.7;3.2,3.9) 50\n"
"R $6(2.2,1.2;3.4,3.4) $7(2.2,1.2;3.4,3.4) 2.77778\n"
"R $8(0.4,0.4;2.2,4.2) $9(0.4,0.4;2.2,4.2) 1\n"
"R $10(0.6,4.9;1.2,5.1) $11(0.6,4.9;1.2,5.1) 25"
);
}

View File

@ -8,6 +8,7 @@ include($$PWD/../../lib_ut.pri)
SOURCES = \
pexRExtractorTests.cc \
pexRNetExtractorTests.cc \
pexSquareCountingRExtractorTests.cc \
pexTriangulationRExtractorTests.cc

BIN
testdata/pex/netex_viagen1.gds vendored Normal file

Binary file not shown.

BIN
testdata/pex/netex_viagen2.gds vendored Normal file

Binary file not shown.