WIP: preparations for mask shift in components.

This commit is contained in:
Matthias Koefferlein 2020-08-22 21:15:39 +02:00
parent 03c4eb1f6f
commit 77164ea879
6 changed files with 120 additions and 72 deletions

View File

@ -895,9 +895,9 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
// produce a cell for vias
std::auto_ptr<RuleBasedViaGenerator> rule_based_vg;
std::auto_ptr<GeometryBasedViaGenerator> geo_based_vg;
std::auto_ptr<GeometryBasedLayoutGenerator> geo_based_vg;
std::auto_ptr<LEFDEFViaGenerator> via_generator;
std::auto_ptr<LEFDEFLayoutGenerator> via_generator;
std::set<std::string> seen_layers;
std::vector<std::string> routing_layers;
@ -992,7 +992,7 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
} else if ((is_polygon = test ("POLYGON")) || test ("RECT")) {
if (! geo_based_vg.get ()) {
geo_based_vg.reset (new GeometryBasedViaGenerator ());
geo_based_vg.reset (new GeometryBasedLayoutGenerator ());
}
std::string ln = get ();
@ -1000,9 +1000,9 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
if (m_lef_importer.is_routing_layer (ln)) {
if (routing_layers.size () == 0) {
geo_based_vg->set_bottom_layer (ln);
geo_based_vg->set_maskshift_layer (0, ln);
} else if (routing_layers.size () == 1) {
geo_based_vg->set_top_layer (ln);
geo_based_vg->set_maskshift_layer (2, ln);
}
if (seen_layers.find (ln) == seen_layers.end ()) {
@ -1012,7 +1012,7 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s
} else if (m_lef_importer.is_cut_layer (ln)) {
geo_based_vg->set_cut_layer (ln);
geo_based_vg->set_maskshift_layer (1, ln);
}
@ -1267,6 +1267,11 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
std::string inst_name = get ();
std::string model = get ();
db::FTrans ft;
db::Vector d;
bool is_placed = false;
std::string maskshift;
std::pair<db::Cell *, db::Trans> ct = m_lef_importer.macro_by_name (model);
while (test ("+")) {
@ -1277,15 +1282,13 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
db::Point pt = get_point (scale);
test (")");
db::FTrans ft = get_orient (false /*mandatory*/);
db::Vector d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left ();
ft = get_orient (false /*mandatory*/);
d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left ();
is_placed = true;
if (ct.first) {
db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second);
instances.push_back (std::make_pair (inst_name, inst));
} else {
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
}
} else if (test ("MASKSHIFT")) {
maskshift = get ();
} else {
while (! peek ("+") && ! peek ("-") && ! peek (";")) {
@ -1297,6 +1300,15 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
expect (";");
if (is_placed) {
if (ct.first) {
db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second);
instances.push_back (std::make_pair (inst_name, inst));
} else {
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
}
}
}
}
@ -1467,9 +1479,9 @@ DEFImporter::do_read (db::Layout &layout)
} else if (test ("COMPONENTMASKSHIFT")) {
warn (tl::to_string (tr ("Component mask shift not supported currently")));
m_component_maskshift.clear ();
while (! at_end () && ! test (";")) {
take ();
m_component_maskshift.push_back (get ());
}
} else if (test ("COMPONENTS")) {

View File

@ -66,6 +66,7 @@ private:
std::map<std::string, std::map<std::string, db::Coord> > m_nondefault_widths;
std::map<std::string, ViaDesc> m_via_desc;
std::map<int, db::Polygon> m_styles;
std::vector<std::string> m_component_maskshift;
void read_polygon (db::Polygon &poly, double scale);
void read_rect (db::Polygon &poly, double scale);

View File

@ -76,7 +76,7 @@ static bool is_hex_digit (char c)
return (cup >= 'A' && cup <= 'F') || (c >= '0' && c <= '9');
}
static int hex_value (char c)
static unsigned int hex_value (char c)
{
char cup = toupper (c);
if (cup >= 'A' && cup <= 'F') {
@ -88,16 +88,42 @@ static int hex_value (char c)
}
}
static std::vector<unsigned int> string2masks (const std::string &s)
{
std::vector<unsigned int> res;
res.reserve (s.size ());
for (const char *cp = s.c_str (); *cp; ++cp) {
if (! is_hex_digit (*cp)) {
throw tl::Exception ("Not a hex string: " + s);
}
res.push_back (hex_value (*cp));
}
return res;
}
static unsigned int mask (const std::vector<unsigned int> &masks, unsigned int index)
{
if (index < (unsigned int) masks.size ()) {
return masks [index];
} else {
return 0;
}
}
// -----------------------------------------------------------------------------------
// RuleBasedViaGenerator implementation
RuleBasedViaGenerator::RuleBasedViaGenerator ()
: LEFDEFViaGenerator (), m_bottom_mask (0), m_cut_mask (0), m_top_mask (0), m_rows (1), m_columns (1)
: LEFDEFLayoutGenerator (), m_bottom_mask (0), m_cut_mask (0), m_top_mask (0), m_rows (1), m_columns (1)
{ }
void
RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm)
RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm)
{
unsigned int mask_bottom = mask (masks, 0), mask_cut = mask (masks, 1), mask_top = mask (masks, 2);
if (mask_bottom == 0) {
mask_bottom = m_bottom_mask;
}
@ -238,31 +264,27 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d
// -----------------------------------------------------------------------------------
// GeometryBasedViaGenerator implementation
GeometryBasedViaGenerator::GeometryBasedViaGenerator ()
: LEFDEFViaGenerator ()
GeometryBasedLayoutGenerator::GeometryBasedLayoutGenerator ()
: LEFDEFLayoutGenerator ()
{ }
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 LEFDEFNumberOfMasks *nm) const
GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm) const
{
if (m == 0 || ! nm) {
for (std::vector<std::string>::const_iterator l = m_maskshift_layers.begin (); l != m_maskshift_layers.end (); ++l) {
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;
}
if (*l == ln) {
} else {
unsigned int mm = mask (masks, (unsigned int) (l - m_maskshift_layers.begin ()));
if (m == 0 || ! nm) {
m = mm;
} else if (m > 0) {
m = (m + mm - 2) % nm->number_of_masks (ln) + 1;
}
break;
if (ln == m_bottom_layer) {
return mask_bottom > 0 ? ((m + mask_bottom - 2) % nm->number_of_masks (m_bottom_layer) + 1) : m;
} else if (ln == m_cut_layer) {
return mask_cut > 0 ? ((m + mask_cut - 2) % nm->number_of_masks (m_cut_layer) + 1) : m;
} else if (ln == m_top_layer) {
return mask_top > 0 ? ((m + mask_top - 2) % nm->number_of_masks (m_top_layer) + 1) : m;
}
}
@ -271,11 +293,11 @@ GeometryBasedViaGenerator::mask_for (const std::string &ln, unsigned int m, unsi
}
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)
GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, 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 = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, mask_bottom, mask_cut, mask_top, nm));
std::pair <bool, unsigned int> dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, masks, nm));
if (dl.first) {
cell.shapes (dl.second).insert (i->second);
}
@ -284,7 +306,7 @@ GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layou
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 = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, mask_bottom, mask_cut, mask_top, nm));
std::pair <bool, unsigned int> dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, masks, nm));
if (dl.first) {
cell.shapes (dl.second).insert (i->second);
}
@ -293,13 +315,13 @@ GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layou
}
void
GeometryBasedViaGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask)
GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask)
{
m_polygons [ln].push_back (std::make_pair (mask, poly));
}
void
GeometryBasedViaGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask)
GeometryBasedLayoutGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask)
{
m_boxes [ln].push_back (std::make_pair (mask, box));
}
@ -687,7 +709,7 @@ LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout
LEFDEFReaderState::~LEFDEFReaderState ()
{
for (std::map<std::string, LEFDEFViaGenerator *>::const_iterator i = m_via_generators.begin (); i != m_via_generators.end (); ++i) {
for (std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator i = m_via_generators.begin (); i != m_via_generators.end (); ++i) {
delete i->second;
}
@ -1166,7 +1188,7 @@ LEFDEFReaderState::finish (db::Layout &layout)
}
void
LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFViaGenerator *generator)
LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFLayoutGenerator *generator)
{
if (m_via_generators.find (vn) != m_via_generators.end ()) {
delete m_via_generators [vn];
@ -1183,10 +1205,10 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned
db::Cell *cell = 0;
std::map<std::string, LEFDEFViaGenerator *>::const_iterator g = m_via_generators.find (vn);
std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator g = m_via_generators.find (vn);
if (g != m_via_generators.end ()) {
LEFDEFViaGenerator *vg = g->second;
LEFDEFLayoutGenerator *vg = g->second;
std::string mask_suffix;
if (mask_bottom > 0 || mask_cut > 0 || mask_top > 0) {
@ -1201,7 +1223,13 @@ 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_top, nm);
std::vector<unsigned int> masks;
masks.reserve (3);
masks.push_back (mask_bottom);
masks.push_back (mask_cut);
masks.push_back (mask_top);
vg->create_cell (*this, layout, *cell, masks, nm);
}

View File

@ -876,25 +876,25 @@ public:
/**
* @brief Provides a via generator base class
*/
class DB_PLUGIN_PUBLIC LEFDEFViaGenerator
class DB_PLUGIN_PUBLIC LEFDEFLayoutGenerator
{
public:
LEFDEFViaGenerator () { }
virtual ~LEFDEFViaGenerator () { }
LEFDEFLayoutGenerator () { }
virtual ~LEFDEFLayoutGenerator () { }
virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) = 0;
virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm) = 0;
};
/**
* @brief Provides a via generator implementation for rule-based vias
*/
class DB_PLUGIN_PUBLIC RuleBasedViaGenerator
: public LEFDEFViaGenerator
: public LEFDEFLayoutGenerator
{
public:
RuleBasedViaGenerator ();
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm);
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm);
void set_cutsize (const db::Vector &cutsize) { m_cutsize = cutsize; }
void set_cutspacing (const db::Vector &cutspacing) { m_cutspacing = cutspacing; }
@ -927,26 +927,31 @@ private:
/**
* @brief Provides a geometry-based via generator implementation
*/
class DB_PLUGIN_PUBLIC GeometryBasedViaGenerator
: public LEFDEFViaGenerator
class DB_PLUGIN_PUBLIC GeometryBasedLayoutGenerator
: public LEFDEFLayoutGenerator
{
public:
GeometryBasedViaGenerator ();
GeometryBasedLayoutGenerator ();
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *num_cut_masks);
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *num_cut_masks);
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; }
void set_maskshift_layers (const std::vector<std::string> &ln) { m_maskshift_layers = ln; }
void set_maskshift_layer (unsigned int l, const std::string &s)
{
m_maskshift_layers.resize (l + 1, std::string ());
m_maskshift_layers[l] = s;
}
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;
std::vector<std::string> m_maskshift_layers;
unsigned int mask_for (const std::string &ln, unsigned int m, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) const;
unsigned int mask_for (const std::string &ln, unsigned int m, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm) const;
};
/**
@ -1002,7 +1007,7 @@ public:
*
* The generator is capable of creating a via for a specific mask configuration
*/
void register_via_cell (const std::string &vn, LEFDEFViaGenerator *generator);
void register_via_cell (const std::string &vn, LEFDEFLayoutGenerator *generator);
/**
* @brief Gets the via cell for the given via name or 0 if no such via is registered
@ -1065,7 +1070,7 @@ private:
std::map<std::string, int> m_default_number;
std::map<ViaKey, db::Cell *> m_via_cells;
const LEFDEFReaderOptions *mp_tech_comp;
std::map<std::string, LEFDEFViaGenerator *> m_via_generators;
std::map<std::string, LEFDEFLayoutGenerator *> m_via_generators;
std::pair <bool, unsigned int> open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask);
void map_layer_explicit (const std::string &n, LayerPurpose purpose, const LayerProperties &lp, unsigned int layer, unsigned int mask);

View File

@ -538,7 +538,7 @@ LEFImporter::read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &via_desc,
}
void
LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &via_desc, const std::string &n, double dbu)
LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &via_desc, const std::string &n, double dbu)
{
// ignore resistance spec
if (test ("RESISTANCE")) {
@ -559,9 +559,9 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi
if (m_routing_layers.find (layer_name) != m_routing_layers.end ()) {
if (routing_layers.size () == 0) {
vg->set_bottom_layer (layer_name);
lg->set_maskshift_layer (0, layer_name);
} else if (routing_layers.size () == 1) {
vg->set_top_layer (layer_name);
lg->set_maskshift_layer (2, layer_name);
}
if (seen_layers.find (layer_name) == seen_layers.end ()) {
@ -570,7 +570,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi
}
} else {
vg->set_cut_layer (layer_name);
lg->set_maskshift_layer (1, layer_name);
}
while (! at_end () && ! test (";")) {
@ -597,7 +597,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi
db::Polygon p;
p.assign_hull (points.begin (), points.end ());
vg->add_polygon (layer_name, p, mask);
lg->add_polygon (layer_name, p, mask);
expect (";");
@ -619,7 +619,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi
}
db::Box b (points [0], points [1]);
vg->add_box (layer_name, b, mask);
lg->add_box (layer_name, b, mask);
expect (";");
@ -667,7 +667,7 @@ LEFImporter::read_viadef (Layout &layout)
read_viadef_by_rule (vg.get (), via_desc, n, layout.dbu ());
reader_state ()->register_via_cell (n, vg.release ());
} else {
std::auto_ptr<GeometryBasedViaGenerator> vg (new GeometryBasedViaGenerator ());
std::auto_ptr<GeometryBasedLayoutGenerator> vg (new GeometryBasedLayoutGenerator ());
read_viadef_by_geometry (vg.get (), via_desc, n, layout.dbu ());
reader_state ()->register_via_cell (n, vg.release ());
}

View File

@ -141,11 +141,13 @@ private:
std::map<std::string, unsigned int> m_num_masks;
std::vector <db::Trans> get_iteration (db::Layout &layout);
// @@@
void read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map<std::string, db::Box> *collect_bboxes = 0, properties_id_type prop_id = 0);
// void read_geometries (GeometryBasedLayoutGenerator *lg, LayerPurpose purpose, std::map<std::string, db::Box> *collect_bboxes = 0, properties_id_type prop_id = 0);
void read_nondefaultrule (Layout &layout);
void read_viadef (Layout &layout);
void read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &desc, const std::string &n, double dbu);
void read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &desc, const std::string &n, double dbu);
void read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &desc, const std::string &n, double dbu);
void read_layer (Layout &layout);
void read_macro (Layout &layout);
};