now physical pb_port binding support multiple ports

This commit is contained in:
tangxifan 2020-08-18 12:38:56 -06:00
parent f833e0ec66
commit 2712c354a9
11 changed files with 239 additions and 144 deletions

View File

@ -1,6 +1,7 @@
/************************************************************************
* Member functions for class PbTypeAnnotation
***********************************************************************/
#include <algorithm>
#include "vtr_log.h"
#include "vtr_assert.h"
#include "pb_type_annotation.h"
@ -85,24 +86,15 @@ std::vector<std::string> PbTypeAnnotation::port_names() const {
return keys;
}
BasicPort PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const {
std::map<std::string, BasicPort>::const_iterator it = operating_pb_type_ports_.find(port_name);
std::map<BasicPort, int> PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const {
std::map<std::string, std::map<BasicPort, int>>::const_iterator it = operating_pb_type_ports_.find(port_name);
if (it == operating_pb_type_ports_.end()) {
/* Return an empty port */
return BasicPort();
return std::map<BasicPort, int>();
}
return operating_pb_type_ports_.at(port_name);
}
int PbTypeAnnotation::physical_pin_rotate_offset(const std::string& port_name) const {
std::map<std::string, int>::const_iterator it = physical_pin_rotate_offsets_.find(port_name);
if (it == physical_pin_rotate_offsets_.end()) {
/* Return a zero offset which is default */
return 0;
}
return physical_pin_rotate_offsets_.at(port_name);
}
std::vector<std::string> PbTypeAnnotation::interconnect_names() const {
std::vector<std::string> keys;
for (auto const& element : interconnect_circuit_model_names_) {
@ -177,27 +169,42 @@ void PbTypeAnnotation::set_physical_pb_type_index_offset(const int& value) {
void PbTypeAnnotation::add_pb_type_port_pair(const std::string& operating_pb_port_name,
const BasicPort& physical_pb_port) {
/* Give a warning if the operating_pb_port_name already exist */
std::map<std::string, BasicPort>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name);
/* Give a warning if the interconnection name already exist */
if (it != operating_pb_type_ports_.end()) {
VTR_LOG_WARN("Redefine operating pb type port '%s' with physical pb type port '%s'\n",
operating_pb_port_name.c_str(), physical_pb_port.get_name().c_str());
}
std::map<std::string, std::map<BasicPort, int>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name);
operating_pb_type_ports_[operating_pb_port_name] = physical_pb_port;
}
void PbTypeAnnotation::set_physical_pin_rotate_offset(const std::string& operating_pb_port_name,
const int& physical_pin_rotate_offset) {
std::map<std::string, BasicPort>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name);
/* Give a warning if the interconnection name already exist */
/* If not exist, initialize and set a default value */
if (it == operating_pb_type_ports_.end()) {
VTR_LOG_ERROR("Operating pb type port '%s' does not exist! Ignore physical pin rotate offset '%d'\n",
operating_pb_port_name.c_str(), physical_pin_rotate_offset);
operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = 0;
/* We can return early */
return;
}
physical_pin_rotate_offsets_[operating_pb_port_name] = physical_pin_rotate_offset;
/* If the physical port is not in the list, we create one and set a default value */
if (0 == operating_pb_type_ports_[operating_pb_port_name].count(physical_pb_port)) {
operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = 0;
}
}
void PbTypeAnnotation::set_physical_pin_rotate_offset(const std::string& operating_pb_port_name,
const BasicPort& physical_pb_port,
const int& physical_pin_rotate_offset) {
std::map<std::string, std::map<BasicPort, int>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name);
if (it == operating_pb_type_ports_.end()) {
VTR_LOG_ERROR("The operating pb_type port '%s' is not valid!\n",
operating_pb_port_name.c_str());
exit(1);
}
if (operating_pb_type_ports_[operating_pb_port_name].end() == operating_pb_type_ports_[operating_pb_port_name].find(physical_pb_port)) {
VTR_LOG_ERROR("The physical pb_type port '%s[%lu:%lu]' definition for operating pb_type port '%s' is not valid!\n",
physical_pb_port.get_name().c_str(),
physical_pb_port.get_lsb(),
physical_pb_port.get_msb(),
operating_pb_port_name.c_str());
exit(1);
}
operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = physical_pin_rotate_offset;
}
void PbTypeAnnotation::add_interconnect_circuit_model_pair(const std::string& interc_name,

View File

@ -48,8 +48,7 @@ class PbTypeAnnotation {
float physical_pb_type_index_factor() const;
int physical_pb_type_index_offset() const;
std::vector<std::string> port_names() const;
BasicPort physical_pb_type_port(const std::string& port_name) const;
int physical_pin_rotate_offset(const std::string& port_name) const;
std::map<BasicPort, int> physical_pb_type_port(const std::string& port_name) const;
std::vector<std::string> interconnect_names() const;
std::string interconnect_circuit_model_name(const std::string& interc_name) const;
public: /* Public mutators */
@ -68,6 +67,7 @@ class PbTypeAnnotation {
void add_pb_type_port_pair(const std::string& operating_pb_port_name,
const BasicPort& physical_pb_port);
void set_physical_pin_rotate_offset(const std::string& operating_pb_port_name,
const BasicPort& physical_pb_port,
const int& physical_pin_rotate_offset);
void add_interconnect_circuit_model_pair(const std::string& interc_name,
const std::string& circuit_model_name);
@ -133,10 +133,9 @@ class PbTypeAnnotation {
*/
int physical_pb_type_index_offset_;
/* Link from the pins under an operating pb_type to physical pb_type */
std::map<std::string, BasicPort> operating_pb_type_ports_;
/* The offset aims to align the pin indices for port of pb_type
/* Link from the pins under an operating pb_type to pairs of
* its physical pb_type and its pin rotating offset
* The offset aims to align the pin indices for port of pb_type
* between operating and physical modes, especially when an operating
* mode contains multiple pb_type (num_pb>1) that are linked to
* the same physical pb_type.
@ -148,7 +147,7 @@ class PbTypeAnnotation {
* operating pb_type adder[0].pin[0] with a full path clb.fle[arith].adder[0]
* to physical pb_type adder[0].pin[1] with a full path clb.fle[physical].adder[0]
*/
std::map<std::string, int> physical_pin_rotate_offsets_;
std::map<std::string, std::map<BasicPort, int>> operating_pb_type_ports_;
/* Link between the interconnects under this pb_type and circuit model names */
std::map<std::string, std::string> interconnect_circuit_model_names_;

View File

@ -55,12 +55,40 @@ void read_xml_pb_port_annotation(pugi::xml_node& xml_port,
const std::string& name_attr = get_attribute(xml_port, "name", loc_data).as_string();
const std::string& physical_mode_port_attr = get_attribute(xml_port, "physical_mode_port", loc_data).as_string();
/* Parse the mode port using openfpga port parser */
openfpga::PortParser port_parser(physical_mode_port_attr);
pb_type_annotation.add_pb_type_port_pair(name_attr, port_parser.port());
/* Split the physical mode port attributes with space */
openfpga::StringToken port_tokenizer(physical_mode_port_attr);
const std::vector<std::string> physical_mode_ports = port_tokenizer.split();
/* We have an optional attribute: physical_mode_pin_rotate_offset */
pb_type_annotation.set_physical_pin_rotate_offset(name_attr, get_attribute(xml_port, "physical_mode_pin_rotate_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0));
/* Parse the mode port using openfpga port parser */
for (const auto& physical_mode_port : physical_mode_ports) {
openfpga::PortParser port_parser(physical_mode_port);
pb_type_annotation.add_pb_type_port_pair(name_attr, port_parser.port());
}
/* We have an optional attribute: physical_mode_pin_rotate_offset
* Split based on the number of physical pb_type ports that have been defined
*/
const std::string& physical_pin_rotate_offset_attr = get_attribute(xml_port, "physical_mode_pin_rotate_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
if (false == physical_pin_rotate_offset_attr.empty()) {
/* Split the physical mode port attributes with space */
openfpga::StringToken offset_tokenizer(physical_pin_rotate_offset_attr);
const std::vector<std::string> rotate_offsets = offset_tokenizer.split();
/* Error out if the offset does not match the port definition */
if (physical_mode_ports.size() != rotate_offsets.size()) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_port),
"Defined %lu physical mode ports but only %lu physical pin rotate offset are defined! Expect size matching.\n",
physical_mode_ports.size(), rotate_offsets.size());
}
for (size_t iport = 0; iport < physical_mode_ports.size(); ++iport) {
openfpga::PortParser port_parser(physical_mode_ports[iport]);
pb_type_annotation.set_physical_pin_rotate_offset(name_attr,
port_parser.port(),
std::stoi(rotate_offsets[iport]));
}
}
}
/********************************************************************

View File

@ -116,8 +116,25 @@ void write_xml_pb_port_annotation(std::fstream& fp,
fp << "\t\t\t" << "<port";
write_xml_attribute(fp, "name", port_name.c_str());
write_xml_attribute(fp, "physical_mode_port", generate_physical_pb_port_name(pb_type_annotation.physical_pb_type_port(port_name)).c_str());
write_xml_attribute(fp, "physical_mode_pin_rotate_offset", pb_type_annotation.physical_pin_rotate_offset(port_name));
std::string physical_mode_port_attr;
for (const auto& physical_pb_port_pair : pb_type_annotation.physical_pb_type_port(port_name)) {
if (false == physical_mode_port_attr.empty()) {
physical_mode_port_attr += " ";
}
physical_mode_port_attr += generate_physical_pb_port_name(physical_pb_port_pair.first);
}
write_xml_attribute(fp, "physical_mode_port", physical_mode_port_attr.c_str());
std::string physical_mode_pin_rotate_offset_attr;
for (const auto& physical_pb_port_pair : pb_type_annotation.physical_pb_type_port(port_name)) {
if (false == physical_mode_pin_rotate_offset_attr.empty()) {
physical_mode_pin_rotate_offset_attr += " ";
}
physical_mode_pin_rotate_offset_attr += std::to_string(physical_pb_port_pair.second);
}
write_xml_attribute(fp, "physical_mode_pin_rotate_offset", physical_mode_pin_rotate_offset_attr.c_str());
fp << "/>" << "\n";
}

View File

@ -124,6 +124,16 @@ bool BasicPort::operator== (const BasicPort& portA) const {
return false;
}
bool BasicPort::operator< (const BasicPort& portA) const {
if ( (0 == this->get_name().compare(portA.get_name()))
&& (this->get_lsb() < portA.get_lsb())
&& (this->get_msb() < portA.get_msb()) ) {
return true;
}
return false;
}
/************************************************************************
* Mutators
***********************************************************************/

View File

@ -21,6 +21,7 @@ class BasicPort {
BasicPort(const BasicPort& basic_port); /* Copy constructor */
public: /* Overloaded operators */
bool operator== (const BasicPort& portA) const;
bool operator< (const BasicPort& portA) const;
public: /* Accessors */
size_t get_width() const; /* get the port width */
size_t get_msb() const; /* get the LSB */

View File

@ -306,35 +306,37 @@ bool try_match_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
t_pb_graph_pin* physical_pb_graph_pin,
const VprDeviceAnnotation& vpr_device_annotation) {
/* If the parent ports of the two pins are not paired, fail */
if (physical_pb_graph_pin->port != vpr_device_annotation.physical_pb_port(operating_pb_graph_pin->port)) {
return false;
}
/* Check the pin number of physical pb_graph_pin matches the pin number of
* operating pb_graph_pin plus a rotation offset
* operating port physical port
* LSB port_range.lsb() pin_number pin_number MSB
* | | |
* Operating port | | +------ |
* | |<----offset--->|
* Physical port | + + +
*
* Note:
* - accumulated offset is NOT the pin rotate offset specified by users
* It is an aggregation of the offset during pin pairing
* Each time, we manage to pair two pins, the accumulated offset will be incremented
* by the pin rotate offset value
* The accumulated offset will be reset to 0 when it exceeds the msb() of the physical port
*/
int acc_offset = vpr_device_annotation.physical_pb_pin_offset(operating_pb_graph_pin->port);
const BasicPort& physical_port_range = vpr_device_annotation.physical_pb_port_range(operating_pb_graph_pin->port);
if (physical_pb_graph_pin->pin_number != operating_pb_graph_pin->pin_number
+ (int)physical_port_range.get_lsb()
+ acc_offset) {
return false;
}
for (t_port* candidate_port : vpr_device_annotation.physical_pb_port(operating_pb_graph_pin->port)) {
if (physical_pb_graph_pin->port != candidate_port) {
return false;
}
/* Check the pin number of physical pb_graph_pin matches the pin number of
* operating pb_graph_pin plus a rotation offset
* operating port physical port
* LSB port_range.lsb() pin_number pin_number MSB
* | | |
* Operating port | | +------ |
* | |<----offset--->|
* Physical port | + + +
*
* Note:
* - accumulated offset is NOT the pin rotate offset specified by users
* It is an aggregation of the offset during pin pairing
* Each time, we manage to pair two pins, the accumulated offset will be incremented
* by the pin rotate offset value
* The accumulated offset will be reset to 0 when it exceeds the msb() of the physical port
*/
int acc_offset = vpr_device_annotation.physical_pb_pin_offset(operating_pb_graph_pin->port, candidate_port);
const BasicPort& physical_port_range = vpr_device_annotation.physical_pb_port_range(operating_pb_graph_pin->port, candidate_port);
if (physical_pb_graph_pin->pin_number != operating_pb_graph_pin->pin_number
+ (int)physical_port_range.get_lsb()
+ acc_offset) {
return false;
}
/* Reach here, it means all the requirements have been met */
return true;
/* Reach here, it means all the requirements have been met */
return true;
}
}
/********************************************************************

View File

@ -211,32 +211,38 @@ bool pair_operating_and_physical_pb_types(t_pb_type* operating_pb_type,
* if not found, we assume that the physical port is the same as the operating pb_port
*/
for (t_port* operating_pb_port : pb_type_ports(operating_pb_type)) {
/* Try to find the port in the pb_type_annotation */
BasicPort expected_physical_pb_port = pb_type_annotation.physical_pb_type_port(std::string(operating_pb_port->name));
if (true == expected_physical_pb_port.get_name().empty()) {
/* Not found, we reset the port information to be consistent as the operating pb_port */
std::map<BasicPort, int> expected_physical_pb_ports = pb_type_annotation.physical_pb_type_port(std::string(operating_pb_port->name));
/* If not defined in the annotation, set the default pair:
* rotate_offset is 0 by default!
*/
if (true == expected_physical_pb_ports.empty()) {
BasicPort expected_physical_pb_port;
expected_physical_pb_port.set_name(std::string(operating_pb_port->name));
expected_physical_pb_port.set_width(operating_pb_port->num_pins);
expected_physical_pb_ports[expected_physical_pb_port] = 0;
}
/* Try to find the expected port in the physical pb_type */
t_port* physical_pb_port = find_pb_type_port(physical_pb_type, expected_physical_pb_port.get_name());
/* Not found, mapping fails */
if (nullptr == physical_pb_port) {
return false;
for (const auto& expected_physical_pb_port : expected_physical_pb_ports) {
/* Try to find the expected port in the physical pb_type */
t_port* physical_pb_port = find_pb_type_port(physical_pb_type, expected_physical_pb_port.first.get_name());
/* Not found, mapping fails */
if (nullptr == physical_pb_port) {
return false;
}
/* If the port range does not match, mapping fails */
if (false == BasicPort(physical_pb_port->name, physical_pb_port->num_pins).contained(expected_physical_pb_port.first)) {
return false;
}
/* Now, port mapping should succeed, we update the vpr_device_annotation
* - port binding
* - port range
* - port pin rotate offset
*/
vpr_device_annotation.add_physical_pb_port(operating_pb_port, physical_pb_port);
vpr_device_annotation.add_physical_pb_port_range(operating_pb_port, physical_pb_port, expected_physical_pb_port.first);
vpr_device_annotation.add_physical_pb_pin_rotate_offset(operating_pb_port, physical_pb_port, expected_physical_pb_port.second);
}
/* If the port range does not match, mapping fails */
if (false == BasicPort(physical_pb_port->name, physical_pb_port->num_pins).contained(expected_physical_pb_port)) {
return false;
}
/* Now, port mapping should succeed, we update the vpr_device_annotation
* - port binding
* - port range
* - port pin rotate offset
*/
vpr_device_annotation.add_physical_pb_port(operating_pb_port, physical_pb_port);
vpr_device_annotation.add_physical_pb_port_range(operating_pb_port, expected_physical_pb_port);
vpr_device_annotation.add_physical_pb_pin_rotate_offset(operating_pb_port, pb_type_annotation.physical_pin_rotate_offset(std::string(operating_pb_port->name)));
}
/* Now, pb_type mapping should succeed, we update the vpr_device_annotation
@ -365,7 +371,7 @@ bool self_pair_physical_pb_types(t_pb_type* physical_pb_type,
for (t_port* physical_pb_port : pb_type_ports(physical_pb_type)) {
BasicPort physical_port_range(physical_pb_port->name, physical_pb_port->num_pins);
vpr_device_annotation.add_physical_pb_port(physical_pb_port, physical_pb_port);
vpr_device_annotation.add_physical_pb_port_range(physical_pb_port, physical_port_range);
vpr_device_annotation.add_physical_pb_port_range(physical_pb_port, physical_pb_port, physical_port_range);
}
/* Now, pb_type mapping should succeed, we update the vpr_device_annotation */

View File

@ -114,7 +114,7 @@ void check_vpr_physical_primitive_pb_type_annotation(t_pb_type* cur_pb_type,
/* Now we need to check each port of the pb_type */
for (t_port* pb_port : pb_type_ports(cur_pb_type)) {
if (nullptr == vpr_device_annotation.physical_pb_port(pb_port)) {
if (0 == vpr_device_annotation.physical_pb_port(pb_port).size()) {
VTR_LOG_ERROR("Find a port '%s' of pb_type '%s' which has not been mapped to any physical port!\n",
pb_port->name, cur_pb_type->name);
VTR_LOG_ERROR("Please specify in the OpenFPGA architecture\n");

View File

@ -48,23 +48,28 @@ t_pb_type* VprDeviceAnnotation::physical_pb_type(t_pb_type* pb_type) const {
return physical_pb_types_.at(pb_type);
}
t_port* VprDeviceAnnotation::physical_pb_port(t_port* pb_port) const {
std::vector<t_port*> VprDeviceAnnotation::physical_pb_port(t_port* pb_port) const {
/* Ensure that the pb_type is in the list */
std::map<t_port*, t_port*>::const_iterator it = physical_pb_ports_.find(pb_port);
std::map<t_port*, std::vector<t_port*>>::const_iterator it = physical_pb_ports_.find(pb_port);
if (it == physical_pb_ports_.end()) {
return nullptr;
return std::vector<t_port*>();
}
return physical_pb_ports_.at(pb_port);
}
BasicPort VprDeviceAnnotation::physical_pb_port_range(t_port* pb_port) const {
BasicPort VprDeviceAnnotation::physical_pb_port_range(t_port* operating_pb_port,
t_port* physical_pb_port) const {
/* Ensure that the pb_type is in the list */
std::map<t_port*, BasicPort>::const_iterator it = physical_pb_port_ranges_.find(pb_port);
std::map<t_port*, std::map<t_port*, BasicPort>>::const_iterator it = physical_pb_port_ranges_.find(operating_pb_port);
if (it == physical_pb_port_ranges_.end()) {
/* Return an invalid port. As such the port width will be 0, which is an invalid value */
return BasicPort();
}
return physical_pb_port_ranges_.at(pb_port);
if (0 == physical_pb_port_ranges_.at(operating_pb_port).count(physical_pb_port)) {
/* Return an invalid port. As such the port width will be 0, which is an invalid value */
return BasicPort();
}
return physical_pb_port_ranges_.at(operating_pb_port).at(physical_pb_port);
}
CircuitModelId VprDeviceAnnotation::pb_type_circuit_model(t_pb_type* physical_pb_type) const {
@ -185,24 +190,34 @@ int VprDeviceAnnotation::physical_pb_type_index_offset(t_pb_type* pb_type) const
return physical_pb_type_index_offsets_.at(pb_type);
}
int VprDeviceAnnotation::physical_pb_pin_rotate_offset(t_port* pb_port) const {
int VprDeviceAnnotation::physical_pb_pin_rotate_offset(t_port* operating_pb_port,
t_port* physical_pb_port) const {
/* Ensure that the pb_type is in the list */
std::map<t_port*, int>::const_iterator it = physical_pb_pin_rotate_offsets_.find(pb_port);
std::map<t_port*, std::map<t_port*, int>>::const_iterator it = physical_pb_pin_rotate_offsets_.find(operating_pb_port);
if (it == physical_pb_pin_rotate_offsets_.end()) {
/* Default value is 0 */
return 0;
}
return physical_pb_pin_rotate_offsets_.at(pb_port);
if (0 == physical_pb_pin_rotate_offsets_.at(operating_pb_port).count(physical_pb_port)) {
/* Default value is 0 */
return 0;
}
return physical_pb_pin_rotate_offsets_.at(operating_pb_port).at(physical_pb_port);
}
int VprDeviceAnnotation::physical_pb_pin_offset(t_port* pb_port) const {
int VprDeviceAnnotation::physical_pb_pin_offset(t_port* operating_pb_port,
t_port* physical_pb_port) const {
/* Ensure that the pb_type is in the list */
std::map<t_port*, int>::const_iterator it = physical_pb_pin_offsets_.find(pb_port);
std::map<t_port*, std::map<t_port*, int>>::const_iterator it = physical_pb_pin_offsets_.find(operating_pb_port);
if (it == physical_pb_pin_offsets_.end()) {
/* Default value is 0 */
return 0;
}
return physical_pb_pin_offsets_.at(pb_port);
if (0 == physical_pb_pin_offsets_.at(operating_pb_port).count(physical_pb_port)) {
/* Default value is 0 */
return 0;
}
return physical_pb_pin_offsets_.at(operating_pb_port).at(physical_pb_port);
}
@ -274,29 +289,28 @@ void VprDeviceAnnotation::add_physical_pb_type(t_pb_type* operating_pb_type, t_p
physical_pb_types_[operating_pb_type] = physical_pb_type;
}
void VprDeviceAnnotation::add_physical_pb_port(t_port* operating_pb_port, t_port* physical_pb_port) {
/* Warn any override attempt */
std::map<t_port*, t_port*>::const_iterator it = physical_pb_ports_.find(operating_pb_port);
if (it != physical_pb_ports_.end()) {
VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port '%s'!\n",
operating_pb_port->name, physical_pb_port->name);
}
physical_pb_ports_[operating_pb_port] = physical_pb_port;
void VprDeviceAnnotation::add_physical_pb_port(t_port* operating_pb_port,
t_port* physical_pb_port) {
physical_pb_ports_[operating_pb_port].push_back(physical_pb_port);
}
void VprDeviceAnnotation::add_physical_pb_port_range(t_port* operating_pb_port, const BasicPort& port_range) {
void VprDeviceAnnotation::add_physical_pb_port_range(t_port* operating_pb_port,
t_port* physical_pb_port,
const BasicPort& port_range) {
/* The port range must satify the port width*/
VTR_ASSERT((size_t)operating_pb_port->num_pins == port_range.get_width());
/* Warn any override attempt */
std::map<t_port*, BasicPort>::const_iterator it = physical_pb_port_ranges_.find(operating_pb_port);
if (it != physical_pb_port_ranges_.end()) {
VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port range '[%ld:%ld]'!\n",
operating_pb_port->name, port_range.get_lsb(), port_range.get_msb());
std::map<t_port*, std::map<t_port*, BasicPort>>::const_iterator it = physical_pb_port_ranges_.find(operating_pb_port);
if ( (it != physical_pb_port_ranges_.end())
&& (0 < physical_pb_port_ranges_[operating_pb_port].count(physical_pb_port)) ) {
VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port range '%s[%ld:%ld]'!\n",
operating_pb_port->name,
physical_pb_port->name,
port_range.get_lsb(), port_range.get_msb());
}
physical_pb_port_ranges_[operating_pb_port] = port_range;
physical_pb_port_ranges_[operating_pb_port][physical_pb_port] = port_range;
}
void VprDeviceAnnotation::add_pb_type_circuit_model(t_pb_type* physical_pb_type, const CircuitModelId& circuit_model) {
@ -396,17 +410,20 @@ void VprDeviceAnnotation::add_physical_pb_type_index_offset(t_pb_type* pb_type,
physical_pb_type_index_offsets_[pb_type] = offset;
}
void VprDeviceAnnotation::add_physical_pb_pin_rotate_offset(t_port* pb_port, const int& offset) {
void VprDeviceAnnotation::add_physical_pb_pin_rotate_offset(t_port* operating_pb_port,
t_port* physical_pb_port,
const int& offset) {
/* Warn any override attempt */
std::map<t_port*, int>::const_iterator it = physical_pb_pin_rotate_offsets_.find(pb_port);
if (it != physical_pb_pin_rotate_offsets_.end()) {
VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port pin rotate offset '%d'!\n",
pb_port->name, offset);
std::map<t_port*, std::map<t_port*, int>>::const_iterator it = physical_pb_pin_rotate_offsets_.find(operating_pb_port);
if ( (it != physical_pb_pin_rotate_offsets_.end())
&& (0 < physical_pb_pin_rotate_offsets_[operating_pb_port].count(physical_pb_port)) ) {
VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port '%s' pin rotate offset '%d'!\n",
operating_pb_port->name, offset);
}
physical_pb_pin_rotate_offsets_[pb_port] = offset;
physical_pb_pin_rotate_offsets_[operating_pb_port][physical_pb_port] = offset;
/* We initialize the accumulated offset to 0 */
physical_pb_pin_offsets_[pb_port] = 0;
physical_pb_pin_offsets_[operating_pb_port][physical_pb_port] = 0;
}
void VprDeviceAnnotation::add_physical_pb_graph_pin(const t_pb_graph_pin* operating_pb_graph_pin,
@ -432,17 +449,17 @@ void VprDeviceAnnotation::add_physical_pb_graph_pin(const t_pb_graph_pin* operat
* Physical port | + + +
*
*/
if (0 == physical_pb_pin_rotate_offset(operating_pb_graph_pin->port)) {
if (0 == physical_pb_pin_rotate_offset(operating_pb_graph_pin->port, physical_pb_graph_pin->port)) {
return;
}
physical_pb_pin_offsets_[operating_pb_graph_pin->port] += physical_pb_pin_rotate_offset(operating_pb_graph_pin->port);
physical_pb_pin_offsets_[operating_pb_graph_pin->port][physical_pb_graph_pin->port] += physical_pb_pin_rotate_offset(operating_pb_graph_pin->port, physical_pb_graph_pin->port);
if ((size_t)physical_pb_port(operating_pb_graph_pin->port)->num_pins - 1
if ((size_t)physical_pb_graph_pin->port->num_pins - 1
< operating_pb_graph_pin->pin_number
+ physical_pb_port_range(operating_pb_graph_pin->port).get_lsb()
+ physical_pb_pin_offsets_[operating_pb_graph_pin->port]) {
physical_pb_pin_offsets_[operating_pb_graph_pin->port] = 0;
+ physical_pb_port_range(operating_pb_graph_pin->port, physical_pb_graph_pin->port).get_lsb()
+ physical_pb_pin_offsets_[operating_pb_graph_pin->port][physical_pb_graph_pin->port]) {
physical_pb_pin_offsets_[operating_pb_graph_pin->port][physical_pb_graph_pin->port] = 0;
}
}

View File

@ -45,8 +45,9 @@ class VprDeviceAnnotation {
bool is_physical_pb_type(t_pb_type* pb_type) const;
t_mode* physical_mode(t_pb_type* pb_type) const;
t_pb_type* physical_pb_type(t_pb_type* pb_type) const;
t_port* physical_pb_port(t_port* pb_port) const;
BasicPort physical_pb_port_range(t_port* pb_port) const;
std::vector<t_port*> physical_pb_port(t_port* pb_port) const;
BasicPort physical_pb_port_range(t_port* operating_pb_port,
t_port* physical_pb_port) const;
CircuitModelId pb_type_circuit_model(t_pb_type* physical_pb_type) const;
CircuitModelId interconnect_circuit_model(t_interconnect* pb_interconnect) const;
e_interconnect interconnect_physical_type(t_interconnect* pb_interconnect) const;
@ -60,7 +61,8 @@ class VprDeviceAnnotation {
float physical_pb_type_index_factor(t_pb_type* pb_type) const;
int physical_pb_type_index_offset(t_pb_type* pb_type) const;
int physical_pb_pin_rotate_offset(t_port* pb_port) const;
int physical_pb_pin_rotate_offset(t_port* operating_pb_port,
t_port* physical_pb_port) const;
/**This function returns an accumulated offset. Note that the
* accumulated offset is NOT the pin rotate offset specified by users
@ -69,7 +71,8 @@ class VprDeviceAnnotation {
* by the pin rotate offset value
* The accumulated offset will be reset to 0 when it exceeds the msb() of the physical port
*/
int physical_pb_pin_offset(t_port* pb_port) const;
int physical_pb_pin_offset(t_port* operating_pb_port,
t_port* physical_pb_port) const;
t_pb_graph_pin* physical_pb_graph_pin(const t_pb_graph_pin* pb_graph_pin) const;
CircuitModelId rr_switch_circuit_model(const RRSwitchId& rr_switch) const;
CircuitModelId rr_segment_circuit_model(const RRSegmentId& rr_segment) const;
@ -78,8 +81,11 @@ class VprDeviceAnnotation {
public: /* Public mutators */
void add_pb_type_physical_mode(t_pb_type* pb_type, t_mode* physical_mode);
void add_physical_pb_type(t_pb_type* operating_pb_type, t_pb_type* physical_pb_type);
void add_physical_pb_port(t_port* operating_pb_port, t_port* physical_pb_port);
void add_physical_pb_port_range(t_port* operating_pb_port, const BasicPort& port_range);
void add_physical_pb_port(t_port* operating_pb_port,
t_port* physical_pb_port);
void add_physical_pb_port_range(t_port* operating_pb_port,
t_port* physical_pb_port,
const BasicPort& port_range);
void add_pb_type_circuit_model(t_pb_type* physical_pb_type, const CircuitModelId& circuit_model);
void add_interconnect_circuit_model(t_interconnect* pb_interconnect, const CircuitModelId& circuit_model);
void add_interconnect_physical_type(t_interconnect* pb_interconnect, const e_interconnect& physical_type);
@ -90,7 +96,9 @@ class VprDeviceAnnotation {
t_pb_graph_node* physical_pb_graph_node);
void add_physical_pb_type_index_factor(t_pb_type* pb_type, const float& factor);
void add_physical_pb_type_index_offset(t_pb_type* pb_type, const int& offset);
void add_physical_pb_pin_rotate_offset(t_port* pb_port, const int& offset);
void add_physical_pb_pin_rotate_offset(t_port* operating_pb_port,
t_port* physical_pb_port,
const int& offset);
void add_physical_pb_graph_pin(const t_pb_graph_pin* operating_pb_graph_pin, t_pb_graph_pin* physical_pb_graph_pin);
void add_rr_switch_circuit_model(const RRSwitchId& rr_switch, const CircuitModelId& circuit_model);
void add_rr_segment_circuit_model(const RRSegmentId& rr_segment, const CircuitModelId& circuit_model);
@ -139,17 +147,17 @@ class VprDeviceAnnotation {
* Note:
* - the parent of physical pb_port MUST be a physical pb_type
*/
std::map<t_port*, t_port*> physical_pb_ports_;
std::map<t_port*, int> physical_pb_pin_rotate_offsets_;
std::map<t_port*, std::vector<t_port*>> physical_pb_ports_;
std::map<t_port*, std::map<t_port*, int>> physical_pb_pin_rotate_offsets_;
/* Accumulated offsets for a physical pb_type port, just for internal usage */
std::map<t_port*, int> physical_pb_pin_offsets_;
std::map<t_port*, std::map<t_port*, int>> physical_pb_pin_offsets_;
/* Pair a pb_port to its LSB and MSB of a physical pb_port
* Note:
* - the LSB and MSB MUST be in range of the physical pb_port
*/
std::map<t_port*, BasicPort> physical_pb_port_ranges_;
std::map<t_port*, std::map<t_port*, BasicPort>> physical_pb_port_ranges_;
/* Pair a pb_port to a circuit port in circuit model
* Note: