debugged pb_type physical mode annotation
This commit is contained in:
parent
b8c504f574
commit
f99dd4c261
|
@ -3,6 +3,7 @@
|
||||||
* which are built on the libarchopenfpga library
|
* which are built on the libarchopenfpga library
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
/* Headers from vtrutil library */
|
/* Headers from vtrutil library */
|
||||||
|
#include "vtr_time.h"
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "vtr_log.h"
|
#include "vtr_log.h"
|
||||||
|
|
||||||
|
@ -68,38 +69,12 @@ 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
|
* This function will identify the physical pb_type for each multi-mode
|
||||||
* 1. there is only a physical mode under each pb_type
|
* pb_type in VPR pb_type graph by following the explicit definition
|
||||||
* 2. physical mode appears only when its parent is a physical mode.
|
* in OpenFPGA architecture XML
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
void rec_check_pb_type_physical_mode(t_pb_type* cur_pb_type) {
|
void build_vpr_physical_pb_mode_explicit_annotation(const DeviceContext& vpr_device_ctx,
|
||||||
/* 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,
|
const Arch& openfpga_arch,
|
||||||
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
VprPbTypeAnnotation& vpr_pb_type_annotation) {
|
||||||
/* Walk through the pb_type annotation stored in the openfpga arch */
|
/* Walk through the pb_type annotation stored in the openfpga arch */
|
||||||
|
@ -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 */
|
/* We must have at least one pb_type in the list */
|
||||||
VTR_ASSERT_SAFE(0 < target_pb_type_names.size());
|
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
|
/* 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
|
* 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:
|
* Top-level function to link openfpga architecture to VPR, including:
|
||||||
* - physical pb_type
|
* - physical pb_type
|
||||||
|
@ -186,8 +264,12 @@ void build_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
void link_arch(OpenfpgaContext& openfpga_context) {
|
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 */
|
/* Annotate physical pb_type in the VPR pb_type graph */
|
||||||
build_vpr_physical_pb_type_annotation(g_vpr_ctx.device(), openfpga_context.arch(),
|
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());
|
openfpga_context.mutable_vpr_pb_type_annotation());
|
||||||
|
|
||||||
/* Annotate idle pb_type in the VPR pb_type graph */
|
/* Annotate idle pb_type in the VPR pb_type graph */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* and pb_graph_node data structure in the OpenFPGA context
|
* and pb_graph_node data structure in the OpenFPGA context
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
/* Headers from vtrutil library */
|
/* Headers from vtrutil library */
|
||||||
|
#include "vtr_assert.h"
|
||||||
#include "vtr_log.h"
|
#include "vtr_log.h"
|
||||||
|
|
||||||
#include "pb_type_utils.h"
|
#include "pb_type_utils.h"
|
||||||
|
@ -15,10 +16,17 @@ namespace openfpga {
|
||||||
* However, this not always true. An exception is the LUT_CLASS
|
* However, this not always true. An exception is the LUT_CLASS
|
||||||
* VPR added two modes by default to a LUT pb_type. Therefore,
|
* 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
|
* 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) {
|
bool is_primitive_pb_type(t_pb_type* pb_type) {
|
||||||
if (LUT_CLASS == pb_type->class_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;
|
return 0 == pb_type->num_modes;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue