diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp index b38796c9c..133ee000c 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp @@ -1,6 +1,7 @@ /************************************************************************ * Member functions for class PbTypeAnnotation ***********************************************************************/ +#include #include "vtr_log.h" #include "vtr_assert.h" #include "pb_type_annotation.h" @@ -85,24 +86,15 @@ std::vector PbTypeAnnotation::port_names() const { return keys; } -BasicPort PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const { - std::map::const_iterator it = operating_pb_type_ports_.find(port_name); +std::map PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const { + std::map>::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(); } return operating_pb_type_ports_.at(port_name); } -int PbTypeAnnotation::physical_pin_rotate_offset(const std::string& port_name) const { - std::map::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 PbTypeAnnotation::interconnect_names() const { std::vector 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::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>::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::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>::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, diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h index e80acc3dc..4e1d4e8a2 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h @@ -48,8 +48,7 @@ class PbTypeAnnotation { float physical_pb_type_index_factor() const; int physical_pb_type_index_offset() const; std::vector 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 physical_pb_type_port(const std::string& port_name) const; std::vector 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 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 physical_pin_rotate_offsets_; + std::map> operating_pb_type_ports_; /* Link between the interconnects under this pb_type and circuit model names */ std::map interconnect_circuit_model_names_; diff --git a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp index 743e23741..a4d25e1cf 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp @@ -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 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 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])); + } + } } /******************************************************************** diff --git a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp index 531e117f1..b013e5801 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp @@ -116,8 +116,25 @@ void write_xml_pb_port_annotation(std::fstream& fp, fp << "\t\t\t" << "" << "\n"; } diff --git a/libopenfpga/libopenfpgautil/src/openfpga_port.cpp b/libopenfpga/libopenfpgautil/src/openfpga_port.cpp index 7e7cc4007..023af7618 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_port.cpp +++ b/libopenfpga/libopenfpgautil/src/openfpga_port.cpp @@ -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 ***********************************************************************/ diff --git a/libopenfpga/libopenfpgautil/src/openfpga_port.h b/libopenfpga/libopenfpgautil/src/openfpga_port.h index d870e94fc..ca1afb4a5 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_port.h +++ b/libopenfpga/libopenfpgautil/src/openfpga_port.h @@ -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 */ diff --git a/openfpga/src/annotation/annotate_pb_graph.cpp b/openfpga/src/annotation/annotate_pb_graph.cpp index 081acf900..93a154222 100644 --- a/openfpga/src/annotation/annotate_pb_graph.cpp +++ b/openfpga/src/annotation/annotate_pb_graph.cpp @@ -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; + } } /******************************************************************** diff --git a/openfpga/src/annotation/annotate_pb_types.cpp b/openfpga/src/annotation/annotate_pb_types.cpp index d8701be78..cb6c9e9b3 100644 --- a/openfpga/src/annotation/annotate_pb_types.cpp +++ b/openfpga/src/annotation/annotate_pb_types.cpp @@ -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 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 */ diff --git a/openfpga/src/annotation/check_pb_type_annotation.cpp b/openfpga/src/annotation/check_pb_type_annotation.cpp index 5159ec064..d0709c81c 100644 --- a/openfpga/src/annotation/check_pb_type_annotation.cpp +++ b/openfpga/src/annotation/check_pb_type_annotation.cpp @@ -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"); diff --git a/openfpga/src/annotation/vpr_device_annotation.cpp b/openfpga/src/annotation/vpr_device_annotation.cpp index 0787e0225..71b3baf63 100644 --- a/openfpga/src/annotation/vpr_device_annotation.cpp +++ b/openfpga/src/annotation/vpr_device_annotation.cpp @@ -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 VprDeviceAnnotation::physical_pb_port(t_port* pb_port) const { /* Ensure that the pb_type is in the list */ - std::map::const_iterator it = physical_pb_ports_.find(pb_port); + std::map>::const_iterator it = physical_pb_ports_.find(pb_port); if (it == physical_pb_ports_.end()) { - return nullptr; + return std::vector(); } 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::const_iterator it = physical_pb_port_ranges_.find(pb_port); + std::map>::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::const_iterator it = physical_pb_pin_rotate_offsets_.find(pb_port); + std::map>::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::const_iterator it = physical_pb_pin_offsets_.find(pb_port); + std::map>::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::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::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>::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::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>::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; } } diff --git a/openfpga/src/annotation/vpr_device_annotation.h b/openfpga/src/annotation/vpr_device_annotation.h index 00209df5c..6ac9ab4b5 100644 --- a/openfpga/src/annotation/vpr_device_annotation.h +++ b/openfpga/src/annotation/vpr_device_annotation.h @@ -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 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 physical_pb_ports_; - std::map physical_pb_pin_rotate_offsets_; + std::map> physical_pb_ports_; + std::map> physical_pb_pin_rotate_offsets_; /* Accumulated offsets for a physical pb_type port, just for internal usage */ - std::map physical_pb_pin_offsets_; + std::map> 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 physical_pb_port_ranges_; + std::map> physical_pb_port_ranges_; /* Pair a pb_port to a circuit port in circuit model * Note: