openfpga/src/base/openfpga_lut_truth_table_fixup.cpp
/********************************************************************
 * Apply the fix-up to truth table of LUT according to its pin
 * rotation status by packer
 *
 * Note: 
 *   - pb must represents a LUT pb in the graph and it should be primitive
 *******************************************************************/
Apply the fix-up to truth table of LUT according to its pin
rotation status by packer

- pb must represents a LUT pb in the graph and it should be primitive
Apply the fix - up to truth table of LUT according to its pin rotation status by packer - pb must represents a LUT pb in the graph and it should be primitive
static 
void fix_up_lut_atom_block_truth_table(const AtomContext& atom_ctx,
                                       t_pb* pb,
                                       const t_pb_routes& pb_route,
                                       VprClusteringAnnotation& vpr_clustering_annotation,
                                       const bool& verbose) {
  t_pb_graph_node* pb_graph_node = pb->pb_graph_node;
  t_pb_type* pb_type = pb->pb_graph_node->pb_type;
  VTR_ASSERT(LUT_CLASS == pb_type->class_type);
  for (int iport = 0; iport < pb_type->num_ports; ++iport) {
    if (IN_PORT != pb_type->ports[iport].type || true == pb_type->ports[iport].is_clock) {
      continue;
    }
    if (pb_type->ports[iport].equivalent == PortEquivalence::NONE) {
      continue;
    }
    AtomBlockId atom_blk = atom_ctx.nlist.find_block(pb->name);
    VTR_ASSERT(atom_blk);
    AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, pb_type->ports[iport].model_port);
    if (!atom_port) { 
      continue;
    }
    std::vector<int> rotated_pin_map(pb_type->ports[iport].num_pins, -1);
    for (int ipin = 0; ipin < pb_type->ports[iport].num_pins; ++ipin) {
      int node_index = pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster;
      if (pb_route.count(node_index)) {
        AtomNetId atom_net = pb_route[node_index].atom_net_id;
        VTR_ASSERT(atom_net);
        for (AtomPinId atom_pin : atom_ctx.nlist.port_pins(atom_port)) {
          AtomNetId atom_pin_net = atom_ctx.nlist.pin_net(atom_pin);
          if (atom_pin_net == atom_net) {
            rotated_pin_map[ipin] = atom_ctx.nlist.pin_port_bit(atom_pin);
            break;
          }
        }
      }
    }
    const AtomNetlist::TruthTable& orig_tt = atom_ctx.nlist.block_truth_table(atom_blk);
    const AtomNetlist::TruthTable& adapt_tt = lut_truth_table_adaption(orig_tt, rotated_pin_map); 
    vpr_clustering_annotation.adapt_truth_table(pb, adapt_tt);
    VTR_LOGV(verbose, "Original truth table\n");
    VTR_LOGV(verbose, "Index: ");
    for (size_t i = 0; i < rotated_pin_map.size(); ++i) {
      if (0 < i) {
        VTR_LOGV(verbose, ",");
      }
      VTR_LOGV(verbose, "%lu", i);
    }
    VTR_LOGV(verbose, "\n");
    for (const std::string& tt_line : truth_table_to_string(orig_tt)) {
      VTR_LOGV(verbose, "\t%s\n", tt_line.c_str());
    }
    VTR_LOGV(verbose, "\n");
    VTR_LOGV(verbose, "Pin rotation map: ");
    for (size_t i = 0; i < rotated_pin_map.size(); ++i) {
      if (0 < i) {
        VTR_LOGV(verbose, ",");
      }
      if (-1 == rotated_pin_map[i]) {
        VTR_LOGV(verbose, "open");
      } else {
        VTR_LOGV(verbose, "%lu", rotated_pin_map[i]);
      }
    }
    VTR_LOGV(verbose, "\n");
    VTR_LOGV(verbose, "Adapt truth table\n");
    for (const std::string& tt_line : truth_table_to_string(adapt_tt)) {
      VTR_LOGV(verbose, "\t%s\n", tt_line.c_str());
    }
    VTR_LOGV(verbose, "\n");
  }
}
static void fix_up_lut_atom_block_truth_table ( const AtomContext & atom_ctx , t_pb * pb , const t_pb_routes & pb_route , VprClusteringAnnotation & vpr_clustering_annotation , const bool & verbose ) { t_pb_graph_node * pb_graph_node = pb -> pb_graph_node ; t_pb_type * pb_type = pb -> pb_graph_node -> pb_type ; VTR_ASSERT ( LUT_CLASS == pb_type -> class_type ) ; for ( int iport = 0 ; iport < pb_type -> num_ports ; ++ iport ) { if ( IN_PORT != pb_type -> ports [ iport ] . type || true == pb_type -> ports [ iport ] . is_clock ) { continue ; } if ( pb_type -> ports [ iport ] . equivalent == PortEquivalence :: NONE ) { continue ; } AtomBlockId atom_blk = atom_ctx . nlist . find_block ( pb -> name ) ; VTR_ASSERT ( atom_blk ) ; AtomPortId atom_port = atom_ctx . nlist . find_atom_port ( atom_blk , pb_type -> ports [ iport ] . model_port ) ; if ( ! atom_port ) { continue ; } std :: vector < int > rotated_pin_map ( pb_type -> ports [ iport ] . num_pins , -1 ) ; for ( int ipin = 0 ; ipin < pb_type -> ports [ iport ] . num_pins ; ++ ipin ) { int node_index = pb_graph_node -> input_pins [ iport ] [ ipin ] . pin_count_in_cluster ; if ( pb_route . count ( node_index ) ) { AtomNetId atom_net = pb_route [ node_index ] . atom_net_id ; VTR_ASSERT ( atom_net ) ; for ( AtomPinId atom_pin : atom_ctx . nlist . port_pins ( atom_port ) ) { AtomNetId atom_pin_net = atom_ctx . nlist . pin_net ( atom_pin ) ; if ( atom_pin_net == atom_net ) { rotated_pin_map [ ipin ] = atom_ctx . nlist . pin_port_bit ( atom_pin ) ; break ; } } } } const AtomNetlist :: TruthTable & orig_tt = atom_ctx . nlist . block_truth_table ( atom_blk ) ; const AtomNetlist :: TruthTable & adapt_tt = lut_truth_table_adaption ( orig_tt , rotated_pin_map ) ; vpr_clustering_annotation . adapt_truth_table ( pb , adapt_tt ) ; VTR_LOGV ( verbose , " \n " ) ; VTR_LOGV ( verbose , " " ) ; for ( size_t i = 0 ; i < rotated_pin_map . size ( ) ; ++ i ) { if ( 0 < i ) { VTR_LOGV ( verbose , " " ) ; } VTR_LOGV ( verbose , " " , i ) ; } VTR_LOGV ( verbose , " \n " ) ; for ( const std :: string & tt_line : truth_table_to_string ( orig_tt ) ) { VTR_LOGV ( verbose , " \t \n " , tt_line . c_str ( ) ) ; } VTR_LOGV ( verbose , " \n " ) ; VTR_LOGV ( verbose , " " ) ; for ( size_t i = 0 ; i < rotated_pin_map . size ( ) ; ++ i ) { if ( 0 < i ) { VTR_LOGV ( verbose , " " ) ; } if ( -1 == rotated_pin_map [ i ] ) { VTR_LOGV ( verbose , " " ) ; } else { VTR_LOGV ( verbose , " " , rotated_pin_map [ i ] ) ; } } VTR_LOGV ( verbose , " \n " ) ; VTR_LOGV ( verbose , " \n " ) ; for ( const std :: string & tt_line : truth_table_to_string ( adapt_tt ) ) { VTR_LOGV ( verbose , " \t \n " , tt_line . c_str ( ) ) ; } VTR_LOGV ( verbose , " \n " ) ; } }
Apply the fix-up to truth table of LUT according to its pin
 rotation status by packer
Apply the fix - up to truth table of LUT according to its pin rotation status by packer
/* We only care about input ports whose pins are equivalent */ /* Reach here, we have to apply a fix-up */ /* Port exists (some LUTs may have no input and hence no port in the atom netlist) */ /* Find the pin rotation status and record it ,
     * Note that some LUT inputs may not be used, we set them to be open by default
     */ /* The pin is mapped to a net, find the original pin in the atom netlist */ /* We can apply truth table adaption now
     * For unused inputs : insert dont care
     * For used inputs : find the bit in the truth table rows and move it by the given mapping
     */ /* Print info is in the verbose mode */