From 8c86c0af042ac0ea52a799c77e837d060b970df3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 29 Jan 2020 16:23:41 -0700 Subject: [PATCH 1/4] add check netlist naming conflict command and functions --- .../base/check_netlist_naming_conflict.cpp | 92 +++++++++++++++++++ .../src/base/check_netlist_naming_conflict.h | 23 +++++ openfpga/src/base/openfpga_setup_command.cpp | 34 ++++++- openfpga/test_script/s298.openfpga | 3 + 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 openfpga/src/base/check_netlist_naming_conflict.cpp create mode 100644 openfpga/src/base/check_netlist_naming_conflict.h diff --git a/openfpga/src/base/check_netlist_naming_conflict.cpp b/openfpga/src/base/check_netlist_naming_conflict.cpp new file mode 100644 index 000000000..58980687f --- /dev/null +++ b/openfpga/src/base/check_netlist_naming_conflict.cpp @@ -0,0 +1,92 @@ +/******************************************************************** + * This file includes functions to detect and correct any naming + * in the users' BLIF netlist that violates the syntax of OpenFPGA + * fabric generator, i.e., Verilog generator and SPICE generator + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "vtr_time.h" +#include "vtr_assert.h" +#include "vtr_log.h" + +#include "check_netlist_naming_conflict.h" + +/* Include global variables of VPR */ +#include "globals.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * This function aims to check if the name contains any of the + * sensitive characters in the list + *******************************************************************/ +static +bool name_contain_sensitive_chars(const std::string& name, + const std::string& sensitive_chars) { + for (const char& sensitive_char : sensitive_chars) { + /* Return true since we find a characters */ + if (std::string::npos != name.find(sensitive_char)) { + return true; + } + } + + return false; +} + +/******************************************************************** + * Detect and report any naming conflict by checking a list of + * sensitive characters + * - Iterate over all the blocks and see if any block name contain + * any sensitive character + * - Iterate over all the nets and see if any net name contain + * any sensitive character + *******************************************************************/ +static +void detect_netlist_naming_conflict(const AtomNetlist& atom_netlist, + const std::string& sensitive_chars) { + size_t num_conflicts = 0; + + /* Walk through blocks in the netlist */ + for (const auto& block : atom_netlist.blocks()) { + const std::string& block_name = atom_netlist.block_name(block); + if (true == name_contain_sensitive_chars(block_name, sensitive_chars)) { + VTR_LOG("Block '%s' violates the syntax requirement by OpenFPGA!\n", + block_name.c_str()); + num_conflicts++; + } + } + + /* Walk through nets in the netlist */ + for (const auto& net : atom_netlist.nets()) { + const std::string& net_name = atom_netlist.net_name(net); + if (true == name_contain_sensitive_chars(net_name, sensitive_chars)) { + VTR_LOG("Net '%s' violates the syntax requirement by OpenFPGA!\n", + net_name.c_str()); + num_conflicts++; + } + } + + if (0 < num_conflicts) { + VTR_LOG("Found %ld naming conflicts in the netlist. Please correct so as to use any fabric generators.\n", + num_conflicts); + } +} + +/******************************************************************** + * Top-level function to detect and correct any naming + * in the users' BLIF netlist that violates the syntax of OpenFPGA + * fabric generator, i.e., Verilog generator and SPICE generator + *******************************************************************/ +void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { + const std::string& sensitive_chars(".,:;\'\"+-<>()[]{}!@#$%^&*~`?/"); + + /* 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); + +} + +} /* end namespace openfpga */ + diff --git a/openfpga/src/base/check_netlist_naming_conflict.h b/openfpga/src/base/check_netlist_naming_conflict.h new file mode 100644 index 000000000..54d86bca4 --- /dev/null +++ b/openfpga/src/base/check_netlist_naming_conflict.h @@ -0,0 +1,23 @@ +#ifndef CHECK_NETLIST_NAMING_CONFLICT_H +#define CHECK_NETLIST_NAMING_CONFLICT_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "command.h" +#include "command_context.h" +#include "openfpga_context.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/base/openfpga_setup_command.cpp b/openfpga/src/base/openfpga_setup_command.cpp index af078446a..ba7ad45b6 100644 --- a/openfpga/src/base/openfpga_setup_command.cpp +++ b/openfpga/src/base/openfpga_setup_command.cpp @@ -5,16 +5,22 @@ *******************************************************************/ #include "openfpga_read_arch.h" #include "openfpga_link_arch.h" +#include "check_netlist_naming_conflict.h" #include "openfpga_setup_command.h" /* begin namespace openfpga */ namespace openfpga { void add_openfpga_setup_commands(openfpga::Shell& shell) { + /* Get the unique id of 'vpr' command which is to be used in creating the dependency graph */ + const ShellCommandId& shell_cmd_vpr_id = shell.command(std::string("vpr")); + /* Add a new class of commands */ ShellCommandClassId openfpga_setup_cmd_class = shell.add_command_class("OpenFPGA setup"); - /* Command 'read_openfpga_arch' */ + /******************************** + * Command 'read_openfpga_arch' + */ Command shell_cmd_read_arch("read_openfpga_arch"); /* Add an option '--file' in short '-f'*/ CommandOptionId read_arch_opt_file = shell_cmd_read_arch.add_option("file", true, "file path to the architecture XML"); @@ -26,7 +32,9 @@ void add_openfpga_setup_commands(openfpga::Shell& shell) { shell.set_command_class(shell_cmd_read_arch_id, openfpga_setup_cmd_class); shell.set_command_execute_function(shell_cmd_read_arch_id, read_arch); - /* Command 'write_openfpga_arch' */ + /******************************** + * Command 'write_openfpga_arch' + */ Command shell_cmd_write_arch("write_openfpga_arch"); /* Add an option '--file' in short '-f'*/ CommandOptionId write_arch_opt_file = shell_cmd_write_arch.add_option("file", true, "file path to the architecture XML"); @@ -40,7 +48,9 @@ void add_openfpga_setup_commands(openfpga::Shell& shell) { /* The 'write_openfpga_arch' command should NOT be executed before 'read_openfpga_arch' */ shell.set_command_dependency(shell_cmd_write_arch_id, std::vector(1, shell_cmd_read_arch_id)); - /* Command 'link_openfpga_arch' */ + /******************************** + * Command 'link_openfpga_arch' + */ Command shell_cmd_link_openfpga_arch("link_openfpga_arch"); /* Add command 'link_openfpga_arch' to the Shell */ @@ -48,12 +58,28 @@ void add_openfpga_setup_commands(openfpga::Shell& shell) { shell.set_command_class(shell_cmd_link_openfpga_arch_id, openfpga_setup_cmd_class); shell.set_command_execute_function(shell_cmd_link_openfpga_arch_id, link_arch); /* The 'link_openfpga_arch' command should NOT be executed before 'read_openfpga_arch' and 'vpr' */ - const ShellCommandId& shell_cmd_vpr_id = shell.command(std::string("vpr")); std::vector cmd_dependency_link_openfpga_arch; cmd_dependency_link_openfpga_arch.push_back(shell_cmd_read_arch_id); cmd_dependency_link_openfpga_arch.push_back(shell_cmd_vpr_id); shell.set_command_dependency(shell_cmd_link_openfpga_arch_id, cmd_dependency_link_openfpga_arch); + /******************************************* + * Command 'check_netlist_naming_conflict' + */ + Command shell_cmd_check_netlist_naming_conflict("check_netlist_naming_conflict"); + /* Add an option '--correction' */ + shell_cmd_check_netlist_naming_conflict.add_option("correction", 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"); + shell_cmd_check_netlist_naming_conflict.set_option_require_value(check_netlist_opt_rpt, openfpga::OPT_STRING); + + /* Add command 'check_netlist_naming_conflict' to the Shell */ + ShellCommandId shell_cmd_check_netlist_naming_conflict_id = shell.add_command(shell_cmd_check_netlist_naming_conflict, "Check any block/net naming in users' BLIF netlist violates the syntax of fabric generator"); + shell.set_command_class(shell_cmd_check_netlist_naming_conflict_id, openfpga_setup_cmd_class); + shell.set_command_execute_function(shell_cmd_check_netlist_naming_conflict_id, check_netlist_naming_conflict); + /* The 'link_openfpga_arch' command should NOT be executed before 'read_openfpga_arch' and 'vpr' */ + std::vector cmd_dependency_check_netlist_naming_conflict(1, shell_cmd_vpr_id); + shell.set_command_dependency(shell_cmd_link_openfpga_arch_id, cmd_dependency_check_netlist_naming_conflict); } } /* end namespace openfpga */ diff --git a/openfpga/test_script/s298.openfpga b/openfpga/test_script/s298.openfpga index 6d4eaa434..08e4d9ce3 100644 --- a/openfpga/test_script/s298.openfpga +++ b/openfpga/test_script/s298.openfpga @@ -7,5 +7,8 @@ read_openfpga_arch -f ./test_openfpga_arch/k6_N10_40nm_openfpga.xml # Annotate the OpenFPGA architecture to VPR data base link_openfpga_arch +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --correction --report ./netlist_renaming.rpt + # Finish and exit OpenFPGA exit From 2dc4c26257cdec0c822c564af4a98c42fa533733 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 29 Jan 2020 17:49:33 -0700 Subject: [PATCH 2/4] add naming fix-up --- .../base/check_netlist_naming_conflict.cpp | 122 +++++++++++++++--- openfpga/src/base/openfpga_context.h | 5 + openfpga/src/base/openfpga_setup_command.cpp | 2 +- openfpga/src/base/vpr_netlist_annotation.cpp | 68 ++++++++++ openfpga/src/base/vpr_netlist_annotation.h | 43 ++++++ openfpga/test_script/s298.openfpga | 2 +- 6 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 openfpga/src/base/vpr_netlist_annotation.cpp create mode 100644 openfpga/src/base/vpr_netlist_annotation.h diff --git a/openfpga/src/base/check_netlist_naming_conflict.cpp b/openfpga/src/base/check_netlist_naming_conflict.cpp index 58980687f..57056712a 100644 --- a/openfpga/src/base/check_netlist_naming_conflict.cpp +++ b/openfpga/src/base/check_netlist_naming_conflict.cpp @@ -21,18 +21,47 @@ namespace openfpga { /******************************************************************** * This function aims to check if the name contains any of the * sensitive characters in the list + * Return a string of sensitive characters which are contained + * in the name *******************************************************************/ static -bool name_contain_sensitive_chars(const std::string& name, - const std::string& sensitive_chars) { +std::string name_contain_sensitive_chars(const std::string& name, + const std::string& sensitive_chars) { + std::string violation; + for (const char& sensitive_char : sensitive_chars) { /* Return true since we find a characters */ 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 *******************************************************************/ 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) { size_t num_conflicts = 0; /* Walk through blocks in the netlist */ for (const auto& block : atom_netlist.blocks()) { const std::string& block_name = atom_netlist.block_name(block); - if (true == name_contain_sensitive_chars(block_name, sensitive_chars)) { - VTR_LOG("Block '%s' violates the syntax requirement by OpenFPGA!\n", - block_name.c_str()); + const std::string& violation = name_contain_sensitive_chars(block_name, sensitive_chars); + if (false == violation.empty()) { + VTR_LOG("Block '%s' contains illegal characters '%s'\n", + block_name.c_str(), violation.c_str()); num_conflicts++; } } @@ -61,19 +91,62 @@ void detect_netlist_naming_conflict(const AtomNetlist& atom_netlist, /* Walk through nets in the netlist */ for (const auto& net : atom_netlist.nets()) { const std::string& net_name = atom_netlist.net_name(net); - if (true == name_contain_sensitive_chars(net_name, sensitive_chars)) { - VTR_LOG("Net '%s' violates the syntax requirement by OpenFPGA!\n", - net_name.c_str()); + const std::string& violation = name_contain_sensitive_chars(net_name, sensitive_chars); + if (false == violation.empty()) { + VTR_LOG("Net '%s' contains illegal characters '%s'\n", + net_name.c_str(), violation.c_str()); num_conflicts++; } } - if (0 < num_conflicts) { - VTR_LOG("Found %ld naming conflicts in the netlist. Please correct so as to use any fabric generators.\n", - num_conflicts); - } + return 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 * 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, const Command& cmd, const CommandContext& cmd_context) { + /* By default, we replace all the illegal characters with '_' */ 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 */ - 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 */ diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index 185a08c5c..cac5877d5 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -3,6 +3,7 @@ #include "vpr_context.h" #include "openfpga_arch.h" +#include "vpr_netlist_annotation.h" #include "vpr_pb_type_annotation.h" /******************************************************************** @@ -36,14 +37,18 @@ class OpenfpgaContext : public Context { public: /* Public accessors */ const openfpga::Arch& arch() const { return arch_; } 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 */ openfpga::Arch& mutable_arch() { return arch_; } 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 */ /* Data structure to store information from read_openfpga_arch library */ openfpga::Arch arch_; /* Annotation to pb_type of VPR */ openfpga::VprPbTypeAnnotation vpr_pb_type_annotation_; + /* Naming fix to netlist */ + openfpga::VprNetlistAnnotation vpr_netlist_annotation_; }; #endif diff --git a/openfpga/src/base/openfpga_setup_command.cpp b/openfpga/src/base/openfpga_setup_command.cpp index ba7ad45b6..9a3eee970 100644 --- a/openfpga/src/base/openfpga_setup_command.cpp +++ b/openfpga/src/base/openfpga_setup_command.cpp @@ -68,7 +68,7 @@ void add_openfpga_setup_commands(openfpga::Shell& shell) { */ Command shell_cmd_check_netlist_naming_conflict("check_netlist_naming_conflict"); /* 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' */ 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); diff --git a/openfpga/src/base/vpr_netlist_annotation.cpp b/openfpga/src/base/vpr_netlist_annotation.cpp new file mode 100644 index 000000000..0d9d5443d --- /dev/null +++ b/openfpga/src/base/vpr_netlist_annotation.cpp @@ -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::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::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::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::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*/ diff --git a/openfpga/src/base/vpr_netlist_annotation.h b/openfpga/src/base/vpr_netlist_annotation.h new file mode 100644 index 000000000..3b8bbd16f --- /dev/null +++ b/openfpga/src/base/vpr_netlist_annotation.h @@ -0,0 +1,43 @@ +#ifndef VPR_NETLIST_ANNOTATION_H +#define VPR_NETLIST_ANNOTATION_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include + +/* 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 block_names_; + std::map net_names_; +}; + +} /* End namespace openfpga*/ + +#endif diff --git a/openfpga/test_script/s298.openfpga b/openfpga/test_script/s298.openfpga index 08e4d9ce3..cafc16074 100644 --- a/openfpga/test_script/s298.openfpga +++ b/openfpga/test_script/s298.openfpga @@ -8,7 +8,7 @@ read_openfpga_arch -f ./test_openfpga_arch/k6_N10_40nm_openfpga.xml link_openfpga_arch # 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 exit From 87f1ca1151ebbb1216567f761f09eafd8b11acb1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 29 Jan 2020 18:56:47 -0700 Subject: [PATCH 3/4] add naming fix-up report generation --- .../src/write_xml_openfpga_arch.cpp | 3 + .../base/check_netlist_naming_conflict.cpp | 99 ++++++++++++++++--- 2 files changed, 89 insertions(+), 13 deletions(-) diff --git a/libopenfpga/libarchopenfpga/src/write_xml_openfpga_arch.cpp b/libopenfpga/libarchopenfpga/src/write_xml_openfpga_arch.cpp index b71853156..eb999dcd1 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_openfpga_arch.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_openfpga_arch.cpp @@ -66,4 +66,7 @@ void write_xml_openfpga_arch(const char* fname, /* Write the simulation */ write_xml_simulation_setting(fp, fname, openfpga_arch.sim_setting); + + /* Close the file stream */ + fp.close(); } diff --git a/openfpga/src/base/check_netlist_naming_conflict.cpp b/openfpga/src/base/check_netlist_naming_conflict.cpp index 57056712a..c3fc50d0b 100644 --- a/openfpga/src/base/check_netlist_naming_conflict.cpp +++ b/openfpga/src/base/check_netlist_naming_conflict.cpp @@ -4,12 +4,19 @@ * fabric generator, i.e., Verilog generator and SPICE generator *******************************************************************/ #include +#include /* Headers from vtrutil library */ #include "vtr_time.h" #include "vtr_assert.h" #include "vtr_log.h" +/* Headers from archopenfpga library */ +#include "write_xml_utils.h" + +/* Headers from openfpgautil library */ +#include "openfpga_digest.h" + #include "check_netlist_naming_conflict.h" /* Include global variables of VPR */ @@ -111,10 +118,10 @@ size_t detect_netlist_naming_conflict(const AtomNetlist& atom_netlist, * 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) { +void fix_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 */ @@ -144,7 +151,62 @@ void correct_netlist_naming_conflict(const AtomNetlist& atom_netlist, VTR_LOG("Fixed %ld naming conflicts in the netlist.\n", num_fixes); } +} +/******************************************************************** + * Report all the fix-up in the naming of netlist components, + * i.e., blocks, nets + *******************************************************************/ +static +void print_netlist_naming_fix_report(const std::string& fname, + const AtomNetlist& atom_netlist, + const VprNetlistAnnotation& vpr_netlist_annotation) { + /* Create a file handler */ + std::fstream fp; + /* Open the file stream */ + fp.open(fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + openfpga::check_file_stream(fname.c_str(), fp); + + fp << " " << "\n"; + fp << "" << "\n"; + + fp << "\t" << "" << "\n"; + + for (const auto& block : atom_netlist.blocks()) { + const std::string& block_name = atom_netlist.block_name(block); + if (false == vpr_netlist_annotation.is_block_renamed(block)) { + continue; + } + fp << "\t\t" << "" << "\n"; + } + + fp << "\t" << "" << "\n"; + + fp << "\t" << "" << "\n"; + + for (const auto& net : atom_netlist.nets()) { + const std::string& net_name = atom_netlist.net_name(net); + if (false == vpr_netlist_annotation.is_net_renamed(net)) { + continue; + } + fp << "\t\t" << "" << "\n"; + } + + fp << "\t" << "" << "\n"; + + + fp << "" << "\n"; + + /* Close the file stream */ + fp.close(); } /******************************************************************** @@ -154,6 +216,8 @@ void correct_netlist_naming_conflict(const AtomNetlist& atom_netlist, *******************************************************************/ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, const Command& cmd, const CommandContext& cmd_context) { + vtr::ScopedStartFinishTimer timer("Check naming violations of netlist blocks and nets"); + /* By default, we replace all the illegal characters with '_' */ const std::string& sensitive_chars(".,:;\'\"+-<>()[]{}!@#$%^&*~`?/"); const std::string& fix_chars("____________________________"); @@ -161,18 +225,27 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, CommandOptionId opt_fix = cmd.option("fix"); /* Do the main job first: detect any naming in the BLIF netlist that violates the syntax */ - 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 (false == cmd_context.option_enable(cmd, opt_fix)) { + 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"); + return; + } /* 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()); + fix_netlist_naming_conflict(g_vpr_ctx.atom().nlist, sensitive_chars, + fix_chars, openfpga_context.mutable_vpr_netlist_annotation()); + + CommandOptionId opt_report = cmd.option("report"); + if (true == cmd_context.option_enable(cmd, opt_report)) { + print_netlist_naming_fix_report(cmd_context.option_value(cmd, opt_report), + g_vpr_ctx.atom().nlist, + openfpga_context.vpr_netlist_annotation()); + } } } From f28ca3ffd0c327f2fa92a08b28d443cbb285e47d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 29 Jan 2020 18:58:57 -0700 Subject: [PATCH 4/4] add more echo to log --- openfpga/src/base/check_netlist_naming_conflict.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfpga/src/base/check_netlist_naming_conflict.cpp b/openfpga/src/base/check_netlist_naming_conflict.cpp index c3fc50d0b..3470c9f0a 100644 --- a/openfpga/src/base/check_netlist_naming_conflict.cpp +++ b/openfpga/src/base/check_netlist_naming_conflict.cpp @@ -202,7 +202,6 @@ void print_netlist_naming_fix_report(const std::string& fname, fp << "\t" << "" << "\n"; - fp << "" << "\n"; /* Close the file stream */ @@ -245,6 +244,8 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, print_netlist_naming_fix_report(cmd_context.option_value(cmd, opt_report), g_vpr_ctx.atom().nlist, openfpga_context.vpr_netlist_annotation()); + VTR_LOG("Naming fix-up report is generated to file '%s'\n", + cmd_context.option_value(cmd, opt_report).c_str()); } } }