aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/rpc/rpc_frontend.cc12
-rw-r--r--frontends/verific/verific.cc178
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";