WIP: first test case for mask support - needs testing.

This commit is contained in:
Matthias Koefferlein 2020-07-27 23:13:15 +02:00
parent 5c7862d8cd
commit d069dde98e
10 changed files with 564 additions and 89 deletions

View File

@ -142,7 +142,7 @@ DEFImporter::read_diearea (db::Layout &layout, db::Cell &design, double scale)
{
std::vector<db::Point> points;
while (! test (";")) {
while (! at_end () && ! test (";")) {
test ("(");
points.push_back (get_point (scale));
test (")");
@ -276,7 +276,7 @@ DEFImporter::read_blockages (db::Layout &layout, db::Cell &design, double scale)
std::string layer;
while (! test (";")) {
while (! at_end () && ! test (";")) {
if (test ("PLACEMENT")) {
@ -570,23 +570,25 @@ DEFImporter::read_single_net (std::string &nondefaultrule, Layout &layout, db::C
} else if (peek ("(")) {
unsigned int new_mask = mask;
while (peek ("(") || peek ("MASK")) {
new_mask = 0;
if (test ("MASK")) {
unsigned int m = get_mask (get_long ());
if (m != mask) {
// stop here with the segments and use the mask value for the next iteration
mask = m;
read_mask = false;
new_mask = get_mask (get_long ());
read_mask = false;
if (! peek ("(")) {
break;
} else if (new_mask != mask) {
break;
}
}
if (! test ("(")) {
// We have a via here. MASK is already read, but the value did not change.
read_mask = false;
break;
}
test ("(");
if (! test ("*")) {
x = get_double ();
@ -613,6 +615,13 @@ DEFImporter::read_single_net (std::string &nondefaultrule, Layout &layout, db::C
}
}
// continue a segment with the current point and the new mask
if (pts.size () > 1) {
pts.erase (pts.begin (), pts.end () - 1);
}
mask = new_mask;
} else if (! peek ("NEW") && ! peek ("+") && ! peek ("-") && ! peek (";")) {
// indicates a via
@ -661,10 +670,16 @@ DEFImporter::read_single_net (std::string &nondefaultrule, Layout &layout, db::C
if (ln == vd->second.m1) {
ln = vd->second.m2;
mask = mask_top;
} else if (ln == vd->second.m2) {
ln = vd->second.m1;
mask = mask_bottom;
} else {
mask = 0;
}
read_mask = false;
}
if (! specialnets) {
@ -890,6 +905,8 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
while (test ("+")) {
bool is_polygon = false;
if (test ("VIARULE")) {
if (! rule_based_vg.get ()) {
@ -974,7 +991,7 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
vd.m1 = bn;
vd.m2 = tn;
} else if (test ("POLYGON")) {
} else if ((is_polygon = test ("POLYGON")) || test ("RECT")) {
if (! geo_based_vg.get ()) {
geo_based_vg.reset (new GeometryBasedViaGenerator ());
@ -982,9 +999,23 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
std::string ln = get ();
if (m_lef_importer.is_routing_layer (ln) && seen_layers.find (ln) == seen_layers.end ()) {
seen_layers.insert (ln);
routing_layers.push_back (ln);
if (m_lef_importer.is_routing_layer (ln)) {
if (routing_layers.size () == 0) {
geo_based_vg->set_bottom_layer (ln);
} else if (routing_layers.size () == 1) {
geo_based_vg->set_top_layer (ln);
}
if (seen_layers.find (ln) == seen_layers.end ()) {
seen_layers.insert (ln);
routing_layers.push_back (ln);
}
} else if (m_lef_importer.is_cut_layer (ln)) {
geo_based_vg->set_cut_layer (ln);
}
if (test ("+")) {
@ -992,32 +1023,20 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
mask = get_mask (get_long ());
}
db::Polygon poly;
read_polygon (poly, scale);
geo_based_vg->add_polygon (ln, poly, mask);
if (is_polygon) {
} else if (test ("RECT")) {
db::Polygon poly;
read_polygon (poly, scale);
geo_based_vg->add_polygon (ln, poly, mask);
} else {
db::Polygon poly;
read_rect (poly, scale);
geo_based_vg->add_polygon (ln, poly, mask);
if (! geo_based_vg.get ()) {
geo_based_vg.reset (new GeometryBasedViaGenerator ());
}
std::string ln = get ();
if (m_lef_importer.is_routing_layer (ln) && seen_layers.find (ln) == seen_layers.end ()) {
seen_layers.insert (ln);
routing_layers.push_back (ln);
}
if (test ("+")) {
expect ("MASK");
mask = get_mask (get_long ());
}
db::Polygon poly;
read_rect (poly, scale);
geo_based_vg->add_polygon (ln, poly, mask);
}
}
@ -1058,9 +1077,8 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
std::string net;
std::string dir;
std::map <std::string, std::vector <db::Polygon> > geometry;
std::map <std::pair<std::string, unsigned int>, std::vector <db::Polygon> > geometry;
db::Trans trans;
unsigned int mask = 0;
while (test ("+")) {
@ -1074,6 +1092,11 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
std::string ln = get ();
unsigned int mask = 0;
if (test ("MASK")) {
mask = get_mask (get_long ());
}
while (test ("DESIGNRULEWIDTH") || test ("SPACING")) {
take ();
}
@ -1086,12 +1109,17 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
db::Point pt2 = get_point (scale);
test (")");
geometry.insert (std::make_pair (ln, std::vector<db::Polygon> ())).first->second.push_back (db::Polygon (db::Box (pt1, pt2)));
geometry.insert (std::make_pair (std::make_pair (ln, mask), std::vector<db::Polygon> ())).first->second.push_back (db::Polygon (db::Box (pt1, pt2)));
} else if (test ("POLYGON")) {
std::string ln = get ();
unsigned int mask = 0;
if (test ("MASK")) {
mask = get_mask (get_long ());
}
while (test ("DESIGNRULEWIDTH") || test ("SPACING")) {
take ();
}
@ -1100,7 +1128,7 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
double x = 0.0, y = 0.0;
while (! test ("+") && ! test (";")) {
while (! at_end () && ! test ("+") && ! test (";")) {
test ("(");
if (! test ("*")) {
@ -1114,7 +1142,7 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
}
std::vector<db::Polygon> &polygons = geometry.insert (std::make_pair (ln, std::vector<db::Polygon> ())).first->second;
std::vector<db::Polygon> &polygons = geometry.insert (std::make_pair (std::make_pair (ln, mask), std::vector<db::Polygon> ())).first->second;
polygons.push_back (db::Polygon ());
polygons.back ().assign_hull (points.begin (), points.end ());
@ -1131,6 +1159,11 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
flush = true;
} else if (test ("VIA")) {
// TODO: implement
error (tl::to_string (tr ("VIA not supported on pins currently")));
} else {
while (! peek ("+") && ! peek ("-") && ! peek (";")) {
take ();
@ -1149,9 +1182,9 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
*/
// Produce geometry collected so far
for (std::map<std::string, std::vector<db::Polygon> >::const_iterator g = geometry.begin (); g != geometry.end (); ++g) {
for (std::map<std::pair<std::string, unsigned int>, std::vector<db::Polygon> >::const_iterator g = geometry.begin (); g != geometry.end (); ++g) {
std::pair <bool, unsigned int> dl = open_layer (layout, g->first, Pins, mask);
std::pair <bool, unsigned int> dl = open_layer (layout, g->first.first, Pins, g->first.second);
if (dl.first) {
db::properties_id_type prop_id = 0;
@ -1172,7 +1205,7 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
}
dl = open_layer (layout, g->first, Label, 0);
dl = open_layer (layout, g->first.first, Label, 0);
if (dl.first) {
db::Box bbox;
if (! g->second.empty ()) {
@ -1208,7 +1241,7 @@ DEFImporter::read_styles (double scale)
double x = 0.0, y = 0.0;
while (! test (";")) {
while (! at_end () && ! test (";")) {
test ("(");
if (! test ("*")) {
@ -1433,6 +1466,13 @@ DEFImporter::do_read (db::Layout &layout)
expect ("END");
expect ("STYLES");
} else if (test ("COMPONENTMASKSHIFT")) {
warn (tl::to_string (tr ("Component mask shift not supported currently")));
while (! at_end () && ! test (";")) {
take ();
}
} else if (test ("COMPONENTS")) {
get_long ();
@ -1454,7 +1494,7 @@ DEFImporter::do_read (db::Layout &layout)
expect ("PINS");
} else {
while (! test (";")) {
while (! at_end () && ! test (";")) {
take ();
}
}

View File

@ -242,37 +242,41 @@ GeometryBasedViaGenerator::GeometryBasedViaGenerator ()
: LEFDEFViaGenerator ()
{ }
unsigned int
GeometryBasedViaGenerator::mask_for (const std::string &ln, unsigned int m, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top) const
{
if (m == 0) {
if (ln == m_bottom_layer) {
return (mask_bottom);
} else if (ln == m_cut_layer) {
return (mask_cut);
} else if (ln == m_top_layer) {
return (mask_top);
}
}
return m;
}
void
GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int /*mask_bottom*/, unsigned int /*mask_cut*/, unsigned int /*mask_top*/, const LEFDEFNumberOfMasks * /*nm*/)
GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks * /*nm*/)
{
for (std::map <std::string, std::list<std::pair<unsigned int, db::Polygon> > >::const_iterator g = m_polygons.begin (); g != m_polygons.end (); ++g) {
for (std::list<std::pair<unsigned int, db::Polygon> >::const_iterator i = g->second.begin (); i != g->second.end (); ++i) {
std::pair <bool, unsigned int> dl (false, 0);
dl = reader.open_layer (layout, g->first, ViaGeometry, i->first);
std::pair <bool, unsigned int> dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, mask_bottom, mask_cut, mask_top));
if (dl.first) {
cell.shapes (dl.second).insert (i->second);
}
}
}
for (std::map <std::string, std::list<std::pair<unsigned int, db::Box> > >::const_iterator g = m_boxes.begin (); g != m_boxes.end (); ++g) {
for (std::list<std::pair<unsigned int, db::Box> >::const_iterator i = g->second.begin (); i != g->second.end (); ++i) {
std::pair <bool, unsigned int> dl (false, 0);
dl = reader.open_layer (layout, g->first, ViaGeometry, i->first);
std::pair <bool, unsigned int> dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, mask_bottom, mask_cut, mask_top));
if (dl.first) {
cell.shapes (dl.second).insert (i->second);
}
}
}
}
@ -433,7 +437,7 @@ static void set_datatypes (db::LEFDEFReaderOptions *data, void (db::LEFDEFReader
if (ex.try_read (mask) && ex.test (":")) {
int dt = 0;
ex.read (dt);
(data->*set_datatype_per_mask) (std::max ((unsigned int) 1, mask) - 1, dt);
(data->*set_datatype_per_mask) (std::max ((unsigned int) 1, mask), dt);
} else {
ex = ex_saved;
int dt = 0;
@ -464,7 +468,7 @@ static void set_suffixes (db::LEFDEFReaderOptions *data, void (db::LEFDEFReaderO
if (ex.try_read (mask) && ex.test (":")) {
std::string sfx;
ex.read_word_or_quoted (sfx);
(data->*set_suffix_per_mask) (std::max ((unsigned int) 1, mask) - 1, sfx);
(data->*set_suffix_per_mask) (std::max ((unsigned int) 1, mask), sfx);
} else {
ex = ex_saved;
std::string sfx;
@ -495,7 +499,7 @@ static std::string get_datatypes (const db::LEFDEFReaderOptions *data, int (db::
if (! res.empty ()) {
res += ",";
}
res += tl::to_string (i + 1);
res += tl::to_string (i);
res += ":";
res += tl::to_string (dt);
}
@ -518,7 +522,7 @@ static std::string get_suffixes (const db::LEFDEFReaderOptions *data, const std:
if (! res.empty ()) {
res += ",";
}
res += tl::to_string (i + 1);
res += tl::to_string (i);
res += ":";
res += tl::to_word_or_quoted_string (sfx);
}
@ -936,47 +940,53 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n
// Note: "name" is the decorated name as provided by the tech component's
// x_suffix specifications.
std::string name (n);
std::string name_suffix;
int dt = 0;
if (mp_tech_comp) {
switch (purpose) {
case Routing:
default:
name += mp_tech_comp->routing_suffix_per_mask (mask);
dt += mp_tech_comp->routing_datatype_per_mask (mask);
name_suffix = mp_tech_comp->routing_suffix_per_mask (mask);
dt = mp_tech_comp->routing_datatype_per_mask (mask);
break;
case SpecialRouting:
name += mp_tech_comp->special_routing_suffix_per_mask (mask);
dt += mp_tech_comp->special_routing_datatype_per_mask (mask);
name_suffix = mp_tech_comp->special_routing_suffix_per_mask (mask);
dt = mp_tech_comp->special_routing_datatype_per_mask (mask);
break;
case ViaGeometry:
name += mp_tech_comp->via_geometry_suffix_per_mask (mask);
dt += mp_tech_comp->via_geometry_datatype_per_mask (mask);
name_suffix = mp_tech_comp->via_geometry_suffix_per_mask (mask);
dt = mp_tech_comp->via_geometry_datatype_per_mask (mask);
break;
case Label:
name += mp_tech_comp->labels_suffix ();
dt += mp_tech_comp->labels_datatype ();
name_suffix = mp_tech_comp->labels_suffix ();
dt = mp_tech_comp->labels_datatype ();
break;
case Pins:
name += mp_tech_comp->pins_suffix_per_mask (mask);
dt += mp_tech_comp->pins_datatype_per_mask (mask);
name_suffix = mp_tech_comp->pins_suffix_per_mask (mask);
dt = mp_tech_comp->pins_datatype_per_mask (mask);
break;
case LEFPins:
name += mp_tech_comp->lef_pins_suffix_per_mask (mask);
dt += mp_tech_comp->lef_pins_datatype_per_mask (mask);
name_suffix = mp_tech_comp->lef_pins_suffix_per_mask (mask);
dt = mp_tech_comp->lef_pins_datatype_per_mask (mask);
break;
case Obstructions:
name += mp_tech_comp->obstructions_suffix ();
dt += mp_tech_comp->obstructions_datatype ();
name_suffix = mp_tech_comp->obstructions_suffix ();
dt = mp_tech_comp->obstructions_datatype ();
break;
case Blockage:
name += mp_tech_comp->blockages_suffix ();
dt += mp_tech_comp->blockages_datatype ();
name_suffix = mp_tech_comp->blockages_suffix ();
dt = mp_tech_comp->blockages_datatype ();
break;
}
}
if (dt > 0 && name_suffix.empty ()) {
name_suffix = "#" + tl::to_string (dt);
}
std::string name = n + name_suffix;
std::pair<bool, unsigned int> ll = m_layer_map.logical (name, layout);
if (ll.first) {
@ -1120,7 +1130,7 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned
std::string cn = mp_tech_comp->via_cellname_prefix () + vn + mask_suffix;
cell = &layout.cell (layout.add_cell (cn.c_str ()));
vg->create_cell (*this, layout, *cell, mask_bottom, mask_cut, mask_bottom, nm);
vg->create_cell (*this, layout, *cell, mask_bottom, mask_cut, mask_top, nm);
}

View File

@ -926,10 +926,16 @@ public:
void add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask);
void add_box (const std::string &ln, const db::Box &box, unsigned int mask);
void set_bottom_layer (const std::string &ln) { m_bottom_layer = ln; }
void set_cut_layer (const std::string &ln) { m_cut_layer = ln; }
void set_top_layer (const std::string &ln) { m_top_layer = ln; }
private:
std::map <std::string, std::list<std::pair<unsigned int, db::Polygon> > > m_polygons;
std::map <std::string, std::list<std::pair<unsigned int, db::Box> > > m_boxes;
std::string m_bottom_layer, m_cut_layer, m_top_layer;
unsigned int mask_for (const std::string &ln, unsigned int m, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top) const;
};
/**

View File

@ -556,9 +556,21 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi
layer_name = get ();
if (m_routing_layers.find (layer_name) != m_routing_layers.end () && seen_layers.find (layer_name) == seen_layers.end ()) {
seen_layers.insert (layer_name);
routing_layers.push_back (layer_name);
if (m_routing_layers.find (layer_name) != m_routing_layers.end ()) {
if (routing_layers.size () == 0) {
vg->set_bottom_layer (layer_name);
} else if (routing_layers.size () == 1) {
vg->set_top_layer (layer_name);
}
if (seen_layers.find (layer_name) == seen_layers.end ()) {
seen_layers.insert (layer_name);
routing_layers.push_back (layer_name);
}
} else {
vg->set_cut_layer (layer_name);
}
while (! at_end () && ! test (";")) {

View File

@ -395,3 +395,22 @@ TEST(112_via_properties)
run_test (_this, "via_properties", "lef:in.lef+def:in.def", "au.oas.gz", default_options (), false);
}
TEST(113_masks_1)
{
db::LEFDEFReaderOptions options = default_options ();
options.set_routing_suffix ("");
options.set_routing_datatype_per_mask (1, 100);
options.set_routing_datatype_per_mask (2, 200);
options.set_special_routing_suffix ("");
options.set_special_routing_datatype_per_mask (1, 101);
options.set_special_routing_datatype_per_mask (2, 201);
options.set_via_geometry_suffix ("");
options.set_via_geometry_datatype_per_mask (1, 102);
options.set_via_geometry_datatype_per_mask (2, 202);
options.set_pins_suffix ("");
options.set_pins_datatype_per_mask (1, 110);
options.set_pins_datatype_per_mask (2, 210);
run_test (_this, "masks-1", "lef:in_tech.lef+def:in.def", "au.oas.gz", options, false);
}

View File

@ -0,0 +1,323 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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 "dbLEFDEFImporter.h"
#include "tlUnitTest.h"
#include <cstdlib>
TEST(1)
{
db::LEFDEFReaderOptions options;
EXPECT_EQ (options.max_mask_number (), (unsigned int) 0);
options.set_dbu (1.5);
EXPECT_EQ (options.dbu (), 1.5);
options.set_produce_net_names (true);
EXPECT_EQ (options.produce_net_names (), true);
options.set_produce_net_names (false);
EXPECT_EQ (options.produce_net_names (), false);
options.set_net_property_name (tl::Variant (12));
EXPECT_EQ (options.net_property_name ().to_string (), "12");
options.set_produce_inst_names (true);
EXPECT_EQ (options.produce_inst_names (), true);
options.set_produce_inst_names (false);
EXPECT_EQ (options.produce_inst_names (), false);
options.set_inst_property_name (tl::Variant (12));
EXPECT_EQ (options.inst_property_name ().to_string (), "12");
options.set_produce_pin_names (true);
EXPECT_EQ (options.produce_pin_names (), true);
options.set_produce_pin_names (false);
EXPECT_EQ (options.produce_pin_names (), false);
options.set_pin_property_name (tl::Variant (12));
EXPECT_EQ (options.pin_property_name ().to_string (), "12");
options.set_produce_cell_outlines (true);
EXPECT_EQ (options.produce_cell_outlines (), true);
options.set_produce_cell_outlines (false);
EXPECT_EQ (options.produce_cell_outlines (), false);
options.set_cell_outline_layer ("OL");
EXPECT_EQ (options.cell_outline_layer (), "OL");
options.set_produce_placement_blockages (true);
EXPECT_EQ (options.produce_placement_blockages (), true);
options.set_produce_placement_blockages (false);
EXPECT_EQ (options.produce_placement_blockages (), false);
options.set_placement_blockage_layer ("B");
EXPECT_EQ (options.placement_blockage_layer (), "B");
options.set_produce_regions (true);
EXPECT_EQ (options.produce_regions (), true);
options.set_produce_regions (false);
EXPECT_EQ (options.produce_regions (), false);
options.set_region_layer ("R");
EXPECT_EQ (options.region_layer (), "R");
options.set_via_cellname_prefix ("VIACELL");
EXPECT_EQ (options.via_cellname_prefix (), "VIACELL");
options.set_produce_via_geometry (true);
EXPECT_EQ (options.produce_via_geometry (), true);
options.set_produce_via_geometry (false);
EXPECT_EQ (options.produce_via_geometry (), false);
options.set_via_geometry_suffix ("VIAG");
EXPECT_EQ (options.via_geometry_suffix (), "VIAG");
options.set_via_geometry_datatype (17);
EXPECT_EQ (options.via_geometry_datatype (), 17);
options.set_via_geometry_suffix_str ("VIAG, 2: VIAGM2, 1: VIAGM1");
EXPECT_EQ (options.via_geometry_suffix_str (), "VIAG,1:VIAGM1,2:VIAGM2");
EXPECT_EQ (options.via_geometry_suffix_per_mask (0), "VIAG");
EXPECT_EQ (options.via_geometry_suffix_per_mask (1), "VIAGM1");
EXPECT_EQ (options.via_geometry_suffix_per_mask (2), "VIAGM2");
EXPECT_EQ (options.via_geometry_suffix_per_mask (3), "VIAG");
options.set_via_geometry_suffix_per_mask (2, "AB");
EXPECT_EQ (options.via_geometry_suffix_per_mask (2), "AB");
EXPECT_EQ (options.max_mask_number (), (unsigned int) 2);
options.set_via_geometry_datatype_str ("17, 2:217, 1: 117");
EXPECT_EQ (options.via_geometry_datatype_str (), "17,1:117,2:217");
EXPECT_EQ (options.via_geometry_datatype_per_mask (0), 17);
EXPECT_EQ (options.via_geometry_datatype_per_mask (1), 117);
EXPECT_EQ (options.via_geometry_datatype_per_mask (2), 217);
EXPECT_EQ (options.via_geometry_datatype_per_mask (3), 17);
options.set_via_geometry_datatype_per_mask (2, 42);
EXPECT_EQ (options.via_geometry_datatype_per_mask (2), 42);
options.clear_via_geometry_suffixes_per_mask ();
EXPECT_EQ (options.via_geometry_suffix_str (), "VIAG");
options.clear_via_geometry_datatypes_per_mask ();
EXPECT_EQ (options.via_geometry_datatype_str (), "17");
options.set_produce_pins (true);
EXPECT_EQ (options.produce_pins (), true);
options.set_produce_pins (false);
EXPECT_EQ (options.produce_pins (), false);
options.set_pins_suffix ("PIN");
EXPECT_EQ (options.pins_suffix (), "PIN");
options.set_pins_datatype (42);
EXPECT_EQ (options.pins_datatype (), 42);
options.set_pins_suffix_str ("PIN, 2: PINM2, 1: PINM1");
EXPECT_EQ (options.pins_suffix_str (), "PIN,1:PINM1,2:PINM2");
EXPECT_EQ (options.pins_suffix_per_mask (0), "PIN");
EXPECT_EQ (options.pins_suffix_per_mask (1), "PINM1");
EXPECT_EQ (options.pins_suffix_per_mask (2), "PINM2");
EXPECT_EQ (options.pins_suffix_per_mask (3), "PIN");
options.set_pins_suffix_per_mask (2, "AB");
EXPECT_EQ (options.pins_suffix_per_mask (2), "AB");
options.set_pins_datatype_str ("42, 2:242, 1: 142");
EXPECT_EQ (options.pins_datatype_str (), "42,1:142,2:242");
EXPECT_EQ (options.pins_datatype_per_mask (0), 42);
EXPECT_EQ (options.pins_datatype_per_mask (1), 142);
EXPECT_EQ (options.pins_datatype_per_mask (2), 242);
EXPECT_EQ (options.pins_datatype_per_mask (3), 42);
options.set_pins_datatype_per_mask (2, 42);
EXPECT_EQ (options.pins_datatype_per_mask (2), 42);
options.clear_pins_suffixes_per_mask ();
EXPECT_EQ (options.pins_suffix_str (), "PIN");
options.clear_pins_datatypes_per_mask ();
EXPECT_EQ (options.pins_datatype_str (), "42");
options.set_produce_lef_pins (true);
EXPECT_EQ (options.produce_lef_pins (), true);
options.set_produce_lef_pins (false);
EXPECT_EQ (options.produce_lef_pins (), false);
options.set_lef_pins_suffix ("LEFPIN");
EXPECT_EQ (options.lef_pins_suffix (), "LEFPIN");
options.set_lef_pins_datatype (41);
EXPECT_EQ (options.lef_pins_datatype (), 41);
options.set_lef_pins_suffix_str ("LEFPIN, 2: LEFPINM2, 1: LEFPINM1");
EXPECT_EQ (options.lef_pins_suffix_str (), "LEFPIN,1:LEFPINM1,2:LEFPINM2");
EXPECT_EQ (options.lef_pins_suffix_per_mask (0), "LEFPIN");
EXPECT_EQ (options.lef_pins_suffix_per_mask (1), "LEFPINM1");
EXPECT_EQ (options.lef_pins_suffix_per_mask (2), "LEFPINM2");
EXPECT_EQ (options.lef_pins_suffix_per_mask (3), "LEFPIN");
options.set_lef_pins_suffix_per_mask (2, "AB");
EXPECT_EQ (options.lef_pins_suffix_per_mask (2), "AB");
options.set_lef_pins_datatype_str ("41, 2:241, 1: 141");
EXPECT_EQ (options.lef_pins_datatype_str (), "41,1:141,2:241");
EXPECT_EQ (options.lef_pins_datatype_per_mask (0), 41);
EXPECT_EQ (options.lef_pins_datatype_per_mask (1), 141);
EXPECT_EQ (options.lef_pins_datatype_per_mask (2), 241);
EXPECT_EQ (options.lef_pins_datatype_per_mask (3), 41);
options.set_lef_pins_datatype_per_mask (2, 41);
EXPECT_EQ (options.lef_pins_datatype_per_mask (2), 41);
options.clear_lef_pins_suffixes_per_mask ();
EXPECT_EQ (options.lef_pins_suffix_str (), "LEFPIN");
options.clear_lef_pins_datatypes_per_mask ();
EXPECT_EQ (options.lef_pins_datatype_str (), "41");
options.set_produce_obstructions (true);
EXPECT_EQ (options.produce_obstructions (), true);
options.set_produce_obstructions (false);
EXPECT_EQ (options.produce_obstructions (), false);
options.set_obstructions_suffix ("OBS");
EXPECT_EQ (options.obstructions_suffix (), "OBS");
options.set_obstructions_datatype (31);
EXPECT_EQ (options.obstructions_datatype (), 31);
options.set_produce_blockages (true);
EXPECT_EQ (options.produce_blockages (), true);
options.set_produce_blockages (false);
EXPECT_EQ (options.produce_blockages (), false);
options.set_blockages_suffix ("BLK");
EXPECT_EQ (options.blockages_suffix (), "BLK");
options.set_blockages_datatype (41);
EXPECT_EQ (options.blockages_datatype (), 41);
options.set_produce_labels (true);
EXPECT_EQ (options.produce_labels (), true);
options.set_produce_labels (false);
EXPECT_EQ (options.produce_labels (), false);
options.set_labels_suffix ("LBL");
EXPECT_EQ (options.labels_suffix (), "LBL");
options.set_labels_datatype (51);
EXPECT_EQ (options.labels_datatype (), 51);
options.set_produce_routing (true);
EXPECT_EQ (options.produce_routing (), true);
options.set_produce_routing (false);
EXPECT_EQ (options.produce_routing (), false);
options.set_routing_suffix ("ROUTING");
EXPECT_EQ (options.routing_suffix (), "ROUTING");
options.set_routing_datatype (40);
EXPECT_EQ (options.routing_datatype (), 40);
options.set_routing_suffix_str ("ROUTING, 2: ROUTINGM2, 1: ROUTINGM1");
EXPECT_EQ (options.routing_suffix_str (), "ROUTING,1:ROUTINGM1,2:ROUTINGM2");
EXPECT_EQ (options.routing_suffix_per_mask (0), "ROUTING");
EXPECT_EQ (options.routing_suffix_per_mask (1), "ROUTINGM1");
EXPECT_EQ (options.routing_suffix_per_mask (2), "ROUTINGM2");
EXPECT_EQ (options.routing_suffix_per_mask (3), "ROUTING");
options.set_routing_suffix_per_mask (2, "AB");
EXPECT_EQ (options.routing_suffix_per_mask (2), "AB");
options.set_routing_datatype_str ("40, 2:240, 1: 140");
EXPECT_EQ (options.routing_datatype_str (), "40,1:140,2:240");
EXPECT_EQ (options.routing_datatype_per_mask (0), 40);
EXPECT_EQ (options.routing_datatype_per_mask (1), 140);
EXPECT_EQ (options.routing_datatype_per_mask (2), 240);
EXPECT_EQ (options.routing_datatype_per_mask (3), 40);
options.set_routing_datatype_per_mask (2, 40);
EXPECT_EQ (options.routing_datatype_per_mask (2), 40);
options.clear_routing_suffixes_per_mask ();
EXPECT_EQ (options.routing_suffix_str (), "ROUTING");
options.clear_routing_datatypes_per_mask ();
EXPECT_EQ (options.routing_datatype_str (), "40");
options.set_produce_special_routing (true);
EXPECT_EQ (options.produce_special_routing (), true);
options.set_produce_special_routing (false);
EXPECT_EQ (options.produce_special_routing (), false);
options.set_special_routing_suffix ("SPECIALROUTING");
EXPECT_EQ (options.special_routing_suffix (), "SPECIALROUTING");
options.set_special_routing_datatype (44);
EXPECT_EQ (options.special_routing_datatype (), 44);
options.set_special_routing_suffix_str ("SPECIALROUTING, 2: SPECIALROUTINGM2, 1: SPECIALROUTINGM1");
EXPECT_EQ (options.special_routing_suffix_str (), "SPECIALROUTING,1:SPECIALROUTINGM1,2:SPECIALROUTINGM2");
EXPECT_EQ (options.special_routing_suffix_per_mask (0), "SPECIALROUTING");
EXPECT_EQ (options.special_routing_suffix_per_mask (1), "SPECIALROUTINGM1");
EXPECT_EQ (options.special_routing_suffix_per_mask (2), "SPECIALROUTINGM2");
EXPECT_EQ (options.special_routing_suffix_per_mask (3), "SPECIALROUTING");
options.set_special_routing_suffix_per_mask (2, "AB");
EXPECT_EQ (options.special_routing_suffix_per_mask (2), "AB");
options.set_special_routing_datatype_str ("44, 2:244, 1: 144");
EXPECT_EQ (options.special_routing_datatype_str (), "44,1:144,2:244");
EXPECT_EQ (options.special_routing_datatype_per_mask (0), 44);
EXPECT_EQ (options.special_routing_datatype_per_mask (1), 144);
EXPECT_EQ (options.special_routing_datatype_per_mask (2), 244);
EXPECT_EQ (options.special_routing_datatype_per_mask (3), 44);
options.set_special_routing_datatype_per_mask (2, 44);
EXPECT_EQ (options.special_routing_datatype_per_mask (2), 44);
options.clear_special_routing_suffixes_per_mask ();
EXPECT_EQ (options.special_routing_suffix_str (), "SPECIALROUTING");
options.clear_special_routing_datatypes_per_mask ();
EXPECT_EQ (options.special_routing_datatype_str (), "44");
EXPECT_EQ (options.begin_lef_files () == options.end_lef_files (), true);
options.push_lef_file ("ABC.lef");
EXPECT_EQ (options.begin_lef_files () == options.end_lef_files (), false);
EXPECT_EQ (options.lef_files ().size (), size_t (1));
EXPECT_EQ (*options.begin_lef_files (), "ABC.lef");
std::vector<std::string> lf = options.lef_files ();
options.clear_lef_files ();
EXPECT_EQ (options.begin_lef_files () == options.end_lef_files (), true);
EXPECT_EQ (options.lef_files ().size (), size_t (0));
options.set_lef_files (lf);
EXPECT_EQ (options.lef_files ().size (), size_t (1));
EXPECT_EQ (*options.begin_lef_files (), "ABC.lef");
options.set_map_file ("ABC.map");
EXPECT_EQ (options.map_file (), "ABC.map");
options.set_macro_resolution_mode (2);
EXPECT_EQ (options.macro_resolution_mode (), (unsigned int) 2);
}

View File

@ -6,7 +6,8 @@ TARGET = lefdef_tests
include($$PWD/../../../../lib_ut.pri)
SOURCES = \
dbLEFDEFImportTests.cc
dbLEFDEFImportTests.cc \
dbLEFDEFReaderOptionsTests.cc
INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common
DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common

BIN
testdata/lefdef/masks-1/au.oas.gz vendored Normal file

Binary file not shown.

32
testdata/lefdef/masks-1/in.def vendored Normal file
View File

@ -0,0 +1,32 @@
VERSION 5.8 ;
DIVIDERCHAR "/" ;
BUSBITCHARS "[]" ;
DESIGN mapfile ;
UNITS DISTANCE MICRONS 1000 ;
DIEAREA ( 0 0 ) ( 1000 3000 ) ;
SPECIALNETS 1 ;
- VDD ( * VDD )
+ ROUTED + MASK 1 + RECT M0PO ( 0 1000 ) ( 500 1500 )
+ ROUTED + MASK 2 + POLYGON M1 ( 0 1600 ) ( 0 2100 ) ( 500 2100 ) ( 500 1600 )
+ ROUTED M1 50 + SHAPE STRIPE ( 500 0 ) MASK 1 ( 500 500 30 ) MASK 112 square ( 0 500 )
+ USE POWER ;
END SPECIALNETS
PINS 1 ;
- VDD + NET VDD + SPECIAL + DIRECTION INOUT + USE POWER
+ LAYER M1 MASK 1 ( 0 0 ) ( 50 70 )
+ LAYER M0PO ( 0 100 ) ( 50 170 )
+ LAYER M0PO MASK 2 ( 100 100 ) ( 150 170 )
;
END PINS
NETS 1 ;
- TOP
+ ROUTED M1 ( 100 700 ) MASK 1 ( 500 * ) MASK 2 ( 1000 * ) MASK 221 square ( * 800 ) ;
END NETS
END DESIGN

32
testdata/lefdef/masks-1/in_tech.lef vendored Normal file
View File

@ -0,0 +1,32 @@
LAYER M0PO
TYPE MASTERSLICE ;
WIDTH 0.02 ;
MASKS 2 ;
END M0PO
LAYER VIA0
TYPE CUT ;
MASKS 2 ;
END VIA0
LAYER M1
TYPE MASTERSLICE ;
WIDTH 0.025 ;
MASKS 2 ;
END M1
LAYER VIA1
TYPE CUT ;
MASKS 2 ;
END VIA1
LAYER M2
TYPE MASTERSLICE ;
WIDTH 0.03 ;
MASKS 2 ;
END M2
VIA square
LAYER M0PO ;
RECT -0.06 -0.06 0.06 0.06 ;
LAYER VIA0 ;
RECT -0.06 -0.06 0.06 0.06 ;
LAYER M1 ;
RECT -0.06 -0.06 0.06 0.06 ;
END square