aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CODEOWNERS37
-rw-r--r--backends/aiger/xaiger.cc52
-rw-r--r--backends/btor/btor.cc81
-rw-r--r--backends/ilang/ilang_backend.cc2
-rw-r--r--backends/json/json.cc4
-rw-r--r--backends/smt2/smtbmc.py5
-rw-r--r--backends/smt2/smtio.py31
-rw-r--r--frontends/aiger/aigerparse.cc7
-rw-r--r--frontends/ast/genrtlil.cc1
-rw-r--r--frontends/ilang/ilang_parser.y3
-rw-r--r--frontends/json/jsonparse.cc7
-rw-r--r--frontends/verific/verific.cc7
-rw-r--r--kernel/constids.inc1
-rw-r--r--kernel/hashlib.h10
-rw-r--r--kernel/rtlil.cc2
-rw-r--r--kernel/rtlil.h11
-rw-r--r--misc/py_wrap_generator.py20
-rw-r--r--passes/cmds/blackbox.cc26
-rw-r--r--passes/sat/qbfsat.cc66
-rw-r--r--passes/techmap/.gitignore1
-rw-r--r--passes/techmap/Makefile.inc12
-rw-r--r--passes/techmap/abc9_ops.cc85
-rw-r--r--passes/techmap/simplemap.cc6
-rw-r--r--passes/techmap/simplemap.h2
-rw-r--r--passes/techmap/techmap.cc338
-rw-r--r--techlibs/common/abc9_unmap.v2
-rw-r--r--tests/arch/ecp5/latches_abc9.ys13
-rw-r--r--tests/arch/ice40/mux.ys3
-rw-r--r--tests/arch/xilinx/abc9_dff.ys57
-rw-r--r--tests/arch/xilinx/pmgen_xilinx_srl.ys2
-rw-r--r--tests/arch/xilinx/xilinx_srl.v2
-rw-r--r--tests/various/abc9.ys3
-rw-r--r--tests/various/attrib07_func_call.v2
-rw-r--r--tests/various/constmsk_testmap.v2
-rw-r--r--tests/various/shregmap.v4
-rw-r--r--tests/verilog/bug2042-sv.ys2
36 files changed, 550 insertions, 359 deletions
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 000000000..a73779920
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,37 @@
+## CODE NOTIFICATIONS
+# Register yourself here to be notified about modifications
+# for any files you have an interest in/know your way around.
+
+# Each line is a file pattern followed by one or more users.
+# Both github usernames and email addresses are supported.
+# Order is important; the last matching pattern takes the most
+# precedence. Previous matches will not be applied.
+
+
+# PATH (can use glob) USERNAME(S)
+
+passes/cmds/scratchpad.cc @nakengelhardt
+frontends/rpc/ @whitequark
+backends/cxxrtl/ @whitequark
+passes/cmds/bugpoint.cc @whitequark
+passes/techmap/flowmap.cc @whitequark
+passes/opt/opt_lut.cc @whitequark
+
+
+## External Contributors
+# Only users with write permission to the repository get review
+# requests automatically, but we add information for other
+# contributors here too, so we know who to ask to take a look.
+# These still override previous lines, so be careful not to
+# accidentally disable any of the above rules.
+
+techlibs/intel_alm/ @ZirconiumX
+
+# pyosys
+misc/*.py @btut
+
+backends/firrtl @ucbjrl @azidar
+
+passes/sat/qbfsat.cc @boqwxp
+passes/cmds/exec.cc @boqwxp
+passes/cmds/printattrs.cc @boqwxp
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index 6b910eecd..8bbadbc91 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -85,7 +85,7 @@ struct XAigerWriter
dict<SigBit, SigBit> not_map, alias_map;
dict<SigBit, pair<SigBit, SigBit>> and_map;
vector<SigBit> ci_bits, co_bits;
- dict<SigBit, Cell*> ff_bits;
+ vector<Cell*> ff_list;
dict<SigBit, float> arrival_times;
vector<pair<int, int>> aig_gates;
@@ -156,7 +156,7 @@ struct XAigerWriter
// promote keep wires
for (auto wire : module->wires())
- if (wire->get_bool_attribute(ID::keep))
+ if (wire->get_bool_attribute(ID::keep) || wire->get_bool_attribute(ID::abc9_keep))
sigmap.add(wire);
for (auto wire : module->wires()) {
@@ -232,8 +232,7 @@ struct XAigerWriter
unused_bits.erase(D);
undriven_bits.erase(Q);
alias_map[Q] = D;
- auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
- log_assert(r.second);
+ ff_list.emplace_back(cell);
continue;
}
@@ -420,8 +419,7 @@ struct XAigerWriter
aig_map[bit] = 2*aig_m;
}
- for (const auto &i : ff_bits) {
- const Cell *cell = i.second;
+ for (auto cell : ff_list) {
const SigBit &q = sigmap(cell->getPort(ID::Q));
aig_m++, aig_i++;
log_assert(!aig_map.count(q));
@@ -468,8 +466,8 @@ struct XAigerWriter
aig_outputs.push_back(aig);
}
- for (auto &i : ff_bits) {
- const SigBit &d = i.first;
+ for (auto cell : ff_list) {
+ const SigBit &d = sigmap(cell->getPort(ID::D));
aig_o++;
aig_outputs.push_back(aig_map.at(d));
}
@@ -541,16 +539,16 @@ struct XAigerWriter
std::stringstream h_buffer;
auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1);
write_h_buffer(1);
- log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ff_bits) + GetSize(ci_bits));
- write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size());
- log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(ff_bits) + GetSize(co_bits));
- write_h_buffer(output_bits.size() + GetSize(ff_bits) + GetSize(co_bits));
- log_debug("piNum = %d\n", GetSize(input_bits) + GetSize(ff_bits));
- write_h_buffer(input_bits.size() + ff_bits.size());
- log_debug("poNum = %d\n", GetSize(output_bits) + GetSize(ff_bits));
- write_h_buffer(output_bits.size() + ff_bits.size());
+ log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ff_list) + GetSize(ci_bits));
+ write_h_buffer(GetSize(input_bits) + GetSize(ff_list) + GetSize(ci_bits));
+ log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(ff_list) + GetSize(co_bits));
+ write_h_buffer(GetSize(output_bits) + GetSize(ff_list) + GetSize(co_bits));
+ log_debug("piNum = %d\n", GetSize(input_bits) + GetSize(ff_list));
+ write_h_buffer(GetSize(input_bits) + GetSize(ff_list));
+ log_debug("poNum = %d\n", GetSize(output_bits) + GetSize(ff_list));
+ write_h_buffer(GetSize(output_bits) + GetSize(ff_list));
log_debug("boxNum = %d\n", GetSize(box_list));
- write_h_buffer(box_list.size());
+ write_h_buffer(GetSize(box_list));
auto write_buffer_float = [](std::stringstream &buffer, float f32) {
buffer.write(reinterpret_cast<const char*>(&f32), sizeof(f32));
@@ -564,7 +562,7 @@ struct XAigerWriter
//for (auto bit : output_bits)
// write_o_buffer(0);
- if (!box_list.empty() || !ff_bits.empty()) {
+ if (!box_list.empty() || !ff_list.empty()) {
dict<IdString, std::tuple<int,int,int>> cell_cache;
int box_count = 0;
@@ -601,17 +599,17 @@ struct XAigerWriter
std::stringstream r_buffer;
auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1);
- log_debug("flopNum = %d\n", GetSize(ff_bits));
- write_r_buffer(ff_bits.size());
+ log_debug("flopNum = %d\n", GetSize(ff_list));
+ write_r_buffer(ff_list.size());
std::stringstream s_buffer;
auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1);
- write_s_buffer(ff_bits.size());
+ write_s_buffer(ff_list.size());
dict<SigSpec, int> clk_to_mergeability;
- for (const auto &i : ff_bits) {
- const SigBit &d = i.first;
- const Cell *cell = i.second;
+ for (const auto cell : ff_list) {
+ const SigBit &d = sigmap(cell->getPort(ID::D));
+ const SigBit &q = sigmap(cell->getPort(ID::Q));
SigSpec clk_and_pol{sigmap(cell->getPort(ID::C)), cell->type[6] == 'P' ? State::S1 : State::S0};
auto r = clk_to_mergeability.insert(std::make_pair(clk_and_pol, clk_to_mergeability.size()+1));
@@ -619,8 +617,7 @@ struct XAigerWriter
log_assert(mergeability > 0);
write_r_buffer(mergeability);
- SigBit Q = sigmap(cell->getPort(ID::Q));
- State init = init_map.at(Q, State::Sx);
+ State init = init_map.at(q, State::Sx);
log_debug("Cell '%s' (type %s) has (* init *) value '%s'.\n", log_id(cell), log_id(cell->type), log_signal(init));
if (init == State::S1)
write_s_buffer(1);
@@ -700,8 +697,6 @@ struct XAigerWriter
for (auto wire : module->wires())
{
- SigSpec sig = sigmap(wire);
-
for (int i = 0; i < GetSize(wire); i++)
{
RTLIL::SigBit b(wire, i);
@@ -714,7 +709,6 @@ struct XAigerWriter
if (output_bits.count(b)) {
int o = ordered_outputs.at(b);
output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), wire->start_offset+i, log_id(wire));
- continue;
}
}
}
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index 2816d3246..bbdcfb70a 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -40,6 +40,7 @@ struct BtorWorker
bool verbose;
bool single_bad;
bool cover_mode;
+ bool print_internal_names;
int next_nid = 1;
int initstate_nid = -1;
@@ -78,7 +79,7 @@ struct BtorWorker
vector<string> info_lines;
dict<int, int> info_clocks;
- void btorf(const char *fmt, ...)
+ void btorf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
{
va_list ap;
va_start(ap, fmt);
@@ -86,7 +87,7 @@ struct BtorWorker
va_end(ap);
}
- void infof(const char *fmt, ...)
+ void infof(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
{
va_list ap;
va_start(ap, fmt);
@@ -98,6 +99,7 @@ struct BtorWorker
string getinfo(T *obj, bool srcsym = false)
{
string infostr = log_id(obj);
+ if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
if (obj->attributes.count(ID::src)) {
string src = obj->attributes.at(ID::src).decode_string().c_str();
if (srcsym && infostr[0] == '$') {
@@ -117,7 +119,7 @@ struct BtorWorker
infostr += " ; " + src;
}
}
- return infostr;
+ return " " + infostr;
}
void btorf_push(const string &id)
@@ -242,7 +244,7 @@ struct BtorWorker
btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero);
nid = next_nid++;
- btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
+ btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
}
else
{
@@ -250,7 +252,7 @@ struct BtorWorker
int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
nid = next_nid++;
- btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
+ btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -291,7 +293,7 @@ struct BtorWorker
int sid = get_bv_sid(width);
int nid = next_nid++;
- btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
+ btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -317,12 +319,12 @@ struct BtorWorker
if (cell->type == ID($_ANDNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
- btorf("%d and %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
+ btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
if (cell->type == ID($_ORNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
- btorf("%d or %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
+ btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -344,13 +346,13 @@ struct BtorWorker
if (cell->type == ID($_OAI3_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
- btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
+ btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
if (cell->type == ID($_AOI3_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
- btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
+ btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -375,14 +377,14 @@ struct BtorWorker
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
- btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
+ btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
if (cell->type == ID($_AOI4_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
- btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
+ btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -414,9 +416,9 @@ struct BtorWorker
int nid = next_nid++;
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
- btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
+ btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
} else {
- btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
+ btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -447,7 +449,7 @@ struct BtorWorker
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid = next_nid++;
- btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
+ btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -488,9 +490,9 @@ struct BtorWorker
int nid = next_nid++;
if (btor_op != "not")
- btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
+ btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
else
- btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
+ btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -521,11 +523,11 @@ struct BtorWorker
if (cell->type == ID($reduce_xnor)) {
int nid2 = next_nid++;
- btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
- btorf("%d not %d %d %d\n", nid2, sid, nid);
+ btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
+ btorf("%d not %d %d\n", nid2, sid, nid);
nid = nid2;
} else {
- btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
+ btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@@ -560,9 +562,9 @@ struct BtorWorker
int tmp = nid;
nid = next_nid++;
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
- btorf("%d not %d %d %s\n", nid, sid, tmp, getinfo(cell).c_str());
+ btorf("%d not %d %d%s\n", nid, sid, tmp, getinfo(cell).c_str());
} else {
- btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
+ btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
}
add_nid_sig(nid, sig_y);
@@ -585,7 +587,7 @@ struct BtorWorker
int nid_s = get_sig_nid(sig_s.extract(i));
int nid2 = next_nid++;
if (i == GetSize(sig_s)-1)
- btorf("%d ite %d %d %d %d %s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
+ btorf("%d ite %d %d %d %d%s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
else
btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
nid = nid2;
@@ -640,7 +642,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig_q));
int nid = next_nid++;
- if (symbol.empty())
+ if (symbol.empty() || (!print_internal_names && symbol[0] == '$'))
btorf("%d state %d\n", nid, sid);
else
btorf("%d state %d %s\n", nid, sid, log_id(symbol));
@@ -1049,8 +1051,8 @@ struct BtorWorker
return nid;
}
- 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)
+ BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, bool print_internal_names, string info_filename) :
+ f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), print_internal_names(print_internal_names), info_filename(info_filename)
{
if (!info_filename.empty())
infof("name %s\n", log_id(module));
@@ -1073,7 +1075,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig));
int nid = next_nid++;
- btorf("%d input %d %s\n", nid, sid, getinfo(wire).c_str());
+ btorf("%d input %d%s\n", nid, sid, getinfo(wire).c_str());
add_nid_sig(nid, sig);
}
@@ -1097,7 +1099,7 @@ struct BtorWorker
btorf_push(stringf("output %s", log_id(wire)));
int nid = get_sig_nid(wire);
- btorf("%d output %d %s\n", next_nid++, nid, getinfo(wire).c_str());
+ btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire).c_str());
btorf_pop(stringf("output %s", log_id(wire)));
}
@@ -1139,10 +1141,10 @@ struct BtorWorker
bad_properties.push_back(nid_en_and_not_a);
} else {
if (cover_mode) {
- infof("bad %d %s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
+ infof("bad %d%s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
} else {
int nid = next_nid++;
- btorf("%d bad %d %s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
+ btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
}
}
@@ -1164,7 +1166,7 @@ struct BtorWorker
bad_properties.push_back(nid_en_and_a);
} else {
int nid = next_nid++;
- btorf("%d bad %d %s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
+ btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
}
btorf_pop(log_id(cell));
@@ -1185,7 +1187,7 @@ struct BtorWorker
continue;
int this_nid = next_nid++;
- btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
+ btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
btorf_pop(stringf("wire %s", log_id(wire)));
continue;
@@ -1256,14 +1258,14 @@ struct BtorWorker
}
int nid2 = next_nid++;
- btorf("%d next %d %d %d %s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str());
+ btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str());
}
else
{
SigSpec sig = sigmap(cell->getPort(ID::D));
int nid_q = get_sig_nid(sig);
int sid = get_bv_sid(GetSize(sig));
- btorf("%d next %d %d %d %s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
+ btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
}
btorf_pop(stringf("next %s", log_id(cell)));
@@ -1353,10 +1355,13 @@ struct BtorBackend : public Backend {
log(" -i <filename>\n");
log(" Create additional info file with auxiliary information\n");
log("\n");
+ log(" -n\n");
+ log(" Don't identify internal netnames\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, cover_mode = false;
+ bool verbose = false, single_bad = false, cover_mode = false, print_internal_names = true;
string info_filename;
log_header(design, "Executing BTOR backend.\n");
@@ -1380,6 +1385,10 @@ struct BtorBackend : public Backend {
info_filename = args[++argidx];
continue;
}
+ if (args[argidx] == "-n") {
+ print_internal_names = false;
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
@@ -1392,7 +1401,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, cover_mode, info_filename);
+ BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename);
*f << stringf("; end of yosys output\n");
}
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index 6e3882d2d..3a418de3c 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -131,6 +131,8 @@ void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::
f << stringf("output %d ", wire->port_id);
if (wire->port_input && wire->port_output)
f << stringf("inout %d ", wire->port_id);
+ if (wire->is_signed)
+ f << stringf("signed ");
f << stringf("%s\n", wire->name.c_str());
}
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 1a8b757ef..5edc50f60 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -160,6 +160,8 @@ struct JsonWriter
f << stringf(" \"offset\": %d,\n", w->start_offset);
if (w->upto)
f << stringf(" \"upto\": 1,\n");
+ if (w->is_signed)
+ f << stringf(" \"signed\": %d,\n", w->is_signed);
f << stringf(" \"bits\": %s\n", get_bits(w).c_str());
f << stringf(" }");
first = false;
@@ -227,6 +229,8 @@ struct JsonWriter
f << stringf(" \"offset\": %d,\n", w->start_offset);
if (w->upto)
f << stringf(" \"upto\": 1,\n");
+ if (w->is_signed)
+ f << stringf(" \"signed\": %d,\n", w->is_signed);
f << stringf(" \"attributes\": {");
write_parameters(w->attributes);
f << stringf("\n }\n");
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index cc3ebb129..03f001bfd 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -1557,8 +1557,9 @@ else: # not tempind, covermode
smt_assert(get_constr_expr(constr_asserts, i))
print_msg("Solving for step %d.." % (last_check_step))
- if smt_check_sat() != "sat":
- print("%s No solution found!" % smt.timestamp())
+ status = smt_check_sat()
+ if status != "sat":
+ print("%s No solution found! (%s)" % (smt.timestamp(), status))
retstatus = "FAILED"
break
diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py
index 62dfe7c11..9f7c8c6d9 100644
--- a/backends/smt2/smtio.py
+++ b/backends/smt2/smtio.py
@@ -121,6 +121,7 @@ class SmtIo:
self.logic_bv = True
self.logic_dt = False
self.forall = False
+ self.timeout = 0
self.produce_models = True
self.smt2cache = [list()]
self.p = None
@@ -135,6 +136,7 @@ class SmtIo:
self.debug_file = opts.debug_file
self.dummy_file = opts.dummy_file
self.timeinfo = opts.timeinfo
+ self.timeout = opts.timeout
self.unroll = opts.unroll
self.noincr = opts.noincr
self.info_stmts = opts.info_stmts
@@ -147,6 +149,7 @@ class SmtIo:
self.debug_file = None
self.dummy_file = None
self.timeinfo = os.name != "nt"
+ self.timeout = 0
self.unroll = False
self.noincr = False
self.info_stmts = list()
@@ -176,18 +179,28 @@ class SmtIo:
self.popen_vargs = ['yices-smt2'] + self.solver_opts
else:
self.popen_vargs = ['yices-smt2', '--incremental'] + self.solver_opts
+ if self.timeout != 0:
+ self.popen_vargs.append('-t')
+ self.popen_vargs.append('%d' % self.timeout);
if self.solver == "z3":
self.popen_vargs = ['z3', '-smt2', '-in'] + self.solver_opts
+ if self.timeout != 0:
+ self.popen_vargs.append('-T:%d' % self.timeout);
if self.solver == "cvc4":
if self.noincr:
self.popen_vargs = ['cvc4', '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts
else:
self.popen_vargs = ['cvc4', '--incremental', '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts
+ if self.timeout != 0:
+ self.popen_vargs.append('--tlimit=%d000' % self.timeout);
if self.solver == "mathsat":
self.popen_vargs = ['mathsat'] + self.solver_opts
+ if self.timeout != 0:
+ print('timeout option is not supported for mathsat.')
+ sys.exit(1)
if self.solver == "boolector":
if self.noincr:
@@ -195,6 +208,9 @@ class SmtIo:
else:
self.popen_vargs = ['boolector', '--smt2', '-i'] + self.solver_opts
self.unroll = True
+ if self.timeout != 0:
+ print('timeout option is not supported for boolector.')
+ sys.exit(1)
if self.solver == "abc":
if len(self.solver_opts) > 0:
@@ -204,6 +220,9 @@ class SmtIo:
self.logic_ax = False
self.unroll = True
self.noincr = True
+ if self.timeout != 0:
+ print('timeout option is not supported for abc.')
+ sys.exit(1)
if self.solver == "dummy":
assert self.dummy_file is not None
@@ -710,7 +729,7 @@ class SmtIo:
if self.forall:
result = self.read()
- while result not in ["sat", "unsat", "unknown"]:
+ while result not in ["sat", "unsat", "unknown", "timeout", "interrupted", ""]:
print("%s %s: %s" % (self.timestamp(), self.solver, result))
result = self.read()
else:
@@ -721,7 +740,7 @@ class SmtIo:
print("(check-sat)", file=self.debug_file)
self.debug_file.flush()
- if result not in ["sat", "unsat"]:
+ if result not in ["sat", "unsat", "unknown", "timeout", "interrupted"]:
if result == "":
print("%s Unexpected EOF response from solver." % (self.timestamp()), flush=True)
else:
@@ -931,7 +950,7 @@ class SmtIo:
class SmtOpts:
def __init__(self):
self.shortopts = "s:S:v"
- self.longopts = ["unroll", "noincr", "noprogress", "dump-smt2=", "logic=", "dummy=", "info=", "nocomments"]
+ self.longopts = ["unroll", "noincr", "noprogress", "timeout=", "dump-smt2=", "logic=", "dummy=", "info=", "nocomments"]
self.solver = "yices"
self.solver_opts = list()
self.debug_print = False
@@ -940,6 +959,7 @@ class SmtOpts:
self.unroll = False
self.noincr = False
self.timeinfo = os.name != "nt"
+ self.timeout = 0
self.logic = None
self.info_stmts = list()
self.nocomments = False
@@ -949,6 +969,8 @@ class SmtOpts:
self.solver = a
elif o == "-S":
self.solver_opts.append(a)
+ elif o == "--timeout":
+ self.timeout = int(a)
elif o == "-v":
self.debug_print = True
elif o == "--unroll":
@@ -980,6 +1002,9 @@ class SmtOpts:
-S <opt>
pass <opt> as command line argument to the solver
+ --timeout <value>
+ set the solver timeout to the specified value (in seconds).
+
--logic <smt2_logic>
use the specified SMT2 logic (e.g. QF_AUFBV)
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index d25587e48..fef788267 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -775,7 +775,6 @@ void AigerReader::post_process()
}
}
- dict<int, Wire*> mergeability_to_clock;
for (uint32_t i = 0; i < flopNum; i++) {
RTLIL::Wire *d = outputs[outputs.size() - flopNum + i];
log_assert(d);
@@ -895,7 +894,9 @@ void AigerReader::post_process()
}
else if (type == "box") {
RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
- if (cell) // ABC could have optimised this box away
+ if (!cell)
+ log_debug("Box %d (%s) no longer exists.\n", variable, log_id(escaped_s));
+ else
module->rename(cell, escaped_s);
}
else
@@ -907,6 +908,8 @@ void AigerReader::post_process()
auto name = wp.first;
int min = wp.second.first;
int max = wp.second.second;
+ if (min == 0 && max == 0)
+ continue;
RTLIL::Wire *wire = module->wire(name);
if (wire)
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index cdc3adc9c..78e6fe5e0 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1065,6 +1065,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->port_input = is_input;
wire->port_output = is_output;
wire->upto = range_swapped;
+ wire->is_signed = is_signed;
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index 118f13de9..879ef4af9 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -192,6 +192,9 @@ wire_options:
wire_options TOK_UPTO {
current_wire->upto = true;
} |
+ wire_options TOK_SIGNED {
+ current_wire->is_signed = true;
+ } |
wire_options TOK_OFFSET TOK_INT {
current_wire->start_offset = $3;
} |
diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc
index 7aceffbfc..8ae7c6578 100644
--- a/frontends/json/jsonparse.cc
+++ b/frontends/json/jsonparse.cc
@@ -309,6 +309,12 @@ void json_import(Design *design, string &modname, JsonNode *node)
port_wire->upto = val->data_number != 0;
}
+ if (port_node->data_dict.count("signed") != 0) {
+ JsonNode *val = port_node->data_dict.at("signed");
+ if (val->type == 'N')
+ port_wire->is_signed = val->data_number != 0;
+ }
+
if (port_node->data_dict.count("offset") != 0) {
JsonNode *val = port_node->data_dict.at("offset");
if (val->type == 'N')
@@ -573,4 +579,3 @@ struct JsonFrontend : public Frontend {
} JsonFrontend;
YOSYS_NAMESPACE_END
-
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index fe4bda68e..cb0368fd5 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -974,6 +974,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
module->memories[memory->name] = memory;
int number_of_bits = net->Size();
+ number_of_bits = 1 << ceil_log2(number_of_bits);
int bits_in_word = number_of_bits;
FOREACH_PORTREF_OF_NET(net, si, pr) {
if (pr->GetInst()->Type() == OPER_READ_PORT) {
@@ -1265,9 +1266,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->OutputSize()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->OutputSize()) || (numchunks & (numchunks - 1)) != 0)
- log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
-
for (int i = 0; i < numchunks; i++)
{
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
@@ -1295,9 +1293,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->Input2Size()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->Input2Size()) || (numchunks & (numchunks - 1)) != 0)
- log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetOutput()->Name());
-
for (int i = 0; i < numchunks; i++)
{
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
diff --git a/kernel/constids.inc b/kernel/constids.inc
index 93c3a7609..383d7c615 100644
--- a/kernel/constids.inc
+++ b/kernel/constids.inc
@@ -171,6 +171,7 @@ X(techmap_autopurge)
X(_TECHMAP_BITS_CONNMAP_)
X(_TECHMAP_CELLTYPE_)
X(techmap_celltype)
+X(_TECHMAP_FAIL_)
X(techmap_maccmap)
X(_TECHMAP_REPLACE_)
X(techmap_simplemap)
diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index 592d6e577..5c87b55f5 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -207,6 +207,7 @@ class dict
entry_t() { }
entry_t(const std::pair<K, T> &udata, int next) : udata(udata), next(next) { }
entry_t(std::pair<K, T> &&udata, int next) : udata(std::move(udata)), next(next) { }
+ bool operator<(const entry_t &other) const { return udata.first < other.udata.first; }
};
std::vector<int> hashtable;
@@ -615,6 +616,15 @@ public:
return !operator==(other);
}
+ unsigned int hash() const {
+ unsigned int h = mkhash_init;
+ for (auto &entry : entries) {
+ h ^= hash_ops<K>::hash(entry.udata.first);
+ h ^= hash_ops<T>::hash(entry.udata.second);
+ }
+ return h;
+ }
+
void reserve(size_t n) { entries.reserve(n); }
size_t size() const { return entries.size(); }
bool empty() const { return entries.empty(); }
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index ca4201b53..397edc4e7 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1862,6 +1862,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth
wire->port_input = other->port_input;
wire->port_output = other->port_output;
wire->upto = other->upto;
+ wire->is_signed = other->is_signed;
wire->attributes = other->attributes;
return wire;
}
@@ -2447,6 +2448,7 @@ RTLIL::Wire::Wire()
port_input = false;
port_output = false;
upto = false;
+ is_signed = false;
#ifdef WITH_PYTHON
RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 8228523d5..51e573e76 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -1236,13 +1236,10 @@ public:
RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
- RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
- RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
- RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
- RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
@@ -1371,7 +1368,7 @@ public:
RTLIL::Module *module;
RTLIL::IdString name;
int width, start_offset, port_id;
- bool port_input, port_output, upto;
+ bool port_input, port_output, upto, is_signed;
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py
index fac5b48a4..fa23e3b2c 100644
--- a/misc/py_wrap_generator.py
+++ b/misc/py_wrap_generator.py
@@ -312,16 +312,16 @@ class PythonListTranslator(Translator):
text += prefix + "\t" + known_containers[types[0].name].typename + " " + tmp_name + " = boost::python::extract<" + known_containers[types[0].name].typename + ">(" + varname + "[" + cntr_name + "]);"
text += known_containers[types[0].name].translate(tmp_name, types[0].cont.args, prefix+"\t")
tmp_name = tmp_name + "___tmp"
- text += prefix + "\t" + varname + "___tmp." + c.insert_name + "(" + tmp_name + ");"
+ text += prefix + "\t" + varname + "___tmp" + c.insert_name + "(" + tmp_name + ");"
elif types[0].name in classnames:
text += prefix + "\t" + types[0].name + "* " + tmp_name + " = boost::python::extract<" + types[0].name + "*>(" + varname + "[" + cntr_name + "]);"
if types[0].attr_type == attr_types.star:
- text += prefix + "\t" + varname + "___tmp." + c.insert_name + "(" + tmp_name + "->get_cpp_obj());"
+ text += prefix + "\t" + varname + "___tmp" + c.insert_name + "(" + tmp_name + "->get_cpp_obj());"
else:
- text += prefix + "\t" + varname + "___tmp." + c.insert_name + "(*" + tmp_name + "->get_cpp_obj());"
+ text += prefix + "\t" + varname + "___tmp" + c.insert_name + "(*" + tmp_name + "->get_cpp_obj());"
else:
text += prefix + "\t" + types[0].name + " " + tmp_name + " = boost::python::extract<" + types[0].name + ">(" + varname + "[" + cntr_name + "]);"
- text += prefix + "\t" + varname + "___tmp." + c.insert_name + "(" + tmp_name + ");"
+ text += prefix + "\t" + varname + "___tmp" + c.insert_name + "(" + tmp_name + ");"
text += prefix + "}"
return text
@@ -349,19 +349,24 @@ class PythonListTranslator(Translator):
text += prefix + "}"
return text
+class IDictTranslator(PythonListTranslator):
+ typename = "boost::python::list"
+ orig_name = "idict"
+ insert_name = ""
+
#Sub-type for std::set
class SetTranslator(PythonListTranslator):
- insert_name = "insert"
+ insert_name = ".insert"
orig_name = "std::set"
#Sub-type for std::vector
class VectorTranslator(PythonListTranslator):
- insert_name = "push_back"
+ insert_name = ".push_back"
orig_name = "std::vector"
#Sub-type for pool
class PoolTranslator(PythonListTranslator):
- insert_name = "insert"
+ insert_name = ".insert"
orig_name = "pool"
#Translates dict-types (dict, std::map), that only differ in their name and
@@ -528,6 +533,7 @@ known_containers = {
"std::set" : SetTranslator,
"std::vector" : VectorTranslator,
"pool" : PoolTranslator,
+ "idict" : IDictTranslator,
"dict" : DictTranslator,
"std::pair" : TupleTranslator,
"std::map" : MapTranslator
diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc
index 5c0405f15..b8297cd77 100644
--- a/passes/cmds/blackbox.cc
+++ b/passes/cmds/blackbox.cc
@@ -48,31 +48,7 @@ struct BlackboxPass : public Pass {
for (auto module : design->selected_whole_modules_warn())
{
- pool<Cell*> remove_cells;
- pool<Wire*> remove_wires;
-
- for (auto cell : module->cells())
- remove_cells.insert(cell);
-
- for (auto wire : module->wires())
- if (wire->port_id == 0)
- remove_wires.insert(wire);
-
- for (auto it = module->memories.begin(); it != module->memories.end(); ++it)
- delete it->second;
- module->memories.clear();
-
- for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
- delete it->second;
- module->processes.clear();
-
- module->new_connections(std::vector<RTLIL::SigSig>());
-
- for (auto cell : remove_cells)
- module->remove(cell);
-
- module->remove(remove_wires);
-
+ module->makeblackbox();
module->set_bool_attribute(ID::blackbox);
}
}
diff --git a/passes/sat/qbfsat.cc b/passes/sat/qbfsat.cc
index 712a46cbc..d6dbf8ef4 100644
--- a/passes/sat/qbfsat.cc
+++ b/passes/sat/qbfsat.cc
@@ -42,6 +42,7 @@ struct QbfSolveOptions {
bool nooptimize, nobisection;
bool sat, unsat, show_smtbmc;
enum Solver{Z3, Yices, CVC4} solver;
+ int timeout;
std::string specialize_soln_file;
std::string write_soln_soln_file;
std::string dump_final_smt2_file;
@@ -49,7 +50,7 @@ struct QbfSolveOptions {
QbfSolveOptions() : specialize(false), specialize_from_file(false), write_solution(false),
nocleanup(false), dump_final_smt2(false), assume_outputs(false), assume_neg(false),
nooptimize(false), nobisection(false), sat(false), unsat(false), show_smtbmc(false),
- solver(Yices), argidx(0) {};
+ solver(Yices), timeout(0), argidx(0) {};
};
std::string get_solver_name(const QbfSolveOptions &opt) {
@@ -67,6 +68,11 @@ std::string get_solver_name(const QbfSolveOptions &opt) {
void recover_solution(QbfSolutionType &sol) {
YS_REGEX_TYPE sat_regex = YS_REGEX_COMPILE("Status: PASSED");
YS_REGEX_TYPE unsat_regex = YS_REGEX_COMPILE("Solver Error.*model is not available");
+ YS_REGEX_TYPE unsat_regex2 = YS_REGEX_COMPILE("Status: FAILED");
+ YS_REGEX_TYPE timeout_regex = YS_REGEX_COMPILE("No solution found! \\(timeout\\)");
+ YS_REGEX_TYPE timeout_regex2 = YS_REGEX_COMPILE("No solution found! \\(interrupted\\)");
+ YS_REGEX_TYPE unknown_regex = YS_REGEX_COMPILE("No solution found! \\(unknown\\)");
+ YS_REGEX_TYPE unknown_regex2 = YS_REGEX_COMPILE("Unexpected EOF response from solver");
YS_REGEX_TYPE memout_regex = YS_REGEX_COMPILE("Solver Error:.*error \"out of memory\"");
YS_REGEX_TYPE hole_value_regex = YS_REGEX_COMPILE_WITH_SUBS("Value for anyconst in [a-zA-Z0-9_]* \\(([^:]*:[^\\)]*)\\): (.*)");
#ifndef NDEBUG
@@ -87,14 +93,40 @@ void recover_solution(QbfSolutionType &sol) {
#endif
sol.hole_to_value[loc] = val;
}
- else if (YS_REGEX_NS::regex_search(x, sat_regex))
+ else if (YS_REGEX_NS::regex_search(x, sat_regex)) {
sat_regex_found = true;
- else if (YS_REGEX_NS::regex_search(x, unsat_regex))
+ sol.sat = true;
+ sol.unknown = false;
+ }
+ else if (YS_REGEX_NS::regex_search(x, unsat_regex)) {
unsat_regex_found = true;
+ sol.sat = false;
+ sol.unknown = false;
+ }
else if (YS_REGEX_NS::regex_search(x, memout_regex)) {
sol.unknown = true;
log_warning("solver ran out of memory\n");
}
+ else if (YS_REGEX_NS::regex_search(x, timeout_regex)) {
+ sol.unknown = true;
+ log_warning("solver timed out\n");
+ }
+ else if (YS_REGEX_NS::regex_search(x, timeout_regex2)) {
+ sol.unknown = true;
+ log_warning("solver timed out\n");
+ }
+ else if (YS_REGEX_NS::regex_search(x, unknown_regex)) {
+ sol.unknown = true;
+ log_warning("solver returned \"unknown\"\n");
+ }
+ else if (YS_REGEX_NS::regex_search(x, unsat_regex2)) {
+ unsat_regex_found = true;
+ sol.sat = false;
+ sol.unknown = false;
+ }
+ else if (YS_REGEX_NS::regex_search(x, unknown_regex2)) {
+ sol.unknown = true;
+ }
}
#ifndef NDEBUG
log_assert(!sol.unknown && sol.sat? sat_regex_found : true);
@@ -329,7 +361,7 @@ QbfSolutionType call_qbf_solver(RTLIL::Module *mod, const QbfSolveOptions &opt,
const std::string yosys_smtbmc_exe = proc_self_dirname() + "yosys-smtbmc";
const std::string smt2_command = "write_smt2 -stbv -wires " + tempdir_name + "/problem" + (iter_num != 0? stringf("%d", iter_num) : "") + ".smt2";
const std::string smtbmc_warning = "z3: WARNING:";
- const std::string smtbmc_cmd = yosys_smtbmc_exe + " -s " + (get_solver_name(opt)) + " -t 1 -g --binary " + (opt.dump_final_smt2? "--dump-smt2 " + opt.dump_final_smt2_file + " " : "") + tempdir_name + "/problem" + (iter_num != 0? stringf("%d", iter_num) : "") + ".smt2 2>&1";
+ const std::string smtbmc_cmd = yosys_smtbmc_exe + " -s " + (get_solver_name(opt)) + (opt.timeout != 0? stringf(" --timeout %d", opt.timeout) : "") + " -t 1 -g --binary " + (opt.dump_final_smt2? "--dump-smt2 " + opt.dump_final_smt2_file + " " : "") + tempdir_name + "/problem" + (iter_num != 0? stringf("%d", iter_num) : "") + ".smt2 2>&1";
Pass::call(mod->design, smt2_command);
@@ -344,14 +376,7 @@ QbfSolutionType call_qbf_solver(RTLIL::Module *mod, const QbfSolveOptions &opt,
};
log_header(mod->design, "Solving QBF-SAT problem.\n");
if (!quiet) log("Launching \"%s\".\n", smtbmc_cmd.c_str());
- int retval = run_command(smtbmc_cmd, process_line);
- if (retval == 0) {
- ret.sat = true;
- ret.unknown = false;
- } else if (retval == 1) {
- ret.sat = false;
- ret.unknown = false;
- }
+ run_command(smtbmc_cmd, process_line);
recover_solution(ret);
return ret;
@@ -514,6 +539,19 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) {
}
continue;
}
+ else if (args[opt.argidx] == "-timeout") {
+ if (args.size() <= opt.argidx + 1)
+ log_cmd_error("timeout not specified.\n");
+ else {
+ int timeout = atoi(args[opt.argidx+1].c_str());
+ if (timeout > 0)
+ opt.timeout = timeout;
+ else
+ log_cmd_error("timeout must be greater than 0.\n");
+ opt.argidx++;
+ }
+ continue;
+ }
else if (args[opt.argidx] == "-sat") {
opt.sat = true;
continue;
@@ -625,6 +663,9 @@ struct QbfSatPass : public Pass {
log(" -solver <solver>\n");
log(" Use a particular solver. Choose one of: \"z3\", \"yices\", and \"cvc4\".\n");
log("\n");
+ log(" -timeout <value>\n");
+ log(" Set the per-iteration timeout in seconds.\n");
+ log("\n");
log(" -sat\n");
log(" Generate an error if the solver does not return \"sat\".\n");
log("\n");
@@ -672,7 +713,6 @@ struct QbfSatPass : public Pass {
QbfSolutionType ret = qbf_solve(module, opt);
module = design->module(module_name);
if (ret.unknown) {
- log_warning("solver did not give an answer\n");
if (opt.sat || opt.unsat)
log_cmd_error("expected problem to be %s\n", opt.sat? "SAT" : "UNSAT");
}
diff --git a/passes/techmap/.gitignore b/passes/techmap/.gitignore
deleted file mode 100644
index e6dcc6bc0..000000000
--- a/passes/techmap/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-techmap.inc
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc
index 1802ba0de..873286608 100644
--- a/passes/techmap/Makefile.inc
+++ b/passes/techmap/Makefile.inc
@@ -45,18 +45,6 @@ OBJS += passes/techmap/flowmap.o
OBJS += passes/techmap/extractinv.o
endif
-GENFILES += passes/techmap/techmap.inc
-
-passes/techmap/techmap.inc: techlibs/common/techmap.v
- $(Q) mkdir -p $(dir $@)
- $(P) echo "// autogenerated from $<" > $@.new
- $(Q) echo "static char stdcells_code[] = {" >> $@.new
- $(Q) od -v -td1 -An $< | $(SED) -e 's/[0-9][0-9]*/&,/g' >> $@.new
- $(Q) echo "0};" >> $@.new
- $(Q) mv $@.new $@
-
-passes/techmap/techmap.o: passes/techmap/techmap.inc
-
ifeq ($(DISABLE_SPAWN),0)
TARGETS += $(PROGRAM_PREFIX)yosys-filterlib$(EXE)
EXTRA_OBJS += passes/techmap/filterlib.o
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index 8d55b18a0..873c37b9a 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -102,8 +102,6 @@ void check(RTLIL::Design *design, bool dff_mode)
auto inst_module = design->module(cell->type);
if (!inst_module)
continue;
- if (!inst_module->get_blackbox_attribute())
- continue;
IdString derived_type;
Module *derived_module;
if (cell->parameters.empty()) {
@@ -111,6 +109,10 @@ void check(RTLIL::Design *design, bool dff_mode)
derived_module = inst_module;
}
else {
+ // Check potential (since its value may depend on a parameter,
+ // but not its existence)
+ if (!inst_module->has_attribute(ID::abc9_flop))
+ continue;
derived_type = inst_module->derive(design, cell->parameters);
derived_module = design->module(derived_type);
log_assert(derived_module);
@@ -127,20 +129,20 @@ void check(RTLIL::Design *design, bool dff_mode)
for (auto derived_cell : derived_module->cells()) {
if (derived_cell->type.in(ID($dff), ID($_DFF_N_), ID($_DFF_P_))) {
if (found)
- log_error("Module '%s' with (* abc9_flop *) contains more than one $_DFF_[NP]_ cell.\n", log_id(derived_module));
+ log_error("Whitebox '%s' with (* abc9_flop *) contains more than one $_DFF_[NP]_ cell.\n", log_id(derived_module));
found = true;
SigBit Q = derived_cell->getPort(ID::Q);
log_assert(GetSize(Q.wire) == 1);
if (!Q.wire->port_output)
- log_error("Module '%s' contains a %s cell where its 'Q' port does not drive a module output!\n", log_id(derived_module), log_id(derived_cell->type));
+ log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell where its 'Q' port does not drive a module output.\n", log_id(derived_module), log_id(derived_cell->type));
Const init = Q.wire->attributes.at(ID::init, State::Sx);
log_assert(GetSize(init) == 1);
}
else if (unsupported.count(derived_cell->type))
- log_error("Module '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", log_id(derived_module), log_id(derived_cell->type));
+ log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", log_id(derived_module), log_id(derived_cell->type));
}
}
}
@@ -173,8 +175,6 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
auto inst_module = design->module(cell->type);
if (!inst_module)
continue;
- if (!inst_module->get_blackbox_attribute())
- continue;
IdString derived_type;
Module *derived_module;
if (cell->parameters.empty()) {
@@ -182,6 +182,10 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
derived_module = inst_module;
}
else {
+ // Check potential for any one of those three
+ // (since its value may depend on a parameter, but not its existence)
+ if (!inst_module->has_attribute(ID::abc9_flop) && !inst_module->has_attribute(ID::abc9_box) && !inst_module->get_bool_attribute(ID::abc9_bypass))
+ continue;
derived_type = inst_module->derive(design, cell->parameters);
derived_module = design->module(derived_type);
}
@@ -211,7 +215,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
// Block sequential synthesis on cells with (* init *) != 1'b0
// because ABC9 doesn't support them
if (init != State::S0) {
- log_warning("Module '%s' contains a %s cell with non-zero initial state -- this is not unsupported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(derived_module), log_id(derived_cell->type));
+ log_warning("Whitebox '%s' with (* abc9_flop *) contains a %s cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(derived_module), log_id(derived_cell->type));
derived_module->set_bool_attribute(ID::abc9_flop, false);
}
break;
@@ -232,10 +236,8 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
auto w = unmap_module->addWire(port, derived_module->wire(port));
// Do not propagate (* init *) values into the box,
// in fact, remove it from outside too
- if (w->port_output && w->attributes.erase(ID::init)) {
- auto r = unmap_module->addWire(stringf("\\_TECHMAP_REMOVEINIT_%s_", log_id(port)));
- unmap_module->connect(r, State::S1);
- }
+ if (w->port_output)
+ w->attributes.erase(ID::init);
}
unmap_module->ports = derived_module->ports;
unmap_module->check();
@@ -719,8 +721,10 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
bit_users[bit].insert(cell->name);
if (cell->output(conn.first) && !abc9_flop)
- for (auto bit : sigmap(conn.second))
- bit_drivers[bit].insert(cell->name);
+ for (const auto &chunk : conn.second.chunks())
+ if (!chunk.wire->get_bool_attribute(ID::abc9_keep))
+ for (auto b : sigmap(SigSpec(chunk)))
+ bit_drivers[b].insert(cell->name);
}
toposort.node(cell->name);
}
@@ -1110,7 +1114,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
for (auto w : mapped_mod->wires()) {
auto nw = module->addWire(remap_name(w->name), GetSize(w));
nw->start_offset = w->start_offset;
- // Remove all (* init *) since they only existon $_DFF_[NP]_
+ // Remove all (* init *) since they only exist on $_DFF_[NP]_
w->attributes.erase(ID::init);
}
@@ -1147,16 +1151,36 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
}
}
+ SigMap initmap;
+ if (dff_mode) {
+ // Build a sigmap prioritising bits with (* init *)
+ initmap.set(module);
+ for (auto w : module->wires()) {
+ auto it = w->attributes.find(ID::init);
+ if (it == w->attributes.end())
+ continue;
+ for (auto i = 0; i < GetSize(w); i++)
+ if (it->second[i] == State::S0 || it->second[i] == State::S1)
+ initmap.add(w);
+ }
+ }
+
std::vector<Cell*> boxes;
for (auto cell : module->cells().to_vector()) {
if (cell->has_keep_attr())
continue;
- // Short out $_DFF_[NP]_ cells since the flop box already has
- // all the information we need to reconstruct cell
+ // Short out (so that existing name can be preserved) and remove
+ // $_DFF_[NP]_ cells since flop box already has all the information
+ // we need to reconstruct them
if (dff_mode && cell->type.in(ID($_DFF_N_), ID($_DFF_P_)) && !cell->get_bool_attribute(ID::abc9_keep)) {
- module->connect(cell->getPort(ID::Q), cell->getPort(ID::D));
+ SigBit Q = cell->getPort(ID::Q);
+ module->connect(Q, cell->getPort(ID::D));
module->remove(cell);
+ auto Qi = initmap(Q);
+ auto it = Qi.wire->attributes.find(ID::init);
+ if (it != Qi.wire->attributes.end())
+ it->second[Qi.offset] = State::Sx;
}
else if (cell->type.in(ID($_AND_), ID($_NOT_)))
module->remove(cell);
@@ -1299,7 +1323,25 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
mapped_cell->connections_.erase(jt);
auto abc9_flop = box_module->get_bool_attribute(ID::abc9_flop);
- if (!abc9_flop) {
+ if (abc9_flop) {
+ // Link this sole flop box output to the output of the existing
+ // flop box, so that any (public) signal it drives will be
+ // preserved
+ SigBit old_q;
+ for (const auto &port_name : box_ports.at(existing_cell->type)) {
+ RTLIL::Wire *w = box_module->wire(port_name);
+ log_assert(w);
+ if (!w->port_output)
+ continue;
+ log_assert(old_q == SigBit());
+ log_assert(GetSize(w) == 1);
+ old_q = existing_cell->getPort(port_name);
+ }
+ auto new_q = outputs[0];
+ new_q.wire = module->wires_.at(remap_name(new_q.wire->name));
+ module->connect(old_q, new_q);
+ }
+ else {
for (const auto &i : inputs)
bit_users[i].insert(mapped_cell->name);
for (const auto &i : outputs)
@@ -1332,11 +1374,12 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
c.wire = module->wires_.at(remap_name(c.wire->name));
newsig.append(c);
}
- cell->setPort(port_name, newsig);
if (w->port_input && !abc9_flop)
for (const auto &i : newsig)
bit2sinks[i].push_back(cell);
+
+ cell->setPort(port_name, std::move(newsig));
}
}
@@ -1398,7 +1441,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
// treated as being "free"), in particular driving primary
// outputs (real primary outputs, or cells treated as blackboxes)
// or driving box inputs.
- // Instead of just mapping those $_NOT_ gates into 2-input $lut-s
+ // Instead of just mapping those $_NOT_ gates into 1-input $lut-s
// at an area and delay cost, see if it is possible to push
// this $_NOT_ into the driving LUT, or into all sink LUTs.
// When this is not possible, (i.e. this signal drives two primary
diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc
index b65b3e972..214157a64 100644
--- a/passes/techmap/simplemap.cc
+++ b/passes/techmap/simplemap.cc
@@ -522,7 +522,7 @@ void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
}
}
-void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers)
+void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers)
{
mappers[ID($not)] = simplemap_not;
mappers[ID($pos)] = simplemap_pos;
@@ -559,7 +559,7 @@ void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL
void simplemap(RTLIL::Module *module, RTLIL::Cell *cell)
{
- static std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers;
+ static dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers;
static bool initialized_mappers = false;
if (!initialized_mappers) {
@@ -595,7 +595,7 @@ struct SimplemapPass : public Pass {
log_header(design, "Executing SIMPLEMAP pass (map simple cells to gate primitives).\n");
extra_args(args, 1, design);
- std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers;
+ dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers;
simplemap_get_mappers(mappers);
for (auto mod : design->modules()) {
diff --git a/passes/techmap/simplemap.h b/passes/techmap/simplemap.h
index c2d73ea79..5091050a1 100644
--- a/passes/techmap/simplemap.h
+++ b/passes/techmap/simplemap.h
@@ -42,7 +42,7 @@ extern void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell);
extern void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell);
extern void simplemap(RTLIL::Module *module, RTLIL::Cell *cell);
-extern void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
+extern void simplemap_get_mappers(dict<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
YOSYS_NAMESPACE_END
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index a554be257..c88f7bd0a 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -27,7 +27,6 @@
#include <string.h>
#include "simplemap.h"
-#include "passes/techmap/techmap.inc"
YOSYS_NAMESPACE_BEGIN
@@ -51,21 +50,21 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
{
vector<SigChunk> chunks = sig;
for (auto &chunk : chunks)
- if (chunk.wire != NULL) {
+ if (chunk.wire != nullptr) {
IdString wire_name = chunk.wire->name;
apply_prefix(prefix, wire_name);
- log_assert(module->wires_.count(wire_name) > 0);
- chunk.wire = module->wires_[wire_name];
+ log_assert(module->wire(wire_name) != nullptr);
+ chunk.wire = module->wire(wire_name);
}
sig = chunks;
}
struct TechmapWorker
{
- std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> simplemap_mappers;
- std::map<std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
- std::map<RTLIL::Module*, bool> techmap_do_cache;
- std::set<RTLIL::Module*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Module>> module_queue;
+ dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> simplemap_mappers;
+ dict<std::pair<IdString, dict<IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
+ dict<RTLIL::Module*, bool> techmap_do_cache;
+ pool<RTLIL::Module*> module_queue;
dict<Module*, SigMap> sigmaps;
pool<IdString> flatten_do_list;
@@ -79,31 +78,21 @@ struct TechmapWorker
RTLIL::SigSpec value;
};
- typedef std::map<std::string, std::vector<TechmapWireData>> TechmapWires;
+ typedef dict<IdString, std::vector<TechmapWireData>> TechmapWires;
- bool extern_mode;
- bool assert_mode;
- bool flatten_mode;
- bool recursive_mode;
- bool autoproc_mode;
- bool ignore_wb;
-
- TechmapWorker()
- {
- extern_mode = false;
- assert_mode = false;
- flatten_mode = false;
- recursive_mode = false;
- autoproc_mode = false;
- ignore_wb = false;
- }
+ bool extern_mode = false;
+ bool assert_mode = false;
+ bool flatten_mode = false;
+ bool recursive_mode = false;
+ bool autoproc_mode = false;
+ bool ignore_wb = false;
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
{
std::string constmap_info;
- std::map<RTLIL::SigBit, std::pair<RTLIL::IdString, int>> connbits_map;
+ dict<RTLIL::SigBit, std::pair<IdString, int>> connbits_map;
- for (auto conn : cell->connections())
+ for (auto &conn : cell->connections())
for (int i = 0; i < GetSize(conn.second); i++) {
RTLIL::SigBit bit = sigmap(conn.second[i]);
if (bit.wire == nullptr) {
@@ -117,7 +106,7 @@ struct TechmapWorker
constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i,
log_id(connbits_map.at(bit).first), connbits_map.at(bit).second);
} else {
- connbits_map[bit] = std::pair<RTLIL::IdString, int>(conn.first, i);
+ connbits_map.emplace(bit, std::make_pair(conn.first, i));
constmap_info += stringf("|%s %d", log_id(conn.first), i);
}
}
@@ -129,24 +118,25 @@ struct TechmapWorker
{
TechmapWires result;
- if (module == NULL)
+ if (module == nullptr)
return result;
- for (auto &it : module->wires_) {
- const char *p = it.first.c_str();
+ for (auto w : module->wires()) {
+ const char *p = w->name.c_str();
if (*p == '$')
continue;
const char *q = strrchr(p+1, '.');
- p = q ? q+1 : p+1;
+ if (q)
+ p = q;
- if (!strncmp(p, "_TECHMAP_", 9)) {
+ if (!strncmp(p, "\\_TECHMAP_", 10)) {
TechmapWireData record;
- record.wire = it.second;
- record.value = it.second;
+ record.wire = w;
+ record.value = w;
result[p].push_back(record);
- it.second->attributes[ID::keep] = RTLIL::Const(1);
- it.second->attributes[ID::_techmap_special_] = RTLIL::Const(1);
+ w->set_bool_attribute(ID::keep);
+ w->set_bool_attribute(ID::_techmap_special_);
}
}
@@ -165,7 +155,7 @@ struct TechmapWorker
if (tpl->processes.size() != 0) {
log("Technology map yielded processes:");
for (auto &it : tpl->processes)
- log(" %s",RTLIL::id2cstr(it.first));
+ log(" %s",log_id(it.first));
log("\n");
if (autoproc_mode) {
Pass::call_on_module(tpl->design, tpl, "proc");
@@ -179,8 +169,8 @@ struct TechmapWorker
orig_cell_name = cell->name.str();
if (!flatten_mode) {
- for (auto &it : tpl->cells_)
- if (it.first == ID::_TECHMAP_REPLACE_) {
+ for (auto tpl_cell : tpl->cells())
+ if (tpl_cell->name == ID::_TECHMAP_REPLACE_) {
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
break;
}
@@ -204,30 +194,30 @@ struct TechmapWorker
design->select(module, m);
}
- std::map<RTLIL::IdString, RTLIL::IdString> positional_ports;
+ dict<IdString, IdString> positional_ports;
dict<Wire*, IdString> temp_renamed_wires;
pool<SigBit> autopurge_tpl_bits;
- for (auto &it : tpl->wires_)
+ for (auto tpl_w : tpl->wires())
{
- if (it.second->port_id > 0)
+ if (tpl_w->port_id > 0)
{
- IdString posportname = stringf("$%d", it.second->port_id);
- positional_ports[posportname] = it.first;
+ IdString posportname = stringf("$%d", tpl_w->port_id);
+ positional_ports.emplace(posportname, tpl_w->name);
- if (!flatten_mode && it.second->get_bool_attribute(ID::techmap_autopurge) &&
- (!cell->hasPort(it.second->name) || !GetSize(cell->getPort(it.second->name))) &&
+ if (!flatten_mode && tpl_w->get_bool_attribute(ID::techmap_autopurge) &&
+ (!cell->hasPort(tpl_w->name) || !GetSize(cell->getPort(tpl_w->name))) &&
(!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname))))
{
if (sigmaps.count(tpl) == 0)
sigmaps[tpl].set(tpl);
- for (auto bit : sigmaps.at(tpl)(it.second))
+ for (auto bit : sigmaps.at(tpl)(tpl_w))
if (bit.wire != nullptr)
autopurge_tpl_bits.insert(bit);
}
}
- IdString w_name = it.second->name;
+ IdString w_name = tpl_w->name;
apply_prefix(cell->name, w_name);
RTLIL::Wire *w = module->wire(w_name);
if (w != nullptr) {
@@ -237,30 +227,30 @@ struct TechmapWorker
w = nullptr;
} else {
w->attributes.erase(ID::hierconn);
- if (GetSize(w) < GetSize(it.second)) {
+ if (GetSize(w) < GetSize(tpl_w)) {
log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w),
- log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
- w->width = GetSize(it.second);
+ log_id(tpl), log_id(tpl_w), log_id(module), log_id(cell));
+ w->width = GetSize(tpl_w);
}
}
}
if (w == nullptr) {
- w = module->addWire(w_name, it.second);
+ w = module->addWire(w_name, tpl_w);
w->port_input = false;
w->port_output = false;
w->port_id = 0;
if (!flatten_mode)
w->attributes.erase(ID::techmap_autopurge);
- if (it.second->get_bool_attribute(ID::_techmap_special_))
+ if (tpl_w->get_bool_attribute(ID::_techmap_special_))
w->attributes.clear();
if (w->attributes.count(ID::src))
w->add_strpool_attribute(ID::src, extra_src_attrs);
}
design->select(module, w);
- if (it.second->name.begins_with("\\_TECHMAP_REPLACE_.")) {
- IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), it.second->name.c_str() + strlen("\\_TECHMAP_REPLACE_"));
- Wire *replace_w = module->addWire(replace_name, it.second);
+ if (tpl_w->name.begins_with("\\_TECHMAP_REPLACE_.")) {
+ IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), tpl_w->name.c_str() + strlen("\\_TECHMAP_REPLACE_"));
+ Wire *replace_w = module->addWire(replace_name, tpl_w);
module->connect(replace_w, w);
}
}
@@ -268,24 +258,23 @@ struct TechmapWorker
SigMap tpl_sigmap(tpl);
pool<SigBit> tpl_written_bits;
- for (auto &it1 : tpl->cells_)
- for (auto &it2 : it1.second->connections_)
- if (it1.second->output(it2.first))
- for (auto bit : tpl_sigmap(it2.second))
+ for (auto tpl_cell : tpl->cells())
+ for (auto &conn : tpl_cell->connections())
+ if (tpl_cell->output(conn.first))
+ for (auto bit : tpl_sigmap(conn.second))
tpl_written_bits.insert(bit);
- for (auto &it1 : tpl->connections_)
- for (auto bit : tpl_sigmap(it1.first))
+ for (auto &conn : tpl->connections())
+ for (auto bit : tpl_sigmap(conn.first))
tpl_written_bits.insert(bit);
SigMap port_signal_map;
- SigSig port_signal_assign;
for (auto &it : cell->connections())
{
- RTLIL::IdString portname = it.first;
+ IdString portname = it.first;
if (positional_ports.count(portname) > 0)
portname = positional_ports.at(portname);
- if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) {
+ if (tpl->wire(portname) == nullptr || tpl->wire(portname)->port_id == 0) {
if (portname.begins_with("$"))
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str());
continue;
@@ -294,7 +283,7 @@ struct TechmapWorker
if (GetSize(it.second) == 0)
continue;
- RTLIL::Wire *w = tpl->wires_.at(portname);
+ RTLIL::Wire *w = tpl->wire(portname);
RTLIL::SigSig c, extra_connect;
if (w->port_output && !w->port_input) {
@@ -377,19 +366,19 @@ struct TechmapWorker
}
}
- for (auto &it : tpl->cells_)
+ for (auto tpl_cell : tpl->cells())
{
- IdString c_name = it.second->name.str();
+ IdString c_name = tpl_cell->name;
bool techmap_replace_cell = (!flatten_mode) && (c_name == ID::_TECHMAP_REPLACE_);
if (techmap_replace_cell)
c_name = orig_cell_name;
- else if (it.second->name.begins_with("\\_TECHMAP_REPLACE_."))
+ else if (tpl_cell->name.begins_with("\\_TECHMAP_REPLACE_."))
c_name = stringf("%s%s", orig_cell_name.c_str(), c_name.c_str() + strlen("\\_TECHMAP_REPLACE_"));
else
apply_prefix(cell->name, c_name);
- RTLIL::Cell *c = module->addCell(c_name, it.second);
+ RTLIL::Cell *c = module->addCell(c_name, tpl_cell);
design->select(module, c);
if (!flatten_mode && c->type.begins_with("\\$"))
@@ -397,12 +386,12 @@ struct TechmapWorker
vector<IdString> autopurge_ports;
- for (auto &it2 : c->connections_)
+ for (auto &conn : c->connections())
{
bool autopurge = false;
if (!autopurge_tpl_bits.empty()) {
- autopurge = GetSize(it2.second) != 0;
- for (auto &bit : sigmaps.at(tpl)(it2.second))
+ autopurge = GetSize(conn.second) != 0;
+ for (auto &bit : sigmaps.at(tpl)(conn.second))
if (!autopurge_tpl_bits.count(bit)) {
autopurge = false;
break;
@@ -410,10 +399,12 @@ struct TechmapWorker
}
if (autopurge) {
- autopurge_ports.push_back(it2.first);
+ autopurge_ports.push_back(conn.first);
} else {
- apply_prefix(cell->name, it2.second, module);
- port_signal_map.apply(it2.second);
+ RTLIL::SigSpec new_conn = conn.second;
+ apply_prefix(cell->name, new_conn, module);
+ port_signal_map.apply(new_conn);
+ c->setPort(conn.first, std::move(new_conn));
}
}
@@ -463,8 +454,8 @@ struct TechmapWorker
}
}
- bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set<RTLIL::Cell*> &handled_cells,
- const std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> &celltypeMap, bool in_recursion)
+ bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, pool<RTLIL::Cell*> &handled_cells,
+ const dict<IdString, pool<IdString>> &celltypeMap, bool in_recursion)
{
std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping";
@@ -489,13 +480,13 @@ struct TechmapWorker
}
}
- TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
- std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
- std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
+ TopoSort<RTLIL::Cell*, IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
+ dict<RTLIL::Cell*, pool<RTLIL::SigBit>> cell_to_inbit;
+ dict<RTLIL::SigBit, pool<RTLIL::Cell*>> outbit_to_cell;
- for (auto cell : module->cells())
+ for (auto cell : module->selected_cells())
{
- if (!design->selected(module, cell) || handled_cells.count(cell) > 0)
+ if (handled_cells.count(cell) > 0)
continue;
std::string cell_type = cell->type.str();
@@ -511,7 +502,7 @@ struct TechmapWorker
if (flatten_mode) {
bool keepit = cell->get_bool_attribute(ID::keep_hierarchy);
for (auto &tpl_name : celltypeMap.at(cell_type))
- if (map->modules_[tpl_name]->get_bool_attribute(ID::keep_hierarchy))
+ if (map->module(tpl_name)->get_bool_attribute(ID::keep_hierarchy))
keepit = true;
if (keepit) {
if (!flatten_keep_list[cell]) {
@@ -533,7 +524,7 @@ struct TechmapWorker
continue;
for (auto &tpl_name : celltypeMap.at(cell_type)) {
- RTLIL::Module *tpl = map->modules_[tpl_name];
+ RTLIL::Module *tpl = map->module(tpl_name);
RTLIL::Wire *port = tpl->wire(conn.first);
if (port && port->port_input)
cell_to_inbit[cell].insert(sig.begin(), sig.end());
@@ -566,9 +557,9 @@ struct TechmapWorker
for (auto &tpl_name : celltypeMap.at(cell_type))
{
- RTLIL::IdString derived_name = tpl_name;
- RTLIL::Module *tpl = map->modules_[tpl_name];
- std::map<RTLIL::IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
+ IdString derived_name = tpl_name;
+ RTLIL::Module *tpl = map->module(tpl_name);
+ dict<IdString, RTLIL::Const> parameters(cell->parameters);
if (tpl->get_blackbox_attribute(ignore_wb))
continue;
@@ -675,7 +666,7 @@ struct TechmapWorker
if (extmapper_name == "simplemap") {
if (simplemap_mappers.count(cell->type) == 0)
- log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type));
+ log_error("No simplemap mapper for cell type %s found!\n", log_id(cell->type));
simplemap_mappers.at(cell->type)(module, cell);
}
@@ -686,7 +677,7 @@ struct TechmapWorker
}
module->remove(cell);
- cell = NULL;
+ cell = nullptr;
}
did_something = true;
@@ -694,10 +685,10 @@ struct TechmapWorker
break;
}
- for (auto conn : cell->connections()) {
+ for (auto &conn : cell->connections()) {
if (conn.first.begins_with("$"))
continue;
- if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0)
+ if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0)
continue;
if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0)
goto next_tpl;
@@ -710,23 +701,23 @@ struct TechmapWorker
}
if (tpl->avail_parameters.count(ID::_TECHMAP_CELLTYPE_) != 0)
- parameters[ID::_TECHMAP_CELLTYPE_] = RTLIL::unescape_id(cell->type);
+ parameters.emplace(ID::_TECHMAP_CELLTYPE_, RTLIL::unescape_id(cell->type));
- for (auto conn : cell->connections()) {
- if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) {
+ for (auto &conn : cell->connections()) {
+ if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first))) != 0) {
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
for (auto &bit : v)
- bit = RTLIL::SigBit(bit.wire == NULL ? RTLIL::State::S1 : RTLIL::State::S0);
- parameters[stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const();
+ bit = RTLIL::SigBit(bit.wire == nullptr ? RTLIL::State::S1 : RTLIL::State::S0);
+ parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const());
}
- if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))) != 0) {
+ if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first))) != 0) {
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
for (auto &bit : v)
- if (bit.wire != NULL)
+ if (bit.wire != nullptr)
bit = RTLIL::SigBit(RTLIL::State::Sx);
- parameters[stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const();
+ parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const());
}
- if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", RTLIL::id2cstr(conn.first))) != 0) {
+ if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first))) != 0) {
auto sig = sigmap(conn.second);
RTLIL::Const value(State::Sx, sig.size());
for (int i = 0; i < sig.size(); i++) {
@@ -735,20 +726,20 @@ struct TechmapWorker
value[i] = it->second;
}
}
- parameters[stringf("\\_TECHMAP_WIREINIT_%s_", RTLIL::id2cstr(conn.first))] = value;
+ parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), value);
}
}
int unique_bit_id_counter = 0;
- std::map<RTLIL::SigBit, int> unique_bit_id;
+ dict<RTLIL::SigBit, int> unique_bit_id;
unique_bit_id[RTLIL::State::S0] = unique_bit_id_counter++;
unique_bit_id[RTLIL::State::S1] = unique_bit_id_counter++;
unique_bit_id[RTLIL::State::Sx] = unique_bit_id_counter++;
unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++;
- for (auto conn : cell->connections())
- if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
- for (auto &bit : sigmap(conn.second).to_sigbit_vector())
+ for (auto &conn : cell->connections())
+ if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first))) != 0) {
+ for (auto &bit : sigmap(conn.second))
if (unique_bit_id.count(bit) == 0)
unique_bit_id[bit] = unique_bit_id_counter++;
}
@@ -763,14 +754,17 @@ struct TechmapWorker
if (tpl->avail_parameters.count(ID::_TECHMAP_BITS_CONNMAP_))
parameters[ID::_TECHMAP_BITS_CONNMAP_] = bits;
- for (auto conn : cell->connections())
- if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
+ for (auto &conn : cell->connections())
+ if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first))) != 0) {
RTLIL::Const value;
- for (auto &bit : sigmap(conn.second).to_sigbit_vector()) {
- RTLIL::Const chunk(unique_bit_id.at(bit), bits);
- value.bits.insert(value.bits.end(), chunk.bits.begin(), chunk.bits.end());
+ for (auto &bit : sigmap(conn.second)) {
+ int val = unique_bit_id.at(bit);
+ for (int i = 0; i < bits; i++) {
+ value.bits.push_back((val & 1) != 0 ? State::S1 : State::S0);
+ val = val >> 1;
+ }
}
- parameters[stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))] = value;
+ parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first)), value);
}
}
@@ -778,17 +772,18 @@ struct TechmapWorker
use_wrapper_tpl:;
// do not register techmap_wrap modules with techmap_cache
} else {
- std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>> key(tpl_name, parameters);
- if (techmap_cache.count(key) > 0) {
- tpl = techmap_cache[key];
+ std::pair<IdString, dict<IdString, RTLIL::Const>> key(tpl_name, parameters);
+ auto it = techmap_cache.find(key);
+ if (it != techmap_cache.end()) {
+ tpl = it->second;
} else {
if (parameters.size() != 0) {
mkdebug.on();
- derived_name = tpl->derive(map, dict<RTLIL::IdString, RTLIL::Const>(parameters.begin(), parameters.end()));
+ derived_name = tpl->derive(map, parameters);
tpl = map->module(derived_name);
log_continue = true;
}
- techmap_cache[key] = tpl;
+ techmap_cache.emplace(std::move(key), tpl);
}
}
@@ -805,7 +800,7 @@ struct TechmapWorker
bool keep_running = true;
techmap_do_cache[tpl] = true;
- std::set<std::string> techmap_wire_names;
+ pool<IdString> techmap_wire_names;
while (keep_running)
{
@@ -815,11 +810,11 @@ struct TechmapWorker
for (auto &it : twd)
techmap_wire_names.insert(it.first);
- for (auto &it : twd["_TECHMAP_FAIL_"]) {
+ for (auto &it : twd[ID::_TECHMAP_FAIL_]) {
RTLIL::SigSpec value = it.value;
if (value.is_fully_const() && value.as_bool()) {
log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n",
- derived_name.c_str(), RTLIL::id2cstr(it.wire->name), log_signal(value));
+ derived_name.c_str(), log_id(it.wire->name), log_signal(value));
techmap_do_cache[tpl] = false;
}
}
@@ -829,13 +824,13 @@ struct TechmapWorker
for (auto &it : twd)
{
- if (it.first.compare(0, 12, "_TECHMAP_DO_") != 0 || it.second.empty())
+ if (!it.first.begins_with("\\_TECHMAP_DO_") || it.second.empty())
continue;
auto &data = it.second.front();
if (!data.value.is_fully_const())
- log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value));
+ log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(data.wire->name), log_signal(data.value));
techmap_wire_names.erase(it.first);
@@ -851,7 +846,7 @@ struct TechmapWorker
cmd_string = cmd_string.substr(strlen("CONSTMAP; "));
log("Analyzing pattern of constant bits for this cell:\n");
- RTLIL::IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true);
+ IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true);
log("Creating constmapped module `%s'.\n", log_id(new_tpl_name));
log_assert(map->module(new_tpl_name) == nullptr);
@@ -862,16 +857,16 @@ struct TechmapWorker
techmap_do_cache[new_tpl] = true;
tpl = new_tpl;
- std::map<RTLIL::SigBit, RTLIL::SigBit> port_new2old_map;
- std::map<RTLIL::SigBit, RTLIL::SigBit> port_connmap;
- std::map<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits;
+ dict<RTLIL::SigBit, RTLIL::SigBit> port_new2old_map;
+ dict<RTLIL::SigBit, RTLIL::SigBit> port_connmap;
+ dict<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits;
for (auto wire : tpl->wires().to_vector())
{
if (!wire->port_input || wire->port_output)
continue;
- RTLIL::IdString port_name = wire->name;
+ IdString port_name = wire->name;
tpl->rename(wire, NEW_ID);
RTLIL::Wire *new_wire = tpl->addWire(port_name, wire);
@@ -879,12 +874,12 @@ struct TechmapWorker
wire->port_id = 0;
for (int i = 0; i < wire->width; i++) {
- port_new2old_map[RTLIL::SigBit(new_wire, i)] = RTLIL::SigBit(wire, i);
- port_connmap[RTLIL::SigBit(wire, i)] = RTLIL::SigBit(new_wire, i);
+ port_new2old_map.emplace(RTLIL::SigBit(new_wire, i), RTLIL::SigBit(wire, i));
+ port_connmap.emplace(RTLIL::SigBit(wire, i), RTLIL::SigBit(new_wire, i));
}
}
- for (auto conn : cell->connections())
+ for (auto &conn : cell->connections())
for (int i = 0; i < GetSize(conn.second); i++)
{
RTLIL::SigBit bit = sigmap(conn.second[i]);
@@ -926,7 +921,7 @@ struct TechmapWorker
log_assert(!strncmp(q, "_TECHMAP_DO_", 12));
std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12);
- while (tpl->wires_.count(new_name))
+ while (tpl->wire(new_name) != nullptr)
new_name += "_";
tpl->rename(data.wire->name, new_name);
@@ -937,17 +932,17 @@ struct TechmapWorker
TechmapWires twd = techmap_find_special_wires(tpl);
for (auto &it : twd) {
- if (it.first != "_TECHMAP_FAIL_" && (it.first.substr(0, 20) != "_TECHMAP_REMOVEINIT_" || it.first[it.first.size()-1] != '_') && it.first.substr(0, 12) != "_TECHMAP_DO_" && it.first.substr(0, 14) != "_TECHMAP_DONE_")
- log_error("Techmap yielded unknown config wire %s.\n", it.first.c_str());
+ if (it.first != ID::_TECHMAP_FAIL_ && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.begins_with("\\_TECHMAP_DO_") && !it.first.begins_with("\\_TECHMAP_DONE_"))
+ log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first));
if (techmap_do_cache[tpl])
for (auto &it2 : it.second)
if (!it2.value.is_fully_const())
- log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value));
+ log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(it2.wire->name), log_signal(it2.value));
techmap_wire_names.erase(it.first);
}
for (auto &it : techmap_wire_names)
- log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", RTLIL::id2cstr(it));
+ log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", log_id(it));
if (recursive_mode) {
if (log_continue) {
@@ -970,10 +965,10 @@ struct TechmapWorker
TechmapWires twd = techmap_find_special_wires(tpl);
for (auto &it : twd) {
- if (it.first.substr(0, 20) == "_TECHMAP_REMOVEINIT_") {
+ if (it.first.begins_with("\\_TECHMAP_REMOVEINIT_")) {
for (auto &it2 : it.second) {
auto val = it2.value.as_const();
- auto wirename = RTLIL::escape_id(it.first.substr(20, it.first.size() - 20 - 1));
+ auto wirename = RTLIL::escape_id(it.first.substr(21, it.first.size() - 21 - 1));
auto it = cell->connections().find(wirename);
if (it != cell->connections().end()) {
auto sig = sigmap(it->second);
@@ -1015,7 +1010,7 @@ struct TechmapWorker
}
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(tpl));
techmap_module_worker(design, module, cell, tpl);
- cell = NULL;
+ cell = nullptr;
}
did_something = true;
mapped_cell = true;
@@ -1275,8 +1270,7 @@ struct TechmapPass : public Pass {
RTLIL::Design *map = new RTLIL::Design;
if (map_files.empty()) {
- std::istringstream f(stdcells_code);
- Frontend::frontend_call(map, &f, "<techmap.v>", verilog_frontend);
+ Frontend::frontend_call(map, nullptr, "+/techmap.v", verilog_frontend);
} else {
for (auto &fn : map_files)
if (fn.compare(0, 1, "%") == 0) {
@@ -1285,35 +1279,30 @@ struct TechmapPass : public Pass {
log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1);
}
for (auto mod : saved_designs.at(fn.substr(1))->modules())
- if (!map->has(mod->name))
+ if (!map->module(mod->name))
map->add(mod->clone());
} else {
- std::ifstream f;
- rewrite_filename(fn);
- f.open(fn.c_str());
- yosys_input_files.insert(fn);
- if (f.fail())
- log_cmd_error("Can't open map file `%s'\n", fn.c_str());
- Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend));
+ Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend));
}
}
log_header(design, "Continuing TECHMAP pass.\n");
- std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
- for (auto &it : map->modules_) {
- if (it.second->attributes.count(ID::techmap_celltype) && !it.second->attributes.at(ID::techmap_celltype).bits.empty()) {
- char *p = strdup(it.second->attributes.at(ID::techmap_celltype).decode_string().c_str());
- for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n"))
- celltypeMap[RTLIL::escape_id(q)].insert(it.first);
+ dict<IdString, pool<IdString>> celltypeMap;
+ for (auto module : map->modules()) {
+ if (module->attributes.count(ID::techmap_celltype) && !module->attributes.at(ID::techmap_celltype).bits.empty()) {
+ char *p = strdup(module->attributes.at(ID::techmap_celltype).decode_string().c_str());
+ for (char *q = strtok(p, " \t\r\n"); q; q = strtok(nullptr, " \t\r\n"))
+ celltypeMap[RTLIL::escape_id(q)].insert(module->name);
free(p);
} else {
- string module_name = it.first.str();
- if (it.first.begins_with("\\$"))
- module_name = module_name.substr(1);
- celltypeMap[module_name].insert(it.first);
+ IdString module_name = module->name.begins_with("\\$") ?
+ module->name.substr(1) : module->name.str();
+ celltypeMap[module_name].insert(module->name);
}
}
+ for (auto &i : celltypeMap)
+ i.second.sort(RTLIL::sort_by_id_str());
for (auto module : design->modules())
worker.module_queue.insert(module);
@@ -1325,7 +1314,7 @@ struct TechmapPass : public Pass {
int module_max_iter = max_iter;
bool did_something = true;
- std::set<RTLIL::Cell*> handled_cells;
+ pool<RTLIL::Cell*> handled_cells;
while (did_something) {
did_something = false;
if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false))
@@ -1382,18 +1371,20 @@ struct FlattenPass : public Pass {
extra_args(args, argidx, design);
- std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
+ dict<IdString, pool<IdString>> celltypeMap;
for (auto module : design->modules())
celltypeMap[module->name].insert(module->name);
+ for (auto &i : celltypeMap)
+ i.second.sort(RTLIL::sort_by_id_str());
- RTLIL::Module *top_mod = NULL;
+ RTLIL::Module *top_mod = nullptr;
if (design->full_selection())
for (auto mod : design->modules())
if (mod->get_bool_attribute(ID::top))
top_mod = mod;
- std::set<RTLIL::Cell*> handled_cells;
- if (top_mod != NULL) {
+ pool<RTLIL::Cell*> handled_cells;
+ if (top_mod != nullptr) {
worker.flatten_do_list.insert(top_mod->name);
while (!worker.flatten_do_list.empty()) {
auto mod = design->module(*worker.flatten_do_list.begin());
@@ -1402,20 +1393,19 @@ struct FlattenPass : public Pass {
worker.flatten_do_list.erase(mod->name);
}
} else {
- for (auto mod : vector<Module*>(design->modules())) {
+ for (auto mod : design->modules().to_vector())
while (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, false)) { }
- }
}
log_suppressed();
log("No more expansions possible.\n");
- if (top_mod != NULL)
+ if (top_mod != nullptr)
{
- pool<RTLIL::IdString> used_modules, new_used_modules;
+ pool<IdString> used_modules, new_used_modules;
new_used_modules.insert(top_mod->name);
while (!new_used_modules.empty()) {
- pool<RTLIL::IdString> queue;
+ pool<IdString> queue;
queue.swap(new_used_modules);
for (auto modname : queue)
used_modules.insert(modname);
@@ -1425,15 +1415,11 @@ struct FlattenPass : public Pass {
new_used_modules.insert(cell->type);
}
- dict<RTLIL::IdString, RTLIL::Module*> new_modules;
- for (auto mod : vector<Module*>(design->modules()))
- if (used_modules[mod->name] || mod->get_blackbox_attribute(worker.ignore_wb)) {
- new_modules[mod->name] = mod;
- } else {
+ for (auto mod : design->modules().to_vector())
+ if (!used_modules[mod->name] && !mod->get_blackbox_attribute(worker.ignore_wb)) {
log("Deleting now unused module %s.\n", log_id(mod));
- delete mod;
+ design->remove(mod);
}
- design->modules_.swap(new_modules);
}
log_pop();
diff --git a/techlibs/common/abc9_unmap.v b/techlibs/common/abc9_unmap.v
index bcbe91477..c39648c62 100644
--- a/techlibs/common/abc9_unmap.v
+++ b/techlibs/common/abc9_unmap.v
@@ -1,5 +1,5 @@
(* techmap_celltype = "$__DFF_N__$abc9_flop $__DFF_P__$abc9_flop" *)
-module $__DFF_x__$abc9_flop (input C, D, Q, output n1);
+module $__DFF_x__$abc9_flop (input C, D, (* init = 1'b0 *) input Q, output n1);
parameter _TECHMAP_CELLTYPE_ = "";
generate if (_TECHMAP_CELLTYPE_ == "$__DFF_N__$abc9_flop")
$_DFF_N_ _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q));
diff --git a/tests/arch/ecp5/latches_abc9.ys b/tests/arch/ecp5/latches_abc9.ys
new file mode 100644
index 000000000..4daf04050
--- /dev/null
+++ b/tests/arch/ecp5/latches_abc9.ys
@@ -0,0 +1,13 @@
+read_verilog <<EOT
+module top(input e, d, output q);
+reg l;
+always @*
+ if (e)
+ l = ~d;
+assign q = ~l;
+endmodule
+EOT
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_ecp5 -abc9
+select -assert-count 2 t:LUT4
+select -assert-none t:LUT4 %% t:* %D
diff --git a/tests/arch/ice40/mux.ys b/tests/arch/ice40/mux.ys
index 99822391d..2b661fd6b 100644
--- a/tests/arch/ice40/mux.ys
+++ b/tests/arch/ice40/mux.ys
@@ -35,6 +35,7 @@ proc
equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
-select -assert-count 11 t:SB_LUT4
+select -assert-min 11 t:SB_LUT4
+select -assert-max 12 t:SB_LUT4
select -assert-none t:SB_LUT4 %% t:* %D
diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys
index fd343969b..210e87477 100644
--- a/tests/arch/xilinx/abc9_dff.ys
+++ b/tests/arch/xilinx/abc9_dff.ys
@@ -50,10 +50,10 @@ FDCE_1 /*#(.INIT(1))*/ fd7(.C(C), .CE(1'b0), .D(D), .CLR(1'b0), .Q(Q[6]));
FDPE_1 #(.INIT(1)) fd8(.C(C), .CE(1'b0), .D(D), .PRE(1'b0), .Q(Q[7]));
endmodule
EOT
-logger -expect warning "Module '\$paramod\\FDRE\\INIT=1' contains a \$dff cell .*" 1
-logger -expect warning "Module '\$paramod\\FDRE_1\\INIT=1' contains a \$dff cell .*" 1
-logger -expect warning "Module 'FDSE' contains a \$dff cell .*" 1
-logger -expect warning "Module '\$paramod\\FDSE_1\\INIT=1' contains a \$dff cell .*" 1
+logger -expect warning "Whitebox '\$paramod\\FDRE\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox '\$paramod\\FDRE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox 'FDSE' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox '\$paramod\\FDSE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
design -load postopt
select -assert-count 8 t:FD*
@@ -82,4 +82,53 @@ select -assert-count 1 t:FDPE
select -assert-count 2 t:INV
select -assert-count 0 t:FD* t:INV %% t:* %D
+
+design -reset
+read_verilog <<EOT
+module top(input clk, input d, output q);
+reg r;
+always @(posedge clk) begin
+r <= d;
+end
+assign q = ~r;
+endmodule
+EOT
+proc
+equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
+design -load postopt
+select -assert-count 1 t:FDRE %co w:r %i
+
+
+design -reset
+read_verilog <<EOT
+module top(input clk, input a, b, output reg q1, output q2);
+reg r;
+always @(posedge clk) begin
+ q1 <= a | b;
+ r <= ~(~a & ~b);
+end
+assign q2 = r;
+endmodule
+EOT
+proc
+equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
+design -load postopt
+select -assert-count 1 t:FDRE %co %a w:r %i
+
+
+design -reset
+read_verilog <<EOT
+module top(input clk, input a, b, output o);
+reg r1, r2;
+always @(posedge clk) begin
+ r1 <= a | b;
+ r2 <= ~(~a & ~b);
+end
+assign o = r1 | r2;
+endmodule
+EOT
+proc
+equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
+
+
logger -expect-no-warnings
diff --git a/tests/arch/xilinx/pmgen_xilinx_srl.ys b/tests/arch/xilinx/pmgen_xilinx_srl.ys
index ea2f20487..e76fb20ab 100644
--- a/tests/arch/xilinx/pmgen_xilinx_srl.ys
+++ b/tests/arch/xilinx/pmgen_xilinx_srl.ys
@@ -1,6 +1,6 @@
read_verilog -icells <<EOT
module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, output SO);
- parameter DEPTH = 1;
+ parameter DEPTH = 2;
parameter [DEPTH-1:0] INIT = 0;
parameter CLKPOL = 1;
parameter ENPOL = 2;
diff --git a/tests/arch/xilinx/xilinx_srl.v b/tests/arch/xilinx/xilinx_srl.v
index bc2a15ab2..29920da41 100644
--- a/tests/arch/xilinx/xilinx_srl.v
+++ b/tests/arch/xilinx/xilinx_srl.v
@@ -29,7 +29,7 @@ endmodule
module $__XILINX_SHREG_(input C, D, E, input [1:0] L, output Q);
parameter CLKPOL = 1;
parameter ENPOL = 1;
-parameter DEPTH = 1;
+parameter DEPTH = 2;
parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}};
reg [DEPTH-1:0] r = INIT;
wire clk = C ^ CLKPOL;
diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys
index ac714665f..a9880c722 100644
--- a/tests/various/abc9.ys
+++ b/tests/various/abc9.ys
@@ -97,4 +97,5 @@ select -assert-count 3 t:$_DFF_N_
select -assert-none c:ff1 c:ff2 c:ff4 %% c:* %D
clean
select -assert-count 2 a:init
-select -assert-none w:w w:z %% a:init %D
+select -assert-count 1 w:w a:init %i
+select -assert-count 1 c:ff4 %co c:ff4 %d %a a:init %i
diff --git a/tests/various/attrib07_func_call.v b/tests/various/attrib07_func_call.v
index f55ef2316..8c9fb2926 100644
--- a/tests/various/attrib07_func_call.v
+++ b/tests/various/attrib07_func_call.v
@@ -11,7 +11,7 @@ module foo(clk, rst, inp_a, inp_b, out);
input wire rst;
input wire [7:0] inp_a;
input wire [7:0] inp_b;
- output wire [7:0] out;
+ output reg [7:0] out;
always @(posedge clk)
if (rst) out <= 0;
diff --git a/tests/various/constmsk_testmap.v b/tests/various/constmsk_testmap.v
index fab1b1bbc..b6809c7c0 100644
--- a/tests/various/constmsk_testmap.v
+++ b/tests/various/constmsk_testmap.v
@@ -1,7 +1,7 @@
(* techmap_celltype = "$reduce_or" *)
module my_opt_reduce_or(...);
parameter A_SIGNED = 0;
- parameter A_WIDTH = 1;
+ parameter A_WIDTH = 2;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
diff --git a/tests/various/shregmap.v b/tests/various/shregmap.v
index 604c2c976..dc828eda7 100644
--- a/tests/various/shregmap.v
+++ b/tests/various/shregmap.v
@@ -13,7 +13,7 @@ assign q = {shift2[3], shift1[3]};
endmodule
module $__SHREG_DFF_P_(input C, D, output Q);
-parameter DEPTH = 1;
+parameter DEPTH = 2;
parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}};
reg [DEPTH-1:0] r = INIT;
always @(posedge C)
@@ -38,7 +38,7 @@ endmodule
module $__XILINX_SHREG_(input C, D, input [1:0] L, output Q);
parameter CLKPOL = 1;
parameter ENPOL = 1;
-parameter DEPTH = 1;
+parameter DEPTH = 2;
parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}};
reg [DEPTH-1:0] r = INIT;
wire clk = C ^ CLKPOL;
diff --git a/tests/verilog/bug2042-sv.ys b/tests/verilog/bug2042-sv.ys
index e815d7fc5..91989f412 100644
--- a/tests/verilog/bug2042-sv.ys
+++ b/tests/verilog/bug2042-sv.ys
@@ -2,7 +2,7 @@ read_verilog -sv <<EOT
module Task_Test_Top
(
input a,
-output b
+output reg b
);
task SomeTaskName(a);