Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
432 changes: 420 additions & 12 deletions src/operation/iRT/source/module/layer_assigner/LayerAssigner.cpp

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions src/operation/iRT/source/module/layer_assigner/LayerAssigner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,28 @@ class LayerAssigner
void assign();

private:
struct LAOverflowEdge
{
PlanarCoord first_coord;
PlanarCoord second_coord;
int32_t layer_idx = -1;
bool has_true_overflow = false;
double total_true_overflow = 0.0;
double max_true_overflow = 0.0;
double total_soft_congestion = 0.0;
double max_soft_congestion = 0.0;
double max_usage_ratio = 0.0;
std::vector<PlanarCoord> split_coord_list;
};
struct LARefineLayerHint
{
PlanarCoord first_coord;
PlanarCoord second_coord;
int32_t layer_idx = -1;
};
// self
static LayerAssigner* _la_instance;
std::vector<LARefineLayerHint> _refine_layer_hint_list;

LayerAssigner() = default;
LayerAssigner(const LayerAssigner& other) = delete;
Expand All @@ -62,7 +82,11 @@ class LayerAssigner
void initSingleTask(LAModel& la_model, LANet* la_task);
bool needRouting(LAModel& la_model);
void spiltPlaneTree(LAModel& la_model);
int32_t getTopoSpiltLength(LAModel& la_model, int32_t segment_length);
void insertMidPoint(LAModel& la_model, TNode<LayerCoord>* planar_node, TNode<LayerCoord>* child_node);
std::vector<LAOverflowEdge> getOverflowEdgeList(LAModel& la_model);
void splitPlaneTreeByOverflow(LAModel& la_model, std::vector<LAOverflowEdge>& overflow_edge_list);
void insertPointList(TNode<LayerCoord>* planar_node, TNode<LayerCoord>* child_node, std::vector<PlanarCoord>& point_list);
void buildPillarTree(LAModel& la_model);
LAPillar convertLAPillar(LayerCoord& layer_coord, std::map<PlanarCoord, std::set<int32_t>, CmpPlanarCoordByXASC>& coord_pin_layer_map);
void assignPillarTree(LAModel& la_model);
Expand All @@ -73,11 +97,16 @@ class LayerAssigner
std::pair<int32_t, double> getParentPillarCost(LAModel& la_model, LAPackage& la_package, int32_t candidate_layer_idx);
double getExtraViaCost(LAModel& la_model, std::set<int32_t>& layer_idx_set, int32_t candidate_layer_idx);
double getSegmentCost(LAModel& la_model, LAPackage& la_package, int32_t candidate_layer_idx);
double getLayerBiasCost(LAModel& la_model, LAPackage& la_package, std::vector<int32_t>& candidate_layer_idx_list, int32_t candidate_layer_idx);
double getRefineLayerHintCost(LAModel& la_model, LAPackage& la_package, int32_t candidate_layer_idx);
double getLayerSwitchCost(LAModel& la_model, LAPackage& la_package, int32_t parent_layer_idx, int32_t candidate_layer_idx);
double getChildPillarCost(LAModel& la_model, LAPackage& la_package, int32_t candidate_layer_idx);
void assignBackward(LAModel& la_model);
int32_t getBestLayerBySelf(TNode<LAPillar>* pillar_node);
int32_t getBestLayerByChild(TNode<LAPillar>* parent_pillar_node);
void buildLayerTree(LAModel& la_model);
MTree<LayerCoord> getAssignedCoordTree(LAModel& la_model);
void commitLayerTree(LAModel& la_model, MTree<LayerCoord>& coord_tree);
std::vector<Segment<LayerCoord>> getRoutingSegmentList(LAModel& la_model);
MTree<LayerCoord> getCoordTree(LAModel& la_model, std::vector<Segment<LayerCoord>>& routing_segment_list);
void uploadNetResult(LAModel& la_model, MTree<LayerCoord>& coord_tree);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,56 @@ class LAComParam
_via_unit = via_unit;
_overflow_unit = overflow_unit;
}
LAComParam(int32_t topo_spilt_length, int32_t mid_topo_spilt_length, int32_t long_topo_spilt_length, int32_t short_segment_length,
int32_t mid_segment_length, int32_t long_segment_length, double via_unit, double overflow_unit, double layer_bias_unit,
double layer_switch_unit)
{
_topo_spilt_length = topo_spilt_length;
_mid_topo_spilt_length = mid_topo_spilt_length;
_long_topo_spilt_length = long_topo_spilt_length;
_short_segment_length = short_segment_length;
_mid_segment_length = mid_segment_length;
_long_segment_length = long_segment_length;
_via_unit = via_unit;
_overflow_unit = overflow_unit;
_layer_bias_unit = layer_bias_unit;
_layer_switch_unit = layer_switch_unit;
}
~LAComParam() = default;
// getter
int32_t get_topo_spilt_length() const { return _topo_spilt_length; }
int32_t get_mid_topo_spilt_length() const { return _mid_topo_spilt_length; }
int32_t get_long_topo_spilt_length() const { return _long_topo_spilt_length; }
int32_t get_short_segment_length() const { return _short_segment_length; }
int32_t get_mid_segment_length() const { return _mid_segment_length; }
int32_t get_long_segment_length() const { return _long_segment_length; }
double get_via_unit() const { return _via_unit; }
double get_overflow_unit() const { return _overflow_unit; }
double get_layer_bias_unit() const { return _layer_bias_unit; }
double get_layer_switch_unit() const { return _layer_switch_unit; }
// setter
void set_topo_spilt_length(const int32_t topo_spilt_length) { _topo_spilt_length = topo_spilt_length; }
void set_mid_topo_spilt_length(const int32_t mid_topo_spilt_length) { _mid_topo_spilt_length = mid_topo_spilt_length; }
void set_long_topo_spilt_length(const int32_t long_topo_spilt_length) { _long_topo_spilt_length = long_topo_spilt_length; }
void set_short_segment_length(const int32_t short_segment_length) { _short_segment_length = short_segment_length; }
void set_mid_segment_length(const int32_t mid_segment_length) { _mid_segment_length = mid_segment_length; }
void set_long_segment_length(const int32_t long_segment_length) { _long_segment_length = long_segment_length; }
void set_via_unit(const double via_unit) { _via_unit = via_unit; }
void set_overflow_unit(const double overflow_unit) { _overflow_unit = overflow_unit; }
void set_layer_bias_unit(const double layer_bias_unit) { _layer_bias_unit = layer_bias_unit; }
void set_layer_switch_unit(const double layer_switch_unit) { _layer_switch_unit = layer_switch_unit; }

private:
int32_t _topo_spilt_length = 0;
int32_t _mid_topo_spilt_length = 0;
int32_t _long_topo_spilt_length = 0;
int32_t _short_segment_length = 0;
int32_t _mid_segment_length = 0;
int32_t _long_segment_length = 0;
double _via_unit = 0;
double _overflow_unit = 0;
double _layer_bias_unit = 0;
double _layer_switch_unit = 0;
};

} // namespace irt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@

namespace irt {

struct LAOverflowMetric
{
double true_overflow = 0.0;
double soft_congestion = 0.0;
double max_usage_ratio = 0.0;
int32_t overflow_orient_num = 0;
int32_t soft_orient_num = 0;
};

class LANode : public LayerCoord
{
public:
Expand Down Expand Up @@ -129,6 +138,103 @@ class LANode : public LayerCoord
cost += (overflow_unit * (boundary_overflow + internal_overflow));
return cost;
}
LAOverflowMetric getOverflowMetric(int32_t net_idx, Direction direction)
{
if (!validDemandUnit()) {
RTLOG.error(Loc::current(), "The demand unit is error!");
}
std::map<Orientation, std::set<int32_t>> orient_net_map = _orient_net_map;
std::map<int32_t, std::set<Orientation>> net_orient_map = _net_orient_map;
if (direction == Direction::kHorizontal) {
for (Orientation orient : {Orientation::kEast, Orientation::kWest}) {
orient_net_map[orient].insert(net_idx);
net_orient_map[net_idx].insert(orient);
}
} else if (direction == Direction::kVertical) {
for (Orientation orient : {Orientation::kSouth, Orientation::kNorth}) {
orient_net_map[orient].insert(net_idx);
net_orient_map[net_idx].insert(orient);
}
} else {
RTLOG.error(Loc::current(), "The direction is error!");
}

constexpr double kSoftStartRatio = 0.90;
LAOverflowMetric metric;
auto addDemandSupply = [&metric, kSoftStartRatio](double demand, double supply) {
if (supply <= 0) {
if (demand > 0) {
metric.true_overflow += demand;
metric.max_usage_ratio = std::max(metric.max_usage_ratio, demand + 1.0);
metric.overflow_orient_num++;
}
return;
}

double usage_ratio = demand / supply;
metric.max_usage_ratio = std::max(metric.max_usage_ratio, usage_ratio);
double overflow = demand - supply;
if (overflow > RT_ERROR) {
metric.true_overflow += overflow;
metric.overflow_orient_num++;
return;
}
if (usage_ratio >= kSoftStartRatio) {
double soft_ratio = (usage_ratio - kSoftStartRatio) / (1.0 - kSoftStartRatio);
metric.soft_congestion += std::pow(soft_ratio, 2);
metric.soft_orient_num++;
}
};

for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
double boundary_demand = 0;
if (RTUTIL.exist(orient_net_map, orient)) {
for (int32_t demand_net_idx : orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
boundary_demand += _boundary_wire_unit;
}
}
double boundary_supply = 0;
if (RTUTIL.exist(_orient_supply_map, orient)) {
boundary_supply = _orient_supply_map[orient];
}
addDemandSupply(boundary_demand, boundary_supply);
}
{
double internal_demand = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
if (RTUTIL.exist(orient_net_map, orient)) {
for (int32_t demand_net_idx : orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
internal_demand += _internal_wire_unit;
}
}
}
for (auto& [net_idx, orient_set] : net_orient_map) {
if (RTUTIL.exist(_ignore_net_orient_map, net_idx)
&& (RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kAbove) || RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kBelow))) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kEast) || RTUTIL.exist(orient_set, Orientation::kWest) || RTUTIL.exist(orient_set, Orientation::kSouth)
|| RTUTIL.exist(orient_set, Orientation::kNorth)) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kAbove) || RTUTIL.exist(orient_set, Orientation::kBelow)) {
internal_demand += _internal_via_unit;
}
}
double internal_supply = 0;
for (auto& [orient, supply] : _orient_supply_map) {
internal_supply += supply;
}
addDemandSupply(internal_demand, internal_supply);
}
return metric;
}
bool validDemandUnit()
{
if (_boundary_wire_unit <= 0) {
Expand Down
Loading
Loading