aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/Makefile.inc6
-rw-r--r--passes/techmap/abc.cc163
-rw-r--r--passes/techmap/abc9.cc63
-rw-r--r--passes/techmap/abc9_exe.cc12
-rw-r--r--passes/techmap/abc9_ops.cc620
-rw-r--r--passes/techmap/alumacc.cc26
-rw-r--r--passes/techmap/clkbufmap.cc12
-rw-r--r--passes/techmap/deminout.cc5
-rw-r--r--passes/techmap/dff2dffe.cc40
-rw-r--r--passes/techmap/dff2dffs.cc12
-rw-r--r--passes/techmap/dffinit.cc10
-rw-r--r--passes/techmap/dfflibmap.cc54
-rw-r--r--passes/techmap/dffsr2dff.cc52
-rw-r--r--passes/techmap/extract.cc141
-rw-r--r--passes/techmap/extract_counter.cc503
-rw-r--r--passes/techmap/extract_fa.cc14
-rw-r--r--passes/techmap/extract_reduce.cc8
-rw-r--r--passes/techmap/extractinv.cc2
-rw-r--r--passes/techmap/flowmap.cc4
-rw-r--r--passes/techmap/hilomap.cc8
-rw-r--r--passes/techmap/insbuf.cc14
-rw-r--r--passes/techmap/iopadmap.cc119
-rw-r--r--passes/techmap/lut2mux.cc2
-rw-r--r--passes/techmap/maccmap.cc16
-rw-r--r--passes/techmap/muxcover.cc66
-rw-r--r--passes/techmap/pmuxtree.cc2
-rw-r--r--passes/techmap/shregmap.cc32
-rw-r--r--passes/techmap/simplemap.cc206
-rw-r--r--passes/techmap/techmap.cc86
-rw-r--r--passes/techmap/tribuf.cc14
-rw-r--r--passes/techmap/zinit.cc18
31 files changed, 1412 insertions, 918 deletions
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc
index c16db0d57..bb3f6da98 100644
--- a/passes/techmap/Makefile.inc
+++ b/passes/techmap/Makefile.inc
@@ -59,10 +59,10 @@ passes/techmap/techmap.inc: techlibs/common/techmap.v
passes/techmap/techmap.o: passes/techmap/techmap.inc
ifneq ($(CONFIG),emcc)
-TARGETS += yosys-filterlib$(EXE)
+TARGETS += $(PROGRAM_PREFIX)yosys-filterlib$(EXE)
EXTRA_OBJS += passes/techmap/filterlib.o
-yosys-filterlib$(EXE): passes/techmap/filterlib.o
+$(PROGRAM_PREFIX)yosys-filterlib$(EXE): passes/techmap/filterlib.o
$(Q) mkdir -p $(dir $@)
- $(P) $(LD) -o yosys-filterlib$(EXE) $(LDFLAGS) $^ $(LDLIBS)
+ $(P) $(LD) -o $(PROGRAM_PREFIX)yosys-filterlib$(EXE) $(LDFLAGS) $^ $(LDLIBS)
endif
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 581652a41..0ee495abd 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -170,7 +170,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
if (clk_polarity != (cell->type == ID($_DFF_P_)))
return;
- if (clk_sig != assign_map(cell->getPort(ID(C))))
+ if (clk_sig != assign_map(cell->getPort(ID::C)))
return;
if (GetSize(en_sig) != 0)
return;
@@ -183,17 +183,17 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
return;
if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
return;
- if (clk_sig != assign_map(cell->getPort(ID(C))))
+ if (clk_sig != assign_map(cell->getPort(ID::C)))
return;
- if (en_sig != assign_map(cell->getPort(ID(E))))
+ if (en_sig != assign_map(cell->getPort(ID::E)))
return;
goto matching_dff;
}
if (0) {
matching_dff:
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
if (keepff)
for (auto &c : sig_q.chunks())
@@ -263,7 +263,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_s = cell->getPort(ID(S));
+ RTLIL::SigSpec sig_s = cell->getPort(ID::S);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -285,7 +285,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_c = cell->getPort(ID(C));
+ RTLIL::SigSpec sig_c = cell->getPort(ID::C);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -307,8 +307,8 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_c = cell->getPort(ID(C));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
+ RTLIL::SigSpec sig_c = cell->getPort(ID::C);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -702,7 +702,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (dff_mode && clk_sig.empty())
log_cmd_error("Clock domain %s not found.\n", clk_str.c_str());
- std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
+ std::string tempdir_name = "/tmp/" + proc_program_prefix()+ "yosys-abc-XXXXXX";
if (!cleanup)
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
@@ -1032,9 +1032,9 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
RTLIL::Wire *w = it.second;
RTLIL::Wire *orig_wire = nullptr;
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
- if (orig_wire != nullptr && orig_wire->attributes.count(ID(src)))
- wire->attributes[ID(src)] = orig_wire->attributes[ID(src)];
- if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx;
+ if (orig_wire != nullptr && orig_wire->attributes.count(ID::src))
+ wire->attributes[ID::src] = orig_wire->attributes[ID::src];
+ if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx;
design->select(module, wire);
}
@@ -1060,7 +1060,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type == ID(NOT)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
@@ -1068,7 +1068,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
@@ -1077,89 +1077,89 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type.in(ID(MUX), ID(NMUX))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX4)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX8)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
- cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
- cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
- cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
- cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
+ cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
+ cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
+ cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
+ cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX16)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
- cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
- cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
- cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
- cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)]));
- cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)]));
- cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)]));
- cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)]));
- cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)]));
- cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)]));
- cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)]));
- cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
- cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
- cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
+ cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
+ cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
+ cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
+ cell->setPort(ID::I, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::I).as_wire()->name)]));
+ cell->setPort(ID::J, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::J).as_wire()->name)]));
+ cell->setPort(ID::K, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::K).as_wire()->name)]));
+ cell->setPort(ID::L, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::L).as_wire()->name)]));
+ cell->setPort(ID::M, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::M).as_wire()->name)]));
+ cell->setPort(ID::N, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::N).as_wire()->name)]));
+ cell->setPort(ID::O, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::O).as_wire()->name)]));
+ cell->setPort(ID::P, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::P).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
+ cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
+ cell->setPort(ID::V, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::V).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type.in(ID(AOI3), ID(OAI3))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type.in(ID(AOI4), ID(OAI4))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
@@ -1172,12 +1172,12 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
} else {
log_assert(en_sig.size() == 1);
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), en_sig);
+ cell->setPort(ID::E, en_sig);
}
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
- cell->setPort(ID(C), clk_sig);
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
+ cell->setPort(ID::C, clk_sig);
design->select(module, cell);
continue;
}
@@ -1201,17 +1201,17 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
} else {
log_assert(en_sig.size() == 1);
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), en_sig);
+ cell->setPort(ID::E, en_sig);
}
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
- cell->setPort(ID(C), clk_sig);
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
+ cell->setPort(ID::C, clk_sig);
design->select(module, cell);
continue;
}
- if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)).as_int() == 2) {
+ if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
SigSpec my_a = module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)];
SigSpec my_y = module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)];
module->connect(my_y, my_a);
@@ -1219,7 +1219,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->parameters = c->parameters;
for (auto &conn : c->connections()) {
RTLIL::SigSpec newsig;
@@ -1244,10 +1244,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (recover_init)
for (auto wire : mapped_mod->wires()) {
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
Wire *w = module->wires_[remap_name(wire->name)];
- log_assert(w->attributes.count(ID(init)) == 0);
- w->attributes[ID(init)] = wire->attributes.at(ID(init));
+ log_assert(w->attributes.count(ID::init) == 0);
+ w->attributes[ID::init] = wire->attributes.at(ID::init);
}
}
@@ -1305,7 +1305,7 @@ struct AbcPass : public Pass {
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -1491,7 +1491,7 @@ struct AbcPass : public Pass {
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
#else
- std::string exe_file = proc_self_dirname() + "yosys-abc";
+ std::string exe_file = proc_self_dirname() + proc_program_prefix() + "yosys-abc";
#endif
std::string script_file, liberty_file, constr_file, clk_str;
std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";
@@ -1509,8 +1509,8 @@ struct AbcPass : public Pass {
#ifdef _WIN32
#ifndef ABCEXTERNAL
- if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
- exe_file = proc_self_dirname() + "..\\yosys-abc";
+ if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix()+ "yosys-abc.exe"))
+ exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
#endif
#endif
@@ -1553,6 +1553,11 @@ struct AbcPass : public Pass {
show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir);
markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups);
+ if (design->scratchpad_get_bool("abc.debug")) {
+ cleanup = false;
+ show_tempdir = true;
+ }
+
size_t argidx, g_argidx;
bool g_arg_from_cmd = false;
char pwd [PATH_MAX];
@@ -1864,9 +1869,9 @@ struct AbcPass : public Pass {
signal_init.clear();
for (Wire *wire : mod->wires())
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = assign_map(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
switch (initval[i]) {
case State::S0:
@@ -1925,14 +1930,14 @@ struct AbcPass : public Pass {
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
{
- key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
+ key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID::C)), true, RTLIL::SigSpec());
}
else
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
{
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
- key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
+ key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID::C)), this_en_pol, assign_map(cell->getPort(ID::E)));
}
else
continue;
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 5ae2fb22a..1b3d5ff06 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -100,7 +100,7 @@ struct Abc9Pass : public ScriptPass
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -145,6 +145,11 @@ struct Abc9Pass : public ScriptPass
log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
log(" 2, 3, .. inputs.\n");
log("\n");
+ log(" -maxlut <width>\n");
+ log(" when auto-generating the lut library, discard all luts equal to or\n");
+ log(" greater than this size (applicable when neither -lut nor -luts is\n");
+ log(" specified).\n");
+ log("\n");
log(" -dff\n");
log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
log(" domains are marked as such and automatically partitioned by ABC.\n");
@@ -175,6 +180,8 @@ struct Abc9Pass : public ScriptPass
std::stringstream exe_cmd;
bool dff_mode, cleanup;
+ bool lut_mode;
+ int maxlut;
std::string box_file;
void clear_flags() YS_OVERRIDE
@@ -183,7 +190,9 @@ struct Abc9Pass : public ScriptPass
exe_cmd << "abc9_exe";
dff_mode = false;
cleanup = true;
- box_file.clear();
+ lut_mode = false;
+ maxlut = 0;
+ box_file = "";
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -204,9 +213,11 @@ struct Abc9Pass : public ScriptPass
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
if ((arg == "-exe" || arg == "-script" || arg == "-D" ||
- /* arg == "-S" || */ arg == "-lut" || arg == "-luts" ||
+ /*arg == "-S" ||*/ arg == "-lut" || arg == "-luts" ||
/*arg == "-box" ||*/ arg == "-W") &&
argidx+1 < args.size()) {
+ if (arg == "-lut" || arg == "-luts")
+ lut_mode = true;
exe_cmd << " " << arg << " " << args[++argidx];
continue;
}
@@ -228,6 +239,10 @@ struct Abc9Pass : public ScriptPass
box_file = args[++argidx];
continue;
}
+ if (arg == "-maxlut" && argidx+1 < args.size()) {
+ maxlut = atoi(args[++argidx].c_str());
+ continue;
+ }
if (arg == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
@@ -240,6 +255,9 @@ struct Abc9Pass : public ScriptPass
}
extra_args(args, argidx, design);
+ if (maxlut && lut_mode)
+ log_cmd_error("abc9 '-maxlut' option only applicable without '-lut' nor '-luts'.\n");
+
log_assert(design);
if (design->selected_modules().empty()) {
log_warning("No modules selected for ABC9 techmapping.\n");
@@ -263,6 +281,14 @@ struct Abc9Pass : public ScriptPass
run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
else
run("abc9_ops -mark_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)");
+ if (help_mode)
+ run("abc9_ops -prep_lut <maxlut>", "(skip if -lut or -luts)");
+ else if (!lut_mode)
+ run(stringf("abc9_ops -prep_lut %d", maxlut));
+ if (help_mode)
+ run("abc9_ops -prep_box [-dff]", "(skip if -box)");
+ else if (box_file.empty())
+ run(stringf("abc9_ops -prep_box %s", dff_mode ? "-dff" : ""));
run("select -set abc9_holes A:abc9_holes");
run("flatten -wb @abc9_holes");
run("techmap @abc9_holes");
@@ -276,9 +302,10 @@ struct Abc9Pass : public ScriptPass
if (check_label("map")) {
if (help_mode) {
run("foreach module in selection");
- run(" abc9_ops -write_box [<value from -box>|(null)] <abc-temp-dir>/input.box");
+ run(" abc9_ops -write_lut <abc-temp-dir>/input.lut", "(skip if '-lut' or '-luts')");
+ run(" abc9_ops -write_box <abc-temp-dir>/input.box");
run(" write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig");
- run(" abc9_exe [options] -cwd <abc-temp-dir> -box <abc-temp-dir>/input.box");
+ run(" abc9_exe [options] -cwd <abc-temp-dir> [-lut <abc-temp-dir>/input.lut] -box <abc-temp-dir>/input.box");
run(" read_aiger -xaiger -wideports -module_name <module-name>$abc9 -map <abc-temp-dir>/input.sym <abc-temp-dir>/output.aig");
run(" abc9_ops -reintegrate");
}
@@ -291,7 +318,7 @@ struct Abc9Pass : public ScriptPass
log("Skipping module %s as it contains processes.\n", log_id(mod));
continue;
}
- log_assert(!mod->attributes.count(ID(abc9_box_id)));
+ log_assert(!mod->attributes.count(ID::abc9_box_id));
log_push();
active_design->selection().select(mod);
@@ -299,16 +326,15 @@ struct Abc9Pass : public ScriptPass
if (!active_design->selected_whole_module(mod))
log_error("Can't handle partially selected module %s!\n", log_id(mod));
- std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
+ std::string tempdir_name = "/tmp/" + proc_program_prefix() + "yosys-abc-XXXXXX";
if (!cleanup)
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
- if (box_file.empty())
- run(stringf("abc9_ops -write_box (null) %s/input.box", tempdir_name.c_str()));
- else
- run(stringf("abc9_ops -write_box %s %s/input.box", box_file.c_str(), tempdir_name.c_str()));
- run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
+ if (!lut_mode)
+ run_nocheck(stringf("abc9_ops -write_lut %s/input.lut", tempdir_name.c_str()));
+ run_nocheck(stringf("abc9_ops -write_box %s/input.box", tempdir_name.c_str()));
+ run_nocheck(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs");
@@ -319,9 +345,14 @@ struct Abc9Pass : public ScriptPass
active_design->scratchpad_get_int("write_xaiger.num_inputs"),
num_outputs);
if (num_outputs) {
- run(stringf("%s -cwd %s -box %s/input.box", exe_cmd.str().c_str(), tempdir_name.c_str(), tempdir_name.c_str()));
- run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
- run("abc9_ops -reintegrate");
+ std::string abc9_exe_cmd;
+ abc9_exe_cmd += stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str());
+ if (!lut_mode)
+ abc9_exe_cmd += stringf(" -lut %s/input.lut", tempdir_name.c_str());
+ abc9_exe_cmd += stringf(" -box %s/input.box", tempdir_name.c_str());
+ run_nocheck(abc9_exe_cmd);
+ run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
+ run_nocheck("abc9_ops -reintegrate");
}
else
log("Don't call ABC as there is nothing to map.\n");
@@ -330,7 +361,7 @@ struct Abc9Pass : public ScriptPass
log("Removing temp directory.\n");
remove_directory(tempdir_name);
}
-
+ mod->check();
active_design->selection().selected_modules.clear();
log_pop();
}
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index 71221951c..303b04402 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -293,7 +293,7 @@ struct Abc9ExePass : public Pass {
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -362,12 +362,12 @@ struct Abc9ExePass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n");
+ log_header(design, "Executing ABC9_EXE pass (technology mapping using ABC9).\n");
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
#else
- std::string exe_file = proc_self_dirname() + "yosys-abc";
+ std::string exe_file = proc_self_dirname() + proc_program_prefix()+ "yosys-abc";
#endif
std::string script_file, clk_str, box_file, lut_file;
std::string delay_target, lutin_shared = "-S 1", wire_delay;
@@ -383,8 +383,8 @@ struct Abc9ExePass : public Pass {
#ifdef _WIN32
#ifndef ABCEXTERNAL
- if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
- exe_file = proc_self_dirname() + "..\\yosys-abc";
+ if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe"))
+ exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
#endif
#endif
@@ -471,7 +471,7 @@ struct Abc9ExePass : public Pass {
// handle -lut / -luts args
if (!lut_arg.empty()) {
string arg = lut_arg;
- if (arg.find_first_not_of("0123456789:") == std::string::npos) {
+ if (arg.find_first_not_of("0123456789:,") == std::string::npos) {
size_t pos = arg.find_first_of(':');
int lut_mode = 0, lut_mode2 = 0;
if (pos != string::npos) {
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index 7071f0de4..00af36615 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -22,9 +22,7 @@
#include "kernel/sigtools.h"
#include "kernel/utils.h"
#include "kernel/celltypes.h"
-
-#define ABC9_FLOPS_BASE_ID 8000
-#define ABC9_DELAY_BASE_ID 9000
+#include "kernel/timinginfo.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -43,8 +41,8 @@ void check(RTLIL::Design *design)
if (m->name.begins_with("$paramod"))
continue;
- auto flop = m->get_bool_attribute(ID(abc9_flop));
- auto it = m->attributes.find(ID(abc9_box_id));
+ auto flop = m->get_bool_attribute(ID::abc9_flop);
+ auto it = m->attributes.find(ID::abc9_box_id);
if (!flop) {
if (it == m->attributes.end())
continue;
@@ -61,7 +59,7 @@ void check(RTLIL::Design *design)
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", log_id(m));
@@ -73,54 +71,6 @@ void check(RTLIL::Design *design)
carry_out = port_name;
}
}
-
- auto it = w->attributes.find("\\abc9_arrival");
- if (it != w->attributes.end()) {
- int count = 0;
- if (it->second.flags == 0) {
- if (it->second.as_int() < 0)
- log_error("%s.%s has negative arrival value %d!\n", log_id(m), log_id(port_name),
- it->second.as_int());
- count++;
- }
- else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- if (tok.find_first_not_of("0123456789") != std::string::npos)
- log_error("%s.%s has non-integer arrival value '%s'!\n", log_id(m), log_id(port_name),
- tok.c_str());
- if (atoi(tok.c_str()) < 0)
- log_error("%s.%s has negative arrival value %s!\n", log_id(m), log_id(port_name),
- tok.c_str());
- count++;
- }
- if (count > 1 && count != GetSize(w))
- log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(m), log_id(port_name),
- GetSize(w), log_signal(it->second), count);
- }
-
- it = w->attributes.find("\\abc9_required");
- if (it != w->attributes.end()) {
- int count = 0;
- if (it->second.flags == 0) {
- if (it->second.as_int() < 0)
- log_error("%s.%s has negative required value %d!\n", log_id(m), log_id(port_name),
- it->second.as_int());
- count++;
- }
- else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- if (tok.find_first_not_of("0123456789") != std::string::npos)
- log_error("%s.%s has non-integer required value '%s'!\n", log_id(m), log_id(port_name),
- tok.c_str());
- if (atoi(tok.c_str()) < 0)
- log_error("%s.%s has negative required value %s!\n", log_id(m), log_id(port_name),
- tok.c_str());
- count++;
- }
- if (count > 1 && count != GetSize(w))
- log_error("%s.%s is %d bits wide but abc9_required = %s has %d value(s)!\n", log_id(m), log_id(port_name),
- GetSize(w), log_signal(it->second), count);
- }
}
if (carry_in != IdString() && carry_out == IdString())
@@ -143,12 +93,13 @@ void check(RTLIL::Design *design)
void mark_scc(RTLIL::Module *module)
{
// For every unique SCC found, (arbitrarily) find the first
- // cell in the component, and convert all wires driven by
- // its output ports into a new PO, and drive its previous
- // sinks with a new PI
+ // cell in the component, and replace its output connections
+ // with a new wire driven by the old connection but with a
+ // special (* abc9_scc *) attribute set (which is used by
+ // write_xaiger to break this wire into PI and POs)
pool<RTLIL::Const> ids_seen;
for (auto cell : module->cells()) {
- auto it = cell->attributes.find(ID(abc9_scc_id));
+ auto it = cell->attributes.find(ID::abc9_scc_id);
if (it == cell->attributes.end())
continue;
auto id = it->second;
@@ -159,15 +110,13 @@ void mark_scc(RTLIL::Module *module)
for (auto &c : cell->connections_) {
if (c.second.is_fully_const()) continue;
if (cell->output(c.first)) {
- SigBit b = c.second.as_bit();
- Wire *w = b.wire;
- w->set_bool_attribute(ID::keep);
- w->attributes[ID(abc9_scc_id)] = id.as_int();
+ Wire *w = module->addWire(NEW_ID, GetSize(c.second));
+ w->set_bool_attribute(ID::abc9_scc);
+ module->connect(w, c.second);
+ c.second = w;
}
}
}
-
- module->fixup_ports();
}
void prep_dff(RTLIL::Module *module)
@@ -181,7 +130,7 @@ void prep_dff(RTLIL::Module *module)
dict<clkdomain_t, int> clk_to_mergeability;
for (auto cell : module->cells()) {
- if (cell->type != "$__ABC9_FF_")
+ if (cell->type != ID($__ABC9_FF_))
continue;
Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str()));
@@ -192,20 +141,9 @@ void prep_dff(RTLIL::Module *module)
clkdomain_t key(abc9_clock);
auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
- auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
- log_assert(r2.second);
-
- Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
- if (abc9_init_wire == NULL)
- log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
- log_assert(GetSize(abc9_init_wire) == 1);
- SigSpec abc9_init = assign_map(abc9_init_wire);
- if (!abc9_init.is_fully_const())
- log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
- if (abc9_init == State::S1)
- log_error("'%s.init' in module '%s' has value 1'b1 which is not supported by 'abc9 -dff'.\n", cell->name.c_str(), log_id(module));
- r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
+ auto r2 = cell->attributes.insert(ID::abc9_mergeability);
log_assert(r2.second);
+ r2.first->second = r.first->second;
}
RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
@@ -214,20 +152,20 @@ void prep_dff(RTLIL::Module *module)
dict<SigSpec, SigSpec> replace;
for (auto cell : holes_module->cells().to_vector()) {
- if (!cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
- "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_"))
+ if (!cell->type.in(ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
+ ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1), ID($_DFF_PP0_), ID($_DFF_PP1_)))
continue;
- SigBit D = cell->getPort("\\D");
- SigBit Q = cell->getPort("\\Q");
+ SigBit D = cell->getPort(ID::D);
+ SigBit Q = cell->getPort(ID::Q);
// Emulate async control embedded inside $_DFF_* cell with mux in front of D
- if (cell->type.in("$_DFF_NN0_", "$_DFF_PN0_"))
- D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NN1_", "$_DFF_PN1_"))
- D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NP0_", "$_DFF_PP0_"))
- D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NP1_", "$_DFF_PP1_"))
- D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort("\\R"));
+ if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_PN0_)))
+ D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NN1_), ID($_DFF_PN1_)))
+ D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NP0_), ID($_DFF_PP0_)))
+ D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NP1_), ID($_DFF_PP1_)))
+ D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort(ID::R));
// Remove the $_DFF_* cell from what needs to be a combinatorial box
holes_module->remove(cell);
Wire *port;
@@ -270,17 +208,17 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
dict<IdString, std::vector<IdString>> box_ports;
for (auto cell : module->cells()) {
- if (cell->type == "$__ABC9_FF_")
+ if (cell->type == ID($__ABC9_FF_))
continue;
if (cell->has_keep_attr())
continue;
auto inst_module = module->design->module(cell->type);
- bool abc9_flop = inst_module && inst_module->get_bool_attribute("\\abc9_flop");
+ bool abc9_flop = inst_module && inst_module->get_bool_attribute(ID::abc9_flop);
if (abc9_flop && !dff)
continue;
- if ((inst_module && inst_module->attributes.count("\\abc9_box_id")) || abc9_flop) {
+ if ((inst_module && inst_module->get_bool_attribute(ID::abc9_box)) || abc9_flop) {
auto r = box_ports.insert(cell->type);
if (r.second) {
// Make carry in the last PI, and carry out the last PO
@@ -289,7 +227,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
for (const auto &port_name : inst_module->ports) {
auto w = inst_module->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
@@ -327,8 +265,8 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
for (auto &it : bit_users)
if (bit_drivers.count(it.first))
for (auto driver_cell : bit_drivers.at(it.first))
- for (auto user_cell : it.second)
- toposort.edge(driver_cell, user_cell);
+ for (auto user_cell : it.second)
+ toposort.edge(driver_cell, user_cell);
if (ys_debug(1))
toposort.analyze_loops = true;
@@ -351,9 +289,10 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
RTLIL::Module *holes_module = design->addModule(stringf("%s$holes", module->name.c_str()));
log_assert(holes_module);
- holes_module->set_bool_attribute("\\abc9_holes");
+ holes_module->set_bool_attribute(ID::abc9_holes);
dict<IdString, Cell*> cell_cache;
+ TimingInfo timing;
int port_id = 1, box_count = 0;
for (auto cell_name : toposort.sorted) {
@@ -361,10 +300,10 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
log_assert(cell);
RTLIL::Module* box_module = design->module(cell->type);
- if (!box_module || (!box_module->attributes.count("\\abc9_box_id") && !box_module->get_bool_attribute("\\abc9_flop")))
+ if (!box_module || (!box_module->get_bool_attribute(ID::abc9_box) && !box_module->get_bool_attribute(ID::abc9_flop)))
continue;
- cell->attributes["\\abc9_box_seq"] = box_count++;
+ cell->attributes[ID::abc9_box_seq] = box_count++;
IdString derived_type = box_module->derive(design, cell->parameters);
box_module = design->module(derived_type);
@@ -375,7 +314,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
if (box_module->has_processes())
Pass::call_on_module(design, box_module, "proc");
- if (box_module->get_bool_attribute("\\whitebox")) {
+ if (box_module->get_bool_attribute(ID::whitebox)) {
holes_cell = holes_module->addCell(cell->name, derived_type);
if (box_module->has_processes())
@@ -406,7 +345,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
// For flops only, create an extra 1-bit input that drives a new wire
// called "<cell>.abc9_ff.Q" that is used below
- if (box_module->get_bool_attribute("\\abc9_flop")) {
+ if (box_module->get_bool_attribute(ID::abc9_flop)) {
box_inputs++;
Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
if (!holes_wire) {
@@ -440,19 +379,20 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
}
}
-void prep_delays(RTLIL::Design *design)
+void prep_delays(RTLIL::Design *design, bool dff_mode)
{
- std::set<int> delays;
+ TimingInfo timing;
+
+ // Derive all Yosys blackbox modules that are not combinatorial abc9 boxes
+ // (e.g. DSPs, RAMs, etc.) nor abc9 flops and collect all such instantiations
pool<Module*> flops;
std::vector<Cell*> cells;
- dict<IdString,dict<IdString,std::vector<int>>> requireds_cache;
for (auto module : design->selected_modules()) {
if (module->processes.size() > 0) {
log("Skipping module %s as it contains processes.\n", log_id(module));
continue;
}
- cells.clear();
for (auto cell : module->cells()) {
if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY)))
continue;
@@ -462,144 +402,311 @@ void prep_delays(RTLIL::Design *design)
continue;
if (!inst_module->get_blackbox_attribute())
continue;
- if (inst_module->get_bool_attribute(ID(abc9_flop))) {
- IdString derived_type = inst_module->derive(design, cell->parameters);
- inst_module = design->module(derived_type);
- log_assert(inst_module);
+ if (inst_module->attributes.count(ID::abc9_box))
+ continue;
+ IdString derived_type = inst_module->derive(design, cell->parameters);
+ inst_module = design->module(derived_type);
+ log_assert(inst_module);
+
+ if (dff_mode && inst_module->get_bool_attribute(ID::abc9_flop)) {
flops.insert(inst_module);
- continue; // because all flop required times
- // will be captured in the flop box
+ continue; // do not add $__ABC9_DELAY boxes to flops
+ // as delays will be captured in the flop box
}
- if (inst_module->attributes.count(ID(abc9_box_id)))
- continue;
+
+ if (!timing.count(derived_type))
+ timing.setup_module(inst_module);
+
cells.emplace_back(cell);
}
+ }
- delays.clear();
- for (auto cell : cells) {
- RTLIL::Module* inst_module = module->design->module(cell->type);
- log_assert(inst_module);
- auto &cell_requireds = requireds_cache[cell->type];
- for (auto &conn : cell->connections_) {
- auto port_wire = inst_module->wire(conn.first);
- if (!port_wire->port_input)
+ // Insert $__ABC9_DELAY cells on all cells that instantiate blackboxes
+ // with required times
+ for (auto cell : cells) {
+ auto module = cell->module;
+ RTLIL::Module* inst_module = module->design->module(cell->type);
+ log_assert(inst_module);
+ IdString derived_type = inst_module->derive(design, cell->parameters);
+ inst_module = design->module(derived_type);
+ log_assert(inst_module);
+
+ auto &t = timing.at(derived_type).required;
+ for (auto &conn : cell->connections_) {
+ auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire->port_input)
+ continue;
+
+ SigSpec O = module->addWire(NEW_ID, GetSize(conn.second));
+ for (int i = 0; i < GetSize(conn.second); i++) {
+ auto d = t.at(TimingInfo::NameBit(conn.first,i), 0);
+ if (d == 0)
continue;
- auto r = cell_requireds.insert(conn.first);
- auto &requireds = r.first->second;
- if (r.second) {
- auto it = port_wire->attributes.find("\\abc9_required");
- if (it == port_wire->attributes.end())
+#ifndef NDEBUG
+ if (ys_debug(1)) {
+ static std::set<std::tuple<IdString,IdString,int>> seen;
+ if (seen.emplace(derived_type, conn.first, i).second) log("%s.%s[%d] abc9_required = %d\n",
+ log_id(cell->type), log_id(conn.first), i, d);
+ }
+#endif
+ auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
+ box->setPort(ID::I, conn.second[i]);
+ box->setPort(ID::O, O[i]);
+ box->setParam(ID::DELAY, d);
+ conn.second[i] = O[i];
+ }
+ }
+ }
+}
+
+void prep_lut(RTLIL::Design *design, int maxlut)
+{
+ TimingInfo timing;
+
+ std::vector<std::tuple<int, IdString, int, std::vector<int>>> table;
+ for (auto module : design->modules()) {
+ auto it = module->attributes.find(ID::abc9_lut);
+ if (it == module->attributes.end())
+ continue;
+
+ auto &t = timing.setup_module(module);
+
+ TimingInfo::NameBit o;
+ std::vector<int> specify;
+ for (const auto &i : t.comb) {
+ auto &d = i.first.second;
+ if (o == TimingInfo::NameBit())
+ o = d;
+ else if (o != d)
+ log_error("(* abc9_lut *) module '%s' with has more than one output.\n", log_id(module));
+ specify.push_back(i.second);
+ }
+
+ if (maxlut && GetSize(specify) > maxlut)
+ continue;
+ // ABC requires non-decreasing LUT input delays
+ std::sort(specify.begin(), specify.end());
+ table.emplace_back(GetSize(specify), module->name, it->second.as_int(), std::move(specify));
+ }
+ // ABC requires ascending size
+ std::sort(table.begin(), table.end());
+
+ std::stringstream ss;
+ const auto &first = table.front();
+ // If the first entry does not start from a 1-input LUT,
+ // (as ABC requires) crop the first entry to do so
+ for (int i = 1; i < std::get<0>(first); i++) {
+ ss << "# $__ABC9_LUT" << i << std::endl;
+ ss << i << " " << std::get<2>(first);
+ for (int j = 0; j < i; j++)
+ ss << " " << std::get<3>(first)[j];
+ ss << std::endl;
+ }
+ for (const auto &i : table) {
+ ss << "# " << log_id(std::get<1>(i)) << std::endl;
+ ss << std::get<0>(i) << " " << std::get<2>(i);
+ for (const auto &j : std::get<3>(i))
+ ss << " " << j;
+ ss << std::endl;
+ }
+ design->scratchpad_set_string("abc9_ops.lut_library", ss.str());
+}
+
+void write_lut(RTLIL::Module *module, const std::string &dst) {
+ std::ofstream ofs(dst);
+ log_assert(ofs.is_open());
+ ofs << module->design->scratchpad_get_string("abc9_ops.lut_library");
+ ofs.close();
+}
+
+void prep_box(RTLIL::Design *design, bool dff_mode)
+{
+ TimingInfo timing;
+
+ std::stringstream ss;
+ int abc9_box_id = 1;
+ for (auto module : design->modules()) {
+ auto it = module->attributes.find(ID::abc9_box_id);
+ if (it == module->attributes.end())
+ continue;
+ abc9_box_id = std::max(abc9_box_id, it->second.as_int());
+ }
+
+ dict<IdString,std::vector<IdString>> box_ports;
+ for (auto module : design->modules()) {
+ auto abc9_flop = module->get_bool_attribute(ID::abc9_flop);
+ if (abc9_flop) {
+ auto r = module->attributes.insert(ID::abc9_box_id);
+ if (!r.second)
+ continue;
+ r.first->second = abc9_box_id++;
+
+ if (dff_mode) {
+ int num_inputs = 0, num_outputs = 0;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ log_assert(GetSize(wire) == 1);
+ if (wire->port_input) num_inputs++;
+ if (wire->port_output) num_outputs++;
+ }
+ log_assert(num_outputs == 1);
+
+ ss << log_id(module) << " " << r.first->second.as_int();
+ ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
+ ss << " " << num_inputs+1 << " " << num_outputs << std::endl;
+
+ ss << "#";
+ bool first = true;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ if (!wire->port_input)
continue;
- if (it->second.flags == 0) {
- int delay = it->second.as_int();
- delays.insert(delay);
- requireds.emplace_back(delay);
- }
+ if (first)
+ first = false;
else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- int delay = atoi(tok.c_str());
- delays.insert(delay);
- requireds.push_back(delay);
- }
+ ss << " ";
+ ss << log_id(wire);
}
+ ss << " abc9_ff.Q" << std::endl;
- if (requireds.empty())
- continue;
+ auto &t = timing.setup_module(module).required;
+ first = true;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ if (!wire->port_input)
+ continue;
+ if (first)
+ first = false;
+ else
+ ss << " ";
+ log_assert(GetSize(wire) == 1);
+ auto it = t.find(TimingInfo::NameBit(port_name,0));
+ if (it == t.end())
+ // Assume that no setup time means zero
+ ss << 0;
+ else {
+ ss << it->second;
- SigSpec O = module->addWire(NEW_ID, GetSize(conn.second));
- auto it = requireds.begin();
- for (int i = 0; i < GetSize(conn.second); ++i) {
#ifndef NDEBUG
- if (ys_debug(1)) {
- static std::set<std::pair<IdString,IdString>> seen;
- if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_required = %d\n", log_id(cell->type), log_id(conn.first), requireds[i]);
- }
+ if (ys_debug(1)) {
+ static std::set<std::pair<IdString,IdString>> seen;
+ if (seen.emplace(module->name, port_name).second) log("%s.%s abc9_required = %d\n", log_id(module),
+ log_id(port_name), it->second);
+ }
#endif
- auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
- box->setPort(ID(I), conn.second[i]);
- box->setPort(ID(O), O[i]);
- box->setParam(ID(DELAY), *it);
- if (requireds.size() > 1)
- it++;
- conn.second[i] = O[i];
+ }
+
}
+ // Last input is 'abc9_ff.Q'
+ ss << " 0" << std::endl << std::endl;
+ continue;
}
}
+ else {
+ if (!module->attributes.erase(ID::abc9_box))
+ continue;
- std::stringstream ss;
- bool first = true;
- for (auto d : delays) {
- if (first)
- first = false;
- else
- ss << " ";
- ss << d;
+ auto r = module->attributes.insert(ID::abc9_box_id);
+ if (!r.second)
+ continue;
+ r.first->second = abc9_box_id++;
}
- module->attributes[ID(abc9_delays)] = ss.str();
- }
- int flops_id = ABC9_FLOPS_BASE_ID;
- std::stringstream ss;
- for (auto flop_module : flops) {
- int num_inputs = 0, num_outputs = 0;
- for (auto port_name : flop_module->ports) {
- auto wire = flop_module->wire(port_name);
- if (wire->port_input) num_inputs++;
- if (wire->port_output) num_outputs++;
+ auto r = box_ports.insert(module->name);
+ if (r.second) {
+ // Make carry in the last PI, and carry out the last PO
+ // since ABC requires it this way
+ IdString carry_in, carry_out;
+ for (const auto &port_name : module->ports) {
+ auto w = module->wire(port_name);
+ log_assert(w);
+ if (w->get_bool_attribute(ID::abc9_carry)) {
+ log_assert(w->port_input != w->port_output);
+ if (w->port_input)
+ carry_in = port_name;
+ else if (w->port_output)
+ carry_out = port_name;
+ }
+ else
+ r.first->second.push_back(port_name);
+ }
+
+ if (carry_in != IdString()) {
+ r.first->second.push_back(carry_in);
+ r.first->second.push_back(carry_out);
+ }
+ }
+
+ std::vector<SigBit> inputs;
+ std::vector<SigBit> outputs;
+ for (auto port_name : r.first->second) {
+ auto wire = module->wire(port_name);
+ if (wire->port_input)
+ for (int i = 0; i < GetSize(wire); i++)
+ inputs.emplace_back(wire, i);
+ if (wire->port_output)
+ for (int i = 0; i < GetSize(wire); i++)
+ outputs.emplace_back(wire, i);
}
- log_assert(num_outputs == 1);
- auto r = flop_module->attributes.insert(ID(abc9_box_id));
- if (r.second)
- r.first->second = flops_id++;
+ ss << log_id(module) << " " << module->attributes.at(ID::abc9_box_id).as_int();
+ ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
+ ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl;
- ss << log_id(flop_module) << " " << r.first->second.as_int();
- ss << " 1 " << num_inputs+1 << " " << num_outputs << std::endl;
bool first = true;
- for (auto port_name : flop_module->ports) {
- auto wire = flop_module->wire(port_name);
- if (!wire->port_input)
- continue;
+ ss << "#";
+ for (const auto &i : inputs) {
if (first)
first = false;
else
ss << " ";
- ss << wire->attributes.at("\\abc9_required", 0).as_int();
+ if (GetSize(i.wire) == 1)
+ ss << log_id(i.wire);
+ else
+ ss << log_id(i.wire) << "[" << i.offset << "]";
}
- // Last input is 'abc9_ff.Q'
- ss << " 0" << std::endl << std::endl;
- }
- design->scratchpad_set_string("abc9_ops.box.flops", ss.str());
-}
-
-void write_box(RTLIL::Module *module, const std::string &src, const std::string &dst) {
- std::ofstream ofs(dst);
- log_assert(ofs.is_open());
+ ss << std::endl;
- // Since ABC can only accept one box file, we have to copy
- // over the existing box file
- if (src != "(null)") {
- std::ifstream ifs(src);
- ofs << ifs.rdbuf() << std::endl;
- ifs.close();
- }
+ auto &t = timing.setup_module(module).comb;
+ if (!abc9_flop && t.empty())
+ log_warning("(* abc9_box *) module '%s' has no timing (and thus no connectivity) information.\n", log_id(module));
- ofs << module->design->scratchpad_get_string("abc9_ops.box.flops");
+ for (const auto &o : outputs) {
+ first = true;
+ for (const auto &i : inputs) {
+ if (first)
+ first = false;
+ else
+ ss << " ";
+ auto jt = t.find(TimingInfo::BitBit(i,o));
+ if (jt == t.end())
+ ss << "-";
+ else
+ ss << jt->second;
+ }
+ ss << " # ";
+ if (GetSize(o.wire) == 1)
+ ss << log_id(o.wire);
+ else
+ ss << log_id(o.wire) << "[" << o.offset << "]";
+ ss << std::endl;
- auto it = module->attributes.find(ID(abc9_delays));
- if (it != module->attributes.end()) {
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- int d = atoi(tok.c_str());
- ofs << "$__ABC9_DELAY@" << d << " " << ABC9_DELAY_BASE_ID + d << " 0 1 1" << std::endl;
- ofs << d << std::endl;
}
- module->attributes.erase(it);
+ ss << std::endl;
}
- if (ofs.tellp() == 0)
- ofs << "(dummy) 1 0 0 0";
+ // ABC expects at least one box
+ if (ss.tellp() == 0)
+ ss << "(dummy) 1 0 0 0";
+
+ design->scratchpad_set_string("abc9_ops.box_library", ss.str());
+}
+void write_box(RTLIL::Module *module, const std::string &dst) {
+ std::ofstream ofs(dst);
+ log_assert(ofs.is_open());
+ ofs << module->design->scratchpad_get_string("abc9_ops.box_library");
ofs.close();
}
@@ -620,7 +727,7 @@ void reintegrate(RTLIL::Module *module)
dict<IdString,std::vector<IdString>> box_ports;
for (auto m : design->modules()) {
- if (!m->attributes.count(ID(abc9_box_id)))
+ if (!m->attributes.count(ID::abc9_box_id))
continue;
auto r = box_ports.insert(m->name);
@@ -633,7 +740,7 @@ void reintegrate(RTLIL::Module *module)
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
@@ -656,7 +763,7 @@ void reintegrate(RTLIL::Module *module)
continue;
if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
module->remove(cell);
- else if (cell->attributes.erase("\\abc9_box_seq"))
+ else if (cell->attributes.erase(ID::abc9_box_seq))
boxes.emplace_back(cell);
}
@@ -763,13 +870,11 @@ void reintegrate(RTLIL::Module *module)
continue;
}
-#ifndef NDEBUG
RTLIL::Module* box_module = design->module(existing_cell->type);
IdString derived_type = box_module->derive(design, existing_cell->parameters);
RTLIL::Module* derived_module = design->module(derived_type);
log_assert(derived_module);
- log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at("\\abc9_box_id").as_int()));
-#endif
+ log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at(ID::abc9_box_id).as_int()));
mapped_cell->type = existing_cell->type;
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
@@ -777,16 +882,16 @@ void reintegrate(RTLIL::Module *module)
cell->attributes = existing_cell->attributes;
module->swap_names(cell, existing_cell);
- auto jt = mapped_cell->connections_.find("\\i");
+ auto jt = mapped_cell->connections_.find(ID(i));
log_assert(jt != mapped_cell->connections_.end());
SigSpec inputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
- jt = mapped_cell->connections_.find("\\o");
+ jt = mapped_cell->connections_.find(ID(o));
log_assert(jt != mapped_cell->connections_.end());
SigSpec outputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
- auto abc9_flop = box_module->attributes.count("\\abc9_flop");
+ auto abc9_flop = box_module->attributes.count(ID::abc9_flop);
if (!abc9_flop) {
for (const auto &i : inputs)
bit_users[i].insert(mapped_cell->name);
@@ -861,10 +966,8 @@ void reintegrate(RTLIL::Module *module)
RTLIL::Wire *mapped_wire = mapped_mod->wire(port);
RTLIL::Wire *wire = module->wire(port);
log_assert(wire);
- if (wire->attributes.erase(ID(abc9_scc_id))) {
- auto r YS_ATTRIBUTE(unused) = wire->attributes.erase(ID::keep);
- log_assert(r);
- }
+ wire->attributes.erase(ID::abc9_scc);
+
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
log_assert(GetSize(signal) >= GetSize(remap_wire));
@@ -930,7 +1033,7 @@ void reintegrate(RTLIL::Module *module)
// Push downstream LUTs past inverter
for (auto sink_cell : jt->second) {
SigSpec A = sink_cell->getPort(ID::A);
- RTLIL::Const mask = sink_cell->getParam(ID(LUT));
+ RTLIL::Const mask = sink_cell->getParam(ID::LUT);
int index = 0;
for (; index < GetSize(A); index++)
if (A[index] == a_bit)
@@ -944,7 +1047,7 @@ void reintegrate(RTLIL::Module *module)
}
A[index] = y_bit;
sink_cell->setPort(ID::A, A);
- sink_cell->setParam(ID(LUT), mask);
+ sink_cell->setParam(ID::LUT, mask);
}
// Since we have rewritten all sinks (which we know
@@ -953,7 +1056,7 @@ void reintegrate(RTLIL::Module *module)
// that the original driving LUT will become dangling
// and get cleaned away
clone_lut:
- driver_mask = driver_lut->getParam(ID(LUT));
+ driver_mask = driver_lut->getParam(ID::LUT);
for (auto &b : driver_mask.bits) {
if (b == RTLIL::State::S0) b = RTLIL::State::S1;
else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
@@ -993,7 +1096,7 @@ struct Abc9OpsPass : public Pass {
log("\n");
log(" -prep_delays\n");
log(" insert `$__ABC9_DELAY' blackbox cells into the design to account for\n");
- log(" certain delays, e.g. (* abc9_required *) values.\n");
+ log(" certain required times.\n");
log("\n");
log(" -mark_scc\n");
log(" for an arbitrarily chosen cell in each unique SCC of each selected module\n");
@@ -1008,16 +1111,26 @@ struct Abc9OpsPass : public Pass {
log(" whiteboxes.\n");
log("\n");
log(" -dff\n");
- log(" consider flop cells (those instantiating modules marked with (* abc9_flop *)\n");
- log(" during -prep_xaiger.\n");
+ log(" consider flop cells (those instantiating modules marked with (* abc9_flop *))\n");
+ log(" during -prep_{delays,xaiger,box}.\n");
log("\n");
log(" -prep_dff\n");
log(" compute the clock domain and initial value of each flop in the design.\n");
log(" process the '$holes' module to support clock-enable functionality.\n");
log("\n");
- log(" -write_box (<src>|(null)) <dst>\n");
- log(" copy the existing box file from <src> (skip if '(null)') and append any\n");
- log(" new box definitions.\n");
+ log(" -prep_lut <maxlut>\n");
+ log(" pre-compute the lut library by analysing all modules marked with\n");
+ log(" (* abc9_lut=<area> *).\n");
+ log("\n");
+ log(" -write_lut <dst>\n");
+ log(" write the pre-computed lut library to <dst>.\n");
+ log("\n");
+ log(" -prep_box\n");
+ log(" pre-compute the box library by analysing all modules marked with\n");
+ log(" (* abc9_box *).\n");
+ log("\n");
+ log(" -write_box <dst>\n");
+ log(" write the pre-computed box library to <dst>.\n");
log("\n");
log(" -reintegrate\n");
log(" for each selected module, re-intergrate the module '<module-name>$abc9'\n");
@@ -1034,9 +1147,13 @@ struct Abc9OpsPass : public Pass {
bool mark_scc_mode = false;
bool prep_dff_mode = false;
bool prep_xaiger_mode = false;
+ bool prep_lut_mode = false;
+ bool prep_box_mode = false;
bool reintegrate_mode = false;
bool dff_mode = false;
- std::string write_box_src, write_box_dst;
+ std::string write_lut_dst;
+ int maxlut = 0;
+ std::string write_box_dst;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -1061,10 +1178,25 @@ struct Abc9OpsPass : public Pass {
prep_delays_mode = true;
continue;
}
- if (arg == "-write_box" && argidx+2 < args.size()) {
- write_box_src = args[++argidx];
+ if (arg == "-prep_lut" && argidx+1 < args.size()) {
+ prep_lut_mode = true;
+ maxlut = atoi(args[++argidx].c_str());
+ continue;
+ }
+ if (arg == "-maxlut" && argidx+1 < args.size()) {
+ continue;
+ }
+ if (arg == "-write_lut" && argidx+1 < args.size()) {
+ write_lut_dst = args[++argidx];
+ rewrite_filename(write_lut_dst);
+ continue;
+ }
+ if (arg == "-prep_box") {
+ prep_box_mode = true;
+ continue;
+ }
+ if (arg == "-write_box" && argidx+1 < args.size()) {
write_box_dst = args[++argidx];
- rewrite_filename(write_box_src);
rewrite_filename(write_box_dst);
continue;
}
@@ -1080,19 +1212,23 @@ struct Abc9OpsPass : public Pass {
}
extra_args(args, argidx, design);
- if (!(check_mode || mark_scc_mode || prep_delays_mode || prep_xaiger_mode || prep_dff_mode || !write_box_src.empty() || reintegrate_mode))
- log_cmd_error("At least one of -check, -mark_scc, -prep_{delays,xaiger,dff}, -write_box, -reintegrate must be specified.\n");
+ if (!(check_mode || mark_scc_mode || prep_delays_mode || prep_xaiger_mode || prep_dff_mode || prep_lut_mode || prep_box_mode || !write_lut_dst.empty() || !write_box_dst.empty() || reintegrate_mode))
+ log_cmd_error("At least one of -check, -mark_scc, -prep_{delays,xaiger,dff,lut,box}, -write_{lut,box}, -reintegrate must be specified.\n");
- if (dff_mode && !prep_xaiger_mode)
- log_cmd_error("'-dff' option is only relevant for -prep_xaiger.\n");
+ if (dff_mode && !prep_delays_mode && !prep_xaiger_mode && !prep_box_mode)
+ log_cmd_error("'-dff' option is only relevant for -prep_{delay,xaiger,box}.\n");
if (check_mode)
check(design);
if (prep_delays_mode)
- prep_delays(design);
+ prep_delays(design, dff_mode);
+ if (prep_lut_mode)
+ prep_lut(design, maxlut);
+ if (prep_box_mode)
+ prep_box(design, dff_mode);
for (auto mod : design->selected_modules()) {
- if (mod->get_bool_attribute("\\abc9_holes"))
+ if (mod->get_bool_attribute(ID::abc9_holes))
continue;
if (mod->processes.size() > 0) {
@@ -1103,8 +1239,10 @@ struct Abc9OpsPass : public Pass {
if (!design->selected_whole_module(mod))
log_error("Can't handle partially selected module %s!\n", log_id(mod));
- if (!write_box_src.empty())
- write_box(mod, write_box_src, write_box_dst);
+ if (!write_lut_dst.empty())
+ write_lut(mod, write_lut_dst);
+ if (!write_box_dst.empty())
+ write_box(mod, write_box_dst);
if (mark_scc_mode)
mark_scc(mod);
if (prep_dff_mode)
diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc
index 034731b87..1925145d3 100644
--- a/passes/techmap/alumacc.cc
+++ b/passes/techmap/alumacc.cc
@@ -72,7 +72,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_eq() {
if (GetSize(cached_eq) == 0)
- cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(X)), false, alu_cell->get_src_attribute());
+ cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID::X), false, alu_cell->get_src_attribute());
return cached_eq;
}
@@ -84,7 +84,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_cf() {
if (GetSize(cached_cf) == 0) {
- cached_cf = alu_cell->getPort(ID(CO));
+ cached_cf = alu_cell->getPort(ID::CO);
log_assert(GetSize(cached_cf) >= 1);
cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute());
}
@@ -93,7 +93,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_of() {
if (GetSize(cached_of) == 0) {
- cached_of = {alu_cell->getPort(ID(CO)), alu_cell->getPort(ID(CI))};
+ cached_of = {alu_cell->getPort(ID::CO), alu_cell->getPort(ID::CI)};
log_assert(GetSize(cached_of) >= 2);
cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]);
}
@@ -154,7 +154,7 @@ struct AlumaccWorker
if (cell->type.in(ID($pos), ID($neg)))
{
new_port.in_a = sigmap(cell->getPort(ID::A));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = cell->type == ID($neg);
n->macc.ports.push_back(new_port);
}
@@ -162,12 +162,12 @@ struct AlumaccWorker
if (cell->type.in(ID($add), ID($sub)))
{
new_port.in_a = sigmap(cell->getPort(ID::A));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = false;
n->macc.ports.push_back(new_port);
new_port.in_a = sigmap(cell->getPort(ID::B));
- new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::B_SIGNED).as_bool();
new_port.do_subtract = cell->type == ID($sub);
n->macc.ports.push_back(new_port);
}
@@ -176,7 +176,7 @@ struct AlumaccWorker
{
new_port.in_a = sigmap(cell->getPort(ID::A));
new_port.in_b = sigmap(cell->getPort(ID::B));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = false;
n->macc.ports.push_back(new_port);
}
@@ -399,7 +399,7 @@ struct AlumaccWorker
bool cmp_less = cell->type.in(ID($lt), ID($le));
bool cmp_equal = cell->type.in(ID($le), ID($ge));
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
@@ -439,7 +439,7 @@ struct AlumaccWorker
for (auto cell : eq_cells)
{
bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
@@ -495,11 +495,11 @@ struct AlumaccWorker
n->alu_cell->setPort(ID::A, n->a);
n->alu_cell->setPort(ID::B, n->b);
- n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0);
- n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0);
+ n->alu_cell->setPort(ID::CI, GetSize(n->c) ? n->c : State::S0);
+ n->alu_cell->setPort(ID::BI, n->invert_b ? State::S1 : State::S0);
n->alu_cell->setPort(ID::Y, n->y);
- n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y)));
- n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y)));
+ n->alu_cell->setPort(ID::X, module->addWire(NEW_ID, GetSize(n->y)));
+ n->alu_cell->setPort(ID::CO, module->addWire(NEW_ID, GetSize(n->y)));
n->alu_cell->fixup_parameters(n->is_signed, n->is_signed);
for (auto &it : n->cmp)
diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc
index b9cd68883..3f4b6aa66 100644
--- a/passes/techmap/clkbufmap.cc
+++ b/passes/techmap/clkbufmap.cc
@@ -129,13 +129,13 @@ struct ClkbufmapPass : public Pass {
if (module->get_blackbox_attribute()) {
for (auto port : module->ports) {
auto wire = module->wire(port);
- if (wire->get_bool_attribute("\\clkbuf_driver"))
+ if (wire->get_bool_attribute(ID::clkbuf_driver))
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
- if (wire->get_bool_attribute("\\clkbuf_sink"))
+ if (wire->get_bool_attribute(ID::clkbuf_sink))
for (int i = 0; i < GetSize(wire); i++)
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
- auto it = wire->attributes.find("\\clkbuf_inv");
+ auto it = wire->attributes.find(ID::clkbuf_inv);
if (it != wire->attributes.end()) {
IdString in_name = RTLIL::escape_id(it->second.decode_string());
for (int i = 0; i < GetSize(wire); i++) {
@@ -215,7 +215,7 @@ struct ClkbufmapPass : public Pass {
if (wire->port_input && wire->port_output)
continue;
bool process_wire = module->selected(wire);
- if (!select && wire->get_bool_attribute("\\clkbuf_inhibit"))
+ if (!select && wire->get_bool_attribute(ID::clkbuf_inhibit))
process_wire = false;
if (!process_wire) {
// This wire is supposed to be bypassed, so make sure we don't buffer it in
@@ -238,7 +238,7 @@ struct ClkbufmapPass : public Pass {
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
} else if (!sink_wire_bits.count(mapped_wire_bit)) {
// Nothing to do.
- } else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute("\\top"))) {
+ } else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) {
// Clock network not yet buffered, driven by one of
// our cells or a top-level input -- buffer it.
@@ -247,7 +247,7 @@ struct ClkbufmapPass : public Pass {
Wire *iwire = module->addWire(NEW_ID);
cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
- if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute("\\top")) {
+ if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top)) {
log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i);
RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype));
cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc
index b976b401b..a7dce9c81 100644
--- a/passes/techmap/deminout.cc
+++ b/passes/techmap/deminout.cc
@@ -113,7 +113,7 @@ struct DeminoutPass : public Pass {
{
if (bits_numports[bit] > 1 || bits_inout.count(bit))
new_input = true, new_output = true;
- if (bit == State::S0 || bit == State::S1)
+ if (!bit.wire)
new_output = true;
if (bits_written.count(bit)) {
new_output = true;
@@ -121,8 +121,7 @@ struct DeminoutPass : public Pass {
goto tribuf_bit;
} else {
tribuf_bit:
- if (bits_used.count(bit))
- new_input = true;
+ new_input = true;
}
}
diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc
index 0242256e5..aa9bbfe17 100644
--- a/passes/techmap/dff2dffe.cc
+++ b/passes/techmap/dff2dffe.cc
@@ -88,7 +88,7 @@ struct Dff2dffeWorker
cell_int_t mux_cell_int = bit2mux.at(d);
RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A));
RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B));
- RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(S)));
+ RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID::S));
int width = GetSize(sig_a), index = mux_cell_int.second;
for (int i = 0; i < GetSize(sig_s); i++)
@@ -185,8 +185,8 @@ struct Dff2dffeWorker
void handle_dff_cell(RTLIL::Cell *dff_cell)
{
- RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D)));
- RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(Q)));
+ RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID::D));
+ RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID::Q));
std::map<patterns_t, std::set<int>> grouped_patterns;
std::set<int> remaining_indices;
@@ -208,15 +208,15 @@ struct Dff2dffeWorker
}
if (!direct_dict.empty()) {
log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q));
- dff_cell->setPort(ID(E), make_patterns_logic(it.first, true));
+ dff_cell->setPort(ID::E, make_patterns_logic(it.first, true));
dff_cell->type = direct_dict.at(dff_cell->type);
} else
if (dff_cell->type == ID($dff)) {
- RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID(CLK)), make_patterns_logic(it.first, false),
- new_sig_d, new_sig_q, dff_cell->getParam(ID(CLK_POLARITY)).as_bool(), true);
+ RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID::CLK), make_patterns_logic(it.first, false),
+ new_sig_d, new_sig_q, dff_cell->getParam(ID::CLK_POLARITY).as_bool(), true);
log(" created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
} else {
- RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID(C)), make_patterns_logic(it.first, true),
+ RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID::C), make_patterns_logic(it.first, true),
new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true);
log(" created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
}
@@ -235,9 +235,9 @@ struct Dff2dffeWorker
new_sig_d.append(sig_d[i]);
new_sig_q.append(sig_q[i]);
}
- dff_cell->setPort(ID(D), new_sig_d);
- dff_cell->setPort(ID(Q), new_sig_q);
- dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices));
+ dff_cell->setPort(ID::D, new_sig_d);
+ dff_cell->setPort(ID::Q, new_sig_q);
+ dff_cell->setParam(ID::WIDTH, GetSize(remaining_indices));
}
}
@@ -361,19 +361,19 @@ struct Dff2dffePass : public Pass {
for (auto cell_other : mod->selected_cells()) {
if (cell_other->type != cell->type)
continue;
- if (sigmap(cell->getPort(ID(EN))) == sigmap(cell_other->getPort(ID(EN))))
+ if (sigmap(cell->getPort(ID::EN)) == sigmap(cell_other->getPort(ID::EN)))
ce_use++;
}
if (ce_use >= min_ce_use)
continue;
}
- RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(D))));
- mod->addDff(NEW_ID, cell->getPort(ID(CLK)), tmp, cell->getPort(ID(Q)), cell->getParam(ID(CLK_POLARITY)).as_bool());
- if (cell->getParam(ID(EN_POLARITY)).as_bool())
- mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(EN)), tmp);
+ RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID::D)));
+ mod->addDff(NEW_ID, cell->getPort(ID::CLK), tmp, cell->getPort(ID::Q), cell->getParam(ID::CLK_POLARITY).as_bool());
+ if (cell->getParam(ID::EN_POLARITY).as_bool())
+ mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::EN), tmp);
else
- mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(EN)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::EN), tmp);
mod->remove(cell);
continue;
}
@@ -383,7 +383,7 @@ struct Dff2dffePass : public Pass {
for (auto cell_other : mod->selected_cells()) {
if (cell_other->type != cell->type)
continue;
- if (sigmap(cell->getPort(ID(E))) == sigmap(cell_other->getPort(ID(E))))
+ if (sigmap(cell->getPort(ID::E)) == sigmap(cell_other->getPort(ID::E)))
ce_use++;
}
if (ce_use >= min_ce_use)
@@ -393,11 +393,11 @@ struct Dff2dffePass : public Pass {
bool clk_pol = cell->type.compare(7, 1, "P") == 0;
bool en_pol = cell->type.compare(8, 1, "P") == 0;
RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
- mod->addDff(NEW_ID, cell->getPort(ID(C)), tmp, cell->getPort(ID(Q)), clk_pol);
+ mod->addDff(NEW_ID, cell->getPort(ID::C), tmp, cell->getPort(ID::Q), clk_pol);
if (en_pol)
- mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(E)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::E), tmp);
else
- mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(E)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::E), tmp);
mod->remove(cell);
continue;
}
diff --git a/passes/techmap/dff2dffs.cc b/passes/techmap/dff2dffs.cc
index 3fa1ed5cf..c155297d9 100644
--- a/passes/techmap/dff2dffs.cc
+++ b/passes/techmap/dff2dffs.cc
@@ -90,7 +90,7 @@ struct Dff2dffsPass : public Pass {
for (auto cell : ff_cells)
{
- SigSpec sig_d = cell->getPort(ID(D));
+ SigSpec sig_d = cell->getPort(ID::D);
if (GetSize(sig_d) < 1)
continue;
@@ -103,7 +103,7 @@ struct Dff2dffsPass : public Pass {
Cell *mux_cell = sr_muxes.at(bit_d);
SigBit bit_a = sigmap(mux_cell->getPort(ID::A));
SigBit bit_b = sigmap(mux_cell->getPort(ID::B));
- SigBit bit_s = sigmap(mux_cell->getPort(ID(S)));
+ SigBit bit_s = sigmap(mux_cell->getPort(ID::S));
SigBit sr_val, sr_sig;
bool invert_sr;
@@ -120,9 +120,9 @@ struct Dff2dffsPass : public Pass {
}
if (match_init) {
- SigBit bit_q = cell->getPort(ID(Q));
+ SigBit bit_q = cell->getPort(ID::Q);
if (bit_q.wire) {
- auto it = bit_q.wire->attributes.find(ID(init));
+ auto it = bit_q.wire->attributes.find(ID::init);
if (it != bit_q.wire->attributes.end()) {
auto init_val = it->second[bit_q.offset];
if (init_val == State::S1 && sr_val != State::S1)
@@ -155,8 +155,8 @@ struct Dff2dffsPass : public Pass {
else cell->type = ID($__DFFS_PP0_);
}
}
- cell->setPort(ID(R), sr_sig);
- cell->setPort(ID(D), bit_d);
+ cell->setPort(ID::R, sr_sig);
+ cell->setPort(ID::D, bit_d);
}
}
}
diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc
index cf9301442..0424ce434 100644
--- a/passes/techmap/dffinit.cc
+++ b/passes/techmap/dffinit.cc
@@ -99,8 +99,8 @@ struct DffinitPass : public Pass {
pool<SigBit> used_bits;
for (auto wire : module->selected_wires()) {
- if (wire->attributes.count(ID(init))) {
- Const value = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init)) {
+ Const value = wire->attributes.at(ID::init);
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
if (value[i] != State::Sx)
init_bits[sigmap(SigBit(wire, i))] = value[i];
@@ -161,8 +161,8 @@ struct DffinitPass : public Pass {
}
for (auto wire : module->selected_wires())
- if (wire->attributes.count(ID(init))) {
- Const &value = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init)) {
+ Const &value = wire->attributes.at(ID::init);
bool do_cleanup = true;
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
SigBit bit = sigmap(SigBit(wire, i));
@@ -173,7 +173,7 @@ struct DffinitPass : public Pass {
}
if (do_cleanup) {
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
}
}
}
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc
index b15109cd3..aa344cf8a 100644
--- a/passes/techmap/dfflibmap.cc
+++ b/passes/techmap/dfflibmap.cc
@@ -78,7 +78,7 @@ static void logmap_all()
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
{
- if (cell == NULL || attr == NULL || attr->value.empty())
+ if (cell == nullptr || attr == nullptr || attr->value.empty())
return false;
std::string value = attr->value;
@@ -117,7 +117,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode)
{
- LibertyAst *best_cell = NULL;
+ LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
@@ -132,11 +132,11 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue;
LibertyAst *dn = cell->find("dont_use");
- if (dn != NULL && dn->value == "true")
+ if (dn != nullptr && dn->value == "true")
continue;
LibertyAst *ff = cell->find("ff");
- if (ff == NULL)
+ if (ff == nullptr)
continue;
std::string cell_clk_pin, cell_rst_pin, cell_next_pin;
@@ -163,7 +163,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
double area = 0;
LibertyAst *ar = cell->find("area");
- if (ar != NULL && !ar->value.empty())
+ if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());
int num_pins = 0;
@@ -175,7 +175,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue;
LibertyAst *dir = pin->find("direction");
- if (dir == NULL || dir->value == "internal")
+ if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;
@@ -183,7 +183,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
goto continue_cell_loop;
LibertyAst *func = pin->find("function");
- if (dir->value == "output" && func != NULL) {
+ if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
value.erase(pos, 1);
@@ -205,10 +205,10 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
this_cell_ports[pin->args[0]] = 0;
}
- if (!found_output || (best_cell != NULL && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
+ if (!found_output || (best_cell != nullptr && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
continue;
- if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
+ if (best_cell != nullptr && num_pins == best_cell_pins && area > best_cell_area)
continue;
best_cell = cell;
@@ -219,7 +219,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue_cell_loop:;
}
- if (best_cell != NULL) {
+ if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
if (prepare_mode) {
@@ -238,7 +238,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode)
{
- LibertyAst *best_cell = NULL;
+ LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
@@ -253,11 +253,11 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue;
LibertyAst *dn = cell->find("dont_use");
- if (dn != NULL && dn->value == "true")
+ if (dn != nullptr && dn->value == "true")
continue;
LibertyAst *ff = cell->find("ff");
- if (ff == NULL)
+ if (ff == nullptr)
continue;
std::string cell_clk_pin, cell_set_pin, cell_clr_pin, cell_next_pin;
@@ -280,7 +280,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
double area = 0;
LibertyAst *ar = cell->find("area");
- if (ar != NULL && !ar->value.empty())
+ if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());
int num_pins = 0;
@@ -292,7 +292,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue;
LibertyAst *dir = pin->find("direction");
- if (dir == NULL || dir->value == "internal")
+ if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;
@@ -300,7 +300,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
goto continue_cell_loop;
LibertyAst *func = pin->find("function");
- if (dir->value == "output" && func != NULL) {
+ if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
value.erase(pos, 1);
@@ -322,10 +322,10 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
this_cell_ports[pin->args[0]] = 0;
}
- if (!found_output || (best_cell != NULL && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
+ if (!found_output || (best_cell != nullptr && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
continue;
- if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
+ if (best_cell != nullptr && num_pins == best_cell_pins && area > best_cell_area)
continue;
best_cell = cell;
@@ -336,7 +336,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue_cell_loop:;
}
- if (best_cell != NULL) {
+ if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
if (prepare_mode) {
@@ -481,11 +481,11 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
SigMap sigmap(module);
std::vector<RTLIL::Cell*> cell_list;
- for (auto &it : module->cells_) {
- if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
- cell_list.push_back(it.second);
- if (it.second->type == ID($_NOT_))
- notmap[sigmap(it.second->getPort(ID::A))].insert(it.second);
+ for (auto cell : module->cells()) {
+ if (design->selected(module, cell) && cell_mappings.count(cell->type) > 0)
+ cell_list.push_back(cell);
+ if (cell->type == ID($_NOT_))
+ notmap[sigmap(cell->getPort(ID::A))].insert(cell);
}
std::map<std::string, int> stats;
@@ -663,9 +663,9 @@ struct DfflibmapPass : public Pass {
log(" final dff cell mappings:\n");
logmap_all();
- for (auto &it : design->modules_)
- if (design->selected(it.second) && !it.second->get_blackbox_attribute())
- dfflibmap(design, it.second, prepare_mode);
+ for (auto module : design->selected_modules())
+ if (!module->get_blackbox_attribute())
+ dfflibmap(design, module, prepare_mode);
cell_mappings.clear();
}
diff --git a/passes/techmap/dffsr2dff.cc b/passes/techmap/dffsr2dff.cc
index 61b06fdc1..4a3ddaf73 100644
--- a/passes/techmap/dffsr2dff.cc
+++ b/passes/techmap/dffsr2dff.cc
@@ -27,15 +27,15 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
{
if (cell->type == ID($dffsr))
{
- int width = cell->getParam(ID(WIDTH)).as_int();
- bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool();
- bool clrpol = cell->getParam(ID(CLR_POLARITY)).as_bool();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ bool setpol = cell->getParam(ID::SET_POLARITY).as_bool();
+ bool clrpol = cell->getParam(ID::CLR_POLARITY).as_bool();
SigBit setunused = setpol ? State::S0 : State::S1;
SigBit clrunused = clrpol ? State::S0 : State::S1;
- SigSpec setsig = sigmap(cell->getPort(ID(SET)));
- SigSpec clrsig = sigmap(cell->getPort(ID(CLR)));
+ SigSpec setsig = sigmap(cell->getPort(ID::SET));
+ SigSpec clrsig = sigmap(cell->getPort(ID::CLR));
Const reset_val;
SigSpec setctrl, clrctrl;
@@ -78,19 +78,19 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
if (GetSize(setctrl) == 1) {
- cell->setPort(ID(ARST), setctrl);
- cell->setParam(ID(ARST_POLARITY), setpol);
+ cell->setPort(ID::ARST, setctrl);
+ cell->setParam(ID::ARST_POLARITY, setpol);
} else {
- cell->setPort(ID(ARST), clrctrl);
- cell->setParam(ID(ARST_POLARITY), clrpol);
+ cell->setPort(ID::ARST, clrctrl);
+ cell->setParam(ID::ARST_POLARITY, clrpol);
}
cell->type = ID($adff);
- cell->unsetPort(ID(SET));
- cell->unsetPort(ID(CLR));
- cell->setParam(ID(ARST_VALUE), reset_val);
- cell->unsetParam(ID(SET_POLARITY));
- cell->unsetParam(ID(CLR_POLARITY));
+ cell->unsetPort(ID::SET);
+ cell->unsetPort(ID::CLR);
+ cell->setParam(ID::ARST_VALUE, reset_val);
+ cell->unsetParam(ID::SET_POLARITY);
+ cell->unsetParam(ID::CLR_POLARITY);
return;
}
@@ -102,8 +102,8 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
char setpol = cell->type.c_str()[9];
char clrpol = cell->type.c_str()[10];
- SigBit setbit = sigmap(cell->getPort(ID(S)));
- SigBit clrbit = sigmap(cell->getPort(ID(R)));
+ SigBit setbit = sigmap(cell->getPort(ID::S));
+ SigBit clrbit = sigmap(cell->getPort(ID::R));
SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;
@@ -112,14 +112,14 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
if (setbit == setunused) {
cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
goto converted_gate;
}
if (clrbit == clrunused) {
cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
- cell->setPort(ID(R), cell->getPort(ID(S)));
- cell->unsetPort(ID(S));
+ cell->setPort(ID::R, cell->getPort(ID::S));
+ cell->unsetPort(ID::S);
goto converted_gate;
}
@@ -135,9 +135,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
{
if (cell->type == ID($adff))
{
- bool rstpol = cell->getParam(ID(ARST_POLARITY)).as_bool();
+ bool rstpol = cell->getParam(ID::ARST_POLARITY).as_bool();
SigBit rstunused = rstpol ? State::S0 : State::S1;
- SigSpec rstsig = sigmap(cell->getPort(ID(ARST)));
+ SigSpec rstsig = sigmap(cell->getPort(ID::ARST));
if (rstsig != rstunused)
return;
@@ -145,9 +145,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));
cell->type = ID($dff);
- cell->unsetPort(ID(ARST));
- cell->unsetParam(ID(ARST_VALUE));
- cell->unsetParam(ID(ARST_POLARITY));
+ cell->unsetPort(ID::ARST);
+ cell->unsetParam(ID::ARST_VALUE);
+ cell->unsetParam(ID::ARST_POLARITY);
return;
}
@@ -158,7 +158,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
char clkpol = cell->type.c_str()[6];
char rstpol = cell->type.c_str()[7];
- SigBit rstbit = sigmap(cell->getPort(ID(R)));
+ SigBit rstbit = sigmap(cell->getPort(ID::R));
SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;
if (rstbit != rstunused)
@@ -168,7 +168,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));
cell->type = newtype;
- cell->unsetPort(ID(R));
+ cell->unsetPort(ID::R);
return;
}
diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc
index f8798eea5..f29044790 100644
--- a/passes/techmap/extract.cc
+++ b/passes/techmap/extract.cc
@@ -29,8 +29,6 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-using RTLIL::id2cstr;
-
class SubCircuitSolver : public SubCircuit::Solver
{
public:
@@ -58,36 +56,36 @@ public:
return value;
#define param_bool(_n) if (param == _n) return value.as_bool();
- param_bool(ID(ARST_POLARITY));
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- param_bool(ID(CLK_ENABLE));
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(CLR_POLARITY));
- param_bool(ID(EN_POLARITY));
- param_bool(ID(SET_POLARITY));
- param_bool(ID(TRANSPARENT));
+ param_bool(ID::ARST_POLARITY);
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ param_bool(ID::CLK_ENABLE);
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::CLR_POLARITY);
+ param_bool(ID::EN_POLARITY);
+ param_bool(ID::SET_POLARITY);
+ param_bool(ID::TRANSPARENT);
#undef param_bool
#define param_int(_n) if (param == _n) return value.as_int();
- param_int(ID(ABITS))
- param_int(ID(A_WIDTH))
- param_int(ID(B_WIDTH))
- param_int(ID(CTRL_IN_WIDTH))
- param_int(ID(CTRL_OUT_WIDTH))
- param_int(ID(OFFSET))
- param_int(ID(PRIORITY))
- param_int(ID(RD_PORTS))
- param_int(ID(SIZE))
- param_int(ID(STATE_BITS))
- param_int(ID(STATE_NUM))
- param_int(ID(STATE_NUM_LOG2))
- param_int(ID(STATE_RST))
- param_int(ID(S_WIDTH))
- param_int(ID(TRANS_NUM))
- param_int(ID(WIDTH))
- param_int(ID(WR_PORTS))
- param_int(ID(Y_WIDTH))
+ param_int(ID::ABITS)
+ param_int(ID::A_WIDTH)
+ param_int(ID::B_WIDTH)
+ param_int(ID::CTRL_IN_WIDTH)
+ param_int(ID::CTRL_OUT_WIDTH)
+ param_int(ID::OFFSET)
+ param_int(ID::PRIORITY)
+ param_int(ID::RD_PORTS)
+ param_int(ID::SIZE)
+ param_int(ID::STATE_BITS)
+ param_int(ID::STATE_NUM)
+ param_int(ID::STATE_NUM_LOG2)
+ param_int(ID::STATE_RST)
+ param_int(ID::S_WIDTH)
+ param_int(ID::TRANS_NUM)
+ param_int(ID::WIDTH)
+ param_int(ID::WR_PORTS)
+ param_int(ID::Y_WIDTH)
#undef param_int
return value;
@@ -121,8 +119,8 @@ public:
if (wire_attr.size() > 0)
{
- RTLIL::Wire *lastNeedleWire = NULL;
- RTLIL::Wire *lastHaystackWire = NULL;
+ RTLIL::Wire *lastNeedleWire = nullptr;
+ RTLIL::Wire *lastHaystackWire = nullptr;
dict<RTLIL::IdString, RTLIL::Const> emptyAttr;
for (auto &conn : needleCell->connections())
@@ -149,27 +147,27 @@ struct bit_ref_t {
int bit;
};
-bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = NULL,
- int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = NULL)
+bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = nullptr,
+ int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = nullptr)
{
SigMap sigmap(mod);
std::map<RTLIL::SigBit, bit_ref_t> sig_bit_ref;
if (sel && !sel->selected(mod)) {
- log(" Skipping module %s as it is not selected.\n", id2cstr(mod->name));
+ log(" Skipping module %s as it is not selected.\n", log_id(mod->name));
return false;
}
if (mod->processes.size() > 0) {
- log(" Skipping module %s as it contains unprocessed processes.\n", id2cstr(mod->name));
+ log(" Skipping module %s as it contains unprocessed processes.\n", log_id(mod->name));
return false;
}
if (constports) {
- graph.createNode("$const$0", "$const$0", NULL, true);
- graph.createNode("$const$1", "$const$1", NULL, true);
- graph.createNode("$const$x", "$const$x", NULL, true);
- graph.createNode("$const$z", "$const$z", NULL, true);
+ graph.createNode("$const$0", "$const$0", nullptr, true);
+ graph.createNode("$const$1", "$const$1", nullptr, true);
+ graph.createNode("$const$x", "$const$x", nullptr, true);
+ graph.createNode("$const$z", "$const$z", nullptr, true);
graph.createPort("$const$0", "\\Y", 1);
graph.createPort("$const$1", "\\Y", 1);
graph.createPort("$const$x", "\\Y", 1);
@@ -182,28 +180,26 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
std::map<std::pair<RTLIL::Wire*, int>, int> sig_use_count;
if (max_fanout > 0)
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (!sel || sel->selected(mod, cell))
for (auto &conn : cell->connections()) {
RTLIL::SigSpec conn_sig = conn.second;
sigmap.apply(conn_sig);
for (auto &bit : conn_sig)
- if (bit.wire != NULL)
+ if (bit.wire != nullptr)
sig_use_count[std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset)]++;
}
}
// create graph nodes from cells
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (sel && !sel->selected(mod, cell))
continue;
std::string type = cell->type.str();
- if (sel == NULL && type.compare(0, 2, "\\$") == 0)
+ if (sel == nullptr && type.compare(0, 2, "\\$") == 0)
type = type.substr(1);
graph.createNode(cell->name.str(), type, (void*)cell);
@@ -221,7 +217,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
{
auto &bit = conn_sig[i];
- if (bit.wire == NULL) {
+ if (bit.wire == nullptr) {
if (constports) {
std::string node = "$const$x";
if (bit == RTLIL::State::S0) node = "$const$0";
@@ -253,9 +249,8 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
}
// mark external signals (used in non-selected cells)
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (sel && !sel->selected(mod, cell))
for (auto &conn : cell->connections())
{
@@ -271,9 +266,8 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
}
// mark external signals (used in module ports)
- for (auto &wire_it : mod->wires_)
+ for (auto wire : mod->wires())
{
- RTLIL::Wire *wire = wire_it.second;
if (wire->port_id > 0)
{
RTLIL::SigSpec conn_sig(wire);
@@ -300,8 +294,7 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name);
// create cell ports
- for (auto &it : needle->wires_) {
- RTLIL::Wire *wire = it.second;
+ for (auto wire : needle->wires()) {
if (wire->port_id > 0) {
for (int i = 0; i < wire->width; i++)
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
@@ -316,7 +309,7 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
RTLIL::Cell *needle_cell = (RTLIL::Cell*)mapping.needleUserData;
RTLIL::Cell *haystack_cell = (RTLIL::Cell*)mapping.haystackUserData;
- if (needle_cell == NULL)
+ if (needle_cell == nullptr)
continue;
for (auto &conn : needle_cell->connections()) {
@@ -341,10 +334,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
{
int left_idx = 0, right_idx = 0;
- if (left->attributes.count(ID(extract_order)) > 0)
- left_idx = left->attributes.at(ID(extract_order)).as_int();
- if (right->attributes.count(ID(extract_order)) > 0)
- right_idx = right->attributes.at(ID(extract_order)).as_int();
+ if (left->attributes.count(ID::extract_order) > 0)
+ left_idx = left->attributes.at(ID::extract_order).as_int();
+ if (right->attributes.count(ID::extract_order) > 0)
+ right_idx = right->attributes.at(ID::extract_order).as_int();
if (left_idx != right_idx)
return left_idx < right_idx;
return left->name < right->name;
@@ -587,7 +580,7 @@ struct ExtractPass : public Pass {
if (map_filenames.empty() && mine_outfile.empty())
log_cmd_error("Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n");
- RTLIL::Design *map = NULL;
+ RTLIL::Design *map = nullptr;
if (!mine_mode)
{
@@ -630,24 +623,24 @@ struct ExtractPass : public Pass {
log_header(design, "Creating graphs for SubCircuit library.\n");
if (!mine_mode)
- for (auto &mod_it : map->modules_) {
+ for (auto module : map->modules()) {
SubCircuit::Graph mod_graph;
- std::string graph_name = "needle_" + RTLIL::unescape_id(mod_it.first);
+ std::string graph_name = "needle_" + RTLIL::unescape_id(module->name);
log("Creating needle graph %s.\n", graph_name.c_str());
- if (module2graph(mod_graph, mod_it.second, constports)) {
+ if (module2graph(mod_graph, module, constports)) {
solver.addGraph(graph_name, mod_graph);
- needle_map[graph_name] = mod_it.second;
- needle_list.push_back(mod_it.second);
+ needle_map[graph_name] = module;
+ needle_list.push_back(module);
}
}
- for (auto &mod_it : design->modules_) {
+ for (auto module : design->modules()) {
SubCircuit::Graph mod_graph;
- std::string graph_name = "haystack_" + RTLIL::unescape_id(mod_it.first);
+ std::string graph_name = "haystack_" + RTLIL::unescape_id(module->name);
log("Creating haystack graph %s.\n", graph_name.c_str());
- if (module2graph(mod_graph, mod_it.second, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : NULL)) {
+ if (module2graph(mod_graph, module, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : nullptr)) {
solver.addGraph(graph_name, mod_graph);
- haystack_map[graph_name] = mod_it.second;
+ haystack_map[graph_name] = module;
}
}
@@ -680,7 +673,7 @@ struct ExtractPass : public Pass {
}
RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
design->select(haystack_map.at(result.haystackGraphId), new_cell);
- log(" new cell: %s\n", id2cstr(new_cell->name));
+ log(" new cell: %s\n", log_id(new_cell->name));
}
}
}
@@ -697,12 +690,12 @@ struct ExtractPass : public Pass {
for (auto &result: results)
{
log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
- log(" primary match in %s:", id2cstr(haystack_map.at(result.graphId)->name));
+ log(" primary match in %s:", log_id(haystack_map.at(result.graphId)->name));
for (auto &node : result.nodes)
log(" %s", RTLIL::unescape_id(node.nodeId).c_str());
log("\n");
for (auto &it : result.matchesPerGraph)
- log(" matches in %s: %d\n", id2cstr(haystack_map.at(it.first)->name), it.second);
+ log(" matches in %s: %d\n", log_id(haystack_map.at(it.first)->name), it.second);
RTLIL::Module *mod = haystack_map.at(result.graphId);
std::set<RTLIL::Cell*> cells;
@@ -717,12 +710,12 @@ struct ExtractPass : public Pass {
for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = sigmap(conn.second);
for (auto &chunk : sig.chunks())
- if (chunk.wire != NULL)
+ if (chunk.wire != nullptr)
wires.insert(chunk.wire);
}
RTLIL::Module *newMod = new RTLIL::Module;
- newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
+ newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, log_id(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
map->add(newMod);
for (auto wire : wires) {
@@ -739,8 +732,8 @@ struct ExtractPass : public Pass {
for (auto &conn : cell->connections()) {
std::vector<SigChunk> chunks = sigmap(conn.second);
for (auto &chunk : chunks)
- if (chunk.wire != NULL)
- chunk.wire = newMod->wires_.at(chunk.wire->name);
+ if (chunk.wire != nullptr)
+ chunk.wire = newMod->wire(chunk.wire->name);
newCell->setPort(conn.first, chunks);
}
}
diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc
index 17a99493d..68b338143 100644
--- a/passes/techmap/extract_counter.cc
+++ b/passes/techmap/extract_counter.cc
@@ -90,22 +90,35 @@ bool is_unconnected(const RTLIL::SigSpec& port, ModIndex& index)
struct CounterExtraction
{
int width; //counter width
+ bool count_is_up; //count up (else down)
RTLIL::Wire* rwire; //the register output
bool has_reset; //true if we have a reset
bool has_ce; //true if we have a clock enable
+ bool ce_inverted; //true if clock enable is active low
RTLIL::SigSpec rst; //reset pin
bool rst_inverted; //true if reset is active low
bool rst_to_max; //true if we reset to max instead of 0
int count_value; //value we count from
RTLIL::SigSpec ce; //clock signal
RTLIL::SigSpec clk; //clock enable, if any
- RTLIL::SigSpec outsig; //counter output signal
+ RTLIL::SigSpec outsig; //counter overflow output signal
+ RTLIL::SigSpec poutsig; //counter parallel output signal
+ bool has_pout; //whether parallel output is used
RTLIL::Cell* count_mux; //counter mux
RTLIL::Cell* count_reg; //counter register
- RTLIL::Cell* underflow_inv; //inverter reduction for output-underflow detect
+ RTLIL::Cell* overflow_cell; //cell for counter overflow (either inverter reduction or $eq)
pool<ModIndex::PortInfo> pouts; //Ports that take a parallel output from us
};
+struct CounterExtractionSettings
+{
+ pool<RTLIL::IdString>& parallel_cells;
+ int maxwidth;
+ int minwidth;
+ bool allow_arst;
+ int allowed_dirs; //0 = down, 1 = up, 2 = both
+};
+
//attempt to extract a counter centered on the given adder cell
//For now we only support DOWN counters.
//TODO: up/down support
@@ -113,49 +126,132 @@ int counter_tryextract(
ModIndex& index,
Cell *cell,
CounterExtraction& extract,
- pool<RTLIL::IdString>& parallel_cells,
- int maxwidth)
+ CounterExtractionSettings settings)
{
SigMap& sigmap = index.sigmap;
- //A counter with less than 2 bits makes no sense
- //TODO: configurable min threshold
- int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- extract.width = a_width;
- if( (a_width < 2) || (a_width > maxwidth) )
- return 1;
-
- //Second input must be a single bit
- int b_width = cell->getParam(ID(B_WIDTH)).as_int();
- if(b_width != 1)
- return 2;
-
//Both inputs must be unsigned, so don't extract anything with a signed input
- bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
- bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool();
+ bool a_sign = cell->getParam(ID::A_SIGNED).as_bool();
+ bool b_sign = cell->getParam(ID::B_SIGNED).as_bool();
if(a_sign || b_sign)
return 3;
- //To be a counter, one input of the ALU must be a constant 1
- //TODO: can A or B be swapped in synthesized RTL or is B always the 1?
- const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
- if(!b_port.is_fully_const() || (b_port.as_int() != 1) )
- return 4;
-
- //BI and CI must be constant 1 as well
- const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
- if(!bi_port.is_fully_const() || (bi_port.as_int() != 1) )
- return 5;
- const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
- if(!ci_port.is_fully_const() || (ci_port.as_int() != 1) )
- return 6;
-
//CO and X must be unconnected (exactly one connection to each port)
- if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
+ if(!is_unconnected(sigmap(cell->getPort(ID::CO)), index))
return 7;
- if(!is_unconnected(sigmap(cell->getPort(ID(X))), index))
+ if(!is_unconnected(sigmap(cell->getPort(ID::X)), index))
return 8;
+ //true if $alu is performing A - B, else A + B
+ bool alu_is_subtract;
+
+ //BI and CI must be both constant 0 or both constant 1 as well
+ const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID::BI));
+ const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID::CI));
+ if(bi_port.is_fully_const() && bi_port.as_int() == 1 &&
+ ci_port.is_fully_const() && ci_port.as_int() == 1)
+ {
+ alu_is_subtract = true;
+ }
+ else if(bi_port.is_fully_const() && bi_port.as_int() == 0 &&
+ ci_port.is_fully_const() && ci_port.as_int() == 0)
+ {
+ alu_is_subtract = false;
+ }
+ else
+ {
+ return 5;
+ }
+
+ //false -> port B connects to value
+ //true -> port A connects to value
+ bool alu_port_use_a = false;
+
+ if(alu_is_subtract)
+ {
+ const int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ const int b_width = cell->getParam(ID::B_WIDTH).as_int();
+ const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
+
+ // down, cnt <= cnt - 1
+ if (b_width == 1 && b_port.is_fully_const() && b_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = false;
+ }
+
+ // up, cnt <= cnt - -1
+ else if (b_width == a_width && b_port.is_fully_const() && b_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = true;
+ }
+
+ // ???
+ else
+ {
+ return 2;
+ }
+ }
+ else
+ {
+ const int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ const int b_width = cell->getParam(ID::B_WIDTH).as_int();
+ const RTLIL::SigSpec a_port = sigmap(cell->getPort(ID::A));
+ const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
+
+ // down, cnt <= cnt + -1
+ if (b_width == a_width && b_port.is_fully_const() && b_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = false;
+ }
+ else if (a_width == b_width && a_port.is_fully_const() && a_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = false;
+ extract.count_is_up = false;
+ }
+
+ // up, cnt <= cnt + 1
+ else if (b_width == 1 && b_port.is_fully_const() && b_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = true;
+ }
+ else if (a_width == 1 && a_port.is_fully_const() && a_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = false;
+ extract.count_is_up = true;
+ }
+
+ // ???
+ else
+ {
+ return 2;
+ }
+ }
+
+ if (extract.count_is_up && settings.allowed_dirs == 0)
+ return 26;
+ if (!extract.count_is_up && settings.allowed_dirs == 1)
+ return 26;
+
+ //Check if counter is an appropriate size
+ int count_width;
+ if (alu_port_use_a)
+ count_width = cell->getParam(ID::A_WIDTH).as_int();
+ else
+ count_width = cell->getParam(ID::B_WIDTH).as_int();
+ extract.width = count_width;
+ if( (count_width < settings.minwidth) || (count_width > settings.maxwidth) )
+ return 1;
+
//Y must have exactly one connection, and it has to be a $mux cell.
//We must have a direct bus connection from our Y to their A.
const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID::Y));
@@ -169,30 +265,43 @@ int counter_tryextract(
if(!is_full_bus(aluy, index, cell, ID::Y, count_mux, ID::A))
return 11;
- //B connection of the mux is our underflow value
- const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
- if(!underflow.is_fully_const())
- return 12;
- extract.count_value = underflow.as_int();
+ if (extract.count_is_up)
+ {
+ //B connection of the mux must be 0
+ const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
+ if(!(underflow.is_fully_const() && underflow.is_fully_zero()))
+ return 12;
+ }
+ else
+ {
+ //B connection of the mux is our underflow value
+ const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
+ if(!underflow.is_fully_const())
+ return 12;
+ extract.count_value = underflow.as_int();
+ }
- //S connection of the mux must come from an inverter (need not be the only load)
- const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S)));
+ //S connection of the mux must come from an inverter if down, eq if up
+ //(need not be the only load)
+ const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID::S));
extract.outsig = muxsel;
pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
- Cell* underflow_inv = NULL;
+ Cell* overflow_cell = NULL;
for(auto c : muxsel_conns)
{
- if(c->type != ID($logic_not))
+ if(extract.count_is_up && c->type != ID($eq))
continue;
- if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true))
+ if(!extract.count_is_up && c->type != ID($logic_not))
+ continue;
+ if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID::S, true))
continue;
- underflow_inv = c;
+ overflow_cell = c;
break;
}
- if(underflow_inv == NULL)
+ if(overflow_cell == NULL)
return 13;
- extract.underflow_inv = underflow_inv;
+ extract.overflow_cell = overflow_cell;
//Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable
//If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register
@@ -215,18 +324,28 @@ int counter_tryextract(
return 24;
count_reg = *cey_loads.begin();
- //Mux should have A driven by count Q, and B by muxy
- //TODO: if A and B are swapped, CE polarity is inverted
- if(sigmap(cemux->getPort(ID::B)) != muxy)
+ if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID::D)))
return 24;
- if(sigmap(cemux->getPort(ID::A)) != sigmap(count_reg->getPort(ID(Q))))
- return 24;
- if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D))))
+ //Mux should have A driven by count Q, and B by muxy
+ //if A and B are swapped, CE polarity is inverted
+ if(sigmap(cemux->getPort(ID::B)) == muxy &&
+ sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID::Q)))
+ {
+ extract.ce_inverted = false;
+ }
+ else if(sigmap(cemux->getPort(ID::A)) == muxy &&
+ sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID::Q)))
+ {
+ extract.ce_inverted = true;
+ }
+ else
+ {
return 24;
+ }
//Select of the mux is our clock enable
extract.has_ce = true;
- extract.ce = sigmap(cemux->getPort(ID(S)));
+ extract.ce = sigmap(cemux->getPort(ID::S));
}
else
extract.has_ce = false;
@@ -236,13 +355,16 @@ int counter_tryextract(
extract.has_reset = false;
else if(count_reg->type == ID($adff))
{
+ if (!settings.allow_arst)
+ return 25;
+
extract.has_reset = true;
//Check polarity of reset - we may have to add an inverter later on!
- extract.rst_inverted = (count_reg->getParam(ID(ARST_POLARITY)).as_int() != 1);
+ extract.rst_inverted = (count_reg->getParam(ID::ARST_POLARITY).as_int() != 1);
//Verify ARST_VALUE is zero or full scale
- int rst_value = count_reg->getParam(ID(ARST_VALUE)).as_int();
+ int rst_value = count_reg->getParam(ID::ARST_VALUE).as_int();
if(rst_value == 0)
extract.rst_to_max = false;
else if(rst_value == extract.count_value)
@@ -251,7 +373,7 @@ int counter_tryextract(
return 23;
//Save the reset
- extract.rst = sigmap(count_reg->getPort(ID(ARST)));
+ extract.rst = sigmap(count_reg->getPort(ID::ARST));
}
//TODO: support synchronous reset
else
@@ -260,12 +382,14 @@ int counter_tryextract(
//Sanity check that we use the ALU output properly
if(extract.has_ce)
{
- if(!is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B))
+ if(!extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B))
+ return 16;
+ if(extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::A))
return 16;
- if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D)))
+ if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID::D))
return 16;
}
- else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID(D)))
+ else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID::D))
return 16;
//TODO: Verify count_reg CLK_POLARITY is 1
@@ -273,7 +397,9 @@ int counter_tryextract(
//Register output must have exactly two loads, the inverter and ALU
//(unless we have a parallel output!)
//If we have a clock enable, 3 is OK
- const RTLIL::SigSpec qport = count_reg->getPort(ID(Q));
+ const RTLIL::SigSpec qport = count_reg->getPort(ID::Q);
+ extract.poutsig = qport;
+ extract.has_pout = false;
const RTLIL::SigSpec cnout = sigmap(qport);
pool<Cell*> cnout_loads = get_other_cells(cnout, index, count_reg);
unsigned int max_loads = 2;
@@ -283,7 +409,7 @@ int counter_tryextract(
{
for(auto c : cnout_loads)
{
- if(c == underflow_inv)
+ if(c == overflow_cell)
continue;
if(c == cell)
continue;
@@ -291,15 +417,16 @@ int counter_tryextract(
continue;
//If we specified a limited set of cells for parallel output, check that we only drive them
- if(!parallel_cells.empty())
+ if(!settings.parallel_cells.empty())
{
//Make sure we're in the whitelist
- if( parallel_cells.find(c->type) == parallel_cells.end())
+ if( settings.parallel_cells.find(c->type) == settings.parallel_cells.end())
return 17;
}
//Figure out what port(s) are driven by it
//TODO: this can probably be done more efficiently w/o multiple iterations over our whole net?
+ //TODO: For what purpose do we actually need extract.pouts?
for(auto b : qport)
{
pool<ModIndex::PortInfo> ports = index.query_ports(b);
@@ -308,25 +435,75 @@ int counter_tryextract(
if(x.cell != c)
continue;
extract.pouts.insert(ModIndex::PortInfo(c, x.port, 0));
+ extract.has_pout = true;
}
}
}
}
- if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID::A, true))
- return 18;
- if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true))
+ for (auto b : qport)
+ {
+ if(index.query_is_output(b))
+ {
+ // Parallel out goes out of module
+ extract.has_pout = true;
+ }
+ }
+ if(!extract.count_is_up)
+ {
+ if(!is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
+ return 18;
+ }
+ else
+ {
+ if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
+ {
+ // B must be the overflow value
+ const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::B));
+ if(!overflow.is_fully_const())
+ return 12;
+ extract.count_value = overflow.as_int();
+ }
+ else if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::B, true))
+ {
+ // A must be the overflow value
+ const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::A));
+ if(!overflow.is_fully_const())
+ return 12;
+ extract.count_value = overflow.as_int();
+ }
+ else
+ {
+ return 18;
+ }
+ }
+ if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::A, true))
+ return 19;
+ if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::B, true))
return 19;
//Look up the clock from the register
- extract.clk = sigmap(count_reg->getPort(ID(CLK)));
+ extract.clk = sigmap(count_reg->getPort(ID::CLK));
- //Register output net must have an INIT attribute equal to the count value
- extract.rwire = cnout.as_wire();
- if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
- return 20;
- int rinit = extract.rwire->attributes[ID(init)].as_int();
- if(rinit != extract.count_value)
- return 21;
+ if(!extract.count_is_up)
+ {
+ //Register output net must have an INIT attribute equal to the count value
+ extract.rwire = cnout.as_wire();
+ if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
+ return 20;
+ int rinit = extract.rwire->attributes[ID::init].as_int();
+ if(rinit != extract.count_value)
+ return 21;
+ }
+ else
+ {
+ //Register output net must not have an INIT attribute or it must be zero
+ extract.rwire = cnout.as_wire();
+ if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
+ return 0;
+ int rinit = extract.rwire->attributes[ID::init].as_int();
+ if(rinit != 0)
+ return 21;
+ }
return 0;
}
@@ -337,8 +514,7 @@ void counter_worker(
unsigned int& total_counters,
pool<Cell*>& cells_to_remove,
pool<pair<Cell*, string>>& cells_to_rename,
- pool<RTLIL::IdString>& parallel_cells,
- int maxwidth)
+ CounterExtractionSettings settings)
{
SigMap& sigmap = index.sigmap;
@@ -350,20 +526,24 @@ void counter_worker(
//If it's not a wire, don't even try
auto port = sigmap(cell->getPort(ID::A));
if(!port.is_wire())
- return;
- RTLIL::Wire* a_wire = port.as_wire();
+ {
+ port = sigmap(cell->getPort(ID::B));
+ if(!port.is_wire())
+ return;
+ }
+ RTLIL::Wire* port_wire = port.as_wire();
bool force_extract = false;
bool never_extract = false;
- string count_reg_src = a_wire->attributes[ID(src)].decode_string().c_str();
- if(a_wire->attributes.find(ID(COUNT_EXTRACT)) != a_wire->attributes.end())
+ string count_reg_src = port_wire->attributes[ID::src].decode_string().c_str();
+ if(port_wire->attributes.find(ID(COUNT_EXTRACT)) != port_wire->attributes.end())
{
- pool<string> sa = a_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
+ pool<string> sa = port_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
string extract_value;
if(sa.size() >= 1)
{
extract_value = *sa.begin();
log(" Signal %s declared at %s has COUNT_EXTRACT = %s\n",
- log_id(a_wire),
+ log_id(port_wire),
count_reg_src.c_str(),
extract_value.c_str());
@@ -385,21 +565,21 @@ void counter_worker(
//Attempt to extract a counter
CounterExtraction extract;
- int reason = counter_tryextract(index, cell, extract, parallel_cells, maxwidth);
+ int reason = counter_tryextract(index, cell, extract, settings);
//Nonzero code - we could not find a matchable counter.
//Do nothing, unless extraction was forced in which case give an error
if(reason != 0)
{
- static const char* reasons[25]=
+ static const char* reasons[]=
{
"no problem", //0
"counter is too large/small", //1
"counter does not count by one", //2
"counter uses signed math", //3
- "counter does not count by one", //4
- "ALU is not a subtractor", //5
- "ALU is not a subtractor", //6
+ "RESERVED, not implemented", //4
+ "ALU is not an adder/subtractor", //5
+ "RESERVED, not implemented", //6
"ALU ports used outside counter", //7
"ALU ports used outside counter", //8
"ALU output used outside counter", //9
@@ -417,14 +597,16 @@ void counter_worker(
"Underflow value is not equal to init value", //21
"RESERVED, not implemented", //22, kept for compatibility but not used anymore
"Reset is not to zero or COUNT_TO", //23
- "Clock enable configuration is unsupported" //24
+ "Clock enable configuration is unsupported", //24
+ "Async reset used but not permitted", //25
+ "Count direction is not allowed" //26
};
if(force_extract)
{
log_error(
"Counter extraction is set to FORCE on register %s, but a counter could not be inferred (%s)\n",
- log_id(a_wire),
+ log_id(port_wire),
reasons[reason]);
}
return;
@@ -436,16 +618,16 @@ void counter_worker(
//Wipe all of the old connections to the ALU
cell->unsetPort(ID::A);
cell->unsetPort(ID::B);
- cell->unsetPort(ID(BI));
- cell->unsetPort(ID(CI));
- cell->unsetPort(ID(CO));
- cell->unsetPort(ID(X));
+ cell->unsetPort(ID::BI);
+ cell->unsetPort(ID::CI);
+ cell->unsetPort(ID::CO);
+ cell->unsetPort(ID::X);
cell->unsetPort(ID::Y);
- cell->unsetParam(ID(A_SIGNED));
- cell->unsetParam(ID(A_WIDTH));
- cell->unsetParam(ID(B_SIGNED));
- cell->unsetParam(ID(B_WIDTH));
- cell->unsetParam(ID(Y_WIDTH));
+ cell->unsetParam(ID::A_SIGNED);
+ cell->unsetParam(ID::A_WIDTH);
+ cell->unsetParam(ID::B_SIGNED);
+ cell->unsetParam(ID::B_WIDTH);
+ cell->unsetParam(ID::Y_WIDTH);
//Change the cell type
cell->type = ID($__COUNT_);
@@ -475,44 +657,61 @@ void counter_worker(
//Hook up other stuff
//cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1));
cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value));
- cell->setParam(ID(WIDTH), RTLIL::Const(extract.width));
- cell->setPort(ID(CLK), extract.clk);
+ cell->setParam(ID::WIDTH, RTLIL::Const(extract.width));
+ cell->setPort(ID::CLK, extract.clk);
cell->setPort(ID(OUT), extract.outsig);
//Hook up clock enable
if(extract.has_ce)
{
cell->setParam(ID(HAS_CE), RTLIL::Const(1));
- cell->setPort(ID(CE), extract.ce);
+ if(extract.ce_inverted)
+ {
+ auto realce = cell->module->addWire(NEW_ID);
+ cell->module->addNot(NEW_ID, extract.ce, RTLIL::SigSpec(realce));
+ cell->setPort(ID(CE), realce);
+ }
+ else
+ cell->setPort(ID(CE), extract.ce);
}
else
+ {
cell->setParam(ID(HAS_CE), RTLIL::Const(0));
+ cell->setPort(ID(CE), RTLIL::Const(1));
+ }
- //Hook up hard-wired ports (for now up/down are not supported), default to no parallel output
+ if(extract.count_is_up)
+ {
+ cell->setParam(ID(DIRECTION), RTLIL::Const("UP"));
+ //XXX: What is this supposed to do?
+ cell->setPort(ID(UP), RTLIL::Const(1));
+ }
+ else
+ {
+ cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
+ cell->setPort(ID(UP), RTLIL::Const(0));
+ }
+
+ //Hook up hard-wired ports, default to no parallel output
cell->setParam(ID(HAS_POUT), RTLIL::Const(0));
cell->setParam(ID(RESET_TO_MAX), RTLIL::Const(0));
- cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
- cell->setPort(ID(CE), RTLIL::Const(1));
- cell->setPort(ID(UP), RTLIL::Const(0));
//Hook up any parallel outputs
for(auto load : extract.pouts)
{
log(" Counter has parallel output to cell %s port %s\n", log_id(load.cell->name), log_id(load.port));
-
- //Find the wire hooked to the old port
- auto sig = load.cell->getPort(load.port);
-
+ }
+ if(extract.has_pout)
+ {
//Connect it to our parallel output
- //(this is OK to do more than once b/c they all go to the same place)
- cell->setPort(ID(POUT), sig);
+ cell->setPort(ID(POUT), extract.poutsig);
cell->setParam(ID(HAS_POUT), RTLIL::Const(1));
}
//Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
cells_to_remove.insert(extract.count_mux);
cells_to_remove.insert(extract.count_reg);
- cells_to_remove.insert(extract.underflow_inv);
+ cells_to_remove.insert(extract.overflow_cell);
//Log it
total_counters ++;
@@ -527,17 +726,19 @@ void counter_worker(
//TODO: support other kind of reset
reset_type += " async resettable";
}
- log(" Found %d-bit (%s) down counter %s (counting from %d) for register %s, declared at %s\n",
+ log(" Found %d-bit (%s) %s counter %s (counting %s %d) for register %s, declared at %s\n",
extract.width,
reset_type.c_str(),
+ extract.count_is_up ? "up" : "down",
countname.c_str(),
+ extract.count_is_up ? "to" : "from",
extract.count_value,
log_id(extract.rwire->name),
count_reg_src.c_str());
//Optimize the counter
//If we have no parallel output, and we have redundant bits, shrink us
- if(extract.pouts.empty())
+ if(!extract.has_pout)
{
//TODO: Need to update this when we add support for counters with nonzero reset values
//to make sure the reset value fits in our bit space too
@@ -546,7 +747,7 @@ void counter_worker(
int newbits = ceil(log2(extract.count_value));
if(extract.width != newbits)
{
- cell->setParam(ID(WIDTH), RTLIL::Const(newbits));
+ cell->setParam(ID::WIDTH, RTLIL::Const(newbits));
log(" Optimizing out %d unused high-order bits (new width is %d)\n",
extract.width - newbits,
newbits);
@@ -570,7 +771,16 @@ struct ExtractCounterPass : public Pass {
log("to the actual target cells.\n");
log("\n");
log(" -maxwidth N\n");
- log(" Only extract counters up to N bits wide\n");
+ log(" Only extract counters up to N bits wide (default 64)\n");
+ log("\n");
+ log(" -minwidth N\n");
+ log(" Only extract counters at least N bits wide (default 2)\n");
+ log("\n");
+ log(" -allow_arst yes|no\n");
+ log(" Allow counters to have async reset (default yes)\n");
+ log("\n");
+ log(" -dir up|down|both\n");
+ log(" Look for up-counters, down-counters, or both (default down)\n");
log("\n");
log(" -pout X,Y,...\n");
log(" Only allow parallel output from the counter to the listed cell types\n");
@@ -582,9 +792,17 @@ struct ExtractCounterPass : public Pass {
{
log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n");
- int maxwidth = 64;
+ pool<RTLIL::IdString> _parallel_cells;
+ CounterExtractionSettings settings
+ {
+ .parallel_cells = _parallel_cells,
+ .maxwidth = 64,
+ .minwidth = 2,
+ .allow_arst = true,
+ .allowed_dirs = 0,
+ };
+
size_t argidx;
- pool<RTLIL::IdString> parallel_cells;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-pout")
@@ -601,24 +819,63 @@ struct ExtractCounterPass : public Pass {
{
if(pouts[i] == ',')
{
- parallel_cells.insert(RTLIL::escape_id(tmp));
+ settings.parallel_cells.insert(RTLIL::escape_id(tmp));
tmp = "";
}
else
tmp += pouts[i];
}
- parallel_cells.insert(RTLIL::escape_id(tmp));
+ settings.parallel_cells.insert(RTLIL::escape_id(tmp));
continue;
}
if (args[argidx] == "-maxwidth" && argidx+1 < args.size())
{
- maxwidth = atoi(args[++argidx].c_str());
+ settings.maxwidth = atoi(args[++argidx].c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-minwidth" && argidx+1 < args.size())
+ {
+ settings.minwidth = atoi(args[++argidx].c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-allow_arst" && argidx+1 < args.size())
+ {
+ auto arg = args[++argidx];
+ if (arg == "yes")
+ settings.allow_arst = true;
+ else if (arg == "no")
+ settings.allow_arst = false;
+ else
+ log_error("Invalid -allow_arst value \"%s\"\n", arg.c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-dir" && argidx+1 < args.size())
+ {
+ auto arg = args[++argidx];
+ if (arg == "up")
+ settings.allowed_dirs = 1;
+ else if (arg == "down")
+ settings.allowed_dirs = 0;
+ else if (arg == "both")
+ settings.allowed_dirs = 2;
+ else
+ log_error("Invalid -dir value \"%s\"\n", arg.c_str());
continue;
}
}
extra_args(args, argidx, design);
+ if (settings.minwidth < 2)
+ {
+ //A counter with less than 2 bits makes no sense
+ log_warning("Minimum counter width is 2 bits wide\n");
+ settings.minwidth = 2;
+ }
+
//Extract all of the counters we could find
unsigned int total_counters = 0;
for (auto module : design->selected_modules())
@@ -628,7 +885,7 @@ struct ExtractCounterPass : public Pass {
ModIndex index(module);
for (auto cell : module->selected_cells())
- counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells, maxwidth);
+ counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, settings);
for(auto cell : cells_to_remove)
{
diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc
index 9f3bb525b..9023d8687 100644
--- a/passes/techmap/extract_fa.cc
+++ b/passes/techmap/extract_fa.cc
@@ -262,7 +262,7 @@ struct ExtractFaWorker
pool<SigBit> new_leaves = leaves;
new_leaves.erase(bit);
- for (auto port : {ID::A, ID::B, ID(C), ID(D)}) {
+ for (auto port : {ID::A, ID::B, ID::C, ID::D}) {
if (!cell->hasPort(port))
continue;
auto bit = sigmap(SigBit(cell->getPort(port)));
@@ -395,18 +395,18 @@ struct ExtractFaWorker
else
{
Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), 1);
+ cell->setParam(ID::WIDTH, 1);
log(" Created $fa cell %s.\n", log_id(cell));
cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A);
cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B);
- cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
+ cell->setPort(ID::C, f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
X = module->addWire(NEW_ID);
Y = module->addWire(NEW_ID);
- cell->setPort(ID(X), X);
+ cell->setPort(ID::X, X);
cell->setPort(ID::Y, Y);
facache[fakey] = make_tuple(X, Y, cell);
@@ -501,18 +501,18 @@ struct ExtractFaWorker
else
{
Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), 1);
+ cell->setParam(ID::WIDTH, 1);
log(" Created $fa cell %s.\n", log_id(cell));
cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A);
cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B);
- cell->setPort(ID(C), State::S0);
+ cell->setPort(ID::C, State::S0);
X = module->addWire(NEW_ID);
Y = module->addWire(NEW_ID);
- cell->setPort(ID(X), X);
+ cell->setPort(ID::X, X);
cell->setPort(ID::Y, Y);
}
diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc
index 11cfddcd9..2d63e413f 100644
--- a/passes/techmap/extract_reduce.cc
+++ b/passes/techmap/extract_reduce.cc
@@ -286,7 +286,7 @@ struct ExtractReducePass : public Pass
SigSpec input;
for (auto b : input_pool)
if (input_pool_intermed.count(b) == 0)
- input.append_bit(b);
+ input.append(b);
SigBit output = sigmap(head_cell->getPort(ID::Y)[0]);
@@ -294,9 +294,9 @@ struct ExtractReducePass : public Pass
gt == GateType::And ? ID($reduce_and) :
gt == GateType::Or ? ID($reduce_or) :
gt == GateType::Xor ? ID($reduce_xor) : "");
- new_reduce_cell->setParam(ID(A_SIGNED), 0);
- new_reduce_cell->setParam(ID(A_WIDTH), input.size());
- new_reduce_cell->setParam(ID(Y_WIDTH), 1);
+ new_reduce_cell->setParam(ID::A_SIGNED, 0);
+ new_reduce_cell->setParam(ID::A_WIDTH, input.size());
+ new_reduce_cell->setParam(ID::Y_WIDTH, 1);
new_reduce_cell->setPort(ID::A, input);
new_reduce_cell->setPort(ID::Y, output);
diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc
index dda71f12a..269fe5c6c 100644
--- a/passes/techmap/extractinv.cc
+++ b/passes/techmap/extractinv.cc
@@ -90,7 +90,7 @@ struct ExtractinvPass : public Pass {
auto cell_wire = cell_module->wire(port.first);
if (!cell_wire)
continue;
- auto it = cell_wire->attributes.find("\\invertible_pin");
+ auto it = cell_wire->attributes.find(ID::invertible_pin);
if (it == cell_wire->attributes.end())
continue;
IdString param_name = RTLIL::escape_id(it->second.decode_string());
diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc
index a2ad87f7d..72947237b 100644
--- a/passes/techmap/flowmap.cc
+++ b/passes/techmap/flowmap.cc
@@ -1405,7 +1405,7 @@ struct FlowmapWorker
RTLIL::SigSpec lut_a, lut_y = node;
for (auto input_node : input_nodes)
- lut_a.append_bit(input_node);
+ lut_a.append(input_node);
lut_a.append(RTLIL::Const(State::Sx, minlut - input_nodes.size()));
RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table);
@@ -1413,7 +1413,7 @@ struct FlowmapWorker
for (auto gate_node : lut_gates[node])
{
auto gate_origin = node_origins[gate_node];
- lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src)));
+ lut->add_strpool_attribute(ID::src, gate_origin.cell->get_strpool_attribute(ID::src));
packed_count++;
}
lut_count++;
diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc
index 9ec651aef..5aeb5ea79 100644
--- a/passes/techmap/hilomap.cc
+++ b/passes/techmap/hilomap.cc
@@ -105,13 +105,9 @@ struct HilomapPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- module = it.second;
-
- if (!design->selected(module))
- continue;
-
+ module = mod;
last_hi = RTLIL::State::Sm;
last_lo = RTLIL::State::Sm;
diff --git a/passes/techmap/insbuf.cc b/passes/techmap/insbuf.cc
index 2173049b4..0686c0f2b 100644
--- a/passes/techmap/insbuf.cc
+++ b/passes/techmap/insbuf.cc
@@ -41,16 +41,16 @@ struct InsbufPass : public Pass {
{
log_header(design, "Executing INSBUF pass (insert buffer cells for connected wires).\n");
- std::string celltype = "$_BUF_", in_portname = "\\A", out_portname = "\\Y";
+ IdString celltype = ID($_BUF_), in_portname = ID::A, out_portname = ID::Y;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
std::string arg = args[argidx];
if (arg == "-buf" && argidx+3 < args.size()) {
- celltype = args[++argidx];
- in_portname = args[++argidx];
- out_portname = args[++argidx];
+ celltype = RTLIL::escape_id(args[++argidx]);
+ in_portname = RTLIL::escape_id(args[++argidx]);
+ out_portname = RTLIL::escape_id(args[++argidx]);
continue;
}
break;
@@ -76,9 +76,9 @@ struct InsbufPass : public Pass {
continue;
}
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
- cell->setPort(RTLIL::escape_id(in_portname), rhs);
- cell->setPort(RTLIL::escape_id(out_portname), lhs);
+ Cell *cell = module->addCell(NEW_ID, celltype);
+ cell->setPort(in_portname, rhs);
+ cell->setPort(out_portname, lhs);
log("Added %s.%s: %s -> %s\n", log_id(module), log_id(cell), log_signal(rhs), log_signal(lhs));
}
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index 531ac2b99..a18d02652 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -83,6 +83,20 @@ struct IopadmapPass : public Pass {
log("Tristate PADS (-toutpad, -tinoutpad) always operate in -bits mode.\n");
log("\n");
}
+
+ void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) {
+ if (modules_processed.count(module))
+ return;
+ for (auto cell : module->cells()) {
+ Module *submodule = design->module(cell->type);
+ if (!submodule)
+ continue;
+ module_queue(design, submodule, modules_sorted, modules_processed);
+ }
+ modules_sorted.push_back(module);
+ modules_processed.insert(module);
+ }
+
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n");
@@ -172,27 +186,56 @@ struct IopadmapPass : public Pass {
if (!tinoutpad_portname_pad.empty())
ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad)));
- for (auto module : design->modules())
- if (module->get_blackbox_attribute())
- for (auto wire : module->wires())
- if (wire->get_bool_attribute("\\iopad_external_pin"))
- ignore.insert(make_pair(module->name, wire->name));
+ // Recursively collect list of (module, port, bit) triples that already have buffers.
+
+ pool<pair<IdString, pair<IdString, int>>> buf_ports;
+ // Process submodules before module using them.
+ std::vector<Module *> modules_sorted;
+ pool<Module *> modules_processed;
for (auto module : design->selected_modules())
+ module_queue(design, module, modules_sorted, modules_processed);
+
+ for (auto module : modules_sorted)
{
- pool<SigBit> skip_wire_bits;
- dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
+ pool<SigBit> buf_bits;
+ SigMap sigmap(module);
+
+ // Collect explicitly-marked already-buffered SigBits.
+ for (auto wire : module->wires())
+ if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(module->name, wire->name)))
+ for (int i = 0; i < GetSize(wire); i++)
+ buf_bits.insert(sigmap(SigBit(wire, i)));
+ // Collect SigBits connected to already-buffered ports.
for (auto cell : module->cells())
for (auto port : cell->connections())
- if (ignore.count(make_pair(cell->type, port.first)))
- for (auto bit : port.second)
- skip_wire_bits.insert(bit);
+ for (int i = 0; i < port.second.size(); i++)
+ if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
+ buf_bits.insert(sigmap(port.second[i]));
+
+ // Now fill buf_ports.
+ for (auto wire : module->wires())
+ if (wire->port_input || wire->port_output)
+ for (int i = 0; i < GetSize(wire); i++)
+ if (buf_bits.count(sigmap(SigBit(wire, i)))) {
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
+ log("Marking already mapped port: %s.%s[%d].\n", log_id(module), log_id(wire), i);
+ }
+ }
+
+ // Now do the actual buffer insertion.
+
+ for (auto module : design->selected_modules())
+ {
+ dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
+ pool<SigSig> remove_conns;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{
dict<SigBit, Cell *> tbuf_bits;
pool<SigBit> driven_bits;
+ dict<SigBit, SigSig> z_conns;
// Gather tristate buffers and always-on drivers.
for (auto cell : module->cells())
@@ -211,8 +254,10 @@ struct IopadmapPass : public Pass {
for (int i = 0; i < GetSize(conn.first); i++) {
SigBit dstbit = conn.first[i];
SigBit srcbit = conn.second[i];
- if (!srcbit.wire && srcbit.data == State::Sz)
+ if (!srcbit.wire && srcbit.data == State::Sz) {
+ z_conns[dstbit] = conn;
continue;
+ }
driven_bits.insert(dstbit);
}
@@ -234,7 +279,7 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
- if (skip_wire_bits.count(wire_bit))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
continue;
if (tbuf_bits.count(wire_bit))
@@ -246,7 +291,7 @@ struct IopadmapPass : public Pass {
if (tbuf_cell != nullptr) {
// Found a tristate buffer — use it.
- en_sig = tbuf_cell->getPort(ID(E)).as_bit();
+ en_sig = tbuf_cell->getPort(ID::E).as_bit();
data_sig = tbuf_cell->getPort(ID::A).as_bit();
} else if (is_driven) {
// No tristate buffer, but an always-on driver is present.
@@ -261,13 +306,17 @@ struct IopadmapPass : public Pass {
// enable.
en_sig = SigBit(State::S0);
data_sig = SigBit(State::Sx);
+ if (z_conns.count(wire_bit))
+ remove_conns.insert(z_conns[wire_bit]);
}
if (wire->port_input)
{
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(tinoutpad_celltype));
cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig);
cell->attributes[ID::keep] = RTLIL::Const(1);
@@ -282,13 +331,14 @@ struct IopadmapPass : public Pass {
cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!tinoutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad));
} else {
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(toutpad_celltype));
cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig);
cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig);
@@ -298,10 +348,10 @@ struct IopadmapPass : public Pass {
module->remove(tbuf_cell);
module->connect(wire_bit, data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!toutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad));
}
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
}
}
}
@@ -315,7 +365,7 @@ struct IopadmapPass : public Pass {
pool<int> skip_bit_indices;
for (int i = 0; i < GetSize(wire); i++)
- if (skip_wire_bits.count(SigBit(wire, i)))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
skip_bit_indices.insert(i);
if (GetSize(wire) == GetSize(skip_bit_indices))
@@ -366,7 +416,9 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), wire_bit);
if (!portname_pad.empty())
@@ -380,12 +432,16 @@ struct IopadmapPass : public Pass {
}
else
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire));
if (!portname_pad.empty()) {
RTLIL::Wire *new_wire = NULL;
- new_wire = module->addWire(NEW_ID, wire);
+ new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire));
@@ -404,9 +460,19 @@ struct IopadmapPass : public Pass {
}
}
+ if (!remove_conns.empty()) {
+ std::vector<SigSig> new_conns;
+ for (auto &conn : module->connections())
+ if (!remove_conns.count(conn))
+ new_conns.push_back(conn);
+ module->new_connections(new_conns);
+ }
+
for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first;
- RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire);
+ RTLIL::Wire *new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
for (int i = 0; i < wire->width; i++)
@@ -423,6 +489,15 @@ struct IopadmapPass : public Pass {
}
}
+ if (wire->port_output) {
+ auto jt = new_wire->attributes.find(ID::init);
+ // For output ports, move \init attributes from old wire to new wire
+ if (jt != new_wire->attributes.end()) {
+ wire->attributes[ID::init] = std::move(jt->second);
+ new_wire->attributes.erase(jt);
+ }
+ }
+
wire->port_id = 0;
wire->port_input = false;
wire->port_output = false;
diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc
index c6618fc9d..703bf6ff6 100644
--- a/passes/techmap/lut2mux.cc
+++ b/passes/techmap/lut2mux.cc
@@ -27,7 +27,7 @@ int lut2mux(Cell *cell)
{
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_y = cell->getPort(ID::Y);
- Const lut = cell->getParam(ID(LUT));
+ Const lut = cell->getParam(ID::LUT);
int count = 1;
if (GetSize(sig_a) == 1)
diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc
index 09f61927c..3bb929009 100644
--- a/passes/techmap/maccmap.cc
+++ b/passes/techmap/maccmap.cc
@@ -112,12 +112,12 @@ struct MaccmapWorker
RTLIL::Wire *w2 = module->addWire(NEW_ID, width);
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::A, in1);
cell->setPort(ID::B, in2);
- cell->setPort(ID(C), in3);
+ cell->setPort(ID::C, in3);
cell->setPort(ID::Y, w1);
- cell->setPort(ID(X), w2);
+ cell->setPort(ID::X, w2);
out1 = {out_zeros_msb, w1, out_zeros_lsb};
out2 = {out_zeros_msb, w2, out_zeros_lsb};
@@ -240,15 +240,15 @@ struct MaccmapWorker
RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu));
c->setPort(ID::A, summands.front());
c->setPort(ID::B, summands.back());
- c->setPort(ID(CI), State::S0);
- c->setPort(ID(BI), State::S0);
+ c->setPort(ID::CI, State::S0);
+ c->setPort(ID::BI, State::S0);
c->setPort(ID::Y, module->addWire(NEW_ID, width));
- c->setPort(ID(X), module->addWire(NEW_ID, width));
- c->setPort(ID(CO), module->addWire(NEW_ID, width));
+ c->setPort(ID::X, module->addWire(NEW_ID, width));
+ c->setPort(ID::CO, module->addWire(NEW_ID, width));
c->fixup_parameters();
if (!tree_sum_bits.empty()) {
- c->setPort(ID(CI), tree_sum_bits.back());
+ c->setPort(ID::CI, tree_sum_bits.back());
tree_sum_bits.pop_back();
}
log_assert(tree_sum_bits.empty());
diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc
index 5541b6122..bd049d86d 100644
--- a/passes/techmap/muxcover.cc
+++ b/passes/techmap/muxcover.cc
@@ -116,7 +116,7 @@ struct MuxcoverWorker
if (!cell->input(conn.first))
continue;
for (auto bit : sigmap(conn.second)) {
- if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID(S))
+ if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID::S)
roots.insert(bit);
used_once.insert(bit);
}
@@ -519,7 +519,7 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(S), mux.selects[0]);
+ cell->setPort(ID::S, mux.selects[0]);
cell->setPort(ID::Y, bit);
return;
}
@@ -529,10 +529,10 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX4_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
cell->setPort(ID::Y, bit);
return;
}
@@ -542,15 +542,15 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX8_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(E), mux.inputs[4]);
- cell->setPort(ID(F), mux.inputs[5]);
- cell->setPort(ID(G), mux.inputs[6]);
- cell->setPort(ID(H), mux.inputs[7]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
- cell->setPort(ID(U), mux.selects[2]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::E, mux.inputs[4]);
+ cell->setPort(ID::F, mux.inputs[5]);
+ cell->setPort(ID::G, mux.inputs[6]);
+ cell->setPort(ID::H, mux.inputs[7]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
+ cell->setPort(ID::U, mux.selects[2]);
cell->setPort(ID::Y, bit);
return;
}
@@ -560,24 +560,24 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX16_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(E), mux.inputs[4]);
- cell->setPort(ID(F), mux.inputs[5]);
- cell->setPort(ID(G), mux.inputs[6]);
- cell->setPort(ID(H), mux.inputs[7]);
- cell->setPort(ID(I), mux.inputs[8]);
- cell->setPort(ID(J), mux.inputs[9]);
- cell->setPort(ID(K), mux.inputs[10]);
- cell->setPort(ID(L), mux.inputs[11]);
- cell->setPort(ID(M), mux.inputs[12]);
- cell->setPort(ID(N), mux.inputs[13]);
- cell->setPort(ID(O), mux.inputs[14]);
- cell->setPort(ID(P), mux.inputs[15]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
- cell->setPort(ID(U), mux.selects[2]);
- cell->setPort(ID(V), mux.selects[3]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::E, mux.inputs[4]);
+ cell->setPort(ID::F, mux.inputs[5]);
+ cell->setPort(ID::G, mux.inputs[6]);
+ cell->setPort(ID::H, mux.inputs[7]);
+ cell->setPort(ID::I, mux.inputs[8]);
+ cell->setPort(ID::J, mux.inputs[9]);
+ cell->setPort(ID::K, mux.inputs[10]);
+ cell->setPort(ID::L, mux.inputs[11]);
+ cell->setPort(ID::M, mux.inputs[12]);
+ cell->setPort(ID::N, mux.inputs[13]);
+ cell->setPort(ID::O, mux.inputs[14]);
+ cell->setPort(ID::P, mux.inputs[15]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
+ cell->setPort(ID::U, mux.selects[2]);
+ cell->setPort(ID::V, mux.selects[3]);
cell->setPort(ID::Y, bit);
return;
}
diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc
index 31ab13cec..2810b7f2d 100644
--- a/passes/techmap/pmuxtree.cc
+++ b/passes/techmap/pmuxtree.cc
@@ -93,7 +93,7 @@ struct PmuxtreePass : public Pass {
continue;
SigSpec sig_data = cell->getPort(ID::B);
- SigSpec sig_sel = cell->getPort(ID(S));
+ SigSpec sig_sel = cell->getPort(ID::S);
if (!cell->getPort(ID::A).is_fully_undef()) {
sig_data.append(cell->getPort(ID::A));
diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc
index be00e5030..d7a381e0a 100644
--- a/passes/techmap/shregmap.cc
+++ b/passes/techmap/shregmap.cc
@@ -71,12 +71,12 @@ struct ShregmapTechGreenpak4 : ShregmapTech
bool fixup(Cell *cell, dict<int, SigBit> &taps)
{
- auto D = cell->getPort(ID(D));
- auto C = cell->getPort(ID(C));
+ auto D = cell->getPort(ID::D);
+ auto C = cell->getPort(ID::C);
auto newcell = cell->module->addCell(NEW_ID, ID(GP_SHREG));
newcell->setPort(ID(nRST), State::S1);
- newcell->setPort(ID(CLK), C);
+ newcell->setPort(ID::CLK, C);
newcell->setPort(ID(IN), D);
int i = 0;
@@ -117,9 +117,9 @@ struct ShregmapWorker
sigbit_with_non_chain_users.insert(bit);
}
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = sigmap(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
if (initval[i] == State::S0 && !opts.zinit)
sigbit_init[initsig[i]] = false;
@@ -319,7 +319,7 @@ struct ShregmapWorker
initval.push_back(State::S0);
remove_init.insert(bit);
}
- first_cell->setParam(ID(INIT), initval);
+ first_cell->setParam(ID::INIT, initval);
}
if (opts.zinit)
@@ -348,7 +348,7 @@ struct ShregmapWorker
first_cell->type = shreg_cell_type_str;
first_cell->setPort(q_port, last_cell->getPort(q_port));
- first_cell->setParam(ID(DEPTH), depth);
+ first_cell->setParam(ID::DEPTH, depth);
if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict))
remove_cells.insert(first_cell);
@@ -366,18 +366,18 @@ struct ShregmapWorker
for (auto wire : module->wires())
{
- if (wire->attributes.count(ID(init)) == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec initsig = sigmap(wire);
- Const &initval = wire->attributes.at(ID(init));
+ Const &initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
if (remove_init.count(initsig[i]))
initval[i] = State::Sx;
if (SigSpec(initval).is_fully_undef())
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
}
remove_cells.clear();
@@ -548,19 +548,19 @@ struct ShregmapPass : public Pass {
bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none";
if (clk_pos && en_none)
- opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_none)
- opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_pos && en_pos)
- opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_pos && en_neg)
- opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_pos)
- opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_neg)
- opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (en_pos || en_neg)
opts.ffe = true;
diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc
index 91574f3c6..b65b3e972 100644
--- a/passes/techmap/simplemap.cc
+++ b/passes/techmap/simplemap.cc
@@ -31,11 +31,11 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::Y, sig_y[i]);
}
@@ -46,7 +46,7 @@ void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
module->connect(RTLIL::SigSig(sig_y, sig_a));
}
@@ -57,8 +57,8 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
- sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
+ sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool());
if (cell->type == ID($xnor))
{
@@ -66,7 +66,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_t[i]);
gate->setPort(ID::Y, sig_y[i]);
}
@@ -83,7 +83,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]);
gate->setPort(ID::Y, sig_y[i]);
@@ -134,7 +134,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
}
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_a[i+1]);
gate->setPort(ID::Y, sig_t[i/2]);
@@ -147,7 +147,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
if (cell->type == ID($reduce_xnor)) {
RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_t);
last_output_cell = gate;
@@ -175,7 +175,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell
}
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig[i]);
gate->setPort(ID::B, sig[i+1]);
gate->setPort(ID::Y, sig_t[i/2]);
@@ -204,7 +204,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
}
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_y);
}
@@ -233,7 +233,7 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
log_assert(!gate_type.empty());
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::B, sig_b);
gate->setPort(ID::Y, sig_y);
@@ -244,24 +244,24 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
bool is_ne = cell->type.in(ID($ne), ID($nex));
RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b)));
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
- xor_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ xor_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_bitop(module, xor_cell);
module->remove(xor_cell);
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
- reduce_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ reduce_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_reduce(module, reduce_cell);
module->remove(reduce_cell);
if (!is_ne) {
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
- not_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ not_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_lognot(module, not_cell);
module->remove(not_cell);
}
@@ -275,10 +275,10 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]);
- gate->setPort(ID(S), cell->getPort(ID(S)));
+ gate->setPort(ID::S, cell->getPort(ID::S));
gate->setPort(ID::Y, sig_y[i]);
}
}
@@ -286,14 +286,14 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
- RTLIL::SigSpec sig_e = cell->getPort(ID(EN));
+ RTLIL::SigSpec sig_e = cell->getPort(ID::EN);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
- gate->setPort(ID(E), sig_e);
+ gate->setPort(ID::E, sig_e);
gate->setPort(ID::Y, sig_y[i]);
}
}
@@ -301,18 +301,18 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
{
SigSpec lut_ctrl = cell->getPort(ID::A);
- SigSpec lut_data = cell->getParam(ID(LUT));
- lut_data.extend_u0(1 << cell->getParam(ID(WIDTH)).as_int());
+ SigSpec lut_data = cell->getParam(ID::LUT);
+ lut_data.extend_u0(1 << cell->getParam(ID::WIDTH).as_int());
for (int idx = 0; GetSize(lut_data) > 1; idx++) {
SigSpec sig_s = lut_ctrl[idx];
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2);
for (int i = 0; i < GetSize(lut_data); i += 2) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, lut_data[i]);
gate->setPort(ID::B, lut_data[i+1]);
- gate->setPort(ID(S), lut_ctrl[idx]);
+ gate->setPort(ID::S, lut_ctrl[idx]);
gate->setPort(ID::Y, new_lut_data[i/2]);
}
lut_data = new_lut_data;
@@ -324,10 +324,10 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
{
SigSpec ctrl = cell->getPort(ID::A);
- SigSpec table = cell->getParam(ID(TABLE));
+ SigSpec table = cell->getParam(ID::TABLE);
- int width = cell->getParam(ID(WIDTH)).as_int();
- int depth = cell->getParam(ID(DEPTH)).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int depth = cell->getParam(ID::DEPTH).as_int();
table.extend_u0(2 * width * depth);
SigSpec products;
@@ -353,7 +353,7 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int offset = cell->parameters.at(ID(OFFSET)).as_int();
+ int offset = cell->parameters.at(ID::OFFSET).as_int();
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size())));
@@ -369,156 +369,156 @@ void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
- char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N';
+ char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
- RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_s = cell->getPort(ID::SET);
+ RTLIL::SigSpec sig_r = cell->getPort(ID::CLR);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(S), sig_s[i]);
- gate->setPort(ID(R), sig_r[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::S, sig_s[i]);
+ gate->setPort(ID::R, sig_r[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
+ int width = cell->parameters.at(ID::WIDTH).as_int();
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = ID($_FF_);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFF_%c_", clk_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(E), sig_en);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::E, sig_en);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
- char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N';
+ char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
- RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_s = cell->getPort(ID::SET);
+ RTLIL::SigSpec sig_r = cell->getPort(ID::CLR);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(S), sig_s[i]);
- gate->setPort(ID(R), sig_r[i]);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::S, sig_s[i]);
+ gate->setPort(ID::R, sig_r[i]);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char rst_pol = cell->parameters.at(ID(ARST_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char rst_pol = cell->parameters.at(ID::ARST_POLARITY).as_bool() ? 'P' : 'N';
- std::vector<RTLIL::State> rst_val = cell->parameters.at(ID(ARST_VALUE)).bits;
+ std::vector<RTLIL::State> rst_val = cell->parameters.at(ID::ARST_VALUE).bits;
while (int(rst_val.size()) < width)
rst_val.push_back(RTLIL::State::S0);
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_rst = cell->getPort(ID(ARST));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_rst = cell->getPort(ID::ARST);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol);
IdString gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(R), sig_rst);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::R, sig_rst);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DLATCH_%c_", en_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(E), sig_en);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::E, sig_en);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index 0c57733d4..518afa1a7 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -146,7 +146,7 @@ struct TechmapWorker
record.value = it.second;
result[p].push_back(record);
it.second->attributes[ID::keep] = RTLIL::Const(1);
- it.second->attributes[ID(_techmap_special_)] = RTLIL::Const(1);
+ it.second->attributes[ID::_techmap_special_] = RTLIL::Const(1);
}
}
@@ -175,12 +175,12 @@ struct TechmapWorker
}
std::string orig_cell_name;
- pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(src));
+ pool<string> extra_src_attrs = cell->get_strpool_attribute(ID::src);
+ orig_cell_name = cell->name.str();
if (!flatten_mode) {
for (auto &it : tpl->cells_)
- if (it.first == ID(_TECHMAP_REPLACE_)) {
- orig_cell_name = cell->name.str();
+ if (it.first == ID::_TECHMAP_REPLACE_) {
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
break;
}
@@ -197,8 +197,8 @@ struct TechmapWorker
m->start_offset = it.second->start_offset;
m->size = it.second->size;
m->attributes = it.second->attributes;
- if (m->attributes.count(ID(src)))
- m->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (m->attributes.count(ID::src))
+ m->add_strpool_attribute(ID::src, extra_src_attrs);
module->memories[m->name] = m;
memory_renames[it.first] = m->name;
design->select(module, m);
@@ -215,7 +215,7 @@ struct TechmapWorker
IdString posportname = stringf("$%d", it.second->port_id);
positional_ports[posportname] = it.first;
- if (!flatten_mode && it.second->get_bool_attribute(ID(techmap_autopurge)) &&
+ if (!flatten_mode && it.second->get_bool_attribute(ID::techmap_autopurge) &&
(!cell->hasPort(it.second->name) || !GetSize(cell->getPort(it.second->name))) &&
(!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname))))
{
@@ -231,12 +231,12 @@ struct TechmapWorker
apply_prefix(cell->name, w_name);
RTLIL::Wire *w = module->wire(w_name);
if (w != nullptr) {
- if (!flatten_mode || !w->get_bool_attribute(ID(hierconn))) {
+ if (!flatten_mode || !w->get_bool_attribute(ID::hierconn)) {
temp_renamed_wires[w] = w->name;
module->rename(w, NEW_ID);
w = nullptr;
} else {
- w->attributes.erase(ID(hierconn));
+ w->attributes.erase(ID::hierconn);
if (GetSize(w) < GetSize(it.second)) {
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));
@@ -250,11 +250,11 @@ struct TechmapWorker
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_)))
+ w->attributes.erase(ID::techmap_autopurge);
+ if (it.second->get_bool_attribute(ID::_techmap_special_))
w->attributes.clear();
- if (w->attributes.count(ID(src)))
- w->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (w->attributes.count(ID::src))
+ w->add_strpool_attribute(ID::src, extra_src_attrs);
}
design->select(module, w);
@@ -363,7 +363,7 @@ struct TechmapWorker
}
for (auto &attr : w->attributes) {
- if (attr.first == ID(src))
+ if (attr.first == ID::src)
continue;
auto lhs = GetSize(extra_connect.first);
auto rhs = GetSize(extra_connect.second);
@@ -380,7 +380,7 @@ struct TechmapWorker
for (auto &it : tpl->cells_)
{
IdString c_name = it.second->name.str();
- bool techmap_replace_cell = (!flatten_mode) && (c_name == ID(_TECHMAP_REPLACE_));
+ bool techmap_replace_cell = (!flatten_mode) && (c_name == ID::_TECHMAP_REPLACE_);
if (techmap_replace_cell)
c_name = orig_cell_name;
@@ -421,19 +421,19 @@ struct TechmapWorker
c->unsetPort(it2);
if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
- IdString memid = c->getParam(ID(MEMID)).decode_string();
+ IdString memid = c->getParam(ID::MEMID).decode_string();
log_assert(memory_renames.count(memid) != 0);
- c->setParam(ID(MEMID), Const(memory_renames[memid].str()));
+ c->setParam(ID::MEMID, Const(memory_renames[memid].str()));
}
if (c->type == ID($mem)) {
- IdString memid = c->getParam(ID(MEMID)).decode_string();
+ IdString memid = c->getParam(ID::MEMID).decode_string();
apply_prefix(cell->name, memid);
- c->setParam(ID(MEMID), Const(memid.c_str()));
+ c->setParam(ID::MEMID, Const(memid.c_str()));
}
- if (c->attributes.count(ID(src)))
- c->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (c->attributes.count(ID::src))
+ c->add_strpool_attribute(ID::src, extra_src_attrs);
if (techmap_replace_cell)
for (auto attr : cell->attributes)
@@ -481,8 +481,8 @@ struct TechmapWorker
pool<SigBit> remove_init_bits;
for (auto wire : module->wires()) {
- if (wire->attributes.count("\\init")) {
- Const value = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const value = wire->attributes.at(ID::init);
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
if (value[i] != State::Sx)
init_bits[sigmap(SigBit(wire, i))] = value[i];
@@ -509,9 +509,9 @@ struct TechmapWorker
}
if (flatten_mode) {
- bool keepit = cell->get_bool_attribute(ID(keep_hierarchy));
+ 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->modules_[tpl_name]->get_bool_attribute(ID::keep_hierarchy))
keepit = true;
if (keepit) {
if (!flatten_keep_list[cell]) {
@@ -577,13 +577,13 @@ struct TechmapWorker
{
std::string extmapper_name;
- if (tpl->get_bool_attribute(ID(techmap_simplemap)))
+ if (tpl->get_bool_attribute(ID::techmap_simplemap))
extmapper_name = "simplemap";
- if (tpl->get_bool_attribute(ID(techmap_maccmap)))
+ if (tpl->get_bool_attribute(ID::techmap_maccmap))
extmapper_name = "maccmap";
- if (tpl->attributes.count(ID(techmap_wrap)))
+ if (tpl->attributes.count(ID::techmap_wrap))
extmapper_name = "wrap";
if (!extmapper_name.empty())
@@ -598,7 +598,7 @@ struct TechmapWorker
m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
if (extmapper_name == "wrap")
- m_name += ":" + sha1(tpl->attributes.at(ID(techmap_wrap)).decode_string());
+ m_name += ":" + sha1(tpl->attributes.at(ID::techmap_wrap).decode_string());
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
@@ -613,7 +613,7 @@ struct TechmapWorker
int port_counter = 1;
for (auto &c : extmapper_cell->connections_) {
RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
- if (w->name.in(ID::Y, ID(Q)))
+ if (w->name.in(ID::Y, ID::Q))
w->port_output = true;
else
w->port_input = true;
@@ -641,7 +641,7 @@ struct TechmapWorker
}
if (extmapper_name == "wrap") {
- std::string cmd_string = tpl->attributes.at(ID(techmap_wrap)).decode_string();
+ std::string cmd_string = tpl->attributes.at(ID::techmap_wrap).decode_string();
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
mkdebug.on();
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
@@ -709,8 +709,8 @@ struct TechmapWorker
continue;
}
- if (tpl->avail_parameters.count(ID(_TECHMAP_CELLTYPE_)) != 0)
- parameters[ID(_TECHMAP_CELLTYPE_)] = RTLIL::unescape_id(cell->type);
+ if (tpl->avail_parameters.count(ID::_TECHMAP_CELLTYPE_) != 0)
+ parameters[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) {
@@ -760,8 +760,8 @@ struct TechmapWorker
bits = i;
// Increment index by one to get number of bits
bits++;
- if (tpl->avail_parameters.count(ID(_TECHMAP_BITS_CONNMAP_)))
- parameters[ID(_TECHMAP_BITS_CONNMAP_)] = bits;
+ 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) {
@@ -906,8 +906,8 @@ struct TechmapWorker
RTLIL::SigSig port_conn;
for (auto &it : port_connmap) {
- port_conn.first.append_bit(it.first);
- port_conn.second.append_bit(it.second);
+ port_conn.first.append(it.first);
+ port_conn.second.append(it.second);
}
tpl->connect(port_conn);
@@ -1030,8 +1030,8 @@ struct TechmapWorker
if (!remove_init_bits.empty()) {
for (auto wire : module->wires())
- if (wire->attributes.count("\\init")) {
- Const &value = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const &value = wire->attributes.at(ID::init);
bool do_cleanup = true;
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
SigBit bit = sigmap(SigBit(wire, i));
@@ -1042,7 +1042,7 @@ struct TechmapWorker
}
if (do_cleanup) {
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
@@ -1302,8 +1302,8 @@ struct TechmapPass : public Pass {
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());
+ 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);
free(p);
@@ -1389,7 +1389,7 @@ struct FlattenPass : public Pass {
RTLIL::Module *top_mod = NULL;
if (design->full_selection())
for (auto mod : design->modules())
- if (mod->get_bool_attribute(ID(top)))
+ if (mod->get_bool_attribute(ID::top))
top_mod = mod;
std::set<RTLIL::Cell*> handled_cells;
diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc
index decf9a202..90f3a9d6f 100644
--- a/passes/techmap/tribuf.cc
+++ b/passes/techmap/tribuf.cc
@@ -71,7 +71,7 @@ struct TribufWorker {
if (cell->type.in(ID($mux), ID($_MUX_)))
{
- IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E);
+ IdString en_port = cell->type == ID($mux) ? ID::EN : ID::E;
IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_);
if (is_all_z(cell->getPort(ID::A)) && is_all_z(cell->getPort(ID::B))) {
@@ -81,9 +81,9 @@ struct TribufWorker {
if (is_all_z(cell->getPort(ID::A))) {
cell->setPort(ID::A, cell->getPort(ID::B));
- cell->setPort(en_port, cell->getPort(ID(S)));
+ cell->setPort(en_port, cell->getPort(ID::S));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
@@ -91,9 +91,9 @@ struct TribufWorker {
}
if (is_all_z(cell->getPort(ID::B))) {
- cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S))));
+ cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID::S)));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
@@ -121,9 +121,9 @@ struct TribufWorker {
SigSpec pmux_b, pmux_s;
for (auto cell : it.second) {
if (cell->type == ID($tribuf))
- pmux_s.append(cell->getPort(ID(EN)));
+ pmux_s.append(cell->getPort(ID::EN));
else
- pmux_s.append(cell->getPort(ID(E)));
+ pmux_s.append(cell->getPort(ID::E));
pmux_b.append(cell->getPort(ID::A));
module->remove(cell);
}
diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc
index ac3d4ed4a..a427c4987 100644
--- a/passes/techmap/zinit.cc
+++ b/passes/techmap/zinit.cc
@@ -62,12 +62,12 @@ struct ZinitPass : public Pass {
for (auto wire : module->selected_wires())
{
- if (wire->attributes.count(ID(init)) == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at(ID(init));
- wire->attributes.erase(ID(init));
+ Const initval = wire->attributes.at(ID::init);
+ wire->attributes.erase(ID::init);
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
{
@@ -103,8 +103,8 @@ struct ZinitPass : public Pass {
if (!dff_types.count(cell->type))
continue;
- SigSpec sig_d = sigmap(cell->getPort(ID(D)));
- SigSpec sig_q = sigmap(cell->getPort(ID(Q)));
+ SigSpec sig_d = sigmap(cell->getPort(ID::D));
+ SigSpec sig_q = sigmap(cell->getPort(ID::Q));
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
continue;
@@ -120,14 +120,14 @@ struct ZinitPass : public Pass {
}
Wire *initwire = module->addWire(NEW_ID, GetSize(initval));
- initwire->attributes[ID(init)] = initval;
+ initwire->attributes[ID::init] = initval;
for (int i = 0; i < GetSize(initwire); i++)
if (initval.bits.at(i) == State::S1)
{
sig_d[i] = module->NotGate(NEW_ID, sig_d[i]);
module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]);
- initwire->attributes[ID(init)].bits.at(i) = State::S0;
+ initwire->attributes[ID::init].bits.at(i) = State::S0;
}
else
{
@@ -137,8 +137,8 @@ struct ZinitPass : public Pass {
log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type),
log_signal(sig_q), log_signal(initval));
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), initwire);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, initwire);
}
for (auto &it : initbits)