mirror of https://github.com/KLayout/klayout.git
Bugfixing multi-DEF reader with LEF cache, adding a testcase. Making unknown vias an error.
This commit is contained in:
parent
a07d742bee
commit
e27e24ff4f
|
|
@ -1947,48 +1947,52 @@ LEFDEFReaderState::finish (db::Layout &layout)
|
|||
void
|
||||
LEFDEFReaderState::register_via_cell (const std::string &vn, const std::string &nondefaultrule, LEFDEFLayoutGenerator *generator)
|
||||
{
|
||||
if (m_via_generators.find (std::make_pair (vn, nondefaultrule)) != m_via_generators.end ()) {
|
||||
delete m_via_generators [std::make_pair (vn, nondefaultrule)];
|
||||
}
|
||||
m_via_generators [std::make_pair (vn, nondefaultrule)] = generator;
|
||||
// inserts at the end of the range
|
||||
m_via_generators.insert (std::make_pair (std::make_pair (vn, nondefaultrule), generator));
|
||||
}
|
||||
|
||||
LEFDEFLayoutGenerator *
|
||||
LEFDEFReaderState::via_generator (const std::string &vn, const std::string &nondefaultrule)
|
||||
{
|
||||
std::map<std::pair<std::string, std::string>, LEFDEFLayoutGenerator *>::const_iterator g = m_via_generators.find (std::make_pair (vn, nondefaultrule));
|
||||
if (g == m_via_generators.end () && ! nondefaultrule.empty ()) {
|
||||
// default rule is fallback
|
||||
g = m_via_generators.find (std::make_pair (vn, std::string ()));
|
||||
return via_generator_and_rule (vn, nondefaultrule).first;
|
||||
}
|
||||
|
||||
std::pair<LEFDEFLayoutGenerator *, std::string>
|
||||
LEFDEFReaderState::via_generator_and_rule (const std::string &vn, const std::string &nondefaultrule)
|
||||
{
|
||||
auto key = std::make_pair (vn, nondefaultrule);
|
||||
|
||||
auto g = m_via_generators.upper_bound (key);
|
||||
if (g != m_via_generators.begin ()) {
|
||||
--g;
|
||||
}
|
||||
if (g != m_via_generators.end ()) {
|
||||
return g->second;
|
||||
|
||||
if (g == m_via_generators.end () || g->first != key) {
|
||||
if (nondefaultrule.empty ()) {
|
||||
return std::pair<LEFDEFLayoutGenerator *, std::string> (0, std::string ());
|
||||
} else {
|
||||
return 0;
|
||||
// default rule is fallback
|
||||
return via_generator_and_rule (vn, std::string ());
|
||||
}
|
||||
} else {
|
||||
return std::make_pair (g->second, nondefaultrule);
|
||||
}
|
||||
}
|
||||
|
||||
db::Cell *
|
||||
LEFDEFReaderState::via_cell (const std::string &vn, const std::string &nondefaultrule, db::Layout &layout, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm)
|
||||
{
|
||||
ViaKey vk (vn, nondefaultrule, mask_bottom, mask_cut, mask_top);
|
||||
auto gr = via_generator_and_rule (vn, nondefaultrule);
|
||||
LEFDEFLayoutGenerator *vg = gr.first;
|
||||
|
||||
std::map<std::pair<std::string, std::string>, LEFDEFLayoutGenerator *>::const_iterator g = m_via_generators.find (std::make_pair (vn, nondefaultrule));
|
||||
|
||||
if (g == m_via_generators.end () && ! vk.nondefaultrule.empty ()) {
|
||||
// default rule is fallback
|
||||
g = m_via_generators.find (std::make_pair (vn, std::string ()));
|
||||
vk.nondefaultrule.clear ();
|
||||
}
|
||||
ViaKey vk (vn, gr.second, mask_bottom, mask_cut, mask_top);
|
||||
|
||||
std::map<ViaKey, db::Cell *>::const_iterator i = m_via_cells.find (vk);
|
||||
if (i == m_via_cells.end ()) {
|
||||
|
||||
db::Cell *cell = 0;
|
||||
|
||||
if (g != m_via_generators.end ()) {
|
||||
|
||||
LEFDEFLayoutGenerator *vg = g->second;
|
||||
if (vg) {
|
||||
|
||||
std::string n = vn;
|
||||
|
||||
|
|
@ -2017,6 +2021,14 @@ LEFDEFReaderState::via_cell (const std::string &vn, const std::string &nondefaul
|
|||
|
||||
vg->create_cell (*this, layout, *cell, 0, masks, nm);
|
||||
|
||||
} else {
|
||||
|
||||
std::string details;
|
||||
if (! nondefaultrule.empty () && nondefaultrule != vk.nondefaultrule) {
|
||||
details = tl::sprintf (tl::to_string (tr (" (trying with NONDEFAULTRULE '%s' and without)")), nondefaultrule);
|
||||
}
|
||||
error (tl::sprintf (tl::to_string (tr ("Could not find a via specification with name '%s'")) + details, vn));
|
||||
|
||||
}
|
||||
|
||||
m_via_cells[vk] = cell;
|
||||
|
|
|
|||
|
|
@ -1526,7 +1526,7 @@ private:
|
|||
std::map<std::string, int> m_default_number;
|
||||
const LEFDEFReaderOptions *mp_tech_comp;
|
||||
std::map<ViaKey, db::Cell *> m_via_cells;
|
||||
std::map<std::pair<std::string, std::string>, LEFDEFLayoutGenerator *> m_via_generators;
|
||||
std::multimap<std::pair<std::string, std::string>, LEFDEFLayoutGenerator *> m_via_generators;
|
||||
std::map<MacroKey, std::pair<db::Cell *, db::Trans> > m_macro_cells;
|
||||
std::map<std::string, LEFDEFLayoutGenerator *> m_macro_generators;
|
||||
std::map<std::string, db::cell_index_type> m_foreign_cells;
|
||||
|
|
@ -1538,6 +1538,7 @@ private:
|
|||
std::set<unsigned int> open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask);
|
||||
db::cell_index_type foreign_cell(Layout &layout, const std::string &name);
|
||||
void read_single_map_file (const std::string &path, std::map<std::pair<std::string, LayerDetailsKey>, std::vector<db::LayerProperties> > &layer_map);
|
||||
std::pair<LEFDEFLayoutGenerator *, std::string> via_generator_and_rule (const std::string &vn, const std::string &nondefaultrule);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "dbWriter.h"
|
||||
#include "dbDEFImporter.h"
|
||||
#include "dbLEFImporter.h"
|
||||
#include "dbCommonReader.h"
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
#include "dbTestSupport.h"
|
||||
|
|
@ -1102,3 +1103,35 @@ TEST(214_issue1877)
|
|||
db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS);
|
||||
}
|
||||
|
||||
// multi-DEF reader support (issue-2014)
|
||||
TEST(215_multiDEF)
|
||||
{
|
||||
std::string fn_path (tl::testdata ());
|
||||
fn_path += "/lefdef/multi_def/";
|
||||
|
||||
db::Layout ly;
|
||||
|
||||
db::LoadLayoutOptions opt;
|
||||
// anything else will not make much sense
|
||||
opt.get_options<db::CommonReaderOptions> ().cell_conflict_resolution = db::CellConflictResolution::RenameCell;
|
||||
|
||||
// Test "set_option_by_name"
|
||||
opt.set_option_by_name ("lefdef_config.lef_context_enabled", true);
|
||||
opt.set_option_by_name ("lefdef_config.map_file", "layers.map");
|
||||
opt.set_option_by_name ("lefdef_config.read_lef_with_def", true);
|
||||
|
||||
const char *files[] = {
|
||||
"main.def",
|
||||
"comp_a.def",
|
||||
"comp_b.def",
|
||||
"comp_c.def"
|
||||
};
|
||||
|
||||
for (const char **fn = files; fn != files + sizeof (files) / sizeof (files[0]); ++fn) {
|
||||
tl::InputStream is (fn_path + *fn);
|
||||
db::Reader reader (is);
|
||||
reader.read (ly, opt);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,20 @@
|
|||
VERSION 5.8 ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DESIGN comp_a ;
|
||||
UNITS DISTANCE MICRONS 1000 ;
|
||||
DIEAREA ( 0 0 ) ( 10000 2000 ) ;
|
||||
|
||||
VIAS 2 ;
|
||||
- via1 + VIARULE M1M2_PR + CUTSIZE 150 150 + LAYERS met1 via met2 + CUTSPACING 170 170 + ENCLOSURE 85 165 55 85 + ROWCOL 2 2 ;
|
||||
- via2 + VIARULE M2M3_PR + CUTSIZE 200 200 + LAYERS met2 via2 met3 + CUTSPACING 200 200 + ENCLOSURE 40 85 65 65 + ROWCOL 3 3 ;
|
||||
END VIAS
|
||||
SPECIALNETS 2 ;
|
||||
- VGND ( PIN VGND ) ( * VNB ) ( * VGND ) + USE GROUND
|
||||
+ ROUTED met1 480 + SHAPE FOLLOWPIN ( 0 1000 ) ( 2000 1000 )
|
||||
NEW met1 0 + SHAPE STRIPE ( 2000 1000 ) via1
|
||||
+ ROUTED met2 480 + SHAPE FOLLOWPIN ( 2000 1000 ) ( 4000 1000 )
|
||||
NEW met2 0 + SHAPE STRIPE ( 4000 1000 ) via2 ;
|
||||
END SPECIALNETS
|
||||
END DESIGN
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
VERSION 5.7 ;
|
||||
NOWIREEXTENSIONATPIN ON ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
MACRO comp_a
|
||||
CLASS BLOCK ;
|
||||
FOREIGN comp_a ;
|
||||
ORIGIN 0.000 0.000 ;
|
||||
SIZE 10000.000 BY 2000.000 ;
|
||||
END comp_a
|
||||
END LIBRARY
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
VERSION 5.8 ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DESIGN comp_b ;
|
||||
UNITS DISTANCE MICRONS 1000 ;
|
||||
DIEAREA ( 0 0 ) ( 10000 2000 ) ;
|
||||
|
||||
VIAS 2 ;
|
||||
- via1 + VIARULE M1M2_PR + CUTSIZE 150 150 + LAYERS met1 via met2 + CUTSPACING 170 170 + ENCLOSURE 85 165 55 85 + ROWCOL 2 1 ;
|
||||
- via2 + VIARULE M2M3_PR + CUTSIZE 200 200 + LAYERS met2 via2 met3 + CUTSPACING 200 200 + ENCLOSURE 40 85 65 65 + ROWCOL 3 2 ;
|
||||
END VIAS
|
||||
SPECIALNETS 2 ;
|
||||
- VGND ( PIN VGND ) ( * VNB ) ( * VGND ) + USE GROUND
|
||||
+ ROUTED met1 480 + SHAPE FOLLOWPIN ( 0 1000 ) ( 2000 1000 )
|
||||
NEW met1 0 + SHAPE STRIPE ( 2000 1000 ) via1
|
||||
+ ROUTED met2 480 + SHAPE FOLLOWPIN ( 2000 1000 ) ( 4000 1000 )
|
||||
NEW met2 0 + SHAPE STRIPE ( 4000 1000 ) via2 ;
|
||||
END SPECIALNETS
|
||||
END DESIGN
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
VERSION 5.7 ;
|
||||
NOWIREEXTENSIONATPIN ON ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
MACRO comp_b
|
||||
CLASS BLOCK ;
|
||||
FOREIGN comp_b ;
|
||||
ORIGIN 0.000 0.000 ;
|
||||
SIZE 10000.000 BY 2000.000 ;
|
||||
END comp_b
|
||||
END LIBRARY
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
VERSION 5.8 ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DESIGN comp_c ;
|
||||
UNITS DISTANCE MICRONS 1000 ;
|
||||
DIEAREA ( 0 0 ) ( 10000 2000 ) ;
|
||||
|
||||
SPECIALNETS 2 ;
|
||||
- VGND ( PIN VGND ) ( * VNB ) ( * VGND ) + USE GROUND
|
||||
+ ROUTED met1 480 + SHAPE FOLLOWPIN ( 0 1000 ) ( 2000 1000 )
|
||||
NEW met1 0 + SHAPE STRIPE ( 2000 1000 ) via1
|
||||
+ ROUTED met2 480 + SHAPE FOLLOWPIN ( 2000 1000 ) ( 4000 1000 )
|
||||
NEW met2 0 + SHAPE STRIPE ( 4000 1000 ) via2 ;
|
||||
END SPECIALNETS
|
||||
END DESIGN
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
VERSION 5.7 ;
|
||||
NOWIREEXTENSIONATPIN ON ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
MACRO comp_c
|
||||
CLASS BLOCK ;
|
||||
FOREIGN comp_c ;
|
||||
ORIGIN 0.000 0.000 ;
|
||||
SIZE 10000.000 BY 2000.000 ;
|
||||
END comp_c
|
||||
END LIBRARY
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
met1 VIA,LEFPIN,PIN,SPNET,NET 1 0
|
||||
via VIA,LEFPIN,PIN,SPNET,NET 2 0
|
||||
met2 VIA,LEFPIN,PIN,SPNET,NET 3 0
|
||||
via2 VIA,LEFPIN,PIN,SPNET,NET 4 0
|
||||
met3 VIA,LEFPIN,PIN,SPNET,NET 5 0
|
||||
|
||||
DIEAREA ALL 100 0
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
VERSION 5.8 ;
|
||||
DIVIDERCHAR "/" ;
|
||||
BUSBITCHARS "[]" ;
|
||||
DESIGN caravel ;
|
||||
UNITS DISTANCE MICRONS 1000 ;
|
||||
DIEAREA ( 0 0 ) ( 10000 10000 ) ;
|
||||
COMPONENTS 4 ;
|
||||
- comp_a comp_a + PLACED ( 0 0 ) N ;
|
||||
- comp_b comp_b + PLACED ( 0 2000 ) N ;
|
||||
- comp_c comp_c + PLACED ( 0 4000 ) N ;
|
||||
#- comp_d comp_d + PLACED ( 0 4000 ) N ;
|
||||
END COMPONENTS
|
||||
END DESIGN
|
||||
Binary file not shown.
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
VERSION 5.7 ;
|
||||
|
||||
BUSBITCHARS "[]" ;
|
||||
DIVIDERCHAR "/" ;
|
||||
USEMINSPACING OBS OFF ;
|
||||
|
||||
UNITS
|
||||
DATABASE MICRONS 1000 ;
|
||||
END UNITS
|
||||
|
||||
MANUFACTURINGGRID 0.005 ;
|
||||
|
||||
LAYER met1
|
||||
TYPE ROUTING ;
|
||||
DIRECTION HORIZONTAL ;
|
||||
PITCH 0.34 ;
|
||||
OFFSET 0.17 ;
|
||||
WIDTH 0.14 ;
|
||||
END met1
|
||||
|
||||
LAYER via
|
||||
TYPE CUT ;
|
||||
WIDTH 0.15 ;
|
||||
SPACING 0.17 ;
|
||||
END via
|
||||
|
||||
LAYER met2
|
||||
TYPE ROUTING ;
|
||||
DIRECTION VERTICAL ;
|
||||
PITCH 0.46 ;
|
||||
OFFSET 0.23 ;
|
||||
WIDTH 0.14 ;
|
||||
END met2
|
||||
|
||||
LAYER via2
|
||||
TYPE CUT ;
|
||||
WIDTH 0.2 ;
|
||||
SPACING 0.2 ;
|
||||
END via2
|
||||
|
||||
LAYER met3
|
||||
TYPE ROUTING ;
|
||||
DIRECTION HORIZONTAL ;
|
||||
PITCH 0.68 ;
|
||||
OFFSET 0.34 ;
|
||||
WIDTH 0.3 ;
|
||||
END met3
|
||||
|
||||
VIA via1 DEFAULT
|
||||
LAYER via ;
|
||||
RECT -0.075 -0.075 0.075 0.075 ;
|
||||
LAYER met1 ;
|
||||
RECT -0.16 -0.24 0.16 0.24 ;
|
||||
LAYER met2 ;
|
||||
RECT -0.13 -0.24 0.13 0.24 ;
|
||||
END via1
|
||||
|
||||
VIARULE M1M2_PR GENERATE
|
||||
LAYER met1 ;
|
||||
ENCLOSURE 0.085 0.055 ;
|
||||
LAYER met2 ;
|
||||
ENCLOSURE 0.055 0.085 ;
|
||||
LAYER via ;
|
||||
RECT -0.075 -0.075 0.075 0.075 ;
|
||||
SPACING 0.32 BY 0.32 ;
|
||||
END M1M2_PR
|
||||
|
||||
VIA via2 DEFAULT
|
||||
LAYER via2 ;
|
||||
RECT -0.1 -0.1 0.1 0.1 ;
|
||||
LAYER met2 ;
|
||||
RECT -0.14 -0.24 0.14 0.24 ;
|
||||
LAYER met3 ;
|
||||
RECT -0.165 -0.165 0.165 0.165 ;
|
||||
END via2
|
||||
|
||||
VIARULE M2M3_PR GENERATE
|
||||
LAYER met2 ;
|
||||
ENCLOSURE 0.04 0.085 ;
|
||||
LAYER met3 ;
|
||||
ENCLOSURE 0.065 0.065 ;
|
||||
LAYER via2 ;
|
||||
RECT -0.1 -0.1 0.1 0.1 ;
|
||||
SPACING 0.4 BY 0.4 ;
|
||||
END M2M3_PR
|
||||
|
||||
END LIBRARY
|
||||
|
||||
Loading…
Reference in New Issue