3636#include " utl/CallBackHandler.h"
3737#include " utl/Logger.h"
3838
39+ #include " ../../fastroute/include/FastRoute.h"
40+ #include " ../../fastroute/include/AbstractFastRouteRenderer.h"
41+ #include " ../../fastroute/include/DataType.h"
42+
3943using utl::GRT;
4044
4145namespace grt {
@@ -49,7 +53,8 @@ CUGR::CUGR(odb::dbDatabase* db,
4953 logger_ (log),
5054 callback_handler_(callback_handler),
5155 stt_builder_(stt_builder),
52- sta_(sta)
56+ sta_(sta),
57+ debug_(std::make_unique<DebugSetting>())
5358{
5459}
5560
@@ -159,6 +164,14 @@ void CUGR::patternRoute(std::vector<int>& net_indices)
159164 constants_,
160165 logger_);
161166 pattern_route.constructSteinerTree ();
167+
168+ GRNet* net = gr_nets_[net_index].get ();
169+ if (debug_->isOn () && debug_->steinerTree && net->getDbNet () == debug_->net && pattern_route.hasSttTree ()) {
170+
171+ steinerTreeVisualization (pattern_route.getSttTree (), net);
172+
173+ }
174+
162175 pattern_route.constructRoutingDAG ();
163176 pattern_route.run ();
164177 grid_graph_->addTreeUsage (gr_nets_[net_index]->getRoutingTree ());
@@ -262,6 +275,22 @@ void CUGR::route()
262275 }
263276 }
264277
278+ if (debug_->isOn ()) {
279+ const int x_corner = grid_graph_->getGridline (0 , 0 );
280+ const int y_corner = grid_graph_->getGridline (1 , 0 );
281+ int tile_size = 0 ;
282+ if (grid_graph_->getXSize () > 0 ) {
283+ tile_size = grid_graph_->getGridline (0 , 1 ) - x_corner;
284+ }
285+ if (tile_size <= 0 && grid_graph_->getYSize () > 0 ) {
286+ tile_size = grid_graph_->getGridline (1 , 1 ) - y_corner;
287+ }
288+ if (tile_size <= 0 ) {
289+ tile_size = std::max (1 , grid_graph_->getM2Pitch ());
290+ }
291+ debug_->renderer ->setGridVariables (tile_size, x_corner, y_corner);
292+ }
293+
265294 patternRoute (net_indices);
266295
267296 patternRouteWithDetours (net_indices);
@@ -696,5 +725,123 @@ void CUGR::routeIncremental()
696725
697726 printStatistics ();
698727}
728+ // debug functions
729+ void CUGR::setDebugOn (std::unique_ptr<AbstractFastRouteRenderer> renderer)
730+ {
731+ debug_->renderer = std::move (renderer);
732+ }
733+ void CUGR::setDebugNet (const odb::dbNet* net)
734+ {
735+ debug_->net = net;
736+ }
737+ void CUGR::setDebugSteinerTree (bool steinerTree)
738+ {
739+ debug_->steinerTree = steinerTree;
740+ }
741+ void CUGR::setDebugRectilinearSTree (bool rectilinearSTree)
742+ {
743+ debug_->rectilinearSTree = rectilinearSTree;
744+ }
745+ void CUGR::setDebugTree2D (bool tree2D)
746+ {
747+ debug_->tree2D = tree2D;
748+ }
749+ void CUGR::setDebugTree3D (bool tree3D)
750+ {
751+ debug_->tree3D = tree3D;
752+ }
753+ void CUGR::setSttInputFilename (const char * file_name)
754+ {
755+ debug_->sttInputFileName = std::string (file_name);
756+ }
757+
758+ AbstractFastRouteRenderer* CUGR::getDebugRenderer () const
759+ {
760+ if (debug_ && debug_->renderer ) {
761+ return debug_->renderer .get ();
762+ }
763+ return nullptr ;
764+ }
765+ std::string CUGR::getSttInputFileName ()
766+ {
767+ return debug_->sttInputFileName ;
768+ }
769+ const odb::dbNet* CUGR::getDebugNet ()
770+ {
771+ return debug_->net ;
772+ }
773+ bool CUGR::hasSaveSttInput ()
774+ {
775+ return !debug_->sttInputFileName .empty ();
776+ }
777+
778+ void CUGR::steinerTreeVisualization (const stt::Tree& stree, GRNet* net)
779+ {
780+ if (!debug_->isOn ()) {
781+ return ;
782+ }
783+
784+ // Create FrNet wrapper as renderer expects FrNet*
785+ FrNet frnet;
786+ bool is_clock = (net->getDbNet ()->getSigType () == odb::dbSigType::CLOCK);
787+
788+ frnet.reset (net->getDbNet (),
789+ is_clock,
790+ 0 ,
791+ 0 ,
792+ constants_.min_routing_layer ,
793+ grid_graph_->getNumLayers () - 1 ,
794+ 0.0 ,
795+ nullptr );
796+
797+ FrNetInit (net, &frnet);
798+
799+ debug_->renderer ->highlight (&frnet);
800+ debug_->renderer ->setIs3DVisualization (false );
801+ debug_->renderer ->setSteinerTree (stree);
802+ debug_->renderer ->setTreeStructure (grt::TreeStructure::steinerTreeByStt);
803+ debug_->renderer ->redrawAndPause ();
804+ debug_->renderer ->highlight (nullptr );
805+
806+ }
807+
808+ void CUGR::StTreeVisualization (const StTree& stree, GRNet* net, bool is3DVisualization)
809+ {
810+ if (!debug_->isOn ()) {
811+ return ;
812+ }
813+
814+ // Create FrNet wrapper as renderer expects FrNet*
815+ FrNet frnet;
816+ bool is_clock = (net->getDbNet ()->getSigType () == odb::dbSigType::CLOCK);
817+
818+ frnet.reset (net->getDbNet (),
819+ is_clock,
820+ 0 ,
821+ 0 ,
822+ constants_.min_routing_layer ,
823+ grid_graph_->getNumLayers () - 1 ,
824+ 0.0 ,
825+ nullptr );
826+
827+ FrNetInit (net, &frnet);
828+
829+ debug_->renderer ->highlight (&frnet);
830+ debug_->renderer ->setIs3DVisualization (is3DVisualization);
831+ debug_->renderer ->setStTreeValues (stree);
832+ debug_->renderer ->setTreeStructure (grt::TreeStructure::steinerTreeByFastroute);
833+ debug_->renderer ->redrawAndPause ();
834+ debug_->renderer ->highlight (nullptr );
835+ }
836+
837+ void CUGR::FrNetInit (GRNet* net, FrNet* frnet)
838+ {
839+ for (const auto & pin_aps : net->getPinAccessPoints ()) {
840+ if (!pin_aps.empty ()) {
841+ const auto & ap = pin_aps[0 ];
842+ frnet->addPin (ap.x (), ap.y (), ap.getLayerIdx ());
843+ }
844+ }
845+ }
699846
700847} // namespace grt
0 commit comments