@@ -956,15 +956,42 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
956956 if (print_histogram && slack_histogram.size () > 0 ) {
957957 unsigned num_bins = 20 ;
958958 unsigned bar_width = 60 ;
959+ std::vector<unsigned > bins_count (num_bins);
960+ std::vector<unsigned > bins_bounds (num_bins + 1 );
961+ unsigned max_freq = 0 ;
959962 auto min_slack = slack_histogram.begin ()->first ;
960963 auto max_slack = slack_histogram.rbegin ()->first ;
961- auto bin_size = std::max<unsigned >(1 , ceil ((max_slack - min_slack + 1 ) / float (num_bins)));
962- std::vector<unsigned > bins (num_bins);
963- unsigned max_freq = 0 ;
964- for (const auto &i : slack_histogram) {
965- auto &bin = bins[(i.first - min_slack) / bin_size];
966- bin += i.second ;
967- max_freq = std::max (max_freq, bin);
964+
965+ if ((min_slack < 0 ) && (max_slack > 0 )) {
966+ /* Double sided histogram */
967+ /* [0...bin_ofs-1] = neg */
968+ /* [bin_ofs...num_bins-1] = pos */
969+ auto bin_ofs = std::max<unsigned >(
970+ num_bins / 4 , std::min<unsigned >(num_bins - (num_bins / 4 ) - 1 ,
971+ ceil (float (num_bins) * -min_slack / (max_slack - min_slack))));
972+ auto bin_size_neg = std::max<unsigned >(1 , ceil ((-min_slack + 1 ) / float (bin_ofs)));
973+ auto bin_size_pos = std::max<unsigned >(1 , ceil ((max_slack + 1 ) / float (num_bins - bin_ofs)));
974+ for (unsigned i = 0 ; i < bin_ofs; i++)
975+ bins_bounds[i] = (i - bin_ofs) * bin_size_neg;
976+ for (unsigned i = bin_ofs; i <= num_bins; i++)
977+ bins_bounds[i] = (i - bin_ofs) * bin_size_pos;
978+ for (const auto &i : slack_histogram) {
979+ int idx = (i.first < 0 ) ? (int )bin_ofs + (i.first / (int )bin_size_neg) - 1
980+ : (int )bin_ofs + (i.first / (int )bin_size_pos);
981+ auto &bin = bins_count[idx];
982+ bin += i.second ;
983+ max_freq = std::max (max_freq, bin);
984+ }
985+ } else {
986+ /* Single sided histogram */
987+ auto bin_size = std::max<unsigned >(1 , ceil ((max_slack - min_slack + 1 ) / float (num_bins)));
988+ for (unsigned i = 0 ; i <= num_bins; i++)
989+ bins_bounds[i] = min_slack + bin_size * i;
990+ for (const auto &i : slack_histogram) {
991+ auto &bin = bins_count[(i.first - min_slack) / bin_size];
992+ bin += i.second ;
993+ max_freq = std::max (max_freq, bin);
994+ }
968995 }
969996 bar_width = std::min (bar_width, max_freq);
970997
@@ -973,9 +1000,9 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
9731000 log_info (" legend: * represents %d endpoint(s)\n " , max_freq / bar_width);
9741001 log_info (" + represents [1,%d) endpoint(s)\n " , max_freq / bar_width);
9751002 for (unsigned i = 0 ; i < num_bins; ++i)
976- log_info (" [%6d, %6d) |%s%c\n " , min_slack + bin_size * i, min_slack + bin_size * ( i + 1 ) ,
977- std::string (bins [i] * bar_width / max_freq, ' *' ).c_str (),
978- (bins [i] * bar_width) % max_freq > 0 ? ' +' : ' ' );
1003+ log_info (" [%6d, %6d) |%s%c\n " , bins_bounds[i], bins_bounds[ i + 1 ] ,
1004+ std::string (bins_count [i] * bar_width / max_freq, ' *' ).c_str (),
1005+ (bins_count [i] * bar_width) % max_freq > 0 ? ' +' : ' ' );
9791006 }
9801007}
9811008
0 commit comments