Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/buddies/src/bd/bdReaderOptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ GenericReaderOptions::GenericReaderOptions ()
m_lefdef_produce_special_routing = load_options.get_option_by_name ("lefdef_config.produce_special_routing").to_bool ();
m_lefdef_special_routing_suffix = load_options.get_option_by_name ("lefdef_config.special_routing_suffix_str").to_string ();
m_lefdef_special_routing_datatype = load_options.get_option_by_name ("lefdef_config.special_routing_datatype_str").to_string ();
m_lefdef_skip_duplicate_macros = load_options.get_option_by_name ("lefdef_config.skip_duplicate_macros").to_bool ();

tl::Variant lef_files = load_options.get_option_by_name ("lefdef_config.lef_files");
for (tl::Variant::const_iterator i = lef_files.begin (); i != lef_files.end (); ++i) {
Expand Down Expand Up @@ -653,9 +654,9 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"\n"
"The following values are accepted for this option:\n"
"\n"
"* 0: produce LEF geometry unless a FOREIGN cell is specified (the default)\n"
"* 0: produce LEF geometry unless a FOREIGN cell is specified\n"
"* 1: produce LEF geometry always and ignore FOREIGN\n"
"* 2: Never produce LEF geometry and assume FOREIGN always\n"
"* 2: Never produce LEF geometry and assume FOREIGN always (the default)\n"
"\n"
"In case of FOREIGN macros in mode 0 or always in mode 2, the '--" + m_long_prefix + "lefdef-lef-layouts' option is available to specify "
"external layout files for providing the LEF macro layouts.\n"
Expand Down Expand Up @@ -686,6 +687,15 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"See also '--" + m_long_prefix + "lefdef-read-lef-with-def' for an option to implicitly read all LEF files in the same "
"place than the DEF file.\n"
)
<< tl::arg (group +
"#--" + m_long_prefix + "lefdef-skip-duplicate-macros", &m_lefdef_skip_duplicate_macros, "Skip duplicate LEF macros",
"This option applies when reading DEF files.\n"
"\n"
"If this option is present, having the same macro in different LEF files is a warning rather than being an error. "
"In that case, the first occurance is used. Use this option with care, as it may render invalid layouts when "
"the versions of the macro are defined differently. It is intended for cases, when macros with the same name are guaranteed "
"to be identical. KLayout does not check, if that is actually the case."
)
;

}
Expand Down Expand Up @@ -814,6 +824,7 @@ GenericReaderOptions::configure (db::LoadLayoutOptions &load_options)
load_options.set_option_by_name ("lefdef_config.macro_resolution_mode", m_lefdef_macro_resolution_mode);
load_options.set_option_by_name ("lefdef_config.macro_resolution_mode", m_lefdef_macro_resolution_mode);
load_options.set_option_by_name ("lefdef_config.paths_relative_to_cwd", true);
load_options.set_option_by_name ("lefdef_config.skip_duplicate_macros", m_lefdef_skip_duplicate_macros);

tl::Variant lef_layout_files = tl::Variant::empty_list ();
for (std::vector<std::string>::const_iterator l = m_lefdef_lef_layout_files.begin (); l != m_lefdef_lef_layout_files.end (); ++l) {
Expand Down
1 change: 1 addition & 0 deletions src/buddies/src/bd/bdReaderOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ class BD_PUBLIC GenericReaderOptions
std::vector<std::string> m_lefdef_map_files;
int m_lefdef_macro_resolution_mode;
std::vector<std::string> m_lefdef_lef_layout_files;
bool m_lefdef_skip_duplicate_macros;
};

/**
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ LEFDEFReaderOptions::LEFDEFReaderOptions ()
m_special_routing_datatype (0),
m_separate_groups (false),
m_joined_paths (false),
m_skip_duplicate_macros (false),
m_macro_resolution_mode (0),
m_read_lef_with_def (true),
m_paths_relative_to_cwd (false),
Expand Down Expand Up @@ -682,6 +683,7 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions &
m_macro_layout_files = d.m_macro_layout_files;
m_read_lef_with_def = d.m_read_lef_with_def;
m_paths_relative_to_cwd = d.m_paths_relative_to_cwd;
m_skip_duplicate_macros = d.m_skip_duplicate_macros;
set_macro_layouts (d.macro_layouts ());
}
return *this;
Expand Down Expand Up @@ -1070,6 +1072,9 @@ LEFDEFReaderState::ensure_lef_importer (int warn_level)
{
if (! mp_lef_importer.get ()) {
mp_lef_importer.reset (new db::LEFImporter (warn_level));
if (mp_tech_comp) {
mp_lef_importer->set_skip_duplicate_macros (mp_tech_comp->skip_duplicate_macros ());
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,16 @@ class DB_PLUGIN_PUBLIC LEFDEFReaderOptions
m_map_files = f;
}

bool skip_duplicate_macros () const
{
return m_skip_duplicate_macros;
}

void set_skip_duplicate_macros (bool v)
{
m_skip_duplicate_macros = v;
}

std::string single_map_file () const
{
return m_map_files.empty () ? std::string () : m_map_files.front ();
Expand Down Expand Up @@ -1055,6 +1065,7 @@ class DB_PLUGIN_PUBLIC LEFDEFReaderOptions
bool m_separate_groups;
bool m_joined_paths;
std::vector<std::string> m_map_files;
bool m_skip_duplicate_macros;
unsigned int m_macro_resolution_mode;
bool m_read_lef_with_def;
std::vector<std::string> m_lef_files;
Expand Down
32 changes: 21 additions & 11 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ namespace db
// LEFImporter implementation

LEFImporter::LEFImporter (int warn_level)
: LEFDEFImporter (warn_level)
: LEFDEFImporter (warn_level),
m_skip_duplicate_macros (false)
{
// .. nothing yet ..
}
Expand Down Expand Up @@ -884,16 +885,21 @@ void
LEFImporter::read_macro (Layout &layout)
{
std::string mn = get ();
set_cellname (mn);

GeometryBasedLayoutGenerator *mg = 0;

if (m_macros.find (mn) != m_macros.end ()) {
error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn);
if (m_skip_duplicate_macros) {
warn (tl::to_string (tr ("Skipping duplicate MACRO: : ")) + mn + tl::to_string (tr (" (skip option is enabled by user)")));
} else {
error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn);
}
} else {
mg = new GeometryBasedLayoutGenerator ();
reader_state ()->register_macro_cell (mn, mg);
}

set_cellname (mn);

GeometryBasedLayoutGenerator *mg = new GeometryBasedLayoutGenerator ();
reader_state ()->register_macro_cell (mn, mg);

db::Trans foreign_trans;
std::string foreign_name;

Expand Down Expand Up @@ -965,7 +971,7 @@ LEFImporter::read_macro (Layout &layout)
read_geometries (mg, layout.dbu (), LEFPins, &boxes_for_labels, prop_id);

for (std::map <std::string, db::Box>::const_iterator b = boxes_for_labels.begin (); b != boxes_for_labels.end (); ++b) {
if (! b->second.empty ()) {
if (mg && ! b->second.empty ()) {
mg->add_text (b->first, LEFLabel, db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ())), 0, 0);
}
}
Expand Down Expand Up @@ -1052,7 +1058,9 @@ LEFImporter::read_macro (Layout &layout)

} else if (test ("FIXEDMASK")) {

mg->set_fixedmask (true);
if (mg) {
mg->set_fixedmask (true);
}
expect (";");

} else {
Expand All @@ -1075,8 +1083,10 @@ LEFImporter::read_macro (Layout &layout)

}

mg->add_box (std::string (), Outline, db::Box (-origin, -origin + size), 0, 0);
mg->subtract_overlap_from_outline (m_overlap_layers);
if (mg) {
mg->add_box (std::string (), Outline, db::Box (-origin, -origin + size), 0, 0);
mg->subtract_overlap_from_outline (m_overlap_layers);
}

MacroDesc macro_desc;
macro_desc.foreign_name = foreign_name;
Expand Down
26 changes: 26 additions & 0 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,31 @@ class DB_PLUGIN_PUBLIC LEFImporter
*/
void finish_lef (db::Layout &layout);

/**
* @brief Sets a flag indicating whether to skip duplicate macros
*
* With this flag set to true, macros are ignored when there already
* is a macro with the same name. Use this option with caution, as
* skipping is only permitted if both macros are identical. The
* LEF reader does not check this condition.
*
* The default is "false" (raise an error on duplicate macros).
*/
void set_skip_duplicate_macros (bool f)
{
m_skip_duplicate_macros = f;
}

/**
* @brief Gets a flag indicating whether to skip duplicate macros
*
* See set_skip_duplicate_macros for an explanation of this flag.
*/
bool skip_duplicate_macros () const
{
return m_skip_duplicate_macros;
}

protected:
void do_read (db::Layout &layout);

Expand All @@ -159,6 +184,7 @@ class DB_PLUGIN_PUBLIC LEFImporter
std::map<std::string, ViaDesc> m_vias;
std::set<std::string> m_routing_layers, m_cut_layers, m_overlap_layers;
std::map<std::string, unsigned int> m_num_masks;
bool m_skip_duplicate_macros;

std::vector <db::Trans> get_iteration (double dbu);
void read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, LayerPurpose purpose, std::map<std::string, db::Box> *collect_bboxes = 0, properties_id_type prop_id = 0);
Expand Down
18 changes: 18 additions & 0 deletions src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,24 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
"\n"
"This property has been added in version 0.27. The ability to supply multiple files has been added in version 0.30.6.\n"
) +
gsi::method ("skip_duplicate_macros", &db::LEFDEFReaderOptions::skip_duplicate_macros,
"@brief Gets a value indicating wether to skip duplicate LEF Macro definitions.\n"
"If this property is 'true', having the same macro in different LEF files is a warning rather than being an error. "
"In that case, the first occurance is used. Use this option with care, as it may render invalid layouts when "
"the versions of the macro are defined differently. It is intended for cases, when macros with the same name are guaranteed "
"to be identical. KLayout does not check, if that is actually the case."
"\n"
"The default is 'false' (duplicate macro names are an error).\n"
"\n"
"This property has been added in version 0.30.x.\n"
) +
gsi::method ("skip_duplicate_macros=", &db::LEFDEFReaderOptions::set_skip_duplicate_macros, gsi::arg ("skip_duplicate_macros"),
"@brief Sets a value indicating wether to skip duplicate LEF Macro definitions.\n"
"\n"
"See \\skip_duplicate_macros for a description of this property.\n"
"\n"
"This property has been added in version 0.30.11.\n"
) +
gsi::method ("macro_resolution_mode", &db::LEFDEFReaderOptions::macro_resolution_mode,
"@brief Gets the macro resolution mode (LEF macros into DEF).\n"
"This property describes the way LEF macros are turned into layout cells when reading DEF. There "
Expand Down
51 changes: 51 additions & 0 deletions src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1199,3 +1199,54 @@ TEST(216_line_extensions)
run_test (_this, "issue-2075", "map:test.map+lef:test.lef+def:test.def", "au.oas", default_options (), false);
}

// issue-2374 (skip duplicate LEF macro option)
TEST(217_skip_duplicate_macro)
{
std::string fn_path (tl::testdata ());
fn_path += "/lefdef/issue-2374/";

db::LEFDEFReaderOptions lefdef_opt = default_options ();
lefdef_opt.set_single_map_file ("tech.map");
std::vector<std::string> lf;
lf.push_back ("tech.lef");
lf.push_back ("lib1.lef"); // macros a,b
lf.push_back ("lib2.lef"); // macros b,c
lefdef_opt.set_lef_files (lf);
lefdef_opt.set_read_lef_with_def (false);

db::Layout ly;

try {

db::LoadLayoutOptions opt;
opt.set_options (lefdef_opt);
EXPECT_EQ (lefdef_opt.skip_duplicate_macros (), false);

tl::InputStream is (fn_path + "top.def");
db::Reader reader (is);
reader.read (ly, opt);

// must throw an exception because of duplicate macros
EXPECT_EQ (1, 0);

} catch (...) { }

ly = db::Layout ();

{

db::LEFDEFReaderOptions lo = lefdef_opt;
lo.set_skip_duplicate_macros (true);
EXPECT_EQ (lo.skip_duplicate_macros (), true);
db::LoadLayoutOptions opt;
opt.set_options (lo);

tl::InputStream is (fn_path + "top.def");
db::Reader reader (is);
reader.read (ly, opt);

}

db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS);
}

Binary file added testdata/lefdef/issue-2374/au.oas
Binary file not shown.
20 changes: 20 additions & 0 deletions testdata/lefdef/issue-2374/lib1.lef
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
VERSION 5.8 ;

MACRO a
ORIGIN 0 0 ;
SIZE 600 BY 600 ;
OBS
LAYER M1 ;
RECT 10 10 590 590 ;
END
END a

MACRO b
ORIGIN -600 0 ;
SIZE 400 BY 500 ;
OBS
LAYER M1 ;
RECT 610 10 990 490 ;
END
END b

22 changes: 22 additions & 0 deletions testdata/lefdef/issue-2374/lib2.lef
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
VERSION 5.8 ;

MACRO b
ORIGIN -600 0 ;
SIZE 400 BY 500 ;
OBS
LAYER M1 ;
RECT 610 10 990 590 ;
END
END b

MACRO c
ORIGIN -500 -500 ;
SIZE 500 BY 500 ;
OBS
LAYER M1 ;
POLYGON 510 610 610 610 610 510 990 510 990 990 510 990 ;
LAYER overlap ;
RECT 500 700 1000 1000 ;
POLYGON 500 600 600 600 600 500 1000 500 1000 700 500 700 ;
END
END c
12 changes: 12 additions & 0 deletions testdata/lefdef/issue-2374/tech.lef
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
VERSION 5.8 ;

LAYER M1
TYPE ROUTING ;
DIRECTION HORIZONTAL ;
WIDTH 0.1 ;
PITCH 0.1 ;
END M1

LAYER overlap
TYPE OVERLAP ;
END overlap
6 changes: 6 additions & 0 deletions testdata/lefdef/issue-2374/tech.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DIEAREA ALL 1 0
#BOUNDARY DIEAREA 1 0
BOUNDARY MACRO 1 0
#M1 LEFOBS 2 0
M1 LEFOBS 3 0
M1 BLOCKAGE 3 0
10 changes: 10 additions & 0 deletions testdata/lefdef/issue-2374/top.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
VERSION 5.8 ;
DESIGN top ;
UNITS DISTANCE MICRONS 1000 ;
DIEAREA ( 0 0 ) ( 1000000 1000000 ) ;
COMPONENTS 3 ;
- a a + PLACED ( 0 0 ) N ;
- b b + PLACED ( 600000 0 ) N ;
- c c + PLACED ( 500000 500000 ) N ;
END COMPONENTS
END DESIGN
4 changes: 4 additions & 0 deletions testdata/ruby/dbReaders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ def test_lefdef_options
conf.read_lef_with_def = false
assert_equal(conf.read_lef_with_def, false)

assert_equal(conf.skip_duplicate_macros, false)
conf.skip_duplicate_macros = true
assert_equal(conf.skip_duplicate_macros, true)

end

# MAG Options
Expand Down
Loading