mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #3494 from YosysHQ/micko/verific_attributes
Handle attributes imported from verific
This commit is contained in:
commit
f5e2c0a498
|
@ -190,6 +190,36 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj)
|
||||||
return s;
|
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)
|
void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
|
||||||
{
|
{
|
||||||
MapIter mi;
|
MapIter mi;
|
||||||
|
@ -198,14 +228,10 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
|
||||||
if (obj->Linefile())
|
if (obj->Linefile())
|
||||||
attributes[ID::src] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(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) {
|
FOREACH_ATTRIBUTE(obj, mi, attr) {
|
||||||
if (attr->Key()[0] == ' ' || attr->Value() == nullptr)
|
if (attr->Key()[0] == ' ' || attr->Value() == nullptr)
|
||||||
continue;
|
continue;
|
||||||
std::string val = std::string(attr->Value());
|
attributes[RTLIL::escape_id(attr->Key())] = verific_const(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nl) {
|
if (nl) {
|
||||||
|
@ -2562,6 +2588,45 @@ struct VerificPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
#ifdef YOSYS_ENABLE_VERIFIC
|
#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
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
static bool set_verific_global_flags = true;
|
static bool set_verific_global_flags = true;
|
||||||
|
@ -2634,6 +2699,7 @@ struct VerificPass : public Pass {
|
||||||
const char *release_str = Message::ReleaseString();
|
const char *release_str = Message::ReleaseString();
|
||||||
time_t release_time = Message::ReleaseDate();
|
time_t release_time = Message::ReleaseDate();
|
||||||
char *release_tmstr = ctime(&release_time);
|
char *release_tmstr = ctime(&release_time);
|
||||||
|
std::vector<std::string> tmp_files;
|
||||||
|
|
||||||
if (release_str == nullptr)
|
if (release_str == nullptr)
|
||||||
release_str = "(no release string)";
|
release_str = "(no release string)";
|
||||||
|
@ -2831,8 +2897,7 @@ struct VerificPass : public Pass {
|
||||||
veri_file::AddLibExt(ext.c_str());
|
veri_file::AddLibExt(ext.c_str());
|
||||||
|
|
||||||
while (argidx < GetSize(args)) {
|
while (argidx < GetSize(args)) {
|
||||||
std::string filename(args[argidx++]);
|
std::string filename = frontent_rewrite(args, argidx, tmp_files);
|
||||||
rewrite_filename(filename);
|
|
||||||
file_names.Insert(strdup(filename.c_str()));
|
file_names.Insert(strdup(filename.c_str()));
|
||||||
}
|
}
|
||||||
if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) {
|
if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) {
|
||||||
|
@ -2847,9 +2912,9 @@ struct VerificPass : public Pass {
|
||||||
#ifdef VERIFIC_VHDL_SUPPORT
|
#ifdef VERIFIC_VHDL_SUPPORT
|
||||||
if (GetSize(args) > argidx && args[argidx] == "-vhdl87") {
|
if (GetSize(args) > argidx && args[argidx] == "-vhdl87") {
|
||||||
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str());
|
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str());
|
||||||
for (argidx++; argidx < GetSize(args); argidx++) {
|
argidx++;
|
||||||
std::string filename(args[argidx]);
|
while (argidx < GetSize(args)) {
|
||||||
rewrite_filename(filename);
|
std::string filename = frontent_rewrite(args, argidx, tmp_files);
|
||||||
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_87))
|
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());
|
log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename.c_str());
|
||||||
}
|
}
|
||||||
|
@ -2859,9 +2924,9 @@ struct VerificPass : public Pass {
|
||||||
|
|
||||||
if (GetSize(args) > argidx && args[argidx] == "-vhdl93") {
|
if (GetSize(args) > argidx && args[argidx] == "-vhdl93") {
|
||||||
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str());
|
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str());
|
||||||
for (argidx++; argidx < GetSize(args); argidx++) {
|
argidx++;
|
||||||
std::string filename(args[argidx]);
|
while (argidx < GetSize(args)) {
|
||||||
rewrite_filename(filename);
|
std::string filename = frontent_rewrite(args, argidx, tmp_files);
|
||||||
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_93))
|
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());
|
log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename.c_str());
|
||||||
}
|
}
|
||||||
|
@ -2871,9 +2936,9 @@ struct VerificPass : public Pass {
|
||||||
|
|
||||||
if (GetSize(args) > argidx && args[argidx] == "-vhdl2k") {
|
if (GetSize(args) > argidx && args[argidx] == "-vhdl2k") {
|
||||||
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str());
|
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str());
|
||||||
for (argidx++; argidx < GetSize(args); argidx++) {
|
argidx++;
|
||||||
std::string filename(args[argidx]);
|
while (argidx < GetSize(args)) {
|
||||||
rewrite_filename(filename);
|
std::string filename = frontent_rewrite(args, argidx, tmp_files);
|
||||||
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2K))
|
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());
|
log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename.c_str());
|
||||||
}
|
}
|
||||||
|
@ -2883,9 +2948,9 @@ struct VerificPass : public Pass {
|
||||||
|
|
||||||
if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) {
|
if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) {
|
||||||
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str());
|
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str());
|
||||||
for (argidx++; argidx < GetSize(args); argidx++) {
|
argidx++;
|
||||||
std::string filename(args[argidx]);
|
while (argidx < GetSize(args)) {
|
||||||
rewrite_filename(filename);
|
std::string filename = frontent_rewrite(args, argidx, tmp_files);
|
||||||
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2008))
|
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());
|
log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename.c_str());
|
||||||
}
|
}
|
||||||
|
@ -3237,6 +3302,13 @@ struct VerificPass : public Pass {
|
||||||
cmd_error(args, argidx, "Missing or unsupported mode parameter.\n");
|
cmd_error(args, argidx, "Missing or unsupported mode parameter.\n");
|
||||||
|
|
||||||
check_error:
|
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())
|
if (!verific_error_msg.empty())
|
||||||
log_error("%s\n", verific_error_msg.c_str());
|
log_error("%s\n", verific_error_msg.c_str());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue