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
|
||||
* 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());
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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
|
||||
***********************************************************************/
|
||||
|
@ -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;
|
||||
/* 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*/
|
||||
|
|
|
@ -54,7 +54,18 @@ class VprPbTypeAnnotation {
|
|||
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_offset(t_pb_type* pb_type) 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 */
|
||||
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);
|
||||
|
@ -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_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_graph_pin(t_pb_graph_pin* operating_pb_graph_pin, t_pb_graph_pin* physical_pb_graph_pin);
|
||||
private: /* Internal data */
|
||||
/* Pair a regular pb_type to its physical pb_type */
|
||||
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*, 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
|
||||
* Note:
|
||||
* - the LSB and MSB MUST be in range of the physical pb_port
|
||||
|
|
Loading…
Reference in New Issue