vpr/src/pack/cluster.cpp
/**
 * This function takes the root block of a chain molecule and a proposed
 * placement primitive for this block. The function then checks if this
 * chain root block has a placement constraint (such as being driven from
 * outside the cluster) and returns the status of the placement accordingly.
 */
This function takes the root block of a chain molecule and a proposed
placement primitive for this block. The function then checks if this
chain root block has a placement constraint (such as being driven from
outside the cluster) and returns the status of the placement accordingly.
This function takes the root block of a chain molecule and a proposed placement primitive for this block . The function then checks if this chain root block has a placement constraint ( such as being driven from outside the cluster ) and returns the status of the placement accordingly .
static enum e_block_pack_status check_chain_root_placement_feasibility(const t_pb_graph_node* pb_graph_node,
                                                                       const t_pack_molecule* molecule,
                                                                       const AtomBlockId blk_id) {
    enum e_block_pack_status block_pack_status = BLK_PASSED;
    auto& atom_ctx = g_vpr_ctx.atom();
    bool is_long_chain = molecule->chain_info->is_long_chain;
    const auto& chain_root_pins = molecule->pack_pattern->chain_root_pins;
    t_model_ports* root_port = chain_root_pins[0][0]->port->model_port;
    AtomNetId chain_net_id;
    auto port_id = atom_ctx.nlist.find_atom_port(blk_id, root_port);
    if (port_id) {
        chain_net_id = atom_ctx.nlist.port_net(port_id, chain_root_pins[0][0]->pin_number);
    }
    if (is_long_chain || chain_net_id) {
        auto chain_id = molecule->chain_info->chain_id;
        if (chain_id != -1) {
            if (pb_graph_node != chain_root_pins[chain_id][0]->parent_node) {
                block_pack_status = BLK_FAILED_FEASIBLE;
            }
        } else {
            block_pack_status = BLK_FAILED_FEASIBLE;
            for (const auto& chain : chain_root_pins) {
                for (size_t tieOff = 0; tieOff < chain.size(); tieOff++) {
                    if (pb_graph_node == chain[tieOff]->parent_node) {
                        block_pack_status = BLK_PASSED;
                        break;
                    }
                    if (is_long_chain) break;
                }
            }
        }
    }
    return block_pack_status;
}
static enum e_block_pack_status check_chain_root_placement_feasibility ( const t_pb_graph_node * pb_graph_node , const t_pack_molecule * molecule , const AtomBlockId blk_id ) { enum e_block_pack_status block_pack_status = BLK_PASSED ; auto & atom_ctx = g_vpr_ctx . atom ( ) ; bool is_long_chain = molecule -> chain_info -> is_long_chain ; const auto & chain_root_pins = molecule -> pack_pattern -> chain_root_pins ; t_model_ports * root_port = chain_root_pins [ 0 ] [ 0 ] -> port -> model_port ; AtomNetId chain_net_id ; auto port_id = atom_ctx . nlist . find_atom_port ( blk_id , root_port ) ; if ( port_id ) { chain_net_id = atom_ctx . nlist . port_net ( port_id , chain_root_pins [ 0 ] [ 0 ] -> pin_number ) ; } if ( is_long_chain || chain_net_id ) { auto chain_id = molecule -> chain_info -> chain_id ; if ( chain_id != -1 ) { if ( pb_graph_node != chain_root_pins [ chain_id ] [ 0 ] -> parent_node ) { block_pack_status = BLK_FAILED_FEASIBLE ; } } else { block_pack_status = BLK_FAILED_FEASIBLE ; for ( const auto & chain : chain_root_pins ) { for ( size_t tieOff = 0 ; tieOff < chain . size ( ) ; tieOff ++ ) { if ( pb_graph_node == chain [ tieOff ] -> parent_node ) { block_pack_status = BLK_PASSED ; break ; } if ( is_long_chain ) break ; } } } } return block_pack_status ; }
This function takes the root block of a chain molecule and a proposed
 placement primitive for this block.
This function takes the root block of a chain molecule and a proposed placement primitive for this block .
// if this block is part of a long chain or it is driven by a cluster // input pin we need to check the placement legality of this block // Depending on the logic synthesis even small chains that can fit within one // cluster might need to start at the top of the cluster as their input can be // driven by a global gnd or vdd. Therefore even if this is not a long chain // but its input pin is driven by a net, the placement legality is checked. // if this chain has a chain id assigned to it (implies is_long_chain too) // the chosen primitive should be a valid starting point for the chain // long chains should only be placed at the top of the chain tieOff = 0 // the chain doesn't have an assigned chain_id yet // check if this chosen primitive is one of the possible // starting points for this chain. // this location matches with the one of the dedicated chain // input from outside logic block, therefore it is feasible // long chains should only be placed at the top of the chain tieOff = 0