@@ -916,19 +916,47 @@ struct NexusPacker
916
916
{
917
917
// Keep running until we reach a fixed point
918
918
log_info (" Placing globals...\n " );
919
- bool did_something = true ;
920
- while (did_something) {
921
- did_something = false ;
922
- for (auto &cell : ctx->cells ) {
923
- CellInfo *ci = cell.second .get ();
924
- if (ci->type == id_OSC_CORE)
925
- did_something |= preplace_singleton (ci);
926
- else if (ci->type == id_DCC)
927
- did_something |= preplace_prim (ci, id_CLKI, false );
928
- else if (ci->type == id_PLL_CORE)
929
- did_something |= preplace_prim (ci, id_REFCK, false );
919
+ TopoSort<IdString> sorter;
920
+ auto is_glb_cell = [&](const CellInfo *cell) {
921
+ return cell->type .in (id_OSC_CORE, id_DCC, id_PLL_CORE, id_DCS);
922
+ };
923
+
924
+ for (auto &cell : ctx->cells ) {
925
+ CellInfo *ci = cell.second .get ();
926
+ if (is_glb_cell (ci)) {
927
+ sorter.node (ci->name );
928
+
929
+ auto do_pin = [&](IdString pin) {
930
+ NetInfo *net = ci->getPort (pin);
931
+ if (!net || !net->driver .cell || !is_glb_cell (net->driver .cell ))
932
+ return ;
933
+ sorter.edge (net->driver .cell ->name , ci->name );
934
+ };
935
+
936
+ if (ci->type == id_PLL_CORE) {
937
+ do_pin (id_REFCK);
938
+ } else if (ci->type == id_DCC) {
939
+ do_pin (id_CLKI);
940
+ } else if (ci->type == id_DCS) {
941
+ do_pin (id_CLK0);
942
+ do_pin (id_CLK1);
943
+ }
930
944
}
931
945
}
946
+
947
+ sorter.sort ();
948
+
949
+ for (IdString cell_name : sorter.sorted ) {
950
+ CellInfo *ci = ctx->cells .at (cell_name).get ();
951
+ if (ci->type == id_OSC_CORE)
952
+ preplace_singleton (ci);
953
+ else if (ci->type == id_DCC)
954
+ preplace_prim (ci, id_CLKI, false );
955
+ else if (ci->type == id_PLL_CORE)
956
+ preplace_prim (ci, id_REFCK, false );
957
+ else if (ci->type == id_DCS)
958
+ preplace_prim (ci, id_CLK0, false );
959
+ }
932
960
}
933
961
934
962
// Get a bus port name
0 commit comments