mirror of https://github.com/KLayout/klayout.git
LEF/DEF enhancements (via cellname suffix configurable, group separation disabled by default)
Two new reader options: 1.) via cell name prefix (default is "VIA_"). This name is put in front of the via name to form the cell cell name 2.) group separation disabled by default. Groups are not put into individual parent cells by default.
This commit is contained in:
parent
9c62bb015f
commit
54cf57c772
|
|
@ -59,9 +59,9 @@ DEFImporter::DEFImporter ()
|
|||
}
|
||||
|
||||
void
|
||||
DEFImporter::read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFLayerDelegate &ld)
|
||||
DEFImporter::read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state)
|
||||
{
|
||||
m_lef_importer.read (stream, layout, ld);
|
||||
m_lef_importer.read (stream, layout, state);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -846,8 +846,9 @@ DEFImporter::read_vias (db::Layout &layout, db::Cell & /*design*/, double scale)
|
|||
ViaDesc &vd = m_via_desc.insert (std::make_pair (n, ViaDesc ())).first->second;
|
||||
|
||||
// produce a cell for vias
|
||||
std::string cellname = "VIA_" + n;
|
||||
std::string cellname = options ().via_cellname_prefix () + n;
|
||||
db::Cell &cell = layout.cell (layout.add_cell (cellname.c_str ()));
|
||||
reader_state ()->register_via_cell (n, &cell);
|
||||
vd.cell = &cell;
|
||||
|
||||
bool has_via_rule = false;
|
||||
|
|
@ -1395,7 +1396,7 @@ DEFImporter::do_read (db::Layout &layout)
|
|||
|
||||
db::Cell *others_cell = &design;
|
||||
|
||||
if (! groups.empty ()) {
|
||||
if (! groups.empty () && options ().separate_groups ()) {
|
||||
|
||||
others_cell = &layout.cell (layout.add_cell ("NOGROUP"));
|
||||
design.insert (db::CellInstArray (others_cell->cell_index (), db::Trans ()));
|
||||
|
|
@ -1410,16 +1411,21 @@ DEFImporter::do_read (db::Layout &layout)
|
|||
|
||||
if (! g->region_name.empty ()) {
|
||||
|
||||
std::map<std::string, std::vector<db::Polygon> >::const_iterator r = regions.find (g->region_name);
|
||||
std::map<std::string, std::vector<db::Polygon> >::iterator r = regions.find (g->region_name);
|
||||
if (r == regions.end ()) {
|
||||
warn (tl::sprintf (tl::to_string (tr ("Not a valid region name: %s in group %s")), g->region_name, g->name));
|
||||
|
||||
warn (tl::sprintf (tl::to_string (tr ("Not a valid region name or region is already used: %s in group %s")), g->region_name, g->name));
|
||||
|
||||
} else {
|
||||
|
||||
std::pair <bool, unsigned int> dl = open_layer (layout, std::string (), Region);
|
||||
if (dl.first) {
|
||||
for (std::vector<db::Polygon>::const_iterator p = r->second.begin (); p != r->second.end (); ++p) {
|
||||
group_cell->shapes (dl.second).insert (*p);
|
||||
}
|
||||
}
|
||||
regions.erase (r);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1451,6 +1457,23 @@ DEFImporter::do_read (db::Layout &layout)
|
|||
|
||||
}
|
||||
|
||||
// put all remaining regions into the "others_cell" which is the top cell if there are no groups.
|
||||
|
||||
if (! regions.empty ()) {
|
||||
|
||||
std::pair <bool, unsigned int> dl = open_layer (layout, std::string (), Region);
|
||||
if (dl.first) {
|
||||
|
||||
for (std::map<std::string, std::vector<db::Polygon> >::const_iterator r = regions.begin (); r != regions.end (); ++r) {
|
||||
for (std::vector<db::Polygon>::const_iterator p = r->second.begin (); p != r->second.end (); ++p) {
|
||||
others_cell->shapes (dl.second).insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// treat all remaining cells and put them into the "others_cell" which is the top cell
|
||||
// if there are no groups.
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
* This method reads the layout specified into the given layout.
|
||||
* Multiple LEF files can be read.
|
||||
*/
|
||||
void read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFLayerDelegate &ld);
|
||||
void read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state);
|
||||
|
||||
protected:
|
||||
void do_read (db::Layout &layout);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ LEFDEFReaderOptions::LEFDEFReaderOptions ()
|
|||
m_produce_via_geometry (true),
|
||||
m_via_geometry_suffix (""),
|
||||
m_via_geometry_datatype (0),
|
||||
m_via_cellname_prefix ("VIA_"),
|
||||
m_produce_pins (true),
|
||||
m_pins_suffix (".PIN"),
|
||||
m_pins_datatype (2),
|
||||
|
|
@ -66,7 +67,8 @@ LEFDEFReaderOptions::LEFDEFReaderOptions ()
|
|||
m_labels_datatype (1),
|
||||
m_produce_routing (true),
|
||||
m_routing_suffix (""),
|
||||
m_routing_datatype (0)
|
||||
m_routing_datatype (0),
|
||||
m_separate_groups (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -90,6 +92,7 @@ LEFDEFReaderOptions::LEFDEFReaderOptions (const LEFDEFReaderOptions &d)
|
|||
m_produce_via_geometry (d.m_produce_via_geometry),
|
||||
m_via_geometry_suffix (d.m_via_geometry_suffix),
|
||||
m_via_geometry_datatype (d.m_via_geometry_datatype),
|
||||
m_via_cellname_prefix (d.m_via_cellname_prefix),
|
||||
m_produce_pins (d.m_produce_pins),
|
||||
m_pins_suffix (d.m_pins_suffix),
|
||||
m_pins_datatype (d.m_pins_datatype),
|
||||
|
|
@ -105,6 +108,7 @@ LEFDEFReaderOptions::LEFDEFReaderOptions (const LEFDEFReaderOptions &d)
|
|||
m_produce_routing (d.m_produce_routing),
|
||||
m_routing_suffix (d.m_routing_suffix),
|
||||
m_routing_datatype (d.m_routing_datatype),
|
||||
m_separate_groups (d.m_separate_groups),
|
||||
m_lef_files (d.m_lef_files)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -126,7 +130,7 @@ LEFDEFReaderOptions::format_name () const
|
|||
// -----------------------------------------------------------------------------------
|
||||
// LEFDEFLayerDelegate implementation
|
||||
|
||||
LEFDEFLayerDelegate::LEFDEFLayerDelegate (const LEFDEFReaderOptions *tc)
|
||||
LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc)
|
||||
: m_create_layers (true), m_laynum (1), mp_tech_comp (tc)
|
||||
{
|
||||
if (tc) {
|
||||
|
|
@ -136,14 +140,14 @@ LEFDEFLayerDelegate::LEFDEFLayerDelegate (const LEFDEFReaderOptions *tc)
|
|||
}
|
||||
|
||||
void
|
||||
LEFDEFLayerDelegate::register_layer (const std::string &ln)
|
||||
LEFDEFReaderState::register_layer (const std::string &ln)
|
||||
{
|
||||
m_default_number.insert (std::make_pair (ln, m_laynum));
|
||||
++m_laynum;
|
||||
}
|
||||
|
||||
std::pair <bool, unsigned int>
|
||||
LEFDEFLayerDelegate::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose)
|
||||
LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose)
|
||||
{
|
||||
if (purpose == Outline || purpose == PlacementBlockage || purpose == Region) {
|
||||
|
||||
|
|
@ -327,13 +331,13 @@ LEFDEFLayerDelegate::open_layer (db::Layout &layout, const std::string &n, Layer
|
|||
}
|
||||
|
||||
void
|
||||
LEFDEFLayerDelegate::prepare (db::Layout &layout)
|
||||
LEFDEFReaderState::prepare (db::Layout &layout)
|
||||
{
|
||||
m_layer_map.prepare (layout);
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFLayerDelegate::finish (db::Layout &layout)
|
||||
LEFDEFReaderState::finish (db::Layout &layout)
|
||||
{
|
||||
int lnum = 0;
|
||||
|
||||
|
|
@ -393,11 +397,24 @@ LEFDEFLayerDelegate::finish (db::Layout &layout)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderState::register_via_cell (const std::string &vn, db::Cell *cell)
|
||||
{
|
||||
m_via_cells [vn] = cell;
|
||||
}
|
||||
|
||||
db::Cell *
|
||||
LEFDEFReaderState::via_cell (const std::string &vn)
|
||||
{
|
||||
std::map<std::string, db::Cell *>::const_iterator i = m_via_cells.find (vn);
|
||||
return i != m_via_cells.end () ? i->second : 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// LEFDEFImporter implementation
|
||||
|
||||
LEFDEFImporter::LEFDEFImporter ()
|
||||
: mp_progress (0), mp_stream (0), mp_layer_delegate (0),
|
||||
: mp_progress (0), mp_stream (0), mp_reader_state (0),
|
||||
m_produce_net_props (false), m_net_prop_name_id (0),
|
||||
m_produce_inst_props (false), m_inst_prop_name_id (0),
|
||||
m_produce_pin_props (false), m_pin_prop_name_id (0)
|
||||
|
|
@ -411,7 +428,7 @@ LEFDEFImporter::~LEFDEFImporter ()
|
|||
}
|
||||
|
||||
void
|
||||
LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFLayerDelegate &ld)
|
||||
LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state)
|
||||
{
|
||||
m_fn = stream.filename ();
|
||||
|
||||
|
|
@ -420,34 +437,39 @@ LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFLayerDe
|
|||
progress.set_format_unit (1000.0);
|
||||
progress.set_unit (10000.0);
|
||||
|
||||
mp_reader_state = &state;
|
||||
|
||||
if (state.tech_comp ()) {
|
||||
m_options = *state.tech_comp ();
|
||||
}
|
||||
|
||||
m_produce_net_props = false;
|
||||
m_net_prop_name_id = 0;
|
||||
|
||||
if (ld.tech_comp () && ld.tech_comp ()->produce_net_names ()) {
|
||||
if (m_options.produce_net_names ()) {
|
||||
m_produce_net_props = true;
|
||||
m_net_prop_name_id = layout.properties_repository ().prop_name_id (ld.tech_comp ()->net_property_name ());
|
||||
m_net_prop_name_id = layout.properties_repository ().prop_name_id (m_options.net_property_name ());
|
||||
}
|
||||
|
||||
m_produce_inst_props = false;
|
||||
m_inst_prop_name_id = 0;
|
||||
|
||||
if (ld.tech_comp () && ld.tech_comp ()->produce_inst_names ()) {
|
||||
if (m_options.produce_inst_names ()) {
|
||||
m_produce_inst_props = true;
|
||||
m_inst_prop_name_id = layout.properties_repository ().prop_name_id (ld.tech_comp ()->inst_property_name ());
|
||||
m_inst_prop_name_id = layout.properties_repository ().prop_name_id (m_options.inst_property_name ());
|
||||
}
|
||||
|
||||
m_produce_pin_props = false;
|
||||
m_pin_prop_name_id = 0;
|
||||
|
||||
if (ld.tech_comp () && ld.tech_comp ()->produce_pin_names ()) {
|
||||
if (m_options.produce_pin_names ()) {
|
||||
m_produce_pin_props = true;
|
||||
m_pin_prop_name_id = layout.properties_repository ().prop_name_id (ld.tech_comp ()->pin_property_name ());
|
||||
m_pin_prop_name_id = layout.properties_repository ().prop_name_id (m_options.pin_property_name ());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
mp_progress = &progress;
|
||||
mp_layer_delegate = &ld;
|
||||
mp_stream = new tl::TextInputStream (stream);
|
||||
|
||||
do_read (layout);
|
||||
|
|
|
|||
|
|
@ -255,6 +255,16 @@ public:
|
|||
m_via_geometry_datatype = s;
|
||||
}
|
||||
|
||||
const std::string &via_cellname_prefix () const
|
||||
{
|
||||
return m_via_cellname_prefix;
|
||||
}
|
||||
|
||||
void set_via_cellname_prefix (const std::string &s)
|
||||
{
|
||||
m_via_cellname_prefix = s;
|
||||
}
|
||||
|
||||
bool produce_pins () const
|
||||
{
|
||||
return m_produce_pins;
|
||||
|
|
@ -435,6 +445,16 @@ public:
|
|||
m_lef_files = lf;
|
||||
}
|
||||
|
||||
bool separate_groups () const
|
||||
{
|
||||
return m_separate_groups;
|
||||
}
|
||||
|
||||
void set_separate_groups (bool f)
|
||||
{
|
||||
m_separate_groups = f;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_read_all_layers;
|
||||
db::LayerMap m_layer_map;
|
||||
|
|
@ -454,6 +474,7 @@ private:
|
|||
bool m_produce_via_geometry;
|
||||
std::string m_via_geometry_suffix;
|
||||
int m_via_geometry_datatype;
|
||||
std::string m_via_cellname_prefix;
|
||||
bool m_produce_pins;
|
||||
std::string m_pins_suffix;
|
||||
int m_pins_datatype;
|
||||
|
|
@ -469,6 +490,7 @@ private:
|
|||
bool m_produce_routing;
|
||||
std::string m_routing_suffix;
|
||||
int m_routing_datatype;
|
||||
bool m_separate_groups;
|
||||
std::vector<std::string> m_lef_files;
|
||||
};
|
||||
|
||||
|
|
@ -493,13 +515,13 @@ enum LayerPurpose
|
|||
*
|
||||
* This class will handle the creation and management of layers in the LEF/DEF reader context
|
||||
*/
|
||||
class DB_PLUGIN_PUBLIC LEFDEFLayerDelegate
|
||||
class DB_PLUGIN_PUBLIC LEFDEFReaderState
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
LEFDEFLayerDelegate (const LEFDEFReaderOptions *tc);
|
||||
LEFDEFReaderState (const LEFDEFReaderOptions *tc);
|
||||
|
||||
/**
|
||||
* @brief Set the layer map
|
||||
|
|
@ -546,6 +568,16 @@ public:
|
|||
*/
|
||||
void finish (db::Layout &layout);
|
||||
|
||||
/**
|
||||
* @brief Registers a via cell for the via with the given name
|
||||
*/
|
||||
void register_via_cell (const std::string &vn, db::Cell *cell);
|
||||
|
||||
/**
|
||||
* @brief Gets the via cell for the given via name or 0 if no such via is registered
|
||||
*/
|
||||
db::Cell *via_cell (const std::string &vn);
|
||||
|
||||
/**
|
||||
* @brief Get the technology component pointer
|
||||
*/
|
||||
|
|
@ -560,6 +592,7 @@ private:
|
|||
bool m_create_layers;
|
||||
int m_laynum;
|
||||
std::map<std::string, int> m_default_number;
|
||||
std::map<std::string, db::Cell *> m_via_cells;
|
||||
const LEFDEFReaderOptions *mp_tech_comp;
|
||||
};
|
||||
|
||||
|
|
@ -602,7 +635,7 @@ public:
|
|||
*
|
||||
* This method reads the layout specified into the given layout
|
||||
*/
|
||||
void read (tl::InputStream &stream, db::Layout &layout, LEFDEFLayerDelegate &layer_delegate);
|
||||
void read (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
@ -677,7 +710,7 @@ protected:
|
|||
*/
|
||||
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose)
|
||||
{
|
||||
return mp_layer_delegate->open_layer (layout, name, purpose);
|
||||
return mp_reader_state->open_layer (layout, name, purpose);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -685,7 +718,7 @@ protected:
|
|||
*/
|
||||
void register_layer (const std::string &l)
|
||||
{
|
||||
mp_layer_delegate->register_layer (l);
|
||||
mp_reader_state->register_layer (l);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -752,7 +785,22 @@ protected:
|
|||
return m_pin_prop_name_id;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Gets the reader options
|
||||
*/
|
||||
const db::LEFDEFReaderOptions &options () const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the reader state object
|
||||
*/
|
||||
db::LEFDEFReaderState *reader_state ()
|
||||
{
|
||||
return mp_reader_state;
|
||||
}
|
||||
|
||||
void create_generated_via (std::vector<db::Polygon> &bottom,
|
||||
std::vector<db::Polygon> &cut,
|
||||
std::vector<db::Polygon> &top,
|
||||
|
|
@ -767,7 +815,7 @@ protected:
|
|||
private:
|
||||
tl::AbsoluteProgress *mp_progress;
|
||||
tl::TextInputStream *mp_stream;
|
||||
LEFDEFLayerDelegate *mp_layer_delegate;
|
||||
LEFDEFReaderState *mp_reader_state;
|
||||
std::string m_cellname;
|
||||
std::string m_fn;
|
||||
std::string m_last_token;
|
||||
|
|
@ -777,6 +825,7 @@ private:
|
|||
db::property_names_id_type m_inst_prop_name_id;
|
||||
bool m_produce_pin_props;
|
||||
db::property_names_id_type m_pin_prop_name_id;
|
||||
db::LEFDEFReaderOptions m_options;
|
||||
|
||||
const std::string &next ();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static bool is_def_format (const std::string &fn)
|
|||
* the map file.
|
||||
*/
|
||||
static void
|
||||
read_map_file (const std::string &path, db::LEFDEFLayerDelegate &layers)
|
||||
read_map_file (const std::string &path, db::LEFDEFReaderState &layers)
|
||||
{
|
||||
tl::log << tl::to_string (tr ("Reading LEF/DEF map file")) << " " << path;
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ read_map_file (const std::string &path, db::LEFDEFLayerDelegate &layers)
|
|||
* @brief Imports a .map file present next to the input files
|
||||
*/
|
||||
static void
|
||||
import_map_file_heuristics (const std::string &main_path, db::LEFDEFLayerDelegate &layers)
|
||||
import_map_file_heuristics (const std::string &main_path, db::LEFDEFReaderState &layers)
|
||||
{
|
||||
std::string input_dir = tl::absolute_path (main_path);
|
||||
if (! tl::file_exists (input_dir)) {
|
||||
|
|
@ -273,11 +273,11 @@ private:
|
|||
}
|
||||
|
||||
// Take the layer map and the "read all layers" flag from the reader options - hence we override the
|
||||
db::LEFDEFLayerDelegate layers (lefdef_options);
|
||||
db::LEFDEFReaderState state (lefdef_options);
|
||||
|
||||
import_map_file_heuristics (m_stream.absolute_path (), layers);
|
||||
import_map_file_heuristics (m_stream.absolute_path (), state);
|
||||
|
||||
layers.prepare (layout);
|
||||
state.prepare (layout);
|
||||
layout.dbu (lefdef_options->dbu ());
|
||||
|
||||
if (import_lef) {
|
||||
|
|
@ -292,12 +292,12 @@ private:
|
|||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (tr ("Reading")) << " " << lp;
|
||||
importer.read (lef_stream, layout, layers);
|
||||
importer.read (lef_stream, layout, state);
|
||||
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
importer.read (m_stream, layout, state);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -311,7 +311,7 @@ private:
|
|||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
importer.read_lef (lef_stream, layout, state);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ private:
|
|||
std::string lp = tl::combine_path (input_dir, *e);
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
importer.read_lef (lef_stream, layout, state);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -339,13 +339,13 @@ private:
|
|||
}
|
||||
|
||||
tl::log << tl::to_string (tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
importer.read (m_stream, layout, state);
|
||||
|
||||
}
|
||||
|
||||
layers.finish (layout);
|
||||
state.finish (layout);
|
||||
|
||||
m_layer_map = layers.layer_map ();
|
||||
m_layer_map = state.layer_map ();
|
||||
return m_layer_map;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -345,20 +345,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 ();
|
||||
std::pair<bool, db::cell_index_type> cn = layout.cell_by_name (("VIA_" + vn).c_str ());
|
||||
if (! cn.first) {
|
||||
db::Cell *vc = reader_state ()->via_cell (vn);
|
||||
if (! vc) {
|
||||
warn ("Unknown via: " + vn);
|
||||
}
|
||||
|
||||
if (iterate) {
|
||||
std::vector<db::Trans> ti = get_iteration (layout);
|
||||
if (cn.first) {
|
||||
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
|
||||
cell.insert (db::CellInstArray (db::CellInst (cn.second), *t * db::Trans (points [0])));
|
||||
}
|
||||
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])));
|
||||
}
|
||||
} else if (cn.first) {
|
||||
cell.insert (db::CellInstArray (db::CellInst (cn.second), db::Trans (points [0])));
|
||||
} else {
|
||||
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), db::Trans (points [0])));
|
||||
}
|
||||
|
||||
expect (";");
|
||||
|
|
@ -565,8 +563,9 @@ LEFImporter::read_viadef (Layout &layout)
|
|||
std::string n = get ();
|
||||
|
||||
// produce a cell for vias
|
||||
std::string cellname = "VIA_" + n;
|
||||
std::string cellname = options ().via_cellname_prefix () + n;
|
||||
db::Cell &cell = layout.cell (layout.add_cell (cellname.c_str ()));
|
||||
reader_state ()->register_via_cell (n, &cell);
|
||||
|
||||
ViaDesc &via_desc = m_vias[n];
|
||||
via_desc.cell = &cell;
|
||||
|
|
|
|||
|
|
@ -260,6 +260,18 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"@brief Sets the via geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
) +
|
||||
gsi::method ("via_cellname_prefix", &db::LEFDEFReaderOptions::via_cellname_prefix,
|
||||
"@brief Gets the via cellname prefix.\n"
|
||||
"Vias are represented by cells. The cell name is formed by combining the via cell name prefix and the via name.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.26.5.\n"
|
||||
) +
|
||||
gsi::method ("via_cellname_prefix=", &db::LEFDEFReaderOptions::set_via_cellname_prefix, gsi::arg ("prefix"),
|
||||
"@brief Sets the via cellname prefix.\n"
|
||||
"See \\via_cellname_prefix for details about this property.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.26.5.\n"
|
||||
) +
|
||||
gsi::method ("produce_pins", &db::LEFDEFReaderOptions::produce_pins,
|
||||
"@brief Gets a value indicating whether pin geometries shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
|
|
@ -380,6 +392,20 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"@brief Sets the routing layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
) +
|
||||
gsi::method ("separate_groups", &db::LEFDEFReaderOptions::separate_groups,
|
||||
"@brief Gets a value indicating whether to create separate parent cells for individual groups.\n"
|
||||
"If this property is set to true, instances belonging to different groups are separated by putting them into "
|
||||
"individual parent cells. These parent cells are named after the groups and are put into the master top cell.\n"
|
||||
"If this property is set to false (the default), no such group parents will be formed."
|
||||
"\n"
|
||||
"This property has been added in version 0.26.5.\n"
|
||||
) +
|
||||
gsi::method ("separate_groups=", &db::LEFDEFReaderOptions::set_separate_groups, gsi::arg ("flag"),
|
||||
"@brief Gets a value indicating whether to create separate parent cells for individual groups.\n"
|
||||
"See \\seperate_groups for details about this property.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.26.5.\n"
|
||||
) +
|
||||
gsi::method ("lef_files", &db::LEFDEFReaderOptions::lef_files,
|
||||
"@brief Gets the list technology LEF files to additionally import\n"
|
||||
"Returns a list of path names for technology LEF files to read in addition to the primary file. "
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>775</width>
|
||||
<height>766</height>
|
||||
<height>855</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
@ -200,31 +200,28 @@
|
|||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Layout database unit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dbu">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>Via cell name prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
|
|
@ -237,6 +234,40 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="dbu">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLineEdit" name="prefix_via_cellname">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QCheckBox" name="separate_groups">
|
||||
<property name="text">
|
||||
<string>Produce a parent cell for each group</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>Separate groups</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
db::LEFDEFLayerDelegate layers (&options);
|
||||
db::LEFDEFReaderState layers (&options);
|
||||
layers.prepare (*layout);
|
||||
layout->dbu (options.dbu ());
|
||||
|
||||
|
|
|
|||
|
|
@ -425,6 +425,7 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
data->set_produce_via_geometry (produce_via_geometry->isChecked ());
|
||||
data->set_via_geometry_suffix (tl::to_string (suffix_via_geometry->text ()));
|
||||
data->set_via_geometry_datatype (datatype_via_geometry->text ().toInt ());
|
||||
data->set_via_cellname_prefix (tl::to_string (prefix_via_cellname->text ()));
|
||||
data->set_produce_pins (produce_pins->isChecked ());
|
||||
data->set_pins_suffix (tl::to_string (suffix_pins->text ()));
|
||||
data->set_pins_datatype (datatype_pins->text ().toInt ());
|
||||
|
|
@ -440,6 +441,7 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
data->set_produce_labels (produce_labels->isChecked ());
|
||||
data->set_labels_suffix (tl::to_string (suffix_labels->text ()));
|
||||
data->set_labels_datatype (datatype_labels->text ().toInt ());
|
||||
data->set_separate_groups (separate_groups->isChecked ());
|
||||
|
||||
data->clear_lef_files ();
|
||||
for (int i = 0; i < lef_files->count (); ++i) {
|
||||
|
|
@ -477,6 +479,7 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
produce_via_geometry->setChecked (data->produce_via_geometry ());
|
||||
suffix_via_geometry->setText (tl::to_qstring (data->via_geometry_suffix ()));
|
||||
datatype_via_geometry->setText (QString::number (data->via_geometry_datatype ()));
|
||||
prefix_via_cellname->setText (tl::to_qstring (data->via_cellname_prefix ()));
|
||||
produce_pins->setChecked (data->produce_pins ());
|
||||
suffix_pins->setText (tl::to_qstring (data->pins_suffix ()));
|
||||
datatype_pins->setText (QString::number (data->pins_datatype ()));
|
||||
|
|
@ -492,6 +495,7 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
produce_labels->setChecked (data->produce_labels ());
|
||||
suffix_labels->setText (tl::to_qstring (data->labels_suffix ()));
|
||||
datatype_labels->setText (QString::number (data->labels_datatype ()));
|
||||
separate_groups->setChecked (data->separate_groups ());
|
||||
|
||||
checkbox_changed ();
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ static db::LEFDEFReaderOptions default_options ()
|
|||
|
||||
static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au, const db::LEFDEFReaderOptions &tc, bool priv = true)
|
||||
{
|
||||
db::LEFDEFLayerDelegate ld (&tc);
|
||||
db::LEFDEFReaderState ld (&tc);
|
||||
|
||||
db::Manager m (false);
|
||||
db::Layout layout (&m), layout2 (&m), layout_au (&m);
|
||||
|
|
@ -232,7 +232,11 @@ TEST(17)
|
|||
|
||||
TEST(18)
|
||||
{
|
||||
run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au.oas.gz", default_options ());
|
||||
db::LEFDEFReaderOptions options = default_options ();
|
||||
options.set_separate_groups (true);
|
||||
run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au.oas.gz", options);
|
||||
|
||||
run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au_nogroups.oas.gz", default_options ());
|
||||
}
|
||||
|
||||
TEST(19)
|
||||
|
|
|
|||
|
|
@ -249,6 +249,10 @@ class DBReaders_TestClass < TestBase
|
|||
conf.via_geometry_suffix = "XVIA"
|
||||
assert_equal(conf.via_geometry_suffix, "XVIA")
|
||||
|
||||
assert_equal(conf.via_cellname_prefix, "VIA_")
|
||||
conf.via_cellname_prefix = "ABC"
|
||||
assert_equal(conf.via_cellname_prefix, "ABC")
|
||||
|
||||
assert_equal(conf.via_geometry_datatype, 0)
|
||||
conf.via_geometry_datatype = 17
|
||||
assert_equal(conf.via_geometry_datatype, 17)
|
||||
|
|
@ -313,6 +317,10 @@ class DBReaders_TestClass < TestBase
|
|||
conf.routing_datatype = 22
|
||||
assert_equal(conf.routing_datatype, 22)
|
||||
|
||||
assert_equal(conf.separate_groups, false)
|
||||
conf.separate_groups = true
|
||||
assert_equal(conf.separate_groups, true)
|
||||
|
||||
assert_equal(conf.lef_files.join(","), "")
|
||||
conf.lef_files = [ "u.lef", "v.lef" ]
|
||||
assert_equal(conf.lef_files.join(","), "u.lef,v.lef")
|
||||
|
|
|
|||
Loading…
Reference in New Issue