add pb_graph pin annotation
This commit is contained in:
parent
d62c9fe86f
commit
007e1997e6
|
@ -173,6 +173,172 @@ void annotate_primitive_pb_graph_node_unique_index(const DeviceContext& vpr_devi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Evaluate if the two pb_graph pins are matched by
|
||||||
|
* - pb_type port annotation
|
||||||
|
* - LSB/MSB and pin offset
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
bool try_match_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
||||||
|
t_pb_graph_pin* physical_pb_graph_pin,
|
||||||
|
const VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||||
|
/* If the parent ports of the two pins are not paired, fail */
|
||||||
|
if (physical_pb_graph_pin->port != vpr_pb_type_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_pb_type_annotation.physical_pb_pin_offset(operating_pb_graph_pin->port);
|
||||||
|
const BasicPort& physical_port_range = vpr_pb_type_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reach here, it means all the requirements have been met */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Bind a pb_graph_pin from an operating pb_graph_node to
|
||||||
|
* a pb_graph_pin from a physical pb_graph_node
|
||||||
|
* - the name matching rules are already defined in the vpr_pb_type_annotation
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void annotate_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
||||||
|
t_pb_graph_node* physical_pb_graph_node,
|
||||||
|
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||||
|
/* Iterate over every port and pin of the operating pb_graph_node
|
||||||
|
* and find the physical pins
|
||||||
|
*/
|
||||||
|
for (int iport = 0; iport < physical_pb_graph_node->num_input_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < physical_pb_graph_node->num_input_pins[iport]; ++ipin) {
|
||||||
|
if (false == try_match_pb_graph_pin(operating_pb_graph_pin,
|
||||||
|
&(physical_pb_graph_node->input_pins[iport][ipin]),
|
||||||
|
vpr_pb_type_annotation)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Reach here, it means the pins are matched by the annotation requirements
|
||||||
|
* We can pair the pin and return
|
||||||
|
*/
|
||||||
|
vpr_pb_type_annotation.add_physical_pb_graph_pin(operating_pb_graph_pin, &(physical_pb_graph_node->input_pins[iport][ipin]));
|
||||||
|
VTR_LOG("Bind a pb_graph_node '%s[%d]' pin '%s[%d]' to a pb_graph_node '%s[%d]' pin '%s[%d]'!\n",
|
||||||
|
operating_pb_graph_pin->parent_node->pb_type->name,
|
||||||
|
operating_pb_graph_pin->parent_node->placement_index,
|
||||||
|
operating_pb_graph_pin->port->name,
|
||||||
|
operating_pb_graph_pin->pin_number,
|
||||||
|
physical_pb_graph_node->pb_type->name,
|
||||||
|
physical_pb_graph_node->placement_index,
|
||||||
|
physical_pb_graph_node->input_pins[iport][ipin].port->name,
|
||||||
|
physical_pb_graph_node->input_pins[iport][ipin].pin_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int iport = 0; iport < physical_pb_graph_node->num_output_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < physical_pb_graph_node->num_output_pins[iport]; ++ipin) {
|
||||||
|
if (false == try_match_pb_graph_pin(operating_pb_graph_pin,
|
||||||
|
&(physical_pb_graph_node->output_pins[iport][ipin]),
|
||||||
|
vpr_pb_type_annotation)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Reach here, it means the pins are matched by the annotation requirements
|
||||||
|
* We can pair the pin and return
|
||||||
|
*/
|
||||||
|
vpr_pb_type_annotation.add_physical_pb_graph_pin(operating_pb_graph_pin, &(physical_pb_graph_node->output_pins[iport][ipin]));
|
||||||
|
VTR_LOG("Bind a pb_graph_node '%s[%d]' pin '%s[%d]' to a pb_graph_node '%s[%d]' pin '%s[%d]'!\n",
|
||||||
|
operating_pb_graph_pin->parent_node->pb_type->name,
|
||||||
|
operating_pb_graph_pin->parent_node->placement_index,
|
||||||
|
operating_pb_graph_pin->port->name,
|
||||||
|
operating_pb_graph_pin->pin_number,
|
||||||
|
physical_pb_graph_node->pb_type->name,
|
||||||
|
physical_pb_graph_node->placement_index,
|
||||||
|
physical_pb_graph_node->output_pins[iport][ipin].port->name,
|
||||||
|
physical_pb_graph_node->output_pins[iport][ipin].pin_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int iport = 0; iport < physical_pb_graph_node->num_clock_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < physical_pb_graph_node->num_clock_pins[iport]; ++ipin) {
|
||||||
|
if (false == try_match_pb_graph_pin(operating_pb_graph_pin,
|
||||||
|
&(physical_pb_graph_node->clock_pins[iport][ipin]),
|
||||||
|
vpr_pb_type_annotation)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Reach here, it means the pins are matched by the annotation requirements
|
||||||
|
* We can pair the pin and return
|
||||||
|
*/
|
||||||
|
vpr_pb_type_annotation.add_physical_pb_graph_pin(operating_pb_graph_pin, &(physical_pb_graph_node->clock_pins[iport][ipin]));
|
||||||
|
VTR_LOG("Bind a pb_graph_node '%s[%d]' pin '%s[%d]' to a pb_graph_node '%s[%d]' pin '%s[%d]'!\n",
|
||||||
|
operating_pb_graph_pin->parent_node->pb_type->name,
|
||||||
|
operating_pb_graph_pin->parent_node->placement_index,
|
||||||
|
operating_pb_graph_pin->port->name,
|
||||||
|
operating_pb_graph_pin->pin_number,
|
||||||
|
physical_pb_graph_node->pb_type->name,
|
||||||
|
physical_pb_graph_node->placement_index,
|
||||||
|
physical_pb_graph_node->clock_pins[iport][ipin].port->name,
|
||||||
|
physical_pb_graph_node->clock_pins[iport][ipin].pin_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we reach here, it means that pin pairing fails, error out! */
|
||||||
|
VTR_LOG_ERROR("Fail to match a physical pin for '%s' from pb_graph_node '%s'!\n",
|
||||||
|
operating_pb_graph_pin->port->name,
|
||||||
|
physical_pb_graph_node->hierarchical_type_name().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* This function will try bind each pin of the operating pb_graph_node
|
||||||
|
* to a pin of the physical pb_graph_node by following the annotation
|
||||||
|
* available in vpr_pb_type_annotation
|
||||||
|
* It will add the pin bindings to the vpr_pb_type_annotation
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void annotate_physical_pb_graph_node_pins(t_pb_graph_node* operating_pb_graph_node,
|
||||||
|
t_pb_graph_node* physical_pb_graph_node,
|
||||||
|
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||||
|
/* Iterate over every port and pin of the operating pb_graph_node
|
||||||
|
* and find the physical pins
|
||||||
|
*/
|
||||||
|
for (int iport = 0; iport < operating_pb_graph_node->num_input_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < operating_pb_graph_node->num_input_pins[iport]; ++ipin) {
|
||||||
|
annotate_physical_pb_graph_pin(&(operating_pb_graph_node->input_pins[iport][ipin]),
|
||||||
|
physical_pb_graph_node, vpr_pb_type_annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int iport = 0; iport < operating_pb_graph_node->num_output_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < operating_pb_graph_node->num_output_pins[iport]; ++ipin) {
|
||||||
|
annotate_physical_pb_graph_pin(&(operating_pb_graph_node->output_pins[iport][ipin]),
|
||||||
|
physical_pb_graph_node, vpr_pb_type_annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int iport = 0; iport < operating_pb_graph_node->num_clock_ports; ++iport) {
|
||||||
|
for (int ipin = 0; ipin < operating_pb_graph_node->num_clock_pins[iport]; ++ipin) {
|
||||||
|
annotate_physical_pb_graph_pin(&(operating_pb_graph_node->clock_pins[iport][ipin]),
|
||||||
|
physical_pb_graph_node, vpr_pb_type_annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* This function will recursively walk through all the pb_graph nodes
|
* This function will recursively walk through all the pb_graph nodes
|
||||||
* starting from a top node.
|
* starting from a top node.
|
||||||
|
@ -226,6 +392,7 @@ void rec_build_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_n
|
||||||
physical_pb_graph_node->hierarchical_type_name().c_str());
|
physical_pb_graph_node->hierarchical_type_name().c_str());
|
||||||
|
|
||||||
/* Try to bind each pins under this pb_graph_node to physical_pb_graph_node */
|
/* Try to bind each pins under this pb_graph_node to physical_pb_graph_node */
|
||||||
|
annotate_physical_pb_graph_node_pins(pb_graph_node, physical_pb_graph_node, vpr_pb_type_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
|
@ -195,6 +195,26 @@ int VprPbTypeAnnotation::physical_pb_pin_rotate_offset(t_port* pb_port) const {
|
||||||
return physical_pb_pin_rotate_offsets_.at(pb_port);
|
return physical_pb_pin_rotate_offsets_.at(pb_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VprPbTypeAnnotation::physical_pb_pin_offset(t_port* 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);
|
||||||
|
if (it == physical_pb_pin_offsets_.end()) {
|
||||||
|
/* Default value is 0 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return physical_pb_pin_offsets_.at(pb_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
t_pb_graph_pin* VprPbTypeAnnotation::physical_pb_graph_pin(t_pb_graph_pin* pb_graph_pin) const {
|
||||||
|
/* Ensure that the pb_type is in the list */
|
||||||
|
std::map<t_pb_graph_pin*, t_pb_graph_pin*>::const_iterator it = physical_pb_graph_pins_.find(pb_graph_pin);
|
||||||
|
if (it == physical_pb_graph_pins_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return physical_pb_graph_pins_.at(pb_graph_pin);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Public mutators
|
* Public mutators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -351,6 +371,45 @@ void VprPbTypeAnnotation::add_physical_pb_pin_rotate_offset(t_port* pb_port, con
|
||||||
}
|
}
|
||||||
|
|
||||||
physical_pb_pin_rotate_offsets_[pb_port] = offset;
|
physical_pb_pin_rotate_offsets_[pb_port] = offset;
|
||||||
|
/* We initialize the accumulated offset to 0 */
|
||||||
|
physical_pb_pin_offsets_[pb_port] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VprPbTypeAnnotation::add_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
||||||
|
t_pb_graph_pin* physical_pb_graph_pin) {
|
||||||
|
/* Warn any override attempt */
|
||||||
|
std::map<t_pb_graph_pin*, t_pb_graph_pin*>::const_iterator it = physical_pb_graph_pins_.find(operating_pb_graph_pin);
|
||||||
|
if (it != physical_pb_graph_pins_.end()) {
|
||||||
|
VTR_LOG_WARN("Override the annotation between operating pb_graph_pin '%s' and it physical pb_graph_pin '%s'!\n",
|
||||||
|
operating_pb_graph_pin->port->name, physical_pb_graph_pin->port->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
physical_pb_graph_pins_[operating_pb_graph_pin] = physical_pb_graph_pin;
|
||||||
|
|
||||||
|
/* Update the accumulated offsets for the operating port
|
||||||
|
* Each time we pair two pins, we update the offset by the pin rotate offset
|
||||||
|
* When the accumulated offset exceeds the MSB of the port range of physical port
|
||||||
|
* we reset it to 0
|
||||||
|
* operating port physical port
|
||||||
|
* LSB port_range.lsb() pin_number pin_number MSB
|
||||||
|
* | | |
|
||||||
|
* Operating port | | +------ |
|
||||||
|
* | |<----offset--->|
|
||||||
|
* Physical port | + + +
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (0 == physical_pb_pin_rotate_offset(operating_pb_graph_pin->port)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
physical_pb_pin_offsets_[operating_pb_graph_pin->port] += physical_pb_pin_rotate_offset(operating_pb_graph_pin->port);
|
||||||
|
|
||||||
|
if (physical_pb_port_range(operating_pb_graph_pin->port).get_msb()
|
||||||
|
< operating_pb_graph_pin->pin_number
|
||||||
|
+ physical_pb_port_range(operating_pb_graph_pin->port).get_lsb()
|
||||||
|
+ physical_pb_pin_offset(operating_pb_graph_pin->port)) {
|
||||||
|
physical_pb_pin_offsets_[operating_pb_graph_pin->port] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* End namespace openfpga*/
|
} /* End namespace openfpga*/
|
||||||
|
|
|
@ -54,7 +54,18 @@ class VprPbTypeAnnotation {
|
||||||
t_pb_graph_node* physical_pb_graph_node(t_pb_graph_node* pb_graph_node) const;
|
t_pb_graph_node* physical_pb_graph_node(t_pb_graph_node* pb_graph_node) const;
|
||||||
int physical_pb_type_index_factor(t_pb_type* pb_type) const;
|
int 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_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* pb_port) const;
|
||||||
|
|
||||||
|
/**This function returns an accumulated offset. Note that the
|
||||||
|
* 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 physical_pb_pin_offset(t_port* pb_port) const;
|
||||||
|
t_pb_graph_pin* physical_pb_graph_pin(t_pb_graph_pin* pb_graph_pin) const;
|
||||||
public: /* Public mutators */
|
public: /* Public mutators */
|
||||||
void add_pb_type_physical_mode(t_pb_type* pb_type, t_mode* physical_mode);
|
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_type(t_pb_type* operating_pb_type, t_pb_type* physical_pb_type);
|
||||||
|
@ -71,6 +82,7 @@ class VprPbTypeAnnotation {
|
||||||
void add_physical_pb_type_index_factor(t_pb_type* pb_type, const int& factor);
|
void add_physical_pb_type_index_factor(t_pb_type* pb_type, const int& factor);
|
||||||
void add_physical_pb_type_index_offset(t_pb_type* pb_type, const int& offset);
|
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* pb_port, const int& offset);
|
||||||
|
void add_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin, t_pb_graph_pin* physical_pb_graph_pin);
|
||||||
private: /* Internal data */
|
private: /* Internal data */
|
||||||
/* Pair a regular pb_type to its physical pb_type */
|
/* Pair a regular pb_type to its physical pb_type */
|
||||||
std::map<t_pb_type*, t_pb_type*> physical_pb_types_;
|
std::map<t_pb_type*, t_pb_type*> physical_pb_types_;
|
||||||
|
@ -117,6 +129,9 @@ class VprPbTypeAnnotation {
|
||||||
std::map<t_port*, t_port*> physical_pb_ports_;
|
std::map<t_port*, t_port*> physical_pb_ports_;
|
||||||
std::map<t_port*, int> physical_pb_pin_rotate_offsets_;
|
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_;
|
||||||
|
|
||||||
/* Pair a pb_port to its LSB and MSB of a physical pb_port
|
/* Pair a pb_port to its LSB and MSB of a physical pb_port
|
||||||
* Note:
|
* Note:
|
||||||
* - the LSB and MSB MUST be in range of the physical pb_port
|
* - the LSB and MSB MUST be in range of the physical pb_port
|
||||||
|
|
Loading…
Reference in New Issue