WIP: backward compatible implementation of multi-map capability of layer mapping.

This commit is contained in:
Matthias Koefferlein 2020-12-15 23:05:34 +01:00
parent 7852568284
commit 1f635015ce
13 changed files with 393 additions and 84 deletions

View File

@ -174,9 +174,9 @@ TextGenerator::load_from_data (const char *data, size_t ndata, const std::string
m_description = description;
m_name = name;
std::pair<bool, unsigned int> l1 = map.logical (db::LDPair (1, 0));
std::pair<bool, unsigned int> l2 = map.logical (db::LDPair (2, 0));
std::pair<bool, unsigned int> l3 = map.logical (db::LDPair (3, 0));
std::pair<bool, unsigned int> l1 = map.first_logical (db::LDPair (1, 0));
std::pair<bool, unsigned int> l2 = map.first_logical (db::LDPair (2, 0));
std::pair<bool, unsigned int> l3 = map.first_logical (db::LDPair (3, 0));
if (l1.first && l2.first) {
read_from_layout (layout, l1.second, l2.second, l3.second);
@ -193,9 +193,9 @@ TextGenerator::load_from_file (const std::string &filename)
m_description = filename;
std::pair<bool, unsigned int> l1 = map.logical (db::LDPair (1, 0));
std::pair<bool, unsigned int> l2 = map.logical (db::LDPair (2, 0));
std::pair<bool, unsigned int> l3 = map.logical (db::LDPair (3, 0));
std::pair<bool, unsigned int> l1 = map.first_logical (db::LDPair (1, 0));
std::pair<bool, unsigned int> l2 = map.first_logical (db::LDPair (2, 0));
std::pair<bool, unsigned int> l3 = map.first_logical (db::LDPair (3, 0));
if (l1.first && l2.first) {
read_from_layout (layout, l1.second, l2.second, l3.second);

View File

@ -228,7 +228,7 @@ public:
{
// get the layers which we have to look for
for (db::Layout::layer_iterator l = layout->begin_layers (); l != layout->end_layers (); ++l) {
if (layers.is_empty () || layers.logical (*(*l).second).first) {
if (layers.is_empty () || layers.is_mapped (*(*l).second)) {
m_layers.push_back ((*l).first);
}
}

View File

@ -128,7 +128,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
std::pair<bool, unsigned int> ll (false, 0);
ll = m_layer_map.logical (n, layout);
ll = m_layer_map.first_logical (n, layout);
if (! ll.first && !m_keep_layer_names) {
if (extract_plain_layer (n.c_str (), l)) {
@ -136,7 +136,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
ll = m_layer_map.logical (lp, layout);
ll = m_layer_map.first_logical (lp, layout);
} else if (extract_ld (n.c_str (), l, d, on)) {
@ -144,7 +144,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
lp.layer = l;
lp.datatype = d;
lp.name = on;
ll = m_layer_map.logical (lp, layout);
ll = m_layer_map.first_logical (lp, layout);
}

View File

@ -67,7 +67,7 @@ struct LmapEraseDatatypeInterval
void operator() (LayerMap::datatype_map &a, const LayerMap::datatype_map &)
{
if (is_static_ld (m_dfrom) && is_static_ld (m_dto)) {
a.erase (m_dfrom, m_dto);
a.erase (m_dfrom, m_dto + 1);
} else {
a.clear ();
}
@ -90,6 +90,40 @@ LayerMap::LayerMap ()
// .. nothing yet ..
}
bool
LayerMap::is_mapped (const LDPair &p) const
{
const datatype_map *dm = m_ld_map.mapped (p.layer);
if (!dm) {
return false;
}
const std::set<unsigned int> *l = dm->mapped (p.datatype);
return (l && ! l->empty ());
}
bool
LayerMap::is_mapped (const std::string &n) const
{
std::map<std::string, std::set<unsigned int> >::const_iterator m = m_name_map.find (n);
return m != m_name_map.end () && ! m->second.empty ();
}
bool
LayerMap::is_mapped (const db::LayerProperties &p) const
{
std::set<unsigned int> m;
if (p.layer >= 0 && p.datatype >= 0) {
if (is_mapped (db::LDPair (p.layer, p.datatype))) {
return true;
}
}
if (! p.name.empty ()) {
return is_mapped (p.name);
} else {
return false;
}
}
std::set<unsigned int>
LayerMap::logical (const LDPair &p) const
{
@ -233,13 +267,19 @@ LayerMap::mapping_str (unsigned int ll) const
{
std::string s;
bool f1 = true;
bool is_mmap = false;
for (ld_map::const_iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) {
bool f2 = true;
for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) {
if (d->second.find (ll) != d->second.end ()) {
if (d->second.size () > 1) {
is_mmap = true;
}
// create a string representation
if (!f2) {
s += ",";
@ -268,6 +308,10 @@ LayerMap::mapping_str (unsigned int ll) const
if (l->second.find (ll) != l->second.end ()) {
if (l->second.size () > 1) {
is_mmap = true;
}
if (!f1) {
s += ";";
}
@ -285,7 +329,11 @@ LayerMap::mapping_str (unsigned int ll) const
s += t->second.to_string (true);
}
return s;
if (is_mmap) {
return "+" + s;
} else {
return s;
}
}
void
@ -439,19 +487,19 @@ LayerMap::mapping (unsigned int ll) const
}
void
LayerMap::map (const LDPair &p, unsigned int l)
LayerMap::mmap (const LDPair &p, unsigned int l)
{
insert (p, p, l, (const LayerProperties *) 0);
}
void
LayerMap::map (const std::string &name, unsigned int l)
LayerMap::mmap (const std::string &name, unsigned int l)
{
insert (name, l, (const LayerProperties *) 0);
}
void
LayerMap::map (const LayerProperties &f, unsigned int l)
LayerMap::mmap (const LayerProperties &f, unsigned int l)
{
if (f.name.empty () || is_static_ld (f.layer) || is_static_ld (f.datatype)) {
map (db::LDPair (f.layer, f.datatype), l);
@ -462,19 +510,19 @@ LayerMap::map (const LayerProperties &f, unsigned int l)
}
void
LayerMap::map (const LDPair &p, unsigned int l, const LayerProperties &t)
LayerMap::mmap (const LDPair &p, unsigned int l, const LayerProperties &t)
{
insert (p, p, l, &t);
}
void
LayerMap::map (const std::string &name, unsigned int l, const LayerProperties &t)
LayerMap::mmap (const std::string &name, unsigned int l, const LayerProperties &t)
{
insert (name, l, &t);
}
void
LayerMap::map (const LayerProperties &f, unsigned int l, const LayerProperties &t)
LayerMap::mmap (const LayerProperties &f, unsigned int l, const LayerProperties &t)
{
if (f.name.empty () || is_static_ld (f.layer) || is_static_ld (f.datatype)) {
map (db::LDPair (f.layer, f.datatype), l, t);
@ -485,13 +533,13 @@ LayerMap::map (const LayerProperties &f, unsigned int l, const LayerProperties &
}
void
LayerMap::map (const LDPair &p1, const LDPair &p2, unsigned int l)
LayerMap::mmap (const LDPair &p1, const LDPair &p2, unsigned int l)
{
insert (p1, p2, l, (const LayerProperties *) 0);
}
void
LayerMap::map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &lp)
LayerMap::mmap (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &lp)
{
insert (p1, p2, l, &lp);
}
@ -537,15 +585,15 @@ parse_intervals (tl::Extractor &ex, ld_interval_vector &v)
}
void
LayerMap::map_expr (const std::string &expr, unsigned int l)
LayerMap::mmap_expr (const std::string &expr, unsigned int l)
{
tl::Extractor ex (expr.c_str ());
map_expr (ex, l);
mmap_expr (ex, l);
ex.expect_end ();
}
void
LayerMap::map_expr (tl::Extractor &ex, unsigned int l)
LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l)
{
try {
@ -684,7 +732,7 @@ LayerMap::unmap (const LDPair &p1, const LDPair &p2)
LmapEraseDatatypeInterval op (p1.datatype, p2.datatype);
if (db::is_static_ld (p1.layer) && db::is_static_ld (p2.layer)) {
m_ld_map.add (p1.layer, p1.layer + 1, LayerMap::datatype_map (), op);
m_ld_map.add (p1.layer, p2.layer + 1, LayerMap::datatype_map (), op);
} else {
m_ld_map.add (m_ld_map.begin ()->first.first, m_ld_map.end ()->first.second, LayerMap::datatype_map (), op);
}
@ -812,7 +860,13 @@ LayerMap::from_string_file_format (const std::string &s)
} else {
if (! ex.at_end ()) {
lm.map_expr (ex, l);
if (ex.test ("+")) {
lm.mmap_expr (ex, l);
} else if (ex.test ("-")) {
lm.unmap_expr (ex);
} else {
lm.map_expr (ex, l);
}
if (ex.test ("#") || ex.test ("//")) {
// ignore comments
} else {

View File

@ -199,7 +199,35 @@ public:
*/
LayerMap ();
/**
/**
* @brief Returns the first logical layer for a given layer specification
*/
template <class L>
std::pair<bool, unsigned int> first_logical (const L &p) const
{
std::set<unsigned int> r = logical (p);
if (r.empty ()) {
return std::make_pair (false, 0);
} else {
return std::make_pair (true, *r.begin ());
}
}
/**
* @brief Returns the first logical layer for a given layer specification
*/
template <class L>
std::pair<bool, unsigned int> first_logical (const L &p, db::Layout &layout) const
{
std::set<unsigned int> r = logical (p, layout);
if (r.empty ()) {
return std::make_pair (false, 0);
} else {
return std::make_pair (true, *r.begin ());
}
}
/**
* @brief Query a layer mapping
*
* @return A pair telling if the layer is mapped (first=true) and
@ -246,6 +274,21 @@ public:
*/
std::set<unsigned int> logical (const db::LDPair &p, db::Layout &layout) const;
/**
* @brief Returns a value indicating whether a layer (given by layer/datatype) is mapped
*/
bool is_mapped (const LDPair &p) const;
/**
* @brief Returns a value indicating whether the given named layer is mapped
*/
bool is_mapped (const std::string &name) const;
/**
* @brief Returns a value indicating whether a layer is mapped
*/
bool is_mapped (const db::LayerProperties &p) const;
/**
* @brief Gets the target layer for a given logical layer
*
@ -280,17 +323,81 @@ public:
std::vector<unsigned int> get_layers () const;
/**
* @brief Map a ldpair to a logical layer
* @brief Single-map a physical to a logical layer
*
* "Single-mapping" substitutes a layer mapping. "Multimapping" (mmap_..)
* adds to a given mapping and allows generating 1:n mappings (m:n in fact).
*/
void map (const LDPair &p, unsigned int l);
template <class S>
void map (const S &p, unsigned int l)
{
unmap (p);
mmap (p, l);
}
/**
* @brief Map a name to a logical layer
* @brief Single-map a physical to a logical layer with a target layer
*/
void map (const std::string &name, unsigned int l);
template <class S>
void map (const S &p, unsigned int l, const LayerProperties &t)
{
unmap (p);
mmap (p, l, t);
}
/**
* @brief Map a name or LDPair to a logical layer
* @brief Single-map a physical layer interval with a target layer
*/
void map (const LDPair &p1, const LDPair &p2, unsigned int l)
{
unmap (p1, p2);
mmap (p1, p2, l);
}
/**
* @brief Single-map a physical layer interval with a target layer
*/
void map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t)
{
unmap (p1, p2);
mmap (p1, p2, l, t);
}
/**
* @brief Single-map a physical layer interval (given by an expression)
*/
void map_expr (const std::string &expr, unsigned int l)
{
unmap_expr (expr);
mmap_expr (expr, l);
}
/**
* @brief Same a map_expr with a string argument but taking the expression for a tl::Extractor
*/
void map_expr (tl::Extractor &ex, unsigned int l)
{
tl::Extractor ex1 = ex;
unmap_expr (ex1);
mmap_expr (ex, l);
}
/**
* @brief Multi-map a ldpair to a logical layer
*
* "Multimapping" will not substitute but add to the mapping.
*/
void mmap (const LDPair &p, unsigned int l);
/**
* @brief Multi-map a name to a logical layer
*
* "Multimapping" will not substitute but add to the mapping.
*/
void mmap (const std::string &name, unsigned int l);
/**
* @brief Multi-map a name or LDPair to a logical layer
*
* The algorithm chooses the LDPair from the LayerProperties structure and/or
* the name if no LDPair is given. If the source LayerProperties structure does
@ -299,26 +406,26 @@ public:
* @param f The source (where to derive the match expression from)
* @param l The logical layer to map to the match expression
*/
void map (const LayerProperties &f, unsigned int l);
void mmap (const LayerProperties &f, unsigned int l);
/**
* @brief Map a ldpair to a logical layer with a target layer
* @brief Multi-map a ldpair to a logical layer with a target layer
*
* The target layer specifies which layer to create for the
* corresponding input.
*/
void map (const LDPair &p, unsigned int l, const LayerProperties &t);
void mmap (const LDPair &p, unsigned int l, const LayerProperties &t);
/**
* @brief Map a name to a logical layer with a target layer
* @brief Multi-map a name to a logical layer with a target layer
*
* The target layer specifies which layer to create for the
* corresponding input.
*/
void map (const std::string &name, unsigned int l, const LayerProperties &t);
void mmap (const std::string &name, unsigned int l, const LayerProperties &t);
/**
* @brief Map a name or LDPair to a logical layer with a target layer
* @brief Multi-map a name or LDPair to a logical layer with a target layer
*
* The algorithm chooses the LDPair from the LayerProperties structure or
* the name if no LDPair is given. If the source LayerProperties structure does
@ -328,23 +435,23 @@ public:
* @param l The logical layer to map to the match expression
* @param t The target layer to use for the mapped layer
*/
void map (const LayerProperties &f, unsigned int l, const LayerProperties &t);
void mmap (const LayerProperties &f, unsigned int l, const LayerProperties &t);
/**
* @brief Map a range of ldpair's to a logical layer
* @brief Multi-map a range of ldpair's to a logical layer
*
* The range is given by two pairs p1,p2. The layers
* mapped are [p1.l,p2.l], the datatypes mapped are [p1.d,p2.d].
*/
void map (const LDPair &p1, const LDPair &p2, unsigned int l);
void mmap (const LDPair &p1, const LDPair &p2, unsigned int l);
/**
* @brief Map a range of ldpair's to a logical layer with a target layer
* @brief Multi-map a range of ldpair's to a logical layer with a target layer
*
* The range is given by two pairs p1,p2. The layers
* mapped are [p1.l,p2.l], the datatypes mapped are [p1.d,p2.d].
*/
void map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t);
void mmap (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t);
/**
* @brief Map a range given by a string expression to a logical layer
@ -374,12 +481,12 @@ public:
* This method will throw a LayerSpecFormatException if
* something is wrong with the format string
*/
void map_expr (const std::string &expr, unsigned int l);
void mmap_expr (const std::string &expr, unsigned int l);
/**
* @brief Same a map_expr with a string argument but taking the expression for a tl::Extractor
*/
void map_expr (tl::Extractor &ex, unsigned int l);
void mmap_expr (tl::Extractor &ex, unsigned int l);
/**
* @brief Unmaps a LDPair

View File

@ -36,7 +36,7 @@ namespace gsi
static bool
lm_is_mapped (const db::LayerMap *layer_map, const db::LayerProperties &lp)
{
return !layer_map->logical (lp).empty ();
return layer_map->is_mapped (lp);
}
static int
@ -88,6 +88,36 @@ namespace gsi
layer_map->map_expr (s, l);
}
static void
lm_mmap (db::LayerMap *layer_map, const db::LayerProperties &lp, unsigned int l)
{
layer_map->mmap (lp, l);
}
static void
lm_mmap_with_target (db::LayerMap *layer_map, const db::LayerProperties &lp, unsigned int l, const db::LayerProperties &t)
{
layer_map->mmap (lp, l, t);
}
static void
lm_mmap_interval (db::LayerMap *layer_map, const db::LayerProperties &lp1, const db::LayerProperties &lp2, unsigned int l)
{
layer_map->mmap (ldpair_from_lp (lp1), ldpair_from_lp (lp2), l);
}
static void
lm_mmap_interval_with_target (db::LayerMap *layer_map, const db::LayerProperties &lp1, const db::LayerProperties &lp2, unsigned int l, const db::LayerProperties &t)
{
layer_map->mmap (ldpair_from_lp (lp1), ldpair_from_lp (lp2), l, t);
}
static void
lm_mmap_string (db::LayerMap *layer_map, std::string &s, unsigned int l)
{
layer_map->mmap_expr (s, l);
}
static void
lm_unmap (db::LayerMap *layer_map, const db::LayerProperties &lp)
{
@ -214,6 +244,51 @@ namespace gsi
"\n"
"Target mapping has been added in version 0.20.\n"
) +
gsi::method_ext ("mmap", &lm_mmap, gsi::arg ("phys_layer"), gsi::arg ("log_layer"),
"@brief Maps a physical layer to a logical one and adds to existing mappings\n"
"\n"
"This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the "
"given physical one. Hence this method implements 1:n mapping capabilities.\n"
"For backward compatibility, 'map' still substitutes mapping.\n"
"\n"
"Multi-mapping has been added in version 0.27.\n"
) +
gsi::method_ext ("mmap", &lm_mmap_with_target, gsi::arg ("phys_layer"), gsi::arg ("log_layer"), gsi::arg ("target_layer"),
"@brief Maps a physical layer to a logical one, adds to existing mappings and specifies a target layer\n"
"\n"
"This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the "
"given physical one. Hence this method implements 1:n mapping capabilities.\n"
"For backward compatibility, 'map' still substitutes mapping.\n"
"\n"
"Multi-mapping has been added in version 0.27.\n"
) +
gsi::method_ext ("mmap", &lm_mmap_interval, gsi::arg ("pl_start"), gsi::arg ("pl_stop"), gsi::arg ("log_layer"),
"@brief Maps a physical layer from the given interval to a logical one and adds to existing mappings\n"
"\n"
"This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the "
"given physical one. Hence this method implements 1:n mapping capabilities.\n"
"For backward compatibility, 'map' still substitutes mapping.\n"
"\n"
"Multi-mapping has been added in version 0.27.\n"
) +
gsi::method_ext ("mmap", &lm_mmap_interval_with_target, gsi::arg ("pl_start"), gsi::arg ("pl_stop"), gsi::arg ("log_layer"), gsi::arg ("layer_properties"),
"@brief Maps a physical layer from the given interval to a logical one, adds to existing mappings and specifies a target layer\n"
"\n"
"This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the "
"given physical one. Hence this method implements 1:n mapping capabilities.\n"
"For backward compatibility, 'map' still substitutes mapping.\n"
"\n"
"Multi-mapping has been added in version 0.27.\n"
) +
gsi::method_ext ("mmap", &lm_mmap_string, gsi::arg ("map_expr"), gsi::arg ("log_layer"),
"@brief Maps a physical layer given by an expression to a logical one and adds to existing mappings\n"
"\n"
"This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the "
"given physical one. Hence this method implements 1:n mapping capabilities.\n"
"For backward compatibility, 'map' still substitutes mapping.\n"
"\n"
"Multi-mapping has been added in version 0.27.\n"
) +
gsi::method_ext ("unmap", &lm_unmap, gsi::arg ("phys_layer"),
"@brief Unmaps the given layer\n"
"Unmapping will remove the specific layer from the mapping. This method allows generating "
@ -283,17 +358,18 @@ namespace gsi
"ly.read(\"input.gds\", lo)\n"
"@/code\n"
"\n"
"1:n mapping is possible: a physical layer can be mapped to multiple logical layers. For this, mapping acts additive. "
"1:n mapping is supported: a physical layer can be mapped to multiple logical layers using 'mmap' instead of 'map'. When using this variant, "
"mapping acts additive.\n"
"The following example will map layer 1, datatypes 0 to 255 to logical layer 0, and layer 1, datatype 17 to logical layers "
"0 plus 1:"
"\n"
"@code"
"lm = RBA::LayerMap::new\n"
"lm.map(\"1/0-255\", 0)\n"
"lm.map(\"1/17\", 1)\n"
"lm.map(\"1/0-255\", 0) # (can be 'mmap' too)\n"
"lm.mmap(\"1/17\", 1)\n"
"@/code\n"
"\n"
"'unmapping' allows to remove a mapping. This allows creating 'holes' in mapping ranges. The followin example maps "
"'unmapping' allows removing a mapping. This allows creating 'holes' in mapping ranges. The followin example maps "
"layer 1, datatypes 0 to 16 and 18 to 255 to logical layer 0:"
"\n"
"@code"

View File

@ -29,14 +29,14 @@ TEST(1)
db::LayerMap lm;
lm.map (db::LDPair (1, 5), 17);
EXPECT_EQ (lm.logical (db::LDPair (1, 6)).first, false);
EXPECT_EQ (lm.logical (db::LDPair (1, 5)).first, true);
EXPECT_EQ (lm.logical (db::LDPair (1, 5)).second, (unsigned int) 17);
EXPECT_EQ (lm.first_logical (db::LDPair (1, 6)).first, false);
EXPECT_EQ (lm.first_logical (db::LDPair (1, 5)).first, true);
EXPECT_EQ (lm.first_logical (db::LDPair (1, 5)).second, (unsigned int) 17);
lm.map (db::LDPair (1, 0), db::LDPair (5,0), 18);
EXPECT_EQ (lm.logical (db::LDPair (2, 0)).first, true);
EXPECT_EQ (lm.logical (db::LDPair (2, 0)).second, (unsigned int) 18);
EXPECT_EQ (lm.logical (db::LDPair (0, 0)).first, false);
EXPECT_EQ (lm.first_logical (db::LDPair (2, 0)).first, true);
EXPECT_EQ (lm.first_logical (db::LDPair (2, 0)).second, (unsigned int) 18);
EXPECT_EQ (lm.first_logical (db::LDPair (0, 0)).first, false);
EXPECT_EQ (lm.mapping_str (18), "1/0;2-5/0");
EXPECT_EQ (lm.mapping_str (17), "1/5");
@ -62,16 +62,16 @@ TEST(1)
lm.map_expr ("XP;10/7-8 : XN", 13);
EXPECT_EQ (lm.mapping_str (13), "10/7-8;XP : XN");
EXPECT_EQ (lm.logical ("XP").second, (unsigned int) 13);
EXPECT_EQ (lm.logical ("XP").first, true);
EXPECT_EQ (lm.logical (db::LDPair(10, 6)).first, false);
EXPECT_EQ (lm.logical (db::LDPair(10, 7)).first, true);
EXPECT_EQ (lm.logical (db::LDPair(10, 7)).second, (unsigned int) 13);
EXPECT_EQ (lm.first_logical ("XP").second, (unsigned int) 13);
EXPECT_EQ (lm.first_logical ("XP").first, true);
EXPECT_EQ (lm.first_logical (db::LDPair(10, 6)).first, false);
EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).first, true);
EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).second, (unsigned int) 13);
EXPECT_EQ (lm.mapping (13).to_string (), "XN (10/7)");
lm.clear ();
EXPECT_EQ (lm.logical (db::LDPair(10, 7)).first, false);
EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).first, false);
lm.map_expr ("'XP';10/7-8 : XN", 13);
EXPECT_EQ (lm.mapping_str (13), "10/7-8;XP : XN");
}
@ -349,55 +349,55 @@ TEST(6)
EXPECT_EQ (layers_to_string (ly), "1/0,3/10");
std::pair<bool, unsigned int> p;
p = lm.logical (db::LayerProperties (1, 0));
p = lm.first_logical (db::LayerProperties (1, 0));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 0);
p = lm.logical (db::LayerProperties (2, 0));
p = lm.first_logical (db::LayerProperties (2, 0));
EXPECT_EQ (p.first, false);
p = lm.logical (db::LayerProperties (3, 0));
p = lm.first_logical (db::LayerProperties (3, 0));
EXPECT_EQ (p.first, false);
p = lm.logical (db::LayerProperties (3, 10));
p = lm.first_logical (db::LayerProperties (3, 10));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 1);
p = lm.logical (db::LayerProperties (3, 99));
p = lm.first_logical (db::LayerProperties (3, 99));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 1);
EXPECT_EQ (layers_to_string (ly), "1/0,3/10");
// this will create layer 2/0 in the layout
p = lm.logical (db::LayerProperties (2, 0), ly);
p = lm.first_logical (db::LayerProperties (2, 0), ly);
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 2);
EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0");
p = lm.logical (db::LayerProperties (2, 0));
p = lm.first_logical (db::LayerProperties (2, 0));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 2);
p = lm.logical (db::LayerProperties (2, 0), ly);
p = lm.first_logical (db::LayerProperties (2, 0), ly);
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 2);
EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0");
// this will create layer 2/42 in the layout
p = lm.logical (db::LayerProperties (2, 42), ly);
p = lm.first_logical (db::LayerProperties (2, 42), ly);
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 3);
EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0,2/42");
p = lm.logical (db::LayerProperties (2, 42));
p = lm.first_logical (db::LayerProperties (2, 42));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 3);
p = lm.logical (db::LayerProperties (2, 42), ly);
p = lm.first_logical (db::LayerProperties (2, 42), ly);
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 3);
@ -429,19 +429,91 @@ TEST(7)
EXPECT_EQ (layers_to_string (ly), "85/0,185/0,,");
std::pair<bool, unsigned int> p;
p = lm.logical (db::LayerProperties (85, 0));
p = lm.first_logical (db::LayerProperties (85, 0));
EXPECT_EQ (p.first, false);
EXPECT_EQ (p.second, (unsigned int) 0);
p = lm.logical (db::LayerProperties (185, 0));
p = lm.first_logical (db::LayerProperties (185, 0));
EXPECT_EQ (p.first, false);
EXPECT_EQ (p.second, (unsigned int) 0);
p = lm.logical (db::LayerProperties (10000, 0));
p = lm.first_logical (db::LayerProperties (10000, 0));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 1);
p = lm.logical (db::LayerProperties (10001, 0));
p = lm.first_logical (db::LayerProperties (10001, 0));
EXPECT_EQ (p.first, true);
EXPECT_EQ (p.second, (unsigned int) 0);
}
// multi-mapping, unmapping
TEST(8)
{
db::LayerMap lm;
unsigned int n = 0;
// refinement
// all
lm.mmap_expr ("*/*", n++);
EXPECT_EQ (lm.mapping_str (0), "*/*");
EXPECT_EQ (lm.to_string (),
"layer_map('*/*')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// some
lm.mmap_expr ("*/1-10", n++);
EXPECT_EQ (lm.to_string (),
"layer_map('+*/0,1-10,11-*';'+*/1-10')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// others
lm.mmap_expr ("*/5,15", n++);
EXPECT_EQ (lm.to_string (),
"layer_map('+*/0,1-4,5,6-10,11-14,15,16-*';'+*/1-4,5,6-10';'+*/5,15')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// NOTE: the leading "+" indicates that the listed layers may go somewhere else, so we can't plainly map them
EXPECT_EQ (lm.mapping_str (0), "+*/0,1-4,5,6-10,11-14,15,16-*");
EXPECT_EQ (lm.mapping_str (1), "+*/1-4,5,6-10");
EXPECT_EQ (lm.mapping_str (2), "+*/5,15");
EXPECT_EQ (lm.mapping_str (3), "");
lm = db::LayerMap ();
n = 0;
// refinement
// all
lm.mmap_expr ("*/*", n++);
EXPECT_EQ (lm.mapping_str (0), "*/*");
EXPECT_EQ (lm.to_string (),
"layer_map('*/*')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// some
lm.mmap_expr ("1-10/*", n++);
EXPECT_EQ (lm.to_string (),
"layer_map('+0/*;1-10/*;11-*/*';'+1-10/*')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// others
lm.mmap_expr ("5,15/*", n++);
EXPECT_EQ (lm.to_string (),
"layer_map('+0/*;1-4/*;5/*;6-10/*;11-14/*;15/*;16-*/*';'+1-4/*;5/*;6-10/*';'+5/*;15/*')"
);
EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ());
// NOTE: the leading "+" indicates that the listed layers may go somewhere else, so we can't plainly map them
EXPECT_EQ (lm.mapping_str (0), "+0/*;1-4/*;5/*;6-10/*;11-14/*;15/*;16-*/*");
EXPECT_EQ (lm.mapping_str (1), "+1-4/*;5/*;6-10/*");
EXPECT_EQ (lm.mapping_str (2), "+5/*;15/*");
EXPECT_EQ (lm.mapping_str (3), "");
}

View File

@ -504,7 +504,7 @@ SearchReplaceResults::export_layout (db::Layout &layout)
std::map<unsigned int, db::LayerProperties>::const_iterator lm = m_lp_map.find (layer);
if (lm != m_lp_map.end ()) {
std::pair<bool, unsigned int> ll = insert_lm.logical (lm->second);
std::pair<bool, unsigned int> ll = insert_lm.first_logical (lm->second);
if (! ll.first) {
layer = layout.insert_layer (lm->second);
insert_lm.map (lm->second, layer, lm->second);

View File

@ -381,7 +381,7 @@ DXFReader::do_read (db::Layout &layout, db::cell_index_type top)
{
// create the zero layer - this is not mapped to GDS but can be specified in the layer mapping as
// a layer named "0".
std::pair<bool, unsigned int> ll = layer_map ().logical (zero_layer_name, layout);
std::pair<bool, unsigned int> ll = layer_map ().first_logical (zero_layer_name, layout);
if (ll.first) {
// create the layer if it is not part of the layout yet.

View File

@ -184,7 +184,7 @@ GDS2ReaderBase::finish_element (db::PropertiesRepository &rep)
std::pair <bool, unsigned int>
GDS2ReaderBase::open_dl (db::Layout &layout, const LDPair &dl, bool create)
{
std::pair<bool, unsigned int> ll = m_layer_map.logical (dl, layout);
std::pair<bool, unsigned int> ll = m_layer_map.first_logical (dl, layout);
if (ll.first) {
return ll;

View File

@ -332,7 +332,7 @@ TEST(2)
db::Layout layout_piece (&m);
layout_piece = layout;
std::pair<bool, unsigned int> jj = map_full.logical (pairs[i]);
std::pair<bool, unsigned int> jj = map_full.first_logical (pairs[i]);
EXPECT_EQ (jj.first, true);
for (unsigned int j = 0; j < layout_piece.layers(); ++j) {

View File

@ -1180,7 +1180,7 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n
}
// employ the layer map to find the target layer
std::pair<bool, unsigned int> ll = m_layer_map.logical (lp, layout);
std::pair<bool, unsigned int> ll = m_layer_map.first_logical (lp, layout);
if (ll.first) {
@ -1300,10 +1300,10 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n
// Route the layer through the layer map, first the decorated name and if there is no mapping, the
// undecorated one.
std::pair<bool, unsigned int> ll = m_layer_map.logical (name, layout);
std::pair<bool, unsigned int> ll = m_layer_map.first_logical (name, layout);
bool generic_match = false;
if (! ll.first) {
ll = m_layer_map.logical (n, layout);
ll = m_layer_map.first_logical (n, layout);
generic_match = true;
} else if (n == name) {
// no suffix defined in tech component -> treat as generic match and combine datatypes

View File

@ -557,7 +557,7 @@ OASISReader::warn (const std::string &msg)
std::pair <bool, unsigned int>
OASISReader::open_dl (db::Layout &layout, const LDPair &dl, bool create)
{
std::pair<bool, unsigned int> ll = m_layer_map.logical (dl, layout);
std::pair<bool, unsigned int> ll = m_layer_map.first_logical (dl, layout);
if (ll.first) {
return ll;