OpenFPGA/openfpga/src/repack/physical_pb.cpp

221 lines
7.5 KiB
C++

/******************************************************************************
* Memember functions for data structure PhysicalPb
******************************************************************************/
#include "vtr_assert.h"
#include "vtr_log.h"
#include "physical_pb.h"
/* begin namespace openfpga */
namespace openfpga {
/**************************************************
* Public Accessors
*************************************************/
PhysicalPb::physical_pb_range PhysicalPb::pbs() const {
return vtr::make_range(pb_ids_.begin(), pb_ids_.end());
}
std::vector<PhysicalPbId> PhysicalPb::primitive_pbs() const {
std::vector<PhysicalPbId> results;
/* The primitive pbs are those without any children */
for (auto pb : pbs()) {
if (true == child_pbs_[pb].empty()) {
results.push_back(pb);
}
}
return results;
}
std::string PhysicalPb::name(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return names_[pb];
}
const t_pb_graph_node* PhysicalPb::pb_graph_node(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return pb_graph_nodes_[pb];
}
/* Find the module id by a given name, return invalid if not found */
PhysicalPbId PhysicalPb::find_pb(const t_pb_graph_node* pb_graph_node) const {
if (type2id_map_.find(pb_graph_node) != type2id_map_.end()) {
/* Find it, return the id */
return type2id_map_.at(pb_graph_node);
}
/* Not found, return an invalid id */
return PhysicalPbId::INVALID();
}
PhysicalPbId PhysicalPb::parent(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return parent_pbs_[pb];
}
PhysicalPbId PhysicalPb::child(const PhysicalPbId& pb,
const t_pb_type* pb_type,
const size_t& index) const {
VTR_ASSERT(true == valid_pb_id(pb));
if (0 < child_pbs_[pb].count(pb_type)) {
if (index < child_pbs_[pb].at(pb_type).size()) {
return child_pbs_[pb].at(pb_type)[index];
}
}
return PhysicalPbId::INVALID();
}
std::vector<AtomBlockId> PhysicalPb::atom_blocks(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return atom_blocks_[pb];
}
AtomNetId PhysicalPb::pb_graph_pin_atom_net(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin) const {
VTR_ASSERT(true == valid_pb_id(pb));
if (pin_atom_nets_[pb].find(pb_graph_pin) != pin_atom_nets_[pb].end()) {
/* Find it, return the id */
return pin_atom_nets_[pb].at(pb_graph_pin);
}
/* Not found, return an invalid id */
return AtomNetId::INVALID();
}
bool PhysicalPb::is_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin) const {
VTR_ASSERT(true == valid_pb_id(pb));
if (wire_lut_outputs_[pb].find(pb_graph_pin) != wire_lut_outputs_[pb].end()) {
/* Find it, return the status */
return wire_lut_outputs_[pb].at(pb_graph_pin);
}
/* Not found, return false */
return false;
}
std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> PhysicalPb::truth_tables(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return truth_tables_[pb];
}
std::vector<size_t> PhysicalPb::mode_bits(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb));
return mode_bits_[pb];
}
/******************************************************************************
* Private Mutators
******************************************************************************/
PhysicalPbId PhysicalPb::create_pb(const t_pb_graph_node* pb_graph_node) {
/* Find if the name has been used. If used, return an invalid Id and report error! */
std::map<const t_pb_graph_node*, PhysicalPbId>::iterator it = type2id_map_.find(pb_graph_node);
if (it != type2id_map_.end()) {
return PhysicalPbId::INVALID();
}
/* Create an new id */
PhysicalPbId pb = PhysicalPbId(pb_ids_.size());
pb_ids_.push_back(pb);
/* Allocate other attributes */
names_.emplace_back();
pb_graph_nodes_.push_back(pb_graph_node);
atom_blocks_.emplace_back();
pin_atom_nets_.emplace_back();
wire_lut_outputs_.emplace_back();
child_pbs_.emplace_back();
parent_pbs_.emplace_back();
truth_tables_.emplace_back();
mode_bits_.emplace_back();
/* Register in the name2id map */
type2id_map_[pb_graph_node] = pb;
return pb;
}
void PhysicalPb::add_child(const PhysicalPbId& parent,
const PhysicalPbId& child,
const t_pb_type* child_type) {
VTR_ASSERT(true == valid_pb_id(parent));
VTR_ASSERT(true == valid_pb_id(child));
child_pbs_[parent][child_type].push_back(child);
if (PhysicalPbId::INVALID() != parent_pbs_[child]) {
VTR_LOGF_WARN(__FILE__, __LINE__,
"Overwrite parent '%s' for physical pb '%s' with a new one '%s'!\n",
pb_graph_nodes_[parent_pbs_[child]]->hierarchical_type_name().c_str(),
pb_graph_nodes_[child]->hierarchical_type_name().c_str(),
pb_graph_nodes_[parent]->hierarchical_type_name().c_str());
}
parent_pbs_[child] = parent;
}
void PhysicalPb::set_truth_table(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin,
const AtomNetlist::TruthTable& truth_table) {
VTR_ASSERT(true == valid_pb_id(pb));
if (0 < truth_tables_[pb].count(pb_graph_pin)) {
VTR_LOG_WARN("Overwrite truth tables mapped to pb_graph_pin '%s[%ld]!\n",
pb_graph_pin->port->name, pb_graph_pin->pin_number);
}
truth_tables_[pb][pb_graph_pin] = truth_table;
}
void PhysicalPb::set_mode_bits(const PhysicalPbId& pb,
const std::vector<size_t>& mode_bits) {
VTR_ASSERT(true == valid_pb_id(pb));
mode_bits_[pb] = mode_bits;
}
void PhysicalPb::add_atom_block(const PhysicalPbId& pb,
const AtomBlockId& atom_block) {
VTR_ASSERT(true == valid_pb_id(pb));
atom_blocks_[pb].push_back(atom_block);
}
void PhysicalPb::set_pb_graph_pin_atom_net(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin,
const AtomNetId& atom_net) {
VTR_ASSERT(true == valid_pb_id(pb));
if (pin_atom_nets_[pb].end() != pin_atom_nets_[pb].find(pb_graph_pin)) {
VTR_LOG_WARN("Overwrite pb_graph_pin '%s[%d]' atom net '%lu' with '%lu'\n",
pb_graph_pin->port->name, pb_graph_pin->pin_number,
size_t(pin_atom_nets_[pb][pb_graph_pin]),
size_t(atom_net));
}
pin_atom_nets_[pb][pb_graph_pin] = atom_net;
}
void PhysicalPb::set_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin,
const bool& wire_lut_output) {
VTR_ASSERT(true == valid_pb_id(pb));
if (wire_lut_outputs_[pb].end() != wire_lut_outputs_[pb].find(pb_graph_pin)) {
VTR_LOG_WARN("Overwrite pb_graph_pin '%s[%d]' status on wire LUT output\n",
pb_graph_pin->port->name, pb_graph_pin->pin_number);
}
wire_lut_outputs_[pb][pb_graph_pin] = wire_lut_output;
}
/******************************************************************************
* Private validators/invalidators
******************************************************************************/
bool PhysicalPb::valid_pb_id(const PhysicalPbId& pb_id) const {
return ( size_t(pb_id) < pb_ids_.size() ) && ( pb_id == pb_ids_[pb_id] );
}
bool PhysicalPb::empty() const {
return 0 == pb_ids_.size();
}
} /* end namespace openfpga */