WIP: further preparations for MASKSHIFT components.

This commit is contained in:
Matthias Koefferlein 2020-08-23 00:40:28 +02:00
parent 5b472f33ac
commit dcc99060fc
6 changed files with 412 additions and 230 deletions

View File

@ -1028,13 +1028,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, poly, mask);
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0);
} else {
db::Polygon poly;
read_rect (poly, scale);
geo_based_vg->add_polygon (ln, poly, mask);
geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0);
}
@ -1262,7 +1262,7 @@ DEFImporter::read_styles (double scale)
}
void
DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> > &instances, double scale)
DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::string, CellInstArray> > &instances, double scale)
{
while (test ("-")) {
@ -1274,8 +1274,6 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
bool is_placed = false;
std::string maskshift;
std::pair<db::Cell *, db::Trans> ct = m_lef_importer.macro_by_name (model);
while (test ("+")) {
if (test ("PLACED") || test ("FIXED") || test ("COVER")) {
@ -1303,12 +1301,22 @@ 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 {
std::map<std::string, MacroDesc>::const_iterator m = m_lef_importer.macros ().find (model);
if (m == m_lef_importer.macros ().end ()) {
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
} else {
std::pair<db::Cell *, db::Trans> ct = reader_state ()->macro_cell (model, layout, string2masks (maskshift), m->second, &m_lef_importer);
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));
}
}
}
}
@ -1491,7 +1499,7 @@ DEFImporter::do_read (db::Layout &layout)
get_long ();
expect (";");
read_components (instances, scale);
read_components (layout, instances, scale);
expect ("END");
expect ("COMPONENTS");

View File

@ -81,7 +81,7 @@ private:
void read_vias (db::Layout &layout, db::Cell &design, double scale);
void read_pins (db::Layout &layout, db::Cell &design, double scale);
void read_styles (double scale);
void read_components (std::list<std::pair<std::string, db::CellInstArray> > &instances, 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);
void produce_routing_geometry (db::Cell &design, const db::Polygon *style, unsigned int layer, properties_id_type prop_id, const std::vector<db::Point> &pts, const std::vector<std::pair<db::Coord, db::Coord> > &ext, std::pair<db::Coord, db::Coord> w);
};

View File

@ -88,7 +88,7 @@ static unsigned int hex_value (char c)
}
}
static std::vector<unsigned int> string2masks (const std::string &s)
std::vector<unsigned int> string2masks (const std::string &s)
{
std::vector<unsigned int> res;
res.reserve (s.size ());
@ -100,6 +100,8 @@ static std::vector<unsigned int> string2masks (const std::string &s)
res.push_back (hex_value (*cp));
}
std::reverse (res.begin (), res.end ());
return res;
}
@ -273,7 +275,7 @@ GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, c
{
for (std::vector<std::string>::const_iterator l = m_maskshift_layers.begin (); l != m_maskshift_layers.end (); ++l) {
if (*l == ln) {
if (! l->empty () && *l == ln) {
unsigned int mm = mask (masks, (unsigned int) (l - m_maskshift_layers.begin ()));
@ -295,35 +297,79 @@ GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, c
void
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, masks, nm));
if (dl.first) {
cell.shapes (dl.second).insert (i->second);
}
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) {
std::pair <bool, unsigned int> dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask_for (g->first.first, g->first.second.second, masks, nm));
if (dl.first) {
cell.shapes (dl.second).insert (g->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 = 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);
}
for (std::list<Via>::const_iterator v = m_vias.begin (); v != m_vias.end (); ++v) {
LEFDEFLayoutGenerator *g = reader.via_generator (v->name);
if (! g) {
continue;
}
std::vector<std::string> msl = g->maskshift_layers ();
msl.resize (3, std::string ());
db::Cell *vc = reader.via_cell (v->name, layout,
mask_for (msl [0], v->bottom_mask, masks, nm),
mask_for (msl [1], v->cut_mask, masks, nm),
mask_for (msl [2], v->top_mask, masks, nm),
nm);
if (vc) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), v->trans));
}
}
}
template <class Shape>
static db::Shape insert_shape (db::Shapes &shapes, const Shape &shape, db::properties_id_type prop_id)
{
if (prop_id == 0) {
return shapes.insert (shape);
} else {
return shapes.insert (db::object_with_properties<Shape> (shape, prop_id));
}
}
void
GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask)
GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id)
{
m_polygons [ln].push_back (std::make_pair (mask, poly));
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], poly, prop_id);
}
void
GeometryBasedLayoutGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask)
GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id)
{
m_boxes [ln].push_back (std::make_pair (mask, box));
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], 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)
{
insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], 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);
}
void
GeometryBasedLayoutGenerator::add_via (const std::string &vn, const db::Trans &trans, unsigned int bottom_mask, unsigned int cut_mask, unsigned int top_mask)
{
m_vias.push_back (Via ());
m_vias.back ().name = vn;
m_vias.back ().trans = trans;
m_vias.back ().bottom_mask = bottom_mask;
m_vias.back ().cut_mask = cut_mask;
m_vias.back ().top_mask = top_mask;
}
// -----------------------------------------------------------------------------------
@ -714,6 +760,12 @@ LEFDEFReaderState::~LEFDEFReaderState ()
}
m_via_generators.clear ();
for (std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator i = m_macro_generators.begin (); i != m_macro_generators.end (); ++i) {
delete i->second;
}
m_macro_generators.clear ();
}
void
@ -1196,6 +1248,17 @@ LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFLayoutGenerat
m_via_generators [vn] = generator;
}
LEFDEFLayoutGenerator *
LEFDEFReaderState::via_generator (const std::string &vn)
{
std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator g = m_via_generators.find (vn);
if (g != m_via_generators.end ()) {
return g->second;
} else {
return 0;
}
}
db::Cell *
LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm)
{
@ -1242,6 +1305,109 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned
}
}
void
LEFDEFReaderState::register_macro_cell (const std::string &mn, LEFDEFLayoutGenerator *generator)
{
if (m_macro_generators.find (mn) != m_macro_generators.end ()) {
delete m_macro_generators [mn];
}
m_macro_generators [mn] = generator;
}
LEFDEFLayoutGenerator *
LEFDEFReaderState::macro_generator (const std::string &mn)
{
std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator g = m_macro_generators.find (mn);
if (g != m_macro_generators.end ()) {
return g->second;
} else {
return 0;
}
}
std::pair<db::Cell *, db::Trans>
LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std::vector<unsigned int> &masks, const MacroDesc &macro_desc, const LEFDEFNumberOfMasks *nm)
{
MacroKey mk (mn, masks);
std::map<MacroKey, std::pair<db::Cell *, db::Trans> >::const_iterator i = m_macro_cells.find (mk);
if (i != m_macro_cells.end ()) {
tl_assert (! i->second.first || i->second.first->layout () == &layout);
return i->second;
}
db::Cell *cell = 0;
db::Trans tr;
std::map<std::string, LEFDEFLayoutGenerator *>::const_iterator g = m_macro_generators.find (mn);
if (g == m_macro_generators.end ()) {
return std::make_pair ((db::Cell *) 0, db::Trans ());
}
LEFDEFLayoutGenerator *mg = g->second;
if (! macro_desc.foreign_name.empty ()) {
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (macro_desc.foreign_name.c_str ());
if (c.first) {
ci = c.second;
} else {
ci = layout.add_cell (macro_desc.foreign_name.c_str ());
layout.cell (ci).set_ghost_cell (true);
}
db::Cell *foreign_cell = &layout.cell (ci);
if (macro_desc.foreign_name != mn) {
// create an indirection for renaming the cell
cell = &layout.cell (layout.add_cell (mn.c_str ()));
cell->insert (db::CellInstArray (db::CellInst (foreign_cell->cell_index ()), db::Trans (db::Point () - macro_desc.origin) * macro_desc.foreign_trans));
} else {
// use FOREIGN cell instead of new one
cell = foreign_cell;
tr = db::Trans (db::Point () - macro_desc.origin) * macro_desc.foreign_trans;
}
} else if (tech_comp ()->macro_resolution_mode () == 2) {
// create a ghost cell always
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (mn.c_str ());
if (c.first) {
ci = c.second;
} else {
ci = layout.add_cell (mn.c_str ());
layout.cell (ci).set_ghost_cell (true);
}
cell = &layout.cell (ci);
} else {
// actually implement the real cell
std::string mask_suffix;
for (std::vector<unsigned int>::const_iterator m = masks.begin (); m != masks.end (); ++m) {
mask_suffix += "_";
mask_suffix += tl::to_string (*m);
}
std::string cn = mn + mask_suffix;
cell = &layout.cell (layout.add_cell (cn.c_str ()));
mg->create_cell (*this, layout, *cell, masks, nm);
}
m_macro_cells [mk] = std::make_pair (cell, tr);
return std::make_pair (cell, tr);
}
// -----------------------------------------------------------------------------------
// LEFDEFImporter implementation

View File

@ -44,6 +44,7 @@ namespace db
{
class LEFDEFReaderState;
struct MacroDesc;
/**
* @brief Correct a path relative to the stream and technology
@ -51,6 +52,11 @@ class LEFDEFReaderState;
DB_PLUGIN_PUBLIC
std::string correct_path (const std::string &fn, const db::Layout &layout, const std::string &base_path);
/**
* @brief Convers a string to a MASKSHIFT index list
*/
std::vector<unsigned int> string2masks (const std::string &s);
/**
* @brief Generic base class of DXF reader exceptions
*/
@ -883,6 +889,7 @@ public:
virtual ~LEFDEFLayoutGenerator () { }
virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm) = 0;
virtual std::vector<std::string> maskshift_layers () const = 0;
};
/**
@ -896,6 +903,15 @@ public:
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm);
virtual std::vector<std::string> maskshift_layers () const
{
std::vector<std::string> msl;
msl.push_back (m_bottom_layer);
msl.push_back (m_cut_layer);
msl.push_back (m_top_layer);
return msl;
}
void set_cutsize (const db::Vector &cutsize) { m_cutsize = cutsize; }
void set_cutspacing (const db::Vector &cutspacing) { m_cutspacing = cutspacing; }
void set_offset (const db::Point &offset) { m_offset = offset; }
@ -931,12 +947,23 @@ class DB_PLUGIN_PUBLIC GeometryBasedLayoutGenerator
: public LEFDEFLayoutGenerator
{
public:
struct Via {
Via () : bottom_mask (0), cut_mask (0), top_mask (0) { }
std::string name;
unsigned int bottom_mask, cut_mask, top_mask;
db::Trans trans;
};
GeometryBasedLayoutGenerator ();
virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *num_cut_masks);
virtual std::vector<std::string> maskshift_layers () const { return m_maskshift_layers; }
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 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_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);
void set_maskshift_layers (const std::vector<std::string> &ln) { m_maskshift_layers = ln; }
@ -949,8 +976,8 @@ public:
}
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::map <std::pair<std::string, std::pair<LayerPurpose, unsigned int> >, db::Shapes> m_shapes;
std::list<Via> m_vias;
std::vector<std::string> m_maskshift_layers;
unsigned int mask_for (const std::string &ln, unsigned int m, const std::vector<unsigned int> &masks, const LEFDEFNumberOfMasks *nm) const;
@ -1016,6 +1043,28 @@ public:
*/
db::Cell *via_cell (const std::string &vn, Layout &layout, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm);
/**
* @brief Gets the via generator for a given via name or 0 if there is no such generator
*/
LEFDEFLayoutGenerator *via_generator (const std::string &vn);
/**
* @brief Registers a macro generator for the macro with the given name
*
* The generator is capable of creating a macro for a specific mask configuration
*/
void register_macro_cell (const std::string &mn, LEFDEFLayoutGenerator *generator);
/**
* @brief Gets the macro cell for the given macro name or 0 if no such maco is registered
*/
std::pair<db::Cell *, db::Trans> macro_cell (const std::string &mn, Layout &layout, const std::vector<unsigned int> &masks, const MacroDesc &macro_desc, const LEFDEFNumberOfMasks *nm);
/**
* @brief Gets the macro generator for a given macro name or 0 if there is no such generator
*/
LEFDEFLayoutGenerator *macro_generator (const std::string &mn);
/**
* @brief Get the technology component pointer
*/
@ -1060,6 +1109,35 @@ private:
unsigned int mask_bottom, mask_cut, mask_top;
};
/**
* @brief A key for the via cache
*/
struct MacroKey
{
MacroKey (const std::string &n, const std::vector<unsigned int> &m)
: name (n), masks (m)
{ }
bool operator== (const MacroKey &other) const
{
return name == other.name && masks == other.masks;
}
bool operator< (const MacroKey &other) const
{
if (name != other.name) {
return name < other.name;
}
if (masks != other.masks) {
return masks < other.masks;
}
return false;
}
std::string name;
std::vector<unsigned int> masks;
};
// no copying
LEFDEFReaderState (const LEFDEFReaderState &);
LEFDEFReaderState &operator= (const LEFDEFReaderState &);
@ -1070,9 +1148,11 @@ private:
bool m_has_explicit_layer_mapping;
int m_laynum;
std::map<std::string, int> m_default_number;
std::map<ViaKey, db::Cell *> m_via_cells;
const LEFDEFReaderOptions *mp_tech_comp;
std::map<ViaKey, db::Cell *> m_via_cells;
std::map<std::string, LEFDEFLayoutGenerator *> m_via_generators;
std::map<MacroKey, std::pair<db::Cell *, db::Trans> > m_macro_cells;
std::map<std::string, LEFDEFLayoutGenerator *> m_macro_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);
@ -1091,6 +1171,34 @@ struct DB_PLUGIN_PUBLIC ViaDesc
std::string m1, m2;
};
/**
* @brief A structure describing a macro
*/
struct DB_PLUGIN_PUBLIC MacroDesc
{
MacroDesc () { }
/**
* @brief The name of the FOREIGN cell if present
*/
std::string foreign_name;
/**
* @brief The transformation of the FOREIGN cell
*/
db::Trans foreign_trans;
/**
* @brief The origin
*/
db::Point origin;
/**
* @brief The bounding box
*/
db::Box bbox;
};
/**
* @brief The LEF importer object
*/

View File

@ -43,18 +43,7 @@ LEFImporter::~LEFImporter ()
// .. nothing yet ..
}
db::Box
LEFImporter::macro_bbox_by_name (const std::string &name) const
{
std::map<std::string, db::Box>::const_iterator m = m_macro_bboxes_by_name.find (name);
if (m != m_macro_bboxes_by_name.end ()) {
return m->second;
} else {
return db::Box ();
}
}
double
double
LEFImporter::layer_ext (const std::string &layer, double def_ext) const
{
std::map<std::string, double>::const_iterator l = m_default_ext.find (layer);
@ -105,19 +94,8 @@ LEFImporter::layer_width (const std::string &layer, const std::string &nondefaul
}
}
std::pair<db::Cell *, db::Trans>
LEFImporter::macro_by_name (const std::string &name) const
{
std::map<std::string, std::pair<db::Cell *, db::Trans> >::const_iterator m = m_macros_by_name.find (name);
if (m != m_macros_by_name.end ()) {
return m->second;
} else {
return std::make_pair ((db::Cell *) 0, db::Trans ());
}
}
std::vector <db::Trans>
LEFImporter::get_iteration (db::Layout &layout)
LEFImporter::get_iteration (double dbu)
{
test ("DO");
long nx = get_long ();
@ -131,7 +109,7 @@ LEFImporter::get_iteration (db::Layout &layout)
std::vector <db::Trans> t;
for (long i = 0; i < nx; ++i) {
for (long j = 0; j < ny; ++j) {
t.push_back (db::Trans (db::Vector (db::DVector (dx * i / layout.dbu (), dy * j / layout.dbu ()))));
t.push_back (db::Trans (db::Vector (db::DVector (dx * i / dbu, dy * j / dbu))));
}
}
return t;
@ -158,10 +136,9 @@ static db::Shape insert_shape (db::Cell &cell, unsigned int layer_id, const Shap
}
void
LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map<std::string, db::Box> *collect_bboxes, db::properties_id_type prop_id)
LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, LayerPurpose purpose, std::map<std::string, db::Box> *collect_boxes_for_labels, db::properties_id_type prop_id)
{
std::string layer_name;
double dbu = layout.dbu ();
double w = 0.0;
while (true) {
@ -201,12 +178,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
mask = get_mask (get_long ());
}
int layer_id = -1;
std::pair <bool, unsigned int> dl = open_layer (layout, layer_name, purpose, mask);
if (dl.first) {
layer_id = int (dl.second);
}
bool iterate = test ("ITERATE");
while (! peek (";") && ! peek ("DO")) {
@ -221,20 +192,24 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
db::Path p (points.begin (), points.end (), iw, iw / 2, iw / 2, false);
if (iterate) {
std::vector<db::Trans> ti = get_iteration (layout);
if (layer_id >= 0) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Shape s = insert_shape (cell, layer_id, p, *t, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
}
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Path pt = p.transformed (*t);
lg->add_path (layer_name, purpose, pt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box ();
}
}
} else if (layer_id >= 0) {
db::Shape s = insert_shape (cell, layer_id, p, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
} else {
lg->add_path (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
}
}
expect (";");
@ -248,12 +223,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
mask = get_mask (get_long ());
}
int layer_id = -1;
std::pair <bool, unsigned int> dl = open_layer (layout, layer_name, purpose, mask);
if (dl.first) {
layer_id = int (dl.second);
}
bool iterate = test ("ITERATE");
while (! peek (";") && ! peek ("DO")) {
@ -268,20 +237,23 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
p.assign_hull (points.begin (), points.end ());
if (iterate) {
std::vector<db::Trans> ti = get_iteration (layout);
if (layer_id >= 0) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Shape s = insert_shape (cell, layer_id, p, *t, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
}
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Polygon pt = p.transformed (*t);
lg->add_polygon (layer_name, purpose, pt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box ();
}
}
} else if (layer_id >= 0) {
db::Shape s = insert_shape (cell, layer_id, p, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
} else {
lg->add_polygon (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
}
}
expect (";");
@ -295,39 +267,39 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
mask = get_mask (get_long ());
}
int layer_id = -1;
std::pair <bool, unsigned int> dl = open_layer (layout, layer_name, purpose, mask);
if (dl.first) {
layer_id = int (dl.second);
}
bool iterate = test ("ITERATE");
for (int i = 0; i < 2; ++i) {
test ("(");
double x = get_double ();
double y = get_double ();
points.push_back (db::Point (db::DPoint (x / dbu, y / dbu)));
test (")");
}
db::Box b (points [0], points [1]);
if (iterate) {
std::vector<db::Trans> ti = get_iteration (layout);
if (layer_id >= 0) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Shape s = insert_shape (cell, layer_id, b, *t, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
}
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Box bt = b.transformed (*t);
lg->add_box (layer_name, purpose, bt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = bt;
}
}
} else if (layer_id >= 0) {
db::Shape s = insert_shape (cell, layer_id, b, prop_id);
if (collect_bboxes) {
collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox ();
} else {
lg->add_box (layer_name, purpose, b, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = b;
}
}
expect (";");
@ -348,12 +320,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
unsigned int mask_cut = (mask / 10) % 10;
unsigned int mask_top = (mask / 100) % 10;
int layer_id = -1;
std::pair <bool, unsigned int> dl = open_layer (layout, layer_name, purpose, mask);
if (dl.first) {
layer_id = int (dl.second);
}
double x = 0.0, y = 0.0;
if (test ("(")) {
x = get_double ();
@ -366,20 +332,18 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
points.push_back (db::Vector (db::DVector (x / dbu, y / dbu)));
std::string vn = get ();
db::Cell *vc = reader_state ()->via_cell (vn, layout, mask_bottom, mask_cut, mask_top, this);
if (! vc) {
warn (tl::to_string (tr ("Unknown via: ")) + vn);
}
if (iterate) {
std::vector<db::Trans> ti = get_iteration (layout);
if (vc) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), *t * db::Trans (points [0])));
}
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
lg->add_via (vn, *t * db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
}
} else if (vc) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), db::Trans (points [0])));
} else {
lg->add_via (vn, db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
}
expect (";");
@ -597,7 +561,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc
db::Polygon p;
p.assign_hull (points.begin (), points.end ());
lg->add_polygon (layer_name, p, mask);
lg->add_polygon (layer_name, ViaGeometry, p, mask, 0);
expect (";");
@ -619,7 +583,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc
}
db::Box b (points [0], points [1]);
lg->add_box (layer_name, b, mask);
lg->add_box (layer_name, ViaGeometry, b, mask, 0);
expect (";");
@ -823,14 +787,15 @@ LEFImporter::read_macro (Layout &layout)
{
std::string mn = get ();
if (m_macros_by_name.find (mn) != m_macros_by_name.end ()) {
if (m_macros.find (mn) != m_macros.end ()) {
error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn);
}
set_cellname (mn);
db::Cell &cell = layout.cell (layout.add_cell ());
db::Cell *foreign_cell = 0;
GeometryBasedLayoutGenerator *mg = new GeometryBasedLayoutGenerator ();
reader_state ()->register_macro_cell (mn, mg);
db::Trans foreign_trans;
std::string foreign_name;
@ -892,14 +857,11 @@ LEFImporter::read_macro (Layout &layout)
prop_id = layout.properties_repository ().properties_id (props);
}
std::map <std::string, db::Box> bboxes;
read_geometries (layout, cell, LEFPins, &bboxes, prop_id);
std::map <std::string, db::Box> boxes_for_labels;
read_geometries (mg, layout.dbu (), LEFPins, &boxes_for_labels, prop_id);
for (std::map <std::string, db::Box>::const_iterator b = bboxes.begin (); b != bboxes.end (); ++b) {
std::pair <bool, unsigned int> dl = open_layer (layout, b->first, Label, 0);
if (dl.first) {
cell.shapes (dl.second).insert (db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ())));
}
for (std::map <std::string, db::Box>::const_iterator b = boxes_for_labels.begin (); b != boxes_for_labels.end (); ++b) {
mg->add_text (b->first, Label, db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ())), 0, 0);
}
expect ("END");
@ -915,10 +877,6 @@ LEFImporter::read_macro (Layout &layout)
} else if (test ("FOREIGN")) {
if (foreign_cell) {
error (tl::to_string (tr ("Duplicate FOREIGN definition")));
}
std::string cn = get ();
db::Point vec;
@ -932,26 +890,24 @@ LEFImporter::read_macro (Layout &layout)
if (options ().macro_resolution_mode () != 1) {
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (cn.c_str ());
if (c.first) {
ci = c.second;
} else {
ci = layout.add_cell (cn.c_str ());
layout.cell (ci).set_ghost_cell (true);
if (! foreign_name.empty ()) {
error (tl::to_string (tr ("Duplicate FOREIGN definition")));
}
foreign_cell = &layout.cell (ci);
// What is the definition of the FOREIGN transformation?
// Guessing: this transformation moves the lower-left origin to 0,0
foreign_trans = db::Trans (db::Point () - vec) * db::Trans (ft);
foreign_name = cn;
if (foreign_name != mn) {
warn (tl::to_string (tr ("FOREIGN name differs from MACRO name in macro: ")) + mn);
}
}
} else if (test ("OBS")) {
read_geometries (layout, cell, Obstructions);
read_geometries (mg, layout.dbu (), Obstructions);
expect ("END");
} else if (test ("FIXEDMASK")) {
@ -967,69 +923,14 @@ LEFImporter::read_macro (Layout &layout)
}
if (! foreign_cell) {
mg->add_box (std::string (), Outline, db::Box (-origin, -origin + size), 0, 0);
if (options ().macro_resolution_mode () != 2) {
// actually implement the real cell
layout.rename_cell (cell.cell_index (), mn.c_str ());
std::pair <bool, unsigned int> dl = open_layer (layout, std::string (), Outline, 0);
if (dl.first) {
cell.shapes (dl.second).insert (db::Box (-origin, -origin + size));
}
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&cell, db::Trans ())));
} else {
// macro resolution mode #2 (always create a MACRO reference, no LEF geometry)
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (mn.c_str ());
if (c.first) {
ci = c.second;
} else {
ci = layout.add_cell (mn.c_str ());
layout.cell (ci).set_ghost_cell (true);
}
layout.delete_cell (cell.cell_index ());
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&layout.cell (ci), db::Trans ())));
}
} else if (foreign_name != mn) {
warn (tl::to_string (tr ("FOREIGN name differs from MACRO name in macro: ")) + mn);
layout.rename_cell (cell.cell_index (), mn.c_str ());
// clear imported LEF geometry with a foreign cell, but provide a level of indirection so we have
// both the MACRO and the FOREIGN name
for (unsigned int l = 0; l < layout.layers (); ++l) {
if (layout.is_valid_layer (l)) {
cell.clear (l);
}
}
cell.clear_insts ();
cell.insert (db::CellInstArray (db::CellInst (foreign_cell->cell_index ()), db::Trans (db::Point () - origin) * foreign_trans));
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&cell, db::Trans ())));
} else {
// use FOREIGN cell instead of new one
layout.delete_cell (cell.cell_index ());
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (foreign_cell, db::Trans (db::Point () - origin) * foreign_trans)));
}
m_macro_bboxes_by_name.insert (std::make_pair (mn, db::Box (-origin, -origin + size)));
MacroDesc macro_desc;
macro_desc.foreign_name = foreign_name;
macro_desc.foreign_trans = foreign_trans;
macro_desc.bbox = db::Box (-origin, -origin + size);
macro_desc.origin = origin;
m_macros.insert (std::make_pair (mn, macro_desc));
reset_cellname ();
}

View File

@ -57,14 +57,6 @@ public:
*/
~LEFImporter ();
/**
* @brief Get the cell for a macro name
*
* Returns 0 if the name is not a valid macro name. Otherwise it returns the pointer
* to the corresponding db::Cell object.
*/
std::pair<db::Cell *, db::Trans> macro_by_name (const std::string &macro_name) const;
/**
* @brief Get the cell bbox for the given macro name
*/
@ -126,6 +118,16 @@ public:
return m_vias;
}
/**
* @brief Gets the
*
* The map maps the macro name to the macro description.
*/
const std::map<std::string, MacroDesc> &macros () const
{
return m_macros;
}
protected:
void do_read (db::Layout &layout);
@ -134,16 +136,13 @@ private:
std::map<std::string, std::pair<double, double> > m_default_widths;
std::map<std::string, double> m_default_ext;
std::map<std::string, std::pair<double, double> > m_min_widths;
std::map<std::string, std::pair<db::Cell *, db::Trans> > m_macros_by_name;
std::map<std::string, db::Box> m_macro_bboxes_by_name;
std::map<std::string, MacroDesc> m_macros;
std::map<std::string, ViaDesc> m_vias;
std::set<std::string> m_routing_layers, m_cut_layers;
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);
std::vector <db::Trans> get_iteration (double dbu);
void read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, 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);