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 1 commit
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
Prev Previous commit
Next Next commit
address corner case in which chain root is the first atom encountered…
… for its chain; since it has no driver, check to see if it drives a pattern connection
  • Loading branch information
KA7E committed Oct 19, 2023
commit 4b8fbb5cef965b0c75070dbe50ebeaa4354e1ad6
43 changes: 35 additions & 8 deletions vpr/src/pack/prepack.cpp
Original file line number Diff line number Diff line change
@@ -947,8 +947,6 @@ 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.
// The first time this function is called, assume this is not a chain
// to avoid false length-1 chains.
if (pack_pattern->is_chain) {
blk_id = find_new_root_atom_for_chain(blk_id, pack_pattern, false);
if (!blk_id) return nullptr;
@@ -1294,6 +1292,28 @@ 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.
@@ -1302,7 +1322,7 @@ 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: if atom has no driver, then it is either furthest up the chain (if this function was called from the atom it drives) or not in a real chain
* 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, bool is_nontrivial_chain) {
AtomBlockId new_root_blk_id;
@@ -1327,17 +1347,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
// or it is not in a chain (if this function was not called from the atom this block drives).
// 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) {

// if this block was reached from further down the chain, then this is a chain
if (is_nontrivial_chain) {
return blk_id;
} else {
return AtomBlockId::INVALID();
// 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);