@@ -1862,18 +1862,13 @@ void lefinReader::units(LefParser::lefiUnits* unit)
18621862 if (unit->hasDatabase ()) {
18631863 _lef_units = (int ) unit->databaseNumber ();
18641864
1865- if (_override_lef_dbu == false ) {
1866- if (_create_tech) {
1867- if (_lef_units
1868- < 1000 ) { // historically the database was always stored in nm
1869- setDBUPerMicron (1000 );
1870- } else {
1871- setDBUPerMicron (_lef_units);
1872- }
1873-
1874- _tech->setDbUnitsPerMicron (_dbu_per_micron);
1875- _tech->setLefUnits (_lef_units);
1865+ if (_create_tech && !_override_lef_dbu) {
1866+ // historically the database was always stored in nm
1867+ setDBUPerMicron (std::max (_lef_units, 1000 ));
1868+ if (_db->getDbuPerMicron () == 0 ) {
1869+ _db->setDbuPerMicron (_dbu_per_micron);
18761870 }
1871+ _tech->setLefUnits (_lef_units);
18771872 }
18781873
18791874 if (_lef_units > _dbu_per_micron) {
@@ -1889,33 +1884,61 @@ void lefinReader::units(LefParser::lefiUnits* unit)
18891884 }
18901885}
18911886
1892- void lefinReader::setDBUPerMicron (int dbu)
1887+ namespace {
1888+ bool isValidDBUPerMicron (int dbu)
18931889{
18941890 switch (dbu) {
1895- case 100 :
1896- case 200 :
1897- case 400 :
1898- case 800 :
18991891 case 1000 :
19001892 case 2000 :
19011893 case 4000 :
19021894 case 8000 :
19031895 case 10000 :
19041896 case 20000 :
1905- _dist_factor = dbu;
1906- _dbu_per_micron = dbu;
1907- _area_factor = _dbu_per_micron * _dbu_per_micron;
1908- break ;
1897+ return true ;
19091898 default :
1899+ return false ;
1900+ }
1901+ }
1902+ } // namespace
1903+
1904+ void lefinReader::setDBUPerMicron (int dbu)
1905+ {
1906+ if (!isValidDBUPerMicron (dbu)) {
1907+ ++_errors;
1908+ _logger->warn (utl::ODB,
1909+ 400 ,
1910+ " error: invalid dbu-per-micron value {}; valid units (1000, "
1911+ " 2000, 4000, 8000, 10000, 20000)" ,
1912+ dbu);
1913+
1914+ return ;
1915+ }
1916+ if (_db->getDbuPerMicron () != 0 ) {
1917+ if (dbu > _db->getDbuPerMicron ()) {
1918+ ++_errors;
1919+ _logger->warn (
1920+ utl::ODB,
1921+ 401 ,
1922+ " The LEF UNITS DATABASE MICRON convert factor ({}) is greater than "
1923+ " the database units per micron ({}) of the current database." ,
1924+ dbu,
1925+ _db->getDbuPerMicron ());
1926+ }
1927+ if (_db->getDbuPerMicron () % dbu != 0 ) {
19101928 ++_errors;
19111929 _logger->warn (utl::ODB,
1912- 206 ,
1913- " error: invalid dbu-per-micron value {}; valid units (100, "
1914- " 200, 400, 800"
1915- " 1000, 2000, 4000, 8000, 10000, 20000)" ,
1916- _lef_units);
1917- break ;
1930+ 402 ,
1931+ " The LEF UNITS DATABASE MICRON convert factor ({}) is "
1932+ " not a multiplier of the database units per micron ({}) of "
1933+ " the current database." ,
1934+ dbu,
1935+ _db->getDbuPerMicron ());
1936+ }
1937+ dbu = _db->getDbuPerMicron ();
19181938 }
1939+ _dist_factor = dbu;
1940+ _dbu_per_micron = dbu;
1941+ _area_factor = _dbu_per_micron * _dbu_per_micron;
19191942}
19201943
19211944void lefinReader::useMinSpacing (LefParser::lefiUseMinSpacing* spacing)
@@ -2370,15 +2393,17 @@ dbTech* lefinReader::createTech(const char* name, const char* lef_file)
23702393 lefrSetRelaxMode ();
23712394 init ();
23722395
2373- _tech = dbTech::create (_db, name, _dbu_per_micron );
2396+ _tech = dbTech::create (_db, name);
23742397 _create_tech = true ;
23752398
23762399 if (!readLef (lef_file) || _errors != 0 ) {
23772400 dbTech::destroy (_tech);
23782401 _logger->error (
23792402 utl::ODB, 288 , " LEF data from {} is discarded due to errors" , lef_file);
23802403 }
2381-
2404+ if (_db->getDbuPerMicron () == 0 ) {
2405+ _db->setDbuPerMicron (_dbu_per_micron);
2406+ }
23822407 _db->triggerPostReadLef (_tech, nullptr );
23832408
23842409 return _tech;
@@ -2414,7 +2439,9 @@ dbLib* lefinReader::createLib(dbTech* tech,
24142439 _logger->error (
24152440 utl::ODB, 292 , " LEF data from {} is discarded due to errors" , lef_file);
24162441 }
2417-
2442+ if (_db->getDbuPerMicron () == 0 ) {
2443+ _db->setDbuPerMicron (_dbu_per_micron);
2444+ }
24182445 _db->triggerPostReadLef (_tech, _lib);
24192446 return _lib;
24202447}
@@ -2439,7 +2466,7 @@ dbLib* lefinReader::createTechAndLib(const char* tech_name,
24392466 return nullptr ;
24402467 };
24412468
2442- _tech = dbTech::create (_db, tech_name, _dbu_per_micron );
2469+ _tech = dbTech::create (_db, tech_name);
24432470 _lib_name = lib_name;
24442471 _create_lib = true ;
24452472 _create_tech = true ;
@@ -2458,7 +2485,9 @@ dbLib* lefinReader::createTechAndLib(const char* tech_name,
24582485 if (rules.orderReversed ()) {
24592486 rules.reverse ();
24602487 }
2461-
2488+ if (_db->getDbuPerMicron () == 0 ) {
2489+ _db->setDbuPerMicron (_dbu_per_micron);
2490+ }
24622491 _db->triggerPostReadLef (_tech, _lib);
24632492
24642493 return _lib;
0 commit comments