mirror of https://github.com/KLayout/klayout.git
Mask specific suffixes, datatypes for LEF/DEF reader.
This commit is contained in:
parent
f17e3d50f0
commit
b9c49f0603
|
|
@ -144,14 +144,20 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions &
|
|||
m_region_layer = d.m_region_layer;
|
||||
m_produce_via_geometry = d.m_produce_via_geometry;
|
||||
m_via_geometry_suffix = d.m_via_geometry_suffix;
|
||||
m_via_geometry_suffixes = d.m_via_geometry_suffixes;
|
||||
m_via_geometry_datatype = d.m_via_geometry_datatype;
|
||||
m_via_geometry_datatypes = d.m_via_geometry_datatypes;
|
||||
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_suffixes = d.m_pins_suffixes;
|
||||
m_pins_datatype = d.m_pins_datatype;
|
||||
m_pins_datatypes = d.m_pins_datatypes;
|
||||
m_produce_lef_pins = d.m_produce_lef_pins;
|
||||
m_lef_pins_suffix = d.m_lef_pins_suffix;
|
||||
m_lef_pins_suffixes = d.m_lef_pins_suffixes;
|
||||
m_lef_pins_datatype = d.m_lef_pins_datatype;
|
||||
m_lef_pins_datatypes = d.m_lef_pins_datatypes;
|
||||
m_produce_obstructions = d.m_produce_obstructions;
|
||||
m_obstructions_suffix = d.m_obstructions_suffix;
|
||||
m_obstructions_datatype = d.m_obstructions_datatype;
|
||||
|
|
@ -163,10 +169,14 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions &
|
|||
m_labels_datatype = d.m_labels_datatype;
|
||||
m_produce_routing = d.m_produce_routing;
|
||||
m_routing_suffix = d.m_routing_suffix;
|
||||
m_routing_suffixes = d.m_routing_suffixes;
|
||||
m_routing_datatype = d.m_routing_datatype;
|
||||
m_routing_datatypes = d.m_routing_datatypes;
|
||||
m_produce_special_routing = d.m_produce_special_routing;
|
||||
m_special_routing_suffix = d.m_special_routing_suffix;
|
||||
m_special_routing_suffixes = d.m_special_routing_suffixes;
|
||||
m_special_routing_datatype = d.m_special_routing_datatype;
|
||||
m_special_routing_datatypes = d.m_special_routing_datatypes;
|
||||
m_separate_groups = d.m_separate_groups;
|
||||
m_map_file = d.m_map_file;
|
||||
m_macro_resolution_mode = d.m_macro_resolution_mode;
|
||||
|
|
@ -188,6 +198,234 @@ LEFDEFReaderOptions::format_name () const
|
|||
return n;
|
||||
}
|
||||
|
||||
static void set_datatypes (db::LEFDEFReaderOptions *data, void (db::LEFDEFReaderOptions::*clear) (), void (db::LEFDEFReaderOptions::*set_datatype) (int datatype), void (db::LEFDEFReaderOptions::*set_datatype_per_mask) (unsigned int mask, int datatype), const std::string &s)
|
||||
{
|
||||
(data->*clear) ();
|
||||
|
||||
tl::Extractor ex (s.c_str ());
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
tl::Extractor ex_saved = ex;
|
||||
|
||||
unsigned int mask = 0;
|
||||
if (ex.try_read (mask) && ex.test (":")) {
|
||||
int dt = 0;
|
||||
ex.read (dt);
|
||||
(data->*set_datatype_per_mask) (std::max ((unsigned int) 1, mask) - 1, dt);
|
||||
} else {
|
||||
ex = ex_saved;
|
||||
int dt = 0;
|
||||
ex.read (dt);
|
||||
(data->*set_datatype) (dt);
|
||||
}
|
||||
|
||||
if (ex.at_end ()) {
|
||||
break;
|
||||
} else {
|
||||
ex.expect (",");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void set_suffixes (db::LEFDEFReaderOptions *data, void (db::LEFDEFReaderOptions::*clear) (), void (db::LEFDEFReaderOptions::*set_suffix) (const std::string &suffix), void (db::LEFDEFReaderOptions::*set_suffix_per_mask) (unsigned int mask, const std::string &suffix), const std::string &s)
|
||||
{
|
||||
(data->*clear) ();
|
||||
|
||||
tl::Extractor ex (s.c_str ());
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
tl::Extractor ex_saved = ex;
|
||||
|
||||
unsigned int mask = 0;
|
||||
if (ex.try_read (mask) && ex.test (":")) {
|
||||
std::string sfx;
|
||||
ex.read_word_or_quoted (sfx);
|
||||
(data->*set_suffix_per_mask) (std::max ((unsigned int) 1, mask) - 1, sfx);
|
||||
} else {
|
||||
ex = ex_saved;
|
||||
std::string sfx;
|
||||
ex.read_word_or_quoted (sfx);
|
||||
(data->*set_suffix) (sfx);
|
||||
}
|
||||
|
||||
if (ex.at_end ()) {
|
||||
break;
|
||||
} else {
|
||||
ex.expect (",");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static std::string get_datatypes (const db::LEFDEFReaderOptions *data, int (db::LEFDEFReaderOptions::*get_datatype) () const, int (db::LEFDEFReaderOptions::*get_datatype_per_mask) (unsigned int mask) const, unsigned int max_mask)
|
||||
{
|
||||
std::string res;
|
||||
int dt0 = (data->*get_datatype) ();
|
||||
if (dt0 >= 0) {
|
||||
res += tl::to_string (dt0);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i <= max_mask; ++i) {
|
||||
int dt = (data->*get_datatype_per_mask) (i);
|
||||
if (dt >= 0 && dt != dt0) {
|
||||
if (! res.empty ()) {
|
||||
res += ",";
|
||||
}
|
||||
res += tl::to_string (i + 1);
|
||||
res += ":";
|
||||
res += tl::to_string (dt);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::string get_suffixes (const db::LEFDEFReaderOptions *data, const std::string &(db::LEFDEFReaderOptions::*get_suffix) () const, const std::string &(db::LEFDEFReaderOptions::*get_suffix_per_mask) (unsigned int mask) const, unsigned int max_mask)
|
||||
{
|
||||
std::string res;
|
||||
std::string sfx0 = (data->*get_suffix) ();
|
||||
if (! sfx0.empty ()) {
|
||||
res += tl::to_word_or_quoted_string (sfx0);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i <= max_mask; ++i) {
|
||||
std::string sfx = (data->*get_suffix_per_mask) (i);
|
||||
if (! sfx.empty () && sfx != sfx0) {
|
||||
if (! res.empty ()) {
|
||||
res += ",";
|
||||
}
|
||||
res += tl::to_string (i + 1);
|
||||
res += ":";
|
||||
res += tl::to_word_or_quoted_string (sfx);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_via_geometry_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_via_geometry_suffixes_per_mask, &LEFDEFReaderOptions::set_via_geometry_suffix, &LEFDEFReaderOptions::set_via_geometry_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::via_geometry_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::via_geometry_suffix, &LEFDEFReaderOptions::via_geometry_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_via_geometry_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_via_geometry_datatypes_per_mask, &LEFDEFReaderOptions::set_via_geometry_datatype, &LEFDEFReaderOptions::set_via_geometry_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::via_geometry_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::via_geometry_datatype, &LEFDEFReaderOptions::via_geometry_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_pins_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_pins_suffixes_per_mask, &LEFDEFReaderOptions::set_pins_suffix, &LEFDEFReaderOptions::set_pins_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::pins_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::pins_suffix, &LEFDEFReaderOptions::pins_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_pins_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_pins_datatypes_per_mask, &LEFDEFReaderOptions::set_pins_datatype, &LEFDEFReaderOptions::set_pins_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::pins_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::pins_datatype, &LEFDEFReaderOptions::pins_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_lef_pins_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_lef_pins_suffixes_per_mask, &LEFDEFReaderOptions::set_lef_pins_suffix, &LEFDEFReaderOptions::set_lef_pins_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::lef_pins_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::lef_pins_suffix, &LEFDEFReaderOptions::lef_pins_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_lef_pins_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_lef_pins_datatypes_per_mask, &LEFDEFReaderOptions::set_lef_pins_datatype, &LEFDEFReaderOptions::set_lef_pins_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::lef_pins_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::lef_pins_datatype, &LEFDEFReaderOptions::lef_pins_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_routing_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_routing_suffixes_per_mask, &LEFDEFReaderOptions::set_routing_suffix, &LEFDEFReaderOptions::set_routing_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::routing_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::routing_suffix, &LEFDEFReaderOptions::routing_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_routing_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_routing_datatypes_per_mask, &LEFDEFReaderOptions::set_routing_datatype, &LEFDEFReaderOptions::set_routing_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::routing_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::routing_datatype, &LEFDEFReaderOptions::routing_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_special_routing_suffix_str (const std::string &s)
|
||||
{
|
||||
set_suffixes (this, &LEFDEFReaderOptions::clear_special_routing_suffixes_per_mask, &LEFDEFReaderOptions::set_special_routing_suffix, &LEFDEFReaderOptions::set_special_routing_suffix_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::special_routing_suffix_str () const
|
||||
{
|
||||
return get_suffixes (this, &LEFDEFReaderOptions::special_routing_suffix, &LEFDEFReaderOptions::special_routing_suffix_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptions::set_special_routing_datatype_str (const std::string &s)
|
||||
{
|
||||
set_datatypes (this, &LEFDEFReaderOptions::clear_special_routing_datatypes_per_mask, &LEFDEFReaderOptions::set_special_routing_datatype, &LEFDEFReaderOptions::set_special_routing_datatype_per_mask, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
LEFDEFReaderOptions::special_routing_datatype_str () const
|
||||
{
|
||||
return get_datatypes (this, &LEFDEFReaderOptions::special_routing_datatype, &LEFDEFReaderOptions::special_routing_datatype_per_mask, max_mask_number ());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// LEFDEFLayerDelegate implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,34 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
template <class Value>
|
||||
const Value &per_mask_value (const std::map<unsigned int, Value> &map, const Value &def, unsigned int mask)
|
||||
{
|
||||
typename std::map<unsigned int, Value>::const_iterator i = map.find (mask);
|
||||
return i == map.end () ? def : i->second;
|
||||
}
|
||||
|
||||
inline bool per_mask_value_is_null (int dt) { return dt < 0; }
|
||||
inline bool per_mask_value_is_null (const std::string &pfx) { return pfx.empty (); }
|
||||
|
||||
template <class Value>
|
||||
void set_per_mask_value (std::map<unsigned int, Value> &map, unsigned int mask, const Value &value)
|
||||
{
|
||||
if (per_mask_value_is_null (value)) {
|
||||
map.erase (mask);
|
||||
} else {
|
||||
map [mask] = value;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
void get_max_mask_number (unsigned int &mm, const std::map<unsigned int, Value> &map)
|
||||
{
|
||||
if (! map.empty ()) {
|
||||
mm = std::max (mm, (--map.end ())->first);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The LEF/DEF importer technology component
|
||||
*
|
||||
|
|
@ -262,6 +290,42 @@ public:
|
|||
m_via_geometry_datatype = s;
|
||||
}
|
||||
|
||||
void set_via_geometry_suffix_str (const std::string &s);
|
||||
std::string via_geometry_suffix_str () const;
|
||||
|
||||
void set_via_geometry_datatype_str (const std::string &s);
|
||||
std::string via_geometry_datatype_str () const;
|
||||
|
||||
void clear_via_geometry_suffixes_per_mask ()
|
||||
{
|
||||
m_via_geometry_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_via_geometry_datatypes_per_mask ()
|
||||
{
|
||||
m_via_geometry_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &via_geometry_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_via_geometry_suffixes, m_via_geometry_suffix, mask);
|
||||
}
|
||||
|
||||
void set_via_geometry_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_via_geometry_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int via_geometry_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_via_geometry_datatypes, m_via_geometry_datatype, mask);
|
||||
}
|
||||
|
||||
void set_via_geometry_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_via_geometry_datatypes, mask, s);
|
||||
}
|
||||
|
||||
const std::string &via_cellname_prefix () const
|
||||
{
|
||||
return m_via_cellname_prefix;
|
||||
|
|
@ -302,6 +366,42 @@ public:
|
|||
m_pins_datatype = s;
|
||||
}
|
||||
|
||||
void set_pins_suffix_str (const std::string &s);
|
||||
std::string pins_suffix_str () const;
|
||||
|
||||
void set_pins_datatype_str (const std::string &s);
|
||||
std::string pins_datatype_str () const;
|
||||
|
||||
void clear_pins_suffixes_per_mask ()
|
||||
{
|
||||
m_pins_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_pins_datatypes_per_mask ()
|
||||
{
|
||||
m_pins_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &pins_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_pins_suffixes, m_pins_suffix, mask);
|
||||
}
|
||||
|
||||
void set_pins_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_pins_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int pins_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_pins_datatypes, m_pins_datatype, mask);
|
||||
}
|
||||
|
||||
void set_pins_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_pins_datatypes, mask, s);
|
||||
}
|
||||
|
||||
bool produce_lef_pins () const
|
||||
{
|
||||
return m_produce_lef_pins;
|
||||
|
|
@ -332,6 +432,42 @@ public:
|
|||
m_lef_pins_datatype = s;
|
||||
}
|
||||
|
||||
void set_lef_pins_suffix_str (const std::string &s);
|
||||
std::string lef_pins_suffix_str () const;
|
||||
|
||||
void set_lef_pins_datatype_str (const std::string &s);
|
||||
std::string lef_pins_datatype_str () const;
|
||||
|
||||
void clear_lef_pins_suffixes_per_mask ()
|
||||
{
|
||||
m_lef_pins_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_lef_pins_datatypes_per_mask ()
|
||||
{
|
||||
m_lef_pins_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &lef_pins_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_lef_pins_suffixes, m_lef_pins_suffix, mask);
|
||||
}
|
||||
|
||||
void set_lef_pins_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_lef_pins_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int lef_pins_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_lef_pins_datatypes, m_lef_pins_datatype, mask);
|
||||
}
|
||||
|
||||
void set_lef_pins_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_lef_pins_datatypes, mask, s);
|
||||
}
|
||||
|
||||
bool produce_obstructions () const
|
||||
{
|
||||
return m_produce_obstructions;
|
||||
|
|
@ -452,6 +588,42 @@ public:
|
|||
m_routing_datatype = s;
|
||||
}
|
||||
|
||||
void set_routing_suffix_str (const std::string &s);
|
||||
std::string routing_suffix_str () const;
|
||||
|
||||
void set_routing_datatype_str (const std::string &s);
|
||||
std::string routing_datatype_str () const;
|
||||
|
||||
void clear_routing_suffixes_per_mask ()
|
||||
{
|
||||
m_routing_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_routing_datatypes_per_mask ()
|
||||
{
|
||||
m_routing_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &routing_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_routing_suffixes, m_routing_suffix, mask);
|
||||
}
|
||||
|
||||
void set_routing_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_routing_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int routing_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_routing_datatypes, m_routing_datatype, mask);
|
||||
}
|
||||
|
||||
void set_routing_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_routing_datatypes, mask, s);
|
||||
}
|
||||
|
||||
bool produce_special_routing () const
|
||||
{
|
||||
return m_produce_special_routing;
|
||||
|
|
@ -482,6 +654,58 @@ public:
|
|||
m_special_routing_datatype = s;
|
||||
}
|
||||
|
||||
void set_special_routing_suffix_str (const std::string &s);
|
||||
std::string special_routing_suffix_str () const;
|
||||
|
||||
void set_special_routing_datatype_str (const std::string &s);
|
||||
std::string special_routing_datatype_str () const;
|
||||
|
||||
void clear_special_routing_suffixes_per_mask ()
|
||||
{
|
||||
m_special_routing_suffixes.clear ();
|
||||
}
|
||||
|
||||
void clear_special_routing_datatypes_per_mask ()
|
||||
{
|
||||
m_special_routing_datatypes.clear ();
|
||||
}
|
||||
|
||||
const std::string &special_routing_suffix_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_special_routing_suffixes, m_special_routing_suffix, mask);
|
||||
}
|
||||
|
||||
void set_special_routing_suffix_per_mask (unsigned int mask, const std::string &s)
|
||||
{
|
||||
set_per_mask_value (m_special_routing_suffixes, mask, s);
|
||||
}
|
||||
|
||||
int special_routing_datatype_per_mask (unsigned int mask) const
|
||||
{
|
||||
return per_mask_value (m_special_routing_datatypes, m_special_routing_datatype, mask);
|
||||
}
|
||||
|
||||
void set_special_routing_datatype_per_mask (unsigned int mask, int s)
|
||||
{
|
||||
set_per_mask_value (m_special_routing_datatypes, mask, s);
|
||||
}
|
||||
|
||||
unsigned int max_mask_number () const
|
||||
{
|
||||
unsigned int mm = 0;
|
||||
get_max_mask_number (mm, m_via_geometry_suffixes);
|
||||
get_max_mask_number (mm, m_via_geometry_datatypes);
|
||||
get_max_mask_number (mm, m_pins_suffixes);
|
||||
get_max_mask_number (mm, m_pins_datatypes);
|
||||
get_max_mask_number (mm, m_lef_pins_suffixes);
|
||||
get_max_mask_number (mm, m_lef_pins_datatypes);
|
||||
get_max_mask_number (mm, m_routing_suffixes);
|
||||
get_max_mask_number (mm, m_routing_datatypes);
|
||||
get_max_mask_number (mm, m_special_routing_suffixes);
|
||||
get_max_mask_number (mm, m_special_routing_datatypes);
|
||||
return mm;
|
||||
}
|
||||
|
||||
void clear_lef_files ()
|
||||
{
|
||||
m_lef_files.clear ();
|
||||
|
|
@ -568,13 +792,19 @@ private:
|
|||
bool m_produce_via_geometry;
|
||||
std::string m_via_geometry_suffix;
|
||||
int m_via_geometry_datatype;
|
||||
std::map<unsigned int, std::string> m_via_geometry_suffixes;
|
||||
std::map<unsigned int, int> m_via_geometry_datatypes;
|
||||
std::string m_via_cellname_prefix;
|
||||
bool m_produce_pins;
|
||||
std::string m_pins_suffix;
|
||||
int m_pins_datatype;
|
||||
std::map<unsigned int, std::string> m_pins_suffixes;
|
||||
std::map<unsigned int, int> m_pins_datatypes;
|
||||
bool m_produce_lef_pins;
|
||||
std::string m_lef_pins_suffix;
|
||||
int m_lef_pins_datatype;
|
||||
std::map<unsigned int, std::string> m_lef_pins_suffixes;
|
||||
std::map<unsigned int, int> m_lef_pins_datatypes;
|
||||
bool m_produce_obstructions;
|
||||
std::string m_obstructions_suffix;
|
||||
int m_obstructions_datatype;
|
||||
|
|
@ -587,9 +817,13 @@ private:
|
|||
bool m_produce_routing;
|
||||
std::string m_routing_suffix;
|
||||
int m_routing_datatype;
|
||||
std::map<unsigned int, std::string> m_routing_suffixes;
|
||||
std::map<unsigned int, int> m_routing_datatypes;
|
||||
bool m_produce_special_routing;
|
||||
std::string m_special_routing_suffix;
|
||||
int m_special_routing_datatype;
|
||||
std::map<unsigned int, std::string> m_special_routing_suffixes;
|
||||
std::map<unsigned int, int> m_special_routing_datatypes;
|
||||
bool m_separate_groups;
|
||||
std::string m_map_file;
|
||||
unsigned int m_macro_resolution_mode;
|
||||
|
|
|
|||
|
|
@ -278,14 +278,26 @@ class LEFDEFFormatDeclaration
|
|||
tl::make_member (&LEFDEFReaderOptions::produce_regions, &LEFDEFReaderOptions::set_produce_regions, "produce-regions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::region_layer, &LEFDEFReaderOptions::set_region_layer, "region-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_via_geometry, &LEFDEFReaderOptions::set_produce_via_geometry, "produce-via-geometry") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_suffix, &LEFDEFReaderOptions::set_via_geometry_suffix, "via-geometry-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_datatype, &LEFDEFReaderOptions::set_via_geometry_datatype, "via-geometry-datatype") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_via_geometry_suffix, "special-via_geometry-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_via_geometry_datatype, "special-via_geometry-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_suffix_str, &LEFDEFReaderOptions::set_via_geometry_suffix_str, "special-via_geometry-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_datatype_str, &LEFDEFReaderOptions::set_via_geometry_datatype_str, "special-via_geometry-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_pins, &LEFDEFReaderOptions::set_produce_pins, "produce-pins") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_suffix, &LEFDEFReaderOptions::set_pins_suffix, "pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_datatype, &LEFDEFReaderOptions::set_pins_datatype, "pins-datatype") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_pins_suffix, "special-pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_pins_datatype, "special-pins-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_suffix_str, &LEFDEFReaderOptions::set_pins_suffix_str, "special-pins-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_datatype_str, &LEFDEFReaderOptions::set_pins_datatype_str, "special-pins-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_lef_pins, &LEFDEFReaderOptions::set_produce_lef_pins, "produce-lef-pins") +
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_suffix, &LEFDEFReaderOptions::set_lef_pins_suffix, "lef-pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_datatype, &LEFDEFReaderOptions::set_lef_pins_datatype, "lef-pins-datatype") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_lef_pins_suffix, "special-lef_pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_lef_pins_datatype, "special-lef_pins-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_suffix_str, &LEFDEFReaderOptions::set_lef_pins_suffix_str, "special-lef_pins-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::lef_pins_datatype_str, &LEFDEFReaderOptions::set_lef_pins_datatype_str, "special-lef_pins-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_obstructions, &LEFDEFReaderOptions::set_produce_obstructions, "produce-obstructions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_suffix, &LEFDEFReaderOptions::set_obstructions_suffix, "obstructions-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_datatype, &LEFDEFReaderOptions::set_obstructions_datatype, "obstructions-datatype") +
|
||||
|
|
@ -296,11 +308,19 @@ class LEFDEFFormatDeclaration
|
|||
tl::make_member (&LEFDEFReaderOptions::labels_suffix, &LEFDEFReaderOptions::set_labels_suffix, "labels-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::labels_datatype, &LEFDEFReaderOptions::set_labels_datatype, "labels-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_routing, &LEFDEFReaderOptions::set_produce_routing, "produce-routing") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_suffix, &LEFDEFReaderOptions::set_routing_suffix, "routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_datatype, &LEFDEFReaderOptions::set_routing_datatype, "routing-datatype") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_routing_suffix, "special-routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_routing_datatype, "special-routing-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_suffix_str, &LEFDEFReaderOptions::set_routing_suffix_str, "special-routing-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_datatype_str, &LEFDEFReaderOptions::set_routing_datatype_str, "special-routing-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_special_routing, &LEFDEFReaderOptions::set_produce_special_routing, "produce-special-routing") +
|
||||
tl::make_member (&LEFDEFReaderOptions::special_routing_suffix, &LEFDEFReaderOptions::set_special_routing_suffix, "special-routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::special_routing_datatype, &LEFDEFReaderOptions::set_special_routing_datatype, "special-routing-datatype") +
|
||||
// for backward compatibility
|
||||
tl::make_member (&LEFDEFReaderOptions::set_special_routing_suffix, "special-routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::set_special_routing_datatype, "special-routing-datatype") +
|
||||
// new:
|
||||
tl::make_member (&LEFDEFReaderOptions::special_routing_suffix_str, &LEFDEFReaderOptions::set_special_routing_suffix_str, "special-routing-suffix-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::special_routing_datatype_str, &LEFDEFReaderOptions::set_special_routing_datatype_str, "special-routing-datatype-string") +
|
||||
tl::make_member (&LEFDEFReaderOptions::begin_lef_files, &LEFDEFReaderOptions::end_lef_files, &LEFDEFReaderOptions::push_lef_file, "lef-files") +
|
||||
tl::make_member (&LEFDEFReaderOptions::macro_resolution_mode, &LEFDEFReaderOptions::set_macro_resolution_mode, "macro-resolution-mode", MacroResolutionModeConverter ()) +
|
||||
tl::make_member (&LEFDEFReaderOptions::separate_groups, &LEFDEFReaderOptions::set_separate_groups, "separate-groups") +
|
||||
|
|
|
|||
|
|
@ -260,6 +260,46 @@ 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 ("clear_via_geometry_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_via_geometry_suffixes_per_mask,
|
||||
"@brief Clears the via geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_via_geometry_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_via_geometry_datatypes_per_mask,
|
||||
"@brief Clears the via geometry layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("via_geometry_suffix_per_mask", &db::LEFDEFReaderOptions::via_geometry_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the via geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_via_geometry_suffix_per_mask", &db::LEFDEFReaderOptions::set_via_geometry_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the via geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("via_geometry_datatype", &db::LEFDEFReaderOptions::via_geometry_datatype_per_mask,
|
||||
"@brief Gets the via geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_via_geometry_datatype_per_mask", &db::LEFDEFReaderOptions::set_via_geometry_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the via geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("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"
|
||||
|
|
@ -296,6 +336,46 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"@brief Sets the pin geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
) +
|
||||
gsi::method ("clear_pins_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_pins_suffixes_per_mask,
|
||||
"@brief Clears the pin layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_pin_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_pins_datatypes_per_mask,
|
||||
"@brief Clears the pin layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("pins_suffix_per_mask", &db::LEFDEFReaderOptions::pins_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the pin geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_pins_suffix_per_mask", &db::LEFDEFReaderOptions::set_pins_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the pin geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("pins_datatype", &db::LEFDEFReaderOptions::pins_datatype_per_mask,
|
||||
"@brief Gets the pin geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_pins_datatype_per_mask", &db::LEFDEFReaderOptions::set_pins_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the pin geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("produce_lef_pins", &db::LEFDEFReaderOptions::produce_lef_pins,
|
||||
"@brief Gets a value indicating whether LEF pin geometries shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
|
|
@ -320,6 +400,46 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"@brief Sets the LEF pin geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
) +
|
||||
gsi::method ("clear_lef_pins_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_lef_pins_suffixes_per_mask,
|
||||
"@brief Clears the LEF pin layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_lef_pins_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_lef_pins_datatypes_per_mask,
|
||||
"@brief Clears the LEF pin layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("lef_pins_suffix_per_mask", &db::LEFDEFReaderOptions::lef_pins_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the LEF pin geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_lef_pins_suffix_per_mask", &db::LEFDEFReaderOptions::set_lef_pins_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the LEF pin geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("lef_pins_datatype", &db::LEFDEFReaderOptions::lef_pins_datatype_per_mask,
|
||||
"@brief Gets the LEF pin geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_lef_pins_datatype_per_mask", &db::LEFDEFReaderOptions::set_lef_pins_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the LEF pin geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("produce_obstructions", &db::LEFDEFReaderOptions::produce_obstructions,
|
||||
"@brief Gets a value indicating whether obstruction markers shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
|
|
@ -416,6 +536,46 @@ 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 ("clear_routing_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_routing_suffixes_per_mask,
|
||||
"@brief Clears the routing layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_routing_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_routing_datatypes_per_mask,
|
||||
"@brief Clears the routing layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("routing_suffix_per_mask", &db::LEFDEFReaderOptions::routing_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the routing geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_routing_suffix_per_mask", &db::LEFDEFReaderOptions::set_routing_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the routing geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("routing_datatype", &db::LEFDEFReaderOptions::routing_datatype_per_mask,
|
||||
"@brief Gets the routing geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_routing_datatype_per_mask", &db::LEFDEFReaderOptions::set_routing_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the routing geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("produce_special_routing", &db::LEFDEFReaderOptions::produce_special_routing,
|
||||
"@brief Gets a value indicating whether special routing geometry shall be produced.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules.\n"
|
||||
|
|
@ -452,6 +612,46 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"\n"
|
||||
"The differentiation between special and normal routing has been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_special_routing_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_special_routing_suffixes_per_mask,
|
||||
"@brief Clears the special routing layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("clear_special_routing_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_special_routing_datatypes_per_mask,
|
||||
"@brief Clears the special routing layer datatypes per mask.\n"
|
||||
"See \\produce_via_geometry for details about this property.\n"
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("special_routing_suffix_per_mask", &db::LEFDEFReaderOptions::special_routing_suffix_per_mask, gsi::arg ("mask"),
|
||||
"@brief Gets the special routing geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_special_routing_suffix_per_mask", &db::LEFDEFReaderOptions::set_special_routing_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"),
|
||||
"@brief Sets the special routing geometry layer name suffix per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("special_routing_datatype", &db::LEFDEFReaderOptions::special_routing_datatype_per_mask,
|
||||
"@brief Gets the special routing geometry layer datatype value per mask.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("set_special_routing_datatype_per_mask", &db::LEFDEFReaderOptions::set_special_routing_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"),
|
||||
"@brief Sets the special routing geometry layer datatype value.\n"
|
||||
"See \\produce_via_geometry for details about the layer production rules."
|
||||
"The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)."
|
||||
"\n\n"
|
||||
"Mask specific rules have been introduced in version 0.27."
|
||||
) +
|
||||
gsi::method ("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 "
|
||||
|
|
|
|||
|
|
@ -370,13 +370,26 @@
|
|||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>As properties with name ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="inst_prop_name"/>
|
||||
<widget class="QLineEdit" name="inst_prop_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="8">
|
||||
<widget class="Line" name="line">
|
||||
|
|
@ -386,7 +399,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QLineEdit" name="placement_blockage_layer"/>
|
||||
<widget class="QLineEdit" name="placement_blockage_layer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_18">
|
||||
|
|
@ -399,10 +419,23 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="3" column="7">
|
||||
<widget class="QLineEdit" name="region_layer"/>
|
||||
<widget class="QLineEdit" name="region_layer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="4">
|
||||
<widget class="QLabel" name="help_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html></string>
|
||||
</property>
|
||||
|
|
@ -412,7 +445,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="net_prop_name"/>
|
||||
<widget class="QLineEdit" name="net_prop_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_20">
|
||||
|
|
@ -425,7 +465,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="pin_prop_name"/>
|
||||
<widget class="QLineEdit" name="pin_prop_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6">
|
||||
<widget class="QLabel" name="label_19">
|
||||
|
|
@ -490,6 +537,12 @@
|
|||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>On layer with spec ...</string>
|
||||
</property>
|
||||
|
|
@ -536,7 +589,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QLineEdit" name="outline_layer"/>
|
||||
<widget class="QLineEdit" name="outline_layer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<widget class="QCheckBox" name="produce_regions">
|
||||
|
|
@ -589,6 +649,12 @@
|
|||
</item>
|
||||
<item row="4" column="5" colspan="3">
|
||||
<widget class="QLabel" name="help_label2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><body>(<a href="int:/about/layer_specs.xml">See here for the layer specification</a>)</body></html></string>
|
||||
</property>
|
||||
|
|
@ -731,7 +797,7 @@ If used inside a technology, the file will be looked up relative to the technolo
|
|||
<item row="2" column="5">
|
||||
<widget class="QCheckBox" name="produce_special_routing">
|
||||
<property name="text">
|
||||
<string>Special routing</string>
|
||||
<string>Special routing (*)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -846,7 +912,7 @@ If used inside a technology, the file will be looked up relative to the technolo
|
|||
<item row="1" column="5">
|
||||
<widget class="QCheckBox" name="produce_routing">
|
||||
<property name="text">
|
||||
<string>Routing</string>
|
||||
<string>Routing (*)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -895,7 +961,7 @@ If used inside a technology, the file will be looked up relative to the technolo
|
|||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="produce_via_geometry">
|
||||
<property name="text">
|
||||
<string>Via geometry</string>
|
||||
<string>Via geometry (*)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -909,7 +975,7 @@ If used inside a technology, the file will be looked up relative to the technolo
|
|||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="produce_lef_pins">
|
||||
<property name="text">
|
||||
<string>LEF Pins</string>
|
||||
<string>LEF Pins (*)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -924,7 +990,7 @@ suffix ...</string>
|
|||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="produce_pins">
|
||||
<property name="text">
|
||||
<string>Pins</string>
|
||||
<string>Pins (*)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -1068,6 +1134,17 @@ type ...</string>
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>(*) Separate suffixes or datatypes can be given for different masks, using the following notation:
|
||||
"x,1:y,2:z ..." (which will use x by default, y for MASK 1, z for MASK 2 etc.)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -1158,9 +1235,49 @@ type ...</string>
|
|||
<tabstop>move_lef_files_up</tabstop>
|
||||
<tabstop>move_lef_files_down</tabstop>
|
||||
<tabstop>dbu</tabstop>
|
||||
<tabstop>prefix_via_cellname</tabstop>
|
||||
<tabstop>separate_groups</tabstop>
|
||||
<tabstop>produce_lef_geo</tabstop>
|
||||
<tabstop>produce_net_names</tabstop>
|
||||
<tabstop>net_prop_name</tabstop>
|
||||
<tabstop>produce_inst_names</tabstop>
|
||||
<tabstop>inst_prop_name</tabstop>
|
||||
<tabstop>produce_pin_names</tabstop>
|
||||
<tabstop>pin_prop_name</tabstop>
|
||||
<tabstop>produce_outlines</tabstop>
|
||||
<tabstop>outline_layer</tabstop>
|
||||
<tabstop>produce_placement_blockages</tabstop>
|
||||
<tabstop>placement_blockage_layer</tabstop>
|
||||
<tabstop>produce_regions</tabstop>
|
||||
<tabstop>region_layer</tabstop>
|
||||
<tabstop>layer_map_mode</tabstop>
|
||||
<tabstop>produce_via_geometry</tabstop>
|
||||
<tabstop>suffix_via_geometry</tabstop>
|
||||
<tabstop>datatype_via_geometry</tabstop>
|
||||
<tabstop>produce_pins</tabstop>
|
||||
<tabstop>suffix_pins</tabstop>
|
||||
<tabstop>datatype_pins</tabstop>
|
||||
<tabstop>produce_lef_pins</tabstop>
|
||||
<tabstop>suffix_lef_pins</tabstop>
|
||||
<tabstop>datatype_lef_pins</tabstop>
|
||||
<tabstop>produce_obstructions</tabstop>
|
||||
<tabstop>suffix_obstructions</tabstop>
|
||||
<tabstop>datatype_obstructions</tabstop>
|
||||
<tabstop>produce_routing</tabstop>
|
||||
<tabstop>suffix_routing</tabstop>
|
||||
<tabstop>datatype_routing</tabstop>
|
||||
<tabstop>produce_special_routing</tabstop>
|
||||
<tabstop>suffix_special_routing</tabstop>
|
||||
<tabstop>datatype_special_routing</tabstop>
|
||||
<tabstop>produce_labels</tabstop>
|
||||
<tabstop>suffix_labels</tabstop>
|
||||
<tabstop>datatype_labels</tabstop>
|
||||
<tabstop>produce_blockages</tabstop>
|
||||
<tabstop>suffix_blockages</tabstop>
|
||||
<tabstop>datatype_blockages</tabstop>
|
||||
<tabstop>read_all_cbx</tabstop>
|
||||
<tabstop>mapfile_path</tabstop>
|
||||
<tabstop>browse_mapfile</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ LEFDEFReaderOptionsEditor::LEFDEFReaderOptionsEditor (QWidget *parent)
|
|||
lay::activate_help_links (help_label2);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::LEFDEFReaderOptions *data = dynamic_cast<db::LEFDEFReaderOptions *> (options);
|
||||
|
|
@ -427,15 +427,15 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
data->set_produce_placement_blockages (produce_placement_blockages->isChecked ());
|
||||
data->set_placement_blockage_layer (tl::to_string (placement_blockage_layer->text ()));
|
||||
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_geometry_suffix_str (tl::to_string (suffix_via_geometry->text ()));
|
||||
data->set_via_geometry_datatype_str (tl::to_string (datatype_via_geometry->text ()));
|
||||
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 ());
|
||||
data->set_pins_suffix_str (tl::to_string (suffix_pins->text ()));
|
||||
data->set_pins_datatype_str (tl::to_string (datatype_pins->text ()));
|
||||
data->set_produce_lef_pins (produce_lef_pins->isChecked ());
|
||||
data->set_lef_pins_suffix (tl::to_string (suffix_lef_pins->text ()));
|
||||
data->set_lef_pins_datatype (datatype_lef_pins->text ().toInt ());
|
||||
data->set_lef_pins_suffix_str (tl::to_string (suffix_lef_pins->text ()));
|
||||
data->set_lef_pins_datatype_str (tl::to_string (datatype_lef_pins->text ()));
|
||||
data->set_produce_obstructions (produce_obstructions->isChecked ());
|
||||
data->set_obstructions_suffix (tl::to_string (suffix_obstructions->text ()));
|
||||
data->set_obstructions_datatype (datatype_obstructions->text ().toInt ());
|
||||
|
|
@ -443,11 +443,11 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
data->set_blockages_suffix (tl::to_string (suffix_blockages->text ()));
|
||||
data->set_blockages_datatype (datatype_blockages->text ().toInt ());
|
||||
data->set_produce_routing (produce_routing->isChecked ());
|
||||
data->set_routing_suffix (tl::to_string (suffix_routing->text ()));
|
||||
data->set_routing_datatype (datatype_routing->text ().toInt ());
|
||||
data->set_routing_suffix_str (tl::to_string (suffix_routing->text ()));
|
||||
data->set_routing_datatype_str (tl::to_string (datatype_routing->text ()));
|
||||
data->set_produce_special_routing (produce_special_routing->isChecked ());
|
||||
data->set_special_routing_suffix (tl::to_string (suffix_special_routing->text ()));
|
||||
data->set_special_routing_datatype (datatype_special_routing->text ().toInt ());
|
||||
data->set_special_routing_suffix_str (tl::to_string (suffix_special_routing->text ()));
|
||||
data->set_special_routing_datatype_str (tl::to_string (datatype_special_routing->text ()));
|
||||
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 ());
|
||||
|
|
@ -489,15 +489,15 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
produce_placement_blockages->setChecked (data->produce_placement_blockages ());
|
||||
placement_blockage_layer->setText (tl::to_qstring (data->placement_blockage_layer ()));
|
||||
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 ()));
|
||||
suffix_via_geometry->setText (tl::to_qstring (data->via_geometry_suffix_str ()));
|
||||
datatype_via_geometry->setText (tl::to_qstring (data->via_geometry_datatype_str ()));
|
||||
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 ()));
|
||||
suffix_pins->setText (tl::to_qstring (data->pins_suffix_str ()));
|
||||
datatype_pins->setText (tl::to_qstring (data->pins_datatype_str ()));
|
||||
produce_lef_pins->setChecked (data->produce_lef_pins ());
|
||||
suffix_lef_pins->setText (tl::to_qstring (data->lef_pins_suffix ()));
|
||||
datatype_lef_pins->setText (QString::number (data->lef_pins_datatype ()));
|
||||
suffix_lef_pins->setText (tl::to_qstring (data->lef_pins_suffix_str ()));
|
||||
datatype_lef_pins->setText (tl::to_qstring (data->lef_pins_datatype_str ()));
|
||||
produce_obstructions->setChecked (data->produce_obstructions ());
|
||||
suffix_obstructions->setText (tl::to_qstring (data->obstructions_suffix ()));
|
||||
datatype_obstructions->setText (QString::number (data->obstructions_datatype ()));
|
||||
|
|
@ -505,11 +505,11 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
suffix_blockages->setText (tl::to_qstring (data->blockages_suffix ()));
|
||||
datatype_blockages->setText (QString::number (data->blockages_datatype ()));
|
||||
produce_routing->setChecked (data->produce_routing ());
|
||||
suffix_routing->setText (tl::to_qstring (data->routing_suffix ()));
|
||||
datatype_routing->setText (QString::number (data->routing_datatype ()));
|
||||
suffix_routing->setText (tl::to_qstring (data->routing_suffix_str ()));
|
||||
datatype_routing->setText (tl::to_qstring (data->routing_datatype_str ()));
|
||||
produce_special_routing->setChecked (data->produce_special_routing ());
|
||||
suffix_special_routing->setText (tl::to_qstring (data->special_routing_suffix ()));
|
||||
datatype_special_routing->setText (QString::number (data->special_routing_datatype ()));
|
||||
suffix_special_routing->setText (tl::to_qstring (data->special_routing_suffix_str ()));
|
||||
datatype_special_routing->setText (tl::to_qstring (data->special_routing_datatype_str ()));
|
||||
produce_labels->setChecked (data->produce_labels ());
|
||||
suffix_labels->setText (tl::to_qstring (data->labels_suffix ()));
|
||||
datatype_labels->setText (QString::number (data->labels_datatype ()));
|
||||
|
|
|
|||
|
|
@ -1822,12 +1822,12 @@ make_member (void (Parent::*setter) (const Value &), const std::string &name)
|
|||
* @brief Utility: create a XMLMember object
|
||||
*/
|
||||
template <class Value, class Parent>
|
||||
XMLMember<Value, Parent, XMLMemberAccReadAdaptor <Value, Parent>, XMLMemberDummyWriteAdaptor <Value, Parent>, XMLStdConverter <Value> >
|
||||
XMLMember<Value, Parent, XMLMemberDummyReadAdaptor <Value, Parent>, XMLMemberAccWriteAdaptor <Value, Parent>, XMLStdConverter <Value> >
|
||||
make_member (void (Parent::*setter) (Value), const std::string &name)
|
||||
{
|
||||
return XMLMember<Value, Parent, XMLMemberAccReadAdaptor <Value, Parent>, XMLMemberDummyWriteAdaptor <Value, Parent>, XMLStdConverter <Value> > (
|
||||
XMLMemberAccReadAdaptor <Value, Parent> (setter),
|
||||
XMLMemberDummyWriteAdaptor <Value, Parent> (), name);
|
||||
return XMLMember<Value, Parent, XMLMemberDummyReadAdaptor <Value, Parent>, XMLMemberAccWriteAdaptor <Value, Parent>, XMLStdConverter <Value> > (
|
||||
XMLMemberDummyReadAdaptor <Value, Parent> (),
|
||||
XMLMemberAccWriteAdaptor <Value, Parent> (setter), name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue