diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index 5c10e56a4f6..4222e784536 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -454,6 +455,22 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet) // Read DEF file if (!chiplet.external.def_file.empty()) { + std::error_code ec; + const bool def_exists + = std::filesystem::exists(chiplet.external.def_file, ec); + if (ec) { + logger_->error(utl::ODB, + 558, + "Cannot access DEF file {}: {}", + chiplet.external.def_file, + ec.message()); + } + if (!def_exists) { + logger_->error(utl::ODB, + 557, + "DEF file does not exist: {}", + chiplet.external.def_file); + } odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); std::vector search_libs; for (odb::dbLib* lib : db_->getLibs()) { diff --git a/src/odb/src/db/dbBlock.cpp b/src/odb/src/db/dbBlock.cpp index fbeea28a3ad..48d5fe2e7f1 100644 --- a/src/odb/src/db/dbBlock.cpp +++ b/src/odb/src/db/dbBlock.cpp @@ -2996,7 +2996,7 @@ dbBlock* dbBlock::create(dbChip* chip_, const char* name_, char hier_delimiter_) _dbBlock* top = chip->block_tbl_->create(); top->initialize(chip, nullptr, name_, hier_delimiter_); chip->top_ = top->getOID(); - top->dbu_per_micron_ = chip_->getTech()->getDbUnitsPerMicron(); + top->dbu_per_micron_ = static_cast(chip_->getDb()->getDbuPerMicron()); return (dbBlock*) top; } diff --git a/src/odb/test/BUILD b/src/odb/test/BUILD index c0707cce2a9..63986ff3d88 100644 --- a/src/odb/test/BUILD +++ b/src/odb/test/BUILD @@ -217,6 +217,7 @@ COMPULSORY_TESTS = [ PASSFAIL_TESTS = [ # pass-fail + "read_3dbx-fail", "test_block", "test_bterm", "test_destroy", @@ -280,6 +281,8 @@ filegroup( "data/example2.bmap", "data/example3.bmap", "data/example4.bmap", + "data/fail.3dbx", + "data/fail_def.3dbv", "data/floorplan_initialize.def", "data/floorplan_initialize.v", "data/floorplan_initialize2.def", diff --git a/src/odb/test/CMakeLists.txt b/src/odb/test/CMakeLists.txt index dd1ceda26d6..95a12da29f1 100644 --- a/src/odb/test/CMakeLists.txt +++ b/src/odb/test/CMakeLists.txt @@ -70,6 +70,7 @@ or_integration_tests( write_lef_polygon write_macro_placement PASSFAIL_TESTS + read_3dbx-fail cpp_tests test_block test_bterm diff --git a/src/odb/test/data/fail.3dbx b/src/odb/test/data/fail.3dbx new file mode 100644 index 00000000000..9c5afcb13ad --- /dev/null +++ b/src/odb/test/data/fail.3dbx @@ -0,0 +1,9 @@ +Header: + version: "1.0" + unit: "micron" + precision: 2000 + include: + - nonexistent_include.3dbv + +Design: + name: "TestDesign" diff --git a/src/odb/test/data/fail_def.3dbv b/src/odb/test/data/fail_def.3dbv new file mode 100644 index 00000000000..86d7a1180a2 --- /dev/null +++ b/src/odb/test/data/fail_def.3dbv @@ -0,0 +1,10 @@ +Header: + version: "1.0" + unit: "micron" + precision: 2000 + +ChipletDef: + TestChiplet: + type: hier + external: + DEF_file: nonexistent.def diff --git a/src/odb/test/read_3dbx-fail.ok b/src/odb/test/read_3dbx-fail.ok new file mode 100644 index 00000000000..8505e8a6596 --- /dev/null +++ b/src/odb/test/read_3dbx-fail.ok @@ -0,0 +1,7 @@ +[ERROR ORD-0072] nonexistent_file.3dbx does not exist. +Caught expected error: main file not found +[ERROR ODB-0521] Parser Error: 3DBV Parser Error: Cannot open file: data/nonexistent_include.3dbv +Caught expected error: include file not found +[ERROR ODB-0557] DEF file does not exist: data/nonexistent.def +Caught expected error: DEF file not found +pass diff --git a/src/odb/test/read_3dbx-fail.tcl b/src/odb/test/read_3dbx-fail.tcl new file mode 100644 index 00000000000..9a7e86138c4 --- /dev/null +++ b/src/odb/test/read_3dbx-fail.tcl @@ -0,0 +1,42 @@ +source "helpers.tcl" + +# Test that read_3dbx gives a proper error for a non-existent file +# rather than segfaulting (regression test for issue #10082) + +# Test 1: Main file does not exist (Tcl proc raises ORD-0072 before C++ layer) +if { [catch { read_3dbx "nonexistent_file.3dbx" } err_msg] } { + if { [string first "ORD-0072" $err_msg] < 0 } { + puts "FAIL: Wrong error for missing main file: $err_msg" + exit 1 + } + puts "Caught expected error: main file not found" +} else { + puts "FAIL: Expected an error for non-existent main file" + exit 1 +} + +# Test 2: Main file exists but references a non-existent include +if { [catch { read_3dbx "data/fail.3dbx" } err_msg] } { + if { [string first "ODB-0521" $err_msg] < 0 } { + puts "FAIL: Wrong error for missing include file: $err_msg" + exit 1 + } + puts "Caught expected error: include file not found" +} else { + puts "FAIL: Expected an error for non-existent include file" + exit 1 +} + +# Test 3: 3DBV chiplet references a non-existent DEF file (ODB-0557 from createChiplet) +if { [catch { read_3dbv "data/fail_def.3dbv" } err_msg] } { + if { [string first "ODB-0557" $err_msg] < 0 } { + puts "FAIL: Wrong error for missing DEF file: $err_msg" + exit 1 + } + puts "Caught expected error: DEF file not found" +} else { + puts "FAIL: Expected an error for non-existent DEF file" + exit 1 +} + +puts "pass"