mirror of https://github.com/KLayout/klayout.git
WIP: further preparations for MASKSHIFT components.
This commit is contained in:
parent
5b472f33ac
commit
dcc99060fc
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 ¯o_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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ¯o_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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ¯o_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> ¯os () 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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue