blob: a0f920b6df1b4186604116d6457aca643c57d6ed [file] [log] [blame]
#include "pack_report.h"
#include "vtr_ostream_guard.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "histogram.h"
#include <iostream>
#include <iomanip>
void report_packing_pin_usage(std::ostream& os, const VprContext& ctx) {
os << "#Packing pin usage report\n";
auto& cluster_ctx = ctx.clustering();
auto& device_ctx = ctx.device();
std::map<t_physical_tile_type_ptr, size_t> total_input_pins;
std::map<t_physical_tile_type_ptr, size_t> total_output_pins;
for (auto const& type : device_ctx.physical_tile_types) {
if (is_empty_type(&type)) continue;
t_pb_type* pb_type = logical_block_type(&type)->pb_type;
total_input_pins[&type] = pb_type->num_input_pins + pb_type->num_clock_pins;
total_output_pins[&type] = pb_type->num_output_pins;
}
std::map<t_physical_tile_type_ptr, std::vector<float>> inputs_used;
std::map<t_physical_tile_type_ptr, std::vector<float>> outputs_used;
for (auto blk : cluster_ctx.clb_nlist.blocks()) {
t_physical_tile_type_ptr type = physical_tile_type(blk);
inputs_used[type].push_back(cluster_ctx.clb_nlist.block_input_pins(blk).size() + cluster_ctx.clb_nlist.block_clock_pins(blk).size());
outputs_used[type].push_back(cluster_ctx.clb_nlist.block_output_pins(blk).size());
}
vtr::OsFormatGuard os_guard(os);
os << std::fixed << std::setprecision(2);
for (auto const& physical_type : device_ctx.physical_tile_types) {
auto type = &physical_type;
if (is_empty_type(type)) continue;
if (!inputs_used.count(type)) continue;
float max_inputs = *std::max_element(inputs_used[type].begin(), inputs_used[type].end());
float min_inputs = *std::min_element(inputs_used[type].begin(), inputs_used[type].end());
float avg_inputs = std::accumulate(inputs_used[type].begin(), inputs_used[type].end(), 0) / float(inputs_used[type].size());
float max_outputs = *std::max_element(outputs_used[type].begin(), outputs_used[type].end());
float min_outputs = *std::min_element(outputs_used[type].begin(), outputs_used[type].end());
float avg_outputs = std::accumulate(outputs_used[type].begin(), outputs_used[type].end(), 0) / float(outputs_used[type].size());
os << "Type: " << type->name << "\n";
os << "\tInput Pin Usage:\n";
os << "\t\tMax: " << max_inputs << " (" << max_inputs / float(total_input_pins[type]) << ")"
<< "\n";
os << "\t\tAvg: " << avg_inputs << " (" << avg_inputs / float(total_input_pins[type]) << ")"
<< "\n";
os << "\t\tMin: " << min_inputs << " (" << min_inputs / float(total_input_pins[type]) << ")"
<< "\n";
if (total_input_pins[type] != 0) {
os << "\t\tHistogram:\n";
auto input_histogram = build_histogram(inputs_used[type], 10, 0, total_input_pins[type]);
for (auto line : format_histogram(input_histogram)) {
os << "\t\t" << line << "\n";
}
}
os << "\tOutput Pin Usage:\n";
os << "\t\tMax: " << max_outputs << " (" << max_outputs / float(total_output_pins[type]) << ")"
<< "\n";
os << "\t\tAvg: " << avg_outputs << " (" << avg_outputs / float(total_output_pins[type]) << ")"
<< "\n";
os << "\t\tMin: " << min_outputs << " (" << min_outputs / float(total_output_pins[type]) << ")"
<< "\n";
if (total_output_pins[type] != 0) {
os << "\t\tHistogram:\n";
auto output_histogram = build_histogram(outputs_used[type], 10, 0, total_output_pins[type]);
for (auto line : format_histogram(output_histogram)) {
os << "\t\t" << line << "\n";
}
}
os << "\n";
}
}