@@ -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,63 @@ 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+ return ;
1927+ } else 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+ return ;
1937+ } else {
1938+ dbu = _db->getDbuPerMicron ();
1939+ }
19181940 }
1941+ _dist_factor = dbu;
1942+ _dbu_per_micron = dbu;
1943+ _area_factor = _dbu_per_micron * _dbu_per_micron;
19191944}
19201945
19211946void lefinReader::useMinSpacing (LefParser::lefiUseMinSpacing* spacing)
@@ -2370,7 +2395,7 @@ dbTech* lefinReader::createTech(const char* name, const char* lef_file)
23702395 lefrSetRelaxMode ();
23712396 init ();
23722397
2373- _tech = dbTech::create (_db, name, _dbu_per_micron );
2398+ _tech = dbTech::create (_db, name);
23742399 _create_tech = true ;
23752400
23762401 if (!readLef (lef_file) || _errors != 0 ) {
@@ -2439,7 +2464,7 @@ dbLib* lefinReader::createTechAndLib(const char* tech_name,
24392464 return nullptr ;
24402465 };
24412466
2442- _tech = dbTech::create (_db, tech_name, _dbu_per_micron );
2467+ _tech = dbTech::create (_db, tech_name);
24432468 _lib_name = lib_name;
24442469 _create_lib = true ;
24452470 _create_tech = true ;
0 commit comments