Skip to content

Fix bug in which all non-chain luts are considered length-1 chains. #2363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
48 changes: 41 additions & 7 deletions vpr/src/pack/prepack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static t_pb_graph_node* get_expected_lowest_cost_primitive_for_atom_block(const

static t_pb_graph_node* get_expected_lowest_cost_primitive_for_atom_block_in_pb_graph_node(const AtomBlockId blk_id, t_pb_graph_node* curr_pb_graph_node, float* cost);

static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const t_pack_patterns* list_of_pack_pattern);
static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const t_pack_patterns* list_of_pack_pattern, bool is_nontrivial_chain);

static std::vector<t_pb_graph_pin*> find_end_of_path(t_pb_graph_pin* input_pin, int pattern_index);

Expand Down Expand Up @@ -948,7 +948,7 @@ static t_pack_molecule* try_create_molecule(t_pack_patterns* list_of_pack_patter
// If a chain pattern extends beyond a single logic block, we must find
// the furthest blk_id up the chain that is not mapped to a molecule yet.
if (pack_pattern->is_chain) {
blk_id = find_new_root_atom_for_chain(blk_id, pack_pattern);
blk_id = find_new_root_atom_for_chain(blk_id, pack_pattern, false);
if (!blk_id) return nullptr;
}

Expand Down Expand Up @@ -1292,6 +1292,25 @@ static int compare_pack_pattern(const t_pack_patterns* pattern_a, const t_pack_p
}
return 0;
}
/* checks whether or not this block drives a pattern connection (e.g. its cout drives another block's cin) */
static bool drives_pattern_connection(const t_pack_patterns* pack_pattern, AtomBlockId blk_id) {
auto& atom_ctx = g_vpr_ctx.atom();
auto iconn = pack_pattern->root_block->connections;

while (iconn != NULL) {
t_pb_graph_pin* cur_pin = iconn->from_pin;
t_model_ports* cur_model_port = cur_pin->port->model_port;
AtomPortId cur_port = atom_ctx.nlist.find_atom_port(blk_id, cur_model_port);
if (cur_port) {
AtomNetId cur_net = atom_ctx.nlist.port_net(cur_port, cur_pin->pin_number);

if (cur_net)
return true;
}
iconn = iconn->next;
}
return false;
}

/* A chain can extend across multiple atom blocks. Must segment the chain to fit in an atom
* block by identifying the actual atom that forms the root of the new chain.
Expand All @@ -1300,8 +1319,9 @@ static int compare_pack_pattern(const t_pack_patterns* pattern_a, const t_pack_p
* Assumes that the root of a chain is the primitive that starts the chain or is driven from outside the logic block
* block_index: index of current atom
* list_of_pack_pattern: ptr to current chain pattern
* is_nontrivial_chain: true if this function was called from an atom driven by the current atom (so we know this atom is part of a chain of length > 1)
*/
static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const t_pack_patterns* list_of_pack_pattern) {
static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const t_pack_patterns* list_of_pack_pattern, bool is_nontrivial_chain) {
AtomBlockId new_root_blk_id;
t_pb_graph_pin* root_ipin;
t_pb_graph_node* root_pb_graph_node;
Expand All @@ -1324,11 +1344,24 @@ static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const
// find the block id of the atom block driving the input of this block
AtomBlockId driver_blk_id = atom_ctx.nlist.find_atom_pin_driver(blk_id, model_port, root_ipin->pin_number);

// if there is no driver block for this net
// then it is the furthest up the chain
// if there is no driver block for this net, then
// if it drives a pattern connection, it is furthest up the chain
// if it does not drive a pattern connection and has no driver, it is not in a chain
if (!driver_blk_id) {
return blk_id;
// if this block was reached from further down the chain, then this is a chain
if (is_nontrivial_chain) {
return blk_id;
} else {
// if this is the first chain block encountered, check to see if it drives a pattern connection
if (drives_pattern_connection(list_of_pack_pattern, blk_id)) {
return blk_id;
}
}
// if this block does not drive, and is not driven by, a pattern connection, then this is not a chain

return AtomBlockId::INVALID();
}

// check if driver atom is already packed
auto rng = atom_ctx.atom_molecules.equal_range(driver_blk_id);
bool rng_empty = (rng.first == rng.second);
Expand All @@ -1338,7 +1371,8 @@ static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const
}

// didn't find furthest atom up the chain, keep searching further up the chain
new_root_blk_id = find_new_root_atom_for_chain(driver_blk_id, list_of_pack_pattern);
// if the function reaches this point then the current block has a driver, so this is a nontrivial chain
new_root_blk_id = find_new_root_atom_for_chain(driver_blk_id, list_of_pack_pattern, true);

if (!new_root_blk_id) {
return blk_id;
Expand Down