#include <algorithm>
#include <numeric>

#include "vtr_assert.h"
#include "vtr_log.h"
#include "vpr_error.h"
/*
 *
 * NetlistIdRemapper class implementation
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId NetlistIdRemapper<BlockId, PortId, PinId, NetId>::new_block_id(BlockId old_id) const {
    return block_id_map_[old_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortId NetlistIdRemapper<BlockId, PortId, PinId, NetId>::new_port_id(PortId old_id) const {
    return port_id_map_[old_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId NetlistIdRemapper<BlockId, PortId, PinId, NetId>::new_pin_id(PinId old_id) const {
    return pin_id_map_[old_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId NetlistIdRemapper<BlockId, PortId, PinId, NetId>::new_net_id(NetId old_id) const {
    return net_id_map_[old_id];
}

/*
 *
 * Netlist class implementation
 *
 */

template<typename BlockId, typename PortId, typename PinId, typename NetId>
Netlist<BlockId, PortId, PinId, NetId>::Netlist(std::string name, std::string id)
    : netlist_name_(name)
    , netlist_id_(id) {}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
Netlist<BlockId, PortId, PinId, NetId>::~Netlist() = default;

/*
 *
 * Netlist
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
const std::string& Netlist<BlockId, PortId, PinId, NetId>::netlist_name() const {
    return netlist_name_;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
const std::string& Netlist<BlockId, PortId, PinId, NetId>::netlist_id() const {
    return netlist_id_;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::is_dirty() const {
    return dirty_;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::is_compressed() const {
    return !is_dirty();
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::print_stats() const {
    VTR_LOG("Blocks  %zu capacity/size: %.2f\n", block_ids_.size(), float(block_ids_.capacity()) / block_ids_.size());
    VTR_LOG("Ports   %zu capacity/size: %.2f\n", port_ids_.size(), float(port_ids_.capacity()) / port_ids_.size());
    VTR_LOG("Pins    %zu capacity/size: %.2f\n", pin_ids_.size(), float(pin_ids_.capacity()) / pin_ids_.size());
    VTR_LOG("Nets    %zu capacity/size: %.2f\n", net_ids_.size(), float(net_ids_.capacity()) / net_ids_.size());
    VTR_LOG("Strings %zu capacity/size: %.2f\n", string_ids_.size(), float(string_ids_.capacity()) / string_ids_.size());
}

/*
 *
 * Blocks
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
const std::string& Netlist<BlockId, PortId, PinId, NetId>::block_name(const BlockId blk_id) const {
    StringId str_id = block_names_[blk_id];
    return strings_[str_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::block_is_combinational(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    return block_clock_pins(blk_id).size() == 0;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::attr_range Netlist<BlockId, PortId, PinId, NetId>::block_attrs(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    return vtr::make_range(block_attrs_[blk_id].begin(), block_attrs_[blk_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::param_range Netlist<BlockId, PortId, PinId, NetId>::block_params(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    return vtr::make_range(block_params_[blk_id].begin(), block_params_[blk_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::block_pins(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    return vtr::make_range(block_pins_[blk_id].begin(), block_pins_[blk_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::block_input_pins(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_pins_[blk_id].begin();

    auto end = block_pins_[blk_id].begin() + block_num_input_pins_[blk_id];

    return vtr::make_range(begin, end);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::block_output_pins(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_pins_[blk_id].begin() + block_num_input_pins_[blk_id];

    auto end = begin + block_num_output_pins_[blk_id];

    return vtr::make_range(begin, end);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::block_clock_pins(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_pins_[blk_id].begin()
                 + block_num_input_pins_[blk_id]
                 + block_num_output_pins_[blk_id];

    auto end = begin + block_num_clock_pins_[blk_id];

    VTR_ASSERT_SAFE(end == block_pins_[blk_id].end());

    return vtr::make_range(begin, end);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::port_range Netlist<BlockId, PortId, PinId, NetId>::block_ports(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    return vtr::make_range(block_ports_[blk_id].begin(), block_ports_[blk_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::port_range Netlist<BlockId, PortId, PinId, NetId>::block_input_ports(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_ports_[blk_id].begin();

    auto end = block_ports_[blk_id].begin() + block_num_input_ports_[blk_id];

    return vtr::make_range(begin, end);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::port_range Netlist<BlockId, PortId, PinId, NetId>::block_output_ports(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_ports_[blk_id].begin() + block_num_input_ports_[blk_id];

    auto end = begin + block_num_output_ports_[blk_id];

    return vtr::make_range(begin, end);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::port_range Netlist<BlockId, PortId, PinId, NetId>::block_clock_ports(const BlockId blk_id) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    auto begin = block_ports_[blk_id].begin()
                 + block_num_input_ports_[blk_id]
                 + block_num_output_ports_[blk_id];

    auto end = begin + block_num_clock_ports_[blk_id];

    VTR_ASSERT_SAFE(end == block_ports_[blk_id].end());

    return vtr::make_range(begin, end);
}

/*
 *
 * Ports
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
const std::string& Netlist<BlockId, PortId, PinId, NetId>::port_name(const PortId port_id) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));

    StringId str_id = port_names_[port_id];
    return strings_[str_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::port_block(const PortId port_id) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));

    return port_blocks_[port_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::port_pins(const PortId port_id) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));

    return vtr::make_range(port_pins_[port_id].begin(), port_pins_[port_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId Netlist<BlockId, PortId, PinId, NetId>::port_pin(const PortId port_id, const BitIndex port_bit) const {
    //Convenience look-up bypassing port
    return find_pin(port_id, port_bit);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::port_net(const PortId port_id, const BitIndex port_bit) const {
    //port_pin() will validate that port_bit and port_id are valid so don't
    //check redundently here

    //Convenience look-up bypassing port and pin
    PinId pin_id = port_pin(port_id, port_bit);
    if (pin_id) {
        return pin_net(pin_id);
    } else {
        return NetId::INVALID();
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BitIndex Netlist<BlockId, PortId, PinId, NetId>::port_width(const PortId port_id) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));

    return port_widths_[port_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortType Netlist<BlockId, PortId, PinId, NetId>::port_type(const PortId port_id) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));

    return port_types_[port_id];
}

/*
 *
 * Pins
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
std::string Netlist<BlockId, PortId, PinId, NetId>::pin_name(const PinId pin_id) const {
    BlockId blk = pin_block(pin_id);
    PortId port = pin_port(pin_id);

    return block_name(blk) + "." + port_name(port) + "[" + std::to_string(pin_port_bit(pin_id)) + "]";
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinType Netlist<BlockId, PortId, PinId, NetId>::pin_type(const PinId pin_id) const {
    auto port_id = pin_port(pin_id);

    PinType type = PinType::OPEN;
    switch (port_type(port_id)) {
        case PortType::INPUT: /*fallthrough */;
        case PortType::CLOCK:
            type = PinType::SINK;
            break;
        case PortType::OUTPUT:
            type = PinType::DRIVER;
            break;
        default:
            VTR_ASSERT_OPT_MSG(false, "Valid port type");
    }
    return type;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::pin_net(const PinId pin_id) const {
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    return pin_nets_[pin_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
int Netlist<BlockId, PortId, PinId, NetId>::pin_net_index(const PinId pin_id) const {
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    return pin_net_indices_[pin_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortId Netlist<BlockId, PortId, PinId, NetId>::pin_port(const PinId pin_id) const {
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    return pin_ports_[pin_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BitIndex Netlist<BlockId, PortId, PinId, NetId>::pin_port_bit(const PinId pin_id) const {
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    return pin_port_bits_[pin_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::pin_block(const PinId pin_id) const {
    //Convenience lookup bypassing the port
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    PortId port_id = pin_port(pin_id);
    return port_block(port_id);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortType Netlist<BlockId, PortId, PinId, NetId>::pin_port_type(const PinId pin_id) const {
    PortId port_id = pin_port(pin_id);

    return port_type(port_id);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::pin_is_constant(const PinId pin_id) const {
    VTR_ASSERT_SAFE(valid_pin_id(pin_id));

    return pin_is_constant_[pin_id];
}

/*
 *
 * Nets
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
const std::string& Netlist<BlockId, PortId, PinId, NetId>::net_name(const NetId net_id) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));

    StringId str_id = net_names_[net_id];
    return strings_[str_id];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::net_pins(const NetId net_id) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));

    return vtr::make_range(net_pins_[net_id].begin(), net_pins_[net_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId Netlist<BlockId, PortId, PinId, NetId>::net_pin(const NetId net_id, int net_pin_index) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));
    VTR_ASSERT_SAFE_MSG(net_pin_index >= 0 && size_t(net_pin_index) < net_pins_[net_id].size(), "Pin index must be in range");

    return net_pins_[net_id][net_pin_index];
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::net_pin_block(const NetId net_id, int net_pin_index) const {
    auto pin_id = net_pin(net_id, net_pin_index);

    return pin_block(pin_id);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId Netlist<BlockId, PortId, PinId, NetId>::net_driver(const NetId net_id) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));

    if (net_pins_[net_id].size() > 0) {
        return net_pins_[net_id][0];
    } else {
        return PinId::INVALID();
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::net_driver_block(const NetId net_id) const {
    auto driver_pin_id = net_driver(net_id);
    if (driver_pin_id) {
        return pin_block(driver_pin_id);
    }
    return BlockId::INVALID();
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::net_sinks(const NetId net_id) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));

    return vtr::make_range(++net_pins_[net_id].begin(), net_pins_[net_id].end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::net_is_constant(const NetId net_id) const {
    VTR_ASSERT_SAFE(valid_net_id(net_id));

    //Look-up the driver
    auto driver_pin_id = net_driver(net_id);
    if (driver_pin_id) {
        //Valid driver, see it is constant
        return pin_is_constant(driver_pin_id);
    }

    //No valid driver so can't be const
    return false;
}

/*
 *
 * Aggregates
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::block_range Netlist<BlockId, PortId, PinId, NetId>::blocks() const {
    return vtr::make_range(block_ids_.begin(), block_ids_.end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::port_range Netlist<BlockId, PortId, PinId, NetId>::ports() const {
    return vtr::make_range(port_ids_.begin(), port_ids_.end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::pin_range Netlist<BlockId, PortId, PinId, NetId>::pins() const {
    return vtr::make_range(pin_ids_.begin(), pin_ids_.end());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::net_range Netlist<BlockId, PortId, PinId, NetId>::nets() const {
    return vtr::make_range(net_ids_.begin(), net_ids_.end());
}

/*
 *
 * Lookups
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::find_block(const std::string& name) const {
    auto str_id = find_string(name);
    if (!str_id) {
        return BlockId::INVALID();
    } else {
        return find_block(str_id);
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortId Netlist<BlockId, PortId, PinId, NetId>::find_port(const BlockId blk_id, const std::string& name) const {
    VTR_ASSERT_SAFE(valid_block_id(blk_id));

    //Since we only know the port name, we must search all the ports
    for (auto port_id : block_ports(blk_id)) {
        if (port_name(port_id) == name) {
            return port_id;
        }
    }
    return PortId::INVALID();
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::find_net(const std::string& name) const {
    auto str_id = find_string(name);
    if (!str_id) {
        return NetId::INVALID();
    } else {
        return find_net(str_id);
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId Netlist<BlockId, PortId, PinId, NetId>::find_pin(const PortId port_id, BitIndex port_bit) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));
    VTR_ASSERT_SAFE(valid_port_bit(port_id, port_bit));

    //Pins are stored in ascending order of bit index,
    //so we can binary search for the specific bit
    auto port_bit_cmp = [&](const PinId pin_id, BitIndex bit_index) {
        return pin_port_bit(pin_id) < bit_index;
    };

    auto pins_rng = port_pins(port_id);

    //Finds the location where the pin with bit index port_bit should be located (if it exists)
    auto iter = std::lower_bound(pins_rng.begin(), pins_rng.end(), port_bit, port_bit_cmp);

    if (iter == pins_rng.end() || pin_port_bit(*iter) != port_bit) {
        //Either the end of the pins (i.e. not found), or
        //the value does not match (indicating a gap in the indicies, so also not found)
        return PinId::INVALID();
    } else {
        //Found it
        VTR_ASSERT_SAFE(pin_port_bit(*iter) == port_bit);
        return *iter;
    }
}

/*
 *
 * Validation
 *
 */
//Top-level verification method, checks that the sizes
//references, and lookups are all consistent.
template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::verify() const {
    bool valid = true;

    //Verify data structure consistency
    valid &= verify_sizes();
    valid &= verify_refs();
    valid &= verify_lookups();

    //Verify logical consistency
    valid &= verify_block_invariants();

    return valid;
}

//Checks that the sizes of internal data structures
//are consistent. Should take constant time.
template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::verify_sizes() const {
    bool valid = true;
    valid &= validate_block_sizes();
    valid &= validate_port_sizes();
    valid &= validate_pin_sizes();
    valid &= validate_net_sizes();
    valid &= validate_string_sizes();
    return valid;
}

//Checks that all cross-references are consistent.
//Should take linear time.
template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::verify_refs() const {
    bool valid = true;
    valid &= validate_block_port_refs();
    valid &= validate_port_pin_refs();
    valid &= validate_block_pin_refs();
    valid &= validate_net_pin_refs();
    valid &= validate_string_refs();

    return valid;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::verify_lookups() const {
    //Verify that fast look-ups are consistent

    //Blocks
    for (auto blk_id : blocks()) {
        const auto& name = block_name(blk_id);
        if (find_block(name) != blk_id) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block lookup by name mismatch");
        }
    }

    //Ports
    for (auto port_id : port_ids_) {
        auto blk_id = port_block(port_id);
        const auto& name = port_name(port_id);
        if (find_port(blk_id, name) != port_id) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Port lookup by name mismatch");
        }
    }

    //Pins
    for (auto pin_id : pin_ids_) {
        auto port_id = pin_port(pin_id);
        auto bit = pin_port_bit(pin_id);
        if (find_pin(port_id, bit) != pin_id) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Pin lookup by name mismatch");
        }
    }

    //Nets
    for (auto net_id : nets()) {
        const auto& name = net_name(net_id);
        if (find_net(name) != net_id) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Net lookup by name mismatch");
        }
    }

    //Strings
    for (auto str_id : string_ids_) {
        const auto& name = strings_[str_id];
        if (find_string(name) != str_id) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "String lookup by name mismatch");
        }
    }
    return true;
}

/*
 *
 * Mutators
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::create_block(const std::string name) {
    //Must have a non-empty name
    VTR_ASSERT_MSG(!name.empty(), "Non-Empty block name");

    //Check if the block has already been created
    StringId name_id = create_string(name);
    BlockId blk_id = find_block(name_id);

    if (blk_id == BlockId::INVALID()) {
        //Not found, create it

        //Reserve an id
        blk_id = BlockId(block_ids_.size());
        block_ids_.push_back(blk_id);

        //Initialize the data
        block_names_.push_back(name_id);
        block_attrs_.emplace_back();
        block_params_.emplace_back();

        //Initialize the look-ups
        block_name_to_block_id_.insert(name_id, blk_id);

        block_pins_.emplace_back();
        block_num_input_pins_.push_back(0);
        block_num_output_pins_.push_back(0);
        block_num_clock_pins_.push_back(0);

        block_ports_.emplace_back();
        block_num_input_ports_.push_back(0);
        block_num_output_ports_.push_back(0);
        block_num_clock_ports_.push_back(0);
    }

    //Check post-conditions: values
    VTR_ASSERT(valid_block_id(blk_id));
    VTR_ASSERT(block_name(blk_id) == name);
    VTR_ASSERT_SAFE(find_block(name) == blk_id);

    return blk_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PortId Netlist<BlockId, PortId, PinId, NetId>::create_port(const BlockId blk_id, const std::string name, BitIndex width, PortType type) {
    //Check pre-conditions
    VTR_ASSERT_MSG(valid_block_id(blk_id), "Valid block id");

    //See if the port already exists
    StringId name_id = create_string(name);
    PortId port_id = find_port(blk_id, name);
    if (!port_id) { //Not found, create it
                    //Reserve an id
        port_id = PortId(port_ids_.size());
        port_ids_.push_back(port_id);

        //Initialize the per-port-instance data
        port_blocks_.push_back(blk_id);
        port_names_.push_back(name_id);
        port_widths_.push_back(width);
        port_types_.push_back(type);

        //Allocate the pins, initialize to invalid Ids
        port_pins_.emplace_back();
    }

    //Check post-conditions: values
    VTR_ASSERT(valid_port_id(port_id));
    VTR_ASSERT(port_block(port_id) == blk_id);
    VTR_ASSERT(port_width(port_id) == width);

    return port_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
PinId Netlist<BlockId, PortId, PinId, NetId>::create_pin(const PortId port_id, BitIndex port_bit, const NetId net_id, const PinType type, bool is_const) {
    //Check pre-conditions (valid ids)
    VTR_ASSERT_MSG(valid_port_id(port_id), "Valid port id");
    VTR_ASSERT_MSG(valid_port_bit(port_id, port_bit), "Valid port bit");
    VTR_ASSERT_MSG(valid_net_id(net_id), "Valid net id");

    //See if the pin already exists
    PinId pin_id = find_pin(port_id, port_bit);
    if (!pin_id) {
        //Not found, create it

        //Reserve an id
        pin_id = PinId(pin_ids_.size());
        pin_ids_.push_back(pin_id);

        //Initialize the pin data
        pin_ports_.push_back(port_id);
        pin_port_bits_.push_back(port_bit);
        pin_nets_.push_back(net_id);
        pin_is_constant_.push_back(is_const);

        //Add the pin to the net
        int pins_net_index = associate_pin_with_net(pin_id, type, net_id);

        //Save the net index of the pin
        pin_net_indices_.push_back(pins_net_index);

        //Add the pin to the port
        associate_pin_with_port(pin_id, port_id);

        //Add the pin to the block
        associate_pin_with_block(pin_id, port_type(port_id), port_block(port_id));
    }

    //Check post-conditions: values
    VTR_ASSERT(valid_pin_id(pin_id));
    VTR_ASSERT(pin_port(pin_id) == port_id);
    VTR_ASSERT(pin_port_bit(pin_id) == port_bit);
    VTR_ASSERT(pin_net(pin_id) == net_id);
    VTR_ASSERT(pin_is_constant(pin_id) == is_const);
    VTR_ASSERT_SAFE(find_pin(port_id, port_bit) == pin_id);

    return pin_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::create_net(const std::string name) {
    //Creates an empty net (or returns an existing one)
    VTR_ASSERT_MSG(!name.empty(), "Valid net name");

    //Check if the net has already been created
    StringId name_id = create_string(name);
    NetId net_id = find_net(name_id);
    if (net_id == NetId::INVALID()) {
        //Not found, create it

        //Reserve an id
        net_id = NetId(net_ids_.size());
        net_ids_.push_back(net_id);

        //Initialize the data
        net_names_.push_back(name_id);

        //Initialize the look-ups
        net_name_to_net_id_.insert(name_id, net_id);

        //Initialize with no driver
        net_pins_.emplace_back();
        net_pins_[net_id].emplace_back(PinId::INVALID());

        VTR_ASSERT(net_pins_[net_id].size() == 1);
        VTR_ASSERT(net_pins_[net_id][0] == PinId::INVALID());
    }

    //Check post-conditions: values
    VTR_ASSERT(valid_net_id(net_id));
    VTR_ASSERT(net_name(net_id) == name);
    VTR_ASSERT(find_net(name) == net_id);

    return net_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::add_net(const std::string name, PinId driver, std::vector<PinId> sinks) {
    //Creates a net with a full set of pins
    VTR_ASSERT_MSG(!find_net(name), "Net should not exist");

    //Create the empty net
    NetId net_id = create_net(name);

    //Set the driver and sinks of the net
    auto& dest_pins = net_pins_[net_id];
    dest_pins[0] = driver;
    dest_pins.insert(dest_pins.end(),
                     std::make_move_iterator(sinks.begin()),
                     std::make_move_iterator(sinks.end()));

    //Associate each pin with the net
    int net_index = 0;
    pin_nets_[driver] = net_id;
    pin_net_indices_[driver] = net_index++;
    for (auto sink : sinks) {
        pin_nets_[sink] = net_id;
        pin_net_indices_[sink] = net_index++;
    }

    return net_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::set_pin_is_constant(const PinId pin_id, const bool value) {
    VTR_ASSERT(valid_pin_id(pin_id));

    pin_is_constant_[pin_id] = value;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::set_pin_net(const PinId pin, PinType type, const NetId net) {
    VTR_ASSERT(valid_pin_id(pin));

    VTR_ASSERT((type == PinType::DRIVER && pin_port_type(pin) == PortType::OUTPUT)
               || (type == PinType::SINK && (pin_port_type(pin) == PortType::INPUT || pin_port_type(pin) == PortType::CLOCK)));

    NetId orig_net = pin_net(pin);
    if (orig_net) {
        //Clean up the pin reference on the original net
        remove_net_pin(orig_net, pin);
    }

    //Mark the pin's net
    pin_nets_[pin] = net;

    //Add the pin to the net
    int pins_net_index = associate_pin_with_net(pin, type, net);

    //Save the pin's index within the net
    pin_net_indices_[pin] = pins_net_index;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::set_block_name(const BlockId blk_id, const std::string new_name) {
    VTR_ASSERT(valid_block_id(blk_id));

    //Names must be unique -- no duplicates allowed
    BlockId existing_blk_id = find_block(new_name);
    if (existing_blk_id) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Can not re-name block '%s' to '%s' (a block named '%s' already exists).",
                        block_name(blk_id).c_str(),
                        new_name.c_str(),
                        new_name.c_str());
    }

    //Remove old name-look-up
    {
        StringId old_string = find_string(block_name(blk_id));
        block_name_to_block_id_[old_string] = BlockId::INVALID();
    }

    //Re-name the block
    StringId new_string = create_string(new_name);
    block_names_[blk_id] = new_string;

    //Update name-look-up
    block_name_to_block_id_.insert(new_string, blk_id);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::set_block_attr(const BlockId blk_id, const std::string& name, const std::string& value) {
    VTR_ASSERT(valid_block_id(blk_id));

    block_attrs_[blk_id][name] = value;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::set_block_param(const BlockId blk_id, const std::string& name, const std::string& value) {
    VTR_ASSERT(valid_block_id(blk_id));

    block_params_[blk_id][name] = value;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::merge_nets(const NetId driver_net, const NetId sink_net) {
    VTR_ASSERT(valid_net_id(driver_net));
    VTR_ASSERT(valid_net_id(sink_net));

    //Sink net must not have a driver pin
    PinId sink_driver = net_driver(sink_net);
    if (sink_driver) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Can not merge nets '%s' and '%s' (sink net '%s' should have no driver, but is driven by pin '%s')",
                        net_name(driver_net).c_str(),
                        net_name(sink_net).c_str(),
                        net_name(sink_net).c_str(),
                        pin_name(sink_driver).c_str());
    }

    //We allow the driver net to (potentially) have no driver yet,
    //so we don't check to ensure it exists

    //
    //Merge the nets
    //

    //Move the sinks to the driver net
    for (PinId sink_pin : net_sinks(sink_net)) {
        //Update pin -> net references, also adds pins to driver_net
        set_pin_net(sink_pin, pin_type(sink_pin), driver_net);
    }

    //Remove the sink net
    // Note that we drop the sink net's pin references first,
    // this ensures remove_net() will only clean-up the net
    // data, and will not modify the (already moved) pins
    net_pins_[sink_net].clear(); //Drop sink_net's pin references
    remove_net(sink_net);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_block(const BlockId blk_id) {
    VTR_ASSERT(valid_block_id(blk_id));

    //Remove the ports
    for (PortId block_port : block_ports(blk_id)) {
        remove_port(block_port);
    }

    //Invalidate look-up
    StringId name_id = block_names_[blk_id];
    block_name_to_block_id_.insert(name_id, BlockId::INVALID());

    //Mark as invalid
    block_ids_[blk_id] = BlockId::INVALID();

    //Call derived class' remove()
    remove_block_impl(blk_id);

    //Mark netlist dirty
    dirty_ = true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_port(const PortId port_id) {
    VTR_ASSERT(valid_port_id(port_id));

    //Remove the pins
    for (auto pin : port_pins(port_id)) {
        if (valid_pin_id(pin)) {
            remove_pin(pin);
        }
    }

    //Mark as invalid
    port_ids_[port_id] = PortId::INVALID();

    //Call derived class' remove()
    remove_port_impl(port_id);

    //Mark netlist dirty
    dirty_ = true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_pin(const PinId pin_id) {
    VTR_ASSERT(valid_pin_id(pin_id));

    //Find the associated net
    NetId net = pin_net(pin_id);

    //Remove the pin from the associated net/port/block
    remove_net_pin(net, pin_id);

    //Mark as invalid
    pin_ids_[pin_id] = PinId::INVALID();

    //Call derived class' remove()
    remove_pin_impl(pin_id);

    //Mark netlist dirty
    dirty_ = true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_net(const NetId net_id) {
    VTR_ASSERT(valid_net_id(net_id));

    //Disassociate the pins from the net
    for (auto pin_id : net_pins(net_id)) {
        if (pin_id) {
            pin_nets_[pin_id] = NetId::INVALID();
            pin_net_indices_[pin_id] = INVALID_INDEX;
        }
    }
    //Invalidate look-up
    StringId name_id = net_names_[net_id];
    net_name_to_net_id_.insert(name_id, NetId::INVALID());

    //Mark as invalid
    net_ids_[net_id] = NetId::INVALID();

    //Call derived class' remove()
    remove_net_impl(net_id);

    //Mark netlist dirty
    dirty_ = true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_net_pin(const NetId net_id, const PinId pin_id) {
    //Remove a net-pin connection
    //
    //Note that during sweeping either the net or pin could be invalid (i.e. already swept)
    //so we check before trying to use them

    if (valid_net_id(net_id)) {
        //Warning: this is slow!
        auto iter = std::find(net_pins_[net_id].begin(), net_pins_[net_id].end(), pin_id); //Linear search
        VTR_ASSERT(iter != net_pins_[net_id].end());

        if (net_driver(net_id) == pin_id) {
            //Mark no driver
            net_pins_[net_id][0] = PinId::INVALID();
        } else {
            //Remove sink
            net_pins_[net_id].erase(iter); //Linear remove
        }

        //Note: since we fully update the net we don't need to mark the netlist dirty_
    }

    //Disassociate the pin with the net
    if (valid_pin_id(pin_id)) {
        pin_nets_[pin_id] = NetId::INVALID();
        pin_net_indices_[pin_id] = INVALID_INDEX;

        //Mark netlist dirty, since we are leaving an invalid net id
        dirty_ = true;
    }
}

/*
 *
 * Internal utilities
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::IdRemapper Netlist<BlockId, PortId, PinId, NetId>::remove_and_compress() {
    remove_unused();
    return compress();
}

//Compress the various netlist components to remove invalid entries
// Note: this invalidates all Ids
template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::IdRemapper Netlist<BlockId, PortId, PinId, NetId>::compress() {
    //Build the mappings from old to new id's, potentially
    //re-ordering for improved cache locality
    //
    //The vectors passed as parameters are initialized as a mapping from old to new index
    // e.g. block_id_map[old_id] == new_id
    IdRemapper id_remapper = build_id_maps();

    clean_nets(id_remapper.net_id_map_);
    clean_pins(id_remapper.pin_id_map_);
    clean_ports(id_remapper.port_id_map_);
    clean_blocks(id_remapper.block_id_map_);
    //TODO: clean strings
    //TODO: iterative cleaning?

    //Now we re-build all the cross references
    // Note: net references must be rebuilt (to remove pins) before
    //       the pin references can be rebuilt (to account for index changes
    //       due to pins being removed from the net)
    rebuild_block_refs(id_remapper.pin_id_map_, id_remapper.port_id_map_);
    rebuild_port_refs(id_remapper.block_id_map_, id_remapper.pin_id_map_);
    rebuild_net_refs(id_remapper.pin_id_map_);
    rebuild_pin_refs(id_remapper.port_id_map_, id_remapper.net_id_map_);

    //Re-build the lookups
    rebuild_lookups();

    //Resize containers to exact size
    shrink_to_fit();

    //Netlist is now clean
    dirty_ = false;

    return id_remapper;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::remove_unused() {
    //Mark any nets/pins/ports/blocks which are not in use as invalid
    //so they will be removed

    bool found_unused;
    do {
        found_unused = false;
        //Nets with no connected pins
        for (auto net_id : net_ids_) {
            if (net_id
                && !net_driver(net_id)
                && net_sinks(net_id).size() == 0) {
                remove_net(net_id);
                found_unused = true;
            }
        }

        //Pins with no connected nets
        for (auto pin_id : pin_ids_) {
            if (pin_id && !pin_net(pin_id)) {
                remove_pin(pin_id);
                found_unused = true;
            }
        }

        //Empty ports
        for (auto port_id : port_ids_) {
            if (port_id && port_pins(port_id).size() == 0) {
                remove_port(port_id);
                found_unused = true;
            }
        }

        //Blocks with no pins
        for (auto blk_id : block_ids_) {
            if (blk_id && block_pins(blk_id).size() == 0) {
                remove_block(blk_id);
                found_unused = true;
            }
        }

    } while (found_unused);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::IdRemapper Netlist<BlockId, PortId, PinId, NetId>::build_id_maps() {
    IdRemapper id_remapper;
    id_remapper.block_id_map_ = compress_ids(block_ids_);
    id_remapper.port_id_map_ = compress_ids(port_ids_);
    id_remapper.pin_id_map_ = compress_ids(pin_ids_);
    id_remapper.net_id_map_ = compress_ids(net_ids_);
    return id_remapper;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::clean_blocks(const vtr::vector_map<BlockId, BlockId>& block_id_map) {
    //Update all the block values
    block_ids_ = clean_and_reorder_ids(block_id_map);
    block_names_ = clean_and_reorder_values(block_names_, block_id_map);

    block_pins_ = clean_and_reorder_values(block_pins_, block_id_map);
    block_num_input_pins_ = clean_and_reorder_values(block_num_input_pins_, block_id_map);
    block_num_output_pins_ = clean_and_reorder_values(block_num_output_pins_, block_id_map);
    block_num_clock_pins_ = clean_and_reorder_values(block_num_clock_pins_, block_id_map);

    block_ports_ = clean_and_reorder_values(block_ports_, block_id_map);
    block_num_input_ports_ = clean_and_reorder_values(block_num_input_ports_, block_id_map);
    block_num_output_ports_ = clean_and_reorder_values(block_num_output_ports_, block_id_map);
    block_num_clock_ports_ = clean_and_reorder_values(block_num_clock_ports_, block_id_map);

    block_attrs_ = clean_and_reorder_values(block_attrs_, block_id_map);
    block_params_ = clean_and_reorder_values(block_params_, block_id_map);

    clean_blocks_impl(block_id_map);

    VTR_ASSERT(validate_block_sizes());

    VTR_ASSERT_MSG(are_contiguous(block_ids_), "Ids should be contiguous");
    VTR_ASSERT_MSG(all_valid(block_ids_), "All Ids should be valid");
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::clean_ports(const vtr::vector_map<PortId, PortId>& port_id_map) {
    //Update all the port values
    port_ids_ = clean_and_reorder_ids(port_id_map);
    port_names_ = clean_and_reorder_values(port_names_, port_id_map);
    port_blocks_ = clean_and_reorder_values(port_blocks_, port_id_map);
    port_widths_ = clean_and_reorder_values(port_widths_, port_id_map);
    port_types_ = clean_and_reorder_values(port_types_, port_id_map);
    port_pins_ = clean_and_reorder_values(port_pins_, port_id_map);

    clean_ports_impl(port_id_map);

    VTR_ASSERT(validate_port_sizes());

    VTR_ASSERT_MSG(are_contiguous(port_ids_), "Ids should be contiguous");
    VTR_ASSERT_MSG(all_valid(port_ids_), "All Ids should be valid");
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::clean_pins(const vtr::vector_map<PinId, PinId>& pin_id_map) {
    //Update all the pin values
    pin_ids_ = clean_and_reorder_ids(pin_id_map);
    pin_ports_ = clean_and_reorder_values(pin_ports_, pin_id_map);

    //It is sufficient to merely clean and re-order the pin_port_bits_, since
    //the size of a port (and hence the pin's bit index in the port) does not change
    //during cleaning
    pin_port_bits_ = clean_and_reorder_values(pin_port_bits_, pin_id_map);
    pin_nets_ = clean_and_reorder_values(pin_nets_, pin_id_map);

    //Note that clean and re-order serves only to resize pin_net_indices_, the
    //actual net references are wrong (since net size may have changed during
    //cleaning). They will be updated in rebuild_pin_refs()
    pin_net_indices_ = clean_and_reorder_values(pin_net_indices_, pin_id_map);
    pin_is_constant_ = clean_and_reorder_values(pin_is_constant_, pin_id_map);

    clean_pins_impl(pin_id_map);

    VTR_ASSERT(validate_pin_sizes());

    VTR_ASSERT_MSG(are_contiguous(pin_ids_), "Ids should be contiguous");
    VTR_ASSERT_MSG(all_valid(pin_ids_), "All Ids should be valid");
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::clean_nets(const vtr::vector_map<NetId, NetId>& net_id_map) {
    //Update all the net values
    net_ids_ = clean_and_reorder_ids(net_id_map);
    net_names_ = clean_and_reorder_values(net_names_, net_id_map);
    net_pins_ = clean_and_reorder_values(net_pins_, net_id_map); //Note: actual pin refs are updated in rebuild_net_refs()

    clean_nets_impl(net_id_map);

    VTR_ASSERT(validate_net_sizes());

    VTR_ASSERT_MSG(are_contiguous(net_ids_), "Ids should be contiguous");
    VTR_ASSERT_MSG(all_valid(net_ids_), "All Ids should be valid");
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::rebuild_lookups() {
    //We iterate through the reverse-lookups and update the values (i.e. ids)
    //to the new id values

    //Blocks
    block_name_to_block_id_.clear();
    for (auto blk_id : blocks()) {
        const auto& key = block_names_[blk_id];
        block_name_to_block_id_.insert(key, blk_id);
    }

    //Nets
    net_name_to_net_id_.clear();
    for (auto net_id : nets()) {
        const auto& key = net_names_[net_id];
        net_name_to_net_id_.insert(key, net_id);
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::rebuild_block_refs(const vtr::vector_map<PinId, PinId>& pin_id_map,
                                                                const vtr::vector_map<PortId, PortId>& port_id_map) {
    //Update the pin id references held by blocks
    for (auto blk_id : blocks()) {
        //Before update the references, we need to know how many are valid,
        //so we can also update the numbers of input/output/clock pins

        //Note that we take special care to not modify the pin counts until after
        //they have all been counted (since the block_*_pins() functions depend on
        //the counts).
        size_t num_input_pins = count_valid_refs(block_input_pins(blk_id), pin_id_map);
        size_t num_output_pins = count_valid_refs(block_output_pins(blk_id), pin_id_map);
        size_t num_clock_pins = count_valid_refs(block_clock_pins(blk_id), pin_id_map);

        std::vector<PinId>& pin_collection = block_pins_[blk_id];

        pin_collection = update_valid_refs(pin_collection, pin_id_map);
        block_num_input_pins_[blk_id] = num_input_pins;
        block_num_output_pins_[blk_id] = num_output_pins;
        block_num_clock_pins_[blk_id] = num_clock_pins;

        VTR_ASSERT_SAFE_MSG(all_valid(pin_collection), "All Ids should be valid");
        VTR_ASSERT(pin_collection.size() == size_t(block_num_input_pins_[blk_id] + block_num_output_pins_[blk_id] + block_num_clock_pins_[blk_id]));

        //Similarily for ports
        size_t num_input_ports = count_valid_refs(block_input_ports(blk_id), port_id_map);
        size_t num_output_ports = count_valid_refs(block_output_ports(blk_id), port_id_map);
        size_t num_clock_ports = count_valid_refs(block_clock_ports(blk_id), port_id_map);

        std::vector<PortId>& blk_ports = block_ports_[blk_id];

        blk_ports = update_valid_refs(blk_ports, port_id_map);
        block_num_input_ports_[blk_id] = num_input_ports;
        block_num_output_ports_[blk_id] = num_output_ports;
        block_num_clock_ports_[blk_id] = num_clock_ports;

        VTR_ASSERT_SAFE_MSG(all_valid(blk_ports), "All Ids should be valid");
        VTR_ASSERT(blk_ports.size() == size_t(block_num_input_ports_[blk_id] + block_num_output_ports_[blk_id] + block_num_clock_ports_[blk_id]));
    }

    rebuild_block_refs_impl(pin_id_map, port_id_map);

    VTR_ASSERT(validate_block_sizes());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::rebuild_port_refs(const vtr::vector_map<BlockId, BlockId>& block_id_map,
                                                               const vtr::vector_map<PinId, PinId>& pin_id_map) {
    //Update block and pin references held by ports
    port_blocks_ = update_valid_refs(port_blocks_, block_id_map);
    VTR_ASSERT_SAFE_MSG(all_valid(port_blocks_), "All Ids should be valid");

    VTR_ASSERT(port_blocks_.size() == port_ids_.size());

    for (auto& pin_collection : port_pins_) {
        pin_collection = update_valid_refs(pin_collection, pin_id_map);
        VTR_ASSERT_SAFE_MSG(all_valid(pin_collection), "All Ids should be valid");
    }

    rebuild_port_refs_impl(block_id_map, pin_id_map);

    VTR_ASSERT(validate_port_sizes());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::rebuild_pin_refs(const vtr::vector_map<PortId, PortId>& port_id_map,
                                                              const vtr::vector_map<NetId, NetId>& net_id_map) {
    //Update port and net references held by pins
    pin_ports_ = update_all_refs(pin_ports_, port_id_map);
    VTR_ASSERT_SAFE_MSG(all_valid(pin_ports_), "All Ids should be valid");

    //NOTE: we do not need to update pin_port_bits_ since a pin's index within it's
    //port will not change (since the port width's don't change when cleaned)

    pin_nets_ = update_all_refs(pin_nets_, net_id_map);
    VTR_ASSERT_SAFE_MSG(all_valid(pin_nets_), "All Ids should be valid");

    //We must carefully re-build the pin net indices from scratch, since cleaning
    //may have changed the index of the pin within the net (e.g. if invalid pins
    //were removed)
    //
    //Note that for this to work correctly, the net references must have already been re-built!
    for (auto net : nets()) {
        int i = 0;
        for (auto pin : net_pins(net)) {
            pin_net_indices_[pin] = i;
            ++i;
        }
    }

    rebuild_pin_refs_impl(port_id_map, net_id_map);

    VTR_ASSERT(validate_pin_sizes());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::rebuild_net_refs(const vtr::vector_map<PinId, PinId>& pin_id_map) {
    //Update pin references held by nets
    for (auto& pin_collection : net_pins_) {
        //We take special care to preserve the driver index, since an INVALID id is used
        //to indicate an undriven net it should not be dropped during the update
        pin_collection = update_valid_refs(pin_collection, pin_id_map, {NET_DRIVER_INDEX});

        VTR_ASSERT_SAFE_MSG(all_valid(pin_collection), "All sinks should be valid");
    }

    rebuild_net_refs_impl(pin_id_map);

    VTR_ASSERT(validate_net_sizes());
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::shrink_to_fit() {
    //Block data
    block_ids_.shrink_to_fit();
    block_names_.shrink_to_fit();

    block_pins_.shrink_to_fit();
    for (std::vector<PinId>& pin_collection : block_pins_) {
        pin_collection.shrink_to_fit();
    }
    block_num_input_pins_.shrink_to_fit();
    block_num_output_pins_.shrink_to_fit();
    block_num_clock_pins_.shrink_to_fit();

    block_ports_.shrink_to_fit();
    for (auto& blk_ports : block_ports_) {
        blk_ports.shrink_to_fit();
    }
    block_num_input_ports_.shrink_to_fit();
    block_num_output_ports_.shrink_to_fit();
    block_num_clock_ports_.shrink_to_fit();

    VTR_ASSERT(validate_block_sizes());

    //Port data
    port_ids_.shrink_to_fit();
    port_blocks_.shrink_to_fit();
    port_widths_.shrink_to_fit();
    port_types_.shrink_to_fit();
    port_pins_.shrink_to_fit();
    for (auto& pin_collection : port_pins_) {
        pin_collection.shrink_to_fit();
    }
    VTR_ASSERT(validate_port_sizes());

    //Pin data
    pin_ids_.shrink_to_fit();
    pin_ports_.shrink_to_fit();
    pin_port_bits_.shrink_to_fit();
    pin_nets_.shrink_to_fit();
    pin_is_constant_.shrink_to_fit();
    VTR_ASSERT(validate_pin_sizes());

    //Net data
    net_ids_.shrink_to_fit();
    net_names_.shrink_to_fit();
    net_pins_.shrink_to_fit();
    VTR_ASSERT(validate_net_sizes());

    //String data
    string_ids_.shrink_to_fit();
    strings_.shrink_to_fit();
    VTR_ASSERT(validate_string_sizes());
}

/*
 *
 * Sanity Checks
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_block_id(BlockId block_id) const {
    if (block_id == BlockId::INVALID()
        || !block_ids_.contains(block_id)
        || block_ids_[block_id] != block_id) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_port_id(PortId port_id) const {
    if (port_id == PortId::INVALID()
        || !port_ids_.contains(port_id)
        || port_ids_[port_id] != port_id) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_port_bit(PortId port_id, BitIndex port_bit) const {
    VTR_ASSERT_SAFE(valid_port_id(port_id));
    if (port_bit >= port_width(port_id)) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_pin_id(PinId pin_id) const {
    if (pin_id == PinId::INVALID()
        || !pin_ids_.contains(pin_id)
        || pin_ids_[pin_id] != pin_id) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_net_id(NetId net_id) const {
    if (net_id == NetId::INVALID()
        || !net_ids_.contains(net_id)
        || net_ids_[net_id] != net_id) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::valid_string_id(typename Netlist<BlockId, PortId, PinId, NetId>::StringId string_id) const {
    if (string_id == StringId::INVALID()
        || !string_ids_.contains(string_id)
        || string_ids_[string_id] != string_id) {
        return false;
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_block_sizes() const {
    size_t num_blocks = blocks().size();
    if (block_names_.size() != num_blocks
        || block_pins_.size() != num_blocks
        || block_num_input_pins_.size() != num_blocks
        || block_num_output_pins_.size() != num_blocks
        || block_num_clock_pins_.size() != num_blocks
        || block_ports_.size() != num_blocks
        || block_num_input_ports_.size() != num_blocks
        || block_num_output_ports_.size() != num_blocks
        || block_num_clock_ports_.size() != num_blocks
        || block_attrs_.size() != num_blocks
        || block_params_.size() != num_blocks
        || !validate_block_sizes_impl(num_blocks)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Inconsistent block data sizes");
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_port_sizes() const {
    size_t num_ports = ports().size();
    if (port_names_.size() != num_ports
        || port_blocks_.size() != num_ports
        || port_pins_.size() != num_ports
        || !validate_port_sizes_impl(num_ports)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Inconsistent port data sizes");
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_pin_sizes() const {
    size_t num_pins = pins().size();
    if (pin_ports_.size() != num_pins
        || pin_port_bits_.size() != num_pins
        || pin_nets_.size() != num_pins
        || pin_net_indices_.size() != num_pins
        || pin_is_constant_.size() != num_pins
        || !validate_pin_sizes_impl(num_pins)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Inconsistent pin data sizes");
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_net_sizes() const {
    size_t num_nets = nets().size();
    if (net_names_.size() != num_nets
        || net_pins_.size() != num_nets
        || !validate_net_sizes_impl(num_nets)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Inconsistent net data sizes");
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_string_sizes() const {
    if (strings_.size() != string_ids_.size()) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Inconsistent string data sizes");
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_block_port_refs() const {
    //Verify that all block <-> port references are consistent

    //Track how many times we've seen each port from the blocks
    vtr::vector_map<PortId, unsigned> seen_port_ids(port_ids_.size());

    for (auto blk_id : blocks()) {
        for (auto in_port_id : block_input_ports(blk_id)) {
            if (blk_id != port_block(in_port_id)) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block-input port cross-reference does not match");
            }
            ++seen_port_ids[in_port_id];
        }
        for (auto out_port_id : block_output_ports(blk_id)) {
            if (blk_id != port_block(out_port_id)) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block-output port cross-reference does not match");
            }
            ++seen_port_ids[out_port_id];
        }
        for (auto clock_port_id : block_clock_ports(blk_id)) {
            if (blk_id != port_block(clock_port_id)) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block-clock port cross-reference does not match");
            }
            ++seen_port_ids[clock_port_id];
        }
    }

    //Check that we have neither orphaned ports (i.e. that aren't referenced by a block)
    //nor shared ports (i.e. referenced by multiple blocks)
    auto is_one = [](unsigned val) {
        return val == 1;
    };
    if (!std::all_of(seen_port_ids.begin(), seen_port_ids.end(), is_one)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Port not referenced by a single block");
    }

    if (std::accumulate(seen_port_ids.begin(), seen_port_ids.end(), 0u) != port_ids_.size()) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Found orphaned port (not referenced by a block)");
    }

    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_block_pin_refs() const {
    //Verify that block pin refs are consistent
    //(e.g. inputs are inputs, outputs are outputs etc.)
    for (auto blk_id : blocks()) {
        //Check that only input pins are found when iterating through inputs
        for (auto pin_id : block_input_pins(blk_id)) {
            auto port_id = pin_port(pin_id);

            auto type = port_type(port_id);
            if (type != PortType::INPUT) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Non-input pin in block input pins");
            }
        }

        //Check that only output pins are found when iterating through outputs
        for (auto pin_id : block_output_pins(blk_id)) {
            auto port_id = pin_port(pin_id);

            auto type = port_type(port_id);
            if (type != PortType::OUTPUT) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Non-output pin in block output pins");
            }
        }

        //Check that only clock pins are found when iterating through clocks
        for (auto pin_id : block_clock_pins(blk_id)) {
            auto port_id = pin_port(pin_id);

            auto type = port_type(port_id);
            if (type != PortType::CLOCK) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Non-clock pin in block clock pins");
            }
        }
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_port_pin_refs() const {
    //Check that port <-> pin references are consistent

    //Track how many times we've seen each pin from the ports
    vtr::vector_map<PinId, unsigned> seen_pin_ids(pin_ids_.size());

    for (auto port_id : port_ids_) {
        bool first_bit = true;
        BitIndex prev_bit_index = 0;
        for (auto pin_id : port_pins(port_id)) {
            if (pin_port(pin_id) != port_id) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Port-pin cross-reference does not match");
            }
            if (pin_port_bit(pin_id) >= port_width(port_id)) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Out-of-range port bit index");
            }
            ++seen_pin_ids[pin_id];

            BitIndex port_bit_index = pin_port_bit(pin_id);

            //Verify that the port bit index is legal
            if (!valid_port_bit(port_id, port_bit_index)) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid pin bit index in port");
            }

            //Verify that the pins are listed in increasing order of port bit index,
            //we rely on this property to perform fast binary searches for pins with specific bit
            //indicies
            if (first_bit) {
                prev_bit_index = port_bit_index;
                first_bit = false;
            } else if (prev_bit_index >= port_bit_index) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Port pin indicies are not in ascending order");
            }
        }
    }

    //Check that we have neither orphaned pins (i.e. that aren't referenced by a port)
    //nor shared pins (i.e. referenced by multiple ports)
    auto is_one = [](unsigned val) {
        return val == 1;
    };
    if (!std::all_of(seen_pin_ids.begin(), seen_pin_ids.end(), is_one)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Pins referenced by zero or multiple ports");
    }

    if (std::accumulate(seen_pin_ids.begin(), seen_pin_ids.end(), 0u) != pin_ids_.size()) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Found orphaned pins (not referenced by a port)");
    }

    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_net_pin_refs() const {
    //Check that net <-> pin references are consistent

    //Track how many times we've seen each pin from the ports
    vtr::vector_map<PinId, unsigned> seen_pin_ids(pin_ids_.size());

    for (auto net_id : nets()) {
        auto pins_rng = net_pins(net_id);
        for (auto iter = pins_rng.begin(); iter != pins_rng.end(); ++iter) {
            int pin_index = std::distance(pins_rng.begin(), iter);
            auto pin_id = *iter;

            if (iter == pins_rng.begin()) {
                //The first net pin is the driver, which may be invalid
                //if there is no driver.
                if (pin_id) {
                    VTR_ASSERT(pin_index == NET_DRIVER_INDEX);
                    if (pin_type(pin_id) != PinType::DRIVER) {
                        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Driver pin not found at expected index in net");
                    }
                }
            } else {
                //Any non-driver (i.e. sink) pins must be valid
                if (!pin_id) {
                    VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid pin found in net sinks");
                }

                if (pin_type(pin_id) != PinType::SINK) {
                    VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid pin type found in net sinks");
                }
            }

            if (pin_id) {
                //Verify the cross reference if the pin_id is valid (i.e. a sink or a valid driver)
                if (pin_net(pin_id) != net_id) {
                    VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Net-pin cross-reference does not match");
                }

                if (pin_net_index(pin_id) != pin_index) {
                    VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Pin's net index cross-reference does not match actual net index");
                }

                //We only record valid seen pins since we may see multiple undriven nets with invalid IDs
                ++seen_pin_ids[pin_id];
            }
        }
    }

    //Check that we have neither orphaned pins (i.e. that aren't referenced by a port)
    //nor shared pins (i.e. referenced by multiple ports)
    auto is_one = [](unsigned val) {
        return val == 1;
    };
    if (!std::all_of(seen_pin_ids.begin(), seen_pin_ids.end(), is_one)) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Found pins referenced by zero or multiple nets");
    }

    if (std::accumulate(seen_pin_ids.begin(), seen_pin_ids.end(), 0u) != pin_ids_.size()) {
        VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Found orphaned pins (not referenced by a net)");
    }

    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::validate_string_refs() const {
    for (const auto& str_id : block_names_) {
        if (!valid_string_id(str_id)) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid block name string reference");
        }
    }
    for (const auto& str_id : port_names_) {
        if (!valid_string_id(str_id)) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid port name string reference");
        }
    }
    for (const auto& str_id : net_names_) {
        if (!valid_string_id(str_id)) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Invalid net name string reference");
        }
    }
    return true;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
bool Netlist<BlockId, PortId, PinId, NetId>::verify_block_invariants() const {
    for (auto blk_id : blocks()) {
        //Check block type
        //Find any connected clock
        NetId clk_net_id;
        for (auto pin_id : block_clock_pins(blk_id)) {
            if (pin_id) {
                clk_net_id = pin_net(pin_id);
                break;
            }
        }

        if (block_is_combinational(blk_id)) {
            //Non-sequential types must not have a clock
            if (clk_net_id) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block '%s' is a non-sequential type but has a clock '%s'",
                                block_name(blk_id).c_str(), net_name(clk_net_id).c_str());
            }

        } else {
            //Sequential types must have a clock
            if (!clk_net_id) {
                VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block '%s' is sequential type but has no clock",
                                block_name(blk_id).c_str());
            }
        }

        //Check that block pins and ports are consistent (i.e. same number of pins)
        size_t num_block_pins = block_pins(blk_id).size();

        size_t total_block_port_pins = 0;
        for (auto port_id : block_ports(blk_id)) {
            total_block_port_pins += port_pins(port_id).size();
        }

        if (num_block_pins != total_block_port_pins) {
            VPR_FATAL_ERROR(VPR_ERROR_NETLIST, "Block pins and port pins do not match on block '%s'",
                            block_name(blk_id).c_str());
        }
    }

    return true;
}

/*
 *
 * Internal utilities
 *
 */
template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::StringId Netlist<BlockId, PortId, PinId, NetId>::find_string(const std::string& str) const {
    auto iter = string_to_string_id_.find(str);
    if (iter != string_to_string_id_.end()) {
        StringId str_id = iter->second;

        VTR_ASSERT_SAFE(str_id);
        VTR_ASSERT_SAFE(strings_[str_id] == str);

        return str_id;
    } else {
        return StringId::INVALID();
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
BlockId Netlist<BlockId, PortId, PinId, NetId>::find_block(const typename Netlist<BlockId, PortId, PinId, NetId>::StringId name_id) const {
    VTR_ASSERT_SAFE(valid_string_id(name_id));
    auto iter = block_name_to_block_id_.find(name_id);
    if (iter != block_name_to_block_id_.end()) {
        BlockId blk_id = *iter;

        //Check post-conditions
        if (blk_id) {
            VTR_ASSERT_SAFE(valid_block_id(blk_id));
            VTR_ASSERT_SAFE(block_names_[blk_id] == name_id);
        }

        return blk_id;
    } else {
        return BlockId::INVALID();
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::associate_pin_with_block(const PinId pin_id, const PortType type, const BlockId blk_id) {
    //Get an interator pointing to where we want to insert
    pin_iterator iter;
    if (type == PortType::INPUT) {
        iter = block_input_pins(blk_id).end();
        ++block_num_input_pins_[blk_id];
    } else if (type == PortType::OUTPUT) {
        iter = block_output_pins(blk_id).end();
        ++block_num_output_pins_[blk_id];
    } else {
        VTR_ASSERT(type == PortType::CLOCK);
        iter = block_clock_pins(blk_id).end();
        ++block_num_clock_pins_[blk_id];
    }

    //Insert the element just before iter
    auto new_iter = block_pins_[blk_id].insert(iter, pin_id);

    //Inserted value should be the last valid range element
    if (type == PortType::INPUT) {
        VTR_ASSERT(new_iter + 1 == block_input_pins(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_output_pins(blk_id).begin());
    } else if (type == PortType::OUTPUT) {
        VTR_ASSERT(new_iter + 1 == block_output_pins(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_clock_pins(blk_id).begin());
    } else {
        VTR_ASSERT(type == PortType::CLOCK);
        VTR_ASSERT(new_iter + 1 == block_clock_pins(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_pins(blk_id).end());
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
int Netlist<BlockId, PortId, PinId, NetId>::associate_pin_with_net(const PinId pin_id, const PinType type, const NetId net_id) {
    //Add the pin to the net
    if (type == PinType::DRIVER) {
        VTR_ASSERT_MSG(net_pins_[net_id].size() > 0, "Must be space for net's pin");
        VTR_ASSERT_MSG(net_pins_[net_id][0] == PinId::INVALID(), "Must be no existing net driver");

        net_pins_[net_id][0] = pin_id; //Set driver

        return 0; //Driver always at index 0
    } else {
        VTR_ASSERT(type == PinType::SINK);

        net_pins_[net_id].emplace_back(pin_id); //Add sink

        return net_pins_[net_id].size() - 1; //Index of inserted pin
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::associate_pin_with_port(const PinId pin_id, const PortId port_id) {
    //A ports pins are stored in ascending order of port bit index, to allow for fast look-ups.
    //As a result we need to ensure that even if pins are created out-of-order (with respect
    //to port bit) they are still inserted in the port in sorted order.
    //
    //As a result we find the correct position using std::lower_bound and insert there.
    //Note that in the typical case (when port pins are created in order) this will be
    //the end of the port's pins and the insertion will be efficient. Only in the (more
    //unusual) case where the pins are created out-of-order will we need to do a slow
    //insert in the middle of the vector.
    auto port_bit_cmp = [&](const PinId pin, BitIndex bit_index) {
        return pin_port_bit(pin) < bit_index;
    };
    auto iter = std::lower_bound(port_pins_[port_id].begin(), port_pins_[port_id].end(), pin_port_bit(pin_id), port_bit_cmp);
    port_pins_[port_id].insert(iter, pin_id);
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
void Netlist<BlockId, PortId, PinId, NetId>::associate_port_with_block(const PortId port_id, const PortType type, const BlockId blk_id) {
    //Associate the port with the blocks inputs/outputs/clocks

    //Get an interator pointing to where we want to insert
    port_iterator iter;
    if (type == PortType::INPUT) {
        iter = block_input_ports(blk_id).end();
        ++block_num_input_ports_[blk_id];
    } else if (type == PortType::OUTPUT) {
        iter = block_output_ports(blk_id).end();
        ++block_num_output_ports_[blk_id];
    } else {
        VTR_ASSERT(type == PortType::CLOCK);
        iter = block_clock_ports(blk_id).end();
        ++block_num_clock_ports_[blk_id];
    }

    //Insert the element just before iter
    auto new_iter = block_ports_[blk_id].insert(iter, port_id);

    //Inserted value should be the last valid range element
    if (type == PortType::INPUT) {
        VTR_ASSERT(new_iter + 1 == block_input_ports(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_output_ports(blk_id).begin());
    } else if (type == PortType::OUTPUT) {
        VTR_ASSERT(new_iter + 1 == block_output_ports(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_clock_ports(blk_id).begin());
    } else {
        VTR_ASSERT(type == PortType::CLOCK);
        VTR_ASSERT(new_iter + 1 == block_clock_ports(blk_id).end());
        VTR_ASSERT(new_iter + 1 == block_ports(blk_id).end());
    }
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
typename Netlist<BlockId, PortId, PinId, NetId>::StringId Netlist<BlockId, PortId, PinId, NetId>::create_string(const std::string& str) {
    StringId str_id = find_string(str);
    if (!str_id) {
        //Not found, create

        //Reserve an id
        str_id = StringId(string_ids_.size());
        string_ids_.push_back(str_id);

        //Store the reverse look-up
        auto key = str;
        string_to_string_id_[key] = str_id;

        //Initialize the data
        strings_.emplace_back(str);
    }

    //Check post-conditions: sizes
    VTR_ASSERT(string_to_string_id_.size() == string_ids_.size());
    VTR_ASSERT(strings_.size() == string_ids_.size());

    //Check post-conditions: values
    VTR_ASSERT(strings_[str_id] == str);
    VTR_ASSERT_SAFE(find_string(str) == str_id);

    return str_id;
}

template<typename BlockId, typename PortId, typename PinId, typename NetId>
NetId Netlist<BlockId, PortId, PinId, NetId>::find_net(const typename Netlist<BlockId, PortId, PinId, NetId>::StringId name_id) const {
    VTR_ASSERT_SAFE(valid_string_id(name_id));
    auto iter = net_name_to_net_id_.find(name_id);
    if (iter != net_name_to_net_id_.end()) {
        NetId net_id = *iter;

        if (net_id) {
            //Check post-conditions
            VTR_ASSERT_SAFE(valid_net_id(net_id));
            VTR_ASSERT_SAFE(net_names_[net_id] == name_id);
        }

        return net_id;
    } else {
        return NetId::INVALID();
    }
}
