Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue #1877 (rounding introduces DRC error in LEF/DEF via) #1889

Merged
merged 2 commits into from
Oct 19, 2024
Merged
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
29 changes: 17 additions & 12 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,13 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d

// NOTE: missing cuts due to pattern holes don't change mask assignment

db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)) / 2, (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1)) / 2);
db::Box via_box (m_offset - vs, m_offset + vs);
// special rounding to ensure the dimensions are correct for non-even width or height (issue #1877)
db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)), (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1)));
if (vs.x () % 2 != 0 || vs.y () % 2 != 0) {
reader.warn (tl::sprintf (tl::to_string (tr ("Via has odd width or height (x,y dimension of cut array is %s database units) - this may lead to inaccurate positioning of the via")), vs.to_string ()));
}
db::Point via_ll = m_offset - db::Vector (vs.x () / 2, vs.y () / 2);
db::Box via_box (via_ll, via_ll + vs);

std::set <unsigned int> dl;

Expand Down Expand Up @@ -975,15 +980,15 @@ LEFDEFReaderState::~LEFDEFReaderState ()
}

void
LEFDEFReaderState::common_reader_error (const std::string &msg)
LEFDEFReaderState::error (const std::string &msg)
{
if (mp_importer) {
mp_importer->error (msg);
}
}

void
LEFDEFReaderState::common_reader_warn (const std::string &msg, int warn_level)
LEFDEFReaderState::warn (const std::string &msg, int warn_level)
{
if (mp_importer) {
mp_importer->warn (msg, warn_level);
Expand Down Expand Up @@ -1117,7 +1122,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
size_t max_purpose_str = 15;

if (! ex.try_read_word (w1) || ! ex.try_read_word (w2, "._$,/:") || ! try_read_layers (ex, layers) || ! try_read_layers (ex, datatypes)) {
common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d not understood - skipped")), path, ts.line_number ()));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d not understood - skipped")), path, ts.line_number ()));
continue;
}

Expand All @@ -1143,7 +1148,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
name = "REGIONS_NONE";
lp = RegionsNone;
} else if (w2 != "ALL") {
common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d - ignoring unknowns REGION purpose %s (use FENCE, GUIDE or ALL)")), path, ts.line_number (), w2));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d - ignoring unknowns REGION purpose %s (use FENCE, GUIDE or ALL)")), path, ts.line_number (), w2));
}

for (std::vector<int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
Expand Down Expand Up @@ -1176,7 +1181,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::

if (*p == "DIEAREA" || *p == "ALL" || *p == "COMP") {

common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NAME record ignored for entity: %s")), path, ts.line_number (), *p));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NAME record ignored for entity: %s")), path, ts.line_number (), *p));

} else {

Expand All @@ -1193,7 +1198,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
if (label_purpose == Pins || label_purpose == LEFPins) {
layer_defs.push_back (std::make_pair (lp.front (), label_purpose == Pins ? Label : LEFLabel));
} else {
common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NAME record ignored for purpose: %s")), path, ts.line_number (), purpose_to_name (label_purpose)));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NAME record ignored for purpose: %s")), path, ts.line_number (), purpose_to_name (label_purpose)));
}

} else {
Expand Down Expand Up @@ -1226,7 +1231,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
} else if (w1 == "COMP") {

// ignore "COMP (ALL) ..."
common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: COMP entry ignored")), path, ts.line_number ()));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: COMP entry ignored")), path, ts.line_number ()));

} else {

Expand Down Expand Up @@ -1261,7 +1266,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
if (ex.test (":VOLTAGE:")) {
double f = 0.0;
ex.read (f);
common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NET voltage constraint ignored for layer %s")), path, ts.line_number (), w1));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: NET voltage constraint ignored for layer %s")), path, ts.line_number (), w1));
}

} else if (i->second == ViaGeometry) {
Expand All @@ -1284,7 +1289,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::

if (i == purpose_translation.end ()) {

common_reader_warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: purpose %s ignored for layer %s")), path, ts.line_number (), ps, w1));
warn (tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: purpose %s ignored for layer %s")), path, ts.line_number (), ps, w1));

} else if (i->second == All) {

Expand Down Expand Up @@ -1379,7 +1384,7 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu
msg += tl::to_string (tr (" Via size ")) + via_size.to_string ();
}
#endif
common_reader_warn (msg + tl::to_string (tr (" - layer is ignored")));
warn (msg + tl::to_string (tr (" - layer is ignored")));
}

return ll;
Expand Down
14 changes: 12 additions & 2 deletions src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1354,9 +1354,19 @@ class DB_PLUGIN_PUBLIC LEFDEFReaderState
return m_foreign_cells;
}

/**
* @brief Issues an error
*/
void error (const std::string &msg);

/**
* @brief Issues a warning
*/
void warn (const std::string &msg, int warn_level = 1);

protected:
virtual void common_reader_error (const std::string &msg);
virtual void common_reader_warn (const std::string &msg, int warn_level = 1);
virtual void common_reader_error (const std::string &msg) { error (msg); }
virtual void common_reader_warn (const std::string &msg, int warn_level) { warn (msg, warn_level); }

private:
/**
Expand Down
23 changes: 23 additions & 0 deletions src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1077,3 +1077,26 @@ TEST(213_no_duplicate_LEF)
db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS);
}

// issue-1877 (VIA placement rounding)
TEST(214_issue1877)
{
db::Layout ly;

std::string fn_path (tl::testdata ());
fn_path += "/lefdef/issue-1877/";

db::LEFDEFReaderOptions lefdef_opt = default_options ();
lefdef_opt.set_map_file ("tech.map");
lefdef_opt.set_read_lef_with_def (true);
db::LoadLayoutOptions opt;
opt.set_options (lefdef_opt);

{
tl::InputStream is (fn_path + "test.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-1877/au.oas
Binary file not shown.
27 changes: 27 additions & 0 deletions testdata/lefdef/issue-1877/tech.lef
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
VERSION 5.6 ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;

UNITS
DATABASE MICRONS 1000 ;
END UNITS
MANUFACTURINGGRID 0.001 ;

LAYER METAL_1
TYPE ROUTING ;
DIRECTION HORIZONTAL ;
WIDTH 0.6 ;
END METAL_1

LAYER VIA_1
TYPE CUT ;
END VIA_1

LAYER METAL_2
TYPE ROUTING ;
DIRECTION VERTICAL ;
WIDTH 0.6 ;
END METAL_2

END LIBRARY

4 changes: 4 additions & 0 deletions testdata/lefdef/issue-1877/tech.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
DIEAREA ALL 1 0
METAL_1 ALL 2 0
VIA_1 ALL 3 0
METAL_2 ALL 4 0
21 changes: 21 additions & 0 deletions testdata/lefdef/issue-1877/test.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
VERSION 5.8 ;
DIVIDERCHAR "/" ;
BUSBITCHARS "[]" ;
DESIGN dummy_design ;
UNITS DISTANCE MICRONS 1000 ;

DIEAREA ( 21500 7000 ) ( 26000 9000 ) ;

VIAS 1 ;
- via1_2_XXXX_XXX_X_X_XXX_XXX + VIARULE MYVIA1_ARRAY + CUTSIZE 246 246 + LAYERS METAL_1 VIA_1 METAL_2 + CUTSPACING 231 231 + ENCLOSURE 62 137 8 61 + ROWCOL 1 8 ;
END VIAS


SPECIALNETS 1 ;
- VDD
# ( PIN VDD ) ( * vdd )
+ USE POWER
+ ROUTED METAL_1 0 + SHAPE STRIPE ( 23620 7840 ) via1_2_XXXX_XXX_X_X_XXX_XXX ;
END SPECIALNETS

END DESIGN
Loading