diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 45d3d7b90..7c18c7ba0 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -42,7 +42,7 @@ jobs: - 'gcc-10' # newest, make sure to update maximum standard step to match - 'clang-19' - - 'gcc-13' + - 'gcc-14' include: # macOS x86 - os: macos-13 @@ -81,7 +81,7 @@ jobs: # maximum standard, only on newest compilers - name: Build C++20 - if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-13' }} + if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }} shell: bash run: | make config-$CC_SHORT diff --git a/Makefile b/Makefile index 139a8be0a..acfd64f01 100644 --- a/Makefile +++ b/Makefile @@ -180,7 +180,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.57+72 +YOSYS_VER := 0.57+157 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'.' -f3) @@ -681,6 +681,7 @@ $(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o +OBJS += kernel/rtlil_bufnorm.o OBJS += kernel/log_help.o ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) OBJS += kernel/log_compat.o diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index c7ed3b81f..05714bc2e 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -91,7 +91,7 @@ struct Index { int pos = index_wires(info, m); for (auto cell : m->cells()) { - if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3))) + if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port))) continue; Module *submodule = m->design->module(cell->type); @@ -566,7 +566,7 @@ struct Index { } Lit ret; - if (!bit.wire->port_input) { + if (!bit.wire->port_input || bit.wire->port_output) { // an output of a cell Cell *driver = bit.wire->driverCell(); @@ -618,7 +618,7 @@ struct Index { if (!cursor) { log_assert(bit.wire->module == top); - log_assert(bit.wire->port_input); + log_assert(bit.wire->port_input && !bit.wire->port_output); return lits[top_minfo->windices[bit.wire] + bit.offset]; } else { log_assert(bit.wire->module == cursor->leaf_module(*this)); @@ -723,7 +723,7 @@ struct AigerWriter : Index { for (auto id : top->ports) { Wire *w = top->wire(id); log_assert(w); - if (w->port_input) + if (w->port_input && !w->port_output) for (int i = 0; i < w->width; i++) { pi_literal(SigBit(w, i)) = lit_counter; inputs.push_back(SigBit(w, i)); @@ -828,7 +828,7 @@ struct XAigerAnalysis : Index { { log_assert(cursor.is_top()); // TOOD: fix analyzer to work with hierarchy - if (bit.wire->port_input) + if (bit.wire->port_input && !bit.wire->port_output) return false; Cell *driver = bit.wire->driverCell(); @@ -838,7 +838,7 @@ struct XAigerAnalysis : Index { int max = 1; for (auto wire : mod->wires()) - if (wire->port_input) + if (wire->port_input && !wire->port_output) for (int i = 0; i < wire->width; i++) { int ilevel = visit(cursor, driver->getPort(wire->name)[i]); max = std::max(max, ilevel + 1); @@ -858,7 +858,7 @@ struct XAigerAnalysis : Index { for (auto id : top->ports) { Wire *w = top->wire(id); log_assert(w); - if (w->port_input) + if (w->port_input && !w->port_output) for (int i = 0; i < w->width; i++) pi_literal(SigBit(w, i)) = 0; } @@ -868,7 +868,7 @@ struct XAigerAnalysis : Index { Module *def = design->module(box->type); if (!(def && def->has_attribute(ID::abc9_box_id))) for (auto &conn : box->connections_) - if (box->output(conn.first)) + if (box->port_dir(conn.first) != RTLIL::PD_INPUT) for (auto bit : conn.second) pi_literal(bit, &cursor) = 0; } @@ -883,7 +883,7 @@ struct XAigerAnalysis : Index { Module *def = design->module(box->type); if (!(def && def->has_attribute(ID::abc9_box_id))) for (auto &conn : box->connections_) - if (box->input(conn.first)) + if (box->port_dir(conn.first) == RTLIL::PD_INPUT) for (auto bit : conn.second) (void) eval_po(bit); } @@ -903,6 +903,16 @@ struct XAigerWriter : AigerWriter { typedef std::pair HierBit; std::vector pos; std::vector pis; + + // * The aiger output port sequence is COs (inputs to modeled boxes), + // inputs to opaque boxes, then module outputs. COs going first is + // required by abc. + // * proper_pos_counter counts ports which follow after COs + // * The mapping file `pseudopo` and `po` statements use indexing relative + // to the first port following COs. + // * If a module output is directly driven by an opaque box, the emission + // of the po statement in the mapping file is skipped. This is done to + // aid re-integration of the mapped result. int proper_pos_counter = 0; pool driven_by_opaque_box; @@ -937,15 +947,10 @@ struct XAigerWriter : AigerWriter { lit_counter += 2; } - void append_box_ports(Cell *box, HierCursor &cursor, bool inputs) + void append_opaque_box_ports(Cell *box, HierCursor &cursor, bool inputs) { for (auto &conn : box->connections_) { - bool is_input = box->input(conn.first); - bool is_output = box->output(conn.first); - - if (!(is_input || is_output) || (is_input && is_output)) - log_error("Ambiguous port direction on %s/%s\n", - log_id(box->type), log_id(conn.first)); + bool is_input = box->port_dir(conn.first) == RTLIL::PD_INPUT; if (is_input && inputs) { int bitp = 0; @@ -955,13 +960,14 @@ struct XAigerWriter : AigerWriter { continue; } + // Inputs to opaque boxes are proper POs as far as abc is concerned if (map_file.is_open()) { log_assert(cursor.is_top()); - map_file << "pseudopo " << proper_pos_counter++ << " " << bitp + map_file << "pseudopo " << proper_pos_counter << " " << bitp << " " << box->name.c_str() << " " << conn.first.c_str() << "\n"; } - + proper_pos_counter++; pos.push_back(std::make_pair(bit, cursor)); if (mapping_prep) @@ -969,10 +975,10 @@ struct XAigerWriter : AigerWriter { bitp++; } - } else if (is_output && !inputs) { + } else if (!is_input && !inputs) { for (auto &bit : conn.second) { - if (!bit.wire || bit.wire->port_input) - log_error("Bad connection"); + if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output)) + log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second)); ensure_pi(bit, cursor); @@ -1012,7 +1018,7 @@ struct XAigerWriter : AigerWriter { for (auto box : minfo.found_blackboxes) { log_debug(" - %s.%s (type %s): ", cursor.path().c_str(), - RTLIL::unescape_id(box->name).c_str(), + RTLIL::unescape_id(box->name), log_id(box->type)); Module *box_module = design->module(box->type), *box_derived; @@ -1038,7 +1044,7 @@ struct XAigerWriter : AigerWriter { }); for (auto [cursor, box, def] : opaque_boxes) - append_box_ports(box, cursor, false); + append_opaque_box_ports(box, cursor, false); holes_module = design->addModule(NEW_ID); std::vector holes_pis; @@ -1086,6 +1092,8 @@ struct XAigerWriter : AigerWriter { bit = RTLIL::Sx; } + // Nonopaque box inputs come first and are not part of + // the PO numbering used by the mapping file. pos.push_back(std::make_pair(bit, cursor)); } boxes_co_num += port->width; @@ -1106,7 +1114,7 @@ struct XAigerWriter : AigerWriter { holes_pi_idx++; } holes_wb->setPort(port_id, in_conn); - } else if (port->port_output && !port->port_input) { + } else if (port->port_output) { // primary for (int i = 0; i < port->width; i++) { SigBit bit; @@ -1138,7 +1146,7 @@ struct XAigerWriter : AigerWriter { } for (auto [cursor, box, def] : opaque_boxes) - append_box_ports(box, cursor, true); + append_opaque_box_ports(box, cursor, true); write_be32(h_buffer, 1); write_be32(h_buffer, pis.size()); @@ -1159,7 +1167,7 @@ struct XAigerWriter : AigerWriter { log_assert(port); if (port->port_input && !port->port_output) { box_co_num += port->width; - } else if (port->port_output && !port->port_input) { + } else if (port->port_output) { box_ci_num += port->width; } else { log_abort(); @@ -1182,7 +1190,7 @@ struct XAigerWriter : AigerWriter { reset_counters(); for (auto w : top->wires()) - if (w->port_input) + if (w->port_input && !w->port_output) for (int i = 0; i < w->width; i++) ensure_pi(SigBit(w, i)); @@ -1195,10 +1203,14 @@ struct XAigerWriter : AigerWriter { for (auto w : top->wires()) if (w->port_output) for (int i = 0; i < w->width; i++) { + // When a module output is directly driven by an opaque box, we + // don't emit it to the mapping file to aid re-integration, but we + // do emit a proper PO. if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) { - map_file << "po " << proper_pos_counter++ << " " << i + map_file << "po " << proper_pos_counter << " " << i << " " << w->name.c_str() << "\n"; } + proper_pos_counter++; pos.push_back(std::make_pair(SigBit(w, i), HierCursor{})); } @@ -1446,7 +1458,7 @@ struct XAiger2Backend : Backend { if (!map_filename.empty()) { writer.map_file.open(map_filename); if (!writer.map_file) - log_cmd_error("Failed to open '%s' for writing\n", map_filename.c_str()); + log_cmd_error("Failed to open '%s' for writing\n", map_filename); } design->bufNormalize(true); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 5fd21717e..bba7249c7 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -705,12 +705,13 @@ struct BtorWorker } } - Const initval; + Const::Builder initval_bits(GetSize(sig_q)); for (int i = 0; i < GetSize(sig_q); i++) if (initbits.count(sig_q[i])) - initval.bits().push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0); + initval_bits.push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0); else - initval.bits().push_back(State::Sx); + initval_bits.push_back(State::Sx); + Const initval = initval_bits.build(); int nid_init_val = -1; @@ -1039,10 +1040,11 @@ struct BtorWorker { if (bit.wire == nullptr) { - Const c(bit.data); - - while (i+GetSize(c) < GetSize(sig) && sig[i+GetSize(c)].wire == nullptr) - c.bits().push_back(sig[i+GetSize(c)].data); + Const::Builder c_bits; + c_bits.push_back(bit.data); + while (i + GetSize(c_bits) < GetSize(sig) && sig[i + GetSize(c_bits)].wire == nullptr) + c_bits.push_back(sig[i + GetSize(c_bits)].data); + Const c = c_bits.build(); if (consts.count(c) == 0) { int sid = get_bv_sid(GetSize(c)); diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 0c9f6c054..48710aff8 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1533,7 +1533,7 @@ struct CxxrtlWorker { } // Internal cells } else if (is_internal_cell(cell->type)) { - log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str()); + log_cmd_error("Unsupported internal cell `%s'.\n", cell->type); // User cells } else if (for_debug) { // Outlines are called on demand when computing the value of a debug item. Nothing to do here. @@ -1668,26 +1668,29 @@ struct CxxrtlWorker { f << signal_temp << " == "; dump_sigspec(compare, /*is_lhs=*/false, for_debug); } else if (compare.is_fully_const()) { - RTLIL::Const compare_mask, compare_value; + RTLIL::Const::Builder compare_mask_builder(compare.size()); + RTLIL::Const::Builder compare_value_builder(compare.size()); for (auto bit : compare.as_const()) { switch (bit) { case RTLIL::S0: case RTLIL::S1: - compare_mask.bits().push_back(RTLIL::S1); - compare_value.bits().push_back(bit); + compare_mask_builder.push_back(RTLIL::S1); + compare_value_builder.push_back(bit); break; case RTLIL::Sx: case RTLIL::Sz: case RTLIL::Sa: - compare_mask.bits().push_back(RTLIL::S0); - compare_value.bits().push_back(RTLIL::S0); + compare_mask_builder.push_back(RTLIL::S0); + compare_value_builder.push_back(RTLIL::S0); break; default: log_assert(false); } } + RTLIL::Const compare_mask = compare_mask_builder.build(); + RTLIL::Const compare_value = compare_value_builder.build(); f << "and_uu<" << compare.size() << ">(" << signal_temp << ", "; dump_const(compare_mask); f << ") == "; @@ -3042,7 +3045,7 @@ struct CxxrtlWorker { if (init == RTLIL::Const()) { init = RTLIL::Const(State::Sx, GetSize(bit.wire)); } - init.bits()[bit.offset] = port.init_value[i]; + init.set(bit.offset, port.init_value[i]); } } } @@ -3800,7 +3803,7 @@ struct CxxrtlBackend : public Backend { if (args[argidx] == "-print-output" && argidx+1 < args.size()) { worker.print_output = args[++argidx]; if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) { - log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str()); + log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output); worker.print_output = "std::cout"; } continue; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 83d0afaf3..61d6ee254 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -30,9 +30,9 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str() -#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br).c_str() -#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str() +#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true) +#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br) +#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false) struct EdifNames { @@ -513,7 +513,7 @@ struct EdifBackend : public Backend { if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) { if (sig == RTLIL::State::Sx) { for (auto &ref : it.second) - log_warning("Exporting x-bit on %s as zero bit.\n", ref.first.c_str()); + log_warning("Exporting x-bit on %s as zero bit.\n", ref.first); sig = RTLIL::State::S0; } else if (sig == RTLIL::State::Sz) { continue; diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index e54b46e63..577d95ad7 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -465,7 +465,7 @@ struct FirrtlWorker // If there is no instance for this, just return. if (instModule == NULL) { - log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str()); + log_warning("No instance for %s.%s\n", cell_type, cell_name); return; } @@ -490,7 +490,7 @@ struct FirrtlWorker const SigSpec *sinkSig = nullptr; switch (dir) { case FD_INOUT: - log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second)); + log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type, log_signal(it->second)); YS_FALLTHROUGH case FD_OUT: sourceExpr = firstName; @@ -498,7 +498,7 @@ struct FirrtlWorker sinkSig = &secondSig; break; case FD_NODIRECTION: - log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second)); + log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type, log_signal(it->second)); YS_FALLTHROUGH case FD_IN: sourceExpr = secondExpr; diff --git a/backends/functional/test_generic.cc b/backends/functional/test_generic.cc index a0474ea2b..c01649a0f 100644 --- a/backends/functional/test_generic.cc +++ b/backends/functional/test_generic.cc @@ -105,7 +105,7 @@ struct MemContentsTest { RTLIL::Const values; for(addr_t addr = low; addr <= high; addr++) { RTLIL::Const word(data_dist(rnd), data_width); - values.bits().insert(values.bits().end(), word.begin(), word.end()); + values.append(word); } insert_concatenated(low, values); } diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc index ed981f961..8ebc685f0 100644 --- a/backends/simplec/simplec.cc +++ b/backends/simplec/simplec.cc @@ -657,7 +657,7 @@ struct SimplecWorker { SigSpec sig = sigmaps.at(module)(w); Const val = w->attributes.at(ID::init); - val.bits().resize(GetSize(sig), State::Sx); + val.resize(GetSize(sig), State::Sx); for (int i = 0; i < GetSize(sig); i++) if (val[i] == State::S0 || val[i] == State::S1) { diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 1d3757463..d80622029 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -1079,14 +1079,14 @@ struct Smt2Worker RTLIL::SigSpec sig = sigmap(wire); Const val = wire->attributes.at(ID::init); - val.bits().resize(GetSize(sig), State::Sx); + val.resize(GetSize(sig), State::Sx); if (bvmode && GetSize(sig) > 1) { Const mask(State::S1, GetSize(sig)); bool use_mask = false; for (int i = 0; i < GetSize(sig); i++) if (val[i] != State::S0 && val[i] != State::S1) { - val.bits()[i] = State::S0; - mask.bits()[i] = State::S0; + val.set(i, State::S0); + mask.set(i, State::S0); use_mask = true; } if (use_mask) @@ -1361,10 +1361,10 @@ struct Smt2Worker for (int k = 0; k < GetSize(initword); k++) { if (initword[k] == State::S0 || initword[k] == State::S1) { gen_init_constr = true; - initmask.bits()[k] = State::S1; + initmask.set(k, State::S1); } else { - initmask.bits()[k] = State::S0; - initword.bits()[k] = State::S0; + initmask.set(k, State::S0); + initword.set(k, State::S0); } } diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index ae7df4776..7011f4b3c 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -327,19 +327,20 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o void dump_reg_init(std::ostream &f, SigSpec sig) { - Const initval; bool gotinit = false; + Const::Builder initval_bits(sig.size()); for (auto bit : active_sigmap(sig)) { if (active_initdata.count(bit)) { - initval.bits().push_back(active_initdata.at(bit)); + initval_bits.push_back(active_initdata.at(bit)); gotinit = true; } else { - initval.bits().push_back(State::Sx); + initval_bits.push_back(State::Sx); } } if (gotinit) { + Const initval = initval_bits.build(); f << " = "; dump_const(f, initval); } @@ -784,9 +785,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) dump_sigspec(os, port.data.extract(sub * mem.width, mem.width)); os << stringf(" = %s[", mem_id);; if (port.wide_log2) { - Const addr_lo; + Const::Builder addr_lo_builder(port.wide_log2); for (int i = 0; i < port.wide_log2; i++) - addr_lo.bits().push_back(State(sub >> i & 1)); + addr_lo_builder.push_back(State(sub >> i & 1)); + Const addr_lo = addr_lo_builder.build(); os << "{"; os << temp_id; os << ", "; @@ -985,7 +987,7 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) + if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) { RTLIL::SigSpec sig = cell->getPort(ID::Q); if (GetSize(sig) != 1 || sig.is_fully_const()) @@ -1114,6 +1116,33 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) } if (cell->type.in(ID($_BUF_), ID($buf))) { + if (cell->type == ID($buf) && cell->getPort(ID::A).has_const(State::Sz)) { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); + a.extend_u0(GetSize(y)); + + if (a.has_const(State::Sz)) { + SigSpec new_a; + SigSpec new_y; + for (int i = 0; i < GetSize(a); ++i) { + SigBit b = a[i]; + if (b == State::Sz) + continue; + new_a.append(b); + new_y.append(y[i]); + } + a = std::move(new_a); + y = std::move(new_y); + } + if (!y.empty()) { + f << stringf("%s" "assign ", indent); + dump_sigspec(f, y); + f << stringf(" = "); + dump_sigspec(f, a); + f << stringf(";\n"); + } + return true; + } f << stringf("%s" "assign ", indent); dump_sigspec(f, cell->getPort(ID::Y)); f << stringf(" = "); @@ -1513,7 +1542,30 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->type == ID($input_port)) + return true; + + if (cell->type == ID($connect)) + { + int width = cell->getParam(ID::WIDTH).as_int() ; + if (width == 1) { + f << stringf("%s" "tran(", indent); + dump_sigspec(f, cell->getPort(ID::A)); + f << stringf(", "); + dump_sigspec(f, cell->getPort(ID::B)); + f << stringf(");\n"); + } else { + auto tran_id = next_auto_id(); + f << stringf("%s" "tran %s[%d:0](", indent, tran_id, width - 1); + dump_sigspec(f, cell->getPort(ID::A)); + f << stringf(", "); + dump_sigspec(f, cell->getPort(ID::B)); + f << stringf(");\n"); + } + return true; + } + + if (cell->is_builtin_ff()) { FfData ff(nullptr, cell); @@ -1991,7 +2043,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } - if (siminit && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) { + if (siminit && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) { std::stringstream ss; dump_reg_init(ss, cell->getPort(ID::Q)); if (!ss.str().empty()) { @@ -2349,7 +2401,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) continue; } - if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) + if (!cell->is_builtin_ff() || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) continue; RTLIL::SigSpec sig = cell->getPort(ID::Q); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index db4cb12ba..70d94faff 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -448,7 +448,7 @@ void AigerReader::parse_xaiger() bool success = ce.eval(o); log_assert(success); log_assert(o.wire == nullptr); - lut_mask.bits()[gray] = o.data; + lut_mask.set(gray, o.data); } RTLIL::Cell *output_cell = module->cell(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID)); log_assert(output_cell); diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index b61c0bea9..4a16abee9 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1076,8 +1076,10 @@ RTLIL::Const AstNode::realAsConst(int width) bool is_negative = v < 0; if (is_negative) v *= -1; + RTLIL::Const::Builder b(width); for (int i = 0; i < width; i++, v /= 2) - result.bits().push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0); + b.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0); + result = b.build(); if (is_negative) result = const_neg(result, result, false, false, result.size()); } @@ -1444,7 +1446,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump if (design->has(child->str)) { RTLIL::Module *existing_mod = design->module(child->str); if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { - log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str.c_str()); + log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str); } else if (nooverwrite) { log("Ignoring re-definition of module `%s' at %s.\n", child->str.c_str(), child->loc_string().c_str()); @@ -1820,7 +1822,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict rewritten; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 41e10cf98..c26750c98 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -732,16 +732,17 @@ struct AST_INTERNAL::ProcessGenerator current_case->actions.push_back(SigSig(en, true)); RTLIL::SigSpec triggers; - RTLIL::Const polarity; + RTLIL::Const::Builder polarity_builder; for (auto sync : proc->syncs) { if (sync->type == RTLIL::STp) { triggers.append(sync->signal); - polarity.bits().push_back(RTLIL::S1); + polarity_builder.push_back(RTLIL::S1); } else if (sync->type == RTLIL::STn) { triggers.append(sync->signal); - polarity.bits().push_back(RTLIL::S0); + polarity_builder.push_back(RTLIL::S0); } } + RTLIL::Const polarity = polarity_builder.build(); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print)); set_src_attr(cell, ast); @@ -794,7 +795,7 @@ struct AST_INTERNAL::ProcessGenerator fmt.append_literal("\n"); fmt.emit_rtlil(cell); } else if (!ast->str.empty()) { - log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); + log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str); } break; @@ -829,22 +830,23 @@ struct AST_INTERNAL::ProcessGenerator current_case->actions.push_back(SigSig(en, true)); RTLIL::SigSpec triggers; - RTLIL::Const polarity; + RTLIL::Const::Builder polarity_builder; for (auto sync : proc->syncs) { if (sync->type == RTLIL::STp) { triggers.append(sync->signal); - polarity.bits().push_back(RTLIL::S1); + polarity_builder.push_back(RTLIL::S1); } else if (sync->type == RTLIL::STn) { triggers.append(sync->signal); - polarity.bits().push_back(RTLIL::S0); + polarity_builder.push_back(RTLIL::S0); } } + RTLIL::Const polarity = polarity_builder.build(); RTLIL::Cell *cell = current_module->addCell(cellname, ID($check)); set_src_attr(cell, ast); for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first); cell->attributes[attr.first] = attr.second->asAttrConst(); } cell->setParam(ID::FLAVOR, flavor); @@ -893,7 +895,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx); for (int i = 0; i < portid; i++) { int new_bit = port_map[std::make_pair(memid, i)]; - priority_mask.bits()[new_bit] = orig_priority_mask[i]; + priority_mask.set(new_bit, orig_priority_mask[i]); } action.priority_mask = priority_mask; sync->mem_write_actions.push_back(action); @@ -1239,7 +1241,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun while (children[0]->simplify(true, 1, -1, false) == true) { } if (children[0]->type != AST_CONSTANT) input_error("System function %s called with non-const argument!\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); width_hint = max(width_hint, int(children[0]->asInt(true))); } break; @@ -1289,7 +1291,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun while (right->simplify(true, 1, -1, false)) { } if (left->type != AST_CONSTANT || right->type != AST_CONSTANT) input_error("Function %s has non-constant width!", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); result_width = abs(int(left->asInt(true) - right->asInt(true))); } width_hint = max(width_hint, result_width); @@ -1537,7 +1539,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (dynamic_cast(current_module)) { /* nothing to do here */ } else if (flag_autowire) - log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str); else input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str); } @@ -2193,12 +2195,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int sz = children.size(); if (str == "$info") { if (sz > 0) - log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str()); + log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str); else log_file_info(*location.begin.filename, location.begin.line, "\n"); } else if (str == "$warning") { if (sz > 0) - log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str); else log_file_warning(*location.begin.filename, location.begin.line, "\n"); } else if (str == "$error") { @@ -2235,12 +2237,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (GetSize(children) > 1) input_error("System function %s got %d arguments, expected 1 or 0.\n", - RTLIL::unescape_id(str).c_str(), GetSize(children)); + RTLIL::unescape_id(str), GetSize(children)); if (GetSize(children) == 1) { if (children[0]->type != AST_CONSTANT) input_error("System function %s called with non-const argument!\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); width = children[0]->asInt(true); } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7328290ea..81018e137 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -161,10 +161,10 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_ arg.sig = node_arg->bitsAsConst(); arg.signed_ = node_arg->is_signed; } else if (may_fail) { - log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str, index + 1); return Fmt(); } else { - log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str, index + 1); } args.push_back(arg); } @@ -974,7 +974,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin message += stringf("%s%s", first_element ? " See " : ", ", place); first_element = false; } - log_warning("%s\n", message.c_str()); + log_warning("%s\n", message); } silent_activate: @@ -1032,7 +1032,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" || str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) { - log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str); delete_children(); str = std::string(); } @@ -1042,7 +1042,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { if (!current_always) { - log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str); delete_children(); str = std::string(); } else { @@ -1144,7 +1144,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin i--; // Adjust index since we removed an element } else { // If we can't find the package, just remove the import node to avoid errors later - log_warning("Package `%s' not found for import, removing import statement\n", child->str.c_str()); + log_warning("Package `%s' not found for import, removing import statement\n", child->str); children.erase(children.begin() + i); i--; // Adjust index since we removed an element } @@ -1438,7 +1438,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic) children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg) - log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str.c_str(), loc_string().c_str()); + log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str, loc_string()); if (type == AST_ASSIGN && children[0]->id2ast->is_reg) { bool is_rand_reg = false; if (children[1]->type == AST_FCALL) { @@ -1452,7 +1452,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin is_rand_reg = true; } if (!is_rand_reg) - log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str.c_str(), loc_string().c_str()); + log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str, loc_string()); } children[0]->was_checked = true; } @@ -1915,7 +1915,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (current_scope.at(modname)->type != AST_CELL) input_error("Defparam argument `%s . %s` does not match a cell!\n", - RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str()); + RTLIL::unescape_id(modname), RTLIL::unescape_id(paramname)); auto paraset = std::make_unique(location, AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : nullptr); paraset->str = paramname; @@ -2756,19 +2756,24 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin newNode = std::make_unique(location, AST_GENBLOCK); int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1; + if (this->children.at(1)->type == AST_PRIMITIVE) { + // Move the range to the AST_PRIMITIVE node and replace this with the AST_PRIMITIVE node handled below + newNode = std::move(this->children.at(1)); + newNode->range_left = this->children.at(0)->range_left; + newNode->range_right = this->children.at(0)->range_right; + newNode->range_valid = true; + goto apply_newNode; + } + for (int i = 0; i < num; i++) { int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i; auto new_cell_owned = children.at(1)->clone(); auto* new_cell = new_cell_owned.get(); newNode->children.push_back(std::move(new_cell_owned)); new_cell->str += stringf("[%d]", idx); - if (new_cell->type == AST_PRIMITIVE) { - input_error("Cell arrays of primitives are currently not supported.\n"); - } else { - this->dumpAst(NULL, " "); - log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); - new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str); - } + + log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); + new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str); } goto apply_newNode; @@ -2789,6 +2794,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } children.clear(); + // TODO handle bit-widths of primitives and support cell arrays for more primitives + + if (range_valid && str != "tran") + input_error("Cell arrays of primitives are currently not supported.\n"); + if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1") { if (children_list.size() != 3) @@ -2817,7 +2827,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin fixup_hierarchy_flags(); did_something = true; } - else if (str == "buf" || str == "not") + else if (str == "buf" || str == "not" || str == "tran") { auto& input = children_list.back(); if (str == "not") @@ -3394,11 +3404,11 @@ skip_dynamic_range_lvalue_expansion:; if (GetSize(children) != 1 && GetSize(children) != 2) input_error("System function %s got %d arguments, expected 1 or 2.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); if (!current_always_clocked) input_error("System function %s is only allowed in clocked blocks.\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); if (GetSize(children) == 2) { @@ -3469,11 +3479,11 @@ skip_dynamic_range_lvalue_expansion:; { if (GetSize(children) != 1) input_error("System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); if (!current_always_clocked) input_error("System function %s is only allowed in clocked blocks.\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); auto present = children.at(0)->clone(); auto past = clone(); @@ -3511,7 +3521,7 @@ skip_dynamic_range_lvalue_expansion:; { if (children.size() != 1) input_error("System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); auto buf = children[0]->clone(); while (buf->simplify(true, stage, width_hint, sign_hint)) { } @@ -3538,11 +3548,11 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$dimensions" || str == "\\$unpacked_dimensions" || str == "\\$bits") { if (children.size() != 1) input_error("System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); } else { if (children.size() != 1 && children.size() != 2) input_error("System function %s got %d arguments, expected 1 or 2.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); if (children.size() == 2) { auto buf = children[1]->clone(); // Evaluate constant expression @@ -3634,18 +3644,18 @@ skip_dynamic_range_lvalue_expansion:; if (func_with_two_arguments) { if (children.size() != 2) input_error("System function %s got %d arguments, expected 2.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); } else { if (children.size() != 1) input_error("System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); } if (children.size() >= 1) { while (children[0]->simplify(true, stage, width_hint, sign_hint)) { } if (!children[0]->isConst()) input_error("Failed to evaluate system function `%s' with non-constant argument.\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[0]->detectSignWidth(child_width_hint, child_sign_hint); @@ -3656,7 +3666,7 @@ skip_dynamic_range_lvalue_expansion:; while (children[1]->simplify(true, stage, width_hint, sign_hint)) { } if (!children[1]->isConst()) input_error("Failed to evaluate system function `%s' with non-constant argument.\n", - RTLIL::unescape_id(str).c_str()); + RTLIL::unescape_id(str)); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[1]->detectSignWidth(child_width_hint, child_sign_hint); @@ -3703,7 +3713,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$countbits") { if (children.size() < 2) input_error("System function %s got %d arguments, expected at least 2.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); std::vector control_bits; @@ -3760,7 +3770,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") { if (children.size() != 1) input_error("System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); auto countbits = clone(); countbits->str = "\\$countbits"; @@ -3834,7 +3844,7 @@ skip_dynamic_range_lvalue_expansion:; { if (GetSize(children) < 2 || GetSize(children) > 4) input_error("System function %s got %d arguments, expected 2-4.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); + RTLIL::unescape_id(str), int(children.size())); auto node_filename = children[0]->clone(); while (node_filename->simplify(true, stage, width_hint, sign_hint)) { } @@ -4366,7 +4376,7 @@ replace_fcall_later:; log_assert(a.size() == b.size()); for (auto i = 0; i < a.size(); i++) if (a[i] != b[i]) - a.bits()[i] = RTLIL::State::Sx; + a.set(i, RTLIL::State::Sx); newNode = mkconst_bits(location, a.to_bits(), sign_hint); } else if (children[1]->isConst() && children[2]->isConst()) { newNode = std::make_unique(location, AST_REALVALUE); @@ -5368,8 +5378,11 @@ bool AstNode::replace_variables(std::map &varia offset -= variables.at(str).offset; if (variables.at(str).range_swapped) offset = -offset; - std::vector &var_bits = variables.at(str).val.bits(); - std::vector new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width); + const RTLIL::Const &val = variables.at(str).val; + std::vector new_bits; + new_bits.reserve(width); + for (int i = 0; i < width; i++) + new_bits.push_back(val[offset+i]); auto newNode = mkconst_bits(location, new_bits, variables.at(str).is_signed); newNode->cloneInto(*this); return true; @@ -5513,7 +5526,7 @@ std::unique_ptr AstNode::eval_const_function(AstNode *fcall, bool must_ int index = i + offset - v.offset; if (v.range_swapped) index = -index; - v.val.bits().at(index) = r.at(i); + v.val.set(index, r.at(i)); } } diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 7bb7224c5..5d6b83618 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -149,7 +149,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool if (buffer[0] == '.') { if (lutptr) { - for (auto &bit : lutptr->bits()) + for (auto bit : *lutptr) if (bit == RTLIL::State::Sx) bit = lut_default_state; lutptr = NULL; @@ -321,9 +321,10 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool const_v = Const(str); } else { int n = strlen(v); - const_v.bits().resize(n); + Const::Builder const_v_builder(n); for (int i = 0; i < n; i++) - const_v.bits()[i] = v[n-i-1] != '0' ? State::S1 : State::S0; + const_v_builder.push_back(v[n-i-1] != '0' ? State::S1 : State::S0); + const_v = const_v_builder.build(); } if (!strcmp(cmd, ".attr")) { if (obj_attributes == nullptr) { @@ -563,21 +564,23 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool log_assert(sopcell->parameters[ID::WIDTH].as_int() == input_len); sopcell->parameters[ID::DEPTH] = sopcell->parameters[ID::DEPTH].as_int() + 1; + Const::Builder table_bits_builder(input_len * 2); for (int i = 0; i < input_len; i++) switch (input[i]) { case '0': - sopcell->parameters[ID::TABLE].bits().push_back(State::S1); - sopcell->parameters[ID::TABLE].bits().push_back(State::S0); + table_bits_builder.push_back(State::S1); + table_bits_builder.push_back(State::S0); break; case '1': - sopcell->parameters[ID::TABLE].bits().push_back(State::S0); - sopcell->parameters[ID::TABLE].bits().push_back(State::S1); + table_bits_builder.push_back(State::S0); + table_bits_builder.push_back(State::S1); break; default: - sopcell->parameters[ID::TABLE].bits().push_back(State::S0); - sopcell->parameters[ID::TABLE].bits().push_back(State::S0); + table_bits_builder.push_back(State::S0); + table_bits_builder.push_back(State::S0); break; } + sopcell->parameters[ID::TABLE].append(table_bits_builder.build()); if (sopmode == -1) { sopmode = (*output == '1'); @@ -605,7 +608,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool goto try_next_value; } } - lutptr->bits().at(i) = !strcmp(output, "0") ? RTLIL::State::S0 : RTLIL::State::S1; + lutptr->set(i, !strcmp(output, "0") ? RTLIL::State::S0 : RTLIL::State::S1); try_next_value:; } diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index f2faa669b..743ac5d9e 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -258,7 +258,7 @@ Const json_parse_attr_param_value(JsonNode *node) } } else if (node->type == 'N') { - value = Const(node->data_number, 32); + value = Const(node->data_number); if (node->data_number < 0) value.flags |= RTLIL::CONST_FLAG_SIGNED; } else diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 72ad8b2b7..80553347c 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -537,7 +537,7 @@ struct LibertyFrontend : public Frontend { if (flag_wb && flag_lib) log_error("-wb and -lib cannot be specified together!\n"); - log_header(design, "Executing Liberty frontend: %s\n", filename.c_str()); + log_header(design, "Executing Liberty frontend: %s\n", filename); LibertyParser parser(*f, filename); int cell_count = 0; diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index df64ecd2f..625b2c0e8 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -91,9 +91,9 @@ struct RpcServer { std::string error; Json json_response = Json::parse(response, error); if (json_response.is_null()) - log_cmd_error("parsing JSON failed: %s\n", error.c_str()); + log_cmd_error("parsing JSON failed: %s\n", error); if (json_response["error"].is_string()) - log_cmd_error("RPC frontend returned an error: %s\n", json_response["error"].string_value().c_str()); + log_cmd_error("RPC frontend returned an error: %s\n", json_response["error"].string_value()); return json_response; } @@ -111,7 +111,7 @@ struct RpcServer { } } else is_valid = false; if (!is_valid) - log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump().c_str()); + log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump()); return modules; } @@ -149,7 +149,7 @@ struct RpcServer { source = response["source"].string_value(); else is_valid = false; if (!is_valid) - log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump().c_str()); + log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump()); return std::make_pair(frontend, source); } }; @@ -163,7 +163,7 @@ struct RpcModule : RTLIL::Module { stripped_name = stripped_name.substr(9); log_assert(stripped_name[0] == '\\'); - log_header(design, "Executing RPC frontend `%s' for module `%s'.\n", server->name.c_str(), stripped_name.c_str()); + log_header(design, "Executing RPC frontend `%s' for module `%s'.\n", server->name, stripped_name); std::string parameter_info; for (auto ¶m : parameters) { @@ -202,7 +202,7 @@ struct RpcModule : RTLIL::Module { } } if (!found_derived_top) - log_cmd_error("RPC frontend did not return requested module `%s`!\n", stripped_name.c_str()); + log_cmd_error("RPC frontend did not return requested module `%s`!\n", stripped_name); for (auto module : derived_design->modules()) for (auto cell : module->cells()) @@ -256,7 +256,7 @@ struct HandleRpcServer : RpcServer { do { DWORD data_written; if (!WriteFile(hsend, &data[offset], data.length() - offset, &data_written, /*lpOverlapped=*/NULL)) - log_cmd_error("WriteFile failed: %s\n", get_last_error_str().c_str()); + log_cmd_error("WriteFile failed: %s\n", get_last_error_str()); offset += data_written; } while(offset < (ssize_t)data.length()); } @@ -268,7 +268,7 @@ struct HandleRpcServer : RpcServer { data.resize(data.length() + 1024); DWORD data_read; if (!ReadFile(hrecv, &data[offset], data.length() - offset, &data_read, /*lpOverlapped=*/NULL)) - log_cmd_error("ReadFile failed: %s\n", get_last_error_str().c_str()); + log_cmd_error("ReadFile failed: %s\n", get_last_error_str()); offset += data_read; data.resize(offset); size_t term_pos = data.find('\n', offset); diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index fc7615364..2b8d7b7ab 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -455,16 +455,17 @@ constant: } while ((int)bits.size() > width) bits.pop_back(); - $$ = new RTLIL::Const; - for (auto it = bits.begin(); it != bits.end(); it++) - $$->bits().push_back(*it); + RTLIL::Const::Builder builder(bits.size()); + for (RTLIL::State bit : bits) + builder.push_back(bit); + $$ = new RTLIL::Const(builder.build()); if (is_signed) { $$->flags |= RTLIL::CONST_FLAG_SIGNED; } free($1); } | TOK_INT { - $$ = new RTLIL::Const($1, 32); + $$ = new RTLIL::Const($1); } | TOK_STRING { $$ = new RTLIL::Const($1); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 21cb838c6..0b2c9642d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -154,7 +154,7 @@ void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefil #endif } else { if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR) - log_warning_noprefix("%s%s\n", message_prefix.c_str(), message.c_str()); + log_warning_noprefix("%s%s\n", message_prefix, message); else log("%s%s\n", message_prefix, message); } @@ -284,13 +284,13 @@ static const RTLIL::Const extract_vhdl_bit_vector(std::string &val, std::string static const RTLIL::Const extract_vhdl_integer(std::string &val) { char *end; - return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10), 32); + return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10)); } static const RTLIL::Const extract_vhdl_char(std::string &val) { if (val.size()==3 && val[0]=='\"' && val.back()=='\"') - return RTLIL::Const((int)val[1], 32); + return RTLIL::Const((int)val[1]); log_error("Error parsing VHDL character.\n"); } @@ -328,7 +328,7 @@ static const RTLIL::Const extract_vhdl_const(const char *value, bool output_sig } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && ((decimal = std::strtol(value, &end, 10)), !end[0])) { is_signed = output_signed; - c = RTLIL::Const((int)decimal, 32); + c = RTLIL::Const((int)decimal); } else if (val == "false") { c = RTLIL::Const::from_string("0"); } else if (val == "true") { @@ -361,7 +361,7 @@ static const RTLIL::Const extract_verilog_const(const char *value, bool allow_s } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && ((decimal = std::strtol(value, &end, 10)), !end[0])) { is_signed = output_signed; - c = RTLIL::Const((int)decimal, 32); + c = RTLIL::Const((int)decimal); } else if (allow_string) { c = RTLIL::Const(val); } else { @@ -1541,7 +1541,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (design->has(module_name)) { if (!nl->IsOperator() && !is_blackbox(nl)) - log_cmd_error("Re-definition of module `%s'.\n", netlist_name.c_str()); + log_cmd_error("Re-definition of module `%s'.\n", netlist_name); return; } @@ -4052,7 +4052,7 @@ struct VerificPass : public Pass { add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_87)) - log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename); set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; @@ -4077,7 +4077,7 @@ struct VerificPass : public Pass { add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_93)) - log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename); set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; @@ -4102,7 +4102,7 @@ struct VerificPass : public Pass { add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2K)) - log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename); set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; @@ -4127,7 +4127,7 @@ struct VerificPass : public Pass { add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2019)) - log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename); set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; @@ -4152,7 +4152,7 @@ struct VerificPass : public Pass { add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2008)) - log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename); set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; @@ -4166,7 +4166,7 @@ struct VerificPass : public Pass { while (argidx < GetSize(args)) { std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!edif.Read(filename.c_str())) - log_cmd_error("Reading `%s' in EDIF mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in EDIF mode failed.\n", filename); } goto check_error; } @@ -4189,7 +4189,7 @@ struct VerificPass : public Pass { while (argidx < GetSize(args)) { std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!synlib_file::Read(filename.c_str(), is_work_set ? work.c_str() : nullptr)) - log_cmd_error("Reading `%s' in LIBERTY mode failed.\n", filename.c_str()); + log_cmd_error("Reading `%s' in LIBERTY mode failed.\n", filename); SynlibLibrary *lib = synlib_file::GetLastLibraryAnalyzed(); if (lib && flag_lib) { MapIter mi ; @@ -4326,7 +4326,7 @@ struct VerificPass : public Pass { unsigned new_insertion = parameters.Insert(key.c_str(), value.c_str(), 1 /* force_overwrite */); if (!new_insertion) - log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); + log_warning_noprefix("-chparam %s already specified: overwriting.\n", key); continue; } if (args[argidx] == "-V") { diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index cc5f07004..3908947eb 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1025,7 +1025,7 @@ struct VerificSvaImporter { if (!importer->mode_keep) log_error("%s", errmsg); - log_warning("%s", errmsg.c_str()); + log_warning("%s", errmsg); throw ParserErrorException(); } diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 9b197b356..573af336b 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -45,11 +45,11 @@ using namespace AST; using namespace VERILOG_FRONTEND; void ConstParser::log_maybe_loc_error(std::string msg) { - log_file_error(*loc.begin.filename, loc.begin.line, "%s", msg.c_str()); + log_file_error(*loc.begin.filename, loc.begin.line, "%s", msg); } void ConstParser::log_maybe_loc_warn(std::string msg) { - log_file_warning(*loc.begin.filename, loc.begin.line, "%s", msg.c_str()); + log_file_warning(*loc.begin.filename, loc.begin.line, "%s", msg); } // divide an arbitrary length decimal number by two and return the rest diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 8674758ab..1858edc97 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -741,7 +741,7 @@ read_define(const std::string &filename, defines_map.add(name, value, (state == 2) ? &args : nullptr); global_defines_cache.add(name, value, (state == 2) ? &args : nullptr); } else { - log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str()); + log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name); } } diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 231891271..2bdaf40ce 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -485,7 +485,7 @@ struct VerilogFrontend : public Frontend { extra_args(f, filename, args, argidx); - log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str()); + log_header(design, "Executing Verilog-2005 frontend: %s\n", filename); log("Parsing %s%s input from `%s' to AST representation.\n", parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str()); diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index c6d2ed992..62a7f7bbb 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -493,7 +493,7 @@ TIME_SCALE_SUFFIX [munpf]?s \"{3}(\"{0,2}([^\\"]|\\.|\\\n))*\"{3} { return process_str(yytext + 3, yyleng - 6, true, out_loc); } -and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { +and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1|tran { auto val = std::make_unique(YYText()); return parser::make_TOK_PRIMITIVE(std::move(val), out_loc); } diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 0e12e6dce..e2071436c 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -100,7 +100,7 @@ struct BitPatternPool bits_t sig2bits(RTLIL::SigSpec sig) { bits_t bits; - bits.bitdata = sig.as_const().bits(); + bits.bitdata = sig.as_const().to_bits(); for (auto &b : bits.bitdata) if (b > RTLIL::State::S1) b = RTLIL::State::Sa; diff --git a/kernel/calc.cc b/kernel/calc.cc index f08c97396..9b0885db9 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -33,10 +33,7 @@ static void extend_u0(RTLIL::Const &arg, int width, bool is_signed) if (arg.size() > 0 && is_signed) padding = arg.back(); - while (GetSize(arg) < width) - arg.bits().push_back(padding); - - arg.bits().resize(width); + arg.resize(width, padding); } static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos) @@ -79,12 +76,12 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b { mag--; for (auto i = 0; i < result_len; i++) - result.bits()[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1; + result.set(i, mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1); } else { for (auto i = 0; i < result_len; i++) - result.bits()[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0; + result.set(i, mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0); } } @@ -140,11 +137,11 @@ RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, boo RTLIL::Const result(RTLIL::State::Sx, result_len); for (auto i = 0; i < result_len; i++) { if (i >= GetSize(arg1_ext)) - result.bits()[i] = RTLIL::State::S0; - else if (arg1_ext.bits()[i] == RTLIL::State::S0) - result.bits()[i] = RTLIL::State::S1; - else if (arg1_ext.bits()[i] == RTLIL::State::S1) - result.bits()[i] = RTLIL::State::S0; + result.set(i, RTLIL::State::S0); + else if (arg1_ext[i] == RTLIL::State::S0) + result.set(i, RTLIL::State::S1); + else if (arg1_ext[i] == RTLIL::State::S1) + result.set(i, RTLIL::State::S0); } return result; @@ -161,9 +158,9 @@ static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL: RTLIL::Const result(RTLIL::State::Sx, result_len); for (auto i = 0; i < result_len; i++) { - RTLIL::State a = i < GetSize(arg1) ? arg1.bits()[i] : RTLIL::State::S0; - RTLIL::State b = i < GetSize(arg2) ? arg2.bits()[i] : RTLIL::State::S0; - result.bits()[i] = logic_func(a, b); + RTLIL::State a = i < GetSize(arg1) ? arg1[i] : RTLIL::State::S0; + RTLIL::State b = i < GetSize(arg2) ? arg2[i] : RTLIL::State::S0; + result.set(i, logic_func(a, b)); } return result; @@ -197,8 +194,8 @@ static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*log temp = logic_func(temp, arg1[i]); RTLIL::Const result(temp); - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -222,9 +219,9 @@ RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Con RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len); if (!buffer.empty()) { if (buffer.front() == RTLIL::State::S0) - buffer.bits().front() = RTLIL::State::S1; + buffer.set(0, RTLIL::State::S1); else if (buffer.front() == RTLIL::State::S1) - buffer.bits().front() = RTLIL::State::S0; + buffer.set(0, RTLIL::State::S0); } return buffer; } @@ -239,9 +236,8 @@ RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const int undef_bit_pos_a = -1; BigInteger a = const2big(arg1, signed1, undef_bit_pos_a); RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -254,9 +250,8 @@ RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; RTLIL::Const result(logic_and(bit_a, bit_b)); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -269,9 +264,8 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; RTLIL::Const result(logic_or(bit_a, bit_b)); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -295,11 +289,11 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co for (int i = 0; i < result_len; i++) { BigInteger pos = BigInteger(i) + offset; if (pos < 0) - result.bits()[i] = vacant_bits; + result.set(i, vacant_bits); else if (pos >= BigInteger(GetSize(arg1))) - result.bits()[i] = sign_ext ? arg1.back() : vacant_bits; + result.set(i, sign_ext ? arg1.back() : vacant_bits); else - result.bits()[i] = arg1[pos.toInt()]; + result.set(i, arg1[pos.toInt()]); } return result; @@ -346,9 +340,8 @@ RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, int undef_bit_pos = -1; bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos); RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -357,9 +350,8 @@ RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, int undef_bit_pos = -1; bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos); RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -383,7 +375,7 @@ RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, matched_status = RTLIL::State::Sx; } - result.bits().front() = matched_status; + result.set(0, matched_status); return result; } @@ -391,9 +383,9 @@ RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, { RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len); if (result.front() == RTLIL::State::S0) - result.bits().front() = RTLIL::State::S1; + result.set(0, RTLIL::State::S1); else if (result.front() == RTLIL::State::S1) - result.bits().front() = RTLIL::State::S0; + result.set(0, RTLIL::State::S0); return result; } @@ -412,7 +404,7 @@ RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2 return result; } - result.bits().front() = RTLIL::State::S1; + result.set(0, RTLIL::State::S1); return result; } @@ -420,9 +412,9 @@ RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2 { RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len); if (result.front() == RTLIL::State::S0) - result.bits().front() = RTLIL::State::S1; + result.set(0, RTLIL::State::S1); else if (result.front() == RTLIL::State::S1) - result.bits().front() = RTLIL::State::S0; + result.set(0, RTLIL::State::S0); return result; } @@ -431,9 +423,8 @@ RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, int undef_bit_pos = -1; bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos); RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -442,9 +433,8 @@ RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, int undef_bit_pos = -1; bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos); RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); - - while (GetSize(result) < result_len) - result.bits().push_back(RTLIL::State::S0); + if (GetSize(result) < result_len) + result.resize(result_len, RTLIL::State::S0); return result; } @@ -628,7 +618,7 @@ RTLIL::Const RTLIL::const_mux(const RTLIL::Const &arg1, const RTLIL::Const &arg2 RTLIL::Const ret = arg1; for (auto i = 0; i < ret.size(); i++) if (ret[i] != arg2[i]) - ret.bits()[i] = State::Sx; + ret.set(i, State::Sx); return ret; } @@ -703,7 +693,7 @@ RTLIL::Const RTLIL::const_bweqx(const RTLIL::Const &arg1, const RTLIL::Const &ar log_assert(arg2.size() == arg1.size()); RTLIL::Const result(RTLIL::State::S0, arg1.size()); for (auto i = 0; i < arg1.size(); i++) - result.bits()[i] = arg1[i] == arg2[i] ? State::S1 : State::S0; + result.set(i, arg1[i] == arg2[i] ? State::S1 : State::S0); return result; } @@ -715,7 +705,7 @@ RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &ar RTLIL::Const result(RTLIL::State::Sx, arg1.size()); for (auto i = 0; i < arg1.size(); i++) { if (arg3[i] != State::Sx || arg1[i] == arg2[i]) - result.bits()[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i]; + result.set(i, arg3[i] == State::S1 ? arg2[i] : arg1[i]); } return result; diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 8e52d0380..c39ced95a 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -447,7 +447,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { ff_op(this, cell); return true; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index f08a695e9..2c3535eac 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -111,6 +111,8 @@ struct CellTypes setup_type(ID($original_tag), {ID::A}, {ID::Y}); setup_type(ID($future_ff), {ID::A}, {ID::Y}); setup_type(ID($scopeinfo), {}, {}); + setup_type(ID($input_port), {}, {ID::Y}); + setup_type(ID($connect), {ID::A, ID::B}, {}); } void setup_internals_eval() @@ -320,6 +322,16 @@ struct CellTypes return it != cell_types.end() && it->second.inputs.count(port) != 0; } + RTLIL::PortDir cell_port_dir(RTLIL::IdString type, RTLIL::IdString port) const + { + auto it = cell_types.find(type); + if (it == cell_types.end()) + return RTLIL::PD_UNKNOWN; + bool is_input = it->second.inputs.count(port); + bool is_output = it->second.outputs.count(port); + return RTLIL::PortDir(is_input + is_output * 2); + } + bool cell_evaluable(const RTLIL::IdString &type) const { auto it = cell_types.find(type); @@ -328,7 +340,7 @@ struct CellTypes static RTLIL::Const eval_not(RTLIL::Const v) { - for (auto &bit : v.bits()) + for (auto bit : v) if (bit == State::S0) bit = State::S1; else if (bit == State::S1) bit = State::S0; return v; @@ -421,16 +433,14 @@ struct CellTypes static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr) { if (cell->type == ID($slice)) { - RTLIL::Const ret; int width = cell->parameters.at(ID::Y_WIDTH).as_int(); int offset = cell->parameters.at(ID::OFFSET).as_int(); - ret.bits().insert(ret.bits().end(), arg1.begin()+offset, arg1.begin()+offset+width); - return ret; + return arg1.extract(offset, width); } if (cell->type == ID($concat)) { RTLIL::Const ret = arg1; - ret.bits().insert(ret.bits().end(), arg2.begin(), arg2.end()); + ret.append(arg2); return ret; } diff --git a/kernel/consteval.h b/kernel/consteval.h index adcf86f8a..b13c7ea5c 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -115,7 +115,7 @@ struct ConstEval for (int i = 0; i < GetSize(coval); i++) { carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry); - coval.bits()[i] = carry ? State::S1 : State::S0; + coval.set(i, carry ? State::S1 : State::S0); } set(sig_co, coval); @@ -249,7 +249,7 @@ struct ConstEval for (int i = 0; i < GetSize(val_y); i++) if (val_y[i] == RTLIL::Sx) - val_x.bits()[i] = RTLIL::Sx; + val_x.set(i, RTLIL::Sx); set(sig_y, val_y); set(sig_x, val_x); diff --git a/kernel/cost.cc b/kernel/cost.cc index d58e05827..70feacd52 100644 --- a/kernel/cost.cc +++ b/kernel/cost.cc @@ -152,7 +152,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell) if (design_ && design_->module(cell->type) && cell->parameters.empty()) { log_debug("%s is a module, recurse\n", cell->name.c_str()); return get(design_->module(cell->type)); - } else if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + } else if (cell->is_builtin_ff()) { log_assert(cell->hasPort(ID::Q) && "Weird flip flop"); log_debug("%s is ff\n", cell->name.c_str()); return cell->getParam(ID::WIDTH).as_int(); diff --git a/kernel/drivertools.cc b/kernel/drivertools.cc index 6290f4470..90bfb0ee7 100644 --- a/kernel/drivertools.cc +++ b/kernel/drivertools.cc @@ -260,7 +260,7 @@ bool DriveChunkMultiple::try_append(DriveBitMultiple const &bit) switch (single.type()) { case DriveType::CONSTANT: { - single.constant().bits().push_back(constant); + single.constant().append(RTLIL::Const(constant)); } break; case DriveType::WIRE: { single.wire().width += 1; @@ -295,8 +295,7 @@ bool DriveChunkMultiple::try_append(DriveChunkMultiple const &chunk) switch (single.type()) { case DriveType::CONSTANT: { - auto &bits = single.constant().bits(); - bits.insert(bits.end(), constant.bits().begin(), constant.bits().end()); + single.constant().append(constant); } break; case DriveType::WIRE: { single.wire().width += width; @@ -349,7 +348,7 @@ bool DriveChunk::try_append(DriveBit const &bit) none_ += 1; return true; case DriveType::CONSTANT: - constant_.bits().push_back(bit.constant()); + constant_.append(RTLIL::Const(bit.constant())); return true; case DriveType::WIRE: return wire_.try_append(bit.wire()); @@ -375,7 +374,7 @@ bool DriveChunk::try_append(DriveChunk const &chunk) none_ += chunk.none_; return true; case DriveType::CONSTANT: - constant_.bits().insert(constant_.bits().end(), chunk.constant_.begin(), chunk.constant_.end()); + constant_.append(chunk.constant_); return true; case DriveType::WIRE: return wire_.try_append(chunk.wire()); diff --git a/kernel/ff.cc b/kernel/ff.cc index 499652465..218598149 100644 --- a/kernel/ff.cc +++ b/kernel/ff.cc @@ -287,6 +287,16 @@ FfData FfData::slice(const std::vector &bits) { res.pol_clr = pol_clr; res.pol_set = pol_set; res.attributes = attributes; + std::optional arst_bits; + if (has_arst) + arst_bits.emplace(bits.size()); + std::optional srst_bits; + if (has_srst) + srst_bits.emplace(bits.size()); + std::optional init_bits; + if (initvals) + init_bits.emplace(bits.size()); + for (int i : bits) { res.sig_q.append(sig_q[i]); if (has_clk || has_gclk) @@ -298,12 +308,19 @@ FfData FfData::slice(const std::vector &bits) { res.sig_set.append(sig_set[i]); } if (has_arst) - res.val_arst.bits().push_back(val_arst[i]); + arst_bits->push_back(val_arst[i]); if (has_srst) - res.val_srst.bits().push_back(val_srst[i]); + srst_bits->push_back(val_srst[i]); if (initvals) - res.val_init.bits().push_back(val_init[i]); + init_bits->push_back(val_init[i]); } + + if (has_arst) + res.val_arst = arst_bits->build(); + if (has_srst) + res.val_srst = srst_bits->build(); + if (initvals) + res.val_init = init_bits->build(); res.width = GetSize(res.sig_q); return res; } @@ -688,10 +705,10 @@ void FfData::flip_rst_bits(const pool &bits) { for (auto bit: bits) { if (has_arst) - val_arst.bits()[bit] = invert(val_arst[bit]); + val_arst.set(bit, invert(val_arst[bit])); if (has_srst) - val_srst.bits()[bit] = invert(val_srst[bit]); - val_init.bits()[bit] = invert(val_init[bit]); + val_srst.set(bit, invert(val_srst[bit])); + val_init.set(bit, invert(val_init[bit])); } } @@ -760,7 +777,7 @@ void FfData::flip_bits(const pool &bits) { Const mask = Const(State::S0, width); for (auto bit: bits) - mask.bits()[bit] = State::S1; + mask.set(bit, State::S1); if (has_clk || has_gclk) sig_d = module->Xor(NEW_ID4_SUFFIX("d"), sig_d, mask, false, attributes[ID::src].decode_string()); // SILIMATE: Improve the naming diff --git a/kernel/ffinit.h b/kernel/ffinit.h index 66c13b68f..920fba307 100644 --- a/kernel/ffinit.h +++ b/kernel/ffinit.h @@ -74,10 +74,10 @@ struct FfInitVals RTLIL::Const operator()(const RTLIL::SigSpec &sig) const { - RTLIL::Const res; + RTLIL::Const::Builder res_bits(GetSize(sig)); for (auto bit : sig) - res.bits().push_back((*this)(bit)); - return res; + res_bits.push_back((*this)(bit)); + return res_bits.build(); } void set_init(RTLIL::SigBit bit, RTLIL::State val) @@ -93,12 +93,12 @@ struct FfInitVals initbits[mbit] = std::make_pair(val,abit); auto it2 = abit.wire->attributes.find(ID::init); if (it2 != abit.wire->attributes.end()) { - it2->second.bits()[abit.offset] = val; + it2->second.set(abit.offset, val); if (it2->second.is_fully_undef()) abit.wire->attributes.erase(it2); } else if (val != State::Sx) { Const cval(State::Sx, GetSize(abit.wire)); - cval.bits()[abit.offset] = val; + cval.set(abit.offset, val); abit.wire->attributes[ID::init] = cval; } } diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc index 3b361c1c2..709549e4d 100644 --- a/kernel/ffmerge.cc +++ b/kernel/ffmerge.cc @@ -42,9 +42,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, poolcells()) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { if (cell->hasPort(ID::D)) { SigSpec d = (*sigmap)(cell->getPort(ID::D)); for (int i = 0; i < GetSize(d); i++) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 6e9f2924a..200e7e5ce 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -401,11 +401,11 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part = {}; } if (++i == fmt.size()) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1); } if (++arg == args.end()) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name.c_str(), fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name, fmtarg - args.begin() + 1); } part.sig = arg->sig; part.signed_ = arg->signed_; @@ -420,7 +420,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik } else break; } if (i == fmt.size()) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1); } bool has_leading_zero = false, has_width = false; @@ -465,15 +465,15 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik if (!has_width && !has_leading_zero) part.width = 20; } else { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name, fmt[i], fmtarg - args.begin() + 1); } } else { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name, fmt[i], fmtarg - args.begin() + 1); } break; } if (i == fmt.size()) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1); } if (part.padding == '\0') { @@ -486,7 +486,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik } if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS) - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1); if (part.base != 10) part.signed_ = false; diff --git a/kernel/functional.cc b/kernel/functional.cc index 75c9b580b..2a1bf598a 100644 --- a/kernel/functional.cc +++ b/kernel/functional.cc @@ -605,7 +605,7 @@ private: } Node node = handle_memory(mem); factory.update_pending(cell_outputs.at({cell, ID(RD_DATA)}), node); - } else if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + } else if (cell->is_builtin_ff()) { FfData ff(&ff_initvals, cell); if (!ff.has_gclk) log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. " diff --git a/kernel/gzip.cc b/kernel/gzip.cc index d19c06579..433c35902 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -103,11 +103,11 @@ gzip_istream::ibuf::~ibuf() { // Never returns nullptr or failed state istream* std::istream* uncompressed(const std::string filename, std::ios_base::openmode mode) { if (!check_file_exists(filename)) - log_cmd_error("File `%s' not found or is a directory\n", filename.c_str()); + log_cmd_error("File `%s' not found or is a directory\n", filename); std::ifstream* f = new std::ifstream(); f->open(filename, mode); if (f->fail()) - log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + log_cmd_error("Can't open input file `%s' for reading: %s\n", filename, strerror(errno)); // Check for gzip magic unsigned char magic[3]; int n = 0; @@ -131,7 +131,7 @@ std::istream* uncompressed(const std::string filename, std::ios_base::openmode m log_assert(ok && "Failed to open gzipped file.\n"); return s; #else - log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); + log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename); #endif // YOSYS_ENABLE_ZLIB } else { f->clear(); diff --git a/kernel/hashlib.h b/kernel/hashlib.h index c96de3658..9d0e28c3a 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -169,8 +169,17 @@ struct hash_ops { } else if constexpr (std::is_pointer_v) { return hash_ops::hash_into((uintptr_t) a, h); } else if constexpr (std::is_same_v) { - for (auto c : a) - h.hash32(c); + int size = a.size(); + int i = 0; + while (i + 8 < size) { + uint64_t v; + memcpy(&v, a.data() + i, 8); + h.hash64(v); + i += 8; + } + uint64_t v = 0; + memcpy(&v, a.data() + i, size - i); + h.hash64(v); return h; } else { return a.hash_into(h); diff --git a/kernel/log.cc b/kernel/log.cc index efdface80..0085980b1 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -68,8 +68,6 @@ int log_debug_suppressed = 0; vector header_count; vector log_id_cache; -vector string_buf; -int string_buf_index = -1; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; @@ -189,7 +187,7 @@ static void logv_string(std::string_view format, std::string str) { if (!linebuffer.empty() && linebuffer.back() == '\n') { for (auto &re : log_warn_regexes) if (std::regex_search(linebuffer, re)) - log_warning("Found log message matching -W regex:\n%s", str.c_str()); + log_warning("Found log message matching -W regex:\n%s", str); for (auto &[_, item] : log_expect_log) if (std::regex_search(linebuffer, item.pattern)) @@ -447,8 +445,6 @@ void log_pop() { header_count.pop_back(); log_id_cache_clear(); - string_buf.clear(); - string_buf_index = -1; log_flush(); } @@ -554,8 +550,6 @@ void log_reset_stack() while (header_count.size() > 1) header_count.pop_back(); log_id_cache_clear(); - string_buf.clear(); - string_buf_index = -1; log_flush(); } @@ -580,38 +574,19 @@ void log_dump_val_worker(RTLIL::State v) { log("%s", log_signal(v)); } -const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) +std::string log_signal(const RTLIL::SigSpec &sig, bool autoint) { std::stringstream buf; RTLIL_BACKEND::dump_sigspec(buf, sig, autoint); - - if (string_buf.size() < 100) { - string_buf.push_back(buf.str()); - return string_buf.back().c_str(); - } else { - if (++string_buf_index == 100) - string_buf_index = 0; - string_buf[string_buf_index] = buf.str(); - return string_buf[string_buf_index].c_str(); - } + return buf.str(); } -const char *log_const(const RTLIL::Const &value, bool autoint) +std::string log_const(const RTLIL::Const &value, bool autoint) { if ((value.flags & RTLIL::CONST_FLAG_STRING) == 0) return log_signal(value, autoint); - std::string str = "\"" + value.decode_string() + "\""; - - if (string_buf.size() < 100) { - string_buf.push_back(str); - return string_buf.back().c_str(); - } else { - if (++string_buf_index == 100) - string_buf_index = 0; - string_buf[string_buf_index] = str; - return string_buf[string_buf_index].c_str(); - } + return "\"" + value.decode_string() + "\""; } const char *log_id(const RTLIL::IdString &str) @@ -729,7 +704,7 @@ dict> get_coverage_data() for (auto &it : extra_coverage_data) { if (coverage_data.count(it.first)) - log_warning("found duplicate coverage id \"%s\".\n", it.first.c_str()); + log_warning("found duplicate coverage id \"%s\".\n", it.first); coverage_data[it.first].first = it.second.first; coverage_data[it.first].second += it.second.second; } diff --git a/kernel/log.h b/kernel/log.h index f360ab149..cbb00191b 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -153,6 +153,11 @@ inline void log_warning(FmtString...> fmt, const Args &... ar { log_formatted_warning("Warning: ", fmt.format(args...)); } + +inline void log_formatted_warning_noprefix(std::string str) +{ + log_formatted_warning("", str); +} template inline void log_warning_noprefix(FmtString...> fmt, const Args &... args) { @@ -253,8 +258,8 @@ extern dict log_expect_log, log_expect_warning, lo extern dict log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error; void log_check_expected(); -const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); -const char *log_const(const RTLIL::Const &value, bool autoint = true); +std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true); +std::string log_const(const RTLIL::Const &value, bool autoint = true); const char *log_id(const RTLIL::IdString &id); template static inline const char *log_id(T *obj, const char *nullstr = nullptr) { diff --git a/kernel/macc.h b/kernel/macc.h index ceda1dceb..b4c58d20b 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -262,7 +262,7 @@ struct Macc bool eval(RTLIL::Const &result) const { - for (auto &bit : result.bits()) + for (auto bit : result) bit = State::S0; for (auto &port : terms) diff --git a/kernel/mem.cc b/kernel/mem.cc index f614a1f81..02d12dea4 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -131,9 +131,6 @@ void Mem::emit() { cell->parameters[ID::WIDTH] = Const(width); cell->parameters[ID::OFFSET] = Const(start_offset); cell->parameters[ID::SIZE] = Const(size); - Const rd_wide_continuation, rd_clk_enable, rd_clk_polarity, rd_transparency_mask, rd_collision_x_mask; - Const wr_wide_continuation, wr_clk_enable, wr_clk_polarity, wr_priority_mask; - Const rd_ce_over_srst, rd_arst_value, rd_srst_value, rd_init_value; SigSpec rd_clk, rd_en, rd_addr, rd_data; SigSpec wr_clk, wr_en, wr_addr, wr_data; SigSpec rd_arst, rd_srst; @@ -147,6 +144,15 @@ void Mem::emit() { for (int i = 0; i < GetSize(wr_ports); i++) for (int j = 0; j < (1 << wr_ports[i].wide_log2); j++) wr_port_xlat.push_back(i); + Const::Builder rd_wide_continuation_builder; + Const::Builder rd_clk_enable_builder; + Const::Builder rd_clk_polarity_builder; + Const::Builder rd_transparency_mask_builder; + Const::Builder rd_collision_x_mask_builder; + Const::Builder rd_ce_over_srst_builder; + Const::Builder rd_arst_value_builder; + Const::Builder rd_srst_value_builder; + Const::Builder rd_init_value_builder; for (auto &port : rd_ports) { for (auto attr: port.attributes) if (!cell->has_attribute(attr.first)) @@ -157,10 +163,10 @@ void Mem::emit() { } for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - rd_wide_continuation.bits().push_back(State(sub != 0)); - rd_clk_enable.bits().push_back(State(port.clk_enable)); - rd_clk_polarity.bits().push_back(State(port.clk_polarity)); - rd_ce_over_srst.bits().push_back(State(port.ce_over_srst)); + rd_wide_continuation_builder.push_back(State(sub != 0)); + rd_clk_enable_builder.push_back(State(port.clk_enable)); + rd_clk_polarity_builder.push_back(State(port.clk_polarity)); + rd_ce_over_srst_builder.push_back(State(port.ce_over_srst)); rd_clk.append(port.clk); rd_arst.append(port.arst); rd_srst.append(port.srst); @@ -170,18 +176,27 @@ void Mem::emit() { rd_addr.append(addr); log_assert(GetSize(addr) == abits); for (auto idx : wr_port_xlat) { - rd_transparency_mask.bits().push_back(State(bool(port.transparency_mask[idx]))); - rd_collision_x_mask.bits().push_back(State(bool(port.collision_x_mask[idx]))); + rd_transparency_mask_builder.push_back(State(bool(port.transparency_mask[idx]))); + rd_collision_x_mask_builder.push_back(State(bool(port.collision_x_mask[idx]))); } } rd_data.append(port.data); for (auto bit : port.arst_value) - rd_arst_value.bits().push_back(bit); + rd_arst_value_builder.push_back(bit); for (auto bit : port.srst_value) - rd_srst_value.bits().push_back(bit); + rd_srst_value_builder.push_back(bit); for (auto bit : port.init_value) - rd_init_value.bits().push_back(bit); + rd_init_value_builder.push_back(bit); } + Const rd_wide_continuation = rd_wide_continuation_builder.build(); + Const rd_clk_enable = rd_clk_enable_builder.build(); + Const rd_clk_polarity = rd_clk_polarity_builder.build(); + Const rd_transparency_mask = rd_transparency_mask_builder.build(); + Const rd_collision_x_mask = rd_collision_x_mask_builder.build(); + Const rd_ce_over_srst = rd_ce_over_srst_builder.build(); + Const rd_arst_value = rd_arst_value_builder.build(); + Const rd_srst_value = rd_srst_value_builder.build(); + Const rd_init_value = rd_init_value_builder.build(); if (rd_ports.empty()) { rd_wide_continuation = State::S0; rd_clk_enable = State::S0; @@ -212,6 +227,10 @@ void Mem::emit() { cell->setPort(ID::RD_SRST, rd_srst); cell->setPort(ID::RD_ADDR, rd_addr); cell->setPort(ID::RD_DATA, rd_data); + Const::Builder wr_wide_continuation_builder; + Const::Builder wr_clk_enable_builder; + Const::Builder wr_clk_polarity_builder; + Const::Builder wr_priority_mask_builder; for (auto &port : wr_ports) { for (auto attr: port.attributes) if (!cell->has_attribute(attr.first)) @@ -222,12 +241,12 @@ void Mem::emit() { } for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - wr_wide_continuation.bits().push_back(State(sub != 0)); - wr_clk_enable.bits().push_back(State(port.clk_enable)); - wr_clk_polarity.bits().push_back(State(port.clk_polarity)); + wr_wide_continuation_builder.push_back(State(sub != 0)); + wr_clk_enable_builder.push_back(State(port.clk_enable)); + wr_clk_polarity_builder.push_back(State(port.clk_polarity)); wr_clk.append(port.clk); for (auto idx : wr_port_xlat) - wr_priority_mask.bits().push_back(State(bool(port.priority_mask[idx]))); + wr_priority_mask_builder.push_back(State(bool(port.priority_mask[idx]))); SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); wr_addr.append(addr); @@ -236,6 +255,10 @@ void Mem::emit() { wr_en.append(port.en); wr_data.append(port.data); } + Const wr_wide_continuation = wr_wide_continuation_builder.build(); + Const wr_clk_enable = wr_clk_enable_builder.build(); + Const wr_clk_polarity = wr_clk_polarity_builder.build(); + Const wr_priority_mask = wr_priority_mask_builder.build(); if (wr_ports.empty()) { wr_wide_continuation = State::S0; wr_clk_enable = State::S0; @@ -414,7 +437,7 @@ void Mem::coalesce_inits() { if (!init.en.is_fully_ones()) { for (int i = 0; i < GetSize(init.data); i++) if (init.en[i % width] != State::S1) - init.data.bits()[i] = State::Sx; + init.data.set(i, State::Sx); init.en = Const(State::S1, width); } continue; @@ -427,7 +450,7 @@ void Mem::coalesce_inits() { log_assert(offset + GetSize(init.data) <= GetSize(cdata)); for (int i = 0; i < GetSize(init.data); i++) if (init.en[i % width] == State::S1) - cdata.bits()[i+offset] = init.data[i]; + cdata.set(i+offset, init.data[i]); init.removed = true; } MemInit new_init; @@ -446,7 +469,7 @@ Const Mem::get_init_data() const { int offset = (init.addr.as_int() - start_offset) * width; for (int i = 0; i < GetSize(init.data); i++) if (0 <= i+offset && i+offset < GetSize(init_data) && init.en[i % width] == State::S1) - init_data.bits()[i+offset] = init.data[i]; + init_data.set(i+offset, init.data[i]); } return init_data; } @@ -1700,7 +1723,7 @@ MemContents::MemContents(Mem *mem) : RTLIL::Const previous = (*this)[addr + i]; for(int j = 0; j < _data_width; j++) if(init.en[j] != State::S1) - data.bits()[_data_width * i + j] = previous[j]; + data.set(_data_width * i + j, previous[j]); } insert_concatenated(init.addr.as_int(), data); } @@ -1846,7 +1869,7 @@ std::map::iterator MemContents::_reserve_rang // we have two different ranges touching at either end, we need to merge them auto upper_end = _range_end(upper_it); // make range bigger (maybe reserve here instead of resize?) - lower_it->second.bits().resize(_range_offset(lower_it, upper_end), State::Sx); + lower_it->second.resize(_range_offset(lower_it, upper_end), State::Sx); // copy only the data beyond our range std::copy(_range_data(upper_it, end_addr), _range_data(upper_it, upper_end), _range_data(lower_it, end_addr)); // keep lower_it, but delete upper_it @@ -1854,16 +1877,16 @@ std::map::iterator MemContents::_reserve_rang return lower_it; } else if (lower_touch) { // we have a range to the left, just make it bigger and delete any other that may exist. - lower_it->second.bits().resize(_range_offset(lower_it, end_addr), State::Sx); + lower_it->second.resize(_range_offset(lower_it, end_addr), State::Sx); // keep lower_it and upper_it _values.erase(std::next(lower_it), upper_it); return lower_it; } else if (upper_touch) { // we have a range to the right, we need to expand it // since we need to erase and reinsert to a new address, steal the data - RTLIL::Const data = std::move(upper_it->second); // note that begin_addr is not in upper_it, otherwise the whole range covered check would have tripped - data.bits().insert(data.bits().begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx); + RTLIL::Const data(State::Sx, (_range_begin(upper_it) - begin_addr) * _data_width); + data.append(std::move(upper_it->second)); // delete lower_it and upper_it, then reinsert _values.erase(lower_it, std::next(upper_it)); return _values.emplace(begin_addr, std::move(data)).first; @@ -1886,7 +1909,7 @@ void MemContents::insert_concatenated(addr_t addr, RTLIL::Const const &values) { std::fill(to_begin + values.size(), to_begin + words * _data_width, State::S0); } -std::vector::iterator MemContents::_range_write(std::vector::iterator it, RTLIL::Const const &word) { +RTLIL::Const::iterator MemContents::_range_write(RTLIL::Const::iterator it, RTLIL::Const const &word) { auto from_end = word.size() <= _data_width ? word.end() : word.begin() + _data_width; auto to_end = std::copy(word.begin(), from_end, it); auto it_next = std::next(it, _data_width); diff --git a/kernel/mem.h b/kernel/mem.h index a06f44bd8..b35ea52c7 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -255,11 +255,13 @@ private: // return the offset the addr would have in the range at `it` size_t _range_offset(std::map::iterator it, addr_t addr) const { return (addr - it->first) * _data_width; } // assuming _range_contains(it, addr), return an iterator pointing to the data at addr - std::vector::iterator _range_data(std::map::iterator it, addr_t addr) { return it->second.bits().begin() + _range_offset(it, addr); } + RTLIL::Const::iterator _range_data(std::map::iterator it, addr_t addr) { + return RTLIL::Const::iterator(it->second, _range_offset(it, addr)); + } // internal version of reserve_range that returns an iterator to the range std::map::iterator _reserve_range(addr_t begin_addr, addr_t end_addr); // write a single word at addr, return iterator to next word - std::vector::iterator _range_write(std::vector::iterator it, RTLIL::Const const &data); + RTLIL::Const::iterator _range_write(RTLIL::Const::iterator it, RTLIL::Const const &data); public: class range { int _data_width; diff --git a/kernel/register.cc b/kernel/register.cc index 4afd7ada3..bd12dcc38 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -199,7 +199,7 @@ void Pass::call(RTLIL::Design *design, std::string command) while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' || cmd_buf.back() == '\r' || cmd_buf.back() == '\n')) cmd_buf.resize(cmd_buf.size()-1); - log_header(design, "Shell command: %s\n", cmd_buf.c_str()); + log_header(design, "Shell command: %s\n", cmd_buf); int retCode = run_command(cmd_buf); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); @@ -262,7 +262,7 @@ void Pass::call(RTLIL::Design *design, std::vector args) } if (pass_register.count(args[0]) == 0) - log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str()); + log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0]); if (pass_register[args[0]]->experimental_flag) log_experimental(args[0]); @@ -521,7 +521,7 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string if (args.size() == 0) return; if (frontend_register.count(args[0]) == 0) - log_cmd_error("No such frontend: %s\n", args[0].c_str()); + log_cmd_error("No such frontend: %s\n", args[0]); if (f != NULL) { auto state = frontend_register[args[0]]->pre_execute(); @@ -596,7 +596,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vectoropen(filename)) { delete gf; - log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename, strerror(errno)); } yosys_output_files.insert(filename); f = gf; @@ -609,7 +609,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vectorfail()) { delete ff; - log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename, strerror(errno)); } f = ff; } @@ -641,7 +641,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f if (args.size() == 0) return; if (backend_register.count(args[0]) == 0) - log_cmd_error("No such backend: %s\n", args[0].c_str()); + log_cmd_error("No such backend: %s\n", args[0]); size_t orig_sel_stack_pos = design->selection_stack.size(); @@ -956,13 +956,7 @@ struct HelpPass : public Pass { auto name = it.first.str(); if (cell_help_messages.contains(name)) { auto cell_help = cell_help_messages.get(name); - if (groups.count(cell_help.group) != 0) { - auto group_cells = &groups.at(cell_help.group); - group_cells->push_back(name); - } else { - auto group_cells = new vector(1, name); - groups.emplace(cell_help.group, *group_cells); - } + groups[cell_help.group].emplace_back(name); auto cell_pair = pair(cell_help, it.second); cells.emplace(name, cell_pair); } else { @@ -972,7 +966,7 @@ struct HelpPass : public Pass { } for (auto &it : cell_help_messages.cell_help) { if (cells.count(it.first) == 0) { - log_warning("Found cell model '%s' without matching cell type.\n", it.first.c_str()); + log_warning("Found cell model '%s' without matching cell type.\n", it.first); } } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6592844e2..daa2d4184 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -89,7 +89,7 @@ static_assert(check_well_known_id_order()); dict RTLIL::constpad; -const pool &RTLIL::builtin_ff_cell_types() { +static const pool &builtin_ff_cell_types_internal() { static const pool res = { ID($sr), ID($ff), @@ -240,14 +240,28 @@ const pool &RTLIL::builtin_ff_cell_types() { return res; } +const pool &RTLIL::builtin_ff_cell_types() { + return builtin_ff_cell_types_internal(); +} + #define check(condition) log_assert(condition && "malformed Const union") -Const::bitvectype& Const::get_bits() const { +const Const::bitvectype& Const::get_bits() const { check(is_bits()); return *get_if_bits(); } -std::string& Const::get_str() const { +const std::string& Const::get_str() const { + check(is_str()); + return *get_if_str(); +} + +Const::bitvectype& Const::get_bits() { + check(is_bits()); + return *get_if_bits(); +} + +std::string& Const::get_str() { check(is_str()); return *get_if_str(); } @@ -259,9 +273,34 @@ RTLIL::Const::Const(const std::string &str) tag = backing_tag::string; } -RTLIL::Const::Const(int val, int width) +RTLIL::Const::Const(long long val) // default width 32 { flags = RTLIL::CONST_FLAG_NONE; + char bytes[] = { + (char)(val >> 24), (char)(val >> 16), (char)(val >> 8), (char)val + }; + new ((void*)&str_) std::string(bytes, 4); + tag = backing_tag::string; +} + +RTLIL::Const::Const(long long val, int width) +{ + flags = RTLIL::CONST_FLAG_NONE; + if ((width & 7) == 0) { + new ((void*)&str_) std::string(); + tag = backing_tag::string; + std::string& str = get_str(); + int bytes = width >> 3; + signed char sign_byte = val < 0 ? -1 : 0; + str.resize(bytes, sign_byte); + bytes = std::min(bytes, sizeof(val)); + for (int i = 0; i < bytes; i++) { + str[str.size() - 1 - i] = val; + val = val >> 8; + } + return; + } + new ((void*)&bits_) bitvectype(); tag = backing_tag::bits; bitvectype& bv = get_bits(); @@ -365,6 +404,11 @@ bool RTLIL::Const::operator<(const RTLIL::Const &other) const bool RTLIL::Const::operator ==(const RTLIL::Const &other) const { + if (is_str() && other.is_str()) + return get_str() == other.get_str(); + if (is_bits() && other.is_bits()) + return get_bits() == other.get_bits(); + if (size() != other.size()) return false; @@ -380,9 +424,9 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const return !(*this == other); } -std::vector& RTLIL::Const::bits() +std::vector& RTLIL::Const::bits_internal() { - bitvectorize(); + bitvectorize_internal(); return get_bits(); } @@ -396,8 +440,14 @@ std::vector RTLIL::Const::to_bits() const bool RTLIL::Const::as_bool() const { - bitvectorize(); - bitvectype& bv = get_bits(); + if (is_str()) { + for (char ch : get_str()) + if (ch != 0) + return true; + return false; + } + + const bitvectype& bv = get_bits(); for (size_t i = 0; i < bv.size(); i++) if (bv[i] == State::S1) return true; @@ -406,15 +456,25 @@ bool RTLIL::Const::as_bool() const int RTLIL::Const::as_int(bool is_signed) const { - bitvectorize(); - bitvectype& bv = get_bits(); int32_t ret = 0; - for (size_t i = 0; i < bv.size() && i < 32; i++) + if (const std::string *s = get_if_str()) { + int size = GetSize(*s); + // Ignore any bytes after the first 4 since bits beyond 32 are truncated. + for (int i = std::min(4, size); i > 0; i--) + ret |= static_cast((*s)[size - i]) << ((i - 1) * 8); + // If is_signed and the string is shorter than 4 bytes then apply sign extension. + if (is_signed && size > 0 && size < 4 && ((*s)[0] & 0x80)) + ret |= UINT32_MAX << size*8; + return ret; + } + + const bitvectype& bv = get_bits(); + int significant_bits = std::min(GetSize(bv), 32); + for (int i = 0; i < significant_bits; i++) if (bv[i] == State::S1) ret |= 1 << i; - if (is_signed && bv.back() == State::S1) - for (size_t i = bv.size(); i < 32; i++) - ret |= 1 << i; + if (is_signed && significant_bits > 0 && significant_bits < 32 && bv.back() == State::S1 ) + ret |= UINT32_MAX << significant_bits; return ret; } @@ -434,7 +494,7 @@ bool RTLIL::Const::convertible_to_int(bool is_signed) const if (size == 32) { if (is_signed) return true; - return get_bits().at(31) != State::S1; + return back() != State::S1; } return false; @@ -455,7 +515,7 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const const auto min_size = get_min_size(is_signed); log_assert(min_size > 0); - const auto neg = get_bits().at(min_size - 1); + const auto neg = (*this)[min_size - 1]; return neg ? std::numeric_limits::min() : std::numeric_limits::max(); } return as_int(is_signed); @@ -488,7 +548,7 @@ int RTLIL::Const::get_min_size(bool is_signed) const void RTLIL::Const::compress(bool is_signed) { auto idx = get_min_size(is_signed); - bits().erase(bits().begin() + idx, bits().end()); + resize(idx, RTLIL::State::S0); } std::optional RTLIL::Const::as_int_compress(bool is_signed) const @@ -498,18 +558,17 @@ std::optional RTLIL::Const::as_int_compress(bool is_signed) const std::string RTLIL::Const::as_string(const char* any) const { - bitvectorize(); - bitvectype& bv = get_bits(); + int sz = size(); std::string ret; - ret.reserve(bv.size()); - for (size_t i = bv.size(); i > 0; i--) - switch (bv[i-1]) { - case S0: ret += "0"; break; - case S1: ret += "1"; break; - case Sx: ret += "x"; break; - case Sz: ret += "z"; break; + ret.reserve(sz); + for (int i = sz - 1; i >= 0; --i) + switch ((*this)[i]) { + case S0: ret.push_back('0'); break; + case S1: ret.push_back('1'); break; + case Sx: ret.push_back('x'); break; + case Sz: ret.push_back('z'); break; case Sa: ret += any; break; - case Sm: ret += "m"; break; + case Sm: ret.push_back('m'); break; } return ret; } @@ -536,8 +595,7 @@ std::string RTLIL::Const::decode_string() const if (auto str = get_if_str()) return *str; - bitvectorize(); - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); const int n = GetSize(bv); const int n_over_8 = n / 8; std::string s; @@ -585,7 +643,7 @@ bool RTLIL::Const::empty() const { } } -void RTLIL::Const::bitvectorize() const { +void RTLIL::Const::bitvectorize_internal() { if (tag == backing_tag::bits) return; @@ -611,26 +669,33 @@ void RTLIL::Const::bitvectorize() const { } void RTLIL::Const::append(const RTLIL::Const &other) { - bitvectorize(); + bitvectorize_internal(); bitvectype& bv = get_bits(); bv.insert(bv.end(), other.begin(), other.end()); } RTLIL::State RTLIL::Const::const_iterator::operator*() const { - if (auto bv = parent.get_if_bits()) + if (auto bv = parent->get_if_bits()) return (*bv)[idx]; - int char_idx = parent.get_str().size() - idx / 8 - 1; - bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8))); + int char_idx = parent->get_str().size() - idx / 8 - 1; + bool bit = (parent->get_str()[char_idx] & (1 << (idx % 8))); return bit ? State::S1 : State::S0; } bool RTLIL::Const::is_fully_zero() const { - bitvectorize(); - bitvectype& bv = get_bits(); cover("kernel.rtlil.const.is_fully_zero"); + if (auto str = get_if_str()) { + for (char ch : *str) + if (ch != 0) + return false; + return true; + } + + const bitvectype& bv = get_bits(); + for (const auto &bit : bv) if (bit != RTLIL::State::S0) return false; @@ -640,10 +705,16 @@ bool RTLIL::Const::is_fully_zero() const bool RTLIL::Const::is_fully_ones() const { - bitvectorize(); - bitvectype& bv = get_bits(); cover("kernel.rtlil.const.is_fully_ones"); + if (auto str = get_if_str()) { + for (char ch : *str) + if (ch != (char)0xff) + return false; + return true; + } + + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::S1) return false; @@ -655,9 +726,10 @@ bool RTLIL::Const::is_fully_def() const { cover("kernel.rtlil.const.is_fully_def"); - bitvectorize(); - bitvectype& bv = get_bits(); + if (is_str()) + return true; + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) return false; @@ -669,9 +741,10 @@ bool RTLIL::Const::is_fully_undef() const { cover("kernel.rtlil.const.is_fully_undef"); - bitvectorize(); - bitvectype& bv = get_bits(); + if (auto str = get_if_str()) + return str->empty(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) return false; @@ -683,9 +756,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const { cover("kernel.rtlil.const.is_fully_undef_x_only"); - bitvectorize(); - bitvectype& bv = get_bits(); + if (auto str = get_if_str()) + return str->empty(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::Sx) return false; @@ -697,12 +771,10 @@ bool RTLIL::Const::is_onehot(int *pos) const { cover("kernel.rtlil.const.is_onehot"); - bitvectorize(); - bitvectype& bv = get_bits(); - bool found = false; - for (int i = 0; i < GetSize(*this); i++) { - auto &bit = bv[i]; + int size = GetSize(*this); + for (int i = 0; i < size; i++) { + State bit = (*this)[i]; if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) return false; if (bit == RTLIL::State::S1) { @@ -716,6 +788,40 @@ bool RTLIL::Const::is_onehot(int *pos) const return found; } +Hasher RTLIL::Const::hash_into(Hasher h) const +{ + if (auto str = get_if_str()) + return hashlib::hash_ops::hash_into(*str, h); + + // If the bits are all 0/1, hash packed bits using the string hash. + // Otherwise hash the leading packed bits with the rest of the bits individually. + const bitvectype &bv = get_bits(); + int size = GetSize(bv); + std::string packed; + int packed_size = (size + 7) >> 3; + packed.resize(packed_size, 0); + for (int bi = 0; bi < packed_size; ++bi) { + char ch = 0; + int end = std::min((bi + 1)*8, size); + for (int i = bi*8; i < end; ++i) { + RTLIL::State b = bv[i]; + if (b > RTLIL::State::S1) { + // Hash the packed bits we've seen so far, plus the remaining bits. + h = hashlib::hash_ops::hash_into(packed, h); + h = hashlib::hash_ops::hash_into(ch, h); + for (; i < size; ++i) { + h = hashlib::hash_ops::hash_into(bv[i], h); + } + h.eat(size); + return h; + } + ch |= static_cast(b) << (i & 7); + } + packed[packed_size - 1 - bi] = ch; + } + return hashlib::hash_ops::hash_into(packed, h); +} + RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const { bitvectype ret_bv; ret_bv.reserve(len); @@ -2361,6 +2467,19 @@ namespace { check_expected(); return; } + if (cell->type.in(ID($input_port))) { + param(ID::WIDTH); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type.in(ID($connect))) { + param(ID::WIDTH); + port(ID::A, param(ID::WIDTH)); + port(ID::B, param(ID::WIDTH)); + check_expected(); + return; + } /* * Checklist for adding internal cell types * ======================================== @@ -2741,7 +2860,13 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) log_assert(cells_.count(cell->name) != 0); log_assert(refcount_cells_ == 0); cells_.erase(cell->name); - delete cell; + if (design && design->flagBufferedNormalized && buf_norm_cell_queue.count(cell)) { + cell->type.clear(); + cell->name.clear(); + pending_deleted_cells.insert(cell); + } else { + delete cell; + } } void RTLIL::Module::remove(RTLIL::Process *process) @@ -2932,6 +3057,14 @@ void RTLIL::Module::fixup_ports() std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare); + if (design && design->flagBufferedNormalized) { + for (auto &w : wires_) + if (w.second->driverCell_ && w.second->driverCell_->type == ID($input_port)) + buf_norm_wire_queue.insert(w.second); + + buf_norm_wire_queue.insert(all_ports.begin(), all_ports.end()); + } + ports.clear(); for (size_t i = 0; i < all_ports.size(); i++) { ports.push_back(all_ports[i]->name); @@ -4097,190 +4230,7 @@ bool RTLIL::Cell::hasPort(const RTLIL::IdString& portname) const return connections_.count(portname) != 0; } -void RTLIL::Cell::unsetPort(const RTLIL::IdString& portname) -{ - RTLIL::SigSpec signal; - auto conn_it = connections_.find(portname); - - if (conn_it != connections_.end()) - { - for (auto mon : module->monitors) - mon->notify_connect(this, conn_it->first, conn_it->second, signal); - - if (module->design) - for (auto mon : module->design->monitors) - mon->notify_connect(this, conn_it->first, conn_it->second, signal); - - if (yosys_xtrace) { - log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname)); - log_backtrace("-X- ", yosys_xtrace-1); - } - - connections_.erase(conn_it); - } -} - -void RTLIL::Design::bufNormalize(bool enable) -{ - if (!enable) - { - if (!flagBufferedNormalized) - return; - - for (auto module : modules()) { - module->bufNormQueue.clear(); - for (auto wire : module->wires()) { - wire->driverCell_ = nullptr; - wire->driverPort_ = IdString(); - } - } - - flagBufferedNormalized = false; - return; - } - - if (!flagBufferedNormalized) - { - for (auto module : modules()) - { - for (auto cell : module->cells()) - for (auto &conn : cell->connections()) { - if (!cell->output(conn.first) || GetSize(conn.second) == 0) - continue; - if (conn.second.is_wire()) { - Wire *wire = conn.second.as_wire(); - log_assert(wire->driverCell_ == nullptr); - wire->driverCell_ = cell; - wire->driverPort_ = conn.first; - } else { - pair key(cell, conn.first); - module->bufNormQueue.insert(key); - } - } - } - - flagBufferedNormalized = true; - } - - for (auto module : modules()) - module->bufNormalize(); -} - -void RTLIL::Module::bufNormalize() -{ - if (!design->flagBufferedNormalized) - return; - - while (GetSize(bufNormQueue) || !connections_.empty()) - { - pool> queue; - bufNormQueue.swap(queue); - - pool outWires; - for (auto &conn : connections()) - for (auto &chunk : conn.first.chunks()) - if (chunk.wire) outWires.insert(chunk.wire); - - SigMap sigmap(this); - new_connections({}); - - Module *module = this; // SILIMATE: Improve the naming - - for (auto &key : queue) - { - Cell *cell = key.first; - const IdString &portname = key.second; - const SigSpec &sig = cell->getPort(portname); - if (GetSize(sig) == 0) continue; - - if (sig.is_wire()) { - Wire *wire = sig.as_wire(); - if (wire->driverCell_) { - log_error("Conflict between %s %s in module %s\n", - log_id(cell), log_id(wire->driverCell_), log_id(this)); - } - log_assert(wire->driverCell_ == nullptr); - wire->driverCell_ = cell; - wire->driverPort_ = portname; - continue; - } - - for (auto &chunk : sig.chunks()) - if (chunk.wire) outWires.insert(chunk.wire); - - Wire *wire = addWire(NEW_ID2_SUFFIX(portname.str()), GetSize(sig)); // SILIMATE: Improve the naming - sigmap.add(sig, wire); - cell->setPort(portname, wire); - - // FIXME: Move init attributes from old 'sig' to new 'wire' - } - - for (auto wire : outWires) - { - SigSpec outsig = wire, insig = sigmap(wire); - for (int i = 0; i < GetSize(wire); i++) - if (insig[i] == outsig[i]) - insig[i] = State::Sx; - addBuf(NEW_ID4_SUFFIX("buf"), insig, outsig); // SILIMATE: Improve the naming - } - } -} - -void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal) -{ - auto r = connections_.insert(portname); - auto conn_it = r.first; - if (!r.second && conn_it->second == signal) - return; - - for (auto mon : module->monitors) - mon->notify_connect(this, conn_it->first, conn_it->second, signal); - - if (module->design) - for (auto mon : module->design->monitors) - mon->notify_connect(this, conn_it->first, conn_it->second, signal); - - if (yosys_xtrace) { - log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal)); - log_backtrace("-X- ", yosys_xtrace-1); - } - - while (module->design && module->design->flagBufferedNormalized && output(portname)) - { - pair key(this, portname); - - if (conn_it->second.is_wire()) { - Wire *w = conn_it->second.as_wire(); - if (w->driverCell_ == this && w->driverPort_ == portname) { - w->driverCell_ = nullptr; - w->driverPort_ = IdString(); - } - } - - if (GetSize(signal) == 0) { - module->bufNormQueue.erase(key); - break; - } - - if (!signal.is_wire()) { - module->bufNormQueue.insert(key); - break; - } - - Wire *w = signal.as_wire(); - if (w->driverCell_ != nullptr) { - pair other_key(w->driverCell_, w->driverPort_); - module->bufNormQueue.insert(other_key); - } - w->driverCell_ = this; - w->driverPort_ = portname; - - module->bufNormQueue.erase(key); - break; - } - - conn_it->second = std::move(signal); -} +// bufnorm const RTLIL::SigSpec &RTLIL::Cell::getPort(const RTLIL::IdString& portname) const { @@ -4325,6 +4275,22 @@ bool RTLIL::Cell::output(const RTLIL::IdString& portname) const return false; } +RTLIL::PortDir RTLIL::Cell::port_dir(const RTLIL::IdString& portname) const +{ + if (yosys_celltypes.cell_known(type)) + return yosys_celltypes.cell_port_dir(type, portname); + if (module && module->design) { + RTLIL::Module *m = module->design->module(type); + if (m == nullptr) + return PortDir::PD_UNKNOWN; + RTLIL::Wire *w = m->wire(portname); + if (w == nullptr) + return PortDir::PD_UNKNOWN; + return PortDir(w->port_input + w->port_output * 2); + } + return PortDir::PD_UNKNOWN; +} + bool RTLIL::Cell::hasParam(const RTLIL::IdString& paramname) const { return parameters.count(paramname) != 0; @@ -4454,6 +4420,10 @@ bool RTLIL::Cell::is_mem_cell() const return type.in(ID($mem), ID($mem_v2)) || has_memid(); } +bool RTLIL::Cell::is_builtin_ff() const { + return builtin_ff_cell_types_internal().count(type) > 0; +} + RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit) { wire = bit.wire; @@ -5479,6 +5449,15 @@ bool RTLIL::SigSpec::is_mostly_const() const return (constbits > width_/2); } +bool RTLIL::SigSpec::known_driver() const +{ + pack(); + for (auto &chunk : chunks_) + if (chunk.is_wire() && !chunk.wire->known_driver()) + return false; + return true; +} + bool RTLIL::SigSpec::is_fully_const() const { cover("kernel.rtlil.sigspec.is_fully_const"); @@ -5561,6 +5540,18 @@ bool RTLIL::SigSpec::has_const() const return false; } +bool RTLIL::SigSpec::has_const(State state) const +{ + cover("kernel.rtlil.sigspec.has_const"); + + pack(); + for (auto it = chunks_.begin(); it != chunks_.end(); it++) + if (it->width > 0 && it->wire == NULL && std::find(it->data.begin(), it->data.end(), state) != it->data.end()) + return true; + return false; +} + + bool RTLIL::SigSpec::has_marked_bits() const { cover("kernel.rtlil.sigspec.has_marked_bits"); @@ -5943,7 +5934,11 @@ bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, R } } - return parse(sig, module, str); + if (!parse(sig, module, str)) + return false; + if (sig.width_ > lhs.width_) + sig.remove(lhs.width_, sig.width_ - lhs.width_); + return true; } RTLIL::CaseRule::~CaseRule() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d2e274afa..8cbe488a4 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -91,6 +91,13 @@ namespace RTLIL STATIC_ID_END, }; + enum PortDir : unsigned char { + PD_UNKNOWN = 0, + PD_INPUT = 1, + PD_OUTPUT = 2, + PD_INOUT = 3 + }; + struct Const; struct AttrObject; struct NamedObject; @@ -557,6 +564,7 @@ template <> struct IDMacroHelper<-1> { namespace RTLIL { extern dict constpad; + [[deprecated("Call cell->is_builtin_ff() instead")]] const pool &builtin_ff_cell_types(); static inline std::string escape_id(const std::string &str) { @@ -829,38 +837,61 @@ private: using bitvectype = std::vector; enum class backing_tag: bool { bits, string }; // Do not access the union or tag even in Const methods unless necessary - mutable backing_tag tag; + backing_tag tag; union { - mutable bitvectype bits_; - mutable std::string str_; + bitvectype bits_; + std::string str_; }; // Use these private utilities instead bool is_bits() const { return tag == backing_tag::bits; } bool is_str() const { return tag == backing_tag::string; } - bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } - std::string* get_if_str() const { return is_str() ? &str_ : NULL; } + bitvectype* get_if_bits() { return is_bits() ? &bits_ : NULL; } + std::string* get_if_str() { return is_str() ? &str_ : NULL; } + const bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } + const std::string* get_if_str() const { return is_str() ? &str_ : NULL; } + + bitvectype& get_bits(); + std::string& get_str(); + const bitvectype& get_bits() const; + const std::string& get_str() const; + std::vector& bits_internal(); + void bitvectorize_internal(); - bitvectype& get_bits() const; - std::string& get_str() const; public: Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector()) {} Const(const std::string &str); - Const(int val, int width = 32); + Const(long long val); // default width is 32 + Const(long long val, int width); Const(RTLIL::State bit, int width = 1); - Const(const std::vector &bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(bits) {} + Const(std::vector bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::move(bits)) {} Const(const std::vector &bits); Const(const RTLIL::Const &other); Const(RTLIL::Const &&other); RTLIL::Const &operator =(const RTLIL::Const &other); ~Const(); + struct Builder + { + Builder() {} + Builder(int expected_width) { bits.reserve(expected_width); } + void push_back(RTLIL::State b) { bits.push_back(b); } + int size() const { return static_cast(bits.size()); } + Const build() { return Const(std::move(bits)); } + private: + std::vector bits; + }; + bool operator <(const RTLIL::Const &other) const; bool operator ==(const RTLIL::Const &other) const; bool operator !=(const RTLIL::Const &other) const; - std::vector& bits(); + [[deprecated("Don't use direct access to the internal std::vector, that's an implementation detail.")]] + std::vector& bits() { return bits_internal(); } + [[deprecated("Don't call bitvectorize() directly, it's an implementation detail.")]] + void bitvectorize() const { const_cast(this)->bitvectorize_internal(); } + bool as_bool() const; // Convert the constant value to a C++ int. @@ -889,37 +920,42 @@ public: std::string decode_string() const; int size() const; bool empty() const; - void bitvectorize() const; void append(const RTLIL::Const &other); + void set(int i, RTLIL::State state) { + bits_internal()[i] = state; + } + void resize(int size, RTLIL::State fill) { + bits_internal().resize(size, fill); + } class const_iterator { private: - const Const& parent; + const Const* parent; size_t idx; public: - using iterator_category = std::input_iterator_tag; + using iterator_category = std::bidirectional_iterator_tag; using value_type = State; using difference_type = std::ptrdiff_t; using pointer = const State*; using reference = const State&; - const_iterator(const Const& c, size_t i) : parent(c), idx(i) {} + const_iterator(const Const& c, size_t i) : parent(&c), idx(i) {} State operator*() const; const_iterator& operator++() { ++idx; return *this; } const_iterator& operator--() { --idx; return *this; } - const_iterator& operator++(int) { ++idx; return *this; } - const_iterator& operator--(int) { --idx; return *this; } + const_iterator operator++(int) { const_iterator result(*this); ++idx; return result; } + const_iterator operator--(int) { const_iterator result(*this); --idx; return result; } const_iterator& operator+=(int i) { idx += i; return *this; } const_iterator operator+(int add) { - return const_iterator(parent, idx + add); + return const_iterator(*parent, idx + add); } const_iterator operator-(int sub) { - return const_iterator(parent, idx - sub); + return const_iterator(*parent, idx - sub); } int operator-(const const_iterator& other) { return idx - other.idx; @@ -934,12 +970,69 @@ public: } }; + class iterator { + private: + Const* parent; + size_t idx; + + public: + class proxy { + private: + Const* parent; + size_t idx; + public: + proxy(Const* parent, size_t idx) : parent(parent), idx(idx) {} + operator State() const { return (*parent)[idx]; } + proxy& operator=(State s) { parent->set(idx, s); return *this; } + proxy& operator=(const proxy& other) { parent->set(idx, (*other.parent)[other.idx]); return *this; } + }; + + using iterator_category = std::bidirectional_iterator_tag; + using value_type = State; + using difference_type = std::ptrdiff_t; + using pointer = proxy*; + using reference = proxy; + + iterator(Const& c, size_t i) : parent(&c), idx(i) {} + + proxy operator*() const { return proxy(parent, idx); } + iterator& operator++() { ++idx; return *this; } + iterator& operator--() { --idx; return *this; } + iterator operator++(int) { iterator result(*this); ++idx; return result; } + iterator operator--(int) { iterator result(*this); --idx; return result; } + iterator& operator+=(int i) { idx += i; return *this; } + + iterator operator+(int add) { + return iterator(*parent, idx + add); + } + iterator operator-(int sub) { + return iterator(*parent, idx - sub); + } + int operator-(const iterator& other) { + return idx - other.idx; + } + + bool operator==(const iterator& other) const { + return idx == other.idx; + } + + bool operator!=(const iterator& other) const { + return !(*this == other); + } + }; + const_iterator begin() const { return const_iterator(*this, 0); } const_iterator end() const { return const_iterator(*this, size()); } + iterator begin() { + return iterator(*this, 0); + } + iterator end() { + return iterator(*this, size()); + } State back() const { return *(end() - 1); } @@ -971,20 +1064,14 @@ public: std::optional as_int_compress(bool is_signed) const; void extu(int width) { - bits().resize(width, RTLIL::State::S0); + resize(width, RTLIL::State::S0); } void exts(int width) { - bitvectype& bv = bits(); - bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back()); + resize(width, empty() ? RTLIL::State::Sx : back()); } - [[nodiscard]] Hasher hash_into(Hasher h) const { - h.eat(size()); - for (auto b : *this) - h.eat(b); - return h; - } + [[nodiscard]] Hasher hash_into(Hasher h) const; }; struct RTLIL::AttrObject @@ -1040,7 +1127,8 @@ struct RTLIL::SigChunk SigChunk(RTLIL::Wire *wire) : wire(wire), width(GetSize(wire)), offset(0) {} SigChunk(RTLIL::Wire *wire, int offset, int width = 1) : wire(wire), width(width), offset(offset) {} SigChunk(const std::string &str) : SigChunk(RTLIL::Const(str)) {} - SigChunk(int val, int width = 32) : SigChunk(RTLIL::Const(val, width)) {} + SigChunk(int val) /*default width 32*/ : SigChunk(RTLIL::Const(val)) {} + SigChunk(int val, int width) : SigChunk(RTLIL::Const(val, width)) {} SigChunk(RTLIL::State bit, int width = 1) : SigChunk(RTLIL::Const(bit, width)) {} SigChunk(const RTLIL::SigBit &bit); @@ -1250,12 +1338,16 @@ public: inline bool is_bit() const { return width_ == 1; } bool is_mostly_const() const; + + bool known_driver() const; + bool is_fully_const() const; bool is_fully_zero() const; bool is_fully_ones() const; bool is_fully_def() const; bool is_fully_undef() const; bool has_const() const; + bool has_const(State state) const; bool has_marked_bits() const; bool is_onehot(int *pos = nullptr) const; @@ -1651,7 +1743,11 @@ public: std::vector ports; void fixup_ports(); - pool> bufNormQueue; + pool buf_norm_cell_queue; + pool> buf_norm_cell_port_queue; + pool buf_norm_wire_queue; + pool pending_deleted_cells; + dict> buf_norm_connect_index; void bufNormalize(); template void rewrite_sigspecs(T &functor); @@ -1987,6 +2083,8 @@ public: int width, start_offset, port_id; bool port_input, port_output, upto, is_signed; + bool known_driver() const { return driverCell_ != nullptr; } + RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; }; RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; }; @@ -2058,6 +2156,7 @@ public: bool known() const; bool input(const RTLIL::IdString &portname) const; bool output(const RTLIL::IdString &portname) const; + PortDir port_dir(const RTLIL::IdString &portname) const; // access cell parameters bool hasParam(const RTLIL::IdString ¶mname) const; @@ -2083,6 +2182,7 @@ public: bool has_memid() const; bool is_mem_cell() const; + bool is_builtin_ff() const; }; struct RTLIL::CaseRule : public RTLIL::AttrObject diff --git a/kernel/rtlil_bufnorm.cc b/kernel/rtlil_bufnorm.cc new file mode 100644 index 000000000..6d619d9e6 --- /dev/null +++ b/kernel/rtlil_bufnorm.cc @@ -0,0 +1,679 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" +#include "kernel/modtools.h" + +#include +#include +#include + +YOSYS_NAMESPACE_BEGIN + + +void RTLIL::Design::bufNormalize(bool enable) +{ + if (!enable) + { + if (!flagBufferedNormalized) + return; + + for (auto module : modules()) { + module->buf_norm_cell_queue.clear(); + module->buf_norm_wire_queue.clear(); + module->buf_norm_cell_port_queue.clear(); + for (auto wire : module->wires()) { + wire->driverCell_ = nullptr; + wire->driverPort_ = IdString(); + } + } + + flagBufferedNormalized = false; + return; + } + + if (!flagBufferedNormalized) + { + for (auto module : modules()) + { + // When entering buf normalized mode, we need the first module-level bufNormalize + // call to know about all drivers, about all module ports (whether represented by + // a cell or not) and about all used but undriven wires (whether represented by a + // cell or not). We ensure this by enqueing all cell output ports and all wires. + + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) { + if (GetSize(conn.second) == 0 || (cell->port_dir(conn.first) != RTLIL::PD_OUTPUT && cell->port_dir(conn.first) != RTLIL::PD_INOUT)) + continue; + module->buf_norm_cell_queue.insert(cell); + module->buf_norm_cell_port_queue.emplace(cell, conn.first); + } + for (auto wire : module->wires()) + module->buf_norm_wire_queue.insert(wire); + + } + + flagBufferedNormalized = true; + } + + for (auto module : modules()) + module->bufNormalize(); +} + +struct bit_drive_data_t { + int drivers = 0; + int inout = 0; + int users = 0; +}; + +typedef ModWalker::PortBit PortBit; + +void RTLIL::Module::bufNormalize() +{ + // Since this is kernel code, we only log with yosys_xtrace set to not get + // in the way when using `debug` to debug specific passes.q +#define xlog(...) do { if (yosys_xtrace) log("#X [bufnorm] " __VA_ARGS__); } while (0) + + if (!design->flagBufferedNormalized) + return; + + if (!buf_norm_cell_queue.empty() || !buf_norm_wire_queue.empty() || !connections_.empty()) + { + // Ensure that every enqueued input port is represented by a cell + for (auto wire : buf_norm_wire_queue) { + if (wire->port_input && !wire->port_output) { + if (wire->driverCell_ != nullptr && wire->driverCell_->type != ID($input_port)) { + wire->driverCell_ = nullptr; + wire->driverPort_.clear(); + } + if (wire->driverCell_ == nullptr) { + Cell *input_port_cell = addCell(NEW_ID, ID($input_port)); + input_port_cell->setParam(ID::WIDTH, GetSize(wire)); + input_port_cell->setPort(ID::Y, wire); // this hits the fast path that doesn't mutate the queues + } + } + } + + // Next we will temporarily undo buf normalization locally for + // everything enqueued. This means we will turn $buf and $connect back + // into connections. When doing this we also need to enqueue the other + // end of $buf and $connect cells, so we use a queue and do this until + // reaching a fixed point. + + // While doing this, we will also discover all drivers fully connected + // to enqueued wires. We keep track of which wires are driven by a + // unique and full cell ports (in which case the wire can stay + // connected to the port) and which cell ports will need to be + // reconnected to a fresh intermediate wire to re-normalize the module. + + idict wire_queue_entries; // Ordered queue of wires to process + int wire_queue_pos = 0; // Index up to which we processed the wires + + // Wires with their unique driving cell port. If we know a wire is + // driven by multiple (potential) drivers, this is indicated by a + // nullptr as cell. + dict> direct_driven_wires; + + // Set of non-unique or driving cell ports for each processed wire. + dict>> direct_driven_wires_conflicts; + + // Set of cell ports that need a fresh intermediate wire. + pool> pending_ports; + + // This helper will be called for every output/inout cell port that is + // already enqueued or becomes reachable when denormalizing $buf or + // $connect cells. + auto enqueue_cell_port = [&](Cell *cell, IdString port) { + xlog("processing cell port %s.%s\n", log_id(cell), log_id(port)); + + // An empty cell type means the cell got removed + if (cell->type.empty()) + return; + + + SigSpec const &sig = cell->getPort(port); + if (cell->type == ID($input_port)) { + // If an `$input_port` cell isn't fully connected to a full + // input port wire, we remove it since the wires are still the + // canonical source of module ports and the `$input_port` cells + // are just helpers to simplfiy the bufnorm invariant. + log_assert(port == ID::Y); + if (!sig.is_wire()) { + buf_norm_cell_queue.insert(cell); + remove(cell); + return; + } + + Wire *w = sig.as_wire(); + if (!w->port_input || w->port_output) { + buf_norm_cell_queue.insert(cell); + remove(cell); + return; + } + w->driverCell_ = cell; + w->driverPort_ = ID::Y; + } else if (cell->type == ID($buf) && cell->attributes.empty() && !cell->name.isPublic()) { + // For a plain `$buf` cell, we enqueue all wires on its input + // side, bypass it using module level connections (skipping 'z + // bits) and then remove the cell. Eventually the module level + // connections will turn back into `$buf` and `$connect` cells, + // but since we also need to handle externally added module + // level connections, turning everything into connections first + // simplifies the logic for doing so. + + // TODO: We could defer removing the $buf cells here, and + // re-use them in case we would create a new identical cell + // later. + log_assert(port == ID::Y); + SigSpec sig_a = cell->getPort(ID::A); + SigSpec sig_y = sig; + + for (auto const &s : {sig_a, sig}) + for (auto const &chunk : s.chunks()) + if (chunk.wire) + wire_queue_entries(chunk.wire); + + if (sig_a.has_const(State::Sz)) { + SigSpec new_a; + SigSpec new_y; + for (int i = 0; i < GetSize(sig_a); ++i) { + SigBit b = sig_a[i]; + if (b == State::Sz) + continue; + new_a.append(b); + new_y.append(sig_y[i]); + } + sig_a = std::move(new_a); + sig_y = std::move(new_y); + } + + if (!sig_y.empty()) + connect(sig_y, sig_a); + buf_norm_cell_queue.insert(cell); + remove(cell); + return; + } + + // Make sure all wires of the cell port are enqueued, ensuring we + // detect other connected drivers (output and inout). + for (auto const &chunk : sig.chunks()) + if (chunk.wire) + wire_queue_entries(chunk.wire); + + if (sig.is_wire()) { + // If the full cell port is connected to a full wire, we might be + // able to keep that connection if this is a unique output port driving that wire + Wire *w = sig.as_wire(); + + // We try to store the current port as unique driver, if this + // succeeds we're done with the port. + auto [found, inserted] = direct_driven_wires.emplace(w, {cell, port}); + if (inserted || (found->second.first == cell && found->second.second == port)) + return; + + // When this failed, we store this port as a conflict. If we + // had already stored a candidate for a unique driver, we also + // move it to the conflicts, leaving a nullptr marker. + + auto &conflicts = direct_driven_wires_conflicts[w]; + if (Cell *other_cell = found->second.first) { + if (other_cell->type == ID($input_port)) { + // Multiple input port cells + log_assert(cell->type != ID($input_port)); + } else { + pending_ports.insert(found->second); + conflicts.emplace(found->second); + found->second = {nullptr, {}}; + } + } + if (cell->type == ID($input_port)) { + found->second = {cell, port}; + } else { + conflicts.emplace(cell, port); + } + } + + // Adds this port to the ports that need a fresh intermediate wire. + // For full wires uniquely driven by a full output port, this isn't + // reached due to the `return` above. + pending_ports.emplace(cell, port); + }; + + // We process all explicitly enqueued cell ports (clearing the module level queue). + for (auto const &[cell, port_name] : buf_norm_cell_port_queue) + enqueue_cell_port(cell, port_name); + buf_norm_cell_port_queue.clear(); + + // And enqueue all wires for `$buf`/`$connect` processing (clearing the module level queue). + for (auto wire : buf_norm_wire_queue) + wire_queue_entries(wire); + buf_norm_wire_queue.clear(); + + // We also enqueue all wires that saw newly added module level connections. + for (auto &[a, b] : connections_) + for (auto &sig : {a, b}) + for (auto const &chunk : sig.chunks()) + if (chunk.wire) + wire_queue_entries(chunk.wire); + + // We then process all wires by processing known driving cell ports + // (previously buf normalized) and following all `$connect` cells (that + // have a dedicated module level index while the design is in buf + // normalized mode). + while (wire_queue_pos < GetSize(wire_queue_entries)) { + auto wire = wire_queue_entries[wire_queue_pos++]; + xlog("processing wire %s\n", log_id(wire)); + + if (wire->driverCell_) { + Cell *cell = wire->driverCell_; + IdString port = wire->driverPort_; + enqueue_cell_port(cell, port); + } + + while (true) { + auto found = buf_norm_connect_index.find(wire); + if (found == buf_norm_connect_index.end()) + break; + while (!found->second.empty()) { + Cell *connect_cell = *found->second.begin(); + log_assert(connect_cell->type == ID($connect)); + SigSpec const &sig_a = connect_cell->getPort(ID::A); + SigSpec const &sig_b = connect_cell->getPort(ID::B); + xlog("found $connect cell %s: %s <-> %s\n", log_id(connect_cell), log_signal(sig_a), log_signal(sig_b)); + for (auto &side : {sig_a, sig_b}) + for (auto chunk : side.chunks()) + if (chunk.wire) + wire_queue_entries(chunk.wire); + connect(sig_a, sig_b); + buf_norm_cell_queue.insert(connect_cell); + remove(connect_cell); + } + } + } + + // At this point we know all cell ports and wires that need to be + // re-normalized and know their connectivity is represented by module + // level connections. + + // As a first step for re-normalization we add all require intermediate + // wires for cell output and inout ports. + for (auto &[cell, port] : pending_ports) { + SigSpec const &sig = cell->getPort(port); + Wire *w = addWire(NEW_ID, GetSize(sig)); + + // We update the module level connections, `direct_driven_wires` + // and `direct_driven_wires_conflicts` in such a way that they + // correspond to what you would get if the intermediate wires had + // been in place from the beginning. + connect(sig, w); + auto port_dir = cell->port_dir(port); + if (port_dir == RTLIL::PD_INOUT || port_dir == RTLIL::PD_UNKNOWN) { + direct_driven_wires.emplace(w, {nullptr, {}}); + direct_driven_wires_conflicts[w].emplace(cell, port); + } else { + direct_driven_wires.emplace(w, {cell, port}); + } + + cell->setPort(port, w); + wire_queue_entries(w); + } + + // At this point we're done with creating wires and know which ones are + // fully driven by full output ports of existing cells. + + // First we clear the bufnorm data for all processed wires, all of + // these will be reassigned later, but we use `driverCell_ == nullptr` + // to keep track of the wires that we still have to update. + for (auto wire : wire_queue_entries) { + wire->driverCell_ = nullptr; + wire->driverPort_.clear(); + } + + // For the unique output cell ports fully connected to a full wire, we + // can update the bufnorm data right away. For all other wires we will + // have to create new `$buf` cells. + for (auto const &[wire, cellport] : direct_driven_wires) { + wire->driverCell_ = cellport.first; + wire->driverPort_ = cellport.second; + } + + + // To create fresh `$buf` cells for all remaining wires, we need to + // process the module level connectivity to figure out what the input + // of those `$buf` cells should be and to figure out whether we need + // any `$connect` cells to represent bidirectional inout connections + // (or driver conflicts). + + if (yosys_xtrace) + for (auto const &[lhs, rhs] : connections_) + xlog("connection %s <-> %s\n", log_signal(lhs), log_signal(rhs)); + + + // We transfer the connectivity into a sigmap and then clear the module + // level connections. This forgets about the structure of module level + // connections, but bufnorm only guarantees that the connectivity as + // maintained by a `SigMap` is preserved. + SigMap sigmap(this); + new_connections({}); + + pool conflicted; + pool driven; + + // We iterate over all direct driven wires and try to make that wire's + // sigbits the representative sigbit for the net. We do a second pass + // to detect conflicts to then remove the conflicts from `driven`. + for (bool check : {false, true}) { + for (auto const &[wire, cellport] : direct_driven_wires) { + if (cellport.first == nullptr) + continue; + auto const &[cell, port] = cellport; + + SigSpec z_mask; + if (cell->type == ID($buf)) + z_mask = cell->getPort(ID::A); + + for (int i = 0; i != GetSize(wire); ++i) { + SigBit driver = SigBit(wire, i); + if (!z_mask.empty() && z_mask[i] == State::Sz) + continue; + if (check) { + SigBit repr = sigmap(driver); + if (repr != driver) + conflicted.insert(repr); + else + driven.insert(repr); + } else { + sigmap.database.promote(driver); + } + } + } + } + + // Ensure that module level inout ports are directly driven or + // connected using `$connect` cells and never `$buf`fered. + for (auto wire : wire_queue_entries) { + if (!wire->port_input || !wire->port_output) + continue; + for (int i = 0; i != GetSize(wire); ++i) { + SigBit driver = SigBit(wire, i); + SigBit repr = sigmap(driver); + if (driver != repr) + driven.erase(repr); + } + } + + for (auto &bit : conflicted) + driven.erase(bit); + + // Module level bitwise connections not representable by `$buf` cells + pool> undirected_connections; + + // Starts out empty but is updated with the connectivity realized by freshly added `$buf` cells + SigMap buf_connected; + + // For every enqueued wire, we compute a SigSpec of representative + // drivers. If there are any bits without a unique driver we represent + // that with `Sz`. If there are multiple drivers for a net, they become + // connected via `$connect` cells but every wire of the net has the + // corresponding bit still driven by a buffered `Sz`. + for (auto wire : wire_queue_entries) { + SigSpec wire_drivers; + for (int i = 0; i < GetSize(wire); ++i) { + SigBit bit(wire, i); + SigBit mapped = sigmap(bit); + xlog("bit %s -> mapped %s\n", log_signal(bit), log_signal(mapped)); + + + buf_connected.apply(bit); + buf_connected.add(bit, mapped); + buf_connected.database.promote(mapped); + + if (wire->driverCell_ == nullptr) { + if (!mapped.is_wire() || driven.count(mapped)) { + wire_drivers.append(mapped); + continue; + } else { + wire_drivers.append(State::Sz); + } + } + + if (bit < mapped) + undirected_connections.emplace(bit, mapped); + else if (mapped < bit) + undirected_connections.emplace(mapped, bit); + } + + if (wire->driverCell_ == nullptr) { + xlog("wire %s drivers %s\n", log_id(wire), log_signal(wire_drivers)); + addBuf(NEW_ID, wire_drivers, wire); + } + } + + // Finally we group the bitwise connections to emit word-level $connect cells + + static auto sort_key = [](std::pair const &p) { + int first_offset = p.first.is_wire() ? p.first.offset : 0; + int second_offset = p.second.is_wire() ? p.second.offset : 0; + return std::make_tuple(p.first.wire, p.second.wire, first_offset - second_offset, p); + }; + + undirected_connections.sort([](std::pair const &p, std::pair const &q) { + return sort_key(p) < sort_key(q); + }); + + SigSpec tmp_a, tmp_b; + + for (auto &[bit_a, bit_b] : undirected_connections) { + tmp_a.append(bit_a); + tmp_b.append(bit_b); + } + + xlog("LHS: %s\n", log_signal(tmp_a)); + xlog("RHS: %s\n", log_signal(tmp_b)); + + + SigSpec sig_a, sig_b; + SigBit next_a, next_b; + + auto emit_connect_cell = [&]() { + if (sig_a.empty()) + return; + xlog("connect %s <-> %s\n", log_signal(sig_a), log_signal(sig_b)); + Cell *connect_cell = addCell(NEW_ID, ID($connect)); + connect_cell->setParam(ID::WIDTH, GetSize(sig_a)); + connect_cell->setPort(ID::A, sig_a); + connect_cell->setPort(ID::B, sig_b); + sig_a = SigSpec(); + sig_b = SigSpec(); + }; + + for (auto &[bit_a, bit_b] : undirected_connections) { + if (bit_a == bit_b) + continue; + if (bit_a != next_a || bit_b != next_b) + emit_connect_cell(); + + sig_a.append(bit_a); + sig_b.append(bit_b); + next_a = bit_a; + next_b = bit_b; + if (next_a.is_wire()) + next_a.offset++; + if (next_b.is_wire()) + next_b.offset++; + + } + emit_connect_cell(); + + buf_norm_cell_queue.clear(); + + log_assert(buf_norm_cell_port_queue.empty()); + log_assert(buf_norm_wire_queue.empty()); + log_assert(connections_.empty()); + } + + for (auto cell : pending_deleted_cells) { + delete cell; + } + pending_deleted_cells.clear(); +} + +void RTLIL::Cell::unsetPort(const RTLIL::IdString& portname) +{ + RTLIL::SigSpec signal; + auto conn_it = connections_.find(portname); + + if (conn_it != connections_.end()) + { + for (auto mon : module->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); + + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); + + if (yosys_xtrace) { + log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname)); + log_backtrace("-X- ", yosys_xtrace-1); + } + + if (module->design && module->design->flagBufferedNormalized) { + if (conn_it->second.is_wire()) { + Wire *w = conn_it->second.as_wire(); + if (w->driverCell_ == this && w->driverPort_ == portname) { + w->driverCell_ = nullptr; + w->driverPort_ = IdString(); + module->buf_norm_wire_queue.insert(w); + } + } + + if (type == ID($connect)) { + for (auto &[port, sig] : connections_) { + for (auto &chunk : sig.chunks()) { + if (!chunk.wire) + continue; + auto it = module->buf_norm_connect_index.find(chunk.wire); + if (it == module->buf_norm_connect_index.end()) + continue; + it->second.erase(this); + if (it->second.empty()) + module->buf_norm_connect_index.erase(it); + } + } + connections_.erase(conn_it); + for (auto &[port, sig] : connections_) { + for (auto &chunk : sig.chunks()) { + if (!chunk.wire) + continue; + module->buf_norm_connect_index[chunk.wire].insert(this); + } + } + return; + } + } + + connections_.erase(conn_it); + } +} + +void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal) +{ + auto r = connections_.insert(portname); + auto conn_it = r.first; + if (!r.second && conn_it->second == signal) + return; + + for (auto mon : module->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); + + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); + + if (yosys_xtrace) { + log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal)); + log_backtrace("-X- ", yosys_xtrace-1); + } + + if (module->design && module->design->flagBufferedNormalized) + { + // We eagerly clear a driver that got disconnected by changing this port connection + if (conn_it->second.is_wire()) { + Wire *w = conn_it->second.as_wire(); + if (w->driverCell_ == this && w->driverPort_ == portname) { + w->driverCell_ = nullptr; + w->driverPort_ = IdString(); + module->buf_norm_wire_queue.insert(w); + } + } + + auto dir = port_dir(portname); + // This is a fast path that handles connecting a full driverless wire to an output port, + // everything else is goes through the bufnorm queues and is handled during the next + // bufNormalize call + if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) { + Wire *w = signal.as_wire(); + if (w->driverCell_ == nullptr) { + w->driverCell_ = this; + w->driverPort_ = portname; + + conn_it->second = std::move(signal); + return; + } + } + + if (dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) { + module->buf_norm_cell_queue.insert(this); + module->buf_norm_cell_port_queue.emplace(this, portname); + } else { + for (auto &chunk : signal.chunks()) + if (chunk.wire != nullptr && chunk.wire->driverCell_ == nullptr) + module->buf_norm_wire_queue.insert(chunk.wire); + } + + if (type == ID($connect)) { + for (auto &[port, sig] : connections_) { + for (auto &chunk : sig.chunks()) { + if (!chunk.wire) + continue; + auto it = module->buf_norm_connect_index.find(chunk.wire); + if (it == module->buf_norm_connect_index.end()) + continue; + it->second.erase(this); + if (it->second.empty()) + module->buf_norm_connect_index.erase(it); + } + } + conn_it->second = std::move(signal); + for (auto &[port, sig] : connections_) { + for (auto &chunk : sig.chunks()) { + if (!chunk.wire) + continue; + module->buf_norm_connect_index[chunk.wire].insert(this); + } + } + return; + } + } + conn_it->second = std::move(signal); + +} + +YOSYS_NAMESPACE_END diff --git a/kernel/satgen.cc b/kernel/satgen.cc index 7885eccf8..f2c1e00c2 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -1202,7 +1202,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) return true; } - if (timestep > 0 && (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit))) + if (timestep > 0 && (cell->is_builtin_ff() || cell->type == ID($anyinit))) { FfData ff(nullptr, cell); diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index 4bdb680ac..a2ebaffa2 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -137,7 +137,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a if (err.empty()) { Tcl_SetObjResult(interp, json_to_tcl(interp, json)); } else - log_warning("Ignoring result.json scratchpad value due to parse error: %s\n", err.c_str()); + log_warning("Ignoring result.json scratchpad value due to parse error: %s\n", err); } else if ((result = scratchpad.find("result.string")) != scratchpad.end()) { Tcl_SetObjResult(interp, Tcl_NewStringObj(result->second.data(), result->second.size())); } @@ -214,18 +214,19 @@ bool mp_int_to_const(mp_int *a, Const &b, bool is_signed) buf.resize(mp_unsigned_bin_size(a)); mp_to_unsigned_bin(a, buf.data()); - b.bits().reserve(mp_count_bits(a) + is_signed); + Const::Builder b_bits(mp_count_bits(a) + is_signed); for (int i = 0; i < mp_count_bits(a);) { for (int j = 0; j < 8 && i < mp_count_bits(a); j++, i++) { bool bv = ((buf.back() & (1 << j)) != 0) ^ negative; - b.bits().push_back(bv ? RTLIL::S1 : RTLIL::S0); + b_bits.push_back(bv ? RTLIL::S1 : RTLIL::S0); } buf.pop_back(); } if (is_signed) { - b.bits().push_back(negative ? RTLIL::S1 : RTLIL::S0); + b_bits.push_back(negative ? RTLIL::S1 : RTLIL::S0); } + b = b_bits.build(); return true; } diff --git a/kernel/yw.cc b/kernel/yw.cc index daad53380..560f7dd38 100644 --- a/kernel/yw.cc +++ b/kernel/yw.cc @@ -185,7 +185,6 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const const std::string &bits = steps[t].bits; RTLIL::Const result(State::Sa, width); - result.bits().reserve(width); int read_begin = GetSize(bits) - 1 - bits_offset; int read_end = max(-1, read_begin - width); @@ -200,7 +199,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const default: log_abort(); } - result.bits()[j] = bit; + result.set(j, bit); } return result; diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index 8c8d3d92d..60f27fd55 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -411,7 +411,7 @@ class SubCircuit::SolverWorker std::string toString() const { - return my_stringf("%s[%d]:%s[%d]", fromPort, fromBit, toPort, toBit); + return my_stringf("%s[%d]:%s[%d]", fromPort.c_str(), fromBit, toPort.c_str(), toBit); } }; @@ -444,7 +444,7 @@ class SubCircuit::SolverWorker std::string str; bool firstPort = true; for (const auto &it : portSizes) { - str += my_stringf("%s%s[%d]", firstPort ? "" : ",", it.first, it.second); + str += my_stringf("%s%s[%d]", firstPort ? "" : ",", it.first.c_str(), it.second); firstPort = false; } return typeId + "(" + str + ")"; diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 0cb38f82a..8e3d3700a 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -71,7 +71,7 @@ keyword_aliases = { #These can be used without any explicit conversion primitive_types = ["void", "bool", "int", "double", "size_t", "std::string", - "string", "State", "char_p", "std::source_location", "source_location"] + "string", "string_view", "std::string_view", "State", "char_p", "std::source_location", "source_location"] from enum import Enum @@ -557,6 +557,7 @@ class Attribute: default_value = None pos = None pos_counter = 0 + coerce_arg = None def __init__(self, wtype, varname, is_const = False, default_value = None): self.wtype = wtype @@ -566,7 +567,7 @@ class Attribute: self.container = None @staticmethod - def from_string(str_def, containing_file, line_number): + def from_string(str_def, containing_file, line_number, *, owner_fn_name=""): if len(str_def) < 3: return None orig = str_def @@ -630,6 +631,19 @@ class Attribute: else: arg.wtype.attr_type = attr_types.amp arg.varname = arg.varname[1:] + + # handle string views + if arg.wtype.name in ["std::string_view", "string_view"]: + if arg.varname == "format" and owner_fn_name.startswith("log_"): + # coerce format strings to "%s" (not bridgable) + arg.coerce_arg = '"%s"' + elif arg.varname == "prefix" and "warning" in owner_fn_name: + # coerce warning prefix to "warning:" + arg.coerce_arg = '"Warning: "' + else: + # boost::python can't bridge string views, so just copy them + arg.wtype.name = "string" + return arg #Generates the varname. If the attribute has no name in the header file, @@ -1391,7 +1405,7 @@ class WFunction: for i, arg in enumerate(args): if arg.strip() == "...": continue - parsed = Attribute.from_string(arg.strip(), containing_file, line_number) + parsed = Attribute.from_string(arg.strip(), containing_file, line_number, owner_fn_name=func.name) if parsed == None: return None # Only allow std::source_location as defaulted last argument, and @@ -1431,6 +1445,8 @@ class WFunction: text += "static " text += self.ret_type.gen_text() + " " + self.alias + "(" for arg in self.args: + if arg.coerce_arg: + continue text += arg.gen_listitem() text += ", " if len(self.args) > 0: @@ -1497,6 +1513,8 @@ class WFunction: text += self.member_of.name + "::" text += self.alias + "(" for arg in self.args: + if arg.coerce_arg: + continue text += arg.gen_listitem() text += ", " if len(self.args) > 0: @@ -1516,13 +1534,14 @@ class WFunction: if self.ret_type.name in classnames: text += self.ret_type.name + "::get_py_obj(" if self.member_of == None: - text += "::" + self.namespace + "::" + self.alias + "(" + text += "::" + self.namespace + "::" + self.name + "(" elif self.is_static: text += self.member_of.namespace + "::" + self.member_of.name + "::" + self.name + "(" else: text += "this->get_cpp_obj()->" + self.name + "(" for arg in self.args: - text += arg.gen_call() + ", " + text += arg.coerce_arg or arg.gen_call() + text += ", " if len(self.args) > 0: text = text[:-2] if self.ret_type.name in classnames: @@ -1639,6 +1658,8 @@ class WFunction: else: text += "(" + self.member_of.name + "::*)(" for a in self.args: + if a.coerce_arg: + continue text += a.gen_listitem_hash() + ", " if len(self.args) > 0: text = text[0:-2] + f"){self.gen_post_qualifiers(True)}>" @@ -2122,6 +2143,16 @@ def parse_header(source): if class_ == None: debug("\tFound unowned function \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces),2) unowned_functions.append(candidate) + + # generate log aliases + if candidate.name.startswith("log_formatted"): + alias = candidate.name.replace("log_formatted", "log") + if alias == "log_string": + alias = "log" + copied_candidate = copy.copy(candidate) + copied_candidate.alias = alias + unowned_functions.append(copied_candidate) + else: debug("\t\tFound function \"" + candidate.name + "\" of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2) class_[0].found_funs.append(candidate) @@ -2359,6 +2390,8 @@ def gen_wrappers(filename, debug_level_ = 0): #include USING_YOSYS_NAMESPACE +using std::string_view; + namespace YOSYS_PYTHON { [[noreturn]] static void log_python_exception_as_error() { diff --git a/passes/cmds/abstract.cc b/passes/cmds/abstract.cc index e475ba71c..88f07a5aa 100644 --- a/passes/cmds/abstract.cc +++ b/passes/cmds/abstract.cc @@ -53,7 +53,7 @@ struct Slice { } static void syntax_error(const std::string &slice) { - log_cmd_error("Invalid slice '%s', expected ':' or ''", slice.c_str()); + log_cmd_error("Invalid slice '%s', expected ':' or ''", slice); } std::string to_string() const { @@ -494,7 +494,7 @@ struct AbstractPass : public Pass { case Enable::ActiveHigh: { Wire *enable_wire = mod->wire("\\" + enable_name); if (!enable_wire) - log_cmd_error("Enable wire %s not found in module %s\n", enable_name.c_str(), mod->name.c_str()); + log_cmd_error("Enable wire %s not found in module %s\n", enable_name, mod->name); if (GetSize(enable_wire) != 1) log_cmd_error("Enable wire %s must have width 1 but has width %d in module %s\n", enable_name.c_str(), GetSize(enable_wire), mod->name.c_str()); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 0d395f043..1011a093c 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -77,7 +77,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n wire = nullptr; if (wire == nullptr) - log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str()); + log_cmd_error("Found incompatible object with same name in module %s!\n", module->name); log("Module %s already has such an object.\n", module->name); } diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index d48e25d68..8432c27fd 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -405,7 +405,11 @@ struct BugpointPass : public Pass { for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) { auto &mask = it2->priority_mask; if (GetSize(mask) > i) { - mask.bits().erase(mask.bits().begin() + i); + RTLIL::Const::Builder new_mask_builder(GetSize(mask) - 1); + for (int k = 0; k < GetSize(mask); k++) + if (k != i) + new_mask_builder.push_back(mask[k]); + mask = new_mask_builder.build(); } } return design_copy; diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index b532b4527..b7a5feb57 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -285,7 +285,7 @@ struct CheckPass : public Pass { } if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2)) \ - || RTLIL::builtin_ff_cell_types().count(cell->type)) { + || cell->is_builtin_ff()) { if (!edges_db.add_edges_from_cell(cell)) coarsened_cells.insert(cell); } @@ -323,7 +323,7 @@ struct CheckPass : public Pass { string message = stringf("Drivers conflicting with a constant %s driver:\n", log_signal(state)); for (auto str : wire_drivers[state]) message += stringf(" %s\n", str); - log_warning("%s", message.c_str()); + log_warning("%s", message); counter++; } @@ -332,7 +332,7 @@ struct CheckPass : public Pass { string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first)); for (auto str : it.second) message += stringf(" %s\n", str); - log_warning("%s", message.c_str()); + log_warning("%s", message); counter++; } @@ -418,7 +418,7 @@ struct CheckPass : public Pass { prev = bit; } - log_warning("%s", message.c_str()); + log_warning("%s", message); counter++; } @@ -426,7 +426,7 @@ struct CheckPass : public Pass { { for (auto cell : module->cells()) { - if (RTLIL::builtin_ff_cell_types().count(cell->type) == 0) + if (cell->is_builtin_ff() == 0) continue; for (auto bit : sigmap(cell->getPort(ID::Q))) diff --git a/passes/cmds/clean_zerowidth.cc b/passes/cmds/clean_zerowidth.cc index 48a8864c0..d48d3a958 100644 --- a/passes/cmds/clean_zerowidth.cc +++ b/passes/cmds/clean_zerowidth.cc @@ -73,7 +73,7 @@ struct CleanZeroWidthPass : public Pass { cell->unsetPort(it.first); } } - } else if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + } else if (cell->is_builtin_ff()) { // Coarse FF cells: remove if WIDTH == 0 (no outputs). // This will also trigger on fine cells, so use the Q port // width instead of actual WIDTH parameter. @@ -158,11 +158,11 @@ struct CleanZeroWidthPass : public Pass { continue; if (GetSize(memwr.address) == 0) memwr.address = State::S0; - Const priority_mask; + RTLIL::Const::Builder new_mask_bits(swizzle.size()); for (auto x : swizzle) { - priority_mask.bits().push_back(memwr.priority_mask[x]); + new_mask_bits.push_back(memwr.priority_mask[x]); } - memwr.priority_mask = priority_mask; + memwr.priority_mask = new_mask_bits.build(); swizzle.push_back(i); new_memwr_actions.push_back(memwr); } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 65292ef92..c6d3320ea 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -150,9 +150,9 @@ struct ConnectPass : public Pass { RTLIL::SigSpec sig_lhs, sig_rhs; if (!RTLIL::SigSpec::parse_sel(sig_lhs, design, module, set_lhs)) - log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs.c_str()); + log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs); if (!RTLIL::SigSpec::parse_rhs(sig_lhs, sig_rhs, module, set_rhs)) - log_cmd_error("Failed to parse set rhs expression `%s'.\n", set_rhs.c_str()); + log_cmd_error("Failed to parse set rhs expression `%s'.\n", set_rhs); sigmap.apply(sig_lhs); sigmap.apply(sig_rhs); @@ -173,7 +173,7 @@ struct ConnectPass : public Pass { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, unset_expr)) - log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr.c_str()); + log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr); sigmap.apply(sig); unset_drivers(design, module, sigmap, sig); @@ -185,11 +185,11 @@ struct ConnectPass : public Pass { log_cmd_error("Can't use -port together with -nounset.\n"); if (module->cell(RTLIL::escape_id(port_cell)) == nullptr) - log_cmd_error("Can't find cell %s.\n", port_cell.c_str()); + log_cmd_error("Can't find cell %s.\n", port_cell); RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) - log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); + log_cmd_error("Failed to parse port expression `%s'.\n", port_expr); if (!flag_assert) { module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index dbe23ccf1..5677c666d 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -42,7 +42,7 @@ struct ConnwrappersWorker decl_celltypes.insert(key.first); if (decls.count(key)) - log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + log_cmd_error("Duplicate port decl: %s %s\n", celltype, portname); portdecl_t decl; decl.widthparam = RTLIL::escape_id(widthparam); @@ -57,7 +57,7 @@ struct ConnwrappersWorker decl_celltypes.insert(key.first); if (decls.count(key)) - log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + log_cmd_error("Duplicate port decl: %s %s\n", celltype, portname); portdecl_t decl; decl.widthparam = RTLIL::escape_id(widthparam); diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index e3fb3a0e6..5a5835a43 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -45,10 +45,10 @@ struct CopyPass : public Pass { std::string trg_name = RTLIL::escape_id(args[2]); if (design->module(src_name) == nullptr) - log_cmd_error("Can't find source module %s.\n", src_name.c_str()); + log_cmd_error("Can't find source module %s.\n", src_name); if (design->module(trg_name) != nullptr) - log_cmd_error("Target module name %s already exists.\n", trg_name.c_str()); + log_cmd_error("Target module name %s already exists.\n", trg_name); RTLIL::Module *new_mod = design->module(src_name)->clone(); new_mod->name = trg_name; diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index bab00c287..7f217329c 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -118,7 +118,7 @@ struct CoverPass : public Pass { if (f == NULL) { for (auto f : out_files) fclose(f); - log_cmd_error("Can't create file %s%s.\n", args[argidx-1] == "-d" ? "in directory " : "", args[argidx].c_str()); + log_cmd_error("Can't create file %s%s.\n", args[argidx-1] == "-d" ? "in directory " : "", args[argidx]); } out_files.push_back(f); continue; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 59cd39c98..ddbd98bfd 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -165,13 +165,13 @@ struct DesignPass : public Pass { got_mode = true; load_name = args[++argidx]; if (saved_designs.count(load_name) == 0) - log_cmd_error("No saved design '%s' found!\n", load_name.c_str()); + log_cmd_error("No saved design '%s' found!\n", load_name); continue; } if (!got_mode && args[argidx] == "-copy-from" && argidx+1 < args.size()) { got_mode = true; if (saved_designs.count(args[++argidx]) == 0) - log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str()); + log_cmd_error("No saved design '%s' found!\n", args[argidx]); copy_from_design = saved_designs.at(args[argidx]); copy_to_design = design; continue; @@ -188,7 +188,7 @@ struct DesignPass : public Pass { got_mode = true; import_mode = true; if (saved_designs.count(args[++argidx]) == 0) - log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str()); + log_cmd_error("No saved design '%s' found!\n", args[argidx]); copy_from_design = saved_designs.at(args[argidx]); copy_to_design = design; as_name = args[argidx]; @@ -202,7 +202,7 @@ struct DesignPass : public Pass { got_mode = true; delete_name = args[++argidx]; if (saved_designs.count(delete_name) == 0) - log_cmd_error("No saved design '%s' found!\n", delete_name.c_str()); + log_cmd_error("No saved design '%s' found!\n", delete_name); continue; } break; diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index 068b5d7d9..0a306d113 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -430,7 +430,7 @@ struct DftTagWorker { return; } - if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { FfData ff(&initvals, cell); if (ff.has_clk || ff.has_gclk) @@ -686,7 +686,7 @@ struct DftTagWorker { return; } - if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { FfData ff(&initvals, cell); // TODO handle some more variants if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { @@ -884,8 +884,10 @@ struct DftTagWorker { { if (sig_a.is_fully_const()) { auto const_val = sig_a.as_const(); - for (State& bit : const_val.bits()) - bit = bit == State::S0 ? State::S1 : bit == State::S1 ? State::S0 : bit; + for (auto bit : const_val) { + State b = bit; + bit = b == State::S0 ? State::S1 : b == State::S1 ? State::S0 : b; + } return const_val; } return module->Not(name, sig_a); diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc index b346fc95d..ea82ff908 100644 --- a/passes/cmds/exec.cc +++ b/passes/cmds/exec.cc @@ -127,7 +127,7 @@ struct ExecPass : public Pass { x.re = YS_REGEX_COMPILE(args[argidx]); expect_stdout.push_back(x); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str()); + log_cmd_error("Error in regex expression '%s' !\n", args[argidx]); } } else if (args[argidx] == "-not-expect-stdout") { flag_expect_stdout = true; @@ -142,15 +142,15 @@ struct ExecPass : public Pass { x.polarity = false; expect_stdout.push_back(x); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str()); + log_cmd_error("Error in regex expression '%s' !\n", args[argidx]); } } else - log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.\n", args[argidx].c_str()); + log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.\n", args[argidx]); } } - log_header(design, "Executing command \"%s\".\n", cmd.c_str()); + log_header(design, "Executing command \"%s\".\n", cmd); log_push(); fflush(stdout); @@ -201,7 +201,7 @@ struct ExecPass : public Pass { if (flag_expect_stdout) for (auto &x : expect_stdout) if (x.polarity ^ x.matched) - log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str()); + log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str); log_pop(); } diff --git a/passes/cmds/future.cc b/passes/cmds/future.cc index 5dcf46bcf..81cc86bff 100644 --- a/passes/cmds/future.cc +++ b/passes/cmds/future.cc @@ -85,7 +85,7 @@ struct FutureWorker { if (found_driver->second.size() > 1) log_error("Found multiple drivers for future_ff target signal %s\n", log_signal(bit)); auto driver = *found_driver->second.begin(); - if (!RTLIL::builtin_ff_cell_types().count(driver.cell->type) && driver.cell->type != ID($anyinit)) + if (!driver.cell->is_builtin_ff() && driver.cell->type != ID($anyinit)) log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), log_id(driver.cell->type)); FfData ff(&initvals, driver.cell); diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index d7264d392..d906c241d 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -184,7 +184,7 @@ private: for(auto &cell : module->cells().to_vector()) { if (!cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_MUX_), ID($_NMUX_), ID($_NOT_), ID($anyconst), ID($allconst), ID($assume), ID($assert)) && module->design->module(cell->type) == nullptr) { - log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); + log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type); } if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_))) { const unsigned int A = 0, B = 1, Y = 2; diff --git a/passes/cmds/logcmd.cc b/passes/cmds/logcmd.cc index 57759fc90..dd2d708d8 100644 --- a/passes/cmds/logcmd.cc +++ b/passes/cmds/logcmd.cc @@ -107,7 +107,7 @@ struct LogPass : public Pass { if (to_stderr) fprintf(stderr, "%s%s", text.c_str(), line_end); if (to_log) { if (!header) log("%s%s", text, line_end); - else log_header(design, "%s%s", text.c_str(), line_end); + else log_header(design, "%s%s", text, line_end); } } } LogPass; diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index 37240bb7e..cab4ab81c 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -112,7 +112,7 @@ struct LoggerPass : public Pass { log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + log_cmd_error("Error in regex expression '%s' !\n", pattern); } continue; } @@ -124,7 +124,7 @@ struct LoggerPass : public Pass { log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + log_cmd_error("Error in regex expression '%s' !\n", pattern); } continue; } @@ -136,7 +136,7 @@ struct LoggerPass : public Pass { log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + log_cmd_error("Error in regex expression '%s' !\n", pattern); } continue; } @@ -188,7 +188,7 @@ struct LoggerPass : public Pass { else log_abort(); } catch (const std::regex_error& e) { - log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + log_cmd_error("Error in regex expression '%s' !\n", pattern); } continue; } diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 6c7921d53..afa830552 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -70,7 +70,7 @@ void load_plugin(std::string filename, std::vector aliases) if(module_p == NULL) { PyErr_Print(); - log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str()); + log_cmd_error("Can't load python module `%s'\n", full_path.filename()); return; } loaded_python_plugins[orig_filename] = module_p; @@ -100,7 +100,7 @@ void load_plugin(std::string filename, std::vector aliases) } if (hdl == NULL) - log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); + log_cmd_error("Can't load module `%s': %s\n", filename, dlerror()); loaded_plugins[orig_filename] = hdl; Pass::init_register(); diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index c4bb7135e..078ffb769 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -31,7 +31,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: to_name = RTLIL::escape_id(to_name); if (module->count_id(to_name)) - log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name.c_str(), module->name.c_str()); + log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name, module->name); RTLIL::Wire *wire_to_rename = module->wire(from_name); RTLIL::Cell *cell_to_rename = module->cell(from_name); @@ -55,7 +55,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: return; } - log_cmd_error("Object `%s' not found!\n", from_name.c_str()); + log_cmd_error("Object `%s' not found!\n", from_name); } static std::string derive_name_from_src(const std::string &src, int counter) @@ -632,7 +632,7 @@ struct RenamePass : public Pass { log("Renaming module %s to %s.\n", module_to_rename->name, to_name); design->rename(module_to_rename, to_name); } else - log_cmd_error("Object `%s' not found!\n", from_name.c_str()); + log_cmd_error("Object `%s' not found!\n", from_name); } } } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 7fcf5cfcd..6da15c19a 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -592,7 +592,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char while (pos < int(arg.size())) { if (arg[pos] != ':' || pos+1 == int(arg.size())) - log_cmd_error("Syntax error in expand operator '%s'.\n", arg.c_str()); + log_cmd_error("Syntax error in expand operator '%s'.\n", arg); pos++; if (arg[pos] == '+' || arg[pos] == '-') { expand_rule_t rule; @@ -617,7 +617,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char for (auto i2 : i1.second) limits.insert(i2); } else - log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str).c_str()); + log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str)); } else limits.insert(RTLIL::escape_id(str)); } @@ -658,7 +658,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char } if (rem_objects == 0) - log_warning("reached configured limit at `%s'.\n", arg.c_str()); + log_warning("reached configured limit at `%s'.\n", arg); } static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel) @@ -804,7 +804,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp log_cmd_error("Must have at least one element on the stack for operator %%coe.\n"); select_op_expand(design, arg, 'o', true); } else - log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str()); + log_cmd_error("Unknown selection operator '%s'.\n", arg); if (work_stack.size() >= 1) select_filter_active_mod(design, work_stack.back()); return; @@ -815,7 +815,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (design->selection_vars.count(set_name) > 0) work_stack.push_back(design->selection_vars[set_name]); else - log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str()); + log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name)); select_filter_active_mod(design, work_stack.back()); return; } @@ -934,7 +934,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg_memb.compare(2, 1, "@") == 0) { std::string set_name = RTLIL::escape_id(arg_memb.substr(3)); if (!design->selection_vars.count(set_name)) - log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str()); + log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name)); auto &muster = design->selection_vars[set_name]; for (auto cell : mod->cells()) @@ -1002,14 +1002,14 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (it.second == false && !disable_empty_warning) { std::string selection_str = select_blackboxes ? "=" : ""; selection_str += it.first; - log_warning("Selection \"%s\" did not match any module.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any module.\n", selection_str); } } for (auto &it : arg_memb_found) { if (it.second == false && !disable_empty_warning) { std::string selection_str = select_blackboxes ? "=" : ""; selection_str += it.first; - log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any object.\n", selection_str); } } } @@ -1428,7 +1428,7 @@ struct SelectPass : public Pass { continue; } if (arg.size() > 0 && arg[0] == '-') - log_cmd_error("Unknown option %s.\n", arg.c_str()); + log_cmd_error("Unknown option %s.\n", arg); bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_modcount != -1) || (assert_count != -1) || (assert_max != -1) || (assert_min != -1); select_stmt(design, arg, disable_empty_warning); @@ -1451,7 +1451,7 @@ struct SelectPass : public Pass { while (std::getline(f, line)) { size_t slash_pos = line.find('/'); if (slash_pos == string::npos) { - log_warning("Ignoring line without slash in 'select -read': %s\n", line.c_str()); + log_warning("Ignoring line without slash in 'select -read': %s\n", line); continue; } IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos)); @@ -1762,7 +1762,7 @@ struct CdPass : public Pass { return; } - log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname).c_str()); + log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname)); } } CdPass; diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index f590c2fa9..25d8fd34c 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -39,7 +39,7 @@ struct setunset_t } else { RTLIL::SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value)) - log_cmd_error("Can't decode value '%s'!\n", set_value.c_str()); + log_cmd_error("Can't decode value '%s'!\n", set_value); value = sig_value.as_const(); } } diff --git a/passes/cmds/setenv.cc b/passes/cmds/setenv.cc index 850d7c961..90eeab702 100644 --- a/passes/cmds/setenv.cc +++ b/passes/cmds/setenv.cc @@ -52,7 +52,7 @@ struct SetenvPass : public Pass { _putenv_s(name.c_str(), value.c_str()); #else if (setenv(name.c_str(), value.c_str(), 1)) - log_cmd_error("Invalid name \"%s\".\n", name.c_str()); + log_cmd_error("Invalid name \"%s\".\n", name); #endif } diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index c4a555e6a..5d2ccfcc8 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -243,7 +243,7 @@ struct SetundefPass : public Pass { { for (auto *cell : module->selected_cells()) { for (auto ¶meter : cell->parameters) { - for (auto &bit : parameter.second.bits()) { + for (auto bit : parameter.second) { if (bit > RTLIL::State::S1) bit = worker.next_bit(); } @@ -364,7 +364,7 @@ struct SetundefPass : public Pass { for (auto cell : module->cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; for (auto bit : sigmap(cell->getPort(ID::Q))) @@ -390,12 +390,12 @@ struct SetundefPass : public Pass { for (auto wire : initwires) { Const &initval = wire->attributes[ID::init]; - initval.bits().resize(GetSize(wire), State::Sx); + initval.resize(GetSize(wire), State::Sx); for (int i = 0; i < GetSize(wire); i++) { SigBit bit = sigmap(SigBit(wire, i)); if (initval[i] == State::Sx && ffbits.count(bit)) { - initval.bits()[i] = worker.next_bit(); + initval.set(i, worker.next_bit()); ffbits.erase(bit); } } @@ -421,7 +421,7 @@ struct SetundefPass : public Pass { continue; Const &initval = wire->attributes[ID::init]; - initval.bits().resize(GetSize(wire), State::Sx); + initval.resize(GetSize(wire), State::Sx); if (initval.is_fully_undef()) { wire->attributes.erase(ID::init); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index c2d446162..d0d9c0f85 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -926,7 +926,7 @@ struct ShowPass : public Pass { if (f == nullptr) { for (auto lib : libs) delete lib; - log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str()); + log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file); } ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_wireshape, flag_signed, flag_stretch, flag_enum, flag_abbreviate, flag_notitle, flag_href, color_selections, label_selections, colorattr); fclose(f); diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index f142e3092..fac5d97a0 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -75,10 +75,11 @@ struct SplitnetsWorker it = wire->attributes.find(ID::init); if (it != wire->attributes.end()) { - Const old_init = it->second, new_init; + Const old_init = it->second; + RTLIL::Const::Builder new_init_bits_builder(width); for (int i = offset; i < offset+width; i++) - new_init.bits().push_back(i < GetSize(old_init) ? old_init.at(i) : State::Sx); - new_wire->attributes.emplace(ID::init, new_init); + new_init_bits_builder.push_back(i < GetSize(old_init) ? old_init.at(i) : State::Sx); + new_wire->attributes.emplace(ID::init, new_init_bits_builder.build()); } std::vector sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector(); diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 8fa348553..23c2a060b 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -477,9 +477,9 @@ struct StatPass : public Pass { techname = args[++argidx]; continue; } - if (args[argidx] == "-top" && argidx+1 < args.size()) { - if (design->module(RTLIL::escape_id(args[argidx+1])) == nullptr) - log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str()); + if (args[argidx] == "-top" && argidx + 1 < args.size()) { + if (design->module(RTLIL::escape_id(args[argidx + 1])) == nullptr) + log_cmd_error("Can't find module %s.\n", args[argidx + 1]); top_mod = design->module(RTLIL::escape_id(args[++argidx])); continue; } @@ -495,7 +495,7 @@ struct StatPass : public Pass { log_header(design, "Printing statistics.\n"); if (techname != "" && techname != "xilinx" && techname != "cmos" && !json_mode) - log_cmd_error("Unsupported technology: '%s'\n", techname.c_str()); + log_cmd_error("Unsupported technology: '%s'\n", techname); if (json_mode) { log("{\n"); diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index fbd42e311..cef94b9ce 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -83,7 +83,7 @@ struct TeePass : public Pass { if (f == NULL) { for (auto cf : files_to_close) fclose(cf); - log_cmd_error("Can't create file %s.\n", args[argidx].c_str()); + log_cmd_error("Can't create file %s.\n", args[argidx]); } log_files.push_back(f); files_to_close.push_back(f); diff --git a/passes/cmds/timeest.cc b/passes/cmds/timeest.cc index 86a529520..ce9c628f4 100644 --- a/passes/cmds/timeest.cc +++ b/passes/cmds/timeest.cc @@ -88,7 +88,7 @@ struct EstimateSta { for (auto cell : m->cells()) { SigSpec launch, sample; - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { // collect launch and sample points for FF cell FfData ff(nullptr, cell); if (!ff.has_clk) { @@ -403,7 +403,7 @@ struct TimeestPass : Pass { for (auto m : d->selected_modules()) { if (!m->wire(RTLIL::escape_id(clk))) { - log_warning("No domain '%s' in module %s\n", clk.c_str(), log_id(m)); + log_warning("No domain '%s' in module %s\n", clk, log_id(m)); continue; } diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index fd45d6ba0..e3b09d029 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -994,7 +994,7 @@ struct VizPass : public Pass { if (f != nullptr) return; f = fopen(dot_file.c_str(), "w"); if (f == nullptr) - log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str()); + log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file); }; for (auto module : modlist) { VizWorker worker(module, config); diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 186e5eec0..7291bb859 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -302,7 +302,7 @@ struct XpropWorker return; } - if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { FfData ff(&initvals, cell); if (cell->type != ID($anyinit)) @@ -828,9 +828,9 @@ struct XpropWorker auto init_q_is_1 = init_q; auto init_q_is_x = init_q; - for (auto &bit : init_q_is_1.bits()) + for (auto bit : init_q_is_1) bit = bit == State::S1 ? State::S1 : State::S0; - for (auto &bit : init_q_is_x.bits()) + for (auto bit : init_q_is_x) bit = bit == State::Sx ? State::S1 : State::S0; initvals.remove_init(sig_q); @@ -853,7 +853,7 @@ struct XpropWorker return; } - if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { FfData ff(&initvals, cell); if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { @@ -865,14 +865,14 @@ struct XpropWorker auto init_q_is_x = init_q; if (ff.is_anyinit) { - for (auto &bit : init_q_is_1.bits()) + for (auto bit : init_q_is_1) bit = State::Sx; - for (auto &bit : init_q_is_x.bits()) + for (auto bit : init_q_is_x) bit = State::S0; } else { - for (auto &bit : init_q_is_1.bits()) + for (auto bit : init_q_is_1) bit = bit == State::S1 ? State::S1 : State::S0; - for (auto &bit : init_q_is_x.bits()) + for (auto bit : init_q_is_x) bit = bit == State::Sx ? State::S1 : State::S0; } diff --git a/passes/equiv/equiv_add.cc b/passes/equiv/equiv_add.cc index 1bcd4a887..b3c97fa80 100644 --- a/passes/equiv/equiv_add.cc +++ b/passes/equiv/equiv_add.cc @@ -61,18 +61,18 @@ struct EquivAddPass : public Pass { if (gold_cell == nullptr) { if (try_mode) { - log_warning("Can't find gold cell '%s'.\n", args[2].c_str()); + log_warning("Can't find gold cell '%s'.\n", args[2]); return; } - log_cmd_error("Can't find gold cell '%s'.\n", args[2].c_str()); + log_cmd_error("Can't find gold cell '%s'.\n", args[2]); } if (gate_cell == nullptr) { if (try_mode) { - log_warning("Can't find gate cell '%s'.\n", args[3].c_str()); + log_warning("Can't find gate cell '%s'.\n", args[3]); return; } - log_cmd_error("Can't find gate cell '%s'.\n", args[3].c_str()); + log_cmd_error("Can't find gate cell '%s'.\n", args[3]); } for (auto conn : gold_cell->connections()) @@ -126,18 +126,18 @@ struct EquivAddPass : public Pass { if (!SigSpec::parse(gate_signal, module, args[2])) { if (try_mode) { - log_warning("Error in gate signal: %s\n", args[2].c_str()); + log_warning("Error in gate signal: %s\n", args[2]); return; } - log_cmd_error("Error in gate signal: %s\n", args[2].c_str()); + log_cmd_error("Error in gate signal: %s\n", args[2]); } if (!SigSpec::parse_rhs(gate_signal, gold_signal, module, args[1])) { if (try_mode) { - log_warning("Error in gold signal: %s\n", args[1].c_str()); + log_warning("Error in gold signal: %s\n", args[1]); return; } - log_cmd_error("Error in gold signal: %s\n", args[1].c_str()); + log_cmd_error("Error in gold signal: %s\n", args[1]); } log_assert(GetSize(gold_signal) == GetSize(gate_signal)); diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index 1995be3cd..e1a3a7990 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -56,7 +56,7 @@ struct EquivInductWorker for (auto cell : cells) { if (!satgen.importCell(cell, step) && !cell_warn_cache.count(cell)) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) log_warning("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); else log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 9b10817d4..207c4cd2e 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -48,7 +48,7 @@ struct EquivMakeWorker { std::ifstream f(fn); if (f.fail()) - log_cmd_error("Can't open blacklist file '%s'!\n", fn.c_str()); + log_cmd_error("Can't open blacklist file '%s'!\n", fn); string line, token; while (std::getline(f, line)) { @@ -68,7 +68,7 @@ struct EquivMakeWorker { std::ifstream f(fn); if (f.fail()) - log_cmd_error("Can't open encfile '%s'!\n", fn.c_str()); + log_cmd_error("Can't open encfile '%s'!\n", fn); dict *ed = nullptr; string line, token; @@ -82,7 +82,7 @@ struct EquivMakeWorker IdString modname = RTLIL::escape_id(next_token(line)); IdString signame = RTLIL::escape_id(next_token(line)); if (encdata.count(signame)) - log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame.c_str(), fn.c_str()); + log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn); encdata[signame] = dict(); ed = &encdata[signame]; continue; @@ -95,7 +95,7 @@ struct EquivMakeWorker continue; } - log_cmd_error("Syntax error in encfile '%s'!\n", fn.c_str()); + log_cmd_error("Syntax error in encfile '%s'!\n", fn); } } } @@ -502,13 +502,13 @@ struct EquivMakePass : public Pass { worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2])); if (worker.gold_mod == nullptr) - log_cmd_error("Can't find gold module %s.\n", args[argidx].c_str()); + log_cmd_error("Can't find gold module %s.\n", args[argidx]); if (worker.gate_mod == nullptr) - log_cmd_error("Can't find gate module %s.\n", args[argidx+1].c_str()); + log_cmd_error("Can't find gate module %s.\n", args[argidx+1]); if (worker.equiv_mod != nullptr) - log_cmd_error("Equiv module %s already exists.\n", args[argidx+2].c_str()); + log_cmd_error("Equiv module %s already exists.\n", args[argidx+2]); if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 9e3076077..97f95ac63 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -93,7 +93,7 @@ struct EquivSimpleWorker for (auto &conn : cell->connections()) if (yosys_celltypes.cell_input(cell->type, conn.first)) for (auto bit : model.sigmap(conn.second)) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { if (!conn.first.in(ID::CLK, ID::C)) next_seed.insert(bit); } else @@ -231,7 +231,7 @@ struct EquivSimpleWorker static void report_missing_model(Cell* cell) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) log_cmd_error("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); else log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 86d654cc4..9cffbf95a 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -225,7 +225,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false) if (!warnings.empty()) { string warnmsg = stringf("Regarding the user-specified fsm_encoding attribute on %s.%s:\n", log_id(wire->module), log_id(wire)); for (auto w : warnings) warnmsg += " " + w; - log_warning("%s", warnmsg.c_str()); + log_warning("%s", warnmsg); } else { log("FSM state register %s.%s already has fsm_encoding attribute.\n", log_id(wire->module), log_id(wire)); } diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index d83cff5cdc..43a797ff4 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -171,7 +171,7 @@ undef_bit_in_next_state: if (tr.ctrl_in.at(it.second) == State::S1 && exclusive_ctrls.count(it.first) != 0) for (auto &dc_bit : exclusive_ctrls.at(it.first)) if (ctrl_in_bit_indices.count(dc_bit)) - tr.ctrl_in.bits().at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa; + tr.ctrl_in.set(ctrl_in_bit_indices.at(dc_bit), RTLIL::State::Sa); RTLIL::Const log_state_in = RTLIL::Const(RTLIL::State::Sx, fsm_data.state_bits); if (state_in >= 0) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 8a18d259a..c19edcc88 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -176,7 +176,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) state_dff->type = ID($adff); state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY]; state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state]; - for (auto &bit : state_dff->parameters[ID::ARST_VALUE].bits()) + for (auto bit : state_dff->parameters[ID::ARST_VALUE]) if (bit != RTLIL::State::S1) bit = RTLIL::State::S0; state_dff->setPort(ID::ARST, fsm_cell->getPort(ID::ARST)); diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 99771f90a..b61dec890 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -169,13 +169,16 @@ struct FsmOpt for (auto tr : fsm_data.transition_table) { - RTLIL::State &si = tr.ctrl_in.bits()[i]; - RTLIL::State &sj = tr.ctrl_in.bits()[j]; + RTLIL::State si = tr.ctrl_in[i]; + RTLIL::State sj = tr.ctrl_in[j]; - if (si > RTLIL::State::S1) + if (si > RTLIL::State::S1) { si = sj; - else if (sj > RTLIL::State::S1) + tr.ctrl_in.set(i, si); + } else if (sj > RTLIL::State::S1) { sj = si; + tr.ctrl_in.set(j, sj); + } if (si == sj) { RTLIL::SigSpec tmp(tr.ctrl_in); @@ -207,8 +210,8 @@ struct FsmOpt for (auto tr : fsm_data.transition_table) { - RTLIL::State &si = tr.ctrl_in.bits()[i]; - RTLIL::State &sj = tr.ctrl_out.bits()[j]; + RTLIL::State si = tr.ctrl_in[i]; + RTLIL::State sj = tr.ctrl_out[j]; if (si > RTLIL::State::S1 || si == sj) { RTLIL::SigSpec tmp(tr.ctrl_in); @@ -240,14 +243,14 @@ struct FsmOpt RTLIL::Const other_pattern = pattern; if (pattern[bit] == RTLIL::State::S1) - other_pattern.bits()[bit] = RTLIL::State::S0; + other_pattern.set(bit, RTLIL::State::S0); else - other_pattern.bits()[bit] = RTLIL::State::S1; + other_pattern.set(bit, RTLIL::State::S1); if (set.count(other_pattern) > 0) { log(" Merging pattern %s and %s from group (%d %d %s).\n", log_signal(pattern), log_signal(other_pattern), tr.state_in, tr.state_out, log_signal(tr.ctrl_out)); - other_pattern.bits()[bit] = RTLIL::State::Sa; + other_pattern.set(bit, RTLIL::State::Sa); new_set.insert(other_pattern); did_something = true; continue; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 8ee03329f..e4cd53a07 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -106,7 +106,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs if (encoding == "one-hot") { new_code = RTLIL::Const(RTLIL::State::Sa, fsm_data.state_bits); - new_code.bits()[state_idx] = RTLIL::State::S1; + new_code.set(state_idx, RTLIL::State::S1); } else if (encoding == "binary") { new_code = RTLIL::Const(state_idx, fsm_data.state_bits); diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 9aa12241e..4d824e136 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -45,35 +45,27 @@ struct FsmData cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size()); cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2); cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state); - cell->parameters[ID::STATE_TABLE] = RTLIL::Const(); - - for (int i = 0; i < int(state_table.size()); i++) { - std::vector &bits_table = cell->parameters[ID::STATE_TABLE].bits(); - std::vector &bits_state = state_table[i].bits(); - bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end()); - } + RTLIL::Const cell_state_table; + for (const RTLIL::Const &c : state_table) + cell_state_table.append(c); + cell->parameters[ID::STATE_TABLE] = std::move(cell_state_table); cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size()); - cell->parameters[ID::TRANS_TABLE] = RTLIL::Const(); + RTLIL::Const cell_trans_table; for (int i = 0; i < int(transition_table.size()); i++) { - std::vector &bits_table = cell->parameters[ID::TRANS_TABLE].bits(); transition_t &tr = transition_table[i]; RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2); RTLIL::Const const_state_out = RTLIL::Const(tr.state_out, state_num_log2); - std::vector &bits_state_in = const_state_in.bits(); - std::vector &bits_state_out = const_state_out.bits(); - - std::vector &bits_ctrl_in = tr.ctrl_in.bits(); - std::vector &bits_ctrl_out = tr.ctrl_out.bits(); // append lsb first - bits_table.insert(bits_table.end(), bits_ctrl_out.begin(), bits_ctrl_out.end()); - bits_table.insert(bits_table.end(), bits_state_out.begin(), bits_state_out.end()); - bits_table.insert(bits_table.end(), bits_ctrl_in.begin(), bits_ctrl_in.end()); - bits_table.insert(bits_table.end(), bits_state_in.begin(), bits_state_in.end()); + cell_trans_table.append(tr.ctrl_out); + cell_trans_table.append(const_state_out); + cell_trans_table.append(tr.ctrl_in); + cell_trans_table.append(const_state_in); } + cell->parameters[ID::TRANS_TABLE] = std::move(cell_trans_table); } void copy_from_cell(RTLIL::Cell *cell) @@ -95,25 +87,18 @@ struct FsmData const RTLIL::Const &trans_table = cell->parameters[ID::TRANS_TABLE]; for (int i = 0; i < state_num; i++) { - RTLIL::Const state_code; - int off_begin = i*state_bits, off_end = off_begin + state_bits; - state_code.bits().insert(state_code.bits().begin(), state_table.begin()+off_begin, state_table.begin()+off_end); + int off_begin = i*state_bits; + RTLIL::Const state_code = state_table.extract(off_begin, state_bits); this->state_table.push_back(state_code); } for (int i = 0; i < trans_num; i++) { - auto off_ctrl_out = trans_table.begin() + i*(num_inputs+num_outputs+2*state_num_log2); - auto off_state_out = off_ctrl_out + num_outputs; - auto off_ctrl_in = off_state_out + state_num_log2; - auto off_state_in = off_ctrl_in + num_inputs; - auto off_end = off_state_in + state_num_log2; - - RTLIL::Const state_in, state_out, ctrl_in, ctrl_out; - ctrl_out.bits().insert(ctrl_out.bits().begin(), off_ctrl_out, off_state_out); - state_out.bits().insert(state_out.bits().begin(), off_state_out, off_ctrl_in); - ctrl_in.bits().insert(ctrl_in.bits().begin(), off_ctrl_in, off_state_in); - state_in.bits().insert(state_in.bits().begin(), off_state_in, off_end); + int base_offset = i*(num_inputs+num_outputs+2*state_num_log2); + RTLIL::Const ctrl_out = trans_table.extract(base_offset, num_outputs); + RTLIL::Const state_out = trans_table.extract(base_offset + num_outputs, state_num_log2); + RTLIL::Const ctrl_in = trans_table.extract(base_offset + num_outputs + state_num_log2, num_inputs); + RTLIL::Const state_in = trans_table.extract(base_offset + num_outputs + state_num_log2 + num_inputs, state_num_log2); transition_t tr; tr.state_in = state_in.as_int(); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 7a2c7e00f..2faeb25d0 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -937,7 +937,7 @@ struct HierarchyPass : public Pass { const std::string &value = args[++argidx]; auto r = parameters.emplace(key, value); if (!r.second) { - log_warning("-chparam %s already specified: overwriting.\n", key.c_str()); + log_warning("-chparam %s already specified: overwriting.\n", key); r.first->second = value; } continue; @@ -957,7 +957,7 @@ struct HierarchyPass : public Pass { for (auto ¶ : parameters) { SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) - log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + log_cmd_error("Can't decode value '%s'!\n", para.second); top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); } } @@ -991,7 +991,7 @@ struct HierarchyPass : public Pass { } #endif if (top_mod == NULL) - log_cmd_error("Module `%s' not found!\n", load_top_mod.c_str()); + log_cmd_error("Module `%s' not found!\n", load_top_mod); } else { #ifdef YOSYS_ENABLE_VERIFIC if (verific_import_pending) @@ -1045,7 +1045,7 @@ struct HierarchyPass : public Pass { for (auto ¶ : parameters) { SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) - log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + log_cmd_error("Can't decode value '%s'!\n", para.second); top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); } diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 1d2e9948f..d1479bec5 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -80,7 +80,7 @@ struct SubmodWorker flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used); if (set_int_driven) for (int i = c.offset; i < c.offset+c.width; i++) { - wire_flags.at(c.wire).is_int_driven.bits()[i] = State::S1; + wire_flags.at(c.wire).is_int_driven.set(i, State::S1); flag_found_something = true; } } @@ -97,7 +97,7 @@ struct SubmodWorker for (auto &conn : cell->connections()) flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first), false, false); } else { - log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); + log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name, cell->type); for (auto &conn : cell->connections()) flag_signal(conn.second, true, true, true, false, false); } @@ -113,7 +113,7 @@ struct SubmodWorker for (auto &conn : cell->connections()) flag_signal(conn.second, false, false, false, true, true); if (flag_found_something) - log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); + log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name, cell->type); } } @@ -187,8 +187,8 @@ struct SubmodWorker auto it = sig[i].wire->attributes.find(ID::init); if (it != sig[i].wire->attributes.end()) { auto jt = new_wire->attributes.insert(std::make_pair(ID::init, Const(State::Sx, GetSize(sig)))).first; - jt->second.bits()[i] = it->second[sig[i].offset]; - it->second.bits()[sig[i].offset] = State::Sx; + jt->second.set(i, it->second[sig[i].offset]); + it->second.set(sig[i].offset, State::Sx); } } } @@ -430,7 +430,7 @@ struct SubmodPass : public Pass { RTLIL::Module *module = nullptr; for (auto mod : design->selected_modules()) { if (module != nullptr) - log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod->name.c_str()); + log_cmd_error("More than one module selected: %s %s\n", module->name, mod->name); module = mod; } if (module == nullptr) diff --git a/passes/memory/memlib.cc b/passes/memory/memlib.cc index 216b750fd..11c9f9074 100644 --- a/passes/memory/memlib.cc +++ b/passes/memory/memlib.cc @@ -1097,7 +1097,7 @@ Library MemLibrary::parse_library(const std::vector &filenames, con Parser(file, res, defines, defines_unused); } for (auto def: defines_unused) { - log_warning("define %s not used in the library.\n", def.c_str()); + log_warning("define %s not used in the library.\n", def); } return res; } diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 8ef2c4271..10301b44a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -848,9 +848,9 @@ grow_read_ports:; for (int i = 0; i < mem.width; i++) if (shuffle_map[i] != -1) { module->connect(port.data[shuffle_map[i]], new_data[i]); - new_init_value.bits()[i] = port.init_value[shuffle_map[i]]; - new_arst_value.bits()[i] = port.arst_value[shuffle_map[i]]; - new_srst_value.bits()[i] = port.srst_value[shuffle_map[i]]; + new_init_value.set(i, port.init_value[shuffle_map[i]]); + new_arst_value.set(i, port.arst_value[shuffle_map[i]]); + new_srst_value.set(i, port.srst_value[shuffle_map[i]]); } port.data = new_data; port.init_value = new_init_value; @@ -887,9 +887,9 @@ grow_read_ports:; for (int i = 0; i < init_size; i++) for (int j = 0; j < bram.dbits; j++) if (init_offset+i < GetSize(initdata) && init_offset+i >= 0) - initparam.bits()[i*bram.dbits+j] = initdata[init_offset+i][init_shift+j]; + initparam.set(i*bram.dbits+j, initdata[init_offset+i][init_shift+j]); else - initparam.bits()[i*bram.dbits+j] = State::Sx; + initparam.set(i*bram.dbits+j, State::Sx); c->setParam(ID::INIT, initparam); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 76dff7ee9..86a0cdd64 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -60,16 +60,17 @@ struct MemoryShareWorker bool merge_rst_value(Mem &mem, Const &res, int wide_log2, const Const &src1, int sub1, const Const &src2, int sub2) { res = Const(State::Sx, mem.width << wide_log2); for (int i = 0; i < GetSize(src1); i++) - res.bits()[i + sub1 * mem.width] = src1[i]; + res.set(i + sub1 * mem.width, src1[i]); for (int i = 0; i < GetSize(src2); i++) { if (src2[i] == State::Sx) continue; - auto &dst = res.bits()[i + sub2 * mem.width]; + int idx = i + sub2 * mem.width; + RTLIL::State dst = res[idx]; if (dst == src2[i]) continue; if (dst != State::Sx) return false; - dst = src2[i]; + res.set(idx, src2[i]); } return true; } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 8b382acf6..e18ad2715 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -206,7 +206,7 @@ void rmunused_module_cells(Module *module, bool verbose) if (verbose) log_debug(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str()); module->design->scratchpad_set_bool("opt.did_something", true); - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) ffinit.remove_init(cell->getPort(ID::Q)); module->remove(cell); count_rm_cells++; @@ -233,7 +233,7 @@ void rmunused_module_cells(Module *module, bool verbose) for (auto it : driver_driver_logs) { if (used_raw_bits.count(it.first)) for (auto msg : it.second) - log_warning("%s\n", msg.c_str()); + log_warning("%s\n", msg); } } @@ -406,7 +406,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused for (int i = 0; i < wire->width; i++) { auto it = init_bits.find(RTLIL::SigBit(wire, i)); if (it != init_bits.end()) { - val.bits()[i] = it->second; + val.set(i, it->second); found = true; } } @@ -425,7 +425,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused if (wire->attributes.count(ID::init)) initval = wire->attributes.at(ID::init); if (GetSize(initval) != GetSize(wire)) - initval.bits().resize(GetSize(wire), State::Sx); + initval.resize(GetSize(wire), State::Sx); if (initval.is_fully_undef()) wire->attributes.erase(ID::init); @@ -457,7 +457,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused if (s1[i] != s2[i]) { if (s2[i] == State::Sx && (initval[i] == State::S0 || initval[i] == State::S1)) { s2[i] = initval[i]; - initval.bits()[i] = State::Sx; + initval.set(i, State::Sx); } new_conn.first.append(s1[i]); new_conn.second.append(s2[i]); @@ -600,15 +600,40 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool unusedbitsattr log("Finding unused cells or wires in module %s..\n", module->name); std::vector delcells; - for (auto cell : module->cells()) + for (auto cell : module->cells()) { if (cell->type.in(ID($pos), ID($_BUF_), ID($buf)) && !cell->has_keep_attr()) { bool is_signed = cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool(); RTLIL::SigSpec a = cell->getPort(ID::A); RTLIL::SigSpec y = cell->getPort(ID::Y); a.extend_u0(GetSize(y), is_signed); - module->connect(y, a); + + if (a.has_const(State::Sz)) { + SigSpec new_a; + SigSpec new_y; + for (int i = 0; i < GetSize(a); ++i) { + SigBit b = a[i]; + if (b == State::Sz) + continue; + new_a.append(b); + new_y.append(y[i]); + } + a = std::move(new_a); + y = std::move(new_y); + } + if (!y.empty()) + module->connect(y, a); + delcells.push_back(cell); + } else if (cell->type.in(ID($connect)) && !cell->has_keep_attr()) { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); + if (a.has_const() && !b.has_const()) + std::swap(a, b); + module->connect(a, b); + delcells.push_back(cell); + } else if (cell->type.in(ID($input_port)) && !cell->has_keep_attr()) { delcells.push_back(cell); } + } for (auto cell : delcells) { if (verbose) log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(), diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index f36e1053e..799bd67b7 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -89,7 +89,7 @@ struct OptDffWorker } } - if (module->design->selected(module, cell) && RTLIL::builtin_ff_cell_types().count(cell->type)) + if (module->design->selected(module, cell) && cell->is_builtin_ff()) dff_cells.push_back(cell); } @@ -409,27 +409,29 @@ struct OptDffWorker } else if (ff.pol_clr == ff.pol_set) { // Try a more complex conversion to plain async reset. State val_neutral = ff.pol_set ? State::S0 : State::S1; - Const val_arst; SigBit sig_arst; if (ff.sig_clr[0] == val_neutral) sig_arst = ff.sig_set[0]; else sig_arst = ff.sig_clr[0]; bool failed = false; + Const::Builder val_arst_builder(ff.width); for (int i = 0; i < ff.width; i++) { if (ff.sig_clr[i] == sig_arst && ff.sig_set[i] == val_neutral) - val_arst.bits().push_back(State::S0); + val_arst_builder.push_back(State::S0); else if (ff.sig_set[i] == sig_arst && ff.sig_clr[i] == val_neutral) - val_arst.bits().push_back(State::S1); - else + val_arst_builder.push_back(State::S1); + else { failed = true; + break; + } } if (!failed) { log_debug("Converting CLR/SET to ARST on %s (%s) from module %s.\n", log_id(cell), log_id(cell->type), log_id(module)); ff.has_sr = false; ff.has_arst = true; - ff.val_arst = val_arst; + ff.val_arst = val_arst_builder.build(); ff.sig_arst = sig_arst; ff.pol_arst = ff.pol_clr; changed = true; @@ -648,7 +650,7 @@ struct OptDffWorker std::map> groups; std::vector remaining_indices; std::vector new_cells; - Const val_srst; + Const::Builder val_srst_builder(ff.width); for (int i = 0 ; i < ff.width; i++) { ctrls_t resets; @@ -690,17 +692,19 @@ struct OptDffWorker groups[resets].push_back(i); } else remaining_indices.push_back(i); - val_srst.bits().push_back(reset_val); + val_srst_builder.push_back(reset_val); } + Const val_srst = val_srst_builder.build(); for (auto &it : groups) { FfData new_ff = ff.slice(it.second); - new_ff.val_srst = Const(); + Const::Builder new_val_srst_builder(new_ff.width); for (int i = 0; i < new_ff.width; i++) { int j = it.second[i]; - new_ff.val_srst.bits().push_back(val_srst[j]); + new_val_srst_builder.push_back(val_srst[j]); } - ctrl_t srst = combine_resets(it.first, ff.is_fine, module, cell); + new_ff.val_srst = new_val_srst_builder.build(); + ctrl_t srst = combine_resets(it.first, ff.is_fine); new_ff.has_srst = true; new_ff.sig_srst = srst.first; @@ -820,7 +824,7 @@ struct OptDffWorker bool did_something = false; for (auto cell : module->selected_cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index f47457c8e..865b7cecc 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -83,7 +83,7 @@ void replace_undriven(RTLIL::Module *module, const CellTypes &ct) auto cursor = initbits.find(bit); if (cursor != initbits.end()) { revisit_initwires.insert(cursor->second.first); - val.bits()[i] = cursor->second.second; + val.set(i, cursor->second.second); } } @@ -101,7 +101,7 @@ void replace_undriven(RTLIL::Module *module, const CellTypes &ct) Const initval = wire->attributes.at(ID::init); for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) { if (SigBit(initval[i]) == sig[i]) - initval.bits()[i] = State::Sx; + initval.set(i, State::Sx); } if (initval.is_fully_undef()) { log_debug("Removing init attribute from %s/%s.\n", log_id(module), log_id(wire)); diff --git a/passes/opt/opt_ffinv.cc b/passes/opt/opt_ffinv.cc index 52e180a20..42d6da49b 100644 --- a/passes/opt/opt_ffinv.cc +++ b/passes/opt/opt_ffinv.cc @@ -96,10 +96,10 @@ struct OptFfInvWorker } } Const mask = lut->getParam(ID::LUT); - Const new_mask; - for (int j = 0; j < (1 << GetSize(sig_a)); j++) { - new_mask.bits().push_back(mask[j ^ flip_mask]); - } + Const::Builder new_mask_builder(1 << GetSize(sig_a)); + for (int j = 0; j < (1 << GetSize(sig_a)); j++) + new_mask_builder.push_back(mask[j ^ flip_mask]); + Const new_mask = new_mask_builder.build(); if (GetSize(sig_a) == 1 && new_mask.as_int() == 2) { module->connect(lut->getPort(ID::Y), ff.sig_q); module->remove(lut); @@ -178,13 +178,14 @@ struct OptFfInvWorker if (d_lut->type == ID($lut)) { Const mask = d_lut->getParam(ID::LUT); - Const new_mask; + Const::Builder new_mask_builder(GetSize(mask)); for (int i = 0; i < GetSize(mask); i++) { if (mask[i] == State::S0) - new_mask.bits().push_back(State::S1); + new_mask_builder.push_back(State::S1); else - new_mask.bits().push_back(State::S0); + new_mask_builder.push_back(State::S0); } + Const new_mask = new_mask_builder.build(); d_lut->setParam(ID::LUT, new_mask); if (d_lut->getParam(ID::WIDTH) == 1 && new_mask.as_int() == 2) { module->connect(ff.sig_d, d_lut->getPort(ID::A)); @@ -208,7 +209,7 @@ struct OptFfInvWorker std::vector ffs; for (Cell *cell : module->selected_cells()) - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) ffs.push_back(cell); for (Cell *cell : ffs) { diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 97147fc48..37ae38225 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -493,7 +493,7 @@ struct OptLutWorker eval_inputs[lutM_new_inputs[i]] = (eval >> i) & 1; } eval_inputs[lutA_output] = evaluate_lut(lutA, eval_inputs); - lutM_new_table.bits()[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs); + lutM_new_table.set(eval, (RTLIL::State) evaluate_lut(lutB, eval_inputs)); } log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID::LUT).as_string().c_str()); @@ -555,7 +555,7 @@ struct OptLutPass : public Pass { { std::string tech = args[++argidx]; if (tech != "ice40") - log_cmd_error("Unsupported -tech argument: %s\n", tech.c_str()); + log_cmd_error("Unsupported -tech argument: %s\n", tech); dlogic = {{ ID(SB_CARRY), diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 492676ece..fa8eb563b 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -59,7 +59,7 @@ struct OptLutInsPass : public Pass { extra_args(args, argidx, design); if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "ecp5" && techname != "gowin") - log_cmd_error("Unsupported technology: '%s'\n", techname.c_str()); + log_cmd_error("Unsupported technology: '%s'\n", techname); for (auto module : design->selected_modules()) { @@ -213,7 +213,7 @@ struct OptLutInsPass : public Pass { } lidx |= val << j; } - new_lut.bits()[i] = lut[lidx]; + new_lut.set(i, lut[lidx]); } // For lattice, and gowin do not replace with a const driver — the nextpnr // packer requires a complete set of LUTs for wide LUT muxes. diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 741708101..08bfcd7ae 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -175,36 +175,36 @@ struct OptMemPass : public Pass { } for (auto &port: mem.rd_ports) { SigSpec new_data; - Const new_init; - Const new_arst; - Const new_srst; + Const::Builder new_init_bits; + Const::Builder new_arst_bits; + Const::Builder new_srst_bits; for (int sub = 0; sub < (1 << port.wide_log2); sub++) { for (auto i: swizzle) { int bidx = sub * mem.width + i; new_data.append(port.data[bidx]); - new_init.bits().push_back(port.init_value[bidx]); - new_arst.bits().push_back(port.arst_value[bidx]); - new_srst.bits().push_back(port.srst_value[bidx]); + new_init_bits.push_back(port.init_value[bidx]); + new_arst_bits.push_back(port.arst_value[bidx]); + new_srst_bits.push_back(port.srst_value[bidx]); } } port.data = new_data; - port.init_value = new_init; - port.arst_value = new_arst; - port.srst_value = new_srst; + port.init_value = new_init_bits.build(); + port.arst_value = new_arst_bits.build(); + port.srst_value = new_srst_bits.build(); } for (auto &init: mem.inits) { - Const new_data; - Const new_en; + Const::Builder new_data_bits; for (int s = 0; s < GetSize(init.data); s += mem.width) { for (auto i: swizzle) { - new_data.bits().push_back(init.data[s + i]); + new_data_bits.push_back(init.data[s + i]); } } + init.data = new_data_bits.build(); + Const::Builder new_en_bits; for (auto i: swizzle) { - new_en.bits().push_back(init.en[i]); + new_en_bits.push_back(init.en[i]); } - init.data = new_data; - init.en = new_en; + init.en = new_en_bits.build(); } mem.width = GetSize(swizzle); changed = true; diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index fbfdb9b63..1cb499740 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -110,7 +110,7 @@ struct OptMergeWorker comm.eat(hash_ops>::hash(port, assign_map(sig))); } h = comm.hash_into(h); - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) h = initvals(cell->getPort(ID::Q)).hash_into(h); } return h; @@ -153,7 +153,7 @@ struct OptMergeWorker for (const auto &it : cell1->connections_) { if (cell1->output(it.first)) { - if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) { + if (it.first == ID::Q && cell1->is_builtin_ff()) { // For the 'Q' output of state elements, // use the (* init *) attribute value conn1[it.first] = initvals(it.second); @@ -201,7 +201,7 @@ struct OptMergeWorker bool has_dont_care_initval(const RTLIL::Cell *cell) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) return false; return !initvals(cell->getPort(ID::Q)).is_fully_def(); diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index e512a5be1..4a0864df0 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -321,11 +321,12 @@ struct Pmux2ShiftxPass : public Pass { bits.sort(); pair entry; - + RTLIL::Const::Builder entry_bits_builder(GetSize(bits)); for (auto it : bits) { entry.first.append(it.first); - entry.second.bits().push_back(it.second); + entry_bits_builder.push_back(it.second); } + entry.second = entry_bits_builder.build(); eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; @@ -342,11 +343,12 @@ struct Pmux2ShiftxPass : public Pass { bits.sort(); pair entry; - + RTLIL::Const::Builder entry_bits_builder(GetSize(bits)); for (auto it : bits) { entry.first.append(it.first); - entry.second.bits().push_back(it.second); + entry_bits_builder.push_back(it.second); } + entry.second = entry_bits_builder.build(); eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; @@ -591,7 +593,7 @@ struct Pmux2ShiftxPass : public Pass { used_src_columns[best_src_col] = true; perm_new_from_old[dst_col] = best_src_col; - perm_xormask.bits()[dst_col] = best_inv ? State::S1 : State::S0; + perm_xormask.set(dst_col, best_inv ? State::S1 : State::S0); } } @@ -614,7 +616,7 @@ struct Pmux2ShiftxPass : public Pass { Const new_c(State::S0, GetSize(old_c)); for (int i = 0; i < GetSize(old_c); i++) - new_c.bits()[i] = old_c[perm_new_from_old[i]]; + new_c.set(i, old_c[perm_new_from_old[i]]); Const new_c_before_xor = new_c; new_c = const_xor(new_c, perm_xormask, false, false, GetSize(new_c)); @@ -687,7 +689,7 @@ struct Pmux2ShiftxPass : public Pass { if (!full_case) { Const enable_mask(State::S0, max_choice+1); for (auto &it : perm_choices) - enable_mask.bits()[it.first.as_int()] = State::S1; + enable_mask.set(it.first.as_int(), State::S1); en = module->addWire(NEW_ID); module->addShift(NEW_ID, enable_mask, cmp, en, false, src); } diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 1d7ba7d98..307cd299b 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -790,12 +790,13 @@ struct ShareWorker } p.first = RTLIL::SigSpec(); - p.second.bits().clear(); + RTLIL::Const::Builder new_bits(p_bits.size()); for (auto &it : p_bits) { p.first.append(it.first); - p.second.bits().push_back(it.second); + new_bits.push_back(it.second); } + p.second = new_bits.build(); return true; } @@ -818,9 +819,9 @@ struct ShareWorker auto otherval = val; if (otherval[i] == State::S0) - otherval.bits()[i] = State::S1; + otherval.set(i, State::S1); else if (otherval[i] == State::S1) - otherval.bits()[i] = State::S0; + otherval.set(i, State::S0); else continue; @@ -829,8 +830,11 @@ struct ShareWorker auto newsig = sig; newsig.remove(i); - auto newval = val; - newval.bits().erase(newval.bits().begin() + i); + RTLIL::Const::Builder new_bits(val.size() - 1); + for (int j = 0; j < val.size(); ++j) + if (j != i) + new_bits.push_back(val[j]); + RTLIL::Const newval = new_bits.build(); db[newsig].insert(newval); db[sig].erase(otherval); @@ -926,7 +930,8 @@ struct ShareWorker if (used_in_a) for (auto p : c_patterns) { for (int i = 0; i < GetSize(sig_s); i++) - p.first.append(sig_s[i]), p.second.bits().push_back(RTLIL::State::S0); + p.first.append(sig_s[i]); + p.second.append(RTLIL::Const(RTLIL::State::S0, GetSize(sig_s))); if (sort_check_activation_pattern(p)) if (!insert_capped(activation_patterns_cache[cell], p)) { recursion_state.erase(cell); @@ -936,7 +941,8 @@ struct ShareWorker for (int idx : used_in_b_parts) for (auto p : c_patterns) { - p.first.append(sig_s[idx]), p.second.bits().push_back(RTLIL::State::S1); + p.first.append(sig_s[idx]); + p.second.append(RTLIL::Const(RTLIL::State::S1)); if (sort_check_activation_pattern(p)) if (!insert_capped(activation_patterns_cache[cell], p)) { recursion_state.erase(cell); @@ -989,12 +995,14 @@ struct ShareWorker { std::vector p_first = p.first; ssc_pair_t new_p; + RTLIL::Const::Builder new_p_second_bits; for (int i = 0; i < GetSize(p_first); i++) if (filter_bits.count(p_first[i]) == 0) { new_p.first.append(p_first[i]); - new_p.second.bits().push_back(p.second.at(i)); + new_p_second_bits.push_back(p.second.at(i)); } + new_p.second = new_p_second_bits.build(); out.insert(new_p); } diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 59015707d..5a94e479b 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -220,10 +220,10 @@ struct WreduceWorker // Narrow ARST_VALUE parameter to new size. if (cell->parameters.count(ID::ARST_VALUE)) { - rst_value.bits().resize(GetSize(sig_q)); + rst_value.resize(GetSize(sig_q), State::S0); cell->setParam(ID::ARST_VALUE, rst_value); } else if (cell->parameters.count(ID::SRST_VALUE)) { - rst_value.bits().resize(GetSize(sig_q)); + rst_value.resize(GetSize(sig_q), State::S0); cell->setParam(ID::SRST_VALUE, rst_value); } diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 892500850..f6d6a3f93 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -238,7 +238,7 @@ struct TestPmgenPass : public Pass { if (pattern == "xilinx_srl.variable") return GENERATE_PATTERN(xilinx_srl_pm, variable); - log_cmd_error("Unknown pattern: %s\n", pattern.c_str()); + log_cmd_error("Unknown pattern: %s\n", pattern); } void execute(std::vector args, RTLIL::Design *design) override diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 99cacf5fd..3d27eaa9a 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -52,17 +52,15 @@ void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc) Const value = valuesig.as_const(); Const &wireinit = lhs_c.wire->attributes[ID::init]; - - while (GetSize(wireinit) < lhs_c.wire->width) - wireinit.bits().push_back(State::Sx); - + if (GetSize(wireinit) < lhs_c.wire->width) + wireinit.resize(lhs_c.wire->width, State::Sx); for (int i = 0; i < lhs_c.width; i++) { - auto &initbit = wireinit.bits()[i + lhs_c.offset]; + int index = i + lhs_c.offset; + State initbit = wireinit[index]; if (initbit != State::Sx && initbit != value[i]) log_cmd_error("Conflicting initialization values for %s.\n", log_signal(lhs_c)); - initbit = value[i]; + wireinit.set(index, value[i]); } - log(" Set init value: %s = %s\n", log_signal(lhs_c.wire), log_signal(wireinit)); } offset += lhs_c.width; diff --git a/passes/proc/proc_memwr.cc b/passes/proc/proc_memwr.cc index 88aea39bb..a5ae0d6d5 100644 --- a/passes/proc/proc_memwr.cc +++ b/passes/proc/proc_memwr.cc @@ -39,7 +39,7 @@ void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict &n Const priority_mask(State::S0, port_id); for (int i = 0; i < GetSize(prev_port_ids); i++) if (memwr.priority_mask[i] == State::S1) - priority_mask.bits()[prev_port_ids[i]] = State::S1; + priority_mask.set(prev_port_ids[i], State::S1); prev_port_ids.push_back(port_id); RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($memwr_v2)); diff --git a/passes/proc/proc_rom.cc b/passes/proc/proc_rom.cc index d3b781e60..a7b485194 100644 --- a/passes/proc/proc_rom.cc +++ b/passes/proc/proc_rom.cc @@ -97,7 +97,7 @@ struct RomWorker log_debug("rejecting switch: lhs not uniform\n"); return; } - val.bits()[it2->second] = it.second[i].data; + val.set(it2->second, it.second[i].data); } } for (auto bit: val) { @@ -114,7 +114,7 @@ struct RomWorker } Const c = addr.as_const(); while (GetSize(c) && c.back() == State::S0) - c.bits().pop_back(); + c.resize(c.size() - 1, State::S0); if (GetSize(c) > swsigbits) continue; if (GetSize(c) > 30) { @@ -155,22 +155,22 @@ struct RomWorker Mem mem(module, NEW_ID, GetSize(lhs), 0, 1 << abits); mem.attributes = sw->attributes; - Const init_data; + Const::Builder builder(mem.size * GetSize(lhs)); for (int i = 0; i < mem.size; i++) { auto it = vals.find(i); if (it == vals.end()) { log_assert(got_default); for (auto bit: default_val) - init_data.bits().push_back(bit); + builder.push_back(bit); } else { for (auto bit: it->second) - init_data.bits().push_back(bit); + builder.push_back(bit); } } MemInit init; init.addr = 0; - init.data = init_data; + init.data = builder.build(); init.en = Const(State::S1, GetSize(lhs)); mem.inits.push_back(std::move(init)); diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index e86a78d81..eb3b154b2 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -129,7 +129,7 @@ struct Async2syncPass : public Pass { continue; } - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index db1eaad4b..dd94dd0d7 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -275,7 +275,7 @@ struct Clk2fflogicPass : public Pass { continue; } - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index bde5e1ecb..b0eaaca22 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -94,11 +94,11 @@ struct BruteForceEquivChecker continue; if (mod2->wire(w->name) == nullptr) - log_cmd_error("Port %s in module 1 has no counterpart in module 2!\n", w->name.c_str()); + log_cmd_error("Port %s in module 1 has no counterpart in module 2!\n", w->name); RTLIL::Wire *w2 = mod2->wire(w->name); if (w->width != w2->width || w->port_input != w2->port_input || w->port_output != w2->port_output) - log_cmd_error("Port %s in module 1 does not match its counterpart in module 2!\n", w->name.c_str()); + log_cmd_error("Port %s in module 1 does not match its counterpart in module 2!\n", w->name); if (w->port_input) { mod1_inputs.append(w); @@ -256,7 +256,7 @@ struct VlogHammerReporter for (int j = input_widths[i]-1; j >= 0; j--) { ce.set(RTLIL::SigSpec(wire, j), bits.back()); recorded_set_vars.append(RTLIL::SigSpec(wire, j)); - recorded_set_vals.bits().push_back(bits.back()); + recorded_set_vars.append(RTLIL::Const(bits.back())); bits.pop_back(); } if (module == modules.front()) { @@ -346,7 +346,7 @@ struct VlogHammerReporter log_error("Pattern %s is to short!\n", pattern); patterns.push_back(sig.as_const()); if (invert_pattern) { - for (auto &bit : patterns.back().bits()) + for (auto bit : patterns.back()) if (bit == RTLIL::State::S0) bit = RTLIL::State::S1; else if (bit == RTLIL::State::S1) @@ -454,11 +454,11 @@ struct EvalPass : public Pass { for (auto &it : sets) { RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, it.first)) - log_cmd_error("Failed to parse lhs set expression `%s'.\n", it.first.c_str()); + log_cmd_error("Failed to parse lhs set expression `%s'.\n", it.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, it.second)) - log_cmd_error("Failed to parse rhs set expression `%s'.\n", it.second.c_str()); + log_cmd_error("Failed to parse rhs set expression `%s'.\n", it.second); if (!rhs.is_fully_const()) - log_cmd_error("Right-hand-side set expression `%s' is not constant.\n", it.second.c_str()); + log_cmd_error("Right-hand-side set expression `%s' is not constant.\n", it.second); if (lhs.size() != rhs.size()) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", it.first.c_str(), log_signal(lhs), lhs.size(), it.second.c_str(), log_signal(rhs), rhs.size()); @@ -476,7 +476,7 @@ struct EvalPass : public Pass { for (auto &it : shows) { RTLIL::SigSpec signal, value, undef; if (!RTLIL::SigSpec::parse_sel(signal, design, module, it)) - log_cmd_error("Failed to parse show expression `%s'.\n", it.c_str()); + log_cmd_error("Failed to parse show expression `%s'.\n", it); value = signal; if (set_undef) { while (!ce.eval(value, undef)) { @@ -502,14 +502,14 @@ struct EvalPass : public Pass { for (auto &it : shows) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, it)) - log_cmd_error("Failed to parse show expression `%s'.\n", it.c_str()); + log_cmd_error("Failed to parse show expression `%s'.\n", it); signal.append(sig); } for (auto &it : tables) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, it)) - log_cmd_error("Failed to parse table expression `%s'.\n", it.c_str()); + log_cmd_error("Failed to parse table expression `%s'.\n", it); tabsigs.append(sig); } diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index 2d31822c4..505526c14 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -118,7 +118,7 @@ struct FmcombineWorker Cell *gold = import_prim_cell(cell, "_gold"); Cell *gate = import_prim_cell(cell, "_gate"); if (opts.initeq) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { SigSpec gold_q = gold->getPort(ID::Q); SigSpec gate_q = gate->getPort(ID::Q); SigSpec en = module->Initstate(NEW_ID); diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 286bf2976..452e0e59b 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -92,7 +92,7 @@ struct InitValWorker ModWalker::PortBit portbit = *portbits.begin(); RTLIL::Cell *cell = portbit.cell; - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) { FfData ff(&initvals, cell); @@ -224,7 +224,7 @@ struct InitValWorker for (auto portbit : portbits) { RTLIL::Cell *cell = portbit.cell; - if (!cell->type.in(ID($mux), ID($and), ID($or), ID($mem_v2)) && !RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (!cell->type.in(ID($mux), ID($and), ID($or), ID($mem_v2)) && !cell->is_builtin_ff()) { return true; } } @@ -232,7 +232,7 @@ struct InitValWorker for (auto portbit : portbits) { RTLIL::Cell *cell = portbit.cell; - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) { FfData ff(&initvals, cell); if (ff.has_aload || ff.has_sr || ff.has_arst || ff.has_gclk || !ff.has_clk) @@ -641,7 +641,7 @@ struct FormalFfPass : public Pass { pool input_bits; pool> input_clk_bits; for (auto cell : module->selected_cells()) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { FfData ff(&initvals, cell); if (!ff.has_clk) continue; @@ -743,7 +743,7 @@ struct FormalFfPass : public Pass { auto gate_driver = *found->second.begin(); - if (!RTLIL::builtin_ff_cell_types().count(gate_driver.cell->type)) { + if (!gate_driver.cell->is_builtin_ff()) { log_debug("non FF driver for gate enable %s.%s of gated clk bit %s.%s\n", log_id(module), log_signal(SigSpec(gate_enable)), log_id(module), log_signal(SigSpec(clk))); continue; @@ -784,7 +784,7 @@ struct FormalFfPass : public Pass { log_debug("rewriting cell %s.%s (%s)\n", log_id(module), log_id(clocked_cell), log_id(clocked_cell->type)); - if (RTLIL::builtin_ff_cell_types().count(clocked_cell->type)) { + if (clocked_cell->is_builtin_ff()) { FfData ff(&initvals, clocked_cell); log_assert(ff.has_clk); @@ -836,7 +836,7 @@ struct FormalFfPass : public Pass { for (auto cell : module->selected_cells()) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) + if (cell->is_builtin_ff()) { FfData ff(&worker.initvals, cell); if (ff.has_aload || ff.has_sr || ff.has_arst || ff.val_init.is_fully_def()) @@ -851,7 +851,7 @@ struct FormalFfPass : public Pass { auto before = ff.val_init; for (int i = 0; i < ff.width; i++) if (ff.val_init[i] == State::Sx && !worker.is_initval_used(ff.sig_q[i])) - ff.val_init.bits()[i] = State::S0; + ff.val_init.set(i, State::S0); if (ff.val_init != before) { log("Setting unused undefined initial value of %s.%s (%s) from %s to %s\n", @@ -883,7 +883,7 @@ struct FormalFfPass : public Pass { continue; } - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 9bcf25547..55a41909d 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -76,11 +76,11 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]); if (design->module(gold_name) == nullptr) - log_cmd_error("Can't find gold module %s!\n", gold_name.c_str()); + log_cmd_error("Can't find gold module %s!\n", gold_name); if (design->module(gate_name) == nullptr) - log_cmd_error("Can't find gate module %s!\n", gate_name.c_str()); + log_cmd_error("Can't find gate module %s!\n", gate_name); if (design->module(miter_name) != nullptr) - log_cmd_error("There is already a module %s!\n", miter_name.c_str()); + log_cmd_error("There is already a module %s!\n", miter_name); RTLIL::Module *gold_module = design->module(gold_name); RTLIL::Module *gate_module = design->module(gate_name); @@ -105,7 +105,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: goto match_gold_port_error; continue; match_gold_port_error: - log_cmd_error("No matching port in gate module was found for %s!\n", gold_wire->name.c_str()); + log_cmd_error("No matching port in gate module was found for %s!\n", gold_wire->name); } for (auto gate_wire : gate_module->wires()) { @@ -125,7 +125,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: goto match_gate_port_error; continue; match_gate_port_error: - log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name.c_str()); + log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name); } log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name)); @@ -322,9 +322,9 @@ void create_miter_assert(struct Pass *that, std::vector args, RTLIL IdString miter_name = argidx < args.size() ? RTLIL::escape_id(args[argidx++]) : ""; if (design->module(module_name) == nullptr) - log_cmd_error("Can't find module %s!\n", module_name.c_str()); + log_cmd_error("Can't find module %s!\n", module_name); if (!miter_name.empty() && design->module(miter_name) != nullptr) - log_cmd_error("There is already a module %s!\n", miter_name.c_str()); + log_cmd_error("There is already a module %s!\n", miter_name); Module *module = design->module(module_name); diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index 58d932f20..79ffcd88d 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -989,7 +989,7 @@ struct MutatePass : public Pass { return; } - log_cmd_error("Invalid mode: %s\n", opts.mode.c_str()); + log_cmd_error("Invalid mode: %s\n", opts.mode); } } MutatePass; diff --git a/passes/sat/qbfsat.cc b/passes/sat/qbfsat.cc index 20cee7956..b011227e2 100644 --- a/passes/sat/qbfsat.cc +++ b/passes/sat/qbfsat.cc @@ -87,7 +87,7 @@ void specialize_from_file(RTLIL::Module *module, const std::string &file) { if (!std::regex_search(buf, bit_m, hole_bit_assn_regex)) { bit_assn = false; if (!std::regex_search(buf, m, hole_assn_regex)) - log_cmd_error("solution file is not formatted correctly: \"%s\"\n", buf.c_str()); + log_cmd_error("solution file is not formatted correctly: \"%s\"\n", buf); } std::string hole_loc = bit_assn? bit_m[1].str() : m[1].str(); @@ -108,7 +108,7 @@ void specialize_from_file(RTLIL::Module *module, const std::string &file) { pool hole_loc_pool(locs.begin(), locs.end()); auto hole_cell_it = anyconst_loc_to_cell.find(hole_loc_pool); if (hole_cell_it == anyconst_loc_to_cell.end()) - log_cmd_error("cannot find matching wire name or $anyconst cell location for hole spec \"%s\"\n", buf.c_str()); + log_cmd_error("cannot find matching wire name or $anyconst cell location for hole spec \"%s\"\n", buf); RTLIL::Cell *hole_cell = hole_cell_it->second; hole_sigbit = hole_cell->getPort(ID::Y)[hole_bit]; @@ -233,7 +233,7 @@ QbfSolutionType call_qbf_solver(RTLIL::Module *mod, const QbfSolveOptions &opt, ret.stdout_lines.push_back(line.substr(0, line.size()-1)); //don't include trailing newline auto warning_pos = line.find(smtbmc_warning); if (warning_pos != std::string::npos) - log_warning("%s", line.substr(warning_pos + smtbmc_warning.size() + 1).c_str()); + log_warning("%s", line.substr(warning_pos + smtbmc_warning.size() + 1)); else if (opt.show_smtbmc && !quiet) log("smtbmc output: %s", line); @@ -420,7 +420,7 @@ QbfSolveOptions parse_args(const std::vector &args) { else if (args[opt.argidx+1] == "cvc5") opt.solver = opt.Solver::CVC5; else - log_cmd_error("Unknown solver \"%s\".\n", args[opt.argidx+1].c_str()); + log_cmd_error("Unknown solver \"%s\".\n", args[opt.argidx+1]); opt.argidx++; } continue; @@ -457,7 +457,7 @@ QbfSolveOptions parse_args(const std::vector &args) { opt.oflag = opt.OptimizationLevel::O2; break; default: - log_cmd_error("unknown argument %s\n", args[opt.argidx].c_str()); + log_cmd_error("unknown argument %s\n", args[opt.argidx]); } continue; } diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 967cb0472..90b85d709 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -106,9 +106,9 @@ struct SatHelper RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s.first)) - log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first.c_str()); + log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, s.second)) - log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second.c_str()); + log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second); show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); @@ -127,9 +127,9 @@ struct SatHelper RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s.first)) - log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first.c_str()); + log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, s.second)) - log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second.c_str()); + log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second); show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); @@ -148,7 +148,7 @@ struct SatHelper RTLIL::SigSpec lhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s)) - log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse lhs set expression `%s'.\n", s); show_signal_pool.add(sigmap(lhs)); log("Import unset-constraint for this timestep: %s\n", log_signal(lhs)); @@ -167,28 +167,28 @@ struct SatHelper for (auto &s : sets_def) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[0].insert(sig); } for (auto &s : sets_any_undef) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[1].insert(sig); } for (auto &s : sets_all_undef) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[2].insert(sig); } for (auto &s : sets_def_at[timestep]) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[0].insert(sig); sets_def_undef[1].erase(sig); sets_def_undef[2].erase(sig); @@ -197,7 +197,7 @@ struct SatHelper for (auto &s : sets_any_undef_at[timestep]) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[0].erase(sig); sets_def_undef[1].insert(sig); sets_def_undef[2].erase(sig); @@ -206,7 +206,7 @@ struct SatHelper for (auto &s : sets_all_undef_at[timestep]) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse set-def expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse set-def expression `%s'.\n", s); sets_def_undef[0].erase(sig); sets_def_undef[1].erase(sig); sets_def_undef[2].insert(sig); @@ -295,9 +295,9 @@ struct SatHelper RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s.first)) - log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first.c_str()); + log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, s.second)) - log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second.c_str()); + log_cmd_error("Failed to parse rhs set expression `%s'.\n", s.second); show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); @@ -362,9 +362,9 @@ struct SatHelper RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s.first)) - log_cmd_error("Failed to parse lhs proof expression `%s'.\n", s.first.c_str()); + log_cmd_error("Failed to parse lhs proof expression `%s'.\n", s.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, s.second)) - log_cmd_error("Failed to parse rhs proof expression `%s'.\n", s.second.c_str()); + log_cmd_error("Failed to parse rhs proof expression `%s'.\n", s.second); show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); @@ -390,9 +390,9 @@ struct SatHelper RTLIL::SigSpec lhs, rhs; if (!RTLIL::SigSpec::parse_sel(lhs, design, module, s.first)) - log_cmd_error("Failed to parse lhs proof-x expression `%s'.\n", s.first.c_str()); + log_cmd_error("Failed to parse lhs proof-x expression `%s'.\n", s.first); if (!RTLIL::SigSpec::parse_rhs(lhs, rhs, module, s.second)) - log_cmd_error("Failed to parse rhs proof-x expression `%s'.\n", s.second.c_str()); + log_cmd_error("Failed to parse rhs proof-x expression `%s'.\n", s.second); show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); @@ -540,7 +540,7 @@ struct SatHelper for (auto &s : shows) { RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, s)) - log_cmd_error("Failed to parse show expression `%s'.\n", s.c_str()); + log_cmd_error("Failed to parse show expression `%s'.\n", s); log("Import show expression: %s\n", log_signal(sig)); modelSig.append(sig); } @@ -620,14 +620,18 @@ struct SatHelper int last_timestep = -2; for (auto &info : modelInfo) { - RTLIL::Const value; bool found_undef = false; + RTLIL::Const::Builder value_builder(info.width); for (int i = 0; i < info.width; i++) { - value.bits().push_back(modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0); - if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) - value.bits().back() = RTLIL::State::Sx, found_undef = true; + RTLIL::State bit = modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0; + if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) { + bit = RTLIL::State::Sx; + found_undef = true; + } + value_builder.push_back(bit); } + RTLIL::Const value = value_builder.build(); if (info.timestep != last_timestep) { const char *hline = "---------------------------------------------------------------------------------------------------" @@ -666,7 +670,7 @@ struct SatHelper rewrite_filename(vcd_file_name); FILE *f = fopen(vcd_file_name.c_str(), "w"); if (!f) - log_cmd_error("Can't open output file `%s' for writing: %s\n", vcd_file_name.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", vcd_file_name, strerror(errno)); log("Dumping SAT model to VCD file %s\n", vcd_file_name); @@ -732,13 +736,14 @@ struct SatHelper int last_timestep = -2; for (auto &info : modelInfo) { - RTLIL::Const value; - + RTLIL::Const::Builder value_builder(info.width); for (int i = 0; i < info.width; i++) { - value.bits().push_back(modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0); + RTLIL::State bit = modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0; if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) - value.bits().back() = RTLIL::State::Sx; + bit = RTLIL::State::Sx; + value_builder.push_back(bit); } + RTLIL::Const value = value_builder.build(); if (info.timestep != last_timestep) { if(last_timestep == 0) @@ -770,7 +775,7 @@ struct SatHelper rewrite_filename(json_file_name); FILE *f = fopen(json_file_name.c_str(), "w"); if (!f) - log_cmd_error("Can't open output file `%s' for writing: %s\n", json_file_name.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", json_file_name, strerror(errno)); log("Dumping SAT model to WaveJSON file '%s'.\n", json_file_name); @@ -779,12 +784,14 @@ struct SatHelper for (auto &info : modelInfo) { - Const value; + RTLIL::Const::Builder value_builder(info.width); for (int i = 0; i < info.width; i++) { - value.bits().push_back(modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0); + RTLIL::State bit = modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0; if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) - value.bits().back() = RTLIL::State::Sx; + bit = RTLIL::State::Sx; + value_builder.push_back(bit); } + Const value = value_builder.build(); wavedata[info.description].first = info.width; wavedata[info.description].second[info.timestep] = value; @@ -1528,7 +1535,7 @@ struct SatPass : public Pass { rewrite_filename(cnf_file_name); FILE *f = fopen(cnf_file_name.c_str(), "w"); if (!f) - log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name, strerror(errno)); log("Dumping CNF to file `%s'.\n", cnf_file_name); cnf_file_name.clear(); @@ -1632,7 +1639,7 @@ struct SatPass : public Pass { rewrite_filename(cnf_file_name); FILE *f = fopen(cnf_file_name.c_str(), "w"); if (!f) - log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno)); + log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name, strerror(errno)); log("Dumping CNF to file `%s'.\n", cnf_file_name); cnf_file_name.clear(); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 7de5f5ce7..7b43dd82a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -129,16 +129,11 @@ struct SimShared bool initstate = true; }; -void zinit(State &v) -{ - if (v != State::S1) - v = State::S0; -} - void zinit(Const &v) { - for (auto &bit : v.bits()) - zinit(bit); + for (auto bit : v) + if (bit != State::S1) + bit = State::S0; } struct SimInstance @@ -263,7 +258,7 @@ struct SimInstance if ((shared->fst) && !(shared->hide_internal && wire->name[0] == '$')) { fstHandle id = shared->fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); if (id==0 && wire->name.isPublic()) - log_warning("Unable to find wire %s in input file.\n", (scope + "." + RTLIL::unescape_id(wire->name)).c_str()); + log_warning("Unable to find wire %s in input file.\n", (scope + "." + RTLIL::unescape_id(wire->name))); fst_handles[wire] = id; } @@ -315,7 +310,7 @@ struct SimInstance } } - if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { FfData ff_data(nullptr, cell); ff_state_t ff; ff.past_d = Const(State::Sx, ff_data.width); @@ -421,16 +416,17 @@ struct SimInstance Const get_state(SigSpec sig) { - Const value; + Const::Builder builder(GetSize(sig)); for (auto bit : sigmap(sig)) if (bit.wire == nullptr) - value.bits().push_back(bit.data); + builder.push_back(bit.data); else if (state_nets.count(bit)) - value.bits().push_back(state_nets.at(bit)); + builder.push_back(state_nets.at(bit)); else - value.bits().push_back(State::Sz); + builder.push_back(State::Sz); + Const value = builder.build(); if (shared->debug) log("[%s] get %s: %s\n", hiername(), log_signal(sig), log_signal(value)); return value; @@ -490,7 +486,7 @@ struct SimInstance for (int i = 0; i < GetSize(data); i++) if (0 <= i+offset && i+offset < state.mem->size * state.mem->width && data[i] != State::Sa) if (state.data[i+offset] != data[i]) - dirty = true, state.data.bits()[i+offset] = data[i]; + dirty = true, state.data.set(i+offset, data[i]); if (dirty) dirty_memories.insert(memid); @@ -502,7 +498,7 @@ struct SimInstance if (offset >= state.mem->size * state.mem->width) log_error("Addressing out of bounds bit %d/%d of memory %s\n", offset, state.mem->size * state.mem->width, log_id(memid)); if (state.data[offset] != data) { - state.data.bits()[offset] = data; + state.data.set(offset, data); dirty_memories.insert(memid); } } @@ -719,10 +715,10 @@ struct SimInstance for(int i=0;i= 0 && index < mem.size) for (int i = 0; i < (mem.width << port.wide_log2); i++) if (enable[i] == State::S1 && mdb.data.at(index*mem.width+i) != data[i]) { - mdb.data.bits().at(index*mem.width+i) = data[i]; + mdb.data.set(index*mem.width+i, data[i]); dirty_memories.insert(mem.memid); did_something = true; } @@ -933,7 +929,7 @@ struct SimInstance if (shared->serious_asserts) log_error("Assertion %s.%s (%s) failed.\n", hiername(), log_id(cell), label); else - log_warning("Assertion %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + log_warning("Assertion %s.%s (%s) failed.\n", hiername(), log_id(cell), label); } } } @@ -973,7 +969,7 @@ struct SimInstance if (w->attributes.count(ID::init) == 0) w->attributes[ID::init] = Const(State::Sx, GetSize(w)); - w->attributes[ID::init].bits()[sig_q[i].offset] = initval[i]; + w->attributes[ID::init].set(sig_q[i].offset, initval[i]); } } @@ -1023,7 +1019,7 @@ struct SimInstance dict registers; for (auto cell : module->cells()) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { FfData ff_data(nullptr, cell); SigSpec q = sigmap(ff_data.sig_q); if (q.is_wire() && signal_database.count(q.as_wire()) != 0) { @@ -1250,7 +1246,7 @@ struct SimInstance Const fst_val = Const::from_string(shared->fst->valueOf(item.second)); Const sim_val = get_state(item.first); if (sim_val.size()!=fst_val.size()) { - log_warning("Signal '%s.%s' size is different in gold and gate.\n", scope.c_str(), log_id(item.first)); + log_warning("Signal '%s.%s' size is different in gold and gate.\n", scope, log_id(item.first)); continue; } if (shared->sim_mode == SimulationMode::sim) { @@ -1258,7 +1254,7 @@ struct SimInstance } else if (shared->sim_mode == SimulationMode::gate && !fst_val.is_fully_def()) { // FST data contains X for(int i=0;isim_mode == SimulationMode::gold && !sim_val.is_fully_def()) { // sim data contains X for(int i=0;icell(escaped_s); if (!c) - log_warning("Wire/cell %s not present in module %s\n",symbol.c_str(),log_id(topmod)); + log_warning("Wire/cell %s not present in module %s\n",symbol,log_id(topmod)); if (c->is_mem_cell()) { std::string memid = c->parameters.at(ID::MEMID).decode_string(); @@ -1879,7 +1875,7 @@ struct SimWorker : SimShared log("witness hierarchy: found wire %s\n", path.str()); bool inserted = hierarchy.paths.emplace(path, {instance, item.wire, {}, INT_MIN}).second; if (!inserted) - log_warning("Yosys witness path `%s` is ambiguous in this design\n", path.str().c_str()); + log_warning("Yosys witness path `%s` is ambiguous in this design\n", path.str()); } } else if (item.mem) { auto it = mem_paths.find(path); @@ -1896,7 +1892,7 @@ struct SimWorker : SimShared continue; bool inserted = hierarchy.paths.emplace(word_path, {instance, nullptr, item.mem->memid, addr}).second; if (!inserted) - log_warning("Yosys witness path `%s` is ambiguous in this design\n", path.str().c_str()); + log_warning("Yosys witness path `%s` is ambiguous in this design\n", path.str()); } } } @@ -1905,7 +1901,7 @@ struct SimWorker : SimShared for (auto &path : paths) if (!hierarchy.paths.count(path)) - log_warning("Yosys witness path `%s` was not found in this design, ignoring\n", path.str().c_str()); + log_warning("Yosys witness path `%s` was not found in this design, ignoring\n", path.str()); dict> clock_inputs; @@ -1928,7 +1924,7 @@ struct SimWorker : SimShared for (int t = 0; t < GetSize(yw.steps); t++) { if (yw.get_bits(t, clock_bits_offset, 1) != expected) - log_warning("Yosys witness trace has an unexpected value for the clock input `%s` in step %d.\n", signal.path.str().c_str(), t); + log_warning("Yosys witness trace has an unexpected value for the clock input `%s` in step %d.\n", signal.path.str(), t); } } } @@ -2006,7 +2002,7 @@ struct SimWorker : SimShared YwHierarchy hierarchy = prepare_yw_hierarchy(yw); if (yw.steps.empty()) { - log_warning("Yosys witness file `%s` contains no time steps\n", yw.filename.c_str()); + log_warning("Yosys witness file `%s` contains no time steps\n", yw.filename); } else { top->set_initstate_outputs(initstate ? State::S1 : State::S0); set_yw_state(yw, hierarchy, 0); @@ -3123,7 +3119,7 @@ struct SimPass : public Pass { } else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".yw") == 0) { worker.run_cosim_yw_witness(top_mod, append); } else { - log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename.c_str()); + log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename); } } diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b6dfb1252..82337afbb 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -375,7 +375,7 @@ void AbcModuleState::mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig) bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff) { - if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->is_builtin_ff()) { FfData ff(&initvals, cell); gate_type_t type = G(FF); if (!ff.has_clk) @@ -751,7 +751,7 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module) log("Breaking loop using new signal %s: %s -> %s\n", log_signal(RTLIL::SigSpec(wire)), run_abc.signal_list[id1].bit_str, run_abc.signal_list[id2].bit_str); else - log(" %*s %s -> %s\n", int(strlen(log_signal(RTLIL::SigSpec(wire)))), "", + log(" %*s %s -> %s\n", int(log_signal(RTLIL::SigSpec(wire)).size()), "", run_abc.signal_list[id1].bit_str, run_abc.signal_list[id2].bit_str); first_line = false; } @@ -984,7 +984,7 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module } if (dff_mode && clk_sig.empty()) - log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); + log_cmd_error("Clock domain %s not found.\n", clk_str); const AbcConfig &config = run_abc.config; if (config.cleanup) @@ -2398,7 +2398,7 @@ struct AbcPass : public Pass { if (g_arg_from_cmd) cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g)); else - log_cmd_error("Unsupported gate type: %s", g.c_str()); + log_cmd_error("Unsupported gate type: %s", g); ok_gate: gate_list.push_back(g); ok_alias: @@ -2503,7 +2503,7 @@ struct AbcPass : public Pass { } } - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index d7a7e3d4a..ac723fdbb 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -329,7 +329,7 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe #endif if (ret != 0) { if (check_file_exists(stringf("%s/output.aig", tempdir_name))) - log_warning("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); + log_warning("ABC: execution of command \"%s\" failed: return code %d.\n", buffer, ret); else log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer, ret); } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 91149ac55..ecba519bf 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -224,7 +224,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) } else if (derived_module->get_bool_attribute(ID::abc9_box)) { for (auto derived_cell : derived_module->cells()) - if (derived_cell->is_mem_cell() || RTLIL::builtin_ff_cell_types().count(derived_cell->type)) { + if (derived_cell->is_mem_cell() || derived_cell->is_builtin_ff()) { derived_module->set_bool_attribute(ID::abc9_box, false); derived_module->set_bool_attribute(ID::abc9_bypass); break; @@ -1216,7 +1216,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) auto Qi = initmap(Q); auto it = Qi.wire->attributes.find(ID::init); if (it != Qi.wire->attributes.end()) - it->second.bits()[Qi.offset] = State::Sx; + it->second.set(Qi.offset, State::Sx); } else if (cell->type.in(ID($_AND_), ID($_NOT_))) module->remove(cell); @@ -1526,8 +1526,11 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) log_assert(index < GetSize(A)); int i = 0; while (i < GetSize(mask)) { - for (int j = 0; j < (1 << index); j++) - std::swap(mask.bits()[i+j], mask.bits()[i+j+(1 << index)]); + for (int j = 0; j < (1 << index); j++) { + State bit = mask[i+j]; + mask.set(i+j, mask[i+j+(1 << index)]); + mask.set(i+j+(1 << index), bit); + } i += 1 << (index+1); } A[index] = y_bit; @@ -1542,7 +1545,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) // and get cleaned away clone_lut: driver_mask = driver_lut->getParam(ID::LUT); - for (auto &b : driver_mask.bits()) { + for (auto b : driver_mask) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } @@ -1563,6 +1566,70 @@ clone_lut: design->remove(mapped_mod); } + +static void replace_zbufs(Design *design) +{ + design->bufNormalize(true); + std::vector zbufs; + + for (auto mod : design->modules()) { + zbufs.clear(); + for (auto cell : mod->cells()) { + if (cell->type != ID($buf)) + continue; + auto &sig = cell->getPort(ID::A); + for (int i = 0; i < GetSize(sig); ++i) { + if (sig[i] == State::Sz) { + zbufs.push_back(cell); + break; + } + } + } + + for (auto cell : zbufs) { + auto sig = cell->getPort(ID::A); + for (int i = 0; i < GetSize(sig); ++i) { + if (sig[i] == State::Sz) { + Wire *w = mod->addWire(NEW_ID); + Cell *ud = mod->addCell(NEW_ID, ID($tribuf)); + ud->set_bool_attribute(ID(aiger2_zbuf)); + ud->setParam(ID::WIDTH, 1); + ud->setPort(ID::Y, w); + ud->setPort(ID::EN, State::S0); + ud->setPort(ID::A, State::S0); + sig[i] = w; + } + } + log("XXX %s -> %s\n", log_signal(cell->getPort(ID::A)), log_signal(sig)); + cell->setPort(ID::A, sig); + } + + mod->bufNormalize(); + } +} + + + +static void restore_zbufs(Design *design) +{ + std::vector to_remove; + + for (auto mod : design->modules()) { + to_remove.clear(); + for (auto cell : mod->cells()) + if (cell->type == ID($tribuf) && cell->has_attribute(ID(aiger2_zbuf))) + to_remove.push_back(cell); + + for (auto cell : to_remove) { + SigSpec sig_y = cell->getPort(ID::Y); + mod->addBuf(NEW_ID, Const(State::Sz, GetSize(sig_y)), sig_y); + mod->remove(cell); + } + mod->bufNormalize(); + } +} + + struct Abc9OpsPass : public Pass { Abc9OpsPass() : Pass("abc9_ops", "helper functions for ABC9") { } void help() override @@ -1665,6 +1732,8 @@ struct Abc9OpsPass : public Pass { bool prep_lut_mode = false; bool prep_box_mode = false; bool reintegrate_mode = false; + bool replace_zbufs_mode = false; + bool restore_zbufs_mode = false; bool dff_mode = false; std::string write_lut_dst; int maxlut = 0; @@ -1751,16 +1820,30 @@ struct Abc9OpsPass : public Pass { dff_mode = true; continue; } + if (arg == "-replace_zbufs") { + replace_zbufs_mode = true; + valid = true; + continue; + } + if (arg == "-restore_zbufs") { + restore_zbufs_mode = true; + valid = true; + continue; + } break; } extra_args(args, argidx, design); if (!valid) - log_cmd_error("At least one of -check, -break_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate must be specified.\n"); + log_cmd_error("At least one of -check, -break_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate, -{replace,restore}_zbufs must be specified.\n"); if (dff_mode && !check_mode && !prep_hier_mode && !prep_delays_mode && !prep_xaiger_mode && !reintegrate_mode) log_cmd_error("'-dff' option is only relevant for -prep_{hier,delay,xaiger} or -reintegrate.\n"); + if (replace_zbufs_mode) + replace_zbufs(design); + if (restore_zbufs_mode) + restore_zbufs(design); if (check_mode) check(design, dff_mode); if (prep_hier_mode) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 286ab4d5b..c48295916 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -169,10 +169,12 @@ struct AbcNewPass : public ScriptPass { } run(stringf(" abc9_ops -write_box %s/input.box", tmpdir)); + run(" abc9_ops -replace_zbufs"); run(stringf(" write_xaiger2 -mapping_prep -map2 %s/input.map2 %s/input.xaig", tmpdir, tmpdir)); run(stringf(" abc9_exe %s -cwd %s -box %s/input.box", exe_options, tmpdir, tmpdir)); run(stringf(" read_xaiger2 -sc_mapping -module_name %s -map2 %s/input.map2 %s/output.aig", modname.c_str(), tmpdir.c_str(), tmpdir.c_str())); + run(" abc9_ops -restore_zbufs"); if (!help_mode && mod->has_attribute(ID(abc9_script))) { if (script_save.empty()) diff --git a/passes/techmap/cellmatch.cc b/passes/techmap/cellmatch.cc index a2a4c4b2c..ce1a75193 100644 --- a/passes/techmap/cellmatch.cc +++ b/passes/techmap/cellmatch.cc @@ -173,7 +173,7 @@ struct CellmatchPass : Pass { derive_luts = true; } else if (args[argidx] == "-lib" && argidx + 1 < args.size()) { if (!saved_designs.count(args[++argidx])) - log_cmd_error("No design '%s' found!\n", args[argidx].c_str()); + log_cmd_error("No design '%s' found!\n", args[argidx]); lib = saved_designs.at(args[argidx]); } else { break; diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index f75d9b640..132b47725 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -333,7 +333,7 @@ struct ClockgatePass : public Pass { int gated_flop_count = 0; for (auto module : design->selected_unboxed_whole_modules()) { for (auto cell : module->cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(nullptr, cell); diff --git a/passes/techmap/constmap.cc b/passes/techmap/constmap.cc index f0757403d..6d18b8494 100644 --- a/passes/techmap/constmap.cc +++ b/passes/techmap/constmap.cc @@ -82,7 +82,7 @@ struct ConstmapPass : public Pass { } } if (!has_port) - log_cmd_error("Cell type '%s' does not have port '%s'.\n", celltype.c_str(), cell_portname.c_str()); + log_cmd_error("Cell type '%s' does not have port '%s'.\n", celltype, cell_portname); bool has_param = false; for (auto &p : existing->avail_parameters){ @@ -91,7 +91,7 @@ struct ConstmapPass : public Pass { } if (!has_param) - log_cmd_error("Cell type '%s' does not have parameter '%s'.\n", celltype.c_str(), cell_paramname.c_str()); + log_cmd_error("Cell type '%s' does not have parameter '%s'.\n", celltype, cell_paramname); } diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index ee83105fd..013675c8a 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -118,13 +118,13 @@ struct DffinitPass : public Pass { for (int i = 0; i < GetSize(sig); i++) { if (initval[i] == State::Sx) continue; - while (GetSize(value) <= i) - value.bits().push_back(State::S0); + if (GetSize(value) <= i) + value.resize(i + 1, State::S0); if (noreinit && value[i] != State::Sx && value[i] != initval[i]) log_error("Trying to assign a different init value for %s.%s.%s which technically " "have a conflicted init value.\n", log_id(module), log_id(cell), log_id(it.second)); - value.bits()[i] = initval[i]; + value.set(i, initval[i]); } if (highlow_mode && GetSize(value) != 0) { diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index facea2e90..dc29750c8 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -869,17 +869,17 @@ struct DffLegalizePass : public Pass { if (ff.has_arst) { if (ff.val_arst[i] == State::Sx) { if (!(supported & (mask << 8))) - ff.val_arst.bits()[i] = State::S0; + ff.val_arst.set(i, State::S0); if (!(supported & (mask << 4))) - ff.val_arst.bits()[i] = State::S1; + ff.val_arst.set(i, State::S1); } } if (ff.has_srst) { if (ff.val_srst[i] == State::Sx) { if (!(supported & (mask << 8))) - ff.val_srst.bits()[i] = State::S0; + ff.val_srst.set(i, State::S0); if (!(supported & (mask << 4))) - ff.val_srst.bits()[i] = State::S1; + ff.val_srst.set(i, State::S1); } } } @@ -1196,7 +1196,7 @@ unrecognized: srst_used.clear(); for (auto cell : module->cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); @@ -1208,7 +1208,7 @@ unrecognized: } for (auto cell : module->selected_cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); legalize_ff(ff); diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc index 8703bf1a0..020597c4b 100644 --- a/passes/techmap/dffunmap.cc +++ b/passes/techmap/dffunmap.cc @@ -74,7 +74,7 @@ struct DffunmapPass : public Pass { for (auto cell : mod->selected_cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 6527b683e..7461e21d8 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -605,7 +605,7 @@ struct ExtractPass : public Pass { f.open(filename.c_str()); if (f.fail()) { delete map; - log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); + log_cmd_error("Can't open map file `%s'.\n", filename); } Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog")); f.close(); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index 7fbe54849..f5f225a9b 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -1401,7 +1401,7 @@ struct FlowmapWorker log_signal(node), log_signal(undef), env.c_str()); } - lut_table.bits()[i] = value.as_bool() ? State::S1 : State::S0; + lut_table.set(i, value.as_bool() ? State::S1 : State::S0); ce.pop(); } diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index c89495c62..7d4fd77ad 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -191,7 +191,7 @@ LibertyExpression LibertyExpression::parse(Lexer &s, int min_prio) { s.next(); lhs = parse(s); if (s.peek() != ')') { - log_warning("expected ')' instead of '%c' while parsing Liberty expression '%s'\n", s.peek(), s.full_expr().c_str()); + log_warning("expected ')' instead of '%c' while parsing Liberty expression '%s'\n", s.peek(), s.full_expr()); return lhs; } s.next(); @@ -200,7 +200,7 @@ LibertyExpression LibertyExpression::parse(Lexer &s, int min_prio) { lhs.kind = Kind::NOT; lhs.children.push_back(parse(s, 7)); } else { - log_warning("unrecognised character '%c' while parsing Liberty expression '%s'\n", c, s.full_expr().c_str()); + log_warning("unrecognised character '%c' while parsing Liberty expression '%s'\n", c, s.full_expr()); return lhs; } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 4e596911c..38ddb4516 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -47,7 +47,22 @@ void simplemap_buf(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_a = cell->getPort(ID::A); RTLIL::SigSpec sig_y = cell->getPort(ID::Y); - module->connect(RTLIL::SigSig(sig_y, sig_a)); + if (sig_a.has_const(State::Sz)) { + SigSpec new_a; + SigSpec new_y; + for (int i = 0; i < GetSize(sig_a); ++i) { + SigBit b = sig_a[i]; + if (b == State::Sz) + continue; + new_a.append(b); + new_y.append(sig_y[i]); + } + sig_a = std::move(new_a); + sig_y = std::move(new_y); + } + + if (!sig_y.empty()) + module->connect(RTLIL::SigSig(sig_y, sig_a)); } void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a7710c89b..010aaa2dc 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -690,15 +690,16 @@ struct TechmapWorker for (auto &conn : cell->connections()) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first))) != 0) { - RTLIL::Const value; - for (auto &bit : sigmap(conn.second)) { + SigSpec sm = sigmap(conn.second); + RTLIL::Const::Builder builder(GetSize(sm) * bits); + for (auto &bit : sm) { int val = unique_bit_id.at(bit); for (int i = 0; i < bits; i++) { - value.bits().push_back((val & 1) != 0 ? State::S1 : State::S0); + builder.push_back((val & 1) != 0 ? State::S1 : State::S0); val = val >> 1; } } - parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first)), value); + parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first)), builder.build()); } } diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index bf049eab7..809651ebd 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -63,7 +63,7 @@ struct ZinitPass : public Pass { for (auto cell : module->selected_cells()) { - if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + if (!cell->is_builtin_ff()) continue; FfData ff(&initvals, cell); @@ -76,7 +76,7 @@ struct ZinitPass : public Pass { if (ff.val_init[i] == State::S1) bits.insert(i); else if (ff.val_init[i] != State::S0 && all_mode) - ff.val_init.bits()[i] = State::S0; + ff.val_init.set(i, State::S0); } ff.flip_bits(bits); ff.emit(); diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 286ef757d..9603956a8 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -641,15 +641,16 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: if (!gold_wire->port_input) continue; - RTLIL::Const in_value; + RTLIL::Const::Builder in_value_builder(GetSize(gold_wire)); for (int i = 0; i < GetSize(gold_wire); i++) - in_value.bits().push_back(xorshift32(2) ? State::S1 : State::S0); + in_value_builder.push_back(xorshift32(2) ? State::S1 : State::S0); + RTLIL::Const in_value = in_value_builder.build(); if (xorshift32(4) == 0) { int inv_chance = 1 + xorshift32(8); for (int i = 0; i < GetSize(gold_wire); i++) if (xorshift32(inv_chance) == 0) - in_value.bits()[i] = RTLIL::Sx; + in_value.set(i, RTLIL::Sx); } if (verbose) @@ -957,7 +958,7 @@ struct TestCellPass : public Pass { if (args[argidx] == "-vlog" && argidx+1 < GetSize(args)) { vlog_file.open(args[++argidx], std::ios_base::trunc); if (!vlog_file.is_open()) - log_cmd_error("Failed to open output file `%s'.\n", args[argidx].c_str()); + log_cmd_error("Failed to open output file `%s'.\n", args[argidx]); continue; } if (args[argidx] == "-bloat" && argidx+1 < GetSize(args)) { @@ -1078,7 +1079,7 @@ struct TestCellPass : public Pass { for (; argidx < GetSize(args); argidx++) { if (args[argidx].rfind("-", 0) == 0) - log_cmd_error("Unexpected option: %s\n", args[argidx].c_str()); + log_cmd_error("Unexpected option: %s\n", args[argidx]); if (args[argidx] == "all") { for (auto &it : cell_types) @@ -1191,7 +1192,7 @@ struct TestCellPass : public Pass { worst_abs = num_cells - num_cells_estimate; worst_rel = (float)(num_cells - num_cells_estimate) / (float)num_cells_estimate; } - log_warning("Upper bound violated for %s: %d > %d\n", cell_type.c_str(), num_cells, num_cells_estimate); + log_warning("Upper bound violated for %s: %d > %d\n", cell_type, num_cells, num_cells_estimate); } } } diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 6e39aa60a..096df07b9 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -3216,3 +3216,26 @@ module \$scopeinfo (); parameter TYPE = ""; endmodule + +// -------------------------------------------------------- +//* group wire +module \$connect (A, B); + +parameter WIDTH = 0; + +inout [WIDTH-1:0] A; +inout [WIDTH-1:0] B; + +tran connect[WIDTH-1:0] (A, B); + +endmodule + +// -------------------------------------------------------- +//* group wire +module \$input_port (Y); + +parameter WIDTH = 0; + +inout [WIDTH-1:0] Y; + +endmodule diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index fdf11904b..7a9ad7693 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -647,3 +647,28 @@ module _90_lut; endmodule `endif + +// -------------------------------------------------------- +// Bufnorm helpers +// -------------------------------------------------------- + +(* techmap_celltype = "$connect" *) +module \$connect (A, B); + +parameter WIDTH = 0; + +inout [WIDTH-1:0] A; +inout [WIDTH-1:0] B; + +assign A = B; // RTLIL assignments are not inherently directed + +endmodule + +(* techmap_celltype = "$input_port" *) +module \$input_port (Y); + +parameter WIDTH = 0; + +inout [WIDTH-1:0] Y; // This cell is just a maker, so we leave Y undriven + +endmodule diff --git a/techlibs/fabulous/synth_fabulous.cc b/techlibs/fabulous/synth_fabulous.cc index 0e6553fa1..3b95ff91e 100644 --- a/techlibs/fabulous/synth_fabulous.cc +++ b/techlibs/fabulous/synth_fabulous.cc @@ -236,7 +236,7 @@ struct SynthPass : public ScriptPass if (args[argidx] == "-carry") { carry_mode = args[++argidx]; if (carry_mode != "none" && carry_mode != "ha") - log_cmd_error("Unsupported carry style: %s\n", carry_mode.c_str()); + log_cmd_error("Unsupported carry style: %s\n", carry_mode); continue; } if (args[argidx] == "-noflatten") { diff --git a/techlibs/gatemate/gatemate_foldinv.cc b/techlibs/gatemate/gatemate_foldinv.cc index cce5d2c4f..1af6a8987 100644 --- a/techlibs/gatemate/gatemate_foldinv.cc +++ b/techlibs/gatemate/gatemate_foldinv.cc @@ -82,7 +82,7 @@ struct FoldInvWorker { Const result(State::S0, GetSize(lut)); for (int i = 0; i < GetSize(lut); i++) { int j = i ^ (1 << bit); - result.bits()[j] = lut[i]; + result.set(j, lut[i]); } return result; } @@ -91,7 +91,7 @@ struct FoldInvWorker { { Const result(State::S0, GetSize(lut)); for (int i = 0; i < GetSize(lut); i++) - result.bits()[i] = (lut[i] == State::S1) ? State::S0 : State::S1; + result.set(i, (lut[i] == State::S1) ? State::S0 : State::S1); return result; } diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 58a2f52e6..5e6083426 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -1958,14 +1958,6 @@ parameter FREQ_DIV = 100; parameter REGULATOR_EN = 1'b0; endmodule -(* blackbox *) -module DCS (CLK0, CLK1, CLK2, CLK3, CLKSEL, SELFORCE, CLKOUT); -input CLK0, CLK1, CLK2, CLK3, SELFORCE; -input [3:0] CLKSEL; -output CLKOUT; -parameter DCS_MODE = "RISING"; -endmodule - (* blackbox *) module EMCU ( input FCLK, diff --git a/techlibs/gowin/cells_xtra.py b/techlibs/gowin/cells_xtra.py index 7a7c9ac0a..01416268a 100644 --- a/techlibs/gowin/cells_xtra.py +++ b/techlibs/gowin/cells_xtra.py @@ -25,7 +25,7 @@ _skip = { # These are already described, no need to extract them from the vendor 'OSCO', 'OSCW', 'OSCZ', 'OSER10', 'OSER16', 'OSER10', 'OSER4', 'OSER8', 'OVIDEO', 'PLLVR', 'RAM16S1', 'RAM16S2', 'RAM16S4', 'RAM16SDP1', 'RAM16SDP2', 'RAM16SDP4', 'rPLL', 'SDP', - 'SDPX9', 'SP', 'SPX9', 'TBUF', 'TLVDS_OBUF', 'VCC', 'DCS', 'EMCU', + 'SDPX9', 'SP', 'SPX9', 'TBUF', 'TLVDS_OBUF', 'VCC', 'EMCU', # These are not planned for implementation 'MUX2_MUX8', 'MUX2_MUX16', 'MUX2_MUX32', 'MUX4', 'MUX8', 'MUX16', 'MUX32', 'DL', 'DLE', 'DLC', 'DLCE', 'DLP', 'DLPE', 'DLN', 'DLNE', @@ -50,7 +50,7 @@ def xtract_cells_decl(dir, fout): fout.write('\n') if l.rstrip()[-1] != ';': state = State.IN_MODULE_MULTILINE - elif l.startswith('parameter') and state == State.IN_MODULE: + elif l.lstrip().startswith('parameter') and state == State.IN_MODULE: fout.write(l) if l.rstrip()[-1] == ',': state = State.IN_PARAMETER diff --git a/techlibs/gowin/cells_xtra_gw1n.v b/techlibs/gowin/cells_xtra_gw1n.v index abf2c0493..436fda0fa 100644 --- a/techlibs/gowin/cells_xtra_gw1n.v +++ b/techlibs/gowin/cells_xtra_gw1n.v @@ -1109,6 +1109,13 @@ parameter IDLE = 4'd0, RD_S2 = 4'd12; endmodule +module DCS (...); +input CLK0, CLK1, CLK2, CLK3, SELFORCE; +input [3:0] CLKSEL; +output CLKOUT; + parameter DCS_MODE = "RISING"; +endmodule + module DQCE (...); input CLKIN; input CE; diff --git a/techlibs/gowin/cells_xtra_gw2a.v b/techlibs/gowin/cells_xtra_gw2a.v index 5c365f8da..4df48ab64 100644 --- a/techlibs/gowin/cells_xtra_gw2a.v +++ b/techlibs/gowin/cells_xtra_gw2a.v @@ -1082,6 +1082,11 @@ input RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD; output DQSR90, DQSW0, DQSW270; output [2:0] RPOINT, WPOINT; output RVALID,RBURST, RFLAG, WFLAG; + parameter FIFO_MODE_SEL = 1'b0; + parameter RD_PNTR = 3'b000; + parameter DQS_MODE = "X1"; + parameter HWL = "false"; + parameter GSREN = "false"; endmodule module DLLDLY (...); @@ -1095,6 +1100,13 @@ parameter DLY_SIGN = 1'b0; parameter DLY_ADJ = 0; endmodule +module DCS (...); +input CLK0, CLK1, CLK2, CLK3, SELFORCE; +input [3:0] CLKSEL; +output CLKOUT; + parameter DCS_MODE = "RISING"; +endmodule + module DQCE (...); input CLKIN; input CE; diff --git a/techlibs/gowin/cells_xtra_gw5a.v b/techlibs/gowin/cells_xtra_gw5a.v index c82f6af25..b4df1f33e 100644 --- a/techlibs/gowin/cells_xtra_gw5a.v +++ b/techlibs/gowin/cells_xtra_gw5a.v @@ -1143,6 +1143,13 @@ input CE; output CLKOUT; endmodule +module DCS (...); +input CLKIN0, CLKIN1, CLKIN2, CLKIN3, SELFORCE; +input [3:0] CLKSEL; +output CLKOUT; +parameter DCS_MODE = "RISING"; +endmodule + module DDRDLL (...); input CLKIN; input STOP; @@ -1714,18 +1721,94 @@ input LOAD; endmodule module ADCLRC (...); + parameter DYN_BKEN = "FALSE"; + parameter BUF_SERDES_Q1_EN = 3'b000; + parameter BUF_BK2_EN = 6'b000000; + parameter BUF_BK3_EN = 6'b000000; + parameter BUF_BK4_EN = 6'b000000; + parameter BUF_BK5_EN = 6'b000000; + parameter BUF_BK10_EN = 5'b00000; + parameter BUF_BK11_EN = 5'b00000; + parameter CLK_SEL = 1'b0; + parameter PIOCLK_SEL = 1'b0; + parameter VSEN_CTL = 3'b000; + parameter VSEN_CTL_SEL = 1'b0; + parameter ADC_MODE = 1'b0; + parameter DIV_CTL = 2'd0; + parameter SAMPLE_CNT_SEL = 3'd4; + parameter RATE_CHANGE_CTRL = 3'd4; endmodule module ADCULC (...); + parameter DYN_BKEN = "FALSE"; + parameter BUF_VCC_EN = 1'b0; + parameter BUF_VCCM_EN = 1'b0; + parameter BUF_MIPI_M0_EN = 3'b000; + parameter BUF_MIPI_M1_EN = 3'b000; + parameter BUF_SERDES_Q0_EN = 3'b000; + parameter BUF_BK6_EN = 6'b000000; + parameter BUF_BK7_EN = 6'b000000; + parameter CLK_SEL = 1'b0; + parameter PIOCLK_SEL = 1'b0; + parameter VSEN_CTL = 3'b000; + parameter VSEN_CTL_SEL = 1'b0; + parameter ADC_MODE = 1'b0; + parameter DIV_CTL = 2'd0; + parameter SAMPLE_CNT_SEL = 3'd4; + parameter RATE_CHANGE_CTRL = 3'd4; endmodule module ADC (...); + parameter CLK_SEL = 1'b0; + parameter DIV_CTL = 2'd0; + parameter BUF_EN = 12'b000000000000; + parameter BUF_BK0_VREF_EN = 1'b0; + parameter BUF_BK1_VREF_EN = 1'b0; + parameter BUF_BK2_VREF_EN = 1'b0; + parameter BUF_BK3_VREF_EN = 1'b0; + parameter BUF_BK4_VREF_EN = 1'b0; + parameter BUF_BK5_VREF_EN = 1'b0; + parameter BUF_BK6_VREF_EN = 1'b0; + parameter BUF_BK7_VREF_EN = 1'b0; + parameter CSR_ADC_MODE = 1'b1; + parameter CSR_VSEN_CTRL = 3'd0; + parameter CSR_SAMPLE_CNT_SEL = 3'd4; + parameter CSR_RATE_CHANGE_CTRL = 3'd4; + parameter CSR_FSCAL = 10'd730; + parameter CSR_OFFSET = -12'd1180; endmodule module ADC_SAR (...); + parameter BUF_EN = 29'b0; + parameter CLK_SEL = 1'b1; + parameter DIV_CTL = 2'd2; + parameter ADC_EN_SEL = 1'b0; + parameter PHASE_SEL = 1'b0; + parameter CSR_ADC_MODE = 1'b1; + parameter CSR_VSEN_CTRL = 3'd0; + parameter CSR_SAMPLE_CNT_SEL = 3'd4; + parameter CSR_RATE_CHANGE_CTRL = 3'd4; + parameter CSR_FSCAL = 10'd730; + parameter CSR_OFFSET = -12'd1180; + parameter ADC_CLK_DIV = 2'b00; + parameter ADC_CLKDIV_EN = 1'b0; + parameter CLK_SRC_SEL = 1'b1; + parameter VREF_BUF_EN = 1'b1; + parameter COUNT_LEN = 5'b10100; + parameter DAC_SAMPLE_END = 5'b10010; + parameter DAC_SAMPLE_START = 5'b01101; + parameter SH_SAMPLE_END = 5'b01011; + parameter SH_SAMPLE_START = 5'b00001; + parameter AUTO_CHOP_EN = 1'b0; + parameter CHOP_CLK_DIV = 4'b0; endmodule module LICD (...); + parameter STAGE_NUM = 2'b00; + parameter ENCDEC_NUM = 2'b00; + parameter CODE_WIDTH = 2'b00; + parameter INTERLEAVE_EN = 3'b000; + parameter INTERLEAVE_MODE = 3'b000; endmodule module MIPI_DPHY (...); @@ -2456,6 +2539,7 @@ parameter EQ_ZLD_LN2 = 4'b1000; endmodule module GTR12_QUAD (...); + parameter POSITION = "Q0"; endmodule module GTR12_UPAR (...); diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc index 37f6d8d9b..4f60a5c37 100644 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ b/techlibs/greenpak4/greenpak4_dffinv.cc @@ -36,9 +36,9 @@ void invert_gp_dff(Cell *cell, bool invert_input) Const initval = cell->getParam(ID::INIT); if (GetSize(initval) >= 1) { if (initval[0] == State::S0) - initval.bits()[0] = State::S1; + initval.set(0, State::S1); else if (initval[0] == State::S1) - initval.bits()[0] = State::S0; + initval.set(0, State::S0); cell->setParam(ID::INIT, initval); } @@ -47,9 +47,9 @@ void invert_gp_dff(Cell *cell, bool invert_input) Const srmode = cell->getParam(ID(SRMODE)); if (GetSize(srmode) >= 1) { if (srmode[0] == State::S0) - srmode.bits()[0] = State::S1; + srmode.set(0, State::S1); else if (srmode[0] == State::S1) - srmode.bits()[0] = State::S0; + srmode.set(0, State::S0); cell->setParam(ID(SRMODE), srmode); } } diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index 99fe45dc4..fa52ecfc6 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -123,7 +123,7 @@ struct SynthGreenPAK4Pass : public ScriptPass log_cmd_error("This command only operates on fully selected designs!\n"); if (part != "SLG46140V" && part != "SLG46620V" && part != "SLG46621V") - log_cmd_error("Invalid part name: '%s'\n", part.c_str()); + log_cmd_error("Invalid part name: '%s'\n", part); log_header(design, "Executing SYNTH_GREENPAK4 pass.\n"); log_push(); diff --git a/techlibs/ice40/ice40_dsp.cc b/techlibs/ice40/ice40_dsp.cc index 3f00028c3..995cdb97e 100644 --- a/techlibs/ice40/ice40_dsp.cc +++ b/techlibs/ice40/ice40_dsp.cc @@ -82,7 +82,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm) SigSpec CD = st.sigCD; if (CD.empty()) - CD = RTLIL::Const(0, 32); + CD = RTLIL::Const(0); else log_assert(GetSize(CD) == 32); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index d433c0408..0a4144451 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -265,7 +265,7 @@ struct SynthIce40Pass : public ScriptPass if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); if (device_opt != "hx" && device_opt != "lp" && device_opt !="u") - log_cmd_error("Invalid or no device specified: '%s'\n", device_opt.c_str()); + log_cmd_error("Invalid or no device specified: '%s'\n", device_opt); if (abc9 && retime) log_cmd_error("-retime option not currently compatible with -abc9!\n"); diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index af0717235..e02885cd0 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -174,7 +174,7 @@ struct SynthIntelPass : public ScriptPass { family_opt != "cycloneiv" && family_opt != "cycloneive" && family_opt != "cyclone10lp") - log_cmd_error("Invalid or no family specified: '%s'\n", family_opt.c_str()); + log_cmd_error("Invalid or no family specified: '%s'\n", family_opt); log_header(design, "Executing SYNTH_INTEL pass.\n"); log_push(); @@ -242,7 +242,7 @@ struct SynthIntelPass : public ScriptPass { run("memory_bram -rules +/intel/common/brams_m9k.txt", "(if applicable for family)"); run("techmap -map +/intel/common/brams_map_m9k.v", "(if applicable for family)"); } else { - log_warning("BRAM mapping is not currently supported for %s.\n", family_opt.c_str()); + log_warning("BRAM mapping is not currently supported for %s.\n", family_opt); } } diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index e1df20dd7..b13c22518 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -306,7 +306,7 @@ struct SynthLatticePass : public ScriptPass family == "lifmd" || family == "lifmdf") {*/ } else - log_cmd_error("Invalid Lattice -family setting: '%s'.\n", family.c_str()); + log_cmd_error("Invalid Lattice -family setting: '%s'.\n", family); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); diff --git a/techlibs/microchip/microchip_dffopt.cc b/techlibs/microchip/microchip_dffopt.cc index 8a13c4325..98e2f17a7 100644 --- a/techlibs/microchip/microchip_dffopt.cc +++ b/techlibs/microchip/microchip_dffopt.cc @@ -93,7 +93,7 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool int lut_idx = i >> idx_data & ((1 << GetSize(data.second)) - 1); new_bit = data.first[lut_idx] == State::S1; } - result.first.bits()[i] = new_bit ? State::S1 : State::S0; + result.first.set(i, new_bit ? State::S1 : State::S0); } return true; } diff --git a/techlibs/microchip/microchip_dsp.cc b/techlibs/microchip/microchip_dsp.cc index 3dfcb8905..df7093bc5 100644 --- a/techlibs/microchip/microchip_dsp.cc +++ b/techlibs/microchip/microchip_dsp.cc @@ -128,7 +128,7 @@ void microchip_dsp_pack(microchip_dsp_pm &pm) continue; for (int i = c.offset; i < c.offset + c.width; i++) { log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); - it->second.bits()[i] = State::Sx; + it->second.set(i, State::Sx); } } }; @@ -244,7 +244,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm) continue; for (int i = c.offset; i < c.offset + c.width; i++) { log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); - it->second.bits()[i] = State::Sx; + it->second.set(i, State::Sx); } } }; diff --git a/techlibs/microchip/synth_microchip.cc b/techlibs/microchip/synth_microchip.cc index 77cedcd1f..e1d3c393a 100644 --- a/techlibs/microchip/synth_microchip.cc +++ b/techlibs/microchip/synth_microchip.cc @@ -234,7 +234,7 @@ struct SynthMicrochipPass : public ScriptPass { if (family == "polarfire") { lut_size = 4; } else { - log_cmd_error("Invalid Microchip -family setting: '%s'.\n", family.c_str()); + log_cmd_error("Invalid Microchip -family setting: '%s'.\n", family); } if (!design->full_selection()) diff --git a/techlibs/nanoxplore/synth_nanoxplore.cc b/techlibs/nanoxplore/synth_nanoxplore.cc index a8f4a05d1..3445ea1be 100644 --- a/techlibs/nanoxplore/synth_nanoxplore.cc +++ b/techlibs/nanoxplore/synth_nanoxplore.cc @@ -218,7 +218,7 @@ struct SynthNanoXplorePass : public ScriptPass } else if (family == "large") { postfix = "_l"; } else - log_cmd_error("Invalid NanoXplore -family setting: '%s'.\n", family.c_str()); + log_cmd_error("Invalid NanoXplore -family setting: '%s'.\n", family); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 83abd156a..c0df06a21 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -249,7 +249,7 @@ struct SynthNexusPass : public ScriptPass { if (family != "lifcl" && family != "lfd2nx") - log_cmd_error("Invalid Nexus -family setting: '%s'.\n", family.c_str()); + log_cmd_error("Invalid Nexus -family setting: '%s'.\n", family); if (check_label("begin")) { diff --git a/techlibs/quicklogic/ql_bram_merge.cc b/techlibs/quicklogic/ql_bram_merge.cc index bed1ba572..7b99d74e5 100644 --- a/techlibs/quicklogic/ql_bram_merge.cc +++ b/techlibs/quicklogic/ql_bram_merge.cc @@ -45,7 +45,7 @@ struct QlBramMergeWorker { { if(cell->type != split_cell_type) continue; if(!cell->hasParam(ID(OPTION_SPLIT))) continue; - if(cell->getParam(ID(OPTION_SPLIT)) != RTLIL::Const(1, 32)) continue; + if(cell->getParam(ID(OPTION_SPLIT)) != RTLIL::Const(1)) continue; mergeable_groups[get_key(cell)].insert(cell); } } diff --git a/techlibs/quicklogic/ql_dsp_simd.cc b/techlibs/quicklogic/ql_dsp_simd.cc index fdd2de406..cd509ce7f 100644 --- a/techlibs/quicklogic/ql_dsp_simd.cc +++ b/techlibs/quicklogic/ql_dsp_simd.cc @@ -200,10 +200,8 @@ struct QlDspSimdPass : public Pass { auto val_a = dsp_a->getParam(it); auto val_b = dsp_b->getParam(it); - mode_bits.bits().insert(mode_bits.bits().end(), - val_a.begin(), val_a.end()); - mode_bits.bits().insert(mode_bits.bits().end(), - val_b.begin(), val_b.end()); + mode_bits.append(val_a); + mode_bits.append(val_b); } // Enable the fractured mode by connecting the control diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 84f9c48a7..ade6f944c 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -176,7 +176,7 @@ struct SynthQuickLogicPass : public ScriptPass { log_cmd_error("This command only operates on fully selected designs!\n"); if (family != "pp3" && family != "qlf_k6n10f") - log_cmd_error("Invalid family specified: '%s'\n", family.c_str()); + log_cmd_error("Invalid family specified: '%s'\n", family); if (abc9 && design->scratchpad_get_int("abc9.D", 0) == 0) { log_warning("delay target has not been set via SDC or scratchpad; assuming 12 MHz clock.\n"); diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 4e422c5cd..46b30573c 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -310,13 +310,13 @@ struct SynthXilinxPass : public ScriptPass lut_size = 4; widelut_size = 6; } else - log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str()); + log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family); if (widemux != 0 && lut_size != 6) log_cmd_error("-widemux is not currently supported for LUT4-based architectures.\n"); if (lut_size != 6) { - log_warning("Shift register inference not yet supported for family %s.\n", family.c_str()); + log_warning("Shift register inference not yet supported for family %s.\n", family); nosrl = true; } diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index bca3deef9..8a6d3e015 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -92,7 +92,7 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool int lut_idx = i >> idx_data & ((1 << GetSize(data.second)) - 1); new_bit = data.first[lut_idx] == State::S1; } - result.first.bits()[i] = new_bit ? State::S1 : State::S0; + result.first.set(i, new_bit ? State::S1 : State::S0); } return true; } @@ -211,8 +211,8 @@ lut_sigin_done: Cell *cell_d = it_D->second.second; if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) { // Flip all bits in the LUT. - for (int i = 0; i < GetSize(lut_d.first); i++) - lut_d.first.bits()[i] = (lut_d.first[i] == State::S1) ? State::S0 : State::S1; + for (auto bit : lut_d.first) + bit = (bit == State::S1) ? State::S0 : State::S1; } LutData lut_d_post_ce; diff --git a/techlibs/xilinx/xilinx_dsp.cc b/techlibs/xilinx/xilinx_dsp.cc index f95930a90..22e6bce5b 100644 --- a/techlibs/xilinx/xilinx_dsp.cc +++ b/techlibs/xilinx/xilinx_dsp.cc @@ -343,7 +343,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) // Since B is an exact power of 2, subtract 1 // by inverting all bits up until hitting // that one hi bit - for (auto &b : B.bits()) + for (auto b : B) if (b == State::S0) b = State::S1; else if (b == State::S1) { b = State::S0; @@ -392,7 +392,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) continue; for (int i = c.offset; i < c.offset+c.width; i++) { log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); - it->second.bits()[i] = State::Sx; + it->second.set(i, State::Sx); } } }; @@ -579,7 +579,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) continue; for (int i = c.offset; i < c.offset+c.width; i++) { log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); - it->second.bits()[i] = State::Sx; + it->second.set(i, State::Sx); } } }; @@ -702,7 +702,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) continue; for (int i = c.offset; i < c.offset+c.width; i++) { log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); - it->second.bits()[i] = State::Sx; + it->second.set(i, State::Sx); } } }; diff --git a/techlibs/xilinx/xilinx_srl.cc b/techlibs/xilinx/xilinx_srl.cc index 32a0064a6..2c23f8f42 100644 --- a/techlibs/xilinx/xilinx_srl.cc +++ b/techlibs/xilinx/xilinx_srl.cc @@ -40,9 +40,8 @@ void run_fixed(xilinx_srl_pm &pm) log_assert(Q.wire); auto it = Q.wire->attributes.find(ID::init); if (it != Q.wire->attributes.end()) { - auto &i = it->second.bits()[Q.offset]; - initval.append(i); - i = State::Sx; + initval.append(it->second[Q.offset]); + it->second.set(Q.offset, State::Sx); } else initval.append(State::Sx); @@ -121,9 +120,8 @@ void run_variable(xilinx_srl_pm &pm) log_assert(Q.wire); auto it = Q.wire->attributes.find(ID::init); if (it != Q.wire->attributes.end()) { - auto &i = it->second.bits()[Q.offset]; - initval.append(i); - i = State::Sx; + initval.append(it->second[Q.offset]); + it->second.set(Q.offset, State::Sx); } else initval.append(State::Sx); diff --git a/tests/sat/fminit_noexpand.ys b/tests/sat/fminit_noexpand.ys new file mode 100644 index 000000000..a271c3c59 --- /dev/null +++ b/tests/sat/fminit_noexpand.ys @@ -0,0 +1,10 @@ +read_verilog -sv < v = {S0, S0, S0, S0, S0, S1, S0, S0}; + Const c(v); + EXPECT_EQ(c.decode_string(), " "); + } + + { + std::vector v = {S0, S0, S0, S0, S0, S1, S0, Sx}; + Const c(v); + EXPECT_EQ(c.decode_string(), " "); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + EXPECT_FALSE(c.is_fully_zero()); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + EXPECT_FALSE(c.is_fully_ones()); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + EXPECT_TRUE(c.is_fully_def()); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + EXPECT_FALSE(c.is_fully_undef()); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + EXPECT_FALSE(c.is_fully_undef_x_only()); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(" "); + EXPECT_TRUE(c.is_str()); + int pos; + EXPECT_TRUE(c.is_onehot(&pos)); + EXPECT_EQ(pos, 5); + EXPECT_TRUE(c.is_str()); + } + } + + TEST_F(KernelRtlilTest, ConstConstIteratorWorks) { + const Const c(0x2, 2); + Const::const_iterator it = c.begin(); + ASSERT_NE(it, c.end()); + EXPECT_EQ(*it, State::S0); + ++it; + ASSERT_NE(it, c.end()); + EXPECT_EQ(*it, State::S1); + ++it; + EXPECT_EQ(it, c.end()); + } + + TEST_F(KernelRtlilTest, ConstConstIteratorPreincrement) { + const Const c(0x2, 2); + Const::const_iterator it = c.begin(); + EXPECT_EQ(*++it, State::S1); + } + + TEST_F(KernelRtlilTest, ConstConstIteratorPostincrement) { + const Const c(0x2, 2); + Const::const_iterator it = c.begin(); + EXPECT_EQ(*it++, State::S0); + } + + TEST_F(KernelRtlilTest, ConstIteratorWorks) { + Const c(0x2, 2); + Const::iterator it = c.begin(); + ASSERT_NE(it, c.end()); + EXPECT_EQ(*it, State::S0); + ++it; + ASSERT_NE(it, c.end()); + EXPECT_EQ(*it, State::S1); + ++it; + ASSERT_EQ(it, c.end()); + } + + TEST_F(KernelRtlilTest, ConstIteratorPreincrement) { + Const c(0x2, 2); + Const::iterator it = c.begin(); + EXPECT_EQ(*++it, State::S1); + } + + TEST_F(KernelRtlilTest, ConstIteratorPostincrement) { + Const c(0x2, 2); + Const::iterator it = c.begin(); + EXPECT_EQ(*it++, State::S0); + } + + TEST_F(KernelRtlilTest, ConstIteratorWriteWorks) { + Const c(0x2, 2); + Const::iterator it = c.begin(); + EXPECT_EQ(*it, State::S0); + *it = State::S1; + EXPECT_EQ(*it, State::S1); + } + + TEST_F(KernelRtlilTest, ConstBuilder) { + Const::Builder b; + EXPECT_EQ(GetSize(b), 0); + b.push_back(S0); + EXPECT_EQ(GetSize(b), 1); + b.push_back(S1); + EXPECT_EQ(GetSize(b), 2); + EXPECT_EQ(b.build(), Const(0x2, 2)); + } + + TEST_F(KernelRtlilTest, ConstSet) { + Const c(0x2, 2); + c.set(0, S1); + EXPECT_EQ(c, Const(0x3, 2)); + } + + TEST_F(KernelRtlilTest, ConstResize) { + Const c(0x2, 2); + c.resize(4, S1); + EXPECT_EQ(c, Const(0xe, 4)); + } + + TEST_F(KernelRtlilTest, ConstEqualStr) { + EXPECT_EQ(Const("abc"), Const("abc")); + EXPECT_NE(Const("abc"), Const("def")); + } + + TEST_F(KernelRtlilTest, ConstEqualBits) { + std::vector v1 = {S0, S1}; + std::vector v2 = {S1, S0}; + EXPECT_EQ(Const(v1), Const(v1)); + EXPECT_NE(Const(v1), Const(v2)); + } + + TEST_F(KernelRtlilTest, ConstEqualStrBits) { + std::vector v1 = {S0, S0, S0, S0, S0, S1, S0, S0}; + EXPECT_EQ(Const(v1), Const(" ")); + EXPECT_NE(Const(v1), Const("a")); + } + + static Hasher::hash_t hash(const Const &c) { + Hasher h; + h = c.hash_into(h); + return h.yield(); + } + + TEST_F(KernelRtlilTest, ConstEqualHashStrBits) { + std::vector v1 = {S0, S0, S0, S0, S0, S1, S0, S0}; + EXPECT_EQ(hash(Const(v1)), hash(Const(" "))); + EXPECT_NE(hash(Const(v1)), hash(Const("a"))); + } + + TEST_F(KernelRtlilTest, ConstIsFullyZero) { + EXPECT_TRUE(Const(0, 8).is_fully_zero()); + EXPECT_FALSE(Const(8, 8).is_fully_zero()); + EXPECT_TRUE(Const().is_fully_zero()); + } + + TEST_F(KernelRtlilTest, ConstIsFullyOnes) { + EXPECT_TRUE(Const(0xf, 4).is_fully_ones()); + EXPECT_FALSE(Const(3, 4).is_fully_ones()); + EXPECT_TRUE(Const().is_fully_ones()); + } + + TEST_F(KernelRtlilTest, ConstIsFullyDef) { + EXPECT_TRUE(Const(0xf, 4).is_fully_def()); + std::vector v1 = {S0, Sx}; + EXPECT_FALSE(Const(v1).is_fully_def()); + EXPECT_TRUE(Const().is_fully_def()); + } + + TEST_F(KernelRtlilTest, ConstIsFullyUndef) { + std::vector v1 = {S0, Sx}; + EXPECT_FALSE(Const(v1).is_fully_undef()); + EXPECT_TRUE(Const(Sz, 2).is_fully_undef()); + EXPECT_TRUE(Const().is_fully_undef()); + } + + TEST_F(KernelRtlilTest, ConstIsFullyUndefXOnly) { + std::vector v1 = {Sx, Sz}; + EXPECT_FALSE(Const(v1).is_fully_undef_x_only()); + EXPECT_TRUE(Const(Sx, 2).is_fully_undef_x_only()); + EXPECT_TRUE(Const().is_fully_undef_x_only()); + } + + TEST_F(KernelRtlilTest, ConstIsOnehot) { + int pos; + EXPECT_TRUE(Const(0x80, 8).is_onehot(&pos)); + EXPECT_EQ(pos, 7); + EXPECT_FALSE(Const(0x82, 8).is_onehot(&pos)); + EXPECT_FALSE(Const(0, 8).is_onehot(&pos)); + EXPECT_TRUE(Const(1, 1).is_onehot(&pos)); + EXPECT_EQ(pos, 0); + EXPECT_FALSE(Const(Sx, 1).is_onehot(&pos)); + std::vector v1 = {Sx, S1}; + EXPECT_FALSE(Const(v1).is_onehot(&pos)); + EXPECT_FALSE(Const().is_onehot(&pos)); } class WireRtlVsHdlIndexConversionTest : diff --git a/tests/various/aiger2.ys b/tests/various/aiger2.ys index d2b024d2f..6f6958141 100644 --- a/tests/various/aiger2.ys +++ b/tests/various/aiger2.ys @@ -157,6 +157,7 @@ splitnets -ports copy test gold flatten gold techmap submodule1 +opt_clean select test write_aiger2 -flatten aiger2_ops.aig select -clear @@ -216,6 +217,7 @@ prep -top top techmap t:$add splitnets -ports top +opt_clean write_aiger2 -flatten aiger2_flatten.aig flatten rename top gold