add naming fix-up
This commit is contained in:
parent
8c86c0af04
commit
2dc4c26257
|
@ -21,18 +21,47 @@ namespace openfpga {
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* This function aims to check if the name contains any of the
|
* This function aims to check if the name contains any of the
|
||||||
* sensitive characters in the list
|
* sensitive characters in the list
|
||||||
|
* Return a string of sensitive characters which are contained
|
||||||
|
* in the name
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
bool name_contain_sensitive_chars(const std::string& name,
|
std::string name_contain_sensitive_chars(const std::string& name,
|
||||||
const std::string& sensitive_chars) {
|
const std::string& sensitive_chars) {
|
||||||
|
std::string violation;
|
||||||
|
|
||||||
for (const char& sensitive_char : sensitive_chars) {
|
for (const char& sensitive_char : sensitive_chars) {
|
||||||
/* Return true since we find a characters */
|
/* Return true since we find a characters */
|
||||||
if (std::string::npos != name.find(sensitive_char)) {
|
if (std::string::npos != name.find(sensitive_char)) {
|
||||||
return true;
|
violation.push_back(sensitive_char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return violation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* This function aims to fix up a name that contains any of the
|
||||||
|
* sensitive characters in the list
|
||||||
|
* Return a string the fixed name
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
std::string fix_name_contain_sensitive_chars(const std::string& name,
|
||||||
|
const std::string& sensitive_chars,
|
||||||
|
const std::string& fix_chars) {
|
||||||
|
std::string fixed_name = name;
|
||||||
|
|
||||||
|
VTR_ASSERT(sensitive_chars.length() == fix_chars.length());
|
||||||
|
|
||||||
|
for (size_t ichar = 0; ichar < sensitive_chars.length(); ++ichar) {
|
||||||
|
/* Keep fixing the characters until we cannot find anymore */
|
||||||
|
std::string::size_type pos = 0u;
|
||||||
|
while (std::string::npos != (pos = fixed_name.find(sensitive_chars[ichar], pos))) {
|
||||||
|
fixed_name.replace(pos, 1, std::string(1, fix_chars[ichar]));
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixed_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -44,16 +73,17 @@ bool name_contain_sensitive_chars(const std::string& name,
|
||||||
* any sensitive character
|
* any sensitive character
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
void detect_netlist_naming_conflict(const AtomNetlist& atom_netlist,
|
size_t detect_netlist_naming_conflict(const AtomNetlist& atom_netlist,
|
||||||
const std::string& sensitive_chars) {
|
const std::string& sensitive_chars) {
|
||||||
size_t num_conflicts = 0;
|
size_t num_conflicts = 0;
|
||||||
|
|
||||||
/* Walk through blocks in the netlist */
|
/* Walk through blocks in the netlist */
|
||||||
for (const auto& block : atom_netlist.blocks()) {
|
for (const auto& block : atom_netlist.blocks()) {
|
||||||
const std::string& block_name = atom_netlist.block_name(block);
|
const std::string& block_name = atom_netlist.block_name(block);
|
||||||
if (true == name_contain_sensitive_chars(block_name, sensitive_chars)) {
|
const std::string& violation = name_contain_sensitive_chars(block_name, sensitive_chars);
|
||||||
VTR_LOG("Block '%s' violates the syntax requirement by OpenFPGA!\n",
|
if (false == violation.empty()) {
|
||||||
block_name.c_str());
|
VTR_LOG("Block '%s' contains illegal characters '%s'\n",
|
||||||
|
block_name.c_str(), violation.c_str());
|
||||||
num_conflicts++;
|
num_conflicts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,19 +91,62 @@ void detect_netlist_naming_conflict(const AtomNetlist& atom_netlist,
|
||||||
/* Walk through nets in the netlist */
|
/* Walk through nets in the netlist */
|
||||||
for (const auto& net : atom_netlist.nets()) {
|
for (const auto& net : atom_netlist.nets()) {
|
||||||
const std::string& net_name = atom_netlist.net_name(net);
|
const std::string& net_name = atom_netlist.net_name(net);
|
||||||
if (true == name_contain_sensitive_chars(net_name, sensitive_chars)) {
|
const std::string& violation = name_contain_sensitive_chars(net_name, sensitive_chars);
|
||||||
VTR_LOG("Net '%s' violates the syntax requirement by OpenFPGA!\n",
|
if (false == violation.empty()) {
|
||||||
net_name.c_str());
|
VTR_LOG("Net '%s' contains illegal characters '%s'\n",
|
||||||
|
net_name.c_str(), violation.c_str());
|
||||||
num_conflicts++;
|
num_conflicts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 < num_conflicts) {
|
return num_conflicts;
|
||||||
VTR_LOG("Found %ld naming conflicts in the netlist. Please correct so as to use any fabric generators.\n",
|
|
||||||
num_conflicts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Correct and report any naming conflict by checking a list of
|
||||||
|
* sensitive characters
|
||||||
|
* - Iterate over all the blocks and correct any block name that contains
|
||||||
|
* any sensitive character
|
||||||
|
* - Iterate over all the nets and correct any net name that contains
|
||||||
|
* any sensitive character
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void correct_netlist_naming_conflict(const AtomNetlist& atom_netlist,
|
||||||
|
const std::string& sensitive_chars,
|
||||||
|
const std::string& fix_chars,
|
||||||
|
VprNetlistAnnotation& vpr_netlist_annotation) {
|
||||||
|
size_t num_fixes = 0;
|
||||||
|
|
||||||
|
/* Walk through blocks in the netlist */
|
||||||
|
for (const auto& block : atom_netlist.blocks()) {
|
||||||
|
const std::string& block_name = atom_netlist.block_name(block);
|
||||||
|
const std::string& violation = name_contain_sensitive_chars(block_name, sensitive_chars);
|
||||||
|
|
||||||
|
if (false == violation.empty()) {
|
||||||
|
/* Apply fix-up here */
|
||||||
|
vpr_netlist_annotation.rename_block(block, fix_name_contain_sensitive_chars(block_name, sensitive_chars, fix_chars));
|
||||||
|
num_fixes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk through nets in the netlist */
|
||||||
|
for (const auto& net : atom_netlist.nets()) {
|
||||||
|
const std::string& net_name = atom_netlist.net_name(net);
|
||||||
|
const std::string& violation = name_contain_sensitive_chars(net_name, sensitive_chars);
|
||||||
|
if (false == violation.empty()) {
|
||||||
|
/* Apply fix-up here */
|
||||||
|
vpr_netlist_annotation.rename_net(net, fix_name_contain_sensitive_chars(net_name, sensitive_chars, fix_chars));
|
||||||
|
num_fixes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < num_fixes) {
|
||||||
|
VTR_LOG("Fixed %ld naming conflicts in the netlist.\n",
|
||||||
|
num_fixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Top-level function to detect and correct any naming
|
* Top-level function to detect and correct any naming
|
||||||
* in the users' BLIF netlist that violates the syntax of OpenFPGA
|
* in the users' BLIF netlist that violates the syntax of OpenFPGA
|
||||||
|
@ -81,11 +154,26 @@ void detect_netlist_naming_conflict(const AtomNetlist& atom_netlist,
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
||||||
const Command& cmd, const CommandContext& cmd_context) {
|
const Command& cmd, const CommandContext& cmd_context) {
|
||||||
|
/* By default, we replace all the illegal characters with '_' */
|
||||||
const std::string& sensitive_chars(".,:;\'\"+-<>()[]{}!@#$%^&*~`?/");
|
const std::string& sensitive_chars(".,:;\'\"+-<>()[]{}!@#$%^&*~`?/");
|
||||||
|
const std::string& fix_chars("____________________________");
|
||||||
|
|
||||||
|
CommandOptionId opt_fix = cmd.option("fix");
|
||||||
|
|
||||||
/* Do the main job first: detect any naming in the BLIF netlist that violates the syntax */
|
/* Do the main job first: detect any naming in the BLIF netlist that violates the syntax */
|
||||||
detect_netlist_naming_conflict(g_vpr_ctx.atom().nlist, sensitive_chars);
|
size_t num_conflicts = detect_netlist_naming_conflict(g_vpr_ctx.atom().nlist, sensitive_chars);
|
||||||
|
VTR_LOGV_ERROR((0 < num_conflicts && (false == cmd_context.option_enable(cmd, opt_fix))),
|
||||||
|
"Found %ld naming conflicts in the netlist. Please correct so as to use any fabric generators.\n",
|
||||||
|
num_conflicts);
|
||||||
|
VTR_LOGV(0 == num_conflicts,
|
||||||
|
"Check naming conflicts in the netlist passed.\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* If the auto correction is enabled, we apply a fix */
|
||||||
|
if (true == cmd_context.option_enable(cmd, opt_fix)) {
|
||||||
|
correct_netlist_naming_conflict(g_vpr_ctx.atom().nlist, sensitive_chars,
|
||||||
|
fix_chars, openfpga_context.mutable_vpr_netlist_annotation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
#include "openfpga_arch.h"
|
#include "openfpga_arch.h"
|
||||||
|
#include "vpr_netlist_annotation.h"
|
||||||
#include "vpr_pb_type_annotation.h"
|
#include "vpr_pb_type_annotation.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -36,14 +37,18 @@ class OpenfpgaContext : public Context {
|
||||||
public: /* Public accessors */
|
public: /* Public accessors */
|
||||||
const openfpga::Arch& arch() const { return arch_; }
|
const openfpga::Arch& arch() const { return arch_; }
|
||||||
const openfpga::VprPbTypeAnnotation& vpr_pb_type_annotation() const { return vpr_pb_type_annotation_; }
|
const openfpga::VprPbTypeAnnotation& vpr_pb_type_annotation() const { return vpr_pb_type_annotation_; }
|
||||||
|
const openfpga::VprNetlistAnnotation& vpr_netlist_annotation() const { return vpr_netlist_annotation_; }
|
||||||
public: /* Public mutators */
|
public: /* Public mutators */
|
||||||
openfpga::Arch& mutable_arch() { return arch_; }
|
openfpga::Arch& mutable_arch() { return arch_; }
|
||||||
openfpga::VprPbTypeAnnotation& mutable_vpr_pb_type_annotation() { return vpr_pb_type_annotation_; }
|
openfpga::VprPbTypeAnnotation& mutable_vpr_pb_type_annotation() { return vpr_pb_type_annotation_; }
|
||||||
|
openfpga::VprNetlistAnnotation& mutable_vpr_netlist_annotation() { return vpr_netlist_annotation_; }
|
||||||
private: /* Internal data */
|
private: /* Internal data */
|
||||||
/* Data structure to store information from read_openfpga_arch library */
|
/* Data structure to store information from read_openfpga_arch library */
|
||||||
openfpga::Arch arch_;
|
openfpga::Arch arch_;
|
||||||
/* Annotation to pb_type of VPR */
|
/* Annotation to pb_type of VPR */
|
||||||
openfpga::VprPbTypeAnnotation vpr_pb_type_annotation_;
|
openfpga::VprPbTypeAnnotation vpr_pb_type_annotation_;
|
||||||
|
/* Naming fix to netlist */
|
||||||
|
openfpga::VprNetlistAnnotation vpr_netlist_annotation_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,7 +68,7 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
||||||
*/
|
*/
|
||||||
Command shell_cmd_check_netlist_naming_conflict("check_netlist_naming_conflict");
|
Command shell_cmd_check_netlist_naming_conflict("check_netlist_naming_conflict");
|
||||||
/* Add an option '--correction' */
|
/* Add an option '--correction' */
|
||||||
shell_cmd_check_netlist_naming_conflict.add_option("correction", false, "Apply correction to any conflicts found");
|
shell_cmd_check_netlist_naming_conflict.add_option("fix", false, "Apply correction to any conflicts found");
|
||||||
/* Add an option '--report' */
|
/* 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");
|
CommandOptionId check_netlist_opt_rpt = shell_cmd_check_netlist_naming_conflict.add_option("report", false, "Output a report file about what any correction applied");
|
||||||
shell_cmd_check_netlist_naming_conflict.set_option_require_value(check_netlist_opt_rpt, openfpga::OPT_STRING);
|
shell_cmd_check_netlist_naming_conflict.set_option_require_value(check_netlist_opt_rpt, openfpga::OPT_STRING);
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/************************************************************************
|
||||||
|
* Member functions for class VprNetlistAnnotation
|
||||||
|
***********************************************************************/
|
||||||
|
#include "vtr_log.h"
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vpr_netlist_annotation.h"
|
||||||
|
|
||||||
|
/* namespace openfpga begins */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Constructors
|
||||||
|
***********************************************************************/
|
||||||
|
VprNetlistAnnotation::VprNetlistAnnotation() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Public accessors
|
||||||
|
***********************************************************************/
|
||||||
|
bool VprNetlistAnnotation::is_block_renamed(const AtomBlockId& block) const {
|
||||||
|
/* Ensure that the pb_type is in the list */
|
||||||
|
std::map<AtomBlockId, std::string>::const_iterator it = block_names_.find(block);
|
||||||
|
return it != block_names_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VprNetlistAnnotation::block_name(const AtomBlockId& block) const {
|
||||||
|
VTR_ASSERT(true == is_block_renamed(block));
|
||||||
|
return block_names_.at(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VprNetlistAnnotation::is_net_renamed(const AtomNetId& net) const {
|
||||||
|
/* Ensure that the pb_type is in the list */
|
||||||
|
std::map<AtomNetId, std::string>::const_iterator it = net_names_.find(net);
|
||||||
|
return it != net_names_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VprNetlistAnnotation::net_name(const AtomNetId& net) const {
|
||||||
|
VTR_ASSERT(true == is_net_renamed(net));
|
||||||
|
return net_names_.at(net);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Public mutators
|
||||||
|
***********************************************************************/
|
||||||
|
void VprNetlistAnnotation::rename_block(const AtomBlockId& block, const std::string& name) {
|
||||||
|
/* Warn any override attempt */
|
||||||
|
std::map<AtomBlockId, std::string>::const_iterator it = block_names_.find(block);
|
||||||
|
if (it != block_names_.end()) {
|
||||||
|
VTR_LOG_WARN("Override the block with name '%s' in netlist annotation!\n",
|
||||||
|
name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
block_names_[block] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VprNetlistAnnotation::rename_net(const AtomNetId& net, const std::string& name) {
|
||||||
|
/* Warn any override attempt */
|
||||||
|
std::map<AtomNetId, std::string>::const_iterator it = net_names_.find(net);
|
||||||
|
if (it != net_names_.end()) {
|
||||||
|
VTR_LOG_WARN("Override the net with name '%s' in netlist annotation!\n",
|
||||||
|
name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
net_names_[net] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* End namespace openfpga*/
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef VPR_NETLIST_ANNOTATION_H
|
||||||
|
#define VPR_NETLIST_ANNOTATION_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files required by the data structure definition
|
||||||
|
*******************************************************************/
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
/* Header from vpr library */
|
||||||
|
#include "atom_netlist.h"
|
||||||
|
|
||||||
|
/* Begin namespace openfpga */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* This is the critical data structure to link the pb_type in VPR
|
||||||
|
* to openfpga annotations
|
||||||
|
* With a given pb_type pointer, it aims to identify:
|
||||||
|
* 1. if the pb_type is a physical pb_type or a operating pb_type
|
||||||
|
* 2. what is the circuit model id linked to a physical pb_type
|
||||||
|
* 3. what is the physical pb_type for an operating pb_type
|
||||||
|
* 4. what is the mode pointer that represents the physical mode for a pb_type
|
||||||
|
*******************************************************************/
|
||||||
|
class VprNetlistAnnotation {
|
||||||
|
public: /* Constructor */
|
||||||
|
VprNetlistAnnotation();
|
||||||
|
public: /* Public accessors */
|
||||||
|
bool is_block_renamed(const AtomBlockId& block) const;
|
||||||
|
std::string block_name(const AtomBlockId& block) const;
|
||||||
|
bool is_net_renamed(const AtomNetId& net) const;
|
||||||
|
std::string net_name(const AtomNetId& net) const;
|
||||||
|
public: /* Public mutators */
|
||||||
|
void rename_block(const AtomBlockId& block, const std::string& name);
|
||||||
|
void rename_net(const AtomNetId& net, const std::string& name);
|
||||||
|
private: /* Internal data */
|
||||||
|
/* Pair a regular pb_type to its physical pb_type */
|
||||||
|
std::map<AtomBlockId, std::string> block_names_;
|
||||||
|
std::map<AtomNetId, std::string> net_names_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* End namespace openfpga*/
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,7 +8,7 @@ read_openfpga_arch -f ./test_openfpga_arch/k6_N10_40nm_openfpga.xml
|
||||||
link_openfpga_arch
|
link_openfpga_arch
|
||||||
|
|
||||||
# Check and correct any naming conflicts in the BLIF netlist
|
# Check and correct any naming conflicts in the BLIF netlist
|
||||||
check_netlist_naming_conflict --correction --report ./netlist_renaming.rpt
|
check_netlist_naming_conflict --fix --report ./netlist_renaming.rpt
|
||||||
|
|
||||||
# Finish and exit OpenFPGA
|
# Finish and exit OpenFPGA
|
||||||
exit
|
exit
|
||||||
|
|
Loading…
Reference in New Issue