@@ -773,6 +773,48 @@ void GateMatePacker::pack_addf()
773
773
}
774
774
}
775
775
776
+ void GateMatePacker::sort_bufg ()
777
+ {
778
+ struct ItemBufG {
779
+ CellInfo *cell;
780
+ int32_t fan_out;
781
+ ItemBufG (CellInfo *cell,int32_t fan_out) : cell(cell), fan_out(fan_out) {}
782
+ };
783
+
784
+ std::vector<ItemBufG> bufg;
785
+ for (auto &cell : ctx->cells ) {
786
+ CellInfo &ci = *cell.second ;
787
+ if (!ci.type .in (id_CC_BUFG))
788
+ continue ;
789
+
790
+ NetInfo *i_net = ci.getPort (id_I);
791
+ if (!i_net) {
792
+ log_warning (" Removing BUFG cell %s since there is no input used.\n " , ci.name .c_str (ctx));
793
+ packed_cells.emplace (ci.name ); // Remove if no input
794
+ continue ;
795
+ }
796
+ NetInfo *o_net = ci.getPort (id_O);
797
+ if (!o_net) {
798
+ log_warning (" Removing BUFG cell %s since there is no output used.\n " , ci.name .c_str (ctx));
799
+ packed_cells.emplace (ci.name ); // Remove if no output
800
+ continue ;
801
+ }
802
+ bufg.push_back (ItemBufG (&ci,o_net->users .entries ()));
803
+ }
804
+
805
+ if (bufg.size ()>4 ) {
806
+ log_warning (" More than 4 BUFG used. Those with highest fan-out will be used.\n " );
807
+ std::sort (bufg.begin (), bufg.end (), [](const ItemBufG& a, const ItemBufG& b) {
808
+ return a.fan_out > b.fan_out ;
809
+ });
810
+ for (size_t i=4 ;i<bufg.size ();i++) {
811
+ log_warning (" Removing BUFG cell %s.\n " , bufg.at (i).cell ->name .c_str (ctx));
812
+ packed_cells.emplace (bufg.at (i).cell ->name );
813
+ }
814
+ }
815
+ flush_cells ();
816
+ }
817
+
776
818
void GateMatePacker::pack_bufg ()
777
819
{
778
820
log_info (" Packing BUFGs..\n " );
@@ -1436,6 +1478,7 @@ void GateMateImpl::pack()
1436
1478
1437
1479
GateMatePacker packer (ctx, this );
1438
1480
packer.pack_constants ();
1481
+ packer.sort_bufg ();
1439
1482
packer.pack_io ();
1440
1483
packer.pack_pll ();
1441
1484
packer.pack_bufg ();
0 commit comments