diff options
Diffstat (limited to 'passes/techmap')
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) |