Merge branch 'refactoring' into dev
This commit is contained in:
commit
7b5ee5c2f6
|
@ -165,6 +165,7 @@ enum e_interconnect {
|
|||
MUX_INTERC = 3,
|
||||
NUM_INTERC_TYPES
|
||||
};
|
||||
constexpr std::array<const char*, NUM_INTERC_TYPES> INTERCONNECT_TYPE_STRING = {{"complete", "direct", "mux"}}; //String versions of interconnection type
|
||||
|
||||
/* Orientations. */
|
||||
enum e_side : unsigned char {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "pb_graph_utils.h"
|
||||
|
||||
#include "annotate_pb_graph.h"
|
||||
#include "check_pb_graph_annotation.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
@ -27,7 +28,8 @@ namespace openfpga {
|
|||
*******************************************************************/
|
||||
static
|
||||
void rec_build_vpr_pb_graph_interconnect_physical_type_annotation(t_pb_graph_node* pb_graph_node,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Skip the root node because we start from the inputs of child pb_graph node
|
||||
*
|
||||
* pb_graph_node
|
||||
|
@ -85,6 +87,9 @@ void rec_build_vpr_pb_graph_interconnect_physical_type_annotation(t_pb_graph_nod
|
|||
/* Skip annotation if we have already done! */
|
||||
continue;
|
||||
}
|
||||
VTR_LOGV(verbose_output,
|
||||
"Infer physical type '%s' of interconnect '%s' (was '%s')\n",
|
||||
INTERCONNECT_TYPE_STRING[interc_physical_type], interc->name, INTERCONNECT_TYPE_STRING[interc->type]);
|
||||
vpr_pb_type_annotation.add_interconnect_physical_type(interc, interc_physical_type);
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +105,9 @@ void rec_build_vpr_pb_graph_interconnect_physical_type_annotation(t_pb_graph_nod
|
|||
for (int ipb = 0; ipb < physical_mode->num_pb_type_children; ++ipb) {
|
||||
/* Each child may exist multiple times in the hierarchy*/
|
||||
for (int jpb = 0; jpb < physical_mode->pb_type_children[ipb].num_pb; ++jpb) {
|
||||
rec_build_vpr_pb_graph_interconnect_physical_type_annotation(&(pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][jpb]), vpr_pb_type_annotation);
|
||||
rec_build_vpr_pb_graph_interconnect_physical_type_annotation(&(pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,13 +122,14 @@ void rec_build_vpr_pb_graph_interconnect_physical_type_annotation(t_pb_graph_nod
|
|||
* build_vpr_physical_pb_mode_implicit_annotation()
|
||||
*******************************************************************/
|
||||
void annotate_pb_graph_interconnect_physical_type(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_graph head */
|
||||
if (nullptr == lb_type.pb_graph_head) {
|
||||
continue;
|
||||
}
|
||||
rec_build_vpr_pb_graph_interconnect_physical_type_annotation(lb_type.pb_graph_head, vpr_pb_type_annotation);
|
||||
rec_build_vpr_pb_graph_interconnect_physical_type_annotation(lb_type.pb_graph_head, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,6 +229,24 @@ bool try_match_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A function to print message to log file/screen when physical pb_graph_pin
|
||||
* binding succeed
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_success_bind_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
||||
t_pb_graph_pin* physical_pb_graph_pin) {
|
||||
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_pin->parent_node->pb_type->name,
|
||||
physical_pb_graph_pin->parent_node->placement_index,
|
||||
physical_pb_graph_pin->port->name,
|
||||
physical_pb_graph_pin->pin_number);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Bind a pb_graph_pin from an operating pb_graph_node to
|
||||
* a pb_graph_pin from a physical pb_graph_node
|
||||
|
@ -229,7 +255,8 @@ bool try_match_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
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) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Iterate over every port and pin of the operating pb_graph_node
|
||||
* and find the physical pins
|
||||
*/
|
||||
|
@ -244,15 +271,9 @@ void annotate_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
* 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);
|
||||
if (true == verbose_output) {
|
||||
print_success_bind_pb_graph_pin(operating_pb_graph_pin, vpr_pb_type_annotation.physical_pb_graph_pin(operating_pb_graph_pin));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -268,15 +289,9 @@ void annotate_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
* 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);
|
||||
if (true == verbose_output) {
|
||||
print_success_bind_pb_graph_pin(operating_pb_graph_pin, vpr_pb_type_annotation.physical_pb_graph_pin(operating_pb_graph_pin));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -292,15 +307,9 @@ void annotate_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
* 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);
|
||||
if (true == verbose_output) {
|
||||
print_success_bind_pb_graph_pin(operating_pb_graph_pin, vpr_pb_type_annotation.physical_pb_graph_pin(operating_pb_graph_pin));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -320,28 +329,32 @@ void annotate_physical_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin,
|
|||
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) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* 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);
|
||||
physical_pb_graph_node, vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
physical_pb_graph_node, vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
physical_pb_graph_node, vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -356,7 +369,8 @@ void annotate_physical_pb_graph_node_pins(t_pb_graph_node* operating_pb_graph_no
|
|||
*******************************************************************/
|
||||
static
|
||||
void rec_build_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_node,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Go recursive first until we touch the primitive node */
|
||||
if (false == is_primitive_pb_type(pb_graph_node->pb_type)) {
|
||||
for (int imode = 0; imode < pb_graph_node->pb_type->num_modes; ++imode) {
|
||||
|
@ -364,7 +378,8 @@ void rec_build_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_n
|
|||
/* Each child may exist multiple times in the hierarchy*/
|
||||
for (int jpb = 0; jpb < pb_graph_node->pb_type->modes[imode].pb_type_children[ipb].num_pb; ++jpb) {
|
||||
rec_build_vpr_physical_pb_graph_node_annotation(&(pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]),
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,12 +409,13 @@ void rec_build_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_n
|
|||
VTR_ASSERT(nullptr != physical_pb_graph_node);
|
||||
vpr_pb_type_annotation.add_physical_pb_graph_node(pb_graph_node, physical_pb_graph_node);
|
||||
|
||||
VTR_LOG("Bind operating pb_graph_node '%s' to physical pb_graph_node '%s'\n",
|
||||
pb_graph_node->hierarchical_type_name().c_str(),
|
||||
physical_pb_graph_node->hierarchical_type_name().c_str());
|
||||
VTR_LOGV(verbose_output,
|
||||
"Bind operating pb_graph_node '%s' to physical pb_graph_node '%s'\n",
|
||||
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 */
|
||||
annotate_physical_pb_graph_node_pins(pb_graph_node, physical_pb_graph_node, vpr_pb_type_annotation);
|
||||
annotate_physical_pb_graph_node_pins(pb_graph_node, physical_pb_graph_node, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -409,13 +425,14 @@ void rec_build_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_n
|
|||
*******************************************************************/
|
||||
static
|
||||
void annotate_physical_pb_graph_node(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_graph head */
|
||||
if (nullptr == lb_type.pb_graph_head) {
|
||||
continue;
|
||||
}
|
||||
rec_build_vpr_physical_pb_graph_node_annotation(lb_type.pb_graph_head, vpr_pb_type_annotation);
|
||||
rec_build_vpr_physical_pb_graph_node_annotation(lb_type.pb_graph_head, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,15 +443,21 @@ void annotate_physical_pb_graph_node(const DeviceContext& vpr_device_ctx,
|
|||
* - Bind pins from operating pb_graph_node to their physical pb_graph_node pins
|
||||
*******************************************************************/
|
||||
void annotate_pb_graph(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
|
||||
VTR_LOG("Assigning unique indices for primitive pb_graph nodes...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
annotate_primitive_pb_graph_node_unique_index(vpr_device_ctx, vpr_pb_type_annotation);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
VTR_LOG("Binding operating pb_graph nodes/pins to physical pb_graph nodes/pins...\n");
|
||||
annotate_physical_pb_graph_node(vpr_device_ctx, vpr_pb_type_annotation);
|
||||
VTR_LOG("Binding operating pb_graph nodes/pins to physical pb_graph nodes/pins...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
annotate_physical_pb_graph_node(vpr_device_ctx, vpr_pb_type_annotation, verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
/* Check each primitive pb_graph_node and pin has been binded to a physical node and pin */
|
||||
check_physical_pb_graph_node_annotation(vpr_device_ctx, const_cast<const VprPbTypeAnnotation&>(vpr_pb_type_annotation));
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
namespace openfpga {
|
||||
|
||||
void annotate_pb_graph_interconnect_physical_type(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation);
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output);
|
||||
|
||||
void annotate_pb_graph(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation);
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace openfpga {
|
|||
static
|
||||
void build_vpr_physical_pb_mode_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
|
||||
/* Since our target is to annotate the physical mode name,
|
||||
|
@ -82,8 +83,9 @@ void build_vpr_physical_pb_mode_explicit_annotation(const DeviceContext& vpr_dev
|
|||
vpr_pb_type_annotation.add_pb_type_physical_mode(target_pb_type, physical_mode);
|
||||
|
||||
/* Give a message */
|
||||
VTR_LOG("Annotate pb_type '%s' with physical mode '%s'\n",
|
||||
target_pb_type->name, physical_mode->name);
|
||||
VTR_LOGV(verbose_output,
|
||||
"Annotate pb_type '%s' with physical mode '%s'\n",
|
||||
target_pb_type->name, physical_mode->name);
|
||||
|
||||
link_success = true;
|
||||
break;
|
||||
|
@ -110,7 +112,8 @@ void build_vpr_physical_pb_mode_explicit_annotation(const DeviceContext& vpr_dev
|
|||
*******************************************************************/
|
||||
static
|
||||
void rec_infer_vpr_physical_pb_mode_annotation(t_pb_type* cur_pb_type,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* We do not check any primitive pb_type */
|
||||
if (true == is_primitive_pb_type(cur_pb_type)) {
|
||||
return;
|
||||
|
@ -128,8 +131,9 @@ void rec_infer_vpr_physical_pb_mode_annotation(t_pb_type* cur_pb_type,
|
|||
if (nullptr == vpr_pb_type_annotation.physical_mode(cur_pb_type)) {
|
||||
/* Not assigned by explicit annotation, we should infer here */
|
||||
vpr_pb_type_annotation.add_pb_type_physical_mode(cur_pb_type, &(cur_pb_type->modes[0]));
|
||||
VTR_LOG("Implicitly infer physical mode '%s' for pb_type '%s'\n",
|
||||
cur_pb_type->modes[0].name, cur_pb_type->name);
|
||||
VTR_LOGV(verbose_output,
|
||||
"Implicitly infer physical mode '%s' for pb_type '%s'\n",
|
||||
cur_pb_type->modes[0].name, cur_pb_type->name);
|
||||
}
|
||||
} else {
|
||||
VTR_ASSERT(1 < cur_pb_type->num_modes);
|
||||
|
@ -151,7 +155,8 @@ void rec_infer_vpr_physical_pb_mode_annotation(t_pb_type* cur_pb_type,
|
|||
/* Traverse the pb_type children under the physical mode */
|
||||
for (int ichild = 0; ichild < physical_mode->num_pb_type_children; ++ichild) {
|
||||
rec_infer_vpr_physical_pb_mode_annotation(&(physical_mode->pb_type_children[ichild]),
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,13 +174,14 @@ void rec_infer_vpr_physical_pb_mode_annotation(t_pb_type* cur_pb_type,
|
|||
*******************************************************************/
|
||||
static
|
||||
void build_vpr_physical_pb_mode_implicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_type head */
|
||||
if (nullptr == lb_type.pb_type) {
|
||||
continue;
|
||||
}
|
||||
rec_infer_vpr_physical_pb_mode_annotation(lb_type.pb_type, vpr_pb_type_annotation);
|
||||
rec_infer_vpr_physical_pb_mode_annotation(lb_type.pb_type, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +263,8 @@ bool pair_operating_and_physical_pb_types(t_pb_type* operating_pb_type,
|
|||
static
|
||||
void build_vpr_physical_pb_type_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
|
||||
/* Since our target is to annotate the operating pb_type tp physical pb_type
|
||||
|
@ -324,8 +331,9 @@ void build_vpr_physical_pb_type_explicit_annotation(const DeviceContext& vpr_dev
|
|||
pb_type_annotation, vpr_pb_type_annotation)) {
|
||||
|
||||
/* Give a message */
|
||||
VTR_LOG("Annotate operating pb_type '%s' to its physical pb_type '%s'\n",
|
||||
target_op_pb_type->name, target_phy_pb_type->name);
|
||||
VTR_LOGV(verbose_output,
|
||||
"Annotate operating pb_type '%s' to its physical pb_type '%s'\n",
|
||||
target_op_pb_type->name, target_phy_pb_type->name);
|
||||
|
||||
link_success = true;
|
||||
break;
|
||||
|
@ -376,7 +384,8 @@ bool self_pair_physical_pb_types(t_pb_type* physical_pb_type,
|
|||
*******************************************************************/
|
||||
static
|
||||
void rec_infer_vpr_physical_pb_type_annotation(t_pb_type* cur_pb_type,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Physical pb_type is mainly for the primitive pb_type */
|
||||
if (true == is_primitive_pb_type(cur_pb_type)) {
|
||||
/* If the physical pb_type has been mapped, we can skip it */
|
||||
|
@ -386,8 +395,9 @@ void rec_infer_vpr_physical_pb_type_annotation(t_pb_type* cur_pb_type,
|
|||
/* Create the pair here */
|
||||
if (true == self_pair_physical_pb_types(cur_pb_type, vpr_pb_type_annotation)) {
|
||||
/* Give a message */
|
||||
VTR_LOG("Implicitly infer the physical pb_type for pb_type '%s' itself\n",
|
||||
cur_pb_type->name);
|
||||
VTR_LOGV(verbose_output,
|
||||
"Implicitly infer the physical pb_type for pb_type '%s' itself\n",
|
||||
cur_pb_type->name);
|
||||
} else {
|
||||
VTR_LOG_ERROR("Unable to infer the physical pb_type for pb_type '%s' itself!\n",
|
||||
cur_pb_type->name);
|
||||
|
@ -403,7 +413,8 @@ void rec_infer_vpr_physical_pb_type_annotation(t_pb_type* cur_pb_type,
|
|||
/* Traverse the pb_type children under the physical mode */
|
||||
for (int ichild = 0; ichild < physical_mode->num_pb_type_children; ++ichild) {
|
||||
rec_infer_vpr_physical_pb_type_annotation(&(physical_mode->pb_type_children[ichild]),
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,13 +429,14 @@ void rec_infer_vpr_physical_pb_type_annotation(t_pb_type* cur_pb_type,
|
|||
*******************************************************************/
|
||||
static
|
||||
void build_vpr_physical_pb_type_implicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_type head */
|
||||
if (nullptr == lb_type.pb_type) {
|
||||
continue;
|
||||
}
|
||||
rec_infer_vpr_physical_pb_type_annotation(lb_type.pb_type, vpr_pb_type_annotation);
|
||||
rec_infer_vpr_physical_pb_type_annotation(lb_type.pb_type, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,7 +450,8 @@ static
|
|||
bool link_physical_pb_port_to_circuit_port(t_pb_type* physical_pb_type,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
bool link_success = true;
|
||||
/* Iterate over the pb_ports
|
||||
* Note:
|
||||
|
@ -481,11 +494,12 @@ bool link_physical_pb_port_to_circuit_port(t_pb_type* physical_pb_type,
|
|||
|
||||
/* Reach here, it means that mapping should be ok, update the vpr_pb_type_annotation */
|
||||
vpr_pb_type_annotation.add_pb_circuit_port(pb_port, circuit_port);
|
||||
VTR_LOG("Bind pb type '%s' port '%s' to circuit model '%s' port '%s'\n",
|
||||
physical_pb_type->name,
|
||||
pb_port->name,
|
||||
circuit_lib.model_name(circuit_model).c_str(),
|
||||
circuit_lib.port_prefix(circuit_port).c_str());
|
||||
VTR_LOGV(verbose_output,
|
||||
"Bind pb type '%s' port '%s' to circuit model '%s' port '%s'\n",
|
||||
physical_pb_type->name,
|
||||
pb_port->name,
|
||||
circuit_lib.model_name(circuit_model).c_str(),
|
||||
circuit_lib.port_prefix(circuit_port).c_str());
|
||||
}
|
||||
|
||||
return link_success;
|
||||
|
@ -499,7 +513,8 @@ static
|
|||
bool link_physical_pb_type_to_circuit_model(t_pb_type* physical_pb_type,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const PbTypeAnnotation& pb_type_annotation,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Reach here, we should have valid operating and physical pb_types */
|
||||
VTR_ASSERT(nullptr != physical_pb_type);
|
||||
|
||||
|
@ -521,7 +536,8 @@ bool link_physical_pb_type_to_circuit_model(t_pb_type* physical_pb_type,
|
|||
}
|
||||
|
||||
/* Ensure that the pb_type ports can be matched in the circuit model ports */
|
||||
if (false == link_physical_pb_port_to_circuit_port(physical_pb_type, circuit_lib, circuit_model_id, vpr_pb_type_annotation)) {
|
||||
if (false == link_physical_pb_port_to_circuit_port(physical_pb_type, circuit_lib, circuit_model_id,
|
||||
vpr_pb_type_annotation, verbose_output)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -539,7 +555,8 @@ bool link_physical_pb_interconnect_to_circuit_model(t_pb_type* physical_pb_type,
|
|||
const std::string& interconnect_name,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const PbTypeAnnotation& pb_type_annotation,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* The physical pb_type should NOT be a primitive, otherwise it should never contain any interconnect */
|
||||
if (true == is_primitive_pb_type(physical_pb_type)) {
|
||||
VTR_LOG_ERROR("Link interconnect to circuit model is not allowed for a primitive pb_type '%s'!\n",
|
||||
|
@ -592,7 +609,8 @@ bool link_physical_pb_interconnect_to_circuit_model(t_pb_type* physical_pb_type,
|
|||
/* Now the circuit model is valid, update the vpr_pb_type_annotation */
|
||||
vpr_pb_type_annotation.add_interconnect_circuit_model(pb_interc, circuit_model_id);
|
||||
|
||||
VTR_LOG("Bind pb_type '%s' physical mode '%s' interconnect '%s' to circuit model '%s'\n",
|
||||
VTR_LOGV(verbose_output,
|
||||
"Bind pb_type '%s' physical mode '%s' interconnect '%s' to circuit model '%s'\n",
|
||||
physical_pb_type->name,
|
||||
physical_mode->name,
|
||||
pb_interc->name,
|
||||
|
@ -613,7 +631,8 @@ bool link_physical_pb_interconnect_to_circuit_model(t_pb_type* physical_pb_type,
|
|||
static
|
||||
void link_vpr_pb_type_to_circuit_model_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
|
||||
/* Since our target is to annotate the circuti model for physical pb_type
|
||||
|
@ -664,11 +683,13 @@ void link_vpr_pb_type_to_circuit_model_explicit_annotation(const DeviceContext&
|
|||
|
||||
/* Only try to bind pb_type to circuit model when it is defined by users */
|
||||
if (true == link_physical_pb_type_to_circuit_model(target_phy_pb_type, openfpga_arch.circuit_lib,
|
||||
pb_type_annotation, vpr_pb_type_annotation)) {
|
||||
pb_type_annotation, vpr_pb_type_annotation,
|
||||
verbose_output)) {
|
||||
/* Give a message */
|
||||
VTR_LOG("Bind physical pb_type '%s' to its circuit model '%s'\n",
|
||||
target_phy_pb_type->name,
|
||||
openfpga_arch.circuit_lib.model_name(vpr_pb_type_annotation.pb_type_circuit_model(target_phy_pb_type)).c_str());
|
||||
VTR_LOGV(verbose_output,
|
||||
"Bind physical pb_type '%s' to its circuit model '%s'\n",
|
||||
target_phy_pb_type->name,
|
||||
openfpga_arch.circuit_lib.model_name(vpr_pb_type_annotation.pb_type_circuit_model(target_phy_pb_type)).c_str());
|
||||
|
||||
link_success = true;
|
||||
break;
|
||||
|
@ -697,7 +718,8 @@ void link_vpr_pb_type_to_circuit_model_explicit_annotation(const DeviceContext&
|
|||
static
|
||||
void link_vpr_pb_interconnect_to_circuit_model_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
|
||||
/* Since our target is to annotate the circuti model for physical pb_type
|
||||
|
@ -749,7 +771,8 @@ void link_vpr_pb_interconnect_to_circuit_model_explicit_annotation(const DeviceC
|
|||
/* Only try to bind interconnect to circuit model when it is defined by users */
|
||||
for (const std::string& interc_name : pb_type_annotation.interconnect_names()) {
|
||||
if (false == link_physical_pb_interconnect_to_circuit_model(target_phy_pb_type, interc_name, openfpga_arch.circuit_lib,
|
||||
pb_type_annotation, vpr_pb_type_annotation)) {
|
||||
pb_type_annotation, vpr_pb_type_annotation,
|
||||
verbose_output)) {
|
||||
VTR_LOG_ERROR("Unable to bind pb_type '%s' interconnect '%s' to circuit model '%s'!\n",
|
||||
target_phy_pb_type_names.back().c_str(),
|
||||
interc_name.c_str(),
|
||||
|
@ -789,7 +812,8 @@ void link_vpr_pb_interconnect_to_circuit_model_explicit_annotation(const DeviceC
|
|||
static
|
||||
void rec_infer_vpr_pb_interconnect_circuit_model_annotation(t_pb_type* cur_pb_type,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* We do not check any primitive pb_type */
|
||||
if (true == is_primitive_pb_type(cur_pb_type)) {
|
||||
return;
|
||||
|
@ -818,17 +842,19 @@ void rec_infer_vpr_pb_interconnect_circuit_model_annotation(t_pb_type* cur_pb_ty
|
|||
cur_pb_type->name);
|
||||
}
|
||||
vpr_pb_type_annotation.add_interconnect_circuit_model(pb_interc, default_circuit_model);
|
||||
VTR_LOG("Implicitly infer a circuit model '%s' for interconnect '%s' under physical mode '%s' of pb_type '%s'\n",
|
||||
circuit_lib.model_name(default_circuit_model).c_str(),
|
||||
pb_interc->name,
|
||||
physical_mode->name,
|
||||
cur_pb_type->name);
|
||||
VTR_LOGV(verbose_output,
|
||||
"Implicitly infer a circuit model '%s' for interconnect '%s' under physical mode '%s' of pb_type '%s'\n",
|
||||
circuit_lib.model_name(default_circuit_model).c_str(),
|
||||
pb_interc->name,
|
||||
physical_mode->name,
|
||||
cur_pb_type->name);
|
||||
}
|
||||
|
||||
/* Traverse the pb_type children under the physical mode */
|
||||
for (int ichild = 0; ichild < physical_mode->num_pb_type_children; ++ichild) {
|
||||
rec_infer_vpr_pb_interconnect_circuit_model_annotation(&(physical_mode->pb_type_children[ichild]),
|
||||
circuit_lib, vpr_pb_type_annotation);
|
||||
circuit_lib, vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,13 +871,14 @@ void rec_infer_vpr_pb_interconnect_circuit_model_annotation(t_pb_type* cur_pb_ty
|
|||
static
|
||||
void link_vpr_pb_interconnect_to_circuit_model_implicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_type head */
|
||||
if (nullptr == lb_type.pb_type) {
|
||||
continue;
|
||||
}
|
||||
rec_infer_vpr_pb_interconnect_circuit_model_annotation(lb_type.pb_type, circuit_lib, vpr_pb_type_annotation);
|
||||
rec_infer_vpr_pb_interconnect_circuit_model_annotation(lb_type.pb_type, circuit_lib, vpr_pb_type_annotation, verbose_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,7 +916,8 @@ bool link_primitive_pb_type_to_mode_bits(t_pb_type* primitive_pb_type,
|
|||
static
|
||||
void link_vpr_pb_type_to_mode_bits_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
|
||||
if (true == pb_type_annotation.mode_bits().empty()) {
|
||||
|
@ -947,9 +975,10 @@ void link_vpr_pb_type_to_mode_bits_explicit_annotation(const DeviceContext& vpr_
|
|||
if (true == link_primitive_pb_type_to_mode_bits(target_pb_type,
|
||||
pb_type_annotation, vpr_pb_type_annotation)) {
|
||||
/* Give a message */
|
||||
VTR_LOG("Bind physical pb_type '%s' to mode selection bits '%s'\n",
|
||||
target_pb_type->name,
|
||||
mode_bits_str.c_str());
|
||||
VTR_LOGV(verbose_output,
|
||||
"Bind physical pb_type '%s' to mode selection bits '%s'\n",
|
||||
target_pb_type->name,
|
||||
mode_bits_str.c_str());
|
||||
|
||||
link_success = true;
|
||||
break;
|
||||
|
@ -973,16 +1002,21 @@ void link_vpr_pb_type_to_mode_bits_explicit_annotation(const DeviceContext& vpr_
|
|||
*******************************************************************/
|
||||
void annotate_pb_types(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output) {
|
||||
|
||||
/* Annotate physical mode to pb_type in the VPR pb_type graph */
|
||||
VTR_LOG("\n");
|
||||
VTR_LOG("Building annotation for physical modes in pb_type...\n");
|
||||
VTR_LOG("Building annotation for physical modes in pb_type...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
build_vpr_physical_pb_mode_explicit_annotation(vpr_device_ctx, openfpga_arch,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
|
||||
build_vpr_physical_pb_mode_implicit_annotation(vpr_device_ctx,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
check_vpr_physical_pb_mode_annotation(vpr_device_ctx,
|
||||
const_cast<const VprPbTypeAnnotation&>(vpr_pb_type_annotation));
|
||||
|
@ -993,8 +1027,10 @@ void annotate_pb_types(const DeviceContext& vpr_device_ctx,
|
|||
*/
|
||||
VTR_LOG("\n");
|
||||
VTR_LOG("Building annotation about physical types for pb_type interconnection...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
annotate_pb_graph_interconnect_physical_type(vpr_device_ctx,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
/* Annotate physical pb_types to operating pb_type in the VPR pb_type graph
|
||||
|
@ -1004,12 +1040,16 @@ void annotate_pb_types(const DeviceContext& vpr_device_ctx,
|
|||
* - physical_pin_rotate_offset
|
||||
*/
|
||||
VTR_LOG("\n");
|
||||
VTR_LOG("Building annotation between operating and physical pb_types...\n");
|
||||
VTR_LOG("Building annotation between operating and physical pb_types...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
build_vpr_physical_pb_type_explicit_annotation(vpr_device_ctx, openfpga_arch,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
|
||||
build_vpr_physical_pb_type_implicit_annotation(vpr_device_ctx,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
check_vpr_physical_pb_type_annotation(vpr_device_ctx,
|
||||
const_cast<const VprPbTypeAnnotation&>(vpr_pb_type_annotation));
|
||||
|
@ -1019,21 +1059,33 @@ void annotate_pb_types(const DeviceContext& vpr_device_ctx,
|
|||
* - interconnect of physical pb_type to circuit model
|
||||
*/
|
||||
VTR_LOG("\n");
|
||||
VTR_LOG("Building annotation between physical pb_types and circuit models...\n");
|
||||
VTR_LOG("Building annotation between physical pb_types and circuit models...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
link_vpr_pb_type_to_circuit_model_explicit_annotation(vpr_device_ctx, openfpga_arch,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
|
||||
link_vpr_pb_interconnect_to_circuit_model_explicit_annotation(vpr_device_ctx, openfpga_arch,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
|
||||
link_vpr_pb_interconnect_to_circuit_model_implicit_annotation(vpr_device_ctx, openfpga_arch.circuit_lib,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
check_vpr_pb_type_circuit_model_annotation(vpr_device_ctx, openfpga_arch.circuit_lib,
|
||||
const_cast<const VprPbTypeAnnotation&>(vpr_pb_type_annotation));
|
||||
|
||||
/* Link physical pb_type to mode_bits */
|
||||
VTR_LOG("\n");
|
||||
VTR_LOG("Building annotation between physical pb_types and mode selection bits...\n");
|
||||
VTR_LOG("Building annotation between physical pb_types and mode selection bits...");
|
||||
VTR_LOGV(verbose_output, "\n");
|
||||
link_vpr_pb_type_to_mode_bits_explicit_annotation(vpr_device_ctx, openfpga_arch,
|
||||
vpr_pb_type_annotation);
|
||||
vpr_pb_type_annotation,
|
||||
verbose_output);
|
||||
VTR_LOG("Done\n");
|
||||
|
||||
check_vpr_pb_type_mode_bits_annotation(vpr_device_ctx, openfpga_arch.circuit_lib,
|
||||
const_cast<const VprPbTypeAnnotation&>(vpr_pb_type_annotation));
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ namespace openfpga {
|
|||
|
||||
void annotate_pb_types(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation);
|
||||
VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
const bool& verbose_output);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/********************************************************************
|
||||
* This file includes functions to check the annotation on
|
||||
* the physical pb_graph_node and pb_graph_pin
|
||||
*******************************************************************/
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_time.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
#include "pb_type_utils.h"
|
||||
#include "check_pb_graph_annotation.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* A function to check if a physical pb_graph_pin for a pb_graph_pin
|
||||
* Print error to log file/screen when checking fails
|
||||
*******************************************************************/
|
||||
static
|
||||
bool check_physical_pb_graph_pin(t_pb_graph_pin* pb_graph_pin,
|
||||
const VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
if (nullptr == vpr_pb_type_annotation.physical_pb_graph_pin(pb_graph_pin)) {
|
||||
VTR_LOG_ERROR("Found a pb_graph_pin '%s' missing physical pb_graph_pin binding!\n",
|
||||
pb_graph_pin->port->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* This function will recursively walk through all the pb_graph nodes
|
||||
* starting from a top node.
|
||||
* It aims to check
|
||||
* - if each primitive pb_graph node has been binded to a physical
|
||||
* pb_graph_node
|
||||
* - if each pin of the primitive pb_graph node has been binded to
|
||||
* a physical graph_pin
|
||||
*******************************************************************/
|
||||
static
|
||||
void rec_check_vpr_physical_pb_graph_node_annotation(t_pb_graph_node* pb_graph_node,
|
||||
const VprPbTypeAnnotation& vpr_pb_type_annotation,
|
||||
size_t& num_err) {
|
||||
/* Go recursive first until we touch the primitive node */
|
||||
if (false == is_primitive_pb_type(pb_graph_node->pb_type)) {
|
||||
for (int imode = 0; imode < pb_graph_node->pb_type->num_modes; ++imode) {
|
||||
for (int ipb = 0; ipb < pb_graph_node->pb_type->modes[imode].num_pb_type_children; ++ipb) {
|
||||
/* Each child may exist multiple times in the hierarchy*/
|
||||
for (int jpb = 0; jpb < pb_graph_node->pb_type->modes[imode].pb_type_children[ipb].num_pb; ++jpb) {
|
||||
rec_check_vpr_physical_pb_graph_node_annotation(&(pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]),
|
||||
vpr_pb_type_annotation, num_err);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure that the pb_graph_node has been mapped to a physical node */
|
||||
t_pb_graph_node* physical_pb_graph_node = vpr_pb_type_annotation.physical_pb_graph_node(pb_graph_node);
|
||||
if (nullptr == physical_pb_graph_node) {
|
||||
VTR_LOG_ERROR("Found a pb_graph_node '%s' missing physical pb_graph_node binding!\n",
|
||||
physical_pb_graph_node->pb_type->name);
|
||||
num_err++;
|
||||
return; /* Invalid pointer already, further check is not applicable */
|
||||
}
|
||||
|
||||
/* Reach here, we should have a valid pointer to the physical pb_graph_node,
|
||||
* Check the physical pb_graph_pin for each pin
|
||||
*/
|
||||
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 == check_physical_pb_graph_pin(&(physical_pb_graph_node->input_pins[iport][ipin]),
|
||||
vpr_pb_type_annotation)) {
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 == check_physical_pb_graph_pin(&(physical_pb_graph_node->output_pins[iport][ipin]),
|
||||
vpr_pb_type_annotation)) {
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 == check_physical_pb_graph_pin(&(physical_pb_graph_node->clock_pins[iport][ipin]),
|
||||
vpr_pb_type_annotation)) {
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Check each primitive pb_graph_node
|
||||
* - It has been binded to an physical pb_graph_node
|
||||
* - Each pin has been binded to a physical pb_graph_node pin
|
||||
*******************************************************************/
|
||||
void check_physical_pb_graph_node_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||
size_t num_err = 0;
|
||||
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_graph head */
|
||||
if (nullptr == lb_type.pb_graph_head) {
|
||||
continue;
|
||||
}
|
||||
rec_check_vpr_physical_pb_graph_node_annotation(lb_type.pb_graph_head, vpr_pb_type_annotation, num_err);
|
||||
}
|
||||
|
||||
if (0 == num_err) {
|
||||
VTR_LOG("Check pb_graph annotation for physical nodes and pins passed.\n");
|
||||
} else {
|
||||
VTR_LOG_ERROR("Check pb_graph annotation for physical nodes and pins failed with %ld errors!\n",
|
||||
num_err);
|
||||
}
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CHECK_PB_GRAPH_ANNOTATION_H
|
||||
#define CHECK_PB_GRAPH_ANNOTATION_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "vpr_context.h"
|
||||
#include "openfpga_context.h"
|
||||
#include "vpr_pb_type_annotation.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void check_physical_pb_graph_node_annotation(const DeviceContext& vpr_device_ctx,
|
||||
const VprPbTypeAnnotation& vpr_pb_type_annotation);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -27,17 +27,21 @@ namespace openfpga {
|
|||
* - physical pb_graph nodes and pb_graph pins
|
||||
* - circuit models for global routing architecture
|
||||
*******************************************************************/
|
||||
void link_arch(OpenfpgaContext& openfpga_context) {
|
||||
void link_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture");
|
||||
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* Annotate pb_type graphs
|
||||
* - physical pb_type
|
||||
* - mode selection bits for pb_type and pb interconnect
|
||||
* - circuit models for pb_type and pb interconnect
|
||||
*/
|
||||
annotate_pb_types(g_vpr_ctx.device(), openfpga_context.arch(),
|
||||
openfpga_context.mutable_vpr_pb_type_annotation());
|
||||
openfpga_context.mutable_vpr_pb_type_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Annotate pb_graph_nodes
|
||||
* - Give unique index to each node in the same type
|
||||
|
@ -45,7 +49,8 @@ void link_arch(OpenfpgaContext& openfpga_context) {
|
|||
* - Bind pins from operating pb_graph_node to their physical pb_graph_node pins
|
||||
*/
|
||||
annotate_pb_graph(g_vpr_ctx.device(),
|
||||
openfpga_context.mutable_vpr_pb_type_annotation());
|
||||
openfpga_context.mutable_vpr_pb_type_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "command.h"
|
||||
#include "command_context.h"
|
||||
#include "openfpga_context.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -13,7 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void link_arch(OpenfpgaContext& openfpga_context);
|
||||
void link_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
|||
* Command 'link_openfpga_arch'
|
||||
*/
|
||||
Command shell_cmd_link_openfpga_arch("link_openfpga_arch");
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd_link_openfpga_arch.add_option("verbose", false, "Show verbose outputs");
|
||||
|
||||
/* Add command 'link_openfpga_arch' to the Shell */
|
||||
ShellCommandId shell_cmd_link_openfpga_arch_id = shell.add_command(shell_cmd_link_openfpga_arch, "Bind OpenFPGA architecture to VPR");
|
||||
|
@ -67,7 +69,7 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
|||
* Command 'check_netlist_naming_conflict'
|
||||
*/
|
||||
Command shell_cmd_check_netlist_naming_conflict("check_netlist_naming_conflict");
|
||||
/* Add an option '--correction' */
|
||||
/* Add an option '--fix' */
|
||||
shell_cmd_check_netlist_naming_conflict.add_option("fix", false, "Apply correction to any conflicts found");
|
||||
/* Add an option '--report' */
|
||||
CommandOptionId check_netlist_opt_rpt = shell_cmd_check_netlist_naming_conflict.add_option("report", false, "Output a report file about what any correction applied");
|
||||
|
|
Loading…
Reference in New Issue