Merge branch 'refactoring' into dev

This commit is contained in:
tangxifan 2020-01-31 11:37:41 -07:00
commit 7b5ee5c2f6
10 changed files with 353 additions and 117 deletions

View File

@ -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 {

View File

@ -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 */

View File

@ -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 */

View File

@ -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));

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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");