From 481884b0bec90eb25598578b9a6db71111ab58e1 Mon Sep 17 00:00:00 2001 From: KA7E Date: Tue, 8 Aug 2023 14:18:18 -0400 Subject: [PATCH 1/3] Fix bug in which all non-chain luts are considered length-1 chains. Current find_new_root_atom_for_chain assumes that an atom without a driver is the root of a chain. This fix permits a driverless atom to be a chain root only if it drives another chain atom. --- vpr/src/pack/prepack.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index 3307472ac79..89af33cca93 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -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 find_end_of_path(t_pb_graph_pin* input_pin, int pattern_index); @@ -947,8 +947,10 @@ 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); + blk_id = find_new_root_atom_for_chain(blk_id, pack_pattern, false); if (!blk_id) return nullptr; } @@ -1300,8 +1302,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: 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 */ -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; @@ -1326,8 +1329,14 @@ static AtomBlockId find_new_root_atom_for_chain(const AtomBlockId blk_id, const // 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 (!driver_blk_id) { - return blk_id; + + if (is_nontrivial_chain) { + return blk_id; + } else { + return AtomBlockId::INVALID(); + } } // check if driver atom is already packed auto rng = atom_ctx.atom_molecules.equal_range(driver_blk_id); @@ -1338,7 +1347,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; From 4b8fbb5cef965b0c75070dbe50ebeaa4354e1ad6 Mon Sep 17 00:00:00 2001 From: KA7E Date: Wed, 18 Oct 2023 20:04:27 -0400 Subject: [PATCH 2/3] 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 --- vpr/src/pack/prepack.cpp | 43 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index 89af33cca93..3089102ffe3 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -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); From 81a597ec2d3fc83ad3264b40df1da528ac22ecd4 Mon Sep 17 00:00:00 2001 From: KA7E Date: Thu, 19 Oct 2023 02:19:05 -0400 Subject: [PATCH 3/3] minor formatting fixes --- vpr/src/pack/prepack.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index 3089102ffe3..36f993b151f 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -1294,12 +1294,10 @@ static int compare_pack_pattern(const t_pack_patterns* pattern_a, const t_pack_p } /* 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); @@ -1314,7 +1312,6 @@ static bool drives_pattern_connection(const t_pack_patterns* pack_pattern, AtomB 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. * Returns AtomBlockId::INVALID() if this block_index doesn't match up with any chain