diff --git a/vpr/src/base/netlist_writer.cpp b/vpr/src/base/netlist_writer.cpp index 285678175..4cdb8e75d 100644 --- a/vpr/src/base/netlist_writer.cpp +++ b/vpr/src/base/netlist_writer.cpp @@ -21,6 +21,8 @@ #include "vpr_error.h" #include "vpr_types.h" +#include "read_blif.h" + #include "netlist_walker.h" #include "netlist_writer.h" @@ -629,7 +631,13 @@ class BlackBoxInst : public Instance { //Verilog parameters for (auto iter = params_.begin(); iter != params_.end(); ++iter) { - os << indent(depth + 1) << "." << iter->first << "(" << iter->second << ")"; + /* Prepend a prefix if needed */ + std::stringstream prefix; + if (is_binary_param(iter->second)) { + prefix << iter->second.length() << "'b"; + } + + os << indent(depth + 1) << "." << iter->first << "(" << prefix.str() << iter->second << ")"; if (iter != --params_.end()) { os << ","; } diff --git a/vpr/src/base/read_blif.cpp b/vpr/src/base/read_blif.cpp index 966794574..965ccf40f 100644 --- a/vpr/src/base/read_blif.cpp +++ b/vpr/src/base/read_blif.cpp @@ -21,6 +21,8 @@ #include #include #include //std::isdigit +#include +#include #include "blifparse.hpp" #include "atom_netlist.h" @@ -382,6 +384,14 @@ struct BlifAllocCallback : public blifparse::Callback { parse_error(lineno_, ".param", "Supported only in extended BLIF format"); } + // Validate the parameter value + bool is_valid = is_string_param(value) || is_binary_param(value) || is_real_param(value); + + if (!is_valid) { + std::string msg = "Incorrect parameter '" + name + "' value specification. Value '" + value + "' is not recognized as string, binary word or real number. Possible causes:\n\t* lack or inconsistency in quotes (string)\n\t* no dot '.' to separate integer and fractional part (real number)\n\t* use of characters other than '1' and '0' (binary word)"; + parse_error(lineno_, ".param", msg); + } + curr_model().set_block_param(curr_block(), name, value); } @@ -655,6 +665,67 @@ vtr::LogicValue to_vtr_logic_value(blifparse::LogicValue val) { return new_val; } +bool is_string_param(const std::string& param) { + /* Empty param is considered a string */ + if (param.empty()) { + return true; + } + + /* There have to be at least 2 characters (the quotes) */ + if (param.length() < 2) { + return false; + } + + /* The first and the last characters must be quotes */ + size_t len = param.length(); + if (param[0] != '"' || param[len - 1] != '"') { + return false; + } + + /* There mustn't be any other quotes except for escaped ones */ + for (size_t i = 1; i < (len - 1); ++i) { + if (param[i] == '"' && param[i - 1] != '\\') { + return false; + } + } + + /* This is a string param */ + return true; +} + +bool is_binary_param(const std::string& param) { + /* Must be non-empty */ + if (param.empty()) { + return false; + } + + /* The string must contain only '0' and '1' */ + for (size_t i = 0; i < param.length(); ++i) { + if (param[i] != '0' && param[i] != '1') { + return false; + } + } + + /* This is a binary word param */ + return true; +} + +bool is_real_param(const std::string& param) { + /* Must be non-empty */ + if (param.empty()) { + return false; + } + + /* The string must match the regular expression */ + static const std::regex real_number_expr("[+-]?([0-9]*\\.[0-9]+)|([0-9]+\\.[0-9]*)"); + if (!std::regex_match(param, real_number_expr)) { + return false; + } + + /* This is a real number param */ + return true; +} + AtomNetlist read_blif(e_circuit_format circuit_format, const char* blif_file, const t_model* user_models, diff --git a/vpr/src/base/read_blif.h b/vpr/src/base/read_blif.h index 819bb035e..a11ba4ecb 100644 --- a/vpr/src/base/read_blif.h +++ b/vpr/src/base/read_blif.h @@ -4,6 +4,10 @@ #include "atom_netlist_fwd.h" #include "read_circuit.h" +bool is_string_param(const std::string& param); +bool is_binary_param(const std::string& param); +bool is_real_param(const std::string& param); + AtomNetlist read_blif(e_circuit_format circuit_format, const char* blif_file, const t_model* user_models,