diff options
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/rpc/rpc_frontend.cc | 12 | ||||
-rw-r--r-- | frontends/verific/verific.cc | 178 |
2 files changed, 162 insertions, 28 deletions
diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index c12640ef0..ec3952661 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -383,12 +383,12 @@ struct RpcFrontend : public Pass { log(" request for the module <module-name> to be derived for a specific set of\n"); log(" parameters. <param-name> starts with \\ for named parameters, and with $\n"); log(" for unnamed parameters, which are numbered starting at 1.<param-value>\n"); - log(" for integer parameters is always specified as a binary string of unlimited\n"); - log(" precision. the <source> returned by the frontend is hygienically parsed\n"); - log(" by a built-in Yosys <frontend>, allowing the RPC frontend to return any\n"); - log(" convenient representation of the module. the derived module is cached,\n"); - log(" so the response should be the same whenever the same set of parameters\n"); - log(" is provided.\n"); + log(" for integer parameters is always specified as a binary string of\n"); + log(" unlimited precision. the <source> returned by the frontend is\n"); + log(" hygienically parsedby a built-in Yosys <frontend>, allowing the RPC\n"); + log(" frontend to return anyconvenient representation of the module. the\n"); + log(" derived module is cached,so the response should be the same whenever the\n"); + log(" same set of parameters is provided.\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override { diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index e0dbe1b32..1b9db8772 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -53,6 +53,10 @@ USING_YOSYS_NAMESPACE #include "VhdlUnits.h" #endif +#ifdef VERIFIC_EDIF_SUPPORT +#include "edif_file.h" +#endif + #include "VerificStream.h" #include "FileSystem.h" @@ -149,6 +153,8 @@ public: } }; +YosysStreamCallBackHandler verific_read_cb; + // ================================================================== VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit) : @@ -188,6 +194,36 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) return s; } +static bool isNumber(const string& str) +{ + for (auto &c : str) { + if (std::isdigit(c) == 0) return false; + } + return true; +} + +// When used as attributes or parameter values Verific constants come already processed. +// - Real string values are already under quotes +// - Numeric values with specified width are always converted to binary +// - Rest of user defined values are handled as 32bit integers +// - There could be some internal values that are strings without quotes +// so we check if value is all digits or not +// +static const RTLIL::Const verific_const(const char *value) +{ + std::string val = std::string(value); + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') + return RTLIL::Const(val.substr(1,val.size()-2)); + else + if (val.find("'b") != std::string::npos) + return RTLIL::Const::from_string(val.substr(val.find("'b") + 2)); + else + if (isNumber(val)) + return RTLIL::Const(std::stoi(val),32); + else + return RTLIL::Const(val); +} + void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl) { MapIter mi; @@ -196,14 +232,10 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att if (obj->Linefile()) attributes[ID::src] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); - // FIXME: Parse numeric attributes FOREACH_ATTRIBUTE(obj, mi, attr) { if (attr->Key()[0] == ' ' || attr->Value() == nullptr) continue; - std::string val = std::string(attr->Value()); - if (val.size()>1 && val[0]=='\"' && val.back()=='\"') - val = val.substr(1,val.size()-2); - attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(val); + attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value()); } if (nl) { @@ -1174,6 +1206,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma memory->name = RTLIL::escape_id(net->Name()); log_assert(module->count_id(memory->name) == 0); module->memories[memory->name] = memory; + import_attributes(memory->attributes, net, nl); int number_of_bits = net->Size(); int bits_in_word = number_of_bits; @@ -2323,6 +2356,9 @@ void verific_import(Design *design, const std::map<std::string,std::string> &par #ifdef VERIFIC_VHDL_SUPPORT vhdl_file::Reset(); #endif +#ifdef VERIFIC_EDIF_SUPPORT + edif_file::Reset(); +#endif Libset::Reset(); Message::Reset(); RuntimeFlags::DeleteAllFlags(); @@ -2384,6 +2420,13 @@ struct VerificPass : public Pass { log("\n"); log("\n"); #endif +#ifdef VERIFIC_EDIF_SUPPORT + log(" verific {-edif} <edif-file>..\n"); + log("\n"); + log("Load the specified EDIF files into Verific.\n"); + log("\n"); + log("\n"); +#endif log(" verific {-f|-F} [-vlog95|-vlog2k|-sv2005|-sv2009|\n"); log(" -sv2012|-sv|-formal] <command-file>\n"); log("\n"); @@ -2559,6 +2602,45 @@ struct VerificPass : public Pass { log("\n"); } #ifdef YOSYS_ENABLE_VERIFIC + std::string frontent_rewrite(std::vector<std::string> &args, int &argidx, std::vector<std::string> &tmp_files) + { + std::string filename = args[argidx++]; + //Accommodate heredocs with EOT marker spaced out from "<<", e.g. "<< EOT" vs. "<<EOT" + if (filename == "<<" && (argidx < GetSize(args))) { + filename += args[argidx++]; + } + if (filename.compare(0, 2, "<<") == 0) { + if (filename.size() <= 2) + log_error("Missing EOT marker in here document!\n"); + std::string eot_marker = filename.substr(2); + if (Frontend::current_script_file == nullptr) + filename = "<stdin>"; + std::string last_here_document; + while (1) { + std::string buffer; + char block[4096]; + while (1) { + if (fgets(block, 4096, Frontend::current_script_file == nullptr? stdin : Frontend::current_script_file) == nullptr) + log_error("Unexpected end of file in here document '%s'!\n", filename.c_str()); + buffer += block; + if (buffer.size() > 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r')) + break; + } + size_t indent = buffer.find_first_not_of(" \t\r\n"); + if (indent != std::string::npos && buffer.compare(indent, eot_marker.size(), eot_marker) == 0) + break; + last_here_document += buffer; + } + filename = make_temp_file(); + tmp_files.push_back(filename); + std::ofstream file(filename); + file << last_here_document; + } else { + rewrite_filename(filename); + } + return filename; + } + void execute(std::vector<std::string> args, RTLIL::Design *design) override { static bool set_verific_global_flags = true; @@ -2631,6 +2713,7 @@ struct VerificPass : public Pass { const char *release_str = Message::ReleaseString(); time_t release_time = Message::ReleaseDate(); char *release_tmstr = ctime(&release_time); + std::vector<std::string> tmp_files; if (release_str == nullptr) release_str = "(no release string)"; @@ -2642,8 +2725,7 @@ struct VerificPass : public Pass { int argidx = 1; std::string work = "work"; - YosysStreamCallBackHandler cb; - veri_file::RegisterCallBackVerificStream(&cb); + veri_file::RegisterCallBackVerificStream(&verific_read_cb); if (GetSize(args) > argidx && (args[argidx] == "-set-error" || args[argidx] == "-set-warning" || args[argidx] == "-set-info" || args[argidx] == "-set-ignore")) @@ -2709,6 +2791,20 @@ struct VerificPass : public Pass { } veri_file::RemoveAllLOptions(); + veri_file::AddLOption("work"); + for (int i = argidx; i < GetSize(args); i++) + { + if (args[i] == "-work" && i+1 < GetSize(args)) { + ++i; + continue; + } + if (args[i] == "-L" && i+1 < GetSize(args)) { + if (args[++i] == "work") + veri_file::RemoveAllLOptions(); + continue; + } + break; + } for (; argidx < GetSize(args); argidx++) { if (args[argidx] == "-work" && argidx+1 < GetSize(args)) { @@ -2829,8 +2925,7 @@ struct VerificPass : public Pass { veri_file::AddLibExt(ext.c_str()); while (argidx < GetSize(args)) { - std::string filename(args[argidx++]); - rewrite_filename(filename); + std::string filename = frontent_rewrite(args, argidx, tmp_files); file_names.Insert(strdup(filename.c_str())); } if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) { @@ -2845,9 +2940,9 @@ struct VerificPass : public Pass { #ifdef VERIFIC_VHDL_SUPPORT if (GetSize(args) > argidx && args[argidx] == "-vhdl87") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str()); - for (argidx++; argidx < GetSize(args); argidx++) { - std::string filename(args[argidx]); - rewrite_filename(filename); + argidx++; + while (argidx < GetSize(args)) { + std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_87)) log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename.c_str()); } @@ -2857,9 +2952,9 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && args[argidx] == "-vhdl93") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); - for (argidx++; argidx < GetSize(args); argidx++) { - std::string filename(args[argidx]); - rewrite_filename(filename); + argidx++; + while (argidx < GetSize(args)) { + std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_93)) log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename.c_str()); } @@ -2869,9 +2964,9 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && args[argidx] == "-vhdl2k") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); - for (argidx++; argidx < GetSize(args); argidx++) { - std::string filename(args[argidx]); - rewrite_filename(filename); + argidx++; + while (argidx < GetSize(args)) { + std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2K)) log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename.c_str()); } @@ -2881,9 +2976,9 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); - for (argidx++; argidx < GetSize(args); argidx++) { - std::string filename(args[argidx]); - rewrite_filename(filename); + argidx++; + while (argidx < GetSize(args)) { + std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2008)) log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename.c_str()); } @@ -2891,7 +2986,18 @@ struct VerificPass : public Pass { goto check_error; } #endif - +#ifdef VERIFIC_EDIF_SUPPORT + if (GetSize(args) > argidx && args[argidx] == "-edif") { + edif_file edif; + argidx++; + while (argidx < GetSize(args)) { + std::string filename = frontent_rewrite(args, argidx, tmp_files); + if (!edif.Read(filename.c_str())) + log_cmd_error("Reading `%s' in EDIF mode failed.\n", filename.c_str()); + } + goto check_error; + } +#endif if (argidx < GetSize(args) && args[argidx] == "-pp") { const char* filename = nullptr; @@ -3155,6 +3261,9 @@ struct VerificPass : public Pass { #ifdef VERIFIC_VHDL_SUPPORT vhdl_file::Reset(); #endif +#ifdef VERIFIC_EDIF_SUPPORT + edif_file::Reset(); +#endif Libset::Reset(); Message::Reset(); RuntimeFlags::DeleteAllFlags(); @@ -3235,6 +3344,13 @@ struct VerificPass : public Pass { cmd_error(args, argidx, "Missing or unsupported mode parameter.\n"); check_error: + if (tmp_files.size()) { + log("Removing temp files.\n"); + for(auto &fn : tmp_files) { + remove(fn.c_str()); + } + } + if (!verific_error_msg.empty()) log_error("%s\n", verific_error_msg.c_str()); @@ -3274,6 +3390,13 @@ struct ReadPass : public Pass { log("\n"); log("\n"); #endif +#ifdef VERIFIC_EDIF_SUPPORT + log(" read {-edif} <edif-file>..\n"); + log("\n"); + log("Load the specified EDIF files. (Requires Verific.)\n"); + log("\n"); + log("\n"); +#endif log(" read {-f|-F} <command-file>\n"); log("\n"); log("Load and execute the specified command file. (Requires Verific.)\n"); @@ -3367,6 +3490,17 @@ struct ReadPass : public Pass { return; } #endif +#ifdef VERIFIC_EDIF_SUPPORT + if (args[1] == "-edif") { + if (use_verific) { + args[0] = "verific"; + Pass::call(design, args); + } else { + cmd_error(args, 1, "This version of Yosys is built without Verific support.\n"); + } + return; + } +#endif if (args[1] == "-f" || args[1] == "-F") { if (use_verific) { args[0] = "verific"; |