debugged pb_type physical mode annotation

This commit is contained in:
tangxifan 2020-01-27 20:40:18 -07:00
parent b8c504f574
commit f99dd4c261
2 changed files with 128 additions and 38 deletions

View File

@ -3,6 +3,7 @@
* which are built on the libarchopenfpga library
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_time.h"
#include "vtr_assert.h"
#include "vtr_log.h"
@ -68,40 +69,14 @@ t_pb_type* try_find_pb_type_with_given_path(t_pb_type* top_pb_type,
}
/********************************************************************
* This function will recursively traverse pb_type graph to ensure
* 1. there is only a physical mode under each pb_type
* 2. physical mode appears only when its parent is a physical mode.
* This function will identify the physical pb_type for each multi-mode
* pb_type in VPR pb_type graph by following the explicit definition
* in OpenFPGA architecture XML
*******************************************************************/
static
void rec_check_pb_type_physical_mode(t_pb_type* cur_pb_type) {
/* We do not check any primitive pb_type */
if (true == is_primitive_pb_type(cur_pb_type)) {
return;
}
/* For non-primitive pb_type: we should iterate over each mode
* Ensure there is only one physical mode
*/
/* Traverse all the modes for identifying idle mode */
for (int imode = 0; cur_pb_type->num_modes; ++imode) {
/* Check each pb_type_child */
for (int ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ++ichild) {
rec_check_pb_type_physical_mode(&(cur_pb_type->modes[imode].pb_type_children[ichild]));
}
}
}
/********************************************************************
* This function will
* - identify the physical pb_type for each multi-mode pb_type in
* VPR pb_type graph
* - identify the physical pb_type for operating pb_types in VPR
*******************************************************************/
static
void build_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
const Arch& openfpga_arch,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
void build_vpr_physical_pb_mode_explicit_annotation(const DeviceContext& vpr_device_ctx,
const Arch& openfpga_arch,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
/* 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,
@ -133,9 +108,6 @@ void build_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
/* We must have at least one pb_type in the list */
VTR_ASSERT_SAFE(0 < target_pb_type_names.size());
VTR_LOG("Trying to link pb_type '%s' to vpr architecture\n",
target_pb_type_names.back().c_str());
/* Pb type information are located at the logic_block_types in the device context of VPR
* We iterate over the vectors and find the pb_type matches the parent_pb_type_name
*/
@ -178,6 +150,112 @@ void build_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
}
}
/********************************************************************
* This function will recursively visit all the pb_type from the top
* pb_type in the graph and
* infer the physical pb_type for each multi-mode
* pb_type in VPR pb_type graph without OpenFPGA architecture XML
*
* The following rule is applied:
* if there is only 1 mode under a pb_type, it will be the default
* physical mode for this pb_type
*******************************************************************/
static
void rec_infer_vpr_physical_pb_mode_annotation(t_pb_type* cur_pb_type,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
/* We do not check any primitive pb_type */
if (true == is_primitive_pb_type(cur_pb_type)) {
return;
}
/* For non-primitive pb_type:
* - if there is only one mode, it will be the physical mode
* we just need to make sure that we do not repeatedly annotate this
* - if there are multiple modes, we should be able to find a physical mode
* and then go recursively
*/
t_mode* physical_mode = nullptr;
if (1 == cur_pb_type->num_modes) {
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);
}
} else {
VTR_ASSERT(1 < cur_pb_type->num_modes);
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_ERROR("Unable to find a physical mode for a multi-mode pb_type '%s'!\n",
cur_pb_type->name);
VTR_LOG_ERROR("Please specify in the OpenFPGA architecture\n");
return;
}
}
/* Get the physical mode from annotation */
physical_mode = vpr_pb_type_annotation.physical_mode(cur_pb_type);
VTR_ASSERT(nullptr != physical_mode);
/* 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);
}
}
/********************************************************************
* This function will infer the physical pb_type for each multi-mode
* pb_type in VPR pb_type graph without OpenFPGA architecture XML
*
* The following rule is applied:
* if there is only 1 mode under a pb_type, it will be the default
* physical mode for this pb_type
*
* Note:
* This function must be executed AFTER the function
* build_vpr_physical_pb_mode_explicit_annotation()
*******************************************************************/
static
void build_vpr_physical_pb_mode_implicit_annotation(const DeviceContext& vpr_device_ctx,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
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);
}
}
/********************************************************************
* This function will recursively traverse pb_type graph to ensure
* 1. there is only a physical mode under each pb_type
* 2. physical mode appears only when its parent is a physical mode.
*******************************************************************/
static
void rec_check_pb_type_physical_mode(t_pb_type* cur_pb_type) {
/* We do not check any primitive pb_type */
if (true == is_primitive_pb_type(cur_pb_type)) {
return;
}
/* For non-primitive pb_type: we should iterate over each mode
* Ensure there is only one physical mode
*/
/* Traverse all the modes for identifying idle mode */
for (int imode = 0; cur_pb_type->num_modes; ++imode) {
/* Check each pb_type_child */
for (int ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ++ichild) {
rec_check_pb_type_physical_mode(&(cur_pb_type->modes[imode].pb_type_children[ichild]));
}
}
}
/********************************************************************
* Top-level function to link openfpga architecture to VPR, including:
* - physical pb_type
@ -186,9 +264,13 @@ void build_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
*******************************************************************/
void link_arch(OpenfpgaContext& openfpga_context) {
vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture");
/* Annotate physical pb_type in the VPR pb_type graph */
build_vpr_physical_pb_type_annotation(g_vpr_ctx.device(), openfpga_context.arch(),
openfpga_context.mutable_vpr_pb_type_annotation());
build_vpr_physical_pb_mode_explicit_annotation(g_vpr_ctx.device(), openfpga_context.arch(),
openfpga_context.mutable_vpr_pb_type_annotation());
build_vpr_physical_pb_mode_implicit_annotation(g_vpr_ctx.device(),
openfpga_context.mutable_vpr_pb_type_annotation());
/* Annotate idle pb_type in the VPR pb_type graph */

View File

@ -3,6 +3,7 @@
* and pb_graph_node data structure in the OpenFPGA context
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "pb_type_utils.h"
@ -15,10 +16,17 @@ namespace openfpga {
* However, this not always true. An exception is the LUT_CLASS
* VPR added two modes by default to a LUT pb_type. Therefore,
* for LUT_CLASS, it is a primitive when it is binded to a blif model
*
* Note:
* - if VPR changes its mode organization for LUT pb_type
* this code should be adapted as well!
************************************************************************/
bool is_primitive_pb_type(t_pb_type* pb_type) {
if (LUT_CLASS == pb_type->class_type) {
return nullptr != pb_type->blif_model;
/* The first mode of LUT is wire, the second is the regular LUT */
VTR_ASSERT(std::string("wire") == std::string(pb_type->modes[0].name));
VTR_ASSERT(std::string(pb_type->name) == std::string(pb_type->modes[1].name));
return true;
}
return 0 == pb_type->num_modes;
}