[Tool] Patch repack to consider design constraints for pins that are not equivalent

This commit is contained in:
tangxifan 2021-04-21 13:53:08 -06:00
parent 12f27cf117
commit 96ce6b545f
3 changed files with 105 additions and 25 deletions

View File

@ -50,6 +50,20 @@ std::string RepackDesignConstraints::net(const RepackDesignConstraintId& repack_
return repack_design_constraint_nets_[repack_design_constraint_id];
}
std::string RepackDesignConstraints::find_constrained_pin_net(const std::string& pb_type,
const openfpga::BasicPort& pin) const {
std::string constrained_net_name;
for (const RepackDesignConstraintId& design_constraint : design_constraints()) {
/* If found a constraint, record the net name */
if ( (pb_type == repack_design_constraint_pb_types_[design_constraint])
&& (pin == repack_design_constraint_pins_[design_constraint])) {
constrained_net_name = repack_design_constraint_nets_[design_constraint];
break;
}
}
return constrained_net_name;
}
bool RepackDesignConstraints::empty() const {
return 0 == repack_design_constraint_ids_.size();
}
@ -106,3 +120,11 @@ void RepackDesignConstraints::set_net(const RepackDesignConstraintId& repack_des
bool RepackDesignConstraints::valid_design_constraint_id(const RepackDesignConstraintId& design_constraint_id) const {
return ( size_t(design_constraint_id) < repack_design_constraint_ids_.size() ) && ( design_constraint_id == repack_design_constraint_ids_[design_constraint_id] );
}
bool RepackDesignConstraints::unconstrained_net(const std::string& net) const {
return net.empty();
}
bool RepackDesignConstraints::unmapped_net(const std::string& net) const {
return std::string(REPACK_DESIGN_CONSTRAINT_OPEN_NET) == net;
}

View File

@ -61,6 +61,10 @@ class RepackDesignConstraints {
/* Get the net to be constrained */
std::string net(const RepackDesignConstraintId& repack_design_constraint_id) const;
/* Find a constrained net */
std::string find_constrained_pin_net(const std::string& pb_type,
const openfpga::BasicPort& pin) const;
/* Check if there are any design constraints */
bool empty() const;
@ -86,6 +90,20 @@ class RepackDesignConstraints {
public: /* Public invalidators/validators */
bool valid_design_constraint_id(const RepackDesignConstraintId& repack_design_constraint_id) const;
/* Show if the net has no constraints (free to map to any pin)
* This function is used to identify the net name returned by APIs:
* - find_constrained_pin_net()
* - net()
*/
bool unconstrained_net(const std::string& net) const;
/* Show if the net is defined specifically not to map to any pin
* This function is used to identify the net name returned by APIs:
* - find_constrained_pin_net()
* - net()
*/
bool unmapped_net(const std::string& net) const;
private: /* Internal data */
/* Unique ids for each design constraint */
vtr::vector<RepackDesignConstraintId, RepackDesignConstraintId> repack_design_constraint_ids_;

View File

@ -230,6 +230,38 @@ std::vector<t_pb_graph_pin*> find_routed_pb_graph_pins_atom_net(const t_pb* pb,
return sink_pb_pins;
}
/***************************************************************************************
* This function will find the actual routing traces of the demanded net
* There is a specific search space applied when searching the routing traces:
* - ONLY applicable to the pb_pin of top-level pb_graph_node
* - candidate can be limited to a set of pb pins
***************************************************************************************/
static
std::vector<int> find_pb_route_by_atom_net(const t_pb* pb,
const t_pb_graph_pin* source_pb_pin,
const AtomNetId& atom_net_id) {
VTR_ASSERT(true == source_pb_pin->parent_node->is_root());
std::vector<int> pb_route_indices;
for (int pin = 0; pin < pb->pb_graph_node->total_pb_pins; ++pin) {
/* Bypass unused pins */
if ((0 == pb->pb_route.count(pin)) || (AtomNetId::INVALID() == pb->pb_route.at(pin).atom_net_id)) {
continue;
}
/* Get the driver pb pin id, it must be valid */
if (atom_net_id != pb->pb_route.at(pin).atom_net_id) {
continue;
}
if (source_pb_pin->port == pb->pb_route.at(pin).pb_graph_pin->port) {
pb_route_indices.push_back(pin);
}
}
return pb_route_indices;
}
/***************************************************************************************
* This function will find the actual source_pb_pin that is mapped by packed in the pb route
* As the inputs of clustered block may be renamed during routing,
@ -422,18 +454,7 @@ void add_lb_router_nets(LbRouter& lb_router,
AtomNetId atom_net_id = pb_pin_mapped_nets[source_pb_pin];
/* Check if the net information is constrained or not */
std::string constrained_net_name;
for (const RepackDesignConstraintId& design_constraint : design_constraints.design_constraints()) {
/* All the pin must have only 1 bit */
VTR_ASSERT_SAFE(1 == design_constraints.pin(design_constraint).get_width());
/* If found a constraint, record the net name */
if ( (std::string(lb_type->pb_type->name) == design_constraints.pb_type(design_constraint))
&& (std::string(source_pb_pin->port->name) == design_constraints.pin(design_constraint).get_name())
&& (size_t(source_pb_pin->pin_number) == design_constraints.pin(design_constraint).get_lsb())) {
constrained_net_name = design_constraints.net(design_constraint);
break;
}
}
std::string constrained_net_name = design_constraints.find_constrained_pin_net(std::string(lb_type->pb_type->name), BasicPort(std::string(source_pb_pin->port->name), source_pb_pin->pin_number, source_pb_pin->pin_number));
/* Find the constrained net mapped to this pin in clustering results */
AtomNetId constrained_atom_net_id = AtomNetId::INVALID();
@ -443,16 +464,21 @@ void add_lb_router_nets(LbRouter& lb_router,
* - if this is valid net name, find the net id from atom_netlist
* and overwrite the atom net id to mapped
*/
if (!constrained_net_name.empty()) {
if (std::string(REPACK_DESIGN_CONSTRAINT_OPEN_NET) != constrained_net_name) {
constrained_atom_net_id = atom_ctx.nlist.find_net(constrained_net_name);
if (false == atom_ctx.nlist.valid_net_id(constrained_atom_net_id)) {
VTR_LOG_WARN("Invalid net '%s' to be constrained! Will drop the constraint in repacking\n",
constrained_net_name.c_str());
}
if ( (!design_constraints.unconstrained_net(constrained_net_name))
&& (!design_constraints.unmapped_net(constrained_net_name))) {
constrained_atom_net_id = atom_ctx.nlist.find_net(constrained_net_name);
if (false == atom_ctx.nlist.valid_net_id(constrained_atom_net_id)) {
VTR_LOG_WARN("Invalid net '%s' to be constrained! Will drop the constraint in repacking\n",
constrained_net_name.c_str());
} else {
VTR_ASSERT_SAFE(false == atom_ctx.nlist.valid_net_id(constrained_atom_net_id));
VTR_LOGV(verbose,
"Accept net '%s' to be constrained on pin '%s[%d]' during repacking\n",
constrained_net_name.c_str(),
source_pb_pin->port->name,
source_pb_pin->pin_number);
}
} else {
VTR_ASSERT_SAFE(constrained_net_name.empty());
} else if (design_constraints.unconstrained_net(constrained_net_name)) {
constrained_atom_net_id = atom_net_id;
}
@ -486,18 +512,35 @@ void add_lb_router_nets(LbRouter& lb_router,
LbRRNodeId source_lb_rr_node = lb_rr_graph.find_node(LB_INTERMEDIATE, source_pb_pin);
VTR_ASSERT(true == lb_rr_graph.valid_node_id(source_lb_rr_node));
/* Output verbose messages for debugging only */
VTR_LOGV(verbose,
"Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id_to_route).c_str());
/* As the pin remapping is allowed during routing, we should
* - Find the routing traces from packing results which is mapped to the net
* from the same port (as remapping is allowed for pins in the same port only)
* - Find the source pb_graph_pin that drives the routing traces during packing
* - Then we can find the sink nodes
*
* When there is a pin constraint applied. The routing trace
* - Find the routing traces from packing results which is mapped to the net
* with the same port constraints
*/
std::vector<int> pb_route_indices = find_pb_route_remapped_source_pb_pin(pb, source_pb_pin, atom_net_id_to_route);
std::vector<int> pb_route_indices;
if (design_constraints.unconstrained_net(constrained_net_name)) {
pb_route_indices = find_pb_route_remapped_source_pb_pin(pb, source_pb_pin, atom_net_id_to_route);
} else {
VTR_ASSERT_SAFE(!design_constraints.unconstrained_net(constrained_net_name));
pb_route_indices = find_pb_route_by_atom_net(pb, source_pb_pin, atom_net_id_to_route);
}
/* It could happen that the constrained net is NOT used in this clb, we just skip it for routing
* For example, a clkB net is never mapped to any ports in the pb that is clocked by clkA net
* */
int pb_route_index;
if (0 == pb_route_indices.size()) {
VTR_LOGV(verbose,
"Bypass routing due to no routing traces found\n");
continue;
} else {
VTR_ASSERT(1 == pb_route_indices.size());
@ -512,9 +555,6 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
/* Output verbose messages for debugging only */
VTR_LOGV(verbose,
"Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id_to_route).c_str());
VTR_LOGV(verbose,
"Source node:\n\t%s -> %s\n",
source_pb_pin->to_string().c_str(),