aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorClaire Wolf <claire@symbioticeda.com>2020-03-13 13:46:32 +0100
committerClaire Wolf <claire@symbioticeda.com>2020-03-13 13:46:32 +0100
commit29e2b2dc05716607b136370432ba602c4f8c4822 (patch)
tree2098c78de43e6218cc9735706492b0db71a23bfc /backends
parenta0cc795e85541b0326b6d4396a726142f0d0f8bb (diff)
downloadyosys-29e2b2dc05716607b136370432ba602c4f8c4822.tar.gz
yosys-29e2b2dc05716607b136370432ba602c4f8c4822.tar.bz2
yosys-29e2b2dc05716607b136370432ba602c4f8c4822.zip
Add info-file and cover features to write_btor
Signed-off-by: Claire Wolf <claire@symbioticeda.com>
Diffstat (limited to 'backends')
-rw-r--r--backends/btor/btor.cc122
1 files changed, 113 insertions, 9 deletions
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index c1da4b127..cd7594c8c 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -39,6 +39,7 @@ struct BtorWorker
RTLIL::Module *module;
bool verbose;
bool single_bad;
+ bool cover_mode;
int next_nid = 1;
int initstate_nid = -1;
@@ -71,7 +72,10 @@ struct BtorWorker
vector<int> bad_properties;
dict<SigBit, bool> initbits;
pool<Wire*> statewires;
- string indent;
+
+ string indent, info_filename;
+ vector<string> info_lines;
+ dict<int, int> info_clocks;
void btorf(const char *fmt, ...)
{
@@ -81,6 +85,14 @@ struct BtorWorker
va_end(ap);
}
+ void infof(const char *fmt, ...)
+ {
+ va_list ap;
+ va_start(ap, fmt);
+ info_lines.push_back(vstringf(fmt, ap));
+ va_end(ap);
+ }
+
void btorf_push(const string &id)
{
if (verbose) {
@@ -544,11 +556,26 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N", "$_FF_"))
+ if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N_", "$_FF_"))
{
SigSpec sig_d = sigmap(cell->getPort("\\D"));
SigSpec sig_q = sigmap(cell->getPort("\\Q"));
+ if (!info_filename.empty() && cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_"))
+ {
+ SigSpec sig_c = sigmap(cell->getPort(cell->type == "$dff" ? "\\CLK" : "\\C"));
+ int nid = get_sig_nid(sig_c);
+ bool negedge = false;
+
+ if (cell->type == "$_DFF_N_")
+ negedge = true;
+
+ if (cell->type == "$dff" && !cell->getParam("\\CLK_POLARITY").as_bool())
+ negedge = true;
+
+ info_clocks[nid] |= negedge ? 2 : 1;
+ }
+
IdString symbol;
if (sig_q.is_wire()) {
@@ -983,9 +1010,12 @@ struct BtorWorker
return nid;
}
- BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad) :
- f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad)
+ BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, string info_filename) :
+ f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), info_filename(info_filename)
{
+ if (!info_filename.empty())
+ infof("name %s\n", log_id(module));
+
btorf_push("inputs");
for (auto wire : module->wires())
@@ -1066,16 +1096,46 @@ struct BtorWorker
btorf("%d not %d %d\n", nid_not_a, sid, nid_a);
btorf("%d and %d %d %d\n", nid_en_and_not_a, sid, nid_en, nid_not_a);
- if (single_bad) {
+ if (single_bad && !cover_mode) {
bad_properties.push_back(nid_en_and_not_a);
} else {
- int nid = next_nid++;
string infostr = log_id(cell);
if (infostr[0] == '$' && cell->attributes.count("\\src")) {
infostr = cell->attributes.at("\\src").decode_string().c_str();
std::replace(infostr.begin(), infostr.end(), ' ', '_');
}
- btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
+ if (cover_mode) {
+ infof("bad %d %s\n", nid_en_and_not_a, infostr.c_str());
+ } else {
+ int nid = next_nid++;
+ btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
+ }
+ }
+
+ btorf_pop(log_id(cell));
+ }
+
+ if (cell->type == "$cover" && cover_mode)
+ {
+ btorf_push(log_id(cell));
+
+ int sid = get_bv_sid(1);
+ int nid_a = get_sig_nid(cell->getPort("\\A"));
+ int nid_en = get_sig_nid(cell->getPort("\\EN"));
+ int nid_en_and_a = next_nid++;
+
+ btorf("%d and %d %d %d\n", nid_en_and_a, sid, nid_en, nid_a);
+
+ if (single_bad) {
+ bad_properties.push_back(nid_en_and_a);
+ } else {
+ string infostr = log_id(cell);
+ if (infostr[0] == '$' && cell->attributes.count("\\src")) {
+ infostr = cell->attributes.at("\\src").decode_string().c_str();
+ std::replace(infostr.begin(), infostr.end(), ' ', '_');
+ }
+ int nid = next_nid++;
+ btorf("%d bad %d %s\n", nid, nid_en_and_a, infostr.c_str());
}
btorf_pop(log_id(cell));
@@ -1210,6 +1270,35 @@ struct BtorWorker
btorf("%d bad %d\n", nid, todo[cursor]);
}
}
+
+ if (!info_filename.empty())
+ {
+ for (auto &it : info_clocks)
+ {
+ switch (it.second)
+ {
+ case 1:
+ infof("posedge %d\n", it.first);
+ break;
+ case 2:
+ infof("negedge %d\n", it.first);
+ break;
+ case 3:
+ infof("event %d\n", it.first);
+ break;
+ default:
+ log_abort();
+ }
+ }
+
+ std::ofstream f;
+ f.open(info_filename.c_str(), std::ofstream::trunc);
+ if (f.fail())
+ log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno));
+ for (auto &it : info_lines)
+ f << it;
+ f.close();
+ }
}
};
@@ -1229,10 +1318,17 @@ struct BtorBackend : public Backend {
log(" -s\n");
log(" Output only a single bad property for all asserts\n");
log("\n");
+ log(" -c\n");
+ log(" Output cover properties using 'bad' statements instead of asserts\n");
+ log("\n");
+ log(" -i <filename>\n");
+ log(" Create additional info file with auxiliary information\n");
+ log("\n");
}
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- bool verbose = false, single_bad = false;
+ bool verbose = false, single_bad = false, cover_mode = false;
+ string info_filename;
log_header(design, "Executing BTOR backend.\n");
@@ -1247,6 +1343,14 @@ struct BtorBackend : public Backend {
single_bad = true;
continue;
}
+ if (args[argidx] == "-c") {
+ cover_mode = true;
+ continue;
+ }
+ if (args[argidx] == "-i" && argidx+1 < args.size()) {
+ info_filename = args[++argidx];
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
@@ -1259,7 +1363,7 @@ struct BtorBackend : public Backend {
*f << stringf("; BTOR description generated by %s for module %s.\n",
yosys_version_str, log_id(topmod));
- BtorWorker(*f, topmod, verbose, single_bad);
+ BtorWorker(*f, topmod, verbose, single_bad, cover_mode, info_filename);
*f << stringf("; end of yosys output\n");
}