Added some tests

This commit is contained in:
Matthias Koefferlein 2025-10-25 17:16:13 +02:00
parent b523f05f80
commit fc3185165f
7 changed files with 182 additions and 5 deletions

View File

@ -2627,18 +2627,18 @@ Layout::convert_cell_to_static (db::cell_index_type ci)
const cell_type &org_cell = cell (ci);
std::string vn = org_cell.get_variant_name ();
if (vn == cell_name (ci)) {
if (vn == std::string (cell_name (ci), vn.size ())) {
// there is a cell name conflict: give priority to the static cell, so it
// will see the variant name
std::string rename_org = uniquify_cell_name (cell_name (ci));
// will see the variant name or at least the original disambiguated name
std::string rename_org = uniquify_cell_name (vn.c_str ());
vn = cell_name (ci);
rename_cell (ci, rename_org.c_str ());
}
ret_ci = add_cell (vn.c_str ());
cell_type &new_cell = cell (ret_ci);
// Note: we convert to static cell by explicitly cloning to the db::Cell class
// Note: we convert to static cell by explicitly converting to the db::Cell class
new_cell = org_cell;
new_cell.set_cell_index (ret_ci);

View File

@ -698,6 +698,7 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
gsi::method ("parameters_from_shape", &PCellDeclarationImpl::parameters_from_shape_fb, "@hide") +
gsi::method ("transformation_from_shape", &PCellDeclarationImpl::transformation_from_shape_fb, "@hide") +
gsi::method ("display_text", &PCellDeclarationImpl::get_display_name_fb, "@hide") +
gsi::method ("cell_name", &PCellDeclarationImpl::get_cell_name_fb, "@hide") +
gsi::method ("wants_lazy_evaluation", &PCellDeclarationImpl::wants_lazy_evaluation_fb, "@hide") +
gsi::method ("description", &PCellDeclarationImpl::get_description_fb, "@hide") +
gsi::method ("via_types", &PCellDeclarationImpl::via_types_fb, "@hide") +

View File

@ -88,6 +88,13 @@ class PD
cell.shapes (l_metal0).insert (db::Box (0, 0, width, height));
}
virtual std::string get_display_name (const db::pcell_parameters_type &parameters) const
{
db::Coord width = db::coord_traits<db::Coord>::rounded (parameters[0].to_double () * 1000.0);
db::Coord height = db::coord_traits<db::Coord>::rounded (parameters[1].to_double () * 1000.0);
return tl::sprintf ("PD(W=%d,H=%d)", width, height);
}
};
TEST(0)
@ -252,3 +259,114 @@ TEST(1)
}
}
// PCell names, convert PCell to static
class PD2
: public PD
{
public:
virtual std::string get_cell_name (const db::pcell_parameters_type &parameters) const
{
db::Coord width = db::coord_traits<db::Coord>::rounded (parameters[0].to_double () * 1000.0);
db::Coord height = db::coord_traits<db::Coord>::rounded (parameters[1].to_double () * 1000.0);
return tl::sprintf ("PD_W%d_H%d", width, height);
}
};
TEST(2)
{
db::Manager m (true);
db::Layout layout(&m);
layout.dbu (0.001);
db::LayerProperties p;
p.layer = 23;
p.datatype = 0;
unsigned int l_cont = layout.insert_layer (p);
p.layer = 16;
p.datatype = 0;
unsigned int l_gate = layout.insert_layer (p);
db::Cell &cell_a = layout.cell (layout.add_cell ("A"));
cell_a.shapes(l_cont).insert(db::Box (50, 50, 150, 150));
cell_a.shapes(l_gate).insert(db::Box (0, 0, 200, 1000));
db::Cell &top = layout.cell (layout.add_cell ("TOP"));
db::pcell_id_type pd = layout.register_pcell ("PD", new PD2 ());
std::vector<tl::Variant> parameters;
parameters.push_back (tl::Variant ());
parameters.push_back (tl::Variant ());
parameters.push_back (tl::Variant ());
tl::Variant &width = parameters[0];
tl::Variant &height = parameters[1];
tl::Variant &orientation = parameters[2];
width = 0.5;
height = 1.0;
orientation = long (0);
db::cell_index_type pd1 = layout.get_pcell_variant (pd, parameters);
top.insert (db::CellInstArray (db::CellInst (pd1), db::Trans (db::Vector (0, 0))));
EXPECT_EQ (layout.display_name (pd1), "PD(W=500,H=1000)");
EXPECT_EQ (layout.cell_name (pd1), "PD_W500_H1000");
EXPECT_EQ (layout.variant_name (pd1), "PD_W500_H1000");
width = 0.4;
height = 0.8;
db::cell_index_type pd2 = layout.get_pcell_variant (pd, parameters);
top.insert (db::CellInstArray (db::CellInst (pd2), db::Trans (db::Vector (0, 2000))));
EXPECT_EQ (layout.display_name (pd2), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd2), "PD_W400_H800");
EXPECT_EQ (layout.variant_name (pd2), "PD_W400_H800");
EXPECT_NE (pd1, pd2);
width = 0.4;
height = 0.8;
orientation = long (1);
db::cell_index_type pd3 = layout.get_pcell_variant (pd, parameters);
auto i3 = top.insert (db::CellInstArray (db::CellInst (pd3), db::Trans (db::Vector (2000, 0))));
EXPECT_EQ (layout.display_name (pd3), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.variant_name (pd3), "PD_W400_H800");
EXPECT_NE (pd2, pd3);
auto pd3_org = pd3;
pd3 = layout.convert_cell_to_static (pd3);
EXPECT_NE (pd3, pd3_org);
auto ci3 = i3.cell_inst ();
ci3.object ().cell_index (pd3);
top.replace (i3, ci3);
EXPECT_EQ (layout.cell (pd3_org).is_proxy (), true);
EXPECT_EQ (layout.cell (pd3).is_proxy (), false);
EXPECT_EQ (layout.display_name (pd3_org), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd3_org), "PD_W400_H800$2");
EXPECT_EQ (layout.variant_name (pd3_org), "PD_W400_H800");
layout.do_cleanup (true);
layout.cleanup ();
EXPECT_EQ (layout.is_valid_cell_index (pd3_org), false);
EXPECT_EQ (layout.display_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.cell_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.variant_name (pd3), "PD_W400_H800$1");
CHECKPOINT ();
db::compare_layouts (_this, layout, tl::testdata () + "/gds/pcell_test20.gds", db::NoNormalization);
}

Binary file not shown.

BIN
testdata/gds/pcell_test20.gds vendored Normal file

Binary file not shown.

View File

@ -27,6 +27,10 @@ class BoxPCell(pya.PCellDeclaration):
# provide a descriptive text for the cell
return "Box(L=" + str(parameters[0]) + ",W=" + ('%.3f' % parameters[1]) + ",H=" + ('%.3f' % parameters[2]) + ")"
def cell_name(self, parameters):
# provide a descriptive text for the cell
return "Box_L" + str(parameters[0]).replace("/", "d") + "_W" + ('%.3f' % parameters[1]).replace(".", "p") + "_H" + ('%.3f' % parameters[2]).replace(".", "p")
def get_parameters(self):
# prepare a set of parameter declarations
@ -100,6 +104,10 @@ if "PCellDeclarationHelper" in pya.__dict__:
# provide a descriptive text for the cell
return "Box2(L=" + str(self.layer) + ",W=" + ('%.3f' % self.width) + ",H=" + ('%.3f' % self.height) + ")"
def cell_name_impl(self):
# provide a descriptive text for the cell
return "Box2_L" + str(self.layer).replace("/", "d") + "_W" + ('%.3f' % self.width).replace(".", "p") + "_H" + ('%.3f' % self.height).replace(".", "p")
def wants_lazy_evaluation(self):
return True
@ -260,6 +268,8 @@ class DBPCellTests(unittest.TestCase):
self.assertEqual(pcell_var.is_pcell_variant(), True)
self.assertEqual(pcell_var.display_title(), "PCellTestLib.Box(L=1/0,W=1.000,H=1.000)")
self.assertEqual(pcell_var.basic_name(), "Box")
self.assertEqual(pcell_var.qname(), "PCellTestLib.Box")
self.assertEqual(pcell_var.name, "Box_L1d0_W1p000_H1p000")
self.assertEqual(pcell_var.pcell_declaration().wants_lazy_evaluation(), False)
self.assertEqual(c1.is_pcell_variant(), False)
self.assertEqual(c1.is_pcell_variant(pcell_inst), True)
@ -394,6 +404,8 @@ class DBPCellTests(unittest.TestCase):
pcell_var = ly.cell(pcell_var_id)
pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans()))
self.assertEqual(pcell_var.basic_name(), "Box2")
self.assertEqual(pcell_var.name, "Box2_L1d0_W1p000_H1p000")
self.assertEqual(pcell_var.qname(), "PCellTestLib2.Box2")
self.assertEqual(pcell_var.pcell_parameters().__repr__(), "[<1/0>, 1.0, 1.0]")
self.assertEqual(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)")
self.assertEqual(nh(pcell_var.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}")

View File

@ -39,6 +39,11 @@ class BoxPCell < RBA::PCellDeclaration
# provide a descriptive text for the cell
return "Box(L=#{parameters[0].to_s},W=#{'%.3f' % parameters[1].to_s},H=#{'%.3f' % parameters[2].to_s})"
end
def cell_name(parameters)
# provide a cell name for the PCell
return "Box_L#{parameters[0].to_s.gsub('/','d')}_W#{('%.3f' % parameters[1]).gsub('.','p')}_H#{('%.3f' % parameters[2]).gsub('.','p')}"
end
def get_parameters
@ -129,6 +134,11 @@ if RBA.constants.member?(:PCellDeclarationHelper)
return "Box2(L=" + layer.to_s + ",W=" + ('%.3f' % width) + ",H=" + ('%.3f' % height) + ")"
end
def cell_name_impl
# provide a cell name for the PCell
return "Box2_L" + layer.to_s.gsub('/', 'd') + "_W" + ('%.3f' % width).gsub('.', 'p') + "_H" + ('%.3f' % height).gsub('.', 'p')
end
def produce_impl
# fetch the parameters
@ -371,6 +381,9 @@ class DBPCell_TestClass < TestBase
param = [ RBA::LayerInfo::new(1, 0) ] # rest is filled with defaults
pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param)
pcell_var = ly.cell(pcell_var_id)
assert_equal(pcell_var.name, "Box_L1d0_W1p000_H1p000")
assert_equal(pcell_var.qname, "PCellTestLib.Box")
assert_equal(pcell_var.basic_name, "Box")
pcell_inst = c1.insert(RBA::CellInstArray::new(pcell_var_id, RBA::Trans::new))
assert_equal(pcell_var.layout.inspect, ly.inspect)
assert_equal(pcell_var.library.inspect, lib.inspect)
@ -512,6 +525,8 @@ class DBPCell_TestClass < TestBase
pcell_var = ly.cell(pcell_var_id)
pcell_inst = c1.insert(RBA::CellInstArray::new(pcell_var_id, RBA::Trans::new))
assert_equal(pcell_var.basic_name, "Box2")
assert_equal(pcell_var.name, "Box2_L1d0_W1p000_H1p000")
assert_equal(pcell_var.qname, "PCellTestLib2.Box2")
assert_equal(pcell_var.pcell_parameters().inspect, "[<1/0>, 1.0, 1.0, 0]")
assert_equal(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)")
assert_equal(norm_hash(pcell_var.pcell_parameters_by_name()), "{\"height\"=>1.0, \"layer\"=><1/0>, \"secret\"=>0, \"width\"=>1.0}")
@ -908,6 +923,37 @@ class DBPCell_TestClass < TestBase
end
# convert to static cell
def test_13
if !RBA.constants.member?(:PCellDeclarationHelper)
return
end
# instantiate and register the library
tl = PCellTestLib2::new
ly = RBA::Layout::new(true)
ly.dbu = 0.01
ci1 = ly.add_cell("c1")
c1 = ly.cell(ci1)
lib = RBA::Library.library_by_name("PCellTestLib2")
assert_equal(lib != nil, true)
pcell_decl = lib.layout().pcell_declaration("Box2")
param = [ RBA::LayerInfo::new(1, 0) ] # rest is filled with defaults
pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param)
static_id = ly.convert_cell_to_static(pcell_var_id)
static = ly.cell(static_id)
assert_equal(static.basic_name, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.name, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.qname, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.is_proxy?, false)
end
end
class DBPCellParameterStates_TestClass < TestBase