blob: a2fc8c31daf256f790e6b17dfeb4f12e7813b20b [file] [log] [blame]
#include "clustered_netlist.h"
#include "vtr_assert.h"
#include "vpr_error.h"
/*
*
*
* ClusteredNetlist Class Implementation
*
*
*/
ClusteredNetlist::ClusteredNetlist(std::string name, std::string id)
: Netlist<ClusterBlockId, ClusterPortId, ClusterPinId, ClusterNetId>(name, id) {}
/*
*
* Blocks
*
*/
t_pb* ClusteredNetlist::block_pb(const ClusterBlockId id) const {
VTR_ASSERT_SAFE(valid_block_id(id));
return block_pbs_[id];
}
t_logical_block_type_ptr ClusteredNetlist::block_type(const ClusterBlockId id) const {
VTR_ASSERT_SAFE(valid_block_id(id));
return block_types_[id];
}
ClusterNetId ClusteredNetlist::block_net(const ClusterBlockId blk_id, const int phys_pin_index) const {
auto pin_id = block_pin(blk_id, phys_pin_index);
if (pin_id) {
return pin_net(pin_id);
}
return ClusterNetId::INVALID();
}
int ClusteredNetlist::block_pin_net_index(const ClusterBlockId blk_id, const int pin_index) const {
auto pin_id = block_pin(blk_id, pin_index);
if (pin_id) {
return pin_net_index(pin_id);
}
return OPEN;
}
ClusterPinId ClusteredNetlist::block_pin(const ClusterBlockId blk, const int phys_pin_index) const {
VTR_ASSERT_SAFE(valid_block_id(blk));
VTR_ASSERT_SAFE_MSG(phys_pin_index >= 0 && phys_pin_index < physical_tile_type(block_type(blk))->num_pins, "Physical pin index must be in range");
return block_logical_pins_[blk][phys_pin_index];
}
bool ClusteredNetlist::block_contains_primary_input(const ClusterBlockId blk) const {
const t_pb* pb = block_pb(blk);
const t_pb* primary_input_pb = pb->find_pb_for_model(".input");
return primary_input_pb != nullptr;
}
//Returns true if the specified block contains a primary output (e.g. BLIF .output primitive)
bool ClusteredNetlist::block_contains_primary_output(const ClusterBlockId blk) const {
const t_pb* pb = block_pb(blk);
const t_pb* primary_output_pb = pb->find_pb_for_model(".output");
return primary_output_pb != nullptr;
}
/*
*
* Pins
*
*/
int ClusteredNetlist::pin_physical_index(const ClusterPinId id) const {
VTR_ASSERT_SAFE(valid_pin_id(id));
return pin_physical_index_[id];
}
int ClusteredNetlist::net_pin_physical_index(const ClusterNetId net_id, int net_pin_index) const {
auto pin_id = net_pin(net_id, net_pin_index);
if (pin_id) {
return pin_physical_index(pin_id);
}
return OPEN; //No valid pin found
}
/*
*
* Nets
*
*/
bool ClusteredNetlist::net_is_ignored(const ClusterNetId id) const {
VTR_ASSERT_SAFE(valid_net_id(id));
return net_is_ignored_[id];
}
bool ClusteredNetlist::net_is_global(const ClusterNetId id) const {
VTR_ASSERT_SAFE(valid_net_id(id));
return net_is_global_[id];
}
/*
*
* Mutators
*
*/
ClusterBlockId ClusteredNetlist::create_block(const char* name, t_pb* pb, t_logical_block_type_ptr type) {
ClusterBlockId blk_id = find_block(name);
if (blk_id == ClusterBlockId::INVALID()) {
blk_id = Netlist::create_block(name);
block_pbs_.insert(blk_id, pb);
block_types_.insert(blk_id, type);
//Allocate and initialize every potential pin of the block
block_logical_pins_.insert(blk_id, std::vector<ClusterPinId>(physical_tile_type(type)->num_pins, ClusterPinId::INVALID()));
}
//Check post-conditions: size
VTR_ASSERT(validate_block_sizes());
//Check post-conditions: values
VTR_ASSERT(block_pb(blk_id) == pb);
VTR_ASSERT(block_type(blk_id) == type);
return blk_id;
}
void ClusteredNetlist::set_pin_physical_index(const ClusterPinId pin, const int phys_pin_index) {
VTR_ASSERT_SAFE(valid_pin_id(pin));
auto blk = pin_block(pin);
int old_phys_pin_index = pin_physical_index(pin);
//Invalidate old mapping
block_logical_pins_[blk][old_phys_pin_index] = ClusterPinId::INVALID();
//Update mappings
pin_physical_index_[pin] = phys_pin_index;
block_logical_pins_[blk][phys_pin_index] = pin;
}
ClusterPortId ClusteredNetlist::create_port(const ClusterBlockId blk_id, const std::string name, BitIndex width, PortType type) {
ClusterPortId port_id = find_port(blk_id, name);
if (!port_id) {
port_id = Netlist::create_port(blk_id, name, width, type);
associate_port_with_block(port_id, type, blk_id);
}
//Check post-conditions: size
VTR_ASSERT(validate_port_sizes());
//Check post-conditions: values
VTR_ASSERT(port_name(port_id) == name);
VTR_ASSERT_SAFE(find_port(blk_id, name) == port_id);
return port_id;
}
ClusterPinId ClusteredNetlist::create_pin(const ClusterPortId port_id, BitIndex port_bit, const ClusterNetId net_id, const PinType pin_type_, int pin_index, bool is_const) {
ClusterPinId pin_id = Netlist::create_pin(port_id, port_bit, net_id, pin_type_, is_const);
pin_physical_index_.push_back(pin_index);
ClusterBlockId block_id = port_block(port_id);
block_logical_pins_[block_id][pin_index] = pin_id;
//Check post-conditions: size
VTR_ASSERT(validate_pin_sizes());
return pin_id;
}
ClusterNetId ClusteredNetlist::create_net(const std::string name) {
//Check if the net has already been created
StringId name_id = create_string(name);
ClusterNetId net_id = find_net(name_id);
if (net_id == ClusterNetId::INVALID()) {
net_id = Netlist::create_net(name);
net_is_ignored_.push_back(false);
net_is_global_.push_back(false);
}
VTR_ASSERT(validate_net_sizes());
return net_id;
}
void ClusteredNetlist::set_net_is_ignored(ClusterNetId net_id, bool state) {
VTR_ASSERT(valid_net_id(net_id));
net_is_ignored_[net_id] = state;
}
void ClusteredNetlist::set_net_is_global(ClusterNetId net_id, bool state) {
VTR_ASSERT(valid_net_id(net_id));
net_is_global_[net_id] = state;
}
void ClusteredNetlist::remove_block_impl(const ClusterBlockId blk_id) {
//Remove & invalidate pointers
free_pb(block_pbs_[blk_id]);
delete block_pbs_[blk_id];
block_pbs_.insert(blk_id, NULL);
block_types_.insert(blk_id, NULL);
block_logical_pins_.insert(blk_id, std::vector<ClusterPinId>());
}
void ClusteredNetlist::remove_port_impl(const ClusterPortId port_id) {
VTR_ASSERT(port_id);
}
void ClusteredNetlist::remove_pin_impl(const ClusterPinId pin_id) {
VTR_ASSERT(pin_id);
}
void ClusteredNetlist::remove_net_impl(const ClusterNetId net_id) {
VTR_ASSERT(net_id);
}
void ClusteredNetlist::clean_blocks_impl(const vtr::vector_map<ClusterBlockId, ClusterBlockId>& block_id_map) {
//Update all the block values
block_pbs_ = clean_and_reorder_values(block_pbs_, block_id_map);
block_types_ = clean_and_reorder_values(block_types_, block_id_map);
block_logical_pins_ = clean_and_reorder_values(block_logical_pins_, block_id_map);
}
void ClusteredNetlist::clean_ports_impl(const vtr::vector_map<ClusterPortId, ClusterPortId>& /*port_id_map*/) {
//Unused
}
void ClusteredNetlist::clean_pins_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& pin_id_map) {
//Update all the pin values
pin_physical_index_ = clean_and_reorder_values(pin_physical_index_, pin_id_map);
}
void ClusteredNetlist::clean_nets_impl(const vtr::vector_map<ClusterNetId, ClusterNetId>& net_id_map) {
//Update all the net values
net_is_ignored_ = clean_and_reorder_values(net_is_ignored_, net_id_map);
net_is_global_ = clean_and_reorder_values(net_is_global_, net_id_map);
}
void ClusteredNetlist::rebuild_block_refs_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& /*pin_id_map*/,
const vtr::vector_map<ClusterPortId, ClusterPortId>& /*port_id_map*/) {
for (auto blk : blocks()) {
block_logical_pins_[blk] = std::vector<ClusterPinId>(physical_tile_type(blk)->num_pins, ClusterPinId::INVALID()); //Reset
for (auto pin : block_pins(blk)) {
int phys_pin_index = pin_physical_index(pin);
block_logical_pins_[blk][phys_pin_index] = pin;
}
}
}
void ClusteredNetlist::rebuild_port_refs_impl(const vtr::vector_map<ClusterBlockId, ClusterBlockId>& /*block_id_map*/,
const vtr::vector_map<ClusterPinId, ClusterPinId>& /*pin_id_map*/) {
//Unused
}
void ClusteredNetlist::rebuild_pin_refs_impl(const vtr::vector_map<ClusterPortId, ClusterPortId>& /*port_id_map*/,
const vtr::vector_map<ClusterNetId, ClusterNetId>& /*net_id_map*/) {
//Unused
}
void ClusteredNetlist::rebuild_net_refs_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& /*pin_id_map*/) {
//Unused
}
void ClusteredNetlist::shrink_to_fit_impl() {
//Block data
block_pbs_.shrink_to_fit();
block_types_.shrink_to_fit();
block_logical_pins_.shrink_to_fit();
//Pin data
pin_physical_index_.shrink_to_fit();
//Net data
net_is_ignored_.shrink_to_fit();
net_is_global_.shrink_to_fit();
}
/*
*
* Sanity Checks
*
*/
bool ClusteredNetlist::validate_block_sizes_impl(size_t num_blocks) const {
if (block_pbs_.size() != num_blocks
|| block_types_.size() != num_blocks
|| block_logical_pins_.size() != num_blocks) {
return false;
}
return true;
}
bool ClusteredNetlist::validate_port_sizes_impl(size_t /*num_ports*/) const {
//No cluster specific port data to check
return true;
}
bool ClusteredNetlist::validate_pin_sizes_impl(size_t num_pins) const {
if (pin_physical_index_.size() != num_pins) {
return false;
}
return true;
}
bool ClusteredNetlist::validate_net_sizes_impl(size_t num_nets) const {
if (net_is_ignored_.size() != num_nets && net_is_global_.size() != num_nets) {
return false;
}
return true;
}