diff --git a/CMakeLists.txt b/CMakeLists.txt index 65bf62053cb..faddf8797a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,11 +142,11 @@ configure_file( # Ask CMake to output a compile_commands.json file for use with things like clang-tidy set(CMAKE_EXPORT_COMPILE_COMMANDS 1) - - add_subdirectory(third-party) if(ENABLE_TESTS) + find_program (BASH_PROGRAM bash REQUIRED) + enable_testing() add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} --parallel --output-on-failure -LE IntegrationTest) include(GoogleTest) diff --git a/src/ant/CMakeLists.txt b/src/ant/CMakeLists.txt index 521a2b66b46..68290ee3033 100644 --- a/src/ant/CMakeLists.txt +++ b/src/ant/CMakeLists.txt @@ -30,3 +30,4 @@ # POSSIBILITY OF SUCH DAMAGE. add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/ant/test/CMakeLists.txt b/src/ant/test/CMakeLists.txt new file mode 100644 index 00000000000..e1dfd857255 --- /dev/null +++ b/src/ant/test/CMakeLists.txt @@ -0,0 +1,13 @@ +include("openroad") + +set(TEST_NAMES + check_api1 + check_drt1 + check_grt1 + ant_check + ant_report +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("ant" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/cmake/openroad.cmake b/src/cmake/openroad.cmake index 07a5681f92a..fbedafa34de 100644 --- a/src/cmake/openroad.cmake +++ b/src/cmake/openroad.cmake @@ -1,2 +1,3 @@ include("swig_lib") include("messages") +include("testing") diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake new file mode 100644 index 00000000000..7b74a4e8fc2 --- /dev/null +++ b/src/cmake/testing.cmake @@ -0,0 +1,19 @@ +function(or_integration_test tool_name test_name regression_binary) + add_test ( + NAME ${tool_name}.${test_name} + COMMAND ${BASH_PROGRAM} ${regression_binary} ${test_name} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + ) + + string(CONCAT ENV + "TEST_TYPE=compare_logfile;" + "CTEST_TESTNAME=${test_name};" + "DIFF_LOCATION=${CMAKE_CURRENT_LIST_DIR}/results/${test_name}.diff" + ) + + set_property(TEST ${tool_name}.${test_name} + PROPERTY ENVIRONMENT ${ENV}) + + set_tests_properties(${tool_name}.${test_name} + PROPERTIES LABELS "IntegrationTest") +endfunction() diff --git a/src/cts/test/CMakeLists.txt b/src/cts/test/CMakeLists.txt index 86c41f885e5..e3781819ad0 100644 --- a/src/cts/test/CMakeLists.txt +++ b/src/cts/test/CMakeLists.txt @@ -6,6 +6,32 @@ include("openroad") +set(TEST_NAMES + check_buffers + check_buffers_blockages + check_charBuf + find_clock + find_clock_pad + no_clocks + no_sinks + simple_test + simple_test_clustered + simple_test_clustered_max_cap + check_wire_rc_cts + post_cts_opt + balance_levels + max_cap + array + array_no_blockages + array_ins_delay + insertion_delay + dummy_load +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("cts" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() + add_executable(cts_unittest cts_unittest.cc) target_include_directories(cts_unittest PUBLIC diff --git a/src/dbSta/CMakeLists.txt b/src/dbSta/CMakeLists.txt index 84335f37c92..a2117215a10 100644 --- a/src/dbSta/CMakeLists.txt +++ b/src/dbSta/CMakeLists.txt @@ -34,3 +34,4 @@ ############################################################################### add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/dbSta/test/CMakeLists.txt b/src/dbSta/test/CMakeLists.txt new file mode 100644 index 00000000000..1ecd4952a28 --- /dev/null +++ b/src/dbSta/test/CMakeLists.txt @@ -0,0 +1,45 @@ +include("openroad") + +set(TEST_NAMES + constant1 + make_port + network_edit1 + sdc_names1 + sdc_names2 + sdc_get1 + sta1 + sta2 + sta3 + sta4 + sta5 + block_sta1 + find_clks1 + find_clks2 + report_json1 + power1 + read_liberty1 + read_verilog1 + read_verilog2 + read_verilog3 + read_verilog4 + read_verilog5 + read_verilog6 + read_verilog7 + read_verilog8 + read_verilog9 + read_verilog10 + report_cell_usage + write_verilog1 + write_verilog2 + write_verilog3 + write_verilog4 + write_verilog5 + write_verilog6 + write_verilog7 + write_verilog8 + write_sdc1 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("ant" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/dft/CMakeLists.txt b/src/dft/CMakeLists.txt index c1937cc59b9..f2c1b524dfb 100644 --- a/src/dft/CMakeLists.txt +++ b/src/dft/CMakeLists.txt @@ -108,7 +108,7 @@ add_subdirectory(src/replace) add_subdirectory(src/stitch) add_subdirectory(src/utils) if(ENABLE_TESTS) - add_subdirectory(test/cpp) + add_subdirectory(test) endif() messages( diff --git a/src/dft/test/CMakeLists.txt b/src/dft/test/CMakeLists.txt index 0aa1867b3df..bb15f33c7cc 100644 --- a/src/dft/test/CMakeLists.txt +++ b/src/dft/test/CMakeLists.txt @@ -1,4 +1,17 @@ # Tests +include("openroad") -find_package(Boost) +set(TEST_NAMES + one_cell_sky130 + one_cell_nangate45 + sub_modules_sky130 + scan_architect_no_mix_sky130 + scan_architect_clock_mix_sky130 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("dft" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() +find_package(Boost) +add_subdirectory(cpp) diff --git a/src/dpl/test/CMakeLists.txt b/src/dpl/test/CMakeLists.txt index 67a5266511e..8f00f200333 100644 --- a/src/dpl/test/CMakeLists.txt +++ b/src/dpl/test/CMakeLists.txt @@ -6,6 +6,74 @@ include("openroad") +set(TEST_NAMES + aes + cell_on_block1 + cell_on_block2 + check1 + check2 + check3 + check4 + check5 + check6 + check7 + check8 + check9 + fence01 + fence02 + fence03 + fillers1 + fillers2 + fillers3 + fillers4 + fillers5 + fillers6 + fillers7 + fillers8 + fragmented_row01 + fragmented_row02 + fragmented_row03 + fragmented_row04 + gcd + hybrid_cells + hybrid_cells2 + ibex + max_disp1 + mirror1 + mirror2 + mirror3 + multi_height_one_site_gap_disallow + multi_height_rows + obstruction1 + obstruction2 + one_site_gap_disallow + pad01 + pad02 + pad03 + pad04 + pad05 + pad06 + pad07 + pad08 + regions1 + regions2 + regions3 + report_failures + simple01 + simple02 + simple03 + simple04 + simple05 + simple07 + simple08 + simple09 + simple10 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("dpl" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() + add_executable(dpl_test dpl_test.cc) target_link_libraries(dpl_test diff --git a/src/dpo/CMakeLists.txt b/src/dpo/CMakeLists.txt index 9d9e7d8a497..db19fd57c1b 100644 --- a/src/dpo/CMakeLists.txt +++ b/src/dpo/CMakeLists.txt @@ -113,3 +113,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/dpo/test/CMakeLists.txt b/src/dpo/test/CMakeLists.txt new file mode 100644 index 00000000000..39b11608b42 --- /dev/null +++ b/src/dpo/test/CMakeLists.txt @@ -0,0 +1,15 @@ +include("openroad") + +set(TEST_NAMES + aes + gcd + ibex + multi_height1 + gcd_no_one_site_gaps + regions1 + regions2 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("dpo" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/drt/CMakeLists.txt b/src/drt/CMakeLists.txt index d6078c44faa..de812063562 100644 --- a/src/drt/CMakeLists.txt +++ b/src/drt/CMakeLists.txt @@ -257,3 +257,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/drt/src/db/tech/frConstraint.h b/src/drt/src/db/tech/frConstraint.h index ba293f227f0..6657badb034 100644 --- a/src/drt/src/db/tech/frConstraint.h +++ b/src/drt/src/db/tech/frConstraint.h @@ -208,6 +208,8 @@ class frLef58MinStepConstraint : public frConstraint frCoord getMinAdjacentLength() const { return minAdjLength_; } bool hasEolWidth() const { return (eolWidth_ != -1); } frCoord getEolWidth() const { return eolWidth_; } + frCoord getNoAdjEol() const { return noAdjEol_; } + bool isExceptRectangle() const { return exceptRectangle_; } // setter void setMinStepLength(frCoord in) { minStepLength_ = in; } @@ -220,6 +222,8 @@ class frLef58MinStepConstraint : public frConstraint return frConstraintTypeEnum::frcLef58MinStepConstraint; } void report(utl::Logger* logger) const override; + void setNoAdjEol(frCoord value) { noAdjEol_ = value; } + void setExceptRectangle(bool value) { exceptRectangle_ = value; } protected: frCoord minStepLength_{-1}; @@ -239,6 +243,8 @@ class frLef58MinStepConstraint : public frConstraint bool exceptSameCorners_{false}; frCoord eolWidth_{-1}; bool concaveCorners_{false}; + frCoord noAdjEol_{-1}; + bool exceptRectangle_{false}; }; // minStep diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index cde04c7578e..ea184649f64 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -496,6 +496,8 @@ class FlexGCWorker::Impl void checkMetalShape_lef58MinStep(gcPin* pin); void checkMetalShape_lef58MinStep_noBetweenEol(gcPin* pin, frLef58MinStepConstraint* con); + void checkMetalShape_lef58MinStep_minAdjLength(gcPin* pin, + frLef58MinStepConstraint* con); void checkMetalSpacingTableInfluence(); void checkPinMetSpcTblInf(gcPin*); void checkRectMetSpcTblInf(gcRect*, frSpacingTableInfluenceConstraint*); diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index 1a52ed14072..c7f5ed8f862 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -1624,6 +1624,95 @@ void FlexGCWorker::Impl::checkMetalShape_lef58MinStep_noBetweenEol( } } +inline void joinSegmentCoords(gcSegment* seg, + frCoord& llx, + frCoord& lly, + frCoord& urx, + frCoord& ury) +{ + llx = std::min(llx, seg->low().x()); + lly = std::min(lly, seg->low().y()); + urx = std::max(urx, seg->low().x()); + ury = std::max(ury, seg->low().y()); + + llx = std::min(llx, seg->high().x()); + lly = std::min(lly, seg->high().y()); + urx = std::max(urx, seg->high().x()); + ury = std::max(ury, seg->high().y()); +} + +void FlexGCWorker::Impl::checkMetalShape_lef58MinStep_minAdjLength( + gcPin* pin, + frLef58MinStepConstraint* con) +{ + auto poly = pin->getPolygon(); + auto layerNum = poly->getLayerNum(); + auto net = poly->getNet(); + if (poly->size() == 4 && con->isExceptRectangle()) { + return; + } + + std::vector startEdges; + auto minStepLength = con->getMinStepLength(); + for (auto& edges : pin->getPolygonEdges()) { + // get the first edge that is >= minstep length + for (auto& e : edges) { + if (gtl::length(*e) < minStepLength) { + startEdges.push_back(e.get()); + } + } + } + for (auto startEdge : startEdges) { + bool violating = false; + auto nextEdge = startEdge->getNextEdge(); + auto prevEdge = startEdge->getPrevEdge(); + if (gtl::length(*(nextEdge)) < con->getMinAdjacentLength() + || gtl::length(*(prevEdge)) < con->getMinAdjacentLength()) { + violating = true; + } + if (con->getNoAdjEol() > -1) { + if (nextEdge->getLowCorner()->getType() == frCornerTypeEnum::CONVEX + && nextEdge->getHighCorner()->getType() == frCornerTypeEnum::CONVEX + && gtl::length(*(nextEdge)) < con->getNoAdjEol()) { + violating = true; + } + if (prevEdge->getLowCorner()->getType() == frCornerTypeEnum::CONVEX + && prevEdge->getHighCorner()->getType() == frCornerTypeEnum::CONVEX + && gtl::length(*(prevEdge)) < con->getNoAdjEol()) { + violating = true; + } + } + // skip if all edges are fixed + if (startEdge->isFixed() && nextEdge->isFixed() && prevEdge->isFixed()) { + continue; + } + if (!violating) { + continue; + } + + // real violation + frCoord llx = startEdge->low().x(); + frCoord lly = startEdge->low().y(); + frCoord urx = startEdge->low().x(); + frCoord ury = startEdge->low().y(); + + joinSegmentCoords(startEdge, llx, lly, urx, ury); + joinSegmentCoords(nextEdge, llx, lly, urx, ury); + joinSegmentCoords(prevEdge, llx, lly, urx, ury); + + auto marker = std::make_unique(); + Rect box(llx, lly, urx, ury); + marker->setBBox(box); + marker->setLayerNum(layerNum); + marker->setConstraint(con); + marker->addSrc(net->getOwner()); + marker->addVictim(net->getOwner(), std::make_tuple(layerNum, box, false)); + marker->addAggressor(net->getOwner(), + std::make_tuple(layerNum, box, false)); + addMarker(std::move(marker)); + } +} + // currently only support nobetweeneol void FlexGCWorker::Impl::checkMetalShape_lef58MinStep(gcPin* pin) { @@ -1632,10 +1721,12 @@ void FlexGCWorker::Impl::checkMetalShape_lef58MinStep(gcPin* pin) // auto net = poly->getNet(); for (auto con : getTech()->getLayer(layerNum)->getLef58MinStepConstraints()) { - if (!con->hasEolWidth()) { - continue; + if (con->hasEolWidth()) { + checkMetalShape_lef58MinStep_noBetweenEol(pin, con); + } + if (con->hasMinAdjacentLength()) { + checkMetalShape_lef58MinStep_minAdjLength(pin, con); } - checkMetalShape_lef58MinStep_noBetweenEol(pin, con); } } diff --git a/src/drt/src/io/io.cpp b/src/drt/src/io/io.cpp index 8bc39fb7d90..b7a6cb17e5e 100644 --- a/src/drt/src/io/io.cpp +++ b/src/drt/src/io/io.cpp @@ -778,7 +778,16 @@ void io::Parser::setNets(odb::dbBlock* block) } tmpP->addToNet(netIn); tmpP->setLayerNum(layerNum); - + auto layer = tech_->name2layer_[layerName]; + auto styleWidth = width; + if (!(styleWidth)) { + if ((layer->isHorizontal() && beginY != endY) + || (!layer->isHorizontal() && beginX != endX)) { + styleWidth = layer->getWrongDirWidth(); + } else { + styleWidth = layer->getWidth(); + } + } width = (width) ? width : tech_->name2layer_[layerName]->getWidth(); auto defaultBeginExt = width / 2; auto defaultEndExt = width / 2; @@ -804,7 +813,7 @@ void io::Parser::setNets(odb::dbBlock* block) frEndStyle tmpEndStyle(tmpEndEnum); frSegStyle tmpSegStyle; - tmpSegStyle.setWidth(width); + tmpSegStyle.setWidth(styleWidth); tmpSegStyle.setBeginStyle( tmpBeginStyle, tmpBeginEnum == frcExtendEndStyle ? defaultBeginExt : beginExt); @@ -1476,12 +1485,21 @@ void io::Parser::setRoutingLayerProperties(odb::dbTechLayer* layer, tech_->addUConstraint(std::move(rightWayOnGridOnlyConstraint)); } for (auto rule : layer->getTechLayerMinStepRules()) { + if (rule->getMaxEdges() > 1) { + logger_->warn(DRT, + 335, + "LEF58_MINSTEP MAXEDGES {} is not supported", + rule->getMaxEdges()); + continue; + } auto con = std::make_unique(); con->setMinStepLength(rule->getMinStepLength()); con->setMaxEdges(rule->isMaxEdgesValid() ? rule->getMaxEdges() : -1); con->setMinAdjacentLength( rule->isMinAdjLength1Valid() ? rule->getMinAdjLength1() : -1); + con->setNoAdjEol(rule->isNoAdjacentEol() ? rule->getEolWidth() : -1); con->setEolWidth(rule->isNoBetweenEol() ? rule->getEolWidth() : -1); + con->setExceptRectangle(rule->isExceptRectangle()); tmpLayer->addLef58MinStepConstraint(con.get()); tech_->addUConstraint(std::move(con)); } diff --git a/src/drt/src/io/io_parser_helper.cpp b/src/drt/src/io/io_parser_helper.cpp index c90f1b4f9b1..93c63385147 100644 --- a/src/drt/src/io/io_parser_helper.cpp +++ b/src/drt/src/io/io_parser_helper.cpp @@ -686,7 +686,7 @@ void io::Parser::checkFig(frPinFig* uFig, foundCenterTracks |= horzTracks.find(box.yCenter()) != horzTracks.end(); } else { foundTracks |= !vertTracks.empty(); - foundCenterTracks |= vertTracks.find(box.yCenter()) != vertTracks.end(); + foundCenterTracks |= vertTracks.find(box.xCenter()) != vertTracks.end(); } } if (foundTracks && box.minDXDY() > layer->getMinWidth()) { @@ -773,7 +773,7 @@ void io::Parser::checkPins() } else if (!foundCenterTracks && !hasPolys) { logger_->warn(DRT, 422, - "No routing tracks pass through the center of Term {}", + "No routing tracks pass through the center of Term {}.", bTerm->getName()); } } diff --git a/src/drt/test/CMakeLists.txt b/src/drt/test/CMakeLists.txt new file mode 100644 index 00000000000..f860df48f31 --- /dev/null +++ b/src/drt/test/CMakeLists.txt @@ -0,0 +1,18 @@ +include("openroad") + +set(TEST_NAMES + ispd18_sample + ndr_vias1 + ndr_vias2 + obstruction + single_step + ta_ap_aligned + ta_pin_aligned + top_level_term + top_level_term2 + drc_test +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("drt" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/drt/test/fixture.cpp b/src/drt/test/fixture.cpp index 03f3ed1ac12..470dcefd9ae 100644 --- a/src/drt/test/fixture.cpp +++ b/src/drt/test/fixture.cpp @@ -276,18 +276,18 @@ void Fixture::makeMinStepConstraint(frLayerNum layer_num) tech->addUConstraint(std::move(con)); } -void Fixture::makeMinStep58Constraint(frLayerNum layer_num) +frLef58MinStepConstraint* Fixture::makeMinStep58Constraint(frLayerNum layer_num) { auto con = std::make_unique(); con->setMinStepLength(50); con->setMaxEdges(1); - con->setEolWidth(200); - + auto rptr = con.get(); frTechObject* tech = design->getTech(); frLayer* layer = tech->getLayer(layer_num); layer->addLef58MinStepConstraint(con.get()); tech->addUConstraint(std::move(con)); + return rptr; } void Fixture::makeRectOnlyConstraint(frLayerNum layer_num) diff --git a/src/drt/test/fixture.h b/src/drt/test/fixture.h index 0da3a29779e..a4dcb699147 100644 --- a/src/drt/test/fixture.h +++ b/src/drt/test/fixture.h @@ -89,7 +89,7 @@ class Fixture void makeMinStepConstraint(frLayerNum layer_num); - void makeMinStep58Constraint(frLayerNum layer_num); + frLef58MinStepConstraint* makeMinStep58Constraint(frLayerNum layer_num); void makeRectOnlyConstraint(frLayerNum layer_num); diff --git a/src/drt/test/gcTest.cpp b/src/drt/test/gcTest.cpp index 0c2539a8ff5..f90057880d0 100644 --- a/src/drt/test/gcTest.cpp +++ b/src/drt/test/gcTest.cpp @@ -489,10 +489,11 @@ BOOST_AUTO_TEST_CASE(min_step) // Check for a lef58 style min step violation. The checker is very // limited and just supports NOBETWEENEOL style. -BOOST_AUTO_TEST_CASE(min_step58) +BOOST_AUTO_TEST_CASE(min_step58_nobetweeneol) { // Setup - makeMinStep58Constraint(2); + auto con = makeMinStep58Constraint(2); + con->setEolWidth(200); frNet* n1 = makeNet("n1"); @@ -510,6 +511,36 @@ BOOST_AUTO_TEST_CASE(min_step58) Rect(200, 50, 300, 70)); } +// Check for a lef58 style min step violation. The checker is very +// limited and just supports NOBETWEENEOL style. +BOOST_AUTO_TEST_CASE(min_step58_minadjlength) +{ + // Setup + auto con = makeMinStep58Constraint(2); + con->setMinAdjacentLength(100); + con->setNoAdjEol(200); + con->setMaxEdges(1); + + frNet* n1 = makeNet("n1"); + + makePathseg(n1, 2, {0, 0}, {500, 0}); + makePathseg(n1, 2, {200, -30}, {200, 70}); + + runGC(); + + // Test the results + auto& markers = worker.getMarkers(); + BOOST_TEST(markers.size() == 2); + testMarker(markers[0].get(), + 2, + frConstraintTypeEnum::frcLef58MinStepConstraint, + Rect(150, 50, 500, 70)); + testMarker(markers[1].get(), + 2, + frConstraintTypeEnum::frcLef58MinStepConstraint, + Rect(0, 50, 250, 70)); +} + // Check for a lef58 rect only violation. The markers are // the concave corners expanded by min-width and intersected // with the metal shapes. diff --git a/src/dst/test/cpp/CMakeLists.txt b/src/dst/test/cpp/CMakeLists.txt index 8693fbaab54..0beb1e33b16 100644 --- a/src/dst/test/cpp/CMakeLists.txt +++ b/src/dst/test/cpp/CMakeLists.txt @@ -28,3 +28,25 @@ target_include_directories(TestDistributed ${DST_HOME}/src ${OPENROAD_HOME}/include ) + +add_test( + NAME "dst.TestWorker" + COMMAND TestWorker +) + +add_test( + NAME "dst.TestBalancer" + COMMAND TestBalancer +) + +# This test case appears to have an internal race condition +#add_test( +# NAME "dst.TestDistributed" +# COMMAND TestDistributed +#) + +add_dependencies(build_and_test + TestWorker + TestBalancer + TestDistributed +) diff --git a/src/fin/CMakeLists.txt b/src/fin/CMakeLists.txt index 274737c5185..0b1127a811e 100644 --- a/src/fin/CMakeLists.txt +++ b/src/fin/CMakeLists.txt @@ -80,3 +80,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/fin/test/CMakeLists.txt b/src/fin/test/CMakeLists.txt new file mode 100644 index 00000000000..ee1ecde82b7 --- /dev/null +++ b/src/fin/test/CMakeLists.txt @@ -0,0 +1,9 @@ +include("openroad") + +set(TEST_NAMES + gcd_fill +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("fin" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/gpl/test/CMakeLists.txt b/src/gpl/test/CMakeLists.txt index 4c2c908ab6d..ac2b0697818 100644 --- a/src/gpl/test/CMakeLists.txt +++ b/src/gpl/test/CMakeLists.txt @@ -1,47 +1,37 @@ include("openroad") -find_program (BASH_PROGRAM bash REQUIRED) - -function(gpl_test test_name) - add_test ( - NAME gpl.${test_name} - COMMAND ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/regression ${test_name} - ) - set_tests_properties(gpl.${test_name} PROPERTIES LABELS "IntegrationTest") -endfunction() - set(TEST_NAMES -simple01 -simple01-obs -simple01-td -simple01-td-tune -simple01-uniform -simple01-ref -simple01-skip-io -simple02 -simple03 -simple04 -simple05 -simple06 -simple07 -simple08 -simple09 -core01 -ar01 -ar02 -incremental01 -incremental02 -error01 -diverge01 -density01 -convergence01 -nograd01 -clust01 -clust02 + simple01 + simple01-obs + simple01-td + simple01-td-tune + simple01-uniform + simple01-ref + simple01-skip-io + simple02 + simple03 + simple04 + simple05 + simple06 + simple07 + simple08 + simple09 + core01 + ar01 + ar02 + incremental01 + incremental02 + error01 + diverge01 + density01 + convergence01 + nograd01 + clust01 + clust02 ) foreach(TEST_NAME IN LISTS TEST_NAMES) - gpl_test(${TEST_NAME}) + or_integration_test("gpl" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) endforeach() add_executable(fft_test fft_test.cc) diff --git a/src/gpl/test/simple01-uniform.def b/src/gpl/test/simple01-uniform.def new file mode 120000 index 00000000000..7c6bf5ed94f --- /dev/null +++ b/src/gpl/test/simple01-uniform.def @@ -0,0 +1 @@ +simple01.def \ No newline at end of file diff --git a/src/gpl/test/simple01-uniform.tcl b/src/gpl/test/simple01-uniform.tcl index a6235d48f47..e067792e923 100644 --- a/src/gpl/test/simple01-uniform.tcl +++ b/src/gpl/test/simple01-uniform.tcl @@ -1,9 +1,9 @@ source helpers.tcl -set test_name simple01 +set test_name simple01-uniform read_lef ./nangate45.lef read_def ./$test_name.def global_placement -init_density_penalty 0.01 -skip_initial_place -density uniform -set def_file [make_result_file $test_name-uniform.def] +set def_file [make_result_file $test_name.def] write_def $def_file -diff_file $def_file $test_name-uniform.defok +diff_file $def_file $test_name.defok diff --git a/src/grt/CMakeLists.txt b/src/grt/CMakeLists.txt index 70f9c4ace8f..c02e9d4a032 100644 --- a/src/grt/CMakeLists.txt +++ b/src/grt/CMakeLists.txt @@ -134,3 +134,5 @@ endif() messages( TARGET grt ) + +add_subdirectory(test) \ No newline at end of file diff --git a/src/grt/src/GlobalRouter.cpp b/src/grt/src/GlobalRouter.cpp index 2b221251645..9bf41cf9e08 100644 --- a/src/grt/src/GlobalRouter.cpp +++ b/src/grt/src/GlobalRouter.cpp @@ -176,6 +176,7 @@ std::vector GlobalRouter::initFastRoute(int min_routing_layer, setCapacities(min_routing_layer, max_routing_layer); std::vector nets = findNets(); + checkPinPlacement(); initNetlist(nets); applyAdjustments(min_routing_layer, max_routing_layer); @@ -722,7 +723,6 @@ float GlobalRouter::getNetSlack(Net* net) void GlobalRouter::initNetlist(std::vector& nets) { - checkPinPlacement(); pad_pins_connections_.clear(); int min_degree = std::numeric_limits::max(); diff --git a/src/grt/src/fastroute/include/DataType.h b/src/grt/src/fastroute/include/DataType.h index 86356664f5e..e61422ab0f6 100644 --- a/src/grt/src/fastroute/include/DataType.h +++ b/src/grt/src/fastroute/include/DataType.h @@ -87,7 +87,6 @@ struct Segment // A Segment is a 2-pin connection struct FrNet // A Net is a set of connected MazePoints { bool isClock() const { return is_clock_; } - bool isRouted() const { return is_routed_; } bool isCritical() { return is_critical_; } float getSlack() const { return slack_; } odb::dbNet* getDbNet() const { return db_net_; } @@ -115,7 +114,6 @@ struct FrNet // A Net is a set of connected MazePoints int max_layer, float slack, std::vector* edge_cost_per_layer); - void setIsRouted(bool is_routed) { is_routed_ = is_routed; } void setMaxLayer(int max_layer) { max_layer_ = max_layer; } void setMinLayer(int min_layer) { min_layer_ = min_layer; } void setSlack(float slack) { slack_ = slack; } @@ -135,7 +133,6 @@ struct FrNet // A Net is a set of connected MazePoints float slack_; // Non-null when an NDR has been applied to the net. std::unique_ptr> edge_cost_per_layer_; - bool is_routed_ = false; }; struct Edge // An Edge is the routing track holder between two adjacent diff --git a/src/grt/src/fastroute/include/FastRoute.h b/src/grt/src/fastroute/include/FastRoute.h index 49081d45fc6..3a9e462641b 100644 --- a/src/grt/src/fastroute/include/FastRoute.h +++ b/src/grt/src/fastroute/include/FastRoute.h @@ -489,7 +489,6 @@ class FastRouteCore bool horizontal, int& best_cost, multi_array& layer_grid); - bool skipNet(int netID); void assignEdge(int netID, int edgeID, bool processDIR); void recoverEdge(int netID, int edgeID); void layerAssignmentV4(); @@ -628,6 +627,7 @@ class FastRouteCore std::set> h_used_ggrid_; std::set> v_used_ggrid_; + std::vector net_ids_; }; } // namespace grt diff --git a/src/grt/src/fastroute/src/FastRoute.cpp b/src/grt/src/fastroute/src/FastRoute.cpp index 3cdfb0c236d..34b5ae45ce5 100644 --- a/src/grt/src/fastroute/src/FastRoute.cpp +++ b/src/grt/src/fastroute/src/FastRoute.cpp @@ -163,6 +163,7 @@ void FastRouteCore::clearNets() delete net; } nets_.clear(); + net_ids_.clear(); seglist_.clear(); db_net_id_map_.clear(); } @@ -273,6 +274,7 @@ FrNet* FastRouteCore::addNet(odb::dbNet* db_net, max_layer, slack, edge_cost_per_layer); + net_ids_.push_back(netID); return net; } @@ -665,12 +667,7 @@ void FastRouteCore::initNetAuxVars() NetRouteMap FastRouteCore::getRoutes() { NetRouteMap routes; - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - - nets_[netID]->setIsRouted(true); + for (const int& netID : net_ids_) { odb::dbNet* db_net = nets_[netID]->getDbNet(); GRoute& route = routes[db_net]; std::unordered_set net_segs; @@ -728,11 +725,7 @@ NetRouteMap FastRouteCore::getPlanarRoutes() // Get routes before layer assignment - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto fr_net = nets_[netID]; odb::dbNet* db_net = fr_net->getDbNet(); GRoute& route = routes[db_net]; @@ -1014,8 +1007,8 @@ NetRouteMap FastRouteCore::run() // debug mode Rectilinear Steiner Tree before overflow iterations if (debug_->isOn() && debug_->rectilinearSTree_) { - for (int netID = 0; netID < netCount(); netID++) { - if (nets_[netID]->getDbNet() == debug_->net_ && !skipNet(netID)) { + for (const int& netID : net_ids_) { + if (nets_[netID]->getDbNet() == debug_->net_) { StTreeVisualization(sttrees_[netID], nets_[netID], false); } } @@ -1265,8 +1258,8 @@ NetRouteMap FastRouteCore::run() // Debug mode Tree 2D after overflow iterations if (debug_->isOn() && debug_->tree2D_) { - for (int netID = 0; netID < netCount(); netID++) { - if (nets_[netID]->getDbNet() == debug_->net_ && !skipNet(netID)) { + for (const int& netID : net_ids_) { + if (nets_[netID]->getDbNet() == debug_->net_) { StTreeVisualization(sttrees_[netID], nets_[netID], false); } } @@ -1322,8 +1315,8 @@ NetRouteMap FastRouteCore::run() // Debug mode Tree 3D after layer assignament if (debug_->isOn() && debug_->tree3D_) { - for (int netID = 0; netID < netCount(); netID++) { - if (nets_[netID]->getDbNet() == debug_->net_ && !skipNet(netID)) { + for (const int& netID : net_ids_) { + if (nets_[netID]->getDbNet() == debug_->net_) { StTreeVisualization(sttrees_[netID], nets_[netID], true); } } @@ -1331,6 +1324,7 @@ NetRouteMap FastRouteCore::run() NetRouteMap routes = getRoutes(); net_eo_.clear(); + net_ids_.clear(); return routes; } @@ -1553,7 +1547,6 @@ void FrNet::reset(odb::dbNet* db_net, std::vector* edge_cost_per_layer) { db_net_ = db_net; - is_routed_ = false; is_critical_ = false; is_clock_ = is_clock; driver_idx_ = driver_idx; diff --git a/src/grt/src/fastroute/src/RSMT.cpp b/src/grt/src/fastroute/src/RSMT.cpp index 4ab2949bed3..fbc7a484517 100644 --- a/src/grt/src/fastroute/src/RSMT.cpp +++ b/src/grt/src/fastroute/src/RSMT.cpp @@ -654,22 +654,18 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, const int flute_accuracy = 2; - for (int i = 0; i < netCount(); i++) { - if (skipNet(i)) { - continue; - } - - FrNet* net = nets_[i]; + for (const int& netID : net_ids_) { + FrNet* net = nets_[netID]; int d = net->getNumPins(); if (reRoute) { if (newType) { - const auto& treeedges = sttrees_[i].edges; - const auto& treenodes = sttrees_[i].nodes; - for (int j = 0; j < sttrees_[i].num_edges(); j++) { + const auto& treeedges = sttrees_[netID].edges; + const auto& treenodes = sttrees_[netID].nodes; + for (int j = 0; j < sttrees_[netID].num_edges(); j++) { // only route the non-degraded edges (len>0) - if (sttrees_[i].edges[j].len > 0) { + if (sttrees_[netID].edges[j].len > 0) { const TreeEdge* treeedge = &(treeedges[j]); const int n1 = treeedge->n1; const int n2 = treeedge->n2; @@ -677,12 +673,12 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, const int y1 = treenodes[n1].y; const int x2 = treenodes[n2].x; const int y2 = treenodes[n2].y; - newRipup(treeedge, x1, y1, x2, y2, i); + newRipup(treeedge, x1, y1, x2, y2, netID); } } } else { // remove the est_usage due to the segments in this net - for (auto& seg : seglist_[i]) { + for (auto& seg : seglist_[netID]) { ripupSegL(&seg); } } @@ -700,25 +696,37 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, if (congestionDriven) { // call congestion driven flute to generate RSMT bool cong; - coeffV = noADJ ? 1.2 : coeffADJ(i); - cong = netCongestion(i); + coeffV = noADJ ? 1.2 : coeffADJ(netID); + cong = netCongestion(netID); if (cong) { - fluteCongest( - i, net->getPinX(), net->getPinY(), flute_accuracy, coeffV, rsmt); + fluteCongest(netID, + net->getPinX(), + net->getPinY(), + flute_accuracy, + coeffV, + rsmt); } else { - fluteNormal( - i, net->getPinX(), net->getPinY(), flute_accuracy, coeffV, rsmt); + fluteNormal(netID, + net->getPinX(), + net->getPinY(), + flute_accuracy, + coeffV, + rsmt); } if (d > 3) { - numShift += edgeShiftNew(rsmt, i); + numShift += edgeShiftNew(rsmt, netID); } } else { // call FLUTE to generate RSMT for each net - if (noADJ || HTreeSuite(i)) { + if (noADJ || HTreeSuite(netID)) { coeffV = 1.2; } - fluteNormal( - i, net->getPinX(), net->getPinY(), flute_accuracy, coeffV, rsmt); + fluteNormal(netID, + net->getPinX(), + net->getPinY(), + flute_accuracy, + coeffV, + rsmt); } } if (debug_->isOn() && debug_->steinerTree_ @@ -727,7 +735,7 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, } if (genTree) { - copyStTree(i, rsmt); + copyStTree(netID, rsmt); } if (net->getNumPins() != rsmt.deg) { @@ -735,8 +743,9 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, } if (congestionDriven) { - for (int j = 0; j < sttrees_[i].num_edges(); j++) - wl1 += sttrees_[i].edges[j].len; + for (int j = 0; j < sttrees_[netID].num_edges(); j++) { + wl1 += sttrees_[netID].edges[j].len; + } } for (int j = 0; j < rsmt.branchCount(); j++) { @@ -750,8 +759,8 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, if (x1 != x2 || y1 != y2) { // the branch is not degraded (a point) // the position of this segment in seglist - seglist_[i].push_back(Segment()); - auto& seg = seglist_[i].back(); + seglist_[netID].push_back(Segment()); + auto& seg = seglist_[netID].back(); if (x1 < x2) { seg.x1 = x1; seg.x2 = x2; @@ -764,16 +773,16 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven, seg.y2 = y1; } - seg.netID = i; + seg.netID = netID; } } // loop j - totalNumSeg += seglist_[i].size(); + totalNumSeg += seglist_[netID].size(); if (reRoute) { // update the est_usage due to the segments in this net newrouteL( - i, + netID, RouteType::NoRoute, true); // route the net with no previous route for each tree edge } diff --git a/src/grt/src/fastroute/src/maze.cpp b/src/grt/src/fastroute/src/maze.cpp index 088372e76aa..adcbf2e3eab 100644 --- a/src/grt/src/fastroute/src/maze.cpp +++ b/src/grt/src/fastroute/src/maze.cpp @@ -60,10 +60,8 @@ void FastRouteCore::fixEmbeddedTrees() // check embedded trees only when maze router is called // i.e., when running overflow iterations if (overflow_iterations_ > 0) { - for (int netID = 0; netID < netCount(); netID++) { - if (!skipNet(netID)) { - checkAndFixEmbeddedTree(netID); - } + for (const int& netID : net_ids_) { + checkAndFixEmbeddedTree(netID); } } } @@ -499,10 +497,8 @@ void FastRouteCore::convertToMazerouteNet(const int netID) void FastRouteCore::convertToMazeroute() { - for (int netID = 0; netID < netCount(); netID++) { - if (!skipNet(netID)) { - convertToMazerouteNet(netID); - } + for (const int& netID : net_ids_) { + convertToMazerouteNet(netID); } for (int i = 0; i < y_grid_; i++) { @@ -1360,12 +1356,9 @@ void FastRouteCore::mazeRouteMSMD(const int iter, std::vector pop_heap2(y_grid_ * x_range_, false); - for (int nidRPC = 0; nidRPC < netCount(); nidRPC++) { - const int netID = ordering ? tree_order_cong_[nidRPC].treeIndex : nidRPC; - - if (skipNet(netID)) { - continue; - } + for (int nidRPC = 0; nidRPC < net_ids_.size(); nidRPC++) { + const int netID + = ordering ? tree_order_cong_[nidRPC].treeIndex : net_ids_[nidRPC]; const int num_terminals = sttrees_[netID].num_terminals; @@ -2566,10 +2559,7 @@ void FastRouteCore::InitLastUsage(const int upType) void FastRouteCore::SaveLastRouteLen() { - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; // loop for all the tree edges const int num_edges = sttrees_[netID].num_edges(); diff --git a/src/grt/src/fastroute/src/maze3D.cpp b/src/grt/src/fastroute/src/maze3D.cpp index 52b50849834..edce512d656 100644 --- a/src/grt/src/fastroute/src/maze3D.cpp +++ b/src/grt/src/fastroute/src/maze3D.cpp @@ -817,10 +817,6 @@ void FastRouteCore::mazeRouteMSMDOrder3D(int expand, for (int orderIndex = 0; orderIndex < endIND; orderIndex++) { const int netID = tree_order_pv_[orderIndex].treeIndex; - if (skipNet(netID)) { - continue; - } - FrNet* net = nets_[netID]; int enlarge = expand; diff --git a/src/grt/src/fastroute/src/route.cpp b/src/grt/src/fastroute/src/route.cpp index bf274cf98b7..b1992c2ca14 100644 --- a/src/grt/src/fastroute/src/route.cpp +++ b/src/grt/src/fastroute/src/route.cpp @@ -229,34 +229,22 @@ void FastRouteCore::routeLAll(bool firstTime) { if (firstTime) { // no previous route // estimate congestion with 0.5+0.5 L - for (int i = 0; i < netCount(); i++) { - if (skipNet(i)) { - continue; - } - - for (auto& seg : seglist_[i]) { + for (const int& netID : net_ids_) { + for (auto& seg : seglist_[netID]) { estimateOneSeg(&seg); } } // L route - for (int i = 0; i < netCount(); i++) { - if (skipNet(i)) { - continue; - } - - for (auto& seg : seglist_[i]) { + for (const int& netID : net_ids_) { + for (auto& seg : seglist_[netID]) { // no need to reroute the H or V segs if (seg.x1 != seg.x2 || seg.y1 != seg.y2) routeSegLFirstTime(&seg); } } } else { // previous is L-route - for (int i = 0; i < netCount(); i++) { - if (skipNet(i)) { - continue; - } - - for (auto& seg : seglist_[i]) { + for (const int& netID : net_ids_) { + for (auto& seg : seglist_[netID]) { // no need to reroute the H or V segs if (seg.x1 != seg.x2 || seg.y1 != seg.y2) { ripupSegL(&seg); @@ -418,16 +406,12 @@ void FastRouteCore::newrouteL(int netID, RouteType ripuptype, bool viaGuided) void FastRouteCore::newrouteLAll(bool firstTime, bool viaGuided) { if (firstTime) { - for (int i = 0; i < netCount(); i++) { - if (!skipNet(i)) { - newrouteL(i, RouteType::NoRoute, viaGuided); // do L-routing - } + for (const int& netID : net_ids_) { + newrouteL(netID, RouteType::NoRoute, viaGuided); // do L-routing } } else { - for (int i = 0; i < netCount(); i++) { - if (!skipNet(i)) { - newrouteL(i, RouteType::LRoute, viaGuided); - } + for (const int& netID : net_ids_) { + newrouteL(netID, RouteType::LRoute, viaGuided); } } } @@ -858,10 +842,8 @@ void FastRouteCore::newrouteZ(int netID, int threshold) // first void FastRouteCore::newrouteZAll(int threshold) { - for (int i = 0; i < netCount(); i++) { - if (!skipNet(i)) { - newrouteZ(i, threshold); // ripup previous route and do Z-routing - } + for (const int& netID : net_ids_) { + newrouteZ(netID, threshold); // ripup previous route and do Z-routing } } @@ -1037,11 +1019,7 @@ void FastRouteCore::spiralRoute(int netID, int edgeID) void FastRouteCore::spiralRouteAll() { - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treenodes = sttrees_[netID].nodes; const int num_terminals = sttrees_[netID].num_terminals; @@ -1088,11 +1066,7 @@ void FastRouteCore::spiralRouteAll() } } - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; auto& treenodes = sttrees_[netID].nodes; const int num_edges = sttrees_[netID].num_edges(); @@ -1118,11 +1092,7 @@ void FastRouteCore::spiralRouteAll() } std::queue edgeQueue; - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { newRipupNet(netID); auto& treeedges = sttrees_[netID].edges; @@ -1174,11 +1144,7 @@ void FastRouteCore::spiralRouteAll() } } - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treenodes = sttrees_[netID].nodes; for (int d = 0; d < sttrees_[netID].num_nodes(); d++) { @@ -1514,11 +1480,7 @@ void FastRouteCore::routeMonotonicAll(int threshold, multi_array d1(boost::extents[y_range_][x_range_]); multi_array d2(boost::extents[y_range_][x_range_]); - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { const int numEdges = sttrees_[netID].num_edges(); for (int edgeID = 0; edgeID < numEdges; edgeID++) { routeMonotonic(netID, diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index 816e3202aea..7cb218b90d5 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -64,11 +64,7 @@ void FastRouteCore::printEdge(int const netID, int const edgeID) void FastRouteCore::ConvertToFull3DType2() { - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; const int num_edges = sttrees_[netID].num_edges(); @@ -151,15 +147,11 @@ void FastRouteCore::netpinOrderInc() { tree_order_pv_.clear(); - for (int j = 0; j < netCount(); j++) { - if (skipNet(j)) { - continue; - } - + for (const int& netID : net_ids_) { int xmin = BIG_INT; int totalLength = 0; - const auto& treenodes = sttrees_[j].nodes; - StTree* stree = &(sttrees_[j]); + const auto& treenodes = sttrees_[netID].nodes; + StTree* stree = &(sttrees_[netID]); const int num_edges = stree->num_edges(); for (int ind = 0; ind < num_edges; ind++) { totalLength += stree->edges[ind].len; @@ -170,7 +162,7 @@ void FastRouteCore::netpinOrderInc() float npvalue = (float) totalLength / stree->num_terminals; - tree_order_pv_.push_back({j, xmin, npvalue}); + tree_order_pv_.push_back({netID, xmin, npvalue}); } std::stable_sort(tree_order_pv_.begin(), tree_order_pv_.end(), comparePVMINX); @@ -182,11 +174,7 @@ void FastRouteCore::fillVIA() int numVIAT1 = 0; int numVIAT2 = 0; - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; int num_terminals = sttrees_[netID].num_terminals; const auto& treenodes = sttrees_[netID].nodes; @@ -405,10 +393,7 @@ int FastRouteCore::threeDVIA() { int numVIA = 0; - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; int num_edges = sttrees_[netID].num_edges(); @@ -847,7 +832,7 @@ void FastRouteCore::assignEdge(int netID, int edgeID, bool processDIR) void FastRouteCore::layerAssignmentV4() { - int i, k, netID, edgeID, nodeID, routeLen; + int i, k, edgeID, nodeID, routeLen; int n1, n2, connectionCNT; int n1a, n2a; @@ -855,11 +840,7 @@ void FastRouteCore::layerAssignmentV4() TreeEdge* treeedge; - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; for (edgeID = 0; edgeID < sttrees_[netID].num_edges(); edgeID++) { treeedge = &(treeedges[edgeID]); @@ -873,11 +854,7 @@ void FastRouteCore::layerAssignmentV4() netpinOrderInc(); for (i = 0; i < tree_order_pv_.size(); i++) { - netID = tree_order_pv_[i].treeIndex; - - if (skipNet(netID)) { - continue; - } + int netID = tree_order_pv_[i].treeIndex; auto& treeedges = sttrees_[netID].edges; auto& treenodes = sttrees_[netID].nodes; @@ -993,15 +970,11 @@ void FastRouteCore::layerAssignmentV4() void FastRouteCore::layerAssignment() { - int netID, d, k, edgeID, numpoints, n1, n2; + int d, k, edgeID, numpoints, n1, n2; bool redundant; TreeEdge* treeedge; - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treenodes = sttrees_[netID].nodes; numpoints = 0; @@ -1048,11 +1021,7 @@ void FastRouteCore::layerAssignment() } } - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; auto& treenodes = sttrees_[netID].nodes; @@ -1127,16 +1096,12 @@ void FastRouteCore::printTree3D(int netID) void FastRouteCore::checkRoute3D() { - int i, netID, edgeID, nodeID, edgelength; + int i, edgeID, nodeID, edgelength; int n1, n2, x1, y1, x2, y2; int distance; bool gridFlag; - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { const auto& treenodes = sttrees_[netID].nodes; const int num_terminals = sttrees_[netID].num_terminals; @@ -1245,23 +1210,20 @@ static bool compareTEL(const OrderTree a, const OrderTree b) void FastRouteCore::StNetOrder() { - int i, j, ind, min_x, min_y; + int i, ind, min_x, min_y; StTree* stree; tree_order_cong_.clear(); - tree_order_cong_.resize(netCount()); + tree_order_cong_.resize(net_ids_.size()); i = 0; - for (j = 0; j < netCount(); j++) { - // if the net is routed - if (skipNet(j)) { - continue; - } + for (int j = 0; j < net_ids_.size(); j++) { + int netID = net_ids_[j]; - stree = &(sttrees_[j]); + stree = &(sttrees_[netID]); tree_order_cong_[j].xmin = 0; - tree_order_cong_[j].treeIndex = j; + tree_order_cong_[j].treeIndex = netID; for (ind = 0; ind < stree->num_edges(); ind++) { const auto& treeedges = stree->edges; @@ -1273,13 +1235,13 @@ void FastRouteCore::StNetOrder() if (gridsX[i] == gridsX[i + 1]) { // a vertical edge min_y = std::min(gridsY[i], gridsY[i + 1]); const int cap = getEdgeCapacity( - nets_[j], gridsX[i], min_y, EdgeDirection::Vertical); + nets_[netID], gridsX[i], min_y, EdgeDirection::Vertical); tree_order_cong_[j].xmin += std::max(0, v_edges_[min_y][gridsX[i]].usage - cap); } else { // a horizontal edge min_x = std::min(gridsX[i], gridsX[i + 1]); const int cap = getEdgeCapacity( - nets_[j], min_x, gridsY[i], EdgeDirection::Horizontal); + nets_[netID], min_x, gridsY[i], EdgeDirection::Horizontal); tree_order_cong_[j].xmin += std::max(0, h_edges_[gridsY[i]][min_x].usage - cap); } @@ -1292,11 +1254,12 @@ void FastRouteCore::StNetOrder() // Set the 70% (or less) of non critical nets that doesn't have overflow // with the lowest priority - for (int ord_elID = 0; ord_elID < netCount(); ord_elID++) { + for (int ord_elID = 0; ord_elID < net_ids_.size(); ord_elID++) { auto order_element = tree_order_cong_[ord_elID]; if (nets_[order_element.treeIndex]->getSlack() == std::ceil(std::numeric_limits::lowest())) { - if (order_element.xmin == 0 && (ord_elID >= (netCount() * 30 / 100))) { + if (order_element.xmin == 0 + && (ord_elID >= (net_ids_.size() * 30 / 100))) { nets_[order_element.treeIndex]->setSlack( std::numeric_limits::max()); } @@ -1327,10 +1290,7 @@ float FastRouteCore::CalculatePartialSlack() parasitics_builder_->estimateParasitcs(db_net, route); } } - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } + for (const int& netID : net_ids_) { auto fr_net = nets_[netID]; odb::dbNet* db_net = fr_net->getDbNet(); float slack = parasitics_builder_->getNetSlack(db_net); @@ -1348,10 +1308,7 @@ float FastRouteCore::CalculatePartialSlack() // Set the non critical nets slack as the lowest float, so they can be // ordered by overflow (and ordered first than the critical nets) - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } + for (const int& netID : net_ids_) { if (nets_[netID]->getSlack() > slack_th) { nets_[netID]->setSlack(std::ceil(std::numeric_limits::lowest())); } @@ -1438,11 +1395,7 @@ void FastRouteCore::recoverEdge(int netID, int edgeID) void FastRouteCore::removeLoops() { - for (int netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { auto& treeedges = sttrees_[netID].edges; const int edgeCost = nets_[netID]->getEdgeCost(); @@ -1770,11 +1723,6 @@ void FastRouteCore::printTree2D(int netID) } } -bool FastRouteCore::skipNet(int netID) -{ - return nets_[netID] == nullptr || nets_[netID]->isRouted(); -} - bool FastRouteCore::checkRoute2DTree(int netID) { bool STHwrong = false; @@ -1870,14 +1818,10 @@ bool FastRouteCore::checkRoute2DTree(int netID) // Copy Routing Solution for the best routing solution so far void FastRouteCore::copyRS(void) { - int i, j, netID, edgeID, numEdges, numNodes; + int i, j, edgeID, numEdges, numNodes; if (!sttrees_bk_.empty()) { - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { numEdges = sttrees_bk_[netID].num_edges(); for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_bk_[netID].edges[edgeID].len > 0) { @@ -1891,11 +1835,7 @@ void FastRouteCore::copyRS(void) sttrees_bk_.resize(netCount()); - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { numNodes = sttrees_[netID].num_nodes(); numEdges = sttrees_[netID].num_edges(); @@ -1942,14 +1882,10 @@ void FastRouteCore::copyRS(void) void FastRouteCore::copyBR(void) { - int i, j, netID, edgeID, numEdges, numNodes, min_y, min_x; + int i, j, edgeID, numEdges, numNodes, min_y, min_x; if (!sttrees_bk_.empty()) { - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { numEdges = sttrees_[netID].num_edges(); for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_[netID].edges[edgeID].len > 0) { @@ -1959,11 +1895,7 @@ void FastRouteCore::copyBR(void) } } - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { numNodes = sttrees_bk_[netID].num_nodes(); numEdges = sttrees_bk_[netID].num_edges(); @@ -2022,7 +1954,7 @@ void FastRouteCore::copyBR(void) v_edges_[i][j].usage = 0; } } - for (netID = 0; netID < netCount(); netID++) { + for (int netID : net_ids_) { numEdges = sttrees_[netID].num_edges(); int edgeCost = nets_[netID]->getEdgeCost(); @@ -2056,13 +1988,9 @@ void FastRouteCore::copyBR(void) void FastRouteCore::freeRR(void) { - int netID, edgeID, numEdges; + int edgeID, numEdges; if (!sttrees_bk_.empty()) { - for (netID = 0; netID < netCount(); netID++) { - if (skipNet(netID)) { - continue; - } - + for (const int& netID : net_ids_) { numEdges = sttrees_bk_[netID].num_edges(); for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_bk_[netID].edges[edgeID].len > 0) { diff --git a/src/grt/test/CMakeLists.txt b/src/grt/test/CMakeLists.txt new file mode 100644 index 00000000000..0be4e9deed6 --- /dev/null +++ b/src/grt/test/CMakeLists.txt @@ -0,0 +1,71 @@ +include("openroad") + +set(TEST_NAMES + bus_route + clock_route + clock_route_alpha + clock_route_error1 + clock_route_error2 + congestion1 + congestion2 + congestion3 + congestion4 + congestion5 + congestion6 + congestion7 + critical_nets_percentage + est_rc1 + est_rc2 + est_rc3 + est_rc4 + gcd + gcd_flute + inst_pin_out_of_die + invalid_routing_layer + invalid_pin_placement + macro_obs_not_aligned + multiple_calls + ndr_1w_3s + ndr_2w_3s + no_tracks + obstruction + obs_out_of_die + overlapping_edges + pd1 + pd2 + pd3 + pd4 + pin_access1 + pin_access2 + pin_edge + pin_track_not_aligned + pre_routed1 + region_adjustment + repair_antennas1 + repair_antennas2 + repair_antennas3 + repair_antennas4 + repair_antennas_error1 + repair_antennas_error2 + report_wire_length1 + report_wire_length2 + report_wire_length3 + report_wire_length4 + report_wire_length5 + report_wire_length6 + set_nets_to_route1 + silence + single_row + top_level_term1 + top_level_term2 + top_level_term3 + tracks1 + tracks2 + tracks3 + upper_layer_net + modeling_instance_obs +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("grt" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 77cf1b19b55..1707876c36f 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -115,3 +115,5 @@ target_include_directories(gui ${OPENSTA_HOME}/include ${DBSTA_HOME}/include ) + +add_subdirectory(test) \ No newline at end of file diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index 90236393d45..07bb7523640 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1495,6 +1495,7 @@ void ClockWidget::saveImage(const std::string& clock_name, if (height_px.has_value()) { view_size.setHeight(height_px.value()); } + print_view.scale(1, 1); // mysteriously necessary sometimes print_view.resize(view_size); // Ensure the new view is sized correctly by Qt by processing the event // so fit will work diff --git a/src/gui/src/dbDescriptors.cpp b/src/gui/src/dbDescriptors.cpp index d69ad95f645..070f26c56b7 100644 --- a/src/gui/src/dbDescriptors.cpp +++ b/src/gui/src/dbDescriptors.cpp @@ -816,6 +816,7 @@ Descriptor::Properties DbMasterDescriptor::getProperties(std::any object) const instances.insert(gui->makeSelected(inst)); } props.push_back({"Instances", instances}); + props.push_back({"Origin", master->getOrigin()}); populateODBProperties(props, master); diff --git a/src/gui/src/gui.cpp b/src/gui/src/gui.cpp index ddfdd967a7e..f5115722824 100644 --- a/src/gui/src/gui.cpp +++ b/src/gui/src/gui.cpp @@ -1492,6 +1492,10 @@ std::string Descriptor::Property::toString(const std::any& value) text += convert_dbu(v->xMax(), false) + ","; text += convert_dbu(v->yMax(), false) + ")"; return text; + } else if (auto v = std::any_cast(&value)) { + std::string text = fmt::format( + "({},{})", convert_dbu(v->x(), false), convert_dbu(v->y(), false)); + return text; } return ""; diff --git a/src/gui/test/CMakeLists.txt b/src/gui/test/CMakeLists.txt new file mode 100644 index 00000000000..3fad41973ec --- /dev/null +++ b/src/gui/test/CMakeLists.txt @@ -0,0 +1,9 @@ +include("openroad") + +set(TEST_NAMES + supported +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("gui" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/ifp/CMakeLists.txt b/src/ifp/CMakeLists.txt index 84335f37c92..a2117215a10 100644 --- a/src/ifp/CMakeLists.txt +++ b/src/ifp/CMakeLists.txt @@ -34,3 +34,4 @@ ############################################################################### add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/ifp/test/CMakeLists.txt b/src/ifp/test/CMakeLists.txt new file mode 100644 index 00000000000..4faeb54197c --- /dev/null +++ b/src/ifp/test/CMakeLists.txt @@ -0,0 +1,33 @@ +include("openroad") + +set(TEST_NAMES + hybrid_rows + hybrid_rows2 + init_floorplan1 + init_floorplan2 + init_floorplan3 + init_floorplan4 + init_floorplan5 + init_floorplan6 + init_floorplan7 + init_floorplan8 + init_floorplan9 + make_tracks1 + make_tracks2 + make_tracks3 + make_tracks4 + make_tracks5 + make_tracks6 + make_tracks7 + multi_height1 + multi_height2 + placement_blockage1 + placement_blockage2 + tiecells + upf_test + upf_shifter_test +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("ifp" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/mpl/CMakeLists.txt b/src/mpl/CMakeLists.txt index a65d8930e17..8f042744ebc 100644 --- a/src/mpl/CMakeLists.txt +++ b/src/mpl/CMakeLists.txt @@ -87,3 +87,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) diff --git a/src/mpl/test/CMakeLists.txt b/src/mpl/test/CMakeLists.txt new file mode 100644 index 00000000000..0b52c691446 --- /dev/null +++ b/src/mpl/test/CMakeLists.txt @@ -0,0 +1,13 @@ +include("openroad") + +set(TEST_NAMES + level3_01 + level3_02 + east_west1 + east_west2 + snap_layer1 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("mpl" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/mpl2/CMakeLists.txt b/src/mpl2/CMakeLists.txt index a677113bde6..9406a52806a 100644 --- a/src/mpl2/CMakeLists.txt +++ b/src/mpl2/CMakeLists.txt @@ -91,5 +91,5 @@ target_link_libraries(mpl2 ) if(ENABLE_TESTS) - add_subdirectory(test/cpp) + add_subdirectory(test) endif() diff --git a/src/mpl2/test/CMakeLists.txt b/src/mpl2/test/CMakeLists.txt new file mode 100644 index 00000000000..cb04709bab0 --- /dev/null +++ b/src/mpl2/test/CMakeLists.txt @@ -0,0 +1,11 @@ +include("openroad") + +set(TEST_NAMES + macro_only +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("mpl2" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() + +add_subdirectory(cpp) diff --git a/src/odb/CMakeLists.txt b/src/odb/CMakeLists.txt index 9bd1a419e48..a8085374442 100644 --- a/src/odb/CMakeLists.txt +++ b/src/odb/CMakeLists.txt @@ -29,7 +29,7 @@ add_subdirectory(src/zutil) add_subdirectory(src/cdl) if(ENABLE_TESTS) - add_subdirectory(test/cpp) + add_subdirectory(test) endif() add_library(odb INTERFACE) diff --git a/src/odb/test/CMakeLists.txt b/src/odb/test/CMakeLists.txt new file mode 100644 index 00000000000..8ff7fd04b2b --- /dev/null +++ b/src/odb/test/CMakeLists.txt @@ -0,0 +1,45 @@ +include("openroad") + +set(TEST_NAMES + bterm_hier_create + multi_tech + transform + rounding + sky130hd_multi_patterned + dont_touch + import_package + read_lef + read_db + read_zipped + create_sboxes + dump_via_rules + dump_vias + read_def + read_def58 + write_def58 + dump_nets + lef_mask + write_lef_and_def + lef_data_access + gcd_def_access + gcd_pdn_def_access + edit_def + wire_encoder + edit_via_params + row_settings + db_read_write + check_routing_tracks + polygon + def_parser + ndr + gcd_abstract_lef + gcd_abstract_lef_with_power + abstract_origin + write_macro_placement +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("odb" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() + +add_subdirectory(cpp) \ No newline at end of file diff --git a/src/pad/CMakeLists.txt b/src/pad/CMakeLists.txt index dfa6a32f360..d3d3960fd6d 100644 --- a/src/pad/CMakeLists.txt +++ b/src/pad/CMakeLists.txt @@ -71,3 +71,5 @@ target_link_libraries(pad messages( TARGET pad ) + +add_subdirectory(test) diff --git a/src/pad/test/CMakeLists.txt b/src/pad/test/CMakeLists.txt new file mode 100644 index 00000000000..7d40e790171 --- /dev/null +++ b/src/pad/test/CMakeLists.txt @@ -0,0 +1,32 @@ +include("openroad") + +set(TEST_NAMES + bump_array_make + bump_array_remove + bump_array_remove_single + make_corner_sites + make_io_sites + non_top_layer + place_pad + place_pad_outsideofrow + place_bondpad + place_bondpad_stagger + place_pad_no_master + place_pad_wrong_master + assign_bumps + connect_by_abutment + rdl_route + rdl_route_failed + rdl_route_assignments + rdl_route_45 + rdl_route_45_cost + rdl_route_via + rdl_route_bump_via + skywater130_overlapping_filler + skywater130_caravel + skywater130_coyote_tc +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("pad" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/par/CMakeLists.txt b/src/par/CMakeLists.txt index e4e72917164..da78b853f76 100644 --- a/src/par/CMakeLists.txt +++ b/src/par/CMakeLists.txt @@ -157,3 +157,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/par/test/CMakeLists.txt b/src/par/test/CMakeLists.txt new file mode 100644 index 00000000000..5edfb1d75dc --- /dev/null +++ b/src/par/test/CMakeLists.txt @@ -0,0 +1,10 @@ +include("openroad") + +set(TEST_NAMES + read_part + partition_gcd +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("par" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/pdn/CMakeLists.txt b/src/pdn/CMakeLists.txt index 89d322ee53d..9f8a240b934 100644 --- a/src/pdn/CMakeLists.txt +++ b/src/pdn/CMakeLists.txt @@ -34,3 +34,4 @@ ############################################################################### add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/pdn/src/PdnGen.cc b/src/pdn/src/PdnGen.cc index 63b0d765a46..20f682f82e3 100644 --- a/src/pdn/src/PdnGen.cc +++ b/src/pdn/src/PdnGen.cc @@ -109,22 +109,34 @@ void PdnGen::buildGrids(bool trim) insts_in_grids.insert(insts_in_grid.begin(), insts_in_grid.end()); } - ShapeTreeMap block_obs; - Grid::makeInitialObstructions(block, block_obs, insts_in_grids, logger_); + ShapeVectorMap block_obs_vec; + Grid::makeInitialObstructions(block, block_obs_vec, insts_in_grids, logger_); for (auto* grid : grids) { - grid->getGridLevelObstructions(block_obs); + grid->getGridLevelObstructions(block_obs_vec); } - ShapeTreeMap all_shapes; + ShapeVectorMap all_shapes_vec; // get special shapes - Grid::makeInitialShapes(block, all_shapes, logger_); - for (const auto& [layer, layer_shapes] : all_shapes) { - auto& layer_obs = block_obs[layer]; + Grid::makeInitialShapes(block, all_shapes_vec, logger_); + for (const auto& [layer, layer_shapes] : all_shapes_vec) { + auto& layer_obs = block_obs_vec[layer]; for (const auto& [box, shape] : layer_shapes) { - layer_obs.insert({shape->getObstructionBox(), shape}); + layer_obs.emplace_back(shape->getObstructionBox(), shape); } } + ShapeTreeMap block_obs; + for (const auto& [layer, shapes] : block_obs_vec) { + block_obs[layer] = ShapeTree(shapes.begin(), shapes.end()); + } + block_obs_vec.clear(); + + ShapeTreeMap all_shapes; + for (const auto& [layer, shapes] : all_shapes_vec) { + all_shapes[layer] = ShapeTree(shapes.begin(), shapes.end()); + } + all_shapes_vec.clear(); + for (auto* grid : grids) { debugPrint( logger_, utl::PDN, "Make", 2, "Build start grid - {}", grid->getName()); @@ -754,17 +766,12 @@ void PdnGen::writeToDb(bool add_pins, const std::string& report_file) const // collect all the SWires from the block auto* block = db_->getChip()->getBlock(); - ShapeTreeMap obstructions; + ShapeVectorMap net_shapes_vec; for (auto* net : block->getNets()) { - ShapeTreeMap net_shapes; - Shape::populateMapFromDb(net, net_shapes); - for (const auto& [layer, net_obs_layer] : net_shapes) { - auto& obs_layer = obstructions[layer]; - for (const auto& [box, shape] : net_obs_layer) { - obs_layer.insert({shape->getObstructionBox(), shape}); - } - } + Shape::populateMapFromDb(net, net_shapes_vec); } + const ShapeTreeMap obstructions(net_shapes_vec.begin(), net_shapes_vec.end()); + net_shapes_vec.clear(); for (auto* domain : domains) { for (const auto& grid : domain->getGrids()) { @@ -812,8 +819,10 @@ void PdnGen::ripUp(odb::dbNet* net) return; } - ShapeTreeMap net_shapes; - Shape::populateMapFromDb(net, net_shapes); + ShapeVectorMap net_shapes_vec; + Shape::populateMapFromDb(net, net_shapes_vec); + ShapeTreeMap net_shapes = Shape::convertVectorToTree(net_shapes_vec); + // remove bterms that connect to swires std::set terms; for (auto* bterm : net->getBTerms()) { diff --git a/src/pdn/src/connect.cpp b/src/pdn/src/connect.cpp index e518fec040e..0b9c364441b 100644 --- a/src/pdn/src/connect.cpp +++ b/src/pdn/src/connect.cpp @@ -491,7 +491,7 @@ void Connect::makeVia(odb::dbSWire* wire, ViaGenerator::Constraint lower_constraint{false, false, true}; if (lower->getLayer() == l0) { - if (!lower->isModifiable() || lower->hasTermConnections()) { + if (!lower->isModifiable() || lower->hasITermConnections()) { // lower is not modifiable to all sides must fit skip_caching = true; lower_constraint.must_fit_x = true; @@ -504,7 +504,7 @@ void Connect::makeVia(odb::dbSWire* wire, } ViaGenerator::Constraint upper_constraint{false, false, true}; if (upper->getLayer() == l1) { - if (!upper->isModifiable() || upper->hasTermConnections()) { + if (!upper->isModifiable() || upper->hasITermConnections()) { // upper is not modifiable to all sides must fit skip_caching = true; upper_constraint.must_fit_x = true; diff --git a/src/pdn/src/grid.cpp b/src/pdn/src/grid.cpp index c848afa9207..646b7cae99d 100644 --- a/src/pdn/src/grid.cpp +++ b/src/pdn/src/grid.cpp @@ -363,18 +363,17 @@ bool Grid::repairVias(const ShapeTreeMap& global_shapes, ShapeTreeMap Grid::getShapes() const { - ShapeTreeMap shapes; + ShapeVectorMap shapes; for (auto* component : getGridComponents()) { for (const auto& [layer, component_shapes] : component->getShapes()) { - auto& layer_shapes = shapes[layer]; - for (const auto& shape : component_shapes) { - layer_shapes.insert(shape); - } + shapes[layer].insert(shapes[layer].end(), + component_shapes.begin(), + component_shapes.end()); } } - return shapes; + return Shape::convertVectorToTree(shapes); } odb::Rect Grid::getDomainArea() const @@ -903,7 +902,7 @@ void Grid::writeToDb(const std::map& net_map, } } -void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const +void Grid::getGridLevelObstructions(ShapeVectorMap& obstructions) const { debugPrint(getLogger(), utl::PDN, @@ -934,7 +933,7 @@ void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const "Adding obstruction on layer {} covering {}", layer->getName(), Shape::getRectText(core, getBlock()->getDbUnitsPerMicron())); - obstructions[layer].insert({obs->getObstructionBox(), obs}); + obstructions[layer].emplace_back(obs->getObstructionBox(), obs); } for (const auto& ring : rings_) { @@ -957,13 +956,13 @@ void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const "Adding obstruction on layer {} covering {}", layer->getName(), Shape::getRectText(ring_rect, getBlock()->getDbUnitsPerMicron())); - obstructions[layer].insert({obs->getObstructionBox(), obs}); + obstructions[layer].emplace_back(obs->getObstructionBox(), obs); } } } void Grid::makeInitialObstructions(odb::dbBlock* block, - ShapeTreeMap& obs, + ShapeVectorMap& obs, const std::set& skip_insts, utl::Logger* logger) { @@ -983,13 +982,13 @@ void Grid::makeInitialObstructions(odb::dbBlock* block, if (box->getTechLayer() == nullptr) { for (auto* layer : block->getDb()->getTech()->getLayers()) { auto shape = std::make_shared(layer, obs_rect, Shape::BLOCK_OBS); - obs[shape->getLayer()].insert({shape->getObstructionBox(), shape}); + obs[shape->getLayer()].emplace_back(shape->getObstructionBox(), shape); } } else { auto shape = std::make_shared( box->getTechLayer(), obs_rect, Shape::BLOCK_OBS); - obs[shape->getLayer()].insert({shape->getObstructionBox(), shape}); + obs[shape->getLayer()].emplace_back(shape->getObstructionBox(), shape); } } @@ -1030,14 +1029,14 @@ void Grid::makeInitialObstructions(odb::dbBlock* block, for (const auto& [layer, shapes] : InstanceGrid::getInstanceObstructions(inst)) { - obs[layer].insert(shapes.begin(), shapes.end()); + obs[layer].insert(obs[layer].end(), shapes.begin(), shapes.end()); } } debugPrint(logger, utl::PDN, "Make", 2, "Get initial obstructions - end"); } void Grid::makeInitialShapes(odb::dbBlock* block, - ShapeTreeMap& shapes, + ShapeVectorMap& shapes, utl::Logger* logger) { debugPrint(logger, utl::PDN, "Make", 2, "Get initial shapes - start"); @@ -1185,7 +1184,7 @@ void CoreGrid::setupDirectConnect( } } -void CoreGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const +void CoreGrid::getGridLevelObstructions(ShapeVectorMap& obstructions) const { if (getDomain()->hasRegion()) { // core grids only have grid level obstructions if they have a region @@ -1345,11 +1344,11 @@ odb::Rect InstanceGrid::getGridBoundary() const return getDomainBoundary(); } -ShapeTreeMap InstanceGrid::getInstanceObstructions( +ShapeVectorMap InstanceGrid::getInstanceObstructions( odb::dbInst* inst, const InstanceGrid::Halo& halo) { - ShapeTreeMap obs; + ShapeVectorMap obs; const odb::dbTransform transform = inst->getTransform(); @@ -1368,7 +1367,7 @@ ShapeTreeMap InstanceGrid::getInstanceObstructions( transform.apply(obs_rect); auto shape = std::make_shared(layer, obs_rect, Shape::BLOCK_OBS); - obs[layer].insert({shape->getObstructionBox(), shape}); + obs[layer].emplace_back(shape->getObstructionBox(), shape); } // generate obstructions based on pins @@ -1383,16 +1382,16 @@ ShapeTreeMap InstanceGrid::getInstanceObstructions( pin_shape->setRect(applyHalo( pin_shape->getObstruction(), halo, true, is_horizontal, is_vertical)); pin_shape->setObstruction(pin_shape->getRect()); - obs[layer].insert({pin_shape->getObstructionBox(), pin_shape}); + obs[layer].emplace_back(pin_shape->getObstructionBox(), pin_shape); } } return obs; } -void InstanceGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const +void InstanceGrid::getGridLevelObstructions(ShapeVectorMap& obstructions) const { - ShapeTreeMap local_obs; + ShapeVectorMap local_obs; Grid::getGridLevelObstructions(local_obs); const odb::Rect inst_box = getGridArea(); @@ -1400,24 +1399,25 @@ void InstanceGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const // copy layer obs for (const auto& [layer, shapes] : local_obs) { auto obs = std::make_shared(layer, inst_box, this); - local_obs[layer].insert({obs->getObstructionBox(), obs}); + local_obs[layer].emplace_back(obs->getObstructionBox(), obs); } // copy instance obstructions for (const auto& [layer, shapes] : getInstanceObstructions(inst_, halos_)) { for (const auto& [box, shape] : shapes) { auto obs = std::make_shared(layer, shape->getRect(), this); - local_obs[layer].insert({box, obs}); + local_obs[layer].emplace_back(box, obs); } } // merge local and global obs for (const auto& [layer, obs] : local_obs) { - obstructions[layer].insert(obs.begin(), obs.end()); + obstructions[layer].insert( + obstructions[layer].end(), obs.begin(), obs.end()); } } -ShapeTreeMap InstanceGrid::getInstancePins(odb::dbInst* inst) +ShapeVectorMap InstanceGrid::getInstancePins(odb::dbInst* inst) { // add instance pins std::vector pins; @@ -1454,9 +1454,9 @@ ShapeTreeMap InstanceGrid::getInstancePins(odb::dbInst* inst) } } - ShapeTreeMap shapes; + ShapeVectorMap shapes; for (auto& pin : pins) { - shapes[pin->getLayer()].insert({pin->getRectBox(), pin}); + shapes[pin->getLayer()].emplace_back(pin->getRectBox(), pin); } return shapes; @@ -1562,7 +1562,8 @@ bool BumpGrid::isRouted() const { odb::dbNet* net = *getNets(startsWithPower()).begin(); - const auto pins = InstanceGrid::getInstancePins(getInstance()); + auto inst_pins = InstanceGrid::getInstancePins(getInstance()); + const auto pins = Shape::convertVectorToTree(inst_pins); for (auto* swire : net->getSWires()) { for (auto* sbox : swire->getWires()) { @@ -1660,15 +1661,20 @@ ExistingGrid::ExistingGrid( void ExistingGrid::populate() { - Grid::makeInitialShapes(domain_->getBlock(), shapes_, getLogger()); + ShapeVectorMap shapes; + Grid::makeInitialShapes(domain_->getBlock(), shapes, getLogger()); for (auto* inst : getBlock()->getInsts()) { if (inst->getPlacementStatus().isFixed()) { - for (const auto& [layer, shapes] : InstanceGrid::getInstancePins(inst)) { - shapes_[layer].insert(shapes.begin(), shapes.end()); + for (const auto& [layer, inst_shapes] : + InstanceGrid::getInstancePins(inst)) { + shapes[layer].insert( + shapes[layer].end(), inst_shapes.begin(), inst_shapes.end()); } } } + + shapes_ = Shape::convertVectorToTree(shapes); } void ExistingGrid::addRing(std::unique_ptr ring) diff --git a/src/pdn/src/grid.h b/src/pdn/src/grid.h index ac701995f00..0e499c2cda6 100644 --- a/src/pdn/src/grid.h +++ b/src/pdn/src/grid.h @@ -169,7 +169,7 @@ class Grid // returns the obstructions the other grids should be aware of, // such as the outline of an instance or layers in use - virtual void getGridLevelObstructions(ShapeTreeMap& obstructions) const; + virtual void getGridLevelObstructions(ShapeVectorMap& obstructions) const; void getObstructions(ShapeTreeMap& obstructions) const; void resetShapes(); @@ -180,11 +180,11 @@ class Grid void makeRoutingObstructions(odb::dbBlock* block) const; static void makeInitialObstructions(odb::dbBlock* block, - ShapeTreeMap& obs, + ShapeVectorMap& obs, const std::set& skip_insts, utl::Logger* logger); static void makeInitialShapes(odb::dbBlock* block, - ShapeTreeMap& shapes, + ShapeVectorMap& shapes, utl::Logger* logger); virtual bool isReplaceable() const { return false; } @@ -246,7 +246,7 @@ class CoreGrid : public Grid void setupDirectConnect( const std::vector& connect_pad_layers); - void getGridLevelObstructions(ShapeTreeMap& obstructions) const override; + void getGridLevelObstructions(ShapeVectorMap& obstructions) const override; protected: void cleanupShapes() override; @@ -280,16 +280,17 @@ class InstanceGrid : public Grid odb::Rect getDomainBoundary() const override; odb::Rect getGridBoundary() const override; - void getGridLevelObstructions(ShapeTreeMap& obstructions) const override; + void getGridLevelObstructions(ShapeVectorMap& obstructions) const override; void setReplaceable(bool replaceable) { replaceable_ = replaceable; } bool isReplaceable() const override { return replaceable_; } virtual bool isValid() const; - static ShapeTreeMap getInstanceObstructions(odb::dbInst* inst, - const Halo& halo = {0, 0, 0, 0}); - static ShapeTreeMap getInstancePins(odb::dbInst* inst); + static ShapeVectorMap getInstanceObstructions(odb::dbInst* inst, + const Halo& halo + = {0, 0, 0, 0}); + static ShapeVectorMap getInstancePins(odb::dbInst* inst); protected: // find all intersections that also overlap with the power/ground pins based diff --git a/src/pdn/src/renderer.cpp b/src/pdn/src/renderer.cpp index 069f04975d3..06be6acb2af 100644 --- a/src/pdn/src/renderer.cpp +++ b/src/pdn/src/renderer.cpp @@ -74,32 +74,26 @@ void PDNRenderer::update() vias_.clear(); repair_.clear(); + ShapeVectorMap shapes; + ShapeVectorMap obs; + std::vector vias; for (const auto& domain : pdn_->getDomains()) { for (auto* net : domain->getBlock()->getNets()) { - ShapeTreeMap net_shapes; - Shape::populateMapFromDb(net, net_shapes); - for (const auto& [layer, net_obs_layer] : net_shapes) { - auto& obs_layer = grid_obstructions_[layer]; - for (const auto& [box, shape] : net_obs_layer) { - obs_layer.insert({shape->getObstructionBox(), shape}); - } - } + Shape::populateMapFromDb(net, obs); } for (const auto& grid : domain->getGrids()) { - grid->getGridLevelObstructions(grid_obstructions_); + grid->getGridLevelObstructions(obs); - for (const auto& [layer, shapes] : grid->getShapes()) { - auto& save_shapes = shapes_[layer]; - for (const auto& shape : shapes) { - save_shapes.insert(shape); - } + for (const auto& [layer, grid_shapes] : grid->getShapes()) { + shapes[layer].insert( + shapes[layer].end(), grid_shapes.begin(), grid_shapes.end()); } - std::vector vias; - grid->getVias(vias); - for (const auto& via : vias) { - vias_.insert({via->getBox(), via}); + std::vector grid_vias; + grid->getVias(grid_vias); + for (auto& via : grid_vias) { + vias.emplace_back(via->getBox(), via); } for (const auto& repair : @@ -125,6 +119,11 @@ void PDNRenderer::update() } } + shapes_ = Shape::convertVectorToTree(shapes); + grid_obstructions_ = Shape::convertVectorToTree(obs); + shapes_ = Shape::convertVectorToTree(shapes); + vias_ = Shape::convertVectorToTree(vias); + redraw(); } diff --git a/src/pdn/src/shape.cpp b/src/pdn/src/shape.cpp index 538428e1192..f6e3d922a63 100644 --- a/src/pdn/src/shape.cpp +++ b/src/pdn/src/shape.cpp @@ -208,7 +208,7 @@ void Shape::updateTermConnections() bool Shape::hasTermConnections() const { - return !bterm_connections_.empty() || !iterm_connections_.empty(); + return hasITermConnections() || hasBTermConnections(); } odb::Rect Shape::getMinimumRect() const @@ -399,8 +399,20 @@ void Shape::writeToDb(odb::dbSWire* swire, if (make_rect_as_pin) { addBPinToDb(rect_); } + const odb::Rect block_area = getGridComponent()->getBlock()->getDieArea(); for (const auto& bterm : bterm_connections_) { - addBPinToDb(bterm); + odb::Rect bterm_shape = bterm; + // Adjust width of shape when bterm is on the edge of the die area + if (bterm.xMin() == block_area.xMin() + || bterm.xMax() == block_area.xMax()) { + bterm_shape.set_ylo(rect_.yMin()); + bterm_shape.set_yhi(rect_.yMax()); + } else if (bterm.yMin() == block_area.yMin() + || bterm.yMax() == block_area.yMax()) { + bterm_shape.set_xlo(rect_.xMin()); + bterm_shape.set_xhi(rect_.xMax()); + } + addBPinToDb(bterm_shape); } } } @@ -444,7 +456,7 @@ void Shape::addBPinToDb(const odb::Rect& rect) const pin->setPlacementStatus(odb::dbPlacementStatus::FIRM); } -void Shape::populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map) +void Shape::populateMapFromDb(odb::dbNet* net, ShapeVectorMap& map) { for (auto* swire : net->getSWires()) { for (auto* box : swire->getWires()) { @@ -464,7 +476,7 @@ void Shape::populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map) shape->setShapeType(Shape::OBS); } shape->generateObstruction(); - map[layer].insert({shape->getRectBox(), shape}); + map[layer].emplace_back(shape->getRectBox(), shape); } } } @@ -617,6 +629,29 @@ Shape* Shape::extendTo( return new_shape.release(); } +ShapeTreeMap Shape::convertVectorToTree(ShapeVectorMap& vec) +{ + ShapeTreeMap trees; + + for (auto& [layer, vals] : vec) { + trees[layer] = ShapeTree(vals.begin(), vals.end()); + } + + ShapeVectorMap empty; + vec.swap(empty); + + return trees; +} + +ViaTree Shape::convertVectorToTree(std::vector& vec) +{ + ViaTree tree(vec.begin(), vec.end()); + + vec = std::vector(); + + return tree; +} + ///////// FollowPinShape::FollowPinShape(odb::dbTechLayer* layer, diff --git a/src/pdn/src/shape.h b/src/pdn/src/shape.h index be3d6c6cd15..bed62198d89 100644 --- a/src/pdn/src/shape.h +++ b/src/pdn/src/shape.h @@ -77,6 +77,7 @@ using ViaValue = std::pair; using ShapeTree = bgi::rtree>; using ViaTree = bgi::rtree>; using ShapeTreeMap = std::map; +using ShapeVectorMap = std::map>; class Grid; class GridComponent; @@ -183,6 +184,8 @@ class Shape // connected virtual void updateTermConnections(); bool hasTermConnections() const; + bool hasITermConnections() const { return !iterm_connections_.empty(); } + bool hasBTermConnections() const { return !bterm_connections_.empty(); }; // returns the smallest shape possible when attempting to trim virtual odb::Rect getMinimumRect() const; @@ -221,7 +224,7 @@ class Shape bool add_pins, bool make_rect_as_pin) const; // copy existing shapes into the map - static void populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map); + static void populateMapFromDb(odb::dbNet* net, ShapeVectorMap& map); static Box rectToBox(const odb::Rect& rect); @@ -234,6 +237,9 @@ class Shape allow_non_preferred_change_ = true; } + static ShapeTreeMap convertVectorToTree(ShapeVectorMap& vec); + static ViaTree convertVectorToTree(std::vector& vec); + protected: bool cut(const ShapeTree& obstructions, std::vector& replacements, diff --git a/src/pdn/src/sroute.cpp b/src/pdn/src/sroute.cpp index 998cda564ee..dea8bdf9a87 100644 --- a/src/pdn/src/sroute.cpp +++ b/src/pdn/src/sroute.cpp @@ -666,15 +666,10 @@ void SRoute::createSrouteWires( auto domains = getDomains(); // collect the the SWires from the block - ShapeTreeMap obstructions; - ShapeTreeMap net_shapes; - Shape::populateMapFromDb(net, net_shapes); - for (const auto& [layer, net_obs_layer] : net_shapes) { - auto& obs_layer = obstructions[layer]; - for (const auto& [box, shape] : net_obs_layer) { - obs_layer.insert({shape->getObstructionBox(), shape}); - } - } + ShapeVectorMap obstructions_vec; + Shape::populateMapFromDb(net, obstructions_vec); + const ShapeTreeMap obstructions + = Shape::convertVectorToTree(obstructions_vec); for (auto* domain : domains) { for (const auto& grid : domain->getGrids()) { diff --git a/src/pdn/test/CMakeLists.txt b/src/pdn/test/CMakeLists.txt new file mode 100644 index 00000000000..eb53ff631af --- /dev/null +++ b/src/pdn/test/CMakeLists.txt @@ -0,0 +1,99 @@ +include("openroad") + +set(TEST_NAMES + reset + report + ripup + convert + names + min_width + max_width + min_spacing + widthtable + design_width + offgrid + core_grid + core_grid_with_rings + core_grid_start_power + core_grid_start_power_strap_ground + core_grid_with_rings_with_straps + core_grid_dual_followpins + core_grid_dual_followpins_error + core_grid_with_dual_rings + core_grid_with_rings_connect + core_grid_cut_pitch + core_grid_snap + core_grid_via_snap + core_grid_split_cuts + core_grid_with_rings_with_straps_rings_over_core + core_grid_with_routing_obstructions + core_grid_adjacentcuts + core_grid_obstruction + core_grid_auto_domain + core_grid_auto_domain_multiple_nets + core_grid_extend_to_boundary + core_grid_extend_to_boundary_no_pins + core_grid_with_M7_pins + core_grid_with_M6_min_area + core_grid_strap_count + core_grid_no_trim + core_grid_offset_strap + core_grid_with_rings_with_limit_straps + core_grid_failed_via_report + macros + macros_with_halo + macros_cells + macros_cells_orient + macros_with_rings + macros_narrow_channel + macros_narrow_channel_large_spacing + macros_narrow_channel_repair_overlap + macros_add_twice + macros_cells_extend_boundary + macros_cells_no_grid + macros_narrow_channel_jog + macros_different_nets + macros_grid_through + macros_grid_through_without_middle + macros_cells_dont_touch + macros_cells_overlapping_ports + macros_cells_not_fixed + macros_cells_via_failure + region_temp_sensor + region_secondary_nets + region_non_rect + pads_black_parrot + pads_black_parrot_offset + pads_black_parrot_no_connect + pads_black_parrot_limit_connect + pads_black_parrot_flipchip + pads_black_parrot_flipchip_connect_bumps + pads_black_parrot_flipchip_connect_overpads + pads_black_parrot_max_width + asap7_vias + asap7_vias_cutclass + asap7_no_via_generate + asap7_vias_arrayspacing + asap7_vias_arrayspacing_notfirst + asap7_vias_arrayspacing_partial + asap7_vias_arrayspacing_3_layer + asap7_vias_max_rows_columns + asap7_vias_dont_use + asap7_taper + asap7_offcenter_via + asap7_no_via_generate_v1_snapped + asap7_failed_macro_grid + asap7_vias_fixed_vias + existing + power_switch + power_switch_star + power_switch_daisy + power_switch_regions + power_switch_cut_rows + repair_vias + sroute_test +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("pdn" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/pdn/test/core_grid_extend_to_boundary.defok b/src/pdn/test/core_grid_extend_to_boundary.defok index cd7626f7b94..2420d424687 100644 --- a/src/pdn/test/core_grid_extend_to_boundary.defok +++ b/src/pdn/test/core_grid_extend_to_boundary.defok @@ -83,8 +83,8 @@ VIAS 6 ; - via2_3_4000_340_1_12_320_320 + VIARULE Via2Array-0 + CUTSIZE 140 140 + LAYERS metal2 via2 metal3 + CUTSPACING 180 180 + ENCLOSURE 70 70 70 70 + ROWCOL 1 12 ; - via3_4_4000_340_1_12_320_320 + VIARULE Via3Array-0 + CUTSIZE 140 140 + LAYERS metal3 via3 metal4 + CUTSPACING 180 180 + ENCLOSURE 70 70 70 70 + ROWCOL 1 12 ; - via4_5_4000_340_1_7_600_600 + VIARULE Via4Array-0 + CUTSIZE 280 280 + LAYERS metal4 via4 metal5 + CUTSPACING 320 320 + ENCLOSURE 0 0 0 0 + ROWCOL 1 7 ; - - via5_6_4000_340_1_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 0 60 30 + ROWCOL 1 7 ; - - via5_6_4000_4000_7_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 60 60 60 60 + ROWCOL 7 7 ; + - via5_6_4000_340_1_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 0 60 0 + ROWCOL 1 7 ; + - via5_6_4000_4000_7_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 60 60 0 + ROWCOL 7 7 ; END VIAS COMPONENTS 482 ; - PHY_1 FILLCELL_X1 + SOURCE DIST + FIXED ( 100320 22400 ) FS ; diff --git a/src/pdn/test/core_grid_extend_to_boundary_no_pins.defok b/src/pdn/test/core_grid_extend_to_boundary_no_pins.defok index 990c842bf45..ec56fe0ae0f 100644 --- a/src/pdn/test/core_grid_extend_to_boundary_no_pins.defok +++ b/src/pdn/test/core_grid_extend_to_boundary_no_pins.defok @@ -83,8 +83,8 @@ VIAS 6 ; - via2_3_4000_340_1_12_320_320 + VIARULE Via2Array-0 + CUTSIZE 140 140 + LAYERS metal2 via2 metal3 + CUTSPACING 180 180 + ENCLOSURE 70 70 70 70 + ROWCOL 1 12 ; - via3_4_4000_340_1_12_320_320 + VIARULE Via3Array-0 + CUTSIZE 140 140 + LAYERS metal3 via3 metal4 + CUTSPACING 180 180 + ENCLOSURE 70 70 70 70 + ROWCOL 1 12 ; - via4_5_4000_340_1_7_600_600 + VIARULE Via4Array-0 + CUTSIZE 280 280 + LAYERS metal4 via4 metal5 + CUTSPACING 320 320 + ENCLOSURE 0 0 0 0 + ROWCOL 1 7 ; - - via5_6_4000_340_1_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 0 60 30 + ROWCOL 1 7 ; - - via5_6_4000_4000_7_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 60 60 60 60 + ROWCOL 7 7 ; + - via5_6_4000_340_1_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 0 60 0 + ROWCOL 1 7 ; + - via5_6_4000_4000_7_7_600_600 + VIARULE Via5Array-0 + CUTSIZE 280 280 + LAYERS metal5 via5 metal6 + CUTSPACING 320 320 + ENCLOSURE 0 60 60 0 + ROWCOL 7 7 ; END VIAS COMPONENTS 482 ; - PHY_1 FILLCELL_X1 + SOURCE DIST + FIXED ( 100320 22400 ) FS ; diff --git a/src/pdn/test/core_grid_with_rings_connect.tcl b/src/pdn/test/core_grid_with_rings_connect.tcl index b01b3710b66..f0639ed2698 100644 --- a/src/pdn/test/core_grid_with_rings_connect.tcl +++ b/src/pdn/test/core_grid_with_rings_connect.tcl @@ -19,6 +19,6 @@ add_pdn_connect -layers {metal1 metal6} pdngen -set def_file [make_result_file core_grid_with_rings.def] +set def_file [make_result_file core_grid_with_rings_connect.def] write_def $def_file diff_files core_grid_with_rings.defok $def_file diff --git a/src/pdn/test/macros_cells_via_failure.tcl b/src/pdn/test/macros_cells_via_failure.tcl index eb6400aaabb..07fe72693cd 100644 --- a/src/pdn/test/macros_cells_via_failure.tcl +++ b/src/pdn/test/macros_cells_via_failure.tcl @@ -49,7 +49,8 @@ add_pdn_stripe -grid {CORE_macro_grid_2} -layer {metal6} -width {0.93} -pitch {4 add_pdn_connect -grid {CORE_macro_grid_2} -layers {metal4 metal6} add_pdn_connect -grid {CORE_macro_grid_2} -layers {metal6 metal7} -pdngen -failed_via_report test.rpt +set rpt_file [make_result_file macros_cells_via_failure_test.rpt] +pdngen -failed_via_report $rpt_file set def_file [make_result_file macros_cells_via_failure.def] write_def $def_file diff --git a/src/ppl/CMakeLists.txt b/src/ppl/CMakeLists.txt index 1d5c42c955e..97a94fdb378 100644 --- a/src/ppl/CMakeLists.txt +++ b/src/ppl/CMakeLists.txt @@ -99,3 +99,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/ppl/test/CMakeLists.txt b/src/ppl/test/CMakeLists.txt new file mode 100644 index 00000000000..912f2e615ad --- /dev/null +++ b/src/ppl/test/CMakeLists.txt @@ -0,0 +1,120 @@ +include("openroad") + +set(TEST_NAMES + add_constraint_debug + add_constraint1 + add_constraint2 + add_constraint3 + add_constraint4 + add_constraint5 + add_constraint6 + add_constraint7 + add_constraint8 + add_constraint9 + add_constraint10 + add_constraint11 + add_constraint12 + add_constraint13 + add_constraint14 + add_constraint15 + add_constraint16 + add_constraint_error1 + add_constraint_error2 + add_constraint_error3 + add_constraint_error4 + add_constraint_error5 + add_constraint_error6 + add_constraint_error7 + annealing1 + annealing2 + annealing3 + annealing4 + annealing_constraint1 + annealing_constraint2 + annealing_constraint3 + annealing_constraint4 + annealing_constraint5 + annealing_constraint6 + annealing_constraint7 + annealing_constraint8 + annealing_large_groups1 + annealing_large_groups2 + annealing_mirrored1 + annealing_mirrored2 + annealing_mirrored3 + annealing_mirrored4 + annealing_mirrored5 + blocked_region + cells_not_placed + exclude1 + exclude2 + exclude3 + gcd + group_pins1 + group_pins2 + group_pins3 + group_pins4 + group_pins5 + group_pins6 + group_pins7 + group_pins8 + group_pins9 + group_pins10 + group_pins_error1 + group_pins_warn1 + invalid_layer + large_groups1 + large_groups2 + large_groups3 + large_groups4 + macro_not_placed + macro_not_placed_random + min_dist_in_tracks1 + min_dist_in_tracks2 + multi_layers + multiple_calls + no_instance_pins + no_pins + no_tracks + on_grid + pin_length + pin_length_error + pin_extension + pin_thick_multiplier + place_pin1 + place_pin2 + place_pin3 + place_pin4 + place_pin5 + place_pin6 + place_pin7 + place_pin_error1 + place_pin_error2 + place_pin_error3 + random1 + random2 + random3 + random4 + random5 + random6 + random7 + random8 + random9 + top_layer1 + top_layer2 + top_layer3 + top_layer4 + top_layer5 + top_layer6 + top_layer7 + top_layer_error + top_layer_error2 + write_pin_placement1 + write_pin_placement2 + write_pin_placement3 + write_pin_placement4 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("ppl" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/psm/CMakeLists.txt b/src/psm/CMakeLists.txt index ac311bb40ce..950e20afd0d 100644 --- a/src/psm/CMakeLists.txt +++ b/src/psm/CMakeLists.txt @@ -30,3 +30,4 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/psm/test/CMakeLists.txt b/src/psm/test/CMakeLists.txt new file mode 100644 index 00000000000..cc9492b5d0c --- /dev/null +++ b/src/psm/test/CMakeLists.txt @@ -0,0 +1,32 @@ +include("openroad") + +set(TEST_NAMES + aes_test_vdd + aes_test_vdd_set_node_density + aes_test_vdd_set_node_density_fact + aes_test_vss + gcd_test_vdd + gcd_no_vsrc + gcd_write_sp_test_vdd + gcd_em_test_vdd + gcd_all_vss + gcd_vss_no_vsrc + gcd_sky130_vdd + aes_asap7_vdd + check_power_grid + check_power_grid_disconnected + check_power_grid_ok_disconnected + check_power_grid_macros + check_power_grid_disconnected_macro + corners + aes_test_bterms + aes_test_multiple_bterms + zerosoc_pads + zerosoc_pads_check_only + zerosoc_pads_check_only_disconnected + pad_connected_by_abutment +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("psm" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() diff --git a/src/rcx/CMakeLists.txt b/src/rcx/CMakeLists.txt index 2824ff8c8dd..346aeb71584 100644 --- a/src/rcx/CMakeLists.txt +++ b/src/rcx/CMakeLists.txt @@ -35,3 +35,5 @@ project(OpenRCX VERSION 0.0.1 LANGUAGES CXX) add_subdirectory(src) +add_subdirectory(test) + diff --git a/src/rcx/test/CMakeLists.txt b/src/rcx/test/CMakeLists.txt new file mode 100644 index 00000000000..c503d9e70fb --- /dev/null +++ b/src/rcx/test/CMakeLists.txt @@ -0,0 +1,13 @@ +include("openroad") + +set(TEST_NAMES + generate_pattern + ext_pattern + gcd + 45_gcd + names +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("rcx" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/rmp/CMakeLists.txt b/src/rmp/CMakeLists.txt index 89d322ee53d..9f8a240b934 100644 --- a/src/rmp/CMakeLists.txt +++ b/src/rmp/CMakeLists.txt @@ -34,3 +34,4 @@ ############################################################################### add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/rmp/test/CMakeLists.txt b/src/rmp/test/CMakeLists.txt new file mode 100644 index 00000000000..c420457d9df --- /dev/null +++ b/src/rmp/test/CMakeLists.txt @@ -0,0 +1,18 @@ +include("openroad") + +set(TEST_NAMES + gcd_restructure + const_cell_removal + blif_writer + blif_writer_input_output + blif_writer_consts + blif_writer_hanging + blif_writer_sequential + blif_reader + blif_reader_const + blif_reader_sequential +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("rmp" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/rsz/CMakeLists.txt b/src/rsz/CMakeLists.txt index 84335f37c92..a2117215a10 100644 --- a/src/rsz/CMakeLists.txt +++ b/src/rsz/CMakeLists.txt @@ -34,3 +34,4 @@ ############################################################################### add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/rsz/test/CMakeLists.txt b/src/rsz/test/CMakeLists.txt new file mode 100644 index 00000000000..761008eb2a4 --- /dev/null +++ b/src/rsz/test/CMakeLists.txt @@ -0,0 +1,118 @@ +include("openroad") + +set(TEST_NAMES + buffer_ports1 + buffer_ports3 + buffer_ports4 + buffer_ports5 + buffer_ports6 + buffer_ports7 + buffer_ports8 + buffer_varying_lengths + eqy_repair_setup2 + eqy_repair_setup5 + fanin_fanout1 + make_parasitics1 + make_parasitics2 + make_parasitics3 + make_parasitics4 + make_parasitics5 + make_parasitics6 + pin_swap1 + resize1 + resize4 + resize5 + resize6 + resize_slack1 + resize_slack2 + resize_slack3 + remove_buffers1 + remove_buffers2 + repair_clk_nets1 + repair_clk_inverters1 + repair_cap1 + repair_cap2 + repair_cap3 + repair_design1 + repair_design2 + repair_design3 + repair_design4 + repair_design5 + repair_fanout1 + repair_fanout2 + repair_fanout3 + repair_fanout4 + repair_fanout5 + repair_fanout6 + repair_fanout7 + repair_fanout8 + repair_hold1 + repair_hold2 + repair_hold3 + repair_hold4 + repair_hold5 + repair_hold6 + repair_hold7 + repair_hold8 + repair_hold9 + repair_hold10 + repair_hold11 + repair_hold12 + repair_hold13 + repair_hold14 + repair_setup1 + repair_setup2 + repair_setup3 + repair_setup4 + repair_setup5 + repair_setup6 + repair_slew1 + repair_slew2 + repair_slew3 + repair_slew4 + repair_slew5 + repair_slew6 + repair_slew7 + repair_slew8 + repair_slew9 + repair_slew10 + repair_slew11 + repair_slew12 + repair_slew13 + repair_slew14 + repair_slew15 + repair_slew16 + repair_slew17 + report_floating_nets1 + report_floating_nets2 + report_floating_nets3 + repair_tie1 + repair_tie2 + repair_tie3 + repair_tie4 + repair_tie5 + repair_tie6 + repair_tie7 + repair_tie8 + repair_wire1 + repair_wire2 + repair_wire3 + repair_wire4 + repair_wire5 + repair_wire6 + repair_wire7 + repair_wire8 + repair_wire9 + repair_wire10 + repair_wire11 + gcd_resize + repair_design3_verbose + repair_setup4_verbose + repair_hold9_verbose + set_dont_touch1 + set_dont_use1 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("rsz" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/stt/CMakeLists.txt b/src/stt/CMakeLists.txt index 8c51043ae4d..9664a6297e2 100644 --- a/src/stt/CMakeLists.txt +++ b/src/stt/CMakeLists.txt @@ -126,3 +126,5 @@ if (Python3_FOUND AND BUILD_PYTHON) ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/stt/test/CMakeLists.txt b/src/stt/test/CMakeLists.txt new file mode 100644 index 00000000000..19dc39e808c --- /dev/null +++ b/src/stt/test/CMakeLists.txt @@ -0,0 +1,15 @@ +include("openroad") + +set(TEST_NAMES + flute1 + flute_gcd + check + parse_clocks + pd1 + pd2 + pd_gcd +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("stt" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/tap/CMakeLists.txt b/src/tap/CMakeLists.txt index 51490fcf276..4411cf92e2e 100644 --- a/src/tap/CMakeLists.txt +++ b/src/tap/CMakeLists.txt @@ -33,4 +33,5 @@ ## POSSIBILITY OF SUCH DAMAGE. ################################################################################ -add_subdirectory(src) \ No newline at end of file +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/tap/test/CMakeLists.txt b/src/tap/test/CMakeLists.txt new file mode 100644 index 00000000000..6ddddaa41f0 --- /dev/null +++ b/src/tap/test/CMakeLists.txt @@ -0,0 +1,29 @@ +include("openroad") + +set(TEST_NAMES + disallow_one_site_gaps + gcd_fakeram + gcd_nangate45 + gcd_sky130 + gcd_asap7 + invalid_cells + multiple_calls + avoid_overlap + boundary_macros + gcd_prefix + gcd_ripup + no_endcap + symmetry + cut_rows + cut_rows_with_endcaps + boundary_macros_separate + boundary_macros_auto_select + boundary_macros_tapcell + gcd_sky130_separate + jpeg_gf180 + aes_gf180 +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("tap" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/upf/CMakeLists.txt b/src/upf/CMakeLists.txt index ed491fa4d90..95d7593beec 100644 --- a/src/upf/CMakeLists.txt +++ b/src/upf/CMakeLists.txt @@ -29,4 +29,5 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -add_subdirectory(src) \ No newline at end of file +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/src/upf/test/CMakeLists.txt b/src/upf/test/CMakeLists.txt new file mode 100644 index 00000000000..ef6120f8f1b --- /dev/null +++ b/src/upf/test/CMakeLists.txt @@ -0,0 +1,10 @@ +include("openroad") + +set(TEST_NAMES + upf_test + levelshifter +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("upf" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/src/utl/CMakeLists.txt b/src/utl/CMakeLists.txt index 162e96e3252..be9a032e21e 100644 --- a/src/utl/CMakeLists.txt +++ b/src/utl/CMakeLists.txt @@ -131,3 +131,5 @@ if(ENABLE_TESTS) utl ) endif() + +add_subdirectory(test) \ No newline at end of file diff --git a/src/utl/test/CMakeLists.txt b/src/utl/test/CMakeLists.txt new file mode 100644 index 00000000000..32edda1791f --- /dev/null +++ b/src/utl/test/CMakeLists.txt @@ -0,0 +1,12 @@ +include("openroad") + +set(TEST_NAMES +test_info + test_error + test_suppress_message + test_metrics +) + +foreach(TEST_NAME IN LISTS TEST_NAMES) + or_integration_test("utl" ${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/regression) +endforeach() \ No newline at end of file diff --git a/test/aes_sky130hs.metrics b/test/aes_sky130hs.metrics index f31c7f26c1f..2926331164f 100644 --- a/test/aes_sky130hs.metrics +++ b/test/aes_sky130hs.metrics @@ -8,62 +8,60 @@ "design__instance__displacement__max": 17.474, "route__wirelength__estimated": 1.3173e+06, "RSZ::repair_design_buffer_count": "518", - "RSZ::max_slew_slack": "19.69558447599411", + "RSZ::max_slew_slack": "19.68039721250534", "RSZ::max_fanout_slack": "100.0", "RSZ::max_capacitance_slack": "56.280056146899526", - "design__instance__displacement__total": 213.084, + "design__instance__displacement__total": 208.702, "design__instance__displacement__mean": 0.004, "design__instance__displacement__max": 5.928, - "route__wirelength__estimated": 1.33444e+06, - "design__instance__count__setup_buffer": 841, - "design__instance__count__hold_buffer": 630, - "RSZ::worst_slack_min": "0.0005018208213230328", - "RSZ::worst_slack_max": "-0.6879021991187272", - "RSZ::tns_max": "-97.86111398227129", - "RSZ::hold_buffer_count": "630", - "design__instance__displacement__total": 7598.82, - "design__instance__displacement__mean": 0.155, - "design__instance__displacement__max": 16.235, - "route__wirelength__estimated": 1.3884e+06, + "route__wirelength__estimated": 1.33431e+06, + "design__instance__count__setup_buffer": 846, + "design__instance__count__hold_buffer": 601, + "RSZ::worst_slack_min": "0.0005530021042057581", + "RSZ::worst_slack_max": "-0.6879061959217289", + "RSZ::tns_max": "-98.9044039106941", + "RSZ::hold_buffer_count": "601", + "design__instance__displacement__total": 7480.57, + "design__instance__displacement__mean": 0.153, + "design__instance__displacement__max": 17.25, + "route__wirelength__estimated": 1.38716e+06, "DPL::utilization": "10.2", - "DPL::design_area": "307836", - "route__net": 16603, + "DPL::design_area": "307348", + "route__net": 16579, "route__net__special": 2, "antenna__violating__nets": 0, "antenna__violating__pins": 0, "GRT::ANT::errors": "0", "design__violations": 0, - "route__net": 16603, + "route__net": 16579, "route__net__special": 2, - "route__drc_errors__iter:1": 13659, - "route__wirelength__iter:1": 1712986, - "route__drc_errors__iter:2": 3067, - "route__wirelength__iter:2": 1707016, - "route__drc_errors__iter:3": 2467, - "route__wirelength__iter:3": 1703968, - "route__drc_errors__iter:4": 61, - "route__wirelength__iter:4": 1704367, - "route__drc_errors__iter:5": 1, - "route__wirelength__iter:5": 1704356, - "route__drc_errors__iter:6": 0, - "route__wirelength__iter:6": 1704359, + "route__drc_errors__iter:1": 11079, + "route__wirelength__iter:1": 1706754, + "route__drc_errors__iter:2": 1570, + "route__wirelength__iter:2": 1700615, + "route__drc_errors__iter:3": 1213, + "route__wirelength__iter:3": 1697715, + "route__drc_errors__iter:4": 10, + "route__wirelength__iter:4": 1697727, + "route__drc_errors__iter:5": 0, + "route__wirelength__iter:5": 1697713, "route__drc_errors": 0, - "route__wirelength": 1704359, - "route__vias": 149586, - "route__vias__singlecut": 149586, + "route__wirelength": 1697713, + "route__vias": 149601, + "route__vias__singlecut": 149601, "route__vias__multicut": 0, "DRT::drv": "0", - "antenna__violating__nets": 111, - "antenna__violating__pins": 112, - "DRT::ANT::errors": "111", + "antenna__violating__nets": 109, + "antenna__violating__pins": 109, + "DRT::ANT::errors": "109", "timing__drv__floating__nets": 0, "timing__drv__floating__pins": 0, - "DRT::worst_slack_min": "-0.21183999598543343", - "DRT::worst_slack_max": "-1.0203118638768833", - "DRT::tns_max": "-136.2589795118327", - "DRT::clock_skew": "0.5525905445188898", - "DRT::max_slew_slack": "-8.156697452068329", + "DRT::worst_slack_min": "-0.1664590734589077", + "DRT::worst_slack_max": "-0.9967604801448263", + "DRT::tns_max": "-134.4156326511716", + "DRT::clock_skew": "0.5093865473606167", + "DRT::max_slew_slack": "-10.26289090514183", "DRT::max_fanout_slack": "100.0", - "DRT::max_capacitance_slack": "-10.2105758345311", + "DRT::max_capacitance_slack": "-12.415987695807061", "DRT::clock_period": "2.811000" } \ No newline at end of file diff --git a/test/aes_sky130hs.metrics_limits b/test/aes_sky130hs.metrics_limits index df2c6511190..3448fbe80f9 100644 --- a/test/aes_sky130hs.metrics_limits +++ b/test/aes_sky130hs.metrics_limits @@ -1,23 +1,23 @@ { "IFP::instance_count" : "19588.8" - ,"DPL::design_area" : "369403.2" + ,"DPL::design_area" : "368817.6" ,"DPL::utilization" : "12.239999999999998" ,"RSZ::repair_design_buffer_count" : "621" ,"RSZ::max_slew_slack" : "0" ,"RSZ::max_capacitance_slack" : "0" ,"RSZ::max_fanout_slack" : "0" - ,"RSZ::worst_slack_min" : "-0.28059817917867697" - ,"RSZ::worst_slack_max" : "-0.9690021991187272" - ,"RSZ::tns_max" : "-556.7287539822713" - ,"RSZ::hold_buffer_count" : "756" + ,"RSZ::worst_slack_min" : "-0.28054699789579424" + ,"RSZ::worst_slack_max" : "-0.9690061959217289" + ,"RSZ::tns_max" : "-557.7720439106942" + ,"RSZ::hold_buffer_count" : "721" ,"GRT::ANT::errors" : "0" ,"DRT::drv" : "0" - ,"DRT::worst_slack_min" : "-0.4929399959854335" - ,"DRT::worst_slack_max" : "-1.3014118638768832" - ,"DRT::tns_max" : "-595.1266195118328" - ,"DRT::clock_skew" : "0.6631086534226677" - ,"DRT::max_slew_slack" : "-9.788036942481995" - ,"DRT::max_capacitance_slack" : "-12.25269100143732" + ,"DRT::worst_slack_min" : "-0.4475590734589077" + ,"DRT::worst_slack_max" : "-1.2778604801448263" + ,"DRT::tns_max" : "-593.2832726511716" + ,"DRT::clock_skew" : "0.6112638568327401" + ,"DRT::max_slew_slack" : "-12.315469086170197" + ,"DRT::max_capacitance_slack" : "-14.899185234968472" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "2.811" } diff --git a/test/regression_tests.tcl b/test/regression_tests.tcl index 93293693aa7..5b1e1f7049a 100644 --- a/test/regression_tests.tcl +++ b/test/regression_tests.tcl @@ -33,6 +33,3 @@ record_flow_tests { jpeg_sky130hs jpeg_sky130hd } - -# sidelined because drt blows chow - diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index d7cb4712ef7..d22026d1ec8 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -29,6 +29,9 @@ set app_options "-no_init -no_splash -exit" set result_dir [file join $test_dir "results"] # Collective diffs. set diff_file [file join $result_dir "diffs"] +if { [info exist ::env(DIFF_LOCATION)] } { + set diff_file "$::env(DIFF_LOCATION)" +} # File containing list of failed tests. set failure_file [file join $result_dir "failures"] # Use the DIFF_OPTIONS envar to change the diff options @@ -69,6 +72,10 @@ proc record_flow_tests { tests } { proc record_tests1 { tests cmp_logfile } { global test_dir + if { [info exist ::env(CTEST_TESTNAME)]} { + set tests "$::env(CTEST_TESTNAME)" + set cmp_logfile "$::env(TEST_TYPE)" + } foreach test $tests { # Prune commented tests from the list. if { [string index $test 0] != "#" } {