Skip to content

Commit ab49f26

Browse files
committed
vpr: utils: add second variant of primitive_type_feasible() check
Signed-off-by: Pawel Czarnecki <pczarnecki@antmicro.com>
1 parent dbc4791 commit ab49f26

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

vpr/src/util/vpr_utils.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,92 @@ bool primitive_type_feasible(const AtomBlockId blk_id, const t_pb_type* cur_pb_t
905905
//Feasible
906906
return true;
907907
}
908+
bool primitive_type_feasible(const AtomBlockId blk_id, t_pb_graph_node* curr_pb_graph_node) {
909+
t_pb_type* cur_pb_type = curr_pb_graph_node->pb_type;
910+
911+
if (cur_pb_type == nullptr) {
912+
return false;
913+
}
914+
915+
auto& atom_ctx = g_vpr_ctx.atom();
916+
if (cur_pb_type->model != atom_ctx.nlist.block_model(blk_id)) {
917+
if ((strcmp(atom_ctx.nlist.block_model(blk_id)->name, MODEL_LATCH) == 0) &&
918+
(strcmp(atom_ctx.nlist.block_model(blk_id)->name, cur_pb_type->model->name) == 0)) {
919+
/**
920+
* Special case for .latch: this model exists in 2 variations which are
921+
* defined one after another in linked list, check if the second variant match
922+
*/
923+
924+
if (cur_pb_type->model->next == atom_ctx.nlist.block_model(blk_id) && atom_ctx.nlist.block_model(blk_id)->inputs[1].trigg_edge == TriggeringEdge::FALLING_EDGE) {
925+
//Next primitive match atom - add secondary references
926+
if (!curr_pb_graph_node->has_secondary)
927+
curr_pb_graph_node->update_pins();
928+
} else {
929+
//Next primitive and atom do not match
930+
return false;
931+
}
932+
} else {
933+
//Primitive and atom do not match
934+
return false;
935+
}
936+
}
937+
938+
VTR_ASSERT_MSG(atom_ctx.nlist.is_compressed(), "This function assumes a compressed/non-dirty netlist");
939+
940+
//Keep track of how many atom ports were checked.
941+
//
942+
//We need to do this since we iterate over the pb's ports and
943+
//may miss some atom ports if there is a mismatch
944+
size_t checked_ports = 0;
945+
946+
//Look at each port on the pb and find the associated port on the
947+
//atom. To be feasible the pb must have as many pins on each port
948+
//as the atom requires
949+
for (int iport = 0; iport < cur_pb_type->num_ports; ++iport) {
950+
t_port* pb_port;
951+
if(curr_pb_graph_node->has_secondary)
952+
pb_port = &cur_pb_type->ports_sec[iport];
953+
else
954+
pb_port = &cur_pb_type->ports[iport];
955+
956+
const t_model_ports* pb_model_port = pb_port->model_port;
957+
958+
//Find the matching port on the atom
959+
auto port_id = atom_ctx.nlist.find_atom_port(blk_id, pb_model_port);
960+
961+
if (port_id) { //Port is used by the atom
962+
963+
//In compressed form the atom netlist stores only in-use pins,
964+
//so we can query the number of required pins directly
965+
int required_atom_pins = atom_ctx.nlist.port_pins(port_id).size();
966+
967+
int available_pb_pins = pb_port->num_pins;
968+
969+
if (available_pb_pins < required_atom_pins) {
970+
//Too many pins required
971+
return false;
972+
}
973+
974+
//Note that this port was checked
975+
++checked_ports;
976+
}
977+
}
978+
979+
//Similarly to pins, only in-use ports are stored in the compressed
980+
//atom netlist, so we can figure out how many ports should have been
981+
//checked directly
982+
size_t atom_ports = atom_ctx.nlist.block_ports(blk_id).size();
983+
984+
//See if all the atom ports were checked
985+
if (checked_ports != atom_ports) {
986+
VTR_ASSERT(checked_ports < atom_ports);
987+
//Required atom port was missing from physical primitive
988+
return false;
989+
}
990+
991+
//Feasible
992+
return true;
993+
}
908994

909995
//Returns the sibling atom of a memory slice pb
910996
// Note that the pb must be part of a MEMORY_CLASS

vpr/src/util/vpr_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ int get_max_primitives_in_pb_type(t_pb_type* pb_type);
109109
int get_max_depth_of_pb_type(t_pb_type* pb_type);
110110
int get_max_nets_in_pb_type(const t_pb_type* pb_type);
111111
bool primitive_type_feasible(AtomBlockId blk_id, const t_pb_type* cur_pb_type);
112+
bool primitive_type_feasible(AtomBlockId blk_id, t_pb_graph_node* curr_pb_graph_node);
112113
t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* model_port, const int model_pin, const t_pb_graph_node* pb_graph_node);
113114
const t_pb_graph_pin* find_pb_graph_pin(const AtomNetlist& netlist, const AtomLookup& netlist_lookup, const AtomPinId pin_id);
114115
t_pb_graph_pin* get_pb_graph_node_pin_from_block_pin(ClusterBlockId iblock, int ipin);

0 commit comments

Comments
 (0)