Bugfixing multi-DEF reader with LEF cache, adding a testcase. Making unknown vias an error.

This commit is contained in:
Matthias Koefferlein 2025-05-18 22:00:39 +02:00
parent a07d742bee
commit e27e24ff4f
14 changed files with 270 additions and 23 deletions

View File

@ -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;
}
if (g != m_via_generators.end ()) {
return g->second;
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 () || 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;

View File

@ -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);
};
/**

View File

@ -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);
}

BIN
testdata/lefdef/multi_def/au.oas vendored Normal file

Binary file not shown.

20
testdata/lefdef/multi_def/comp_a.def vendored Normal file
View File

@ -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

12
testdata/lefdef/multi_def/comp_a.lef vendored Normal file
View File

@ -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

20
testdata/lefdef/multi_def/comp_b.def vendored Normal file
View File

@ -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

12
testdata/lefdef/multi_def/comp_b.lef vendored Normal file
View File

@ -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

16
testdata/lefdef/multi_def/comp_c.def vendored Normal file
View File

@ -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

12
testdata/lefdef/multi_def/comp_c.lef vendored Normal file
View File

@ -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

7
testdata/lefdef/multi_def/layers.map vendored Normal file
View File

@ -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

13
testdata/lefdef/multi_def/main.def vendored Normal file
View File

@ -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

BIN
testdata/lefdef/multi_def/out.oas vendored Normal file

Binary file not shown.

89
testdata/lefdef/multi_def/tech.lef vendored Normal file
View File

@ -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