mirror of https://github.com/KLayout/klayout.git
Merge pull request #732 from KLayout/lefdef-enhancements
Lefdef enhancements
This commit is contained in:
commit
483f67307c
|
|
@ -97,6 +97,9 @@ GenericReaderOptions::GenericReaderOptions ()
|
|||
m_lefdef_produce_lef_pins = load_options.get_option_by_name ("lefdef_config.produce_lef_pins").to_bool ();
|
||||
m_lefdef_lef_pins_suffix = load_options.get_option_by_name ("lefdef_config.lef_pins_suffix_str").to_string ();
|
||||
m_lefdef_lef_pins_datatype = load_options.get_option_by_name ("lefdef_config.lef_pins_datatype_str").to_string ();
|
||||
m_lefdef_produce_fills = load_options.get_option_by_name ("lefdef_config.produce_fills").to_bool ();
|
||||
m_lefdef_fills_suffix = load_options.get_option_by_name ("lefdef_config.fills_suffix_str").to_string ();
|
||||
m_lefdef_fills_datatype = load_options.get_option_by_name ("lefdef_config.fills_datatype_str").to_string ();
|
||||
m_lefdef_produce_obstructions = load_options.get_option_by_name ("lefdef_config.produce_obstructions").to_bool ();
|
||||
m_lefdef_obstruction_suffix = load_options.get_option_by_name ("lefdef_config.obstructions_suffix").to_string ();
|
||||
m_lefdef_obstruction_datatype = load_options.get_option_by_name ("lefdef_config.obstructions_datatype").to_int ();
|
||||
|
|
@ -500,6 +503,20 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
|
|||
"The LEF pin geometry generation and layer mapping is designed in the same way than via geometry mapping. "
|
||||
"See '--" + m_long_prefix + "lefdef-produce-via-geometry' for a description of the mapping scheme.\n"
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#!--" + m_long_prefix + "lefdef-dont-produce-fills", &m_lefdef_produce_fills, "Skips fills when producing geometry",
|
||||
"If this option is given, no fill geometry will be produced."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "lefdef-fills-suffix", &m_lefdef_fills_suffix, "Specifies the fill geometry layer suffix in pattern-based mode",
|
||||
"The fill geometry generation and layer mapfillg is designed in the same way than via geometry mapfillg. "
|
||||
"See '--" + m_long_prefix + "lefdef-via-geometry-suffix' for a description of the mapfillg scheme.\n"
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "lefdef-fills-datatype", &m_lefdef_fills_datatype, "Specifies the fill geometry layer datatype in pattern-based mode",
|
||||
"The fill geometry generation and layer mapfillg is designed in the same way than via geometry mapfillg. "
|
||||
"See '--" + m_long_prefix + "lefdef-produce-via-geometry' for a description of the mapfillg scheme.\n"
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#!--" + m_long_prefix + "lefdef-dont-produce-routing", &m_lefdef_produce_routing, "Skips routing when producing geometry",
|
||||
"If this option is given, no routing geometry will be produced."
|
||||
|
|
@ -724,6 +741,9 @@ GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const
|
|||
load_options.set_option_by_name ("lefdef_config.produce_lef_pins", m_lefdef_produce_lef_pins);
|
||||
load_options.set_option_by_name ("lefdef_config.lef_pins_suffix_str", m_lefdef_lef_pins_suffix);
|
||||
load_options.set_option_by_name ("lefdef_config.lef_pins_datatype_str", m_lefdef_lef_pins_datatype);
|
||||
load_options.set_option_by_name ("lefdef_config.produce_fills", m_lefdef_produce_fills);
|
||||
load_options.set_option_by_name ("lefdef_config.fills_suffix_str", m_lefdef_fills_suffix);
|
||||
load_options.set_option_by_name ("lefdef_config.fills_datatype_str", m_lefdef_fills_datatype);
|
||||
load_options.set_option_by_name ("lefdef_config.produce_obstructions", m_lefdef_produce_obstructions);
|
||||
load_options.set_option_by_name ("lefdef_config.obstructions_suffix", m_lefdef_obstruction_suffix);
|
||||
load_options.set_option_by_name ("lefdef_config.obstructions_datatype", m_lefdef_obstruction_datatype);
|
||||
|
|
|
|||
|
|
@ -161,6 +161,9 @@ private:
|
|||
bool m_lefdef_produce_lef_pins;
|
||||
std::string m_lefdef_lef_pins_suffix;
|
||||
std::string m_lefdef_lef_pins_datatype;
|
||||
bool m_lefdef_produce_fills;
|
||||
std::string m_lefdef_fills_suffix;
|
||||
std::string m_lefdef_fills_datatype;
|
||||
bool m_lefdef_produce_obstructions;
|
||||
std::string m_lefdef_obstruction_suffix;
|
||||
int m_lefdef_obstruction_datatype;
|
||||
|
|
|
|||
|
|
@ -893,8 +893,16 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool
|
|||
}
|
||||
}
|
||||
|
||||
template <class Shape>
|
||||
static db::DVector
|
||||
via_size (double dbu, const Shape &shape)
|
||||
{
|
||||
db::Box box = db::box_convert<Shape> () (shape);
|
||||
return db::DVector (box.width () * dbu, box.height () * dbu);
|
||||
}
|
||||
|
||||
void
|
||||
DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double scale)
|
||||
DEFImporter::read_vias (db::Layout &layout, db::Cell & /*design*/, double scale)
|
||||
{
|
||||
while (test ("-")) {
|
||||
|
||||
|
|
@ -1036,13 +1044,13 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
|
|||
|
||||
db::Polygon poly;
|
||||
read_polygon (poly, scale);
|
||||
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0);
|
||||
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0, via_size (layout.dbu (), poly));
|
||||
|
||||
} else {
|
||||
|
||||
db::Polygon poly;
|
||||
read_rect (poly, scale);
|
||||
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0);
|
||||
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0, via_size (layout.dbu (), poly));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1243,6 +1251,101 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
DEFImporter::read_fills (db::Layout &layout, db::Cell &design, double scale)
|
||||
{
|
||||
std::map <std::pair<std::string, unsigned int>, std::vector <db::Polygon> > geometry;
|
||||
|
||||
while (test ("-")) {
|
||||
|
||||
if (test ("LAYER")) {
|
||||
|
||||
std::string ln = get ();
|
||||
|
||||
unsigned int mask = 0;
|
||||
bool opc = false;
|
||||
|
||||
while (test ("+")) {
|
||||
|
||||
if (test ("MASK")) {
|
||||
mask = get_mask (get_long ());
|
||||
} else if (test ("OPC")) {
|
||||
opc = true;
|
||||
} else {
|
||||
error (tl::to_string (tr ("'MASK' or 'OPC' keyword expected")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector <db::Polygon> polygons;
|
||||
|
||||
while (! test (";")) {
|
||||
|
||||
if (test ("RECT")) {
|
||||
|
||||
test ("(");
|
||||
db::Point pt1 = get_point (scale);
|
||||
test (")");
|
||||
|
||||
test ("(");
|
||||
db::Point pt2 = get_point (scale);
|
||||
test (")");
|
||||
|
||||
polygons.push_back (db::Polygon (db::Box (pt1, pt2)));
|
||||
|
||||
} else if (test ("POLYGON")) {
|
||||
|
||||
std::vector<db::Point> points;
|
||||
|
||||
double x = 0.0, y = 0.0;
|
||||
|
||||
while (test ("(")) {
|
||||
|
||||
if (! test ("*")) {
|
||||
x = get_double ();
|
||||
}
|
||||
if (! test ("*")) {
|
||||
y = get_double ();
|
||||
}
|
||||
points.push_back (db::Point (db::DPoint (x * scale, y * scale)));
|
||||
expect (")");
|
||||
|
||||
}
|
||||
|
||||
polygons.push_back (db::Polygon ());
|
||||
polygons.back ().assign_hull (points.begin (), points.end ());
|
||||
|
||||
} else {
|
||||
error (tl::to_string (tr ("'RECT' or 'POLYGON' keyword expected")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::set<unsigned int> dl = open_layer (layout, ln, opc ? FillsOPC : Fills, mask);
|
||||
if (! dl.empty ()) {
|
||||
for (std::vector<db::Polygon>::const_iterator p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
for (std::set<unsigned int>::const_iterator l = dl.begin (); l != dl.end (); ++l) {
|
||||
design.shapes (*l).insert (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (test ("VIA")) {
|
||||
|
||||
// TODO: implement
|
||||
warn (tl::to_string (tr ("VIA not supported on fills currently")));
|
||||
|
||||
while (! at_end () && ! test (";")) {
|
||||
take ();
|
||||
}
|
||||
|
||||
} else {
|
||||
error (tl::to_string (tr ("'LAYER' or 'VIA' keyword expected")));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DEFImporter::read_styles (double scale)
|
||||
{
|
||||
|
|
@ -1426,10 +1529,16 @@ DEFImporter::do_read (db::Layout &layout)
|
|||
take ();
|
||||
}
|
||||
} else if (test ("FILLS")) {
|
||||
// read over FILLS statements
|
||||
while (! test ("END") || ! test ("FILLS")) {
|
||||
take ();
|
||||
}
|
||||
|
||||
// Read FILLS statements
|
||||
get_long ();
|
||||
expect (";");
|
||||
|
||||
read_fills (layout, design, scale);
|
||||
|
||||
expect ("END");
|
||||
expect ("FILLS");
|
||||
|
||||
} else if (test ("SCANCHAINS")) {
|
||||
// read over SCANCHAINS statements
|
||||
while (! test ("END") || ! test ("SCANCHAINS")) {
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ private:
|
|||
void read_nets (db::Layout &layout, db::Cell &design, double scale, bool specialnets);
|
||||
void read_vias (db::Layout &layout, db::Cell &design, double scale);
|
||||
void read_pins (db::Layout &layout, db::Cell &design, double scale);
|
||||
void read_fills (db::Layout &layout, db::Cell &design, double scale);
|
||||
void read_styles (double scale);
|
||||
void read_components (Layout &layout, std::list<std::pair<std::string, db::CellInstArray> > &instances, double scale);
|
||||
void read_single_net (std::string &nondefaultrule, db::Layout &layout, db::Cell &design, double scale, properties_id_type prop_id, bool specialnets);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,66 @@ static unsigned int mask (const std::vector<unsigned int> &masks, unsigned int i
|
|||
}
|
||||
}
|
||||
|
||||
static std::string purpose_to_name (LayerPurpose purpose)
|
||||
{
|
||||
switch (purpose) {
|
||||
case Outline:
|
||||
return "OUTLINE";
|
||||
case Regions:
|
||||
return "REGION";
|
||||
case PlacementBlockage:
|
||||
return "BLOCKAGE";
|
||||
case Routing:
|
||||
return "NET";
|
||||
case SpecialRouting:
|
||||
return "SPNET";
|
||||
case ViaGeometry:
|
||||
return "VIA";
|
||||
case Label:
|
||||
return "LABEL";
|
||||
case Pins:
|
||||
return "PIN";
|
||||
case Fills:
|
||||
return "FILL";
|
||||
case FillsOPC:
|
||||
return "FILLOPC";
|
||||
case LEFPins:
|
||||
return "LEFPIN";
|
||||
case Obstructions:
|
||||
return "LEFOBS";
|
||||
case Blockage:
|
||||
return "BLK";
|
||||
case All:
|
||||
return "ALL";
|
||||
}
|
||||
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
static std::string
|
||||
layer_spec_to_name (const std::string &layer_name, LayerPurpose purpose, unsigned int mask, const db::DVector &via_size)
|
||||
{
|
||||
std::string ps = purpose_to_name (purpose);
|
||||
|
||||
std::string n = layer_name;
|
||||
if (! n.empty ()) {
|
||||
n += ".";
|
||||
}
|
||||
n += ps;
|
||||
|
||||
if (mask > 0) {
|
||||
n += ":";
|
||||
n += tl::to_string (mask);
|
||||
}
|
||||
|
||||
if (via_size != db::DVector ()) {
|
||||
n += ":SIZE";
|
||||
n += tl::sprintf ("%.12gX%.12g", via_size.x (), via_size.y ());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// RuleBasedViaGenerator implementation
|
||||
|
||||
|
|
@ -144,12 +204,12 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d
|
|||
|
||||
std::set <unsigned int> dl;
|
||||
|
||||
dl = reader.open_layer (layout, m_bottom_layer, ViaGeometry, mask_bottom);
|
||||
dl = reader.open_layer (layout, m_bottom_layer, ViaGeometry, mask_bottom, via_box.enlarged (m_be));
|
||||
for (std::set<unsigned int>::const_iterator l = dl.begin (); l != dl.end (); ++l) {
|
||||
cell.shapes (*l).insert (db::Polygon (via_box.enlarged (m_be).moved (m_bo)));
|
||||
}
|
||||
|
||||
dl = reader.open_layer (layout, m_top_layer, ViaGeometry, mask_top);
|
||||
dl = reader.open_layer (layout, m_top_layer, ViaGeometry, mask_top, via_box.enlarged (m_te));
|
||||
for (std::set<unsigned int>::const_iterator l = dl.begin (); l != dl.end (); ++l) {
|
||||
cell.shapes (*l).insert (db::Polygon (via_box.enlarged (m_te).moved (m_bo)));
|
||||
}
|
||||
|
|
@ -248,7 +308,7 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d
|
|||
cm = (mask_cut + r + c - 1) % num_cut_masks + 1;
|
||||
}
|
||||
|
||||
dl = reader.open_layer (layout, m_cut_layer, ViaGeometry, cm);
|
||||
dl = reader.open_layer (layout, m_cut_layer, ViaGeometry, cm, vb);
|
||||
for (std::set<unsigned int>::const_iterator l = dl.begin (); l != dl.end (); ++l) {
|
||||
cell.shapes (*l).insert (db::Polygon (vb));
|
||||
}
|
||||
|
|
@ -313,12 +373,12 @@ GeometryBasedLayoutGenerator::combine_maskshifts (const std::string &ln, unsigne
|
|||
void
|
||||
GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<std::string> *ext_msl, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm)
|
||||
{
|
||||
for (std::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) {
|
||||
for (std::map <std::pair<std::string, LayerDetailsKey>, db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) {
|
||||
|
||||
unsigned int mshift = get_maskshift (g->first.first, ext_msl, masks);
|
||||
unsigned int mask = mask_for (g->first.first, g->first.second.second, mshift, nm);
|
||||
unsigned int mask = mask_for (g->first.first, g->first.second.mask, mshift, nm);
|
||||
|
||||
std::set <unsigned int> dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask);
|
||||
std::set <unsigned int> dl = reader.open_layer (layout, g->first.first, g->first.second.purpose, mask, g->first.second.via_size);
|
||||
for (std::set<unsigned int>::const_iterator l = dl.begin (); l != dl.end (); ++l) {
|
||||
cell.shapes (*l).insert (g->second);
|
||||
}
|
||||
|
|
@ -363,27 +423,27 @@ static db::Shape insert_shape (db::Shapes &shapes, const Shape &shape, db::prope
|
|||
}
|
||||
|
||||
void
|
||||
GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id)
|
||||
GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size)
|
||||
{
|
||||
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], poly, prop_id);
|
||||
insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], poly, prop_id);
|
||||
}
|
||||
|
||||
void
|
||||
GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id)
|
||||
GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size)
|
||||
{
|
||||
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], box, prop_id);
|
||||
insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], box, prop_id);
|
||||
}
|
||||
|
||||
void
|
||||
GeometryBasedLayoutGenerator::add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, db::properties_id_type prop_id)
|
||||
GeometryBasedLayoutGenerator::add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size)
|
||||
{
|
||||
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], path, prop_id);
|
||||
insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], path, prop_id);
|
||||
}
|
||||
|
||||
void
|
||||
GeometryBasedLayoutGenerator::add_text (const std::string &ln, LayerPurpose purpose, const db::Text &text, unsigned int mask, db::properties_id_type prop_id)
|
||||
{
|
||||
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], text, prop_id);
|
||||
insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask))], text, prop_id);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -425,6 +485,9 @@ LEFDEFReaderOptions::LEFDEFReaderOptions ()
|
|||
m_produce_lef_pins (true),
|
||||
m_lef_pins_suffix (".PIN"),
|
||||
m_lef_pins_datatype (2),
|
||||
m_produce_fills (true),
|
||||
m_fills_suffix (".FILL"),
|
||||
m_fills_datatype (5),
|
||||
m_produce_obstructions (true),
|
||||
m_obstructions_suffix (".OBS"),
|
||||
m_obstructions_datatype (3),
|
||||
|
|
@ -489,6 +552,11 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions &
|
|||
m_lef_pins_suffixes = d.m_lef_pins_suffixes;
|
||||
m_lef_pins_datatype = d.m_lef_pins_datatype;
|
||||
m_lef_pins_datatypes = d.m_lef_pins_datatypes;
|
||||
m_produce_fills = d.m_produce_fills;
|
||||
m_fills_suffix = d.m_fills_suffix;
|
||||
m_fills_suffixes = d.m_fills_suffixes;
|
||||
m_fills_datatype = d.m_fills_datatype;
|
||||
m_fills_datatypes = d.m_fills_datatypes;
|
||||
m_produce_obstructions = d.m_produce_obstructions;
|
||||
m_obstructions_suffix = d.m_obstructions_suffix;
|
||||
m_obstructions_datatype = d.m_obstructions_datatype;
|
||||
|
|
@ -711,6 +779,30 @@ LEFDEFReaderOptions::lef_pins_datatype_str () const
|
|||
return get_datatypes (this, &LEFDEFReaderOptions::lef_pins_datatype, &LEFDEFReaderOptions::lef_pins_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_fills_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_fills_suffixes_per_mask, &LEFDEFReaderOptions::set_fills_suffix, &LEFDEFReaderOptions::set_fills_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::fills_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::fills_suffix, &LEFDEFReaderOptions::fills_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_fills_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_fills_datatypes_per_mask, &LEFDEFReaderOptions::set_fills_datatype, &LEFDEFReaderOptions::set_fills_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::fills_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::fills_datatype, &LEFDEFReaderOptions::fills_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_routing_suffix_str (const std::string &s)
|
||||
{
|
||||
|
|
@ -835,6 +927,8 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
std::map<std::string, LayerPurpose> purpose_translation;
|
||||
purpose_translation ["LEFPIN"] = LEFPins;
|
||||
purpose_translation ["PIN"] = Pins;
|
||||
purpose_translation ["FILL"] = Fills;
|
||||
purpose_translation ["FILLOPC"] = FillsOPC;
|
||||
purpose_translation ["LEFOBS"] = Obstructions;
|
||||
purpose_translation ["SPNET"] = SpecialRouting;
|
||||
purpose_translation ["NET"] = Routing;
|
||||
|
|
@ -842,12 +936,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
purpose_translation ["BLOCKAGE"] = Blockage;
|
||||
purpose_translation ["ALL"] = All;
|
||||
|
||||
std::map<LayerPurpose, std::string> purpose_translation_rev;
|
||||
for (std::map<std::string, LayerPurpose>::const_iterator i = purpose_translation.begin (); i != purpose_translation.end (); ++i) {
|
||||
purpose_translation_rev.insert (std::make_pair (i->second, i->first));
|
||||
}
|
||||
|
||||
std::map<std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, std::vector<db::LayerProperties> > layer_map;
|
||||
std::map<std::pair<std::string, LayerDetailsKey>, std::vector<db::LayerProperties> > layer_map;
|
||||
|
||||
while (! ts.at_end ()) {
|
||||
|
||||
|
|
@ -862,7 +951,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
std::string w1, w2;
|
||||
std::vector<int> layers, datatypes;
|
||||
size_t max_purpose_str = 10;
|
||||
size_t max_purpose_str = 15;
|
||||
|
||||
if (! ex.try_read_word (w1) || ! ex.try_read_word (w2, "._$,/:") || ! try_read_layers (ex, layers) || ! try_read_layers (ex, datatypes)) {
|
||||
tl::warn << tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d not understood - skipped")), path, ts.line_number ());
|
||||
|
|
@ -873,7 +962,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
||||
for (std::vector<int>::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) {
|
||||
layer_map [std::make_pair (std::string (), std::make_pair (Outline, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "OUTLINE"));
|
||||
layer_map [std::make_pair (std::string (), LayerDetailsKey (Outline))].push_back (db::LayerProperties (*l, *d, "OUTLINE"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -881,7 +970,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
||||
for (std::vector<int>::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) {
|
||||
layer_map [std::make_pair (std::string (), std::make_pair (Regions, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "REGIONS"));
|
||||
layer_map [std::make_pair (std::string (), LayerDetailsKey (Regions))].push_back (db::LayerProperties (*l, *d, "REGIONS"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -889,7 +978,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
||||
for (std::vector<int>::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) {
|
||||
layer_map [std::make_pair (std::string (), std::make_pair (PlacementBlockage, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "PLACEMENT_BLK"));
|
||||
layer_map [std::make_pair (std::string (), LayerDetailsKey (PlacementBlockage))].push_back (db::LayerProperties (*l, *d, "PLACEMENT_BLK"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -915,7 +1004,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
for (std::vector<std::string>::const_iterator ln = layer_names.begin (); ln != layer_names.end (); ++ln) {
|
||||
for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
||||
for (std::vector<int>::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) {
|
||||
layer_map [std::make_pair (*ln, std::make_pair (Label, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, final_name));
|
||||
layer_map [std::make_pair (*ln, LayerDetailsKey (Label))].push_back (db::LayerProperties (*l, *d, final_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -934,7 +1023,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
// "(M1,PINS): M1.NET/PINS"
|
||||
// (separating, translating and recombing the purposes)
|
||||
|
||||
std::set<std::pair<LayerPurpose, unsigned int> > translated_purposes;
|
||||
std::set<LayerDetailsKey> translated_purposes;
|
||||
|
||||
std::vector<std::string> purposes = tl::split (w2, ",");
|
||||
std::reverse (purposes.begin (), purposes.end ());
|
||||
|
|
@ -948,6 +1037,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
std::string ps;
|
||||
ex.read_word_or_quoted (ps);
|
||||
db::DVector via_size;
|
||||
|
||||
std::map<std::string, LayerPurpose>::const_iterator i = purpose_translation.find (ps);
|
||||
if (i != purpose_translation.end ()) {
|
||||
|
|
@ -963,9 +1053,11 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
} else if (i->second == ViaGeometry) {
|
||||
|
||||
if (ex.test (":SIZE:")) {
|
||||
std::string sz;
|
||||
ex.read_word (sz);
|
||||
tl::warn << tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: VIA size constraint ignored for layer %s")), path, ts.line_number (), w1);
|
||||
double sx = 0.0, sy = 0.0;
|
||||
ex.read (sx);
|
||||
ex.test("X");
|
||||
ex.read (sy);
|
||||
via_size = db::DVector (sx, sy);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -984,13 +1076,13 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
for (std::map<std::string, LayerPurpose>::const_iterator p = purpose_translation.begin (); p != purpose_translation.end (); ++p) {
|
||||
if (p->second != All) {
|
||||
translated_purposes.insert (std::make_pair (p->second, mask));
|
||||
translated_purposes.insert (LayerDetailsKey (p->second, mask, via_size));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
translated_purposes.insert (std::make_pair (i->second, mask));
|
||||
translated_purposes.insert (LayerDetailsKey (i->second, mask, via_size));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -999,19 +1091,15 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
// create a visual description string for the combined purposes
|
||||
std::string purpose_str;
|
||||
|
||||
for (std::set<std::pair<LayerPurpose, unsigned int> >::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) {
|
||||
for (std::set<LayerDetailsKey>::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) {
|
||||
|
||||
if (p != translated_purposes.begin ()) {
|
||||
purpose_str += "/";
|
||||
}
|
||||
|
||||
std::string ps = purpose_translation_rev [p->first];
|
||||
if (p->second > 0) {
|
||||
ps += ":";
|
||||
ps += tl::to_string (p->second);
|
||||
}
|
||||
std::string ps = layer_spec_to_name (std::string (), p->purpose, p->mask, p->via_size);
|
||||
|
||||
if ((purpose_str + ps).size () > max_purpose_str) {
|
||||
if (p != translated_purposes.begin () && (purpose_str + ps).size () > max_purpose_str) {
|
||||
purpose_str += "...";
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -1022,7 +1110,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
|
||||
std::string final_name = w1 + "." + purpose_str;
|
||||
|
||||
for (std::set<std::pair<LayerPurpose, unsigned int> >::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) {
|
||||
for (std::set<LayerDetailsKey>::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) {
|
||||
for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
||||
for (std::vector<int>::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) {
|
||||
layer_map [std::make_pair (w1, *p)].push_back (db::LayerProperties (*l, *d, final_name));
|
||||
|
|
@ -1043,7 +1131,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
m_layer_map.clear ();
|
||||
|
||||
db::DirectLayerMapping lm (&layout);
|
||||
for (std::map<std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, std::vector<db::LayerProperties> >::const_iterator i = layer_map.begin (); i != layer_map.end (); ++i) {
|
||||
for (std::map<std::pair<std::string, LayerDetailsKey>, std::vector<db::LayerProperties> >::const_iterator i = layer_map.begin (); i != layer_map.end (); ++i) {
|
||||
for (std::vector<db::LayerProperties>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
unsigned int layer = lm.map_layer (*j).second;
|
||||
m_layers [i->first].insert (layer);
|
||||
|
|
@ -1053,9 +1141,13 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
|
|||
}
|
||||
|
||||
std::set <unsigned int>
|
||||
LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask)
|
||||
LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask, const db::DVector &via_size)
|
||||
{
|
||||
std::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, std::set<unsigned int> >::const_iterator nl = m_layers.find (std::make_pair (n, std::make_pair (purpose, mask)));
|
||||
std::map <std::pair<std::string, LayerDetailsKey>, std::set<unsigned int> >::const_iterator nl;
|
||||
nl = m_layers.find (std::make_pair (n, LayerDetailsKey (purpose, mask, via_size)));
|
||||
if (nl == m_layers.end ()) {
|
||||
nl = m_layers.find (std::make_pair (n, LayerDetailsKey (purpose, mask)));
|
||||
}
|
||||
if (nl == m_layers.end ()) {
|
||||
|
||||
std::set <unsigned int> ll;
|
||||
|
|
@ -1064,7 +1156,7 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu
|
|||
ll = open_layer_uncached (layout, n, purpose, mask);
|
||||
}
|
||||
|
||||
m_layers.insert (std::make_pair (std::make_pair (n, std::make_pair (purpose, mask)), ll));
|
||||
m_layers.insert (std::make_pair (std::make_pair (n, LayerDetailsKey (purpose, mask)), ll));
|
||||
return ll;
|
||||
|
||||
} else {
|
||||
|
|
@ -1072,38 +1164,6 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu
|
|||
}
|
||||
}
|
||||
|
||||
static std::string purpose_to_name (LayerPurpose purpose)
|
||||
{
|
||||
switch (purpose) {
|
||||
case Outline:
|
||||
return "OUTLINE";
|
||||
case Regions:
|
||||
return "REGION";
|
||||
case PlacementBlockage:
|
||||
return "BLOCKAGE";
|
||||
case Routing:
|
||||
return "NET";
|
||||
case SpecialRouting:
|
||||
return "SPNET";
|
||||
case ViaGeometry:
|
||||
return "VIA";
|
||||
case Label:
|
||||
return "LABEL";
|
||||
case Pins:
|
||||
return "PIN";
|
||||
case LEFPins:
|
||||
return "LEFPIN";
|
||||
case Obstructions:
|
||||
return "LEFOBS";
|
||||
case Blockage:
|
||||
return "BLK";
|
||||
case All:
|
||||
return "ALL";
|
||||
}
|
||||
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implements implicit layer mapping
|
||||
*
|
||||
|
|
@ -1262,6 +1322,10 @@ std::set<unsigned int> LEFDEFReaderState::open_layer_uncached(db::Layout &layout
|
|||
case Pins:
|
||||
produce = mp_tech_comp->produce_pins ();
|
||||
break;
|
||||
case Fills:
|
||||
case FillsOPC:
|
||||
produce = mp_tech_comp->produce_fills ();
|
||||
break;
|
||||
case LEFPins:
|
||||
produce = mp_tech_comp->produce_lef_pins ();
|
||||
break;
|
||||
|
|
@ -1303,6 +1367,11 @@ std::set<unsigned int> LEFDEFReaderState::open_layer_uncached(db::Layout &layout
|
|||
name_suffix = mp_tech_comp->pins_suffix_per_mask (mask);
|
||||
dt = mp_tech_comp->pins_datatype_per_mask (mask);
|
||||
break;
|
||||
case Fills:
|
||||
case FillsOPC:
|
||||
name_suffix = mp_tech_comp->fills_suffix_per_mask (mask);
|
||||
dt = mp_tech_comp->fills_datatype_per_mask (mask);
|
||||
break;
|
||||
case LEFPins:
|
||||
name_suffix = mp_tech_comp->lef_pins_suffix_per_mask (mask);
|
||||
dt = mp_tech_comp->lef_pins_datatype_per_mask (mask);
|
||||
|
|
@ -1420,24 +1489,13 @@ LEFDEFReaderState::finish (db::Layout &layout)
|
|||
|
||||
db::LayerMap lm;
|
||||
|
||||
for (std::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, std::set<unsigned int> >::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
|
||||
for (std::map <std::pair<std::string, LayerDetailsKey>, std::set<unsigned int> >::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
|
||||
|
||||
if (l->second.empty ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string ps = purpose_to_name (l->first.second.first);
|
||||
|
||||
std::string n = l->first.first;
|
||||
if (! n.empty ()) {
|
||||
n += ".";
|
||||
}
|
||||
n += ps;
|
||||
|
||||
if (l->first.second.second > 0) {
|
||||
n += ":";
|
||||
n += tl::to_string (l->first.second.second);
|
||||
}
|
||||
std::string n = layer_spec_to_name (l->first.first, l->first.second.purpose, l->first.second.mask, l->first.second.via_size);
|
||||
|
||||
for (std::set<unsigned int>::const_iterator li = l->second.begin (); li != l->second.end (); ++li) {
|
||||
|
||||
|
|
|
|||
|
|
@ -476,6 +476,72 @@ public:
|
|||
set_per_mask_value (m_lef_pins_datatypes, mask, s);
|
||||
}
|
||||
|
||||
bool produce_fills () const
|
||||
{
|
||||
return m_produce_fills;
|
||||
}
|
||||
|
||||
void set_produce_fills (bool f)
|
||||
{
|
||||
m_produce_fills = f;
|
||||
}
|
||||
|
||||
const std::string &fills_suffix () const
|
||||
{
|
||||
return m_fills_suffix;
|
||||
}
|
||||
|
||||
void set_fills_suffix (const std::string &s)
|
||||
{
|
||||
m_fills_suffix = s;
|
||||
}
|
||||
|
||||
int fills_datatype () const
|
||||
{
|
||||
return m_fills_datatype;
|
||||
}
|
||||
|
||||
void set_fills_datatype (int s)
|
||||
{
|
||||
m_fills_datatype = s;
|
||||
}
|
||||
|
||||
void set_fills_suffix_str (const std::string &s);
|
||||
std::string fills_suffix_str () const;
|
||||
|
||||
void set_fills_datatype_str (const std::string &s);
|
||||
std::string fills_datatype_str () const;
|
||||
|
||||
void clear_fills_suffixes_per_mask ()
|
||||
{
|
||||
m_fills_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_fills_datatypes_per_mask ()
|
||||
{
|
||||
m_fills_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &fills_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_fills_suffixes, m_fills_suffix, mask);
|
||||
}
|
||||
|
||||
void set_fills_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_fills_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int fills_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_fills_datatypes, m_fills_datatype, mask);
|
||||
}
|
||||
|
||||
void set_fills_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_fills_datatypes, mask, s);
|
||||
}
|
||||
|
||||
bool produce_obstructions () const
|
||||
{
|
||||
return m_produce_obstructions;
|
||||
|
|
@ -707,6 +773,8 @@ public:
|
|||
get_max_mask_number (mm, m_pins_datatypes);
|
||||
get_max_mask_number (mm, m_lef_pins_suffixes);
|
||||
get_max_mask_number (mm, m_lef_pins_datatypes);
|
||||
get_max_mask_number (mm, m_fills_suffixes);
|
||||
get_max_mask_number (mm, m_fills_datatypes);
|
||||
get_max_mask_number (mm, m_routing_suffixes);
|
||||
get_max_mask_number (mm, m_routing_datatypes);
|
||||
get_max_mask_number (mm, m_special_routing_suffixes);
|
||||
|
|
@ -841,6 +909,11 @@ private:
|
|||
int m_lef_pins_datatype;
|
||||
std::map<unsigned int, std::string> m_lef_pins_suffixes;
|
||||
std::map<unsigned int, int> m_lef_pins_datatypes;
|
||||
bool m_produce_fills;
|
||||
std::string m_fills_suffix;
|
||||
int m_fills_datatype;
|
||||
std::map<unsigned int, std::string> m_fills_suffixes;
|
||||
std::map<unsigned int, int> m_fills_datatypes;
|
||||
bool m_produce_obstructions;
|
||||
std::string m_obstructions_suffix;
|
||||
int m_obstructions_datatype;
|
||||
|
|
@ -875,6 +948,8 @@ enum LayerPurpose
|
|||
{
|
||||
Routing = 0, // from DEF only
|
||||
Pins, // from DEF
|
||||
Fills, // from DEF
|
||||
FillsOPC, // from DEF
|
||||
SpecialRouting, // from DEF only
|
||||
LEFPins, // from LEF
|
||||
ViaGeometry, // from LEF+DEF
|
||||
|
|
@ -887,6 +962,46 @@ enum LayerPurpose
|
|||
All // from DEF only
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A structure holding the layer details like purpose, mask and via size
|
||||
*/
|
||||
struct LayerDetailsKey
|
||||
{
|
||||
LayerDetailsKey ()
|
||||
: purpose (Routing), mask (0)
|
||||
{ }
|
||||
|
||||
LayerDetailsKey (LayerPurpose _purpose, unsigned int _mask = 0, const db::DVector &_via_size = db::DVector ())
|
||||
: purpose (_purpose), mask (_mask), via_size (_via_size)
|
||||
{ }
|
||||
|
||||
bool operator< (const LayerDetailsKey &other) const
|
||||
{
|
||||
if (purpose != other.purpose) {
|
||||
return purpose < other.purpose;
|
||||
}
|
||||
if (mask != other.mask) {
|
||||
return mask < other.mask;
|
||||
}
|
||||
return via_size.less (other.via_size);
|
||||
}
|
||||
|
||||
bool operator== (const LayerDetailsKey &other) const
|
||||
{
|
||||
if (purpose != other.purpose) {
|
||||
return false;
|
||||
}
|
||||
if (mask != other.mask) {
|
||||
return false;
|
||||
}
|
||||
return via_size.equal (other.via_size);
|
||||
}
|
||||
|
||||
LayerPurpose purpose;
|
||||
unsigned int mask;
|
||||
db::DVector via_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An interface for resolving the number of masks from a layer name
|
||||
*/
|
||||
|
|
@ -979,9 +1094,9 @@ public:
|
|||
virtual std::vector<std::string> maskshift_layers () const { return m_maskshift_layers; }
|
||||
virtual bool is_fixedmask () const { return m_fixedmask; }
|
||||
|
||||
void add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, properties_id_type prop_id);
|
||||
void add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, properties_id_type prop_id);
|
||||
void add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, properties_id_type prop_id);
|
||||
void add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ());
|
||||
void add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ());
|
||||
void add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ());
|
||||
void add_via (const std::string &vn, const db::Trans &trans, unsigned int bottom_mask, unsigned int cut_mask, unsigned int top_mask);
|
||||
void add_text (const std::string &ln, LayerPurpose purpose, const db::Text &text, unsigned int mask, db::properties_id_type prop_id);
|
||||
|
||||
|
|
@ -1008,7 +1123,7 @@ private:
|
|||
db::Trans trans;
|
||||
};
|
||||
|
||||
std::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, db::Shapes> m_shapes;
|
||||
std::map <std::pair<std::string, LayerDetailsKey>, db::Shapes> m_shapes;
|
||||
std::list<Via> m_vias;
|
||||
std::vector<std::string> m_maskshift_layers;
|
||||
bool m_fixedmask;
|
||||
|
|
@ -1054,7 +1169,17 @@ public:
|
|||
/**
|
||||
* @brief Create a new layer or return the index of the given layer
|
||||
*/
|
||||
std::set<unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask);
|
||||
std::set<unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask, const DVector &via_size = db::DVector ());
|
||||
|
||||
/**
|
||||
* @brief Create a new layer or return the index of the given layer
|
||||
*/
|
||||
template <class Shape>
|
||||
std::set<unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask, const Shape &via_shape)
|
||||
{
|
||||
db::Box via_box = db::box_convert<Shape> () (via_shape);
|
||||
return open_layer (layout, name, purpose, mask, db::DVector (via_box.width () * layout.dbu (), via_box.height () * layout.dbu ()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers a layer (assign a new default layer number)
|
||||
|
|
@ -1188,7 +1313,7 @@ private:
|
|||
LEFDEFReaderState (const LEFDEFReaderState &);
|
||||
LEFDEFReaderState &operator= (const LEFDEFReaderState &);
|
||||
|
||||
std::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, std::set<unsigned int> > m_layers;
|
||||
std::map <std::pair<std::string, LayerDetailsKey>, std::set<unsigned int> > m_layers;
|
||||
db::LayerMap m_layer_map;
|
||||
bool m_create_layers;
|
||||
bool m_has_explicit_layer_mapping;
|
||||
|
|
@ -1363,9 +1488,9 @@ protected:
|
|||
/**
|
||||
* @brief Create a new layer or return the index of the given layer
|
||||
*/
|
||||
std::set<unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask)
|
||||
std::set<unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask, const db::DVector &via_size = db::DVector ())
|
||||
{
|
||||
return mp_reader_state->open_layer (layout, name, purpose, mask);
|
||||
return mp_reader_state->open_layer (layout, name, purpose, mask, via_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -339,6 +339,13 @@ class LEFDEFFormatDeclaration
|
|||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_suffix_str, &LEFDEFReaderOptions::set_lef_pins_suffix_str, "special-lef_pins-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_datatype_str, &LEFDEFReaderOptions::set_lef_pins_datatype_str, "special-lef_pins-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_fills, &LEFDEFReaderOptions::set_produce_fills, "produce-fills") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_fills_suffix, "special-fills-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_fills_datatype, "special-fills-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::fills_suffix_str, &LEFDEFReaderOptions::set_fills_suffix_str, "special-fills-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::fills_datatype_str, &LEFDEFReaderOptions::set_fills_datatype_str, "special-fills-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_obstructions, &LEFDEFReaderOptions::set_produce_obstructions, "produce-obstructions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_suffix, &LEFDEFReaderOptions::set_obstructions_suffix, "obstructions-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_datatype, &LEFDEFReaderOptions::set_obstructions_datatype, "obstructions-datatype") +
|
||||
|
|
|
|||
|
|
@ -517,6 +517,14 @@ LEFImporter::read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &via_desc,
|
|||
}
|
||||
}
|
||||
|
||||
template <class Shape>
|
||||
static db::DVector
|
||||
via_size (double dbu, const Shape &shape)
|
||||
{
|
||||
db::Box box = db::box_convert<Shape> () (shape);
|
||||
return db::DVector (box.width () * dbu, box.height () * dbu);
|
||||
}
|
||||
|
||||
void
|
||||
LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &via_desc, const std::string &n, double dbu)
|
||||
{
|
||||
|
|
@ -577,7 +585,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc
|
|||
db::Polygon p;
|
||||
p.assign_hull (points.begin (), points.end ());
|
||||
|
||||
lg->add_polygon (layer_name, ViaGeometry, p, mask, 0);
|
||||
lg->add_polygon (layer_name, ViaGeometry, p, mask, 0, via_size (dbu, p));
|
||||
|
||||
expect (";");
|
||||
|
||||
|
|
@ -599,7 +607,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc
|
|||
}
|
||||
|
||||
db::Box b (points [0], points [1]);
|
||||
lg->add_box (layer_name, ViaGeometry, b, mask, 0);
|
||||
lg->add_box (layer_name, ViaGeometry, b, mask, 0, via_size (dbu, b));
|
||||
|
||||
expect (";");
|
||||
|
||||
|
|
|
|||
|
|
@ -502,6 +502,94 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
gsi::method ("lef_pins_datatype_str=", &db::LEFDEFReaderOptions::set_lef_pins_datatype_str, gsi::arg ("datatype"),
|
||||
"@hide"
|
||||
) +
|
||||
gsi::method ("produce_fills", &db::LEFDEFReaderOptions::produce_fills,
|
||||
"@brief Gets a value indicating whether fill geometries shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("produce_fills=", &db::LEFDEFReaderOptions::set_produce_fills, gsi::arg ("produce"),
|
||||
"@brief Sets a value indicating whether fill geometries shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_suffix", &db::LEFDEFReaderOptions::fills_suffix,
|
||||
"@brief Gets the fill geometry layer name suffix.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_suffix=", &db::LEFDEFReaderOptions::set_fills_suffix, gsi::arg ("suffix"),
|
||||
"@brief Sets the fill geometry layer name suffix.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_datatype", &db::LEFDEFReaderOptions::fills_datatype,
|
||||
"@brief Gets the fill geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_datatype=", &db::LEFDEFReaderOptions::set_fills_datatype, gsi::arg ("datatype"),
|
||||
"@brief Sets the fill geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"\n\n"
|
||||
"Fill support has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_fills_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_fills_suffixes_per_mask,
|
||||
"@brief Clears the fill layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_fill_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_fills_datatypes_per_mask,
|
||||
"@brief Clears the fill layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_suffix_per_mask", &db::LEFDEFReaderOptions::fills_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the fill geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_fills_suffix_per_mask", &db::LEFDEFReaderOptions::set_fills_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the fill geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_datatype", &db::LEFDEFReaderOptions::fills_datatype_per_mask,
|
||||
"@brief Gets the fill geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_fills_datatype_per_mask", &db::LEFDEFReaderOptions::set_fills_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the fill geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("fills_suffix_str", &db::LEFDEFReaderOptions::fills_suffix_str,
|
||||
"@hide"
|
||||
) +
|
||||
gsi::method ("fills_suffix_str=", &db::LEFDEFReaderOptions::set_fills_suffix_str, gsi::arg ("suffix"),
|
||||
"@hide"
|
||||
) +
|
||||
gsi::method ("fills_datatype_str", &db::LEFDEFReaderOptions::fills_datatype_str,
|
||||
"@hide"
|
||||
) +
|
||||
gsi::method ("fills_datatype_str=", &db::LEFDEFReaderOptions::set_fills_datatype_str, gsi::arg ("datatype"),
|
||||
"@hide"
|
||||
) +
|
||||
gsi::method ("produce_obstructions", &db::LEFDEFReaderOptions::produce_obstructions,
|
||||
"@brief Gets a value indicating whether obstruction markers shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -354,6 +354,7 @@ LEFDEFReaderOptionsEditor::LEFDEFReaderOptionsEditor (QWidget *parent)
|
|||
connect (produce_via_geometry, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_lef_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_fills, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_obstructions, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_blockages, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
connect (produce_routing, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
||||
|
|
@ -493,6 +494,9 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
data->set_produce_lef_pins (produce_lef_pins->isChecked ());
|
||||
data->set_lef_pins_suffix_str (tl::to_string (suffix_lef_pins->text ()));
|
||||
data->set_lef_pins_datatype_str (tl::to_string (datatype_lef_pins->text ()));
|
||||
data->set_produce_fills (produce_fills->isChecked ());
|
||||
data->set_fills_suffix_str (tl::to_string (suffix_fills->text ()));
|
||||
data->set_fills_datatype_str (tl::to_string (datatype_fills->text ()));
|
||||
data->set_produce_obstructions (produce_obstructions->isChecked ());
|
||||
data->set_obstructions_suffix (tl::to_string (suffix_obstructions->text ()));
|
||||
data->set_obstructions_datatype (datatype_obstructions->text ().toInt ());
|
||||
|
|
@ -556,6 +560,9 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
produce_lef_pins->setChecked (data->produce_lef_pins ());
|
||||
suffix_lef_pins->setText (tl::to_qstring (data->lef_pins_suffix_str ()));
|
||||
datatype_lef_pins->setText (tl::to_qstring (data->lef_pins_datatype_str ()));
|
||||
produce_fills->setChecked (data->produce_fills ());
|
||||
suffix_fills->setText (tl::to_qstring (data->fills_suffix_str ()));
|
||||
datatype_fills->setText (tl::to_qstring (data->fills_datatype_str ()));
|
||||
produce_obstructions->setChecked (data->produce_obstructions ());
|
||||
suffix_obstructions->setText (tl::to_qstring (data->obstructions_suffix ()));
|
||||
datatype_obstructions->setText (QString::number (data->obstructions_datatype ()));
|
||||
|
|
@ -604,6 +611,7 @@ LEFDEFReaderOptionsEditor::checkbox_changed ()
|
|||
suffix_via_geometry->setEnabled (produce_via_geometry->isChecked ());
|
||||
suffix_pins->setEnabled (produce_pins->isChecked ());
|
||||
suffix_lef_pins->setEnabled (produce_lef_pins->isChecked ());
|
||||
suffix_fills->setEnabled (produce_fills->isChecked ());
|
||||
suffix_obstructions->setEnabled (produce_obstructions->isChecked ());
|
||||
suffix_blockages->setEnabled (produce_blockages->isChecked ());
|
||||
suffix_routing->setEnabled (produce_routing->isChecked ());
|
||||
|
|
@ -612,6 +620,7 @@ LEFDEFReaderOptionsEditor::checkbox_changed ()
|
|||
datatype_via_geometry->setEnabled (produce_via_geometry->isChecked ());
|
||||
datatype_pins->setEnabled (produce_pins->isChecked ());
|
||||
datatype_lef_pins->setEnabled (produce_lef_pins->isChecked ());
|
||||
datatype_fills->setEnabled (produce_fills->isChecked ());
|
||||
datatype_obstructions->setEnabled (produce_obstructions->isChecked ());
|
||||
datatype_blockages->setEnabled (produce_blockages->isChecked ());
|
||||
datatype_routing->setEnabled (produce_routing->isChecked ());
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ TEST(16)
|
|||
run_test (_this, "def7", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new.oas.gz", options);
|
||||
|
||||
options.set_placement_blockage_layer ("PLACEMENT_BLK (60/0)");
|
||||
run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au_with_map_file-new.oas.gz", options);
|
||||
run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au2_with_map_file-new.oas.gz", options);
|
||||
}
|
||||
|
||||
TEST(17)
|
||||
|
|
@ -332,7 +332,7 @@ TEST(21)
|
|||
TEST(22)
|
||||
{
|
||||
db::LEFDEFReaderOptions opt = default_options ();
|
||||
run_test (_this, "def13", "map:test.map+lef:test.lef_5.8+def:top.def.gz", "au.oas.gz", opt);
|
||||
run_test (_this, "def13", "map:test.map+lef:test.lef_5.8+def:top.def.gz", "au2.oas.gz", opt);
|
||||
}
|
||||
|
||||
TEST(100)
|
||||
|
|
@ -710,20 +710,26 @@ TEST(117_mapfile_all)
|
|||
EXPECT_EQ (lm_read.to_string (),
|
||||
"layer_map("
|
||||
"'OUTLINE : OUTLINE (1/0)';"
|
||||
"'+M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/...\\' (1/5)';"
|
||||
"'+M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/SPNET/...\\' (1/5)';"
|
||||
"'+M1.NET;M1.SPNET : \\'M1.NET/SPNET\\' (16/0)';"
|
||||
"'+M1.NET : M1.NET (18/0)';"
|
||||
"'+M1.BLK;M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/...\\' (22/2)';"
|
||||
"'+\\'M1.NET:1\\';\\'M1.PIN:1\\';\\'M1.SPNET:1\\';\\'M1.VIA:1\\' : \\'M1.NET:1/...\\' (6/0)';"
|
||||
"'+M1.BLK;M1.FILL;M1.FILLOPC;M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/FILL/...\\' (22/2)';"
|
||||
"'+\\'M1.NET:1\\';\\'M1.PIN:1\\';\\'M1.SPNET:1\\';\\'M1.VIA:1\\' : \\'M1.NET:1/PIN:1/...\\' (6/0)';"
|
||||
"'+\\'M1.NET:1\\' : \\'M1.NET:1\\' (7/0)';"
|
||||
"'+M1.PIN : M1.PIN (3/0)';"
|
||||
"'+M1.PIN : M1.PIN (4/0)';"
|
||||
"'+M1.VIA : M1.VIA (20/0)';"
|
||||
"'+M1.VIA : M1.VIA (21/0)';"
|
||||
"'+M1.FILL : M1.FILL (14/0)';"
|
||||
"'+M1.FILL : M1.FILL (15/0)';"
|
||||
"'+M1.FILL : M1.FILL (17/0)';"
|
||||
"'+M1.FILLOPC : M1.FILLOPC (9/0)';"
|
||||
"'\\'M1.FILLOPC:1\\' : \\'M1.FILLOPC:1\\' (10/0)';"
|
||||
"'\\'M1.FILLOPC:2\\' : \\'M1.FILLOPC:2\\' (11/0)';"
|
||||
"'\\'M1.VIA:SIZE0.05X0.05\\' : \\'M1.VIA:SIZE0.05X0.05\\' (20/0)';"
|
||||
"'\\'M1.VIA:SIZE3X3\\' : \\'M1.VIA:SIZE3X3\\' (21/0)';"
|
||||
"'+M1.LABEL : M1.LABEL (26/0)';"
|
||||
"'+M1.LABEL : M1.LABEL (27/0)';"
|
||||
"'+M1.LABEL : M1.LABEL (28/1)';"
|
||||
"'+M1.BLK : M1.BLOCKAGE (13/0)';"
|
||||
"'+M1.BLK : M1.BLK (13/0)';"
|
||||
"'M1_TEXT.LABEL : M1_TEXT.LABEL (29/0)'"
|
||||
")"
|
||||
)
|
||||
|
|
@ -752,6 +758,21 @@ TEST(119_multimapping)
|
|||
)
|
||||
}
|
||||
|
||||
TEST(120_simplefill)
|
||||
{
|
||||
run_test (_this, "fill", "map:simple.map+lef:simple.lef+def:simple.def", "simple_au.oas.gz", default_options (), false);
|
||||
}
|
||||
|
||||
TEST(121_fillwithmask)
|
||||
{
|
||||
run_test (_this, "fill", "map:with_mask.map+lef:with_mask.lef+def:with_mask.def", "with_mask_au.oas.gz", default_options (), false);
|
||||
}
|
||||
|
||||
TEST(130_viasize)
|
||||
{
|
||||
run_test (_this, "viasize", "map:test.map+lef:test.lef+def:test.def", "au.oas.gz", default_options (), false);
|
||||
}
|
||||
|
||||
TEST(200_lefdef_plugin)
|
||||
{
|
||||
db::Layout ly;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
VERSION 5.8 ;
|
||||
DESIGN test ;
|
||||
DIEAREA ( 0 0 ) ( 4000 7000 ) ;
|
||||
FILLS 2 ;
|
||||
- LAYER M1
|
||||
RECT ( 1000 2000 ) ( 1500 4000 )
|
||||
RECT ( 1000 4500 ) ( 1500 6500 ) ;
|
||||
- LAYER M2
|
||||
RECT ( 1000 2000 ) ( 1500 4000 )
|
||||
POLYGON ( 1000 500 ) ( 2000 1500 ) ( 3000 1500 ) ( 3000 500 ) ;
|
||||
- LAYER M2 + OPC
|
||||
RECT ( 3000 2000 ) ( 3500 4000 ) ;
|
||||
END FILLS
|
||||
END DESIGN
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
VERSION 5.8 ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DIVIDERCHAR "/" ;
|
||||
UNITS
|
||||
DATABASE MICRONS 2000 ;
|
||||
END UNITS
|
||||
MANUFACTURINGGRID 0.000500 ;
|
||||
|
||||
LAYER M1
|
||||
TYPE ROUTING ;
|
||||
DIRECTION HORIZONTAL ;
|
||||
PITCH 100 ;
|
||||
WIDTH 50 ;
|
||||
SPACING 50 ;
|
||||
END M1
|
||||
|
||||
LAYER VIA1
|
||||
TYPE CUT ;
|
||||
END VIA1
|
||||
|
||||
LAYER M2
|
||||
TYPE ROUTING ;
|
||||
DIRECTION VERTICAL ;
|
||||
PITCH 100 ;
|
||||
WIDTH 50 ;
|
||||
SPACING 50 ;
|
||||
END M2
|
||||
|
||||
END LIBRARY
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
DIEAREA ALL 100 0
|
||||
M1 FILL 10 1
|
||||
M2 FILL 20 2
|
||||
M2 FILLOPC 20 3
|
||||
Binary file not shown.
|
|
@ -0,0 +1,14 @@
|
|||
VERSION 5.8 ;
|
||||
DESIGN test ;
|
||||
DIEAREA ( 0 0 ) ( 4000 7000 ) ;
|
||||
FILLS 2 ;
|
||||
- LAYER M1 + MASK 1
|
||||
RECT ( 1000 2000 ) ( 1500 4000 )
|
||||
RECT ( 1000 4500 ) ( 1500 6500 ) ;
|
||||
- LAYER M2 + MASK 2
|
||||
RECT ( 1000 2000 ) ( 1500 4000 )
|
||||
POLYGON ( 1000 500 ) ( 2000 1500 ) ( 3000 1500 ) ( 3000 500 ) ;
|
||||
- LAYER M2 + MASK 2 + OPC
|
||||
RECT ( 3000 2000 ) ( 3500 4000 ) ;
|
||||
END FILLS
|
||||
END DESIGN
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
VERSION 5.8 ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DIVIDERCHAR "/" ;
|
||||
UNITS
|
||||
DATABASE MICRONS 2000 ;
|
||||
END UNITS
|
||||
|
||||
LAYER M1
|
||||
TYPE ROUTING ;
|
||||
END M1
|
||||
LAYER M2
|
||||
TYPE ROUTING ;
|
||||
END M2
|
||||
|
||||
END LIBRARY
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
DIEAREA ALL 100 0
|
||||
M1 FILL:MASK:1 10 1
|
||||
M2 FILL:MASK:2 20 2
|
||||
M2 FILLOPC:MASK:2 20 3
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
VERSION 5.8 ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DESIGN chip_top ;
|
||||
UNITS DISTANCE MICRONS 1000 ;
|
||||
DIEAREA ( 0 0 ) ( 300 300 ) ;
|
||||
STYLES 2 ;
|
||||
- STYLE 1 ( 30 10 ) ( 10 30 ) ( -10 30 ) ( -30 10 ) ( -30 -10 ) ( -10 -30 ) ( 10 -30 ) ( 30 -10 ) ;
|
||||
END STYLES
|
||||
VIAS 1 ;
|
||||
- VIA1_small
|
||||
+ RECT M1 ( -20 -15 ) ( 20 15 )
|
||||
+ RECT VIA1 ( -10 -10 ) ( 10 10 )
|
||||
+ RECT VIA1 ( -13 -13 ) ( 13 13 )
|
||||
+ RECT M2 ( -25 -25 ) ( 25 25 ) ;
|
||||
- VIA1_large
|
||||
+ RECT M1 ( -20 -15 ) ( 20 15 )
|
||||
+ RECT VIA1 ( -12 -12 ) ( 12 12 )
|
||||
+ RECT VIA1 ( -13 -13 ) ( 13 13 )
|
||||
+ RECT M2 ( -25 -25 ) ( 25 25 ) ;
|
||||
END VIAS
|
||||
SPECIALNETS 1 ;
|
||||
- dummy
|
||||
+ ROUTED + RECT M2 ( 350 0 ) ( 250 100 )
|
||||
+ POLYGON M1 ( 300 0 ) ( 300 50 ) ( 350 50 ) ( 400 100 ) ( 400 0 )
|
||||
+ ROUTED + POLYGON M2 ( 300 150 ) ( 300 200 ) ( 350 200 ) ( 400 250 ) ( 400 150 )
|
||||
+ RECT M1 ( 0 0 ) ( 100 200 )
|
||||
+ ROUTED M1 30 + MASK 2 ( 0 0 15 ) ( 100 0 0 ) VIA1_small ( 100 100 10 )
|
||||
+ ROUTED M2 50 + SHAPE RING + STYLE 1 ( 0 100 ) ( 100 200 ) ( 200 200 )
|
||||
+ ROUTED + MASK 2 + RECT M2 ( 250 0 ) ( 150 100 )
|
||||
+ ROUTED + SHAPE RING + MASK 1 + VIA VIA1_large E ( 200 200 )
|
||||
;
|
||||
END SPECIALNETS
|
||||
END DESIGN
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
VERSION 5.8 ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DIVIDERCHAR "/" ;
|
||||
|
||||
UNITS
|
||||
DATABASE MICRONS 1000 ;
|
||||
END UNITS
|
||||
|
||||
MANUFACTURINGGRID 0.001 ;
|
||||
|
||||
LAYER M1
|
||||
TYPE ROUTING ;
|
||||
END M1
|
||||
|
||||
LAYER VIA1
|
||||
TYPE CUT ;
|
||||
END VIA1
|
||||
|
||||
LAYER M2
|
||||
TYPE ROUTING ;
|
||||
WIDTH 0.05 ;
|
||||
END M2
|
||||
|
||||
END LIBRARY
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# some variations of map file entries
|
||||
DIEAREA ALL 1 0
|
||||
COMP ALL 2 0
|
||||
M1 NET,SPNET 7 0
|
||||
M2 NET,SPNET 9 0
|
||||
VIA1 VIA 8 0
|
||||
VIA1 VIA:SIZE:0.02x0.02 8 1
|
||||
VIA1 VIA:SIZE:0.024x0.024 8 2
|
||||
|
|
@ -289,6 +289,18 @@ class DBReaders_TestClass < TestBase
|
|||
conf.lef_pins_datatype = 181
|
||||
assert_equal(conf.lef_pins_datatype, 181)
|
||||
|
||||
assert_equal(conf.produce_fills, true)
|
||||
conf.produce_fills = false
|
||||
assert_equal(conf.produce_fills, false)
|
||||
|
||||
assert_equal(conf.fills_suffix, ".FILL")
|
||||
conf.fills_suffix = "XFILL"
|
||||
assert_equal(conf.fills_suffix, "XFILL")
|
||||
|
||||
assert_equal(conf.fills_datatype, 5)
|
||||
conf.fills_datatype = 19
|
||||
assert_equal(conf.fills_datatype, 19)
|
||||
|
||||
assert_equal(conf.produce_obstructions, true)
|
||||
conf.produce_obstructions = false
|
||||
assert_equal(conf.produce_obstructions, false)
|
||||
|
|
|
|||
Loading…
Reference in New Issue