diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index ce351514b..504e4cabb 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -94,7 +94,9 @@ struct AigMaker int inport(IdString portname, int portbit = 0, bool inverter = false) { if (portbit >= GetSize(cell->getPort(portname))) { - if (cell->parameters.count(portname.str() + "_SIGNED") && cell->getParam(portname.str() + "_SIGNED").as_bool()) + IdString signed_param = cell->module->design->twines.find( + cell->module->design->twines.str(portname) + "_SIGNED"); + if (signed_param != IdString::Null && cell->parameters.count(signed_param) && cell->getParam(signed_param).as_bool()) return inport(portname, GetSize(cell->getPort(portname))-1, inverter); return bool_node(inverter); } @@ -266,7 +268,7 @@ struct AigMaker Aig::Aig(Cell *cell) { - if (cell->type[0] != '$') + if (cell->type.isPublic()) return; AigMaker mk(this, cell); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index ceff0bd1a..b11d31f1b 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -65,10 +65,16 @@ struct CellTypes cell_types[ct.type] = ct; } + template + void setup_type(const N &type_str, const pool &inputs, const pool &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) + { + setup_type(ID::lookup(type_str), inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable); + } + void setup_module(RTLIL::Module *module) { - pool inputs, outputs; - for (RTLIL::IdString wire_name : module->ports) { + pool inputs, outputs; + for (auto wire_name : module->ports) { RTLIL::Wire *wire = module->wire(wire_name); if (wire->port_input) inputs.insert(wire->name); @@ -361,7 +367,7 @@ struct CellTypes signed1 = false, signed2 = false; } -#define HANDLE_CELL_TYPE(_t) if (type == ID($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len); +#define HANDLE_CELL_TYPE(_t) if (type == ID::$##_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len); HANDLE_CELL_TYPE(not) HANDLE_CELL_TYPE(and) HANDLE_CELL_TYPE(or) diff --git a/kernel/ff.h b/kernel/ff.h index 217658d35..3efac2944 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -22,6 +22,7 @@ #include "kernel/yosys.h" #include "kernel/ffinit.h" +#include "kernel/twine.h" YOSYS_NAMESPACE_BEGIN @@ -181,6 +182,9 @@ struct FfData : FfTypeData { pol_set = false; } + FfData(Module *module, FfInitVals *initvals, Twine &&name) + : FfData(module, initvals, module->design->twines.add(std::move(name))) {} + FfData(FfInitVals *initvals, Cell *cell_); // Returns a FF identical to this one, but only keeping bit indices from the argument. diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc index 709549e4d..3c3e31010 100644 --- a/kernel/ffmerge.cc +++ b/kernel/ffmerge.cc @@ -29,7 +29,7 @@ bool FfMergeHelper::is_output_unused(RTLIL::SigSpec sig) { } bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { - ff = FfData(module, initvals, NEW_ID); + ff = FfData(module, initvals, module->design->twines.add(NEW_ID)); sigmap->apply(sig); bool found = false; @@ -157,7 +157,7 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { - ff = FfData(module, initvals, NEW_ID); + ff = FfData(module, initvals, module->design->twines.add(NEW_ID)); sigmap->apply(sig); bool found = false; @@ -303,6 +303,7 @@ void FfMergeHelper::remove_output_ff(const pool> &bits) { dff_driver.erase((*sigmap)(q[idx])); q[idx] = module->addWire(stringf("$ffmerge_disconnected$%d", autoidx++)); cell->setPort(ID::Q, q); + initvals->set_init(cell->getPort(ID::Q), (*initvals)(q)); } } diff --git a/kernel/functional.cc b/kernel/functional.cc index d04677332..c571fc603 100644 --- a/kernel/functional.cc +++ b/kernel/functional.cc @@ -120,8 +120,8 @@ struct PrintVisitor : DefaultVisitor { std::string zero_extend(Node, Node a, int out_width) override { return "zero_extend(" + np(a) + ", " + std::to_string(out_width) + ")"; } std::string sign_extend(Node, Node a, int out_width) override { return "sign_extend(" + np(a) + ", " + std::to_string(out_width) + ")"; } std::string constant(Node, RTLIL::Const const& value) override { return "constant(" + value.as_string() + ")"; } - std::string input(Node, IdString name, IdString kind) override { return "input(" + name.str() + ", " + kind.str() + ")"; } - std::string state(Node, IdString name, IdString kind) override { return "state(" + name.str() + ", " + kind.str() + ")"; } + std::string input(Node self, IdString name, IdString kind) override { return "input(" + self.design->twines.str(name) + ", " + self.design->twines.str(kind) + ")"; } + std::string state(Node self, IdString name, IdString kind) override { return "state(" + self.design->twines.str(name) + ", " + self.design->twines.str(kind) + ")"; } std::string default_handler(Node self) override { std::string ret = fn_to_string(self.fn()); ret += "("; @@ -395,7 +395,7 @@ public: Node y = neg_if(y_flipped, sign(b)); return factory.extend(y, y_width, true); } else - log_error("unhandled cell in CellSimplifier %s\n", cellType); + log_error("unhandled cell in CellSimplifier %s\n", factory.ir().design->twines.str(cellType).c_str()); } else { if(cellType.in(ID($mod), ID($modfloor))) return factory.extend(factory.unsigned_mod(a, b), y_width, false); @@ -458,9 +458,9 @@ public: return factory.value(state); } } else if(cellType == ID($check)) { - log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName); + log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", factory.ir().design->twines.str(cellName).c_str()); } else { - log_error("`%s' cells are not supported by the functional backend\n", cellType); + log_error("`%s' cells are not supported by the functional backend\n", factory.ir().design->twines.str(cellType).c_str()); } } }; @@ -497,7 +497,7 @@ class FunctionalIRConstruction { for(auto const &[name, sigspec] : cell->connections()) if(driver_map.celltypes.cell_output(cell->type, name)) { auto node = factory.create_pending(sigspec.size()); - factory.suggest_name(node, cell->name.str() + "$" + name.str()); + factory.suggest_name(node, cell->name.str() + "$" + PooledName(cell->module, name).str()); cell_outputs.emplace({cell, name}, node); if(name == port_name) rv = node; @@ -572,7 +572,7 @@ private: const auto &wr = mem->wr_ports[i]; if (wr.clk_enable) log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " - "Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, mem->memid.unescape()); + "Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, PooledName(mem->module, mem->memid).unescape()); Node en = enqueue(driver_map(DriveSpec(wr.en))); Node addr = enqueue(driver_map(DriveSpec(wr.addr))); Node new_data = enqueue(driver_map(DriveSpec(wr.data))); @@ -582,12 +582,12 @@ private: } if (mem->rd_ports.empty()) log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. " - "Call opt_clean to remove it.", mem->module, mem->memid.unescape()); + "Call opt_clean to remove it.", mem->module, PooledName(mem->module, mem->memid).unescape()); for (size_t i = 0; i < mem->rd_ports.size(); i++) { const auto &rd = mem->rd_ports[i]; if (rd.clk_enable) log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " - "Call memory_nordff to avoid this error.\n", i, mem->module, mem->memid.unescape()); + "Call memory_nordff to avoid this error.\n", i, mem->module, PooledName(mem->module, mem->memid).unescape()); Node addr = enqueue(driver_map(DriveSpec(rd.addr))); read_results.push_back(factory.memory_read(node, addr)); } @@ -695,7 +695,7 @@ public: factory.update_pending(pending, node); } else { DriveSpec driver = driver_map(DriveSpec(port_chunk)); - check_undriven(driver, port_chunk.cell->name.unescape() + " port " + port_chunk.port.unescape()); + check_undriven(driver, port_chunk.cell->name.unescape() + " port " + PooledName(port_chunk.cell->module, port_chunk.port).unescape()); factory.update_pending(pending, enqueue(driver)); } } else { @@ -725,6 +725,7 @@ public: IR IR::from_module(Module *module) { IR ir; + ir.design = module->design; auto factory = ir.factory(); FunctionalIRConstruction ctor(module, factory); ctor.process_queue(); @@ -743,7 +744,7 @@ void IR::topological_sort() { { log_warning("Combinational loop:\n"); for (int *i = begin; i != end; ++i) { - Node node(_graph[*i]); + Node node(_graph[*i], design); log("- %s = %s\n", node.name().unescape(), node.to_string()); } log("\n"); @@ -763,7 +764,7 @@ void IR::topological_sort() { } static IdString merge_name(IdString a, IdString b) { - if(a[0] == '$' && b[0] == '\\') + if(!a.isPublic() && b.isPublic()) return b; else return a; diff --git a/kernel/functional.h b/kernel/functional.h index 6d98da949..7f13b8361 100644 --- a/kernel/functional.h +++ b/kernel/functional.h @@ -159,23 +159,21 @@ namespace Functional { class IRInput { friend class Factory; public: - IdString name; - IdString kind; + PooledName name; + PooledName kind; Sort sort; private: - IRInput(IR &, IdString name, IdString kind, Sort sort) - : name(name), kind(kind), sort(std::move(sort)) {} + IRInput(IR &ir, IdString name, IdString kind, Sort sort); }; class IROutput { friend class Factory; IR &_ir; public: - IdString name; - IdString kind; + PooledName name; + PooledName kind; Sort sort; private: - IROutput(IR &ir, IdString name, IdString kind, Sort sort) - : _ir(ir), name(name), kind(kind), sort(std::move(sort)) {} + IROutput(IR &ir, IdString name, IdString kind, Sort sort); public: Node value() const; bool has_value() const; @@ -185,13 +183,12 @@ namespace Functional { friend class Factory; IR &_ir; public: - IdString name; - IdString kind; + PooledName name; + PooledName kind; Sort sort; private: std::variant _initial; - IRState(IR &ir, IdString name, IdString kind, Sort sort) - : _ir(ir), name(name), kind(kind), sort(std::move(sort)) {} + IRState(IR &ir, IdString name, IdString kind, Sort sort); public: Node next_value() const; bool has_next_value() const; @@ -249,6 +246,7 @@ namespace Functional { dict, IRState> _states; IR::Graph::Ref mutate(Node n); public: + Design *design = nullptr; static IR from_module(Module *module); Factory factory(); int size() const { return _graph.size(); } @@ -301,24 +299,25 @@ namespace Functional { friend class IROutput; friend class IRState; IR::Graph::ConstRef _ref; - explicit Node(IR::Graph::ConstRef ref) : _ref(ref) { } + Node(IR::Graph::ConstRef ref, Design *design) : _ref(ref), design(design) { } explicit operator IR::Graph::ConstRef() { return _ref; } public: + Design *design = nullptr; // the node's index. may change if nodes are added or removed int id() const { return _ref.index(); } // a name suggestion for the node, which need not be unique - IdString name() const { + PooledName name() const { if(_ref.has_sparse_attr()) - return _ref.sparse_attr(); + return {design, _ref.sparse_attr()}; else - return std::string("\\n") + std::to_string(id()); + return {design, design->twines.add(std::string("\\n") + std::to_string(id()))}; } Fn fn() const { return _ref.function().fn(); } Sort sort() const { return _ref.attr().sort; } // returns the width of a bitvector node, errors out for other nodes int width() const { return sort().width(); } size_t arg_count() const { return _ref.size(); } - Node arg(int n) const { return Node(_ref.arg(n)); } + Node arg(int n) const { return Node(_ref.arg(n), design); } // visit calls the appropriate visitor method depending on the type of the node template auto visit(Visitor v) const { @@ -364,15 +363,21 @@ namespace Functional { std::string to_string(); std::string to_string(std::function); }; + inline IRInput::IRInput(IR &ir, IdString name, IdString kind, Sort sort) + : name(ir.design, name), kind(ir.design, kind), sort(std::move(sort)) {} + inline IROutput::IROutput(IR &ir, IdString name, IdString kind, Sort sort) + : _ir(ir), name(ir.design, name), kind(ir.design, kind), sort(std::move(sort)) {} + inline IRState::IRState(IR &ir, IdString name, IdString kind, Sort sort) + : _ir(ir), name(ir.design, name), kind(ir.design, kind), sort(std::move(sort)) {} inline IR::Graph::Ref IR::mutate(Node n) { return _graph[n._ref.index()]; } - inline Node IR::operator[](int i) { return Node(_graph[i]); } - inline Node IROutput::value() const { return Node(_ir._graph({name, kind, false})); } + inline Node IR::operator[](int i) { return Node(_graph[i], design); } + inline Node IROutput::value() const { return Node(_ir._graph({name, kind, false}), _ir.design); } inline bool IROutput::has_value() const { return _ir._graph.has_key({name, kind, false}); } inline void IROutput::set_value(Node value) { log_assert(sort == value.sort()); _ir.mutate(value).assign_key({name, kind, false}); } - inline Node IRState::next_value() const { return Node(_ir._graph({name, kind, true})); } + inline Node IRState::next_value() const { return Node(_ir._graph({name, kind, true}), _ir.design); } inline bool IRState::has_next_value() const { return _ir._graph.has_key({name, kind, true}); } inline void IRState::set_next_value(Node value) { log_assert(sort == value.sort()); _ir.mutate(value).assign_key({name, kind, true}); } - inline Node IR::iterator::operator*() { return Node(_ir->_graph[_index]); } + inline Node IR::iterator::operator*() { return Node(_ir->_graph[_index], _ir->design); } inline arrow_proxy IR::iterator::operator->() { return arrow_proxy(**this); } // AbstractVisitor provides an abstract base class for visitors template struct AbstractVisitor { @@ -458,7 +463,7 @@ namespace Functional { IR::Graph::Ref ref = _ir._graph.add(std::move(fn), {std::move(sort)}); for (auto arg : args) ref.append_arg(IR::Graph::ConstRef(arg)); - return Node(ref); + return Node(ref, _ir.design); } void check_basic_binary(Node const &a, Node const &b) { log_assert(a.sort().is_signal() && a.sort() == b.sort()); } void check_shift(Node const &a, Node const &b) { log_assert(a.sort().is_signal() && b.sort().is_signal() && b.width() == ceil_log2(a.width())); } @@ -552,17 +557,17 @@ namespace Functional { } IRInput &add_input(IdString name, IdString kind, Sort sort) { auto [it, inserted] = _ir._inputs.emplace({name, kind}, IRInput(_ir, name, kind, std::move(sort))); - if (!inserted) log_error("input `%s` was re-defined", name); + if (!inserted) log_error("input `%s` was re-defined", _ir.design->twines.str(name).c_str()); return it->second; } IROutput &add_output(IdString name, IdString kind, Sort sort) { auto [it, inserted] = _ir._outputs.emplace({name, kind}, IROutput(_ir, name, kind, std::move(sort))); - if (!inserted) log_error("output `%s` was re-defined", name); + if (!inserted) log_error("output `%s` was re-defined", _ir.design->twines.str(name).c_str()); return it->second; } IRState &add_state(IdString name, IdString kind, Sort sort) { auto [it, inserted] = _ir._states.emplace({name, kind}, IRState(_ir, name, kind, std::move(sort))); - if (!inserted) log_error("state `%s` was re-defined", name); + if (!inserted) log_error("state `%s` was re-defined", _ir.design->twines.str(name).c_str()); return it->second; } Node value(IRInput const& input) { @@ -574,6 +579,7 @@ namespace Functional { void suggest_name(Node node, IdString name) { _ir.mutate(node).sparse_attr() = name; } + YS_NAME_FWD_2ND_POOL(suggest_name, _ir.design->twines) }; inline Factory IR::factory() { return Factory(*this); } template class Scope { @@ -587,8 +593,8 @@ namespace Functional { void reserve(std::string name) { _used_names.insert(std::move(name)); } - std::string unique_name(IdString suggestion) { - std::string str = suggestion.unescape(); + template std::string unique_name(const N &suggestion) { + std::string str = RTLIL::unescape_id(suggestion); for(size_t i = 0; i < str.size(); i++) if(!is_character_legal(str[i], i)) str[i] = substitution_character; @@ -604,7 +610,7 @@ namespace Functional { } } } - std::string operator()(Id id, IdString suggestion) { + template std::string operator()(Id id, const N &suggestion) { auto it = _by_id.find(id); if(it != _by_id.end()) return it->second; diff --git a/kernel/log.cc b/kernel/log.cc index 4e8c6e35f..2d924bdf0 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -55,9 +55,6 @@ std::chrono::steady_clock::time_point LogManager::get_initial_time() const void (*log_error_atexit)() = nullptr; void (*log_verific_callback)(int msg_type, const char *message_id, LogSourceLocation src, const char *msg) = nullptr; -// TODO: remove when log_id is removed -vector log_id_cache; - static bool next_print_log = true; FileLogSink::FileLogSink(const std::string &filename, bool line_buffered, bool append) @@ -161,13 +158,6 @@ LogMessage::LogMessage(LogSeverity severity, LogSourceLocation src, std::string_ cached_msg = stringf("%s%s%s%s", time_str, loc, prefix, message); } -static void log_id_cache_clear() -{ - for (auto p : log_id_cache) - free(p); - log_id_cache.clear(); -} - void LogManager::logv_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string str_in) { size_t remove_leading = 0; while (format.size() > 1 && format[0] == '\n') { @@ -270,8 +260,6 @@ void LogManager::formatted_header(RTLIL::Design *design, std::string_view format if (hdump.count(header_id) && design != nullptr) for (auto &filename : hdump.at(header_id)) { log("Dumping current design to '%s'.\n", filename); - if (yosys_xtrace) - IdString::xtrace_db_dump(); Pass::call(design, {"dump", "-o", filename}); if (yosys_xtrace) log("#X# -- end of dump --\n"); @@ -453,7 +441,6 @@ void LogManager::push() void LogManager::pop() { header_count.pop_back(); - log_id_cache_clear(); flush(); } @@ -558,12 +545,16 @@ void LogManager::reset_stack() { while (header_count.size() > 1) header_count.pop_back(); - log_id_cache_clear(); flush(); } void log_dump_val_worker(RTLIL::IdString v) { - log("%s", v.unescape()); + if (v == IdString::Null) + log("(null)"); + else if (ID::is_static(v)) + log("%s", ID::str(v)); + else + log("%s", v.handle_token().c_str()); } void log_dump_val_worker(RTLIL::SigSpec v) { @@ -577,7 +568,7 @@ void log_dump_val_worker(RTLIL::State v) { std::string log_signal(const RTLIL::SigSpec &sig, bool autoint) { std::stringstream buf; - RTLIL_BACKEND::dump_sigspec(buf, sig, autoint); + RTLIL_BACKEND::dump_sigspec(buf, sig, autoint, RTLIL_BACKEND::DumpMode::Readable); return buf.str(); } @@ -589,86 +580,24 @@ std::string log_const(const RTLIL::Const &value, bool autoint) return "\"" + value.decode_string() + "\""; } -const char *log_id_str(const std::string &str) -{ - log_id_cache.push_back(strdup(str.c_str())); - return log_id_cache.back(); -} - -static const char *log_id_cached(std::string unescaped) -{ - log_id_cache.push_back(strdup(unescaped.c_str())); - return log_id_cache.back(); -} - -const char *log_id(const IdString &str) -{ - if (str == IdString::Null) - return log_id_cached(std::string()); - if (!ID::is_static(str)) - return log_id_cached(stringf("$twine$%zu", str.untag().raw())); - return log_id_cached(RTLIL::unescape_id(ID::str(str))); -} - -static const char *log_id_twine(const RTLIL::Design *design, IdString name) -{ - return log_id_cached(RTLIL::unescape_id(design->twines.str(name))); -} - -const char *log_id(const RTLIL::Design *design, IdString name) -{ - return log_id_twine(design, name); -} - -const char *log_id(const RTLIL::Module *module, IdString name) -{ - return log_id_twine(module->design, name); -} - -const char *log_id(const RTLIL::Module *obj, const char *nullstr) -{ - if (nullstr && obj == nullptr) return nullstr; - return log_id_twine(obj->design, obj->name); -} -const char *log_id(const RTLIL::Cell *obj, const char *nullstr) -{ - if (nullstr && obj == nullptr) return nullstr; - return log_id_twine(obj->module->design, obj->name); -} -const char *log_id(const RTLIL::Wire *obj, const char *nullstr) -{ - if (nullstr && obj == nullptr) return nullstr; - return log_id_twine(obj->module->design, obj->name); -} -const char *log_id(const RTLIL::Memory *obj, const char *nullstr) -{ - if (nullstr && obj == nullptr) return nullstr; - return log_id_twine(obj->module->design, obj->name); -} -const char *log_id(const RTLIL::Process *obj, const char *nullstr) -{ - if (nullstr && obj == nullptr) return nullstr; - return log_id_twine(obj->module->design, obj->name); -} - void log_module(RTLIL::Module *module, std::string indent) { std::stringstream buf; - RTLIL_BACKEND::dump_module(buf, indent, module, module->design, false); + RTLIL_BACKEND::dump_module(buf, indent, module, module->design, false, true, false, RTLIL_BACKEND::DumpMode::Readable); log("%s", buf.str()); } void log_cell(RTLIL::Cell *cell, std::string indent) { std::stringstream buf; - RTLIL_BACKEND::dump_cell(buf, indent, cell); + RTLIL_BACKEND::dump_cell(buf, indent, cell, cell->module ? cell->module->design : nullptr, RTLIL_BACKEND::DumpMode::Readable); log("%s", buf.str()); } void log_wire(RTLIL::Wire *wire, std::string indent) { std::stringstream buf; - RTLIL_BACKEND::dump_wire(buf, indent, wire); + RTLIL_BACKEND::dump_wire(buf, indent, wire, wire->module ? wire->module->design : nullptr, RTLIL_BACKEND::DumpMode::Readable); log("%s", buf.str()); } diff --git a/kernel/log.h b/kernel/log.h index 451ba4e04..25697e7ac 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -590,29 +590,11 @@ void log_backtrace(const char *prefix, int levels); 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) { - if (nullstr && obj == nullptr) - return nullstr; - return log_id(obj->name); -} void log_module(RTLIL::Module *module, std::string indent = ""); void log_cell(RTLIL::Cell *cell, std::string indent = ""); void log_wire(RTLIL::Wire *wire, std::string indent = ""); -[[noreturn]] -void log_assert_failure(const char *expr, const char *file, int line); -#ifndef NDEBUG -static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { - if (!cond) log_assert_failure(expr, file, line); -} -# define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) -#else -# define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0) -#endif - [[noreturn]] void log_abort_internal(const char *file, int line); #define log_abort() YOSYS_NAMESPACE_PREFIX log_abort_internal(__FILE__, __LINE__) @@ -713,7 +695,7 @@ static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } -void log_dump_val_worker(RTLIL::IdString v); +void log_dump_val_worker(IdString v); void log_dump_val_worker(RTLIL::SigSpec v); void log_dump_val_worker(RTLIL::State v); diff --git a/kernel/mem.cc b/kernel/mem.cc index 63f07aad0..e6a3cf960 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -122,7 +122,7 @@ void Mem::emit() { } if (!cell) { if (memid.empty()) - memid = NEW_ID; + memid = PooledName(module->design, module->design->twines.add(NEW_ID)); cell = module->addCell(memid, ID($mem_v2)); } cell->type = ID($mem_v2); @@ -291,10 +291,8 @@ void Mem::emit() { } if (!mem) { if (memid.empty()) - memid = NEW_ID; - mem = new RTLIL::Memory; - mem->name = memid; - module->memories[memid] = mem; + memid = PooledName(module->design, module->design->twines.add(NEW_ID)); + mem = module->addMemory(memid); } mem->width = width; mem->start_offset = start_offset; @@ -349,8 +347,11 @@ void Mem::emit() { bool v2 = !init.en.is_fully_ones(); if (!init.cell) init.cell = module->addCell(NEW_ID, v2 ? ID($meminit_v2) : ID($meminit)); - else + else { + if (!v2) + init.cell->unsetPort(ID::EN); init.cell->type = v2 ? ID($meminit_v2) : ID($meminit); + } init.cell->attributes = init.attributes; init.cell->parameters[ID::MEMID] = memid.str(); init.cell->parameters[ID::ABITS] = GetSize(init.addr); @@ -361,8 +362,6 @@ void Mem::emit() { init.cell->setPort(ID::DATA, init.data); if (v2) init.cell->setPort(ID::EN, init.en); - else - init.cell->unsetPort(ID::EN); } } } @@ -544,9 +543,9 @@ void Mem::check() { namespace { struct MemIndex { - dict> rd_ports; - dict> wr_ports; - dict> inits; + dict> rd_ports; + dict> wr_ports; + dict> inits; MemIndex (Module *module) { for (auto cell: module->cells()) { if (cell->type.in(ID($memwr), ID($memwr_v2))) @@ -560,14 +559,15 @@ namespace { }; Mem mem_from_memory(Module *module, RTLIL::Memory *mem, const MemIndex &index) { + std::string memid = mem->name.str(); Mem res(module, mem->name, mem->width, mem->start_offset, mem->size); res.packed = false; res.mem = mem; res.attributes = mem->attributes; std::vector rd_transparent; std::vector wr_portid; - if (index.rd_ports.count(mem->name)) { - for (auto cell : index.rd_ports.at(mem->name)) { + if (index.rd_ports.count(memid)) { + for (auto cell : index.rd_ports.at(memid)) { MemRd mrd; bool is_compat = cell->type == ID($memrd); mrd.cell = cell; @@ -609,9 +609,9 @@ namespace { rd_transparent.push_back(transparent); } } - if (index.wr_ports.count(mem->name)) { + if (index.wr_ports.count(memid)) { std::vector> ports; - for (auto cell : index.wr_ports.at(mem->name)) { + for (auto cell : index.wr_ports.at(memid)) { MemWr mwr; bool is_compat = cell->type == ID($memwr); mwr.cell = cell; @@ -654,9 +654,9 @@ namespace { } } } - if (index.inits.count(mem->name)) { + if (index.inits.count(memid)) { std::vector> inits; - for (auto cell : index.inits.at(mem->name)) { + for (auto cell : index.inits.at(memid)) { MemInit init; init.cell = cell; init.attributes = cell->attributes; @@ -716,7 +716,7 @@ namespace { } Mem mem_from_cell(Cell *cell) { - Mem res(cell->module, cell->parameters.at(ID::MEMID).decode_string(), + Mem res(cell->module, cell->module->design->twines.add(cell->parameters.at(ID::MEMID).decode_string()), cell->parameters.at(ID::WIDTH).as_int(), cell->parameters.at(ID::OFFSET).as_int(), cell->parameters.at(ID::SIZE).as_int() @@ -887,6 +887,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (!port.clk_enable) return nullptr; + log_assert(module && module->design); + std::string memid_str = memid.str(); + Cell *c; // There are two ways to handle rdff extraction when transparency is involved: @@ -923,7 +926,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (width) { - SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid, idx), width); + SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid_str, idx), width); SigSpec sig_d; int pos = 0; @@ -933,7 +936,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { port.addr[i] = sig_q[pos++]; } - c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity); + c = module->addDff(stringf("$%s$rdreg[%d]", memid_str, idx), port.clk, sig_d, sig_q, port.clk_polarity); } else { c = nullptr; } @@ -942,7 +945,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { { log_assert(port.arst == State::S0 || port.srst == State::S0); - SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid, idx), GetSize(port.data)); + SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid_str, idx), GetSize(port.data)); SigSpec sig_d = async_d; for (int i = 0; i < GetSize(wr_ports); i++) { @@ -965,7 +968,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { raddr = port.sub_addr(sub); SigSpec addr_eq; if (raddr != waddr) - addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr); + addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid_str, idx, i, sub), raddr, waddr); int pos = 0; int ewidth = width << min_wide_log2; int wsub = wide_write ? sub : 0; @@ -978,10 +981,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos); SigSpec cond; if (raddr != waddr) - cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq); + cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid_str, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq); else cond = wport.en[pos + wsub * width]; - SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond); + SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid_str, idx, i, sub, pos), cur, other, cond); sig_d.replace(pos + rsub * width, merged); pos = epos; } @@ -989,7 +992,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } } - IdString name = stringf("$%s$rdreg[%d]", memid, idx); + IdString name = module->design->twines.add(stringf("$%s$rdreg[%d]", memid_str, idx)); FfData ff(module, initvals, name); ff.width = GetSize(port.data); ff.has_clk = true; diff --git a/kernel/mem.h b/kernel/mem.h index b35ea52c7..0d89adedd 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -91,7 +91,7 @@ struct MemInit : RTLIL::AttrObject { struct Mem : RTLIL::AttrObject { Module *module; - IdString memid; + PooledName memid; bool packed; RTLIL::Memory *mem; Cell *cell; @@ -222,7 +222,9 @@ struct Mem : RTLIL::AttrObject { // in the same clock domain. void emulate_read_first(FfInitVals *initvals); - Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(module->design, memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} + Mem(Module *module, Twine &&memid, int width, int start_offset, int size) + : Mem(module, module->design->twines.add(std::move(memid)), width, start_offset, size) {} }; // MemContents efficiently represents the contents of a potentially sparse memory by storing only those segments that are actually defined diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 067d9d89c..f1106d0ef 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1043,6 +1043,17 @@ RTLIL::Module *RTLIL::Design::module(IdString id) { return modules_.count(id) ? modules_.at(id) : NULL; } +RTLIL::Module *RTLIL::module_by_name(RTLIL::Design *design, const std::string &name) +{ + if (name.empty()) + return nullptr; + std::string escaped = escape_id(name); + for (auto module : design->modules()) + if (design->twines.name_equal(module->name, escaped)) + return module; + return nullptr; +} + RTLIL::Module *RTLIL::Design::top_module() const { RTLIL::Module *module = nullptr; @@ -1434,17 +1445,17 @@ size_t RTLIL::Module::count_id(RTLIL::IdString id) return wires_.count(id) + cells_.count(id) + memories.count(id) + processes.count(id); } -pool RTLIL::Module::object_names() const +pool RTLIL::object_names(const RTLIL::Module *module) { - const TwinePool &twines = design->twines; + const TwinePool &twines = module->design->twines; pool names; - for (auto &it : wires_) + for (auto &it : module->wires_) names.insert(twines.str(it.first)); - for (auto &it : cells_) + for (auto &it : module->cells_) names.insert(twines.str(it.first)); - for (auto &it : memories) + for (auto &it : module->memories) names.insert(twines.str(it.first)); - for (auto &it : processes) + for (auto &it : module->processes) names.insert(twines.str(it.first)); return names; } @@ -3065,6 +3076,17 @@ void RTLIL::copy_attr_dict(dict &dst, } } +RTLIL::Wire *RTLIL::wire_by_name(RTLIL::Module *module, const std::string &name) +{ + if (name.empty()) + return nullptr; + std::string escaped = escape_id(name); + for (auto wire : module->wires()) + if (module->design->twines.name_equal(wire->name, escaped)) + return wire; + return nullptr; +} + RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) { log_assert(design); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9e1ec176d..2a7429469 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1507,7 +1507,6 @@ public: virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail = false); virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); virtual size_t count_id(RTLIL::IdString id); - pool object_names() const; virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); virtual bool reprocess_if_necessary(RTLIL::Design *design); diff --git a/kernel/rtlil_twine_compat.h b/kernel/rtlil_twine_compat.h index 293db2a4e..0f5deaf1b 100644 --- a/kernel/rtlil_twine_compat.h +++ b/kernel/rtlil_twine_compat.h @@ -137,6 +137,10 @@ private: Module *owner(); }; +Module *module_by_name(Design *design, const std::string &name); +Wire *wire_by_name(Module *module, const std::string &name); +pool object_names(const Module *module); + struct PooledName : NameMasqBase { PooledName() = default; explicit PooledName(IdString id) : id_(id) {} diff --git a/kernel/scopeinfo.cc b/kernel/scopeinfo.cc index aac83d564..0bfdee9f7 100644 --- a/kernel/scopeinfo.cc +++ b/kernel/scopeinfo.cc @@ -100,13 +100,19 @@ static const char *attr_prefix(ScopeinfoAttrs attrs) bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == ID($scopeinfo)); - return scopeinfo->has_attribute(attr_prefix(attrs) + id.unescape()); + TwinePool &twines = scopeinfo->module->design->twines; + IdString key = twines.find(attr_prefix(attrs) + twines.unescaped_str(id)); + return key != IdString::Null && scopeinfo->has_attribute(key); } RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == ID($scopeinfo)); - auto found = scopeinfo->attributes.find(attr_prefix(attrs) + id.unescape()); + TwinePool &twines = scopeinfo->module->design->twines; + IdString key = twines.find(attr_prefix(attrs) + twines.unescaped_str(id)); + if (key == IdString::Null) + return RTLIL::Const(); + auto found = scopeinfo->attributes.find(key); if (found == scopeinfo->attributes.end()) return RTLIL::Const(); return found->second; @@ -117,11 +123,15 @@ dict scopeinfo_attributes(const RTLIL::Cell *scop dict attributes; const char *prefix = attr_prefix(attrs); - int prefix_len = strlen(prefix); + size_t prefix_len = strlen(prefix); + TwinePool &twines = scopeinfo->module->design->twines; - for (auto const &entry : scopeinfo->attributes) - if (entry.first.begins_with(prefix)) - attributes.emplace(RTLIL::escape_id(entry.first.c_str() + prefix_len), entry.second); + for (auto const &entry : scopeinfo->attributes) { + std::string name = twines.str(entry.first); + if (name.compare(0, prefix_len, prefix) != 0) + continue; + attributes.emplace(twines.add(RTLIL::escape_id(name.substr(prefix_len))), entry.second); + } return attributes; } diff --git a/kernel/scopeinfo.h b/kernel/scopeinfo.h index e06beb1dc..34172fbc6 100644 --- a/kernel/scopeinfo.h +++ b/kernel/scopeinfo.h @@ -219,12 +219,12 @@ public: return result; } - std::string path_str() { + std::string path_str(const RTLIL::Design *design) { std::string result; for (const auto &item : path()) { if (!result.empty()) result.push_back(' '); - result += RTLIL::unescape_id(item); + result += design->twines.unescaped_str(item); } return result; } @@ -328,7 +328,7 @@ struct ModuleItem { [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(ptr); return h; } }; -static inline void log_dump_val_worker(typename IdTree::Cursor cursor ) { log("%p %s", cursor.target, cursor.scope_name.unescape()); } +static inline void log_dump_val_worker(typename IdTree::Cursor cursor ) { log("%p ", cursor.target); log_dump_val_worker(cursor.scope_name); } template static inline void log_dump_val_worker(const typename std::unique_ptr &cursor ) { log("unique %p", cursor.get()); } @@ -336,14 +336,18 @@ static inline void log_dump_val_worker(const typename std::unique_ptr &cursor template std::vector parse_hdlname(const O* object) { + TwinePool &twines = object->design()->twines; + IdString name = object->name; std::vector path; for (auto const &item : object->get_hdlname_attribute()) - path.push_back("\\" + item); - if (path.empty() && object->name.isPublic()) - path.push_back(object->name); - if (!path.empty() && !(object->name.isPublic() || object->name.begins_with("$paramod") || object->name.begins_with("$abstract"))) { + path.push_back(twines.add("\\" + item)); + bool synthetic = !name.isPublic() && !object->name.begins_with("$paramod") + && !object->name.begins_with("$abstract"); + if (path.empty() && name.isPublic()) + path.push_back(name); + if (!path.empty() && synthetic) { path.pop_back(); - path.push_back(object->name); + path.push_back(name); } return path; } @@ -351,24 +355,25 @@ std::vector parse_hdlname(const O* object) template std::pair, IdString> parse_scopename(const O* object) { + TwinePool &twines = object->design()->twines; std::vector path; IdString trailing = object->name; - if (object->name.isPublic() || object->name.begins_with("$paramod") || object->name.begins_with("$abstract")) { + if (trailing.isPublic() || object->name.begins_with("$paramod") || object->name.begins_with("$abstract")) { for (auto const &item : object->get_hdlname_attribute()) - path.push_back("\\" + item); + path.push_back(twines.add("\\" + item)); if (!path.empty()) { trailing = path.back(); path.pop_back(); } } else if (object->has_attribute(ID::hdlname)) { for (auto const &item : object->get_hdlname_attribute()) - path.push_back("\\" + item); + path.push_back(twines.add("\\" + item)); if (!path.empty()) { path.pop_back(); } } else { for (auto const &item : split_tokens(object->get_string_attribute(ID(scopename)), " ")) - path.push_back("\\" + item); + path.push_back(twines.add("\\" + item)); } return {path, trailing}; } diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index 47c1303a1..21caae041 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -250,13 +250,15 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar ERROR("bad usage: expected \"get_attr -mod [-string|-int|-sint|-uint|-bool] \"" " or \"get_attr [-string|-int|-sint|-uint|-bool] \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(argv[i++]); if (!mod_flag) obj_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + TwineSearch search(&yosys_design->twines); + auto mod_twine = search.find(mod_id); + RTLIL::Module *mod = yosys_design->module(mod_twine); if (!mod) ERROR("module not found") @@ -264,36 +266,39 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar if (mod_flag) { obj = mod; } else { - obj = mod->wire(obj_id); + auto obj_twine = search.find(obj_id); + obj = mod->wire(obj_twine); if (!obj) - obj = mod->memories.at(obj_id, nullptr); + obj = mod->memories.at(obj_twine, nullptr); if (!obj) - obj = mod->cell(obj_id); + obj = mod->cell(obj_twine); if (!obj) - obj = mod->processes.at(obj_id, nullptr); + obj = mod->processes.at(obj_twine, nullptr); } if (!obj) ERROR("object not found") + IdString attr_twine = search.find(attr_id); + if (string_flag) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->get_string_attribute(attr_id).c_str(), -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->get_string_attribute(attr_twine).c_str(), -1)); } else if (int_flag || uint_flag || sint_flag) { - if (!obj->has_attribute(attr_id)) + if (!obj->has_attribute(attr_twine)) ERROR("attribute missing (required for -int)"); - RTLIL::Const &value = obj->attributes.at(attr_id); + RTLIL::Const &value = obj->attributes.at(attr_twine); mp_int value_mp; if (!const_to_mp_int(value, &value_mp, sint_flag, uint_flag)) ERROR("bignum manipulation failed"); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&value_mp)); } else if (bool_flag) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(obj->get_bool_attribute(attr_id))); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(obj->get_bool_attribute(attr_twine))); } else { - if (!obj->has_attribute(attr_id)) + if (!obj->has_attribute(attr_twine)) ERROR("attribute missing (required unless -bool or -string)") - Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->attributes.at(attr_id).as_string().c_str(), -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->attributes.at(attr_twine).as_string().c_str(), -1)); } return TCL_OK; @@ -313,13 +318,15 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar ERROR("bad usage: expected \"has_attr -mod \"" " or \"has_attr \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(argv[i++]); if (!mod_flag) obj_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + TwineSearch search(&yosys_design->twines); + auto mod_twine = search.find(mod_id); + RTLIL::Module *mod = yosys_design->module(mod_twine); if (!mod) ERROR("module not found") @@ -327,19 +334,20 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar if (mod_flag) { obj = mod; } else { - obj = mod->wire(obj_id); + auto obj_twine = search.find(obj_id); + obj = mod->wire(obj_twine); if (!obj) - obj = mod->memories.at(obj_id, nullptr); + obj = mod->memories.at(obj_twine, nullptr); if (!obj) - obj = mod->cell(obj_id); + obj = mod->cell(obj_twine); if (!obj) - obj = mod->processes.at(obj_id, nullptr); + obj = mod->processes.at(obj_twine, nullptr); } if (!obj) ERROR("object not found") - Tcl_SetObjResult(interp, Tcl_NewStringObj(std::to_string(obj->has_attribute(attr_id)).c_str(), -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(std::to_string(obj->has_attribute(search.find(attr_id))).c_str(), -1)); return TCL_OK; } @@ -366,13 +374,15 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const " or \"set_attr [-true|-false] \"" " or \"set_attr -mod [-true|-false| \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); if (!mod_flag) obj_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); attr_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); - RTLIL::Module *mod = yosys_design->module(mod_id); + TwineSearch search(&yosys_design->twines); + auto mod_twine = search.find(mod_id); + RTLIL::Module *mod = yosys_design->module(mod_twine); if (!mod) ERROR("module not found") @@ -380,20 +390,23 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const if (mod_flag) { obj = mod; } else { - obj = mod->wire(obj_id); + auto obj_twine = search.find(obj_id); + obj = mod->wire(obj_twine); if (!obj) - obj = mod->memories.at(obj_id, nullptr); + obj = mod->memories.at(obj_twine, nullptr); if (!obj) - obj = mod->cell(obj_id); + obj = mod->cell(obj_twine); if (!obj) - obj = mod->processes.at(obj_id, nullptr); + obj = mod->processes.at(obj_twine, nullptr); } if (!obj) ERROR("object not found") + IdString attr_twine = yosys_design->twines.add(std::string(attr_id)); + if (string_flag) { - obj->set_string_attribute(attr_id, Tcl_GetString(objv[i++])); + obj->set_string_attribute(attr_twine, Tcl_GetString(objv[i++])); } else if (sint_flag || uint_flag) { RTLIL::Const const_; mp_int value_mp; @@ -413,15 +426,15 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const const_.extu(32); } - obj->attributes[attr_id] = const_; + obj->attributes[attr_twine] = const_; } else if (bool_flag) { - obj->set_bool_attribute(attr_id, atoi(Tcl_GetString(objv[i++])) != 0); + obj->set_bool_attribute(attr_twine, atoi(Tcl_GetString(objv[i++])) != 0); } else if (true_flag) { - obj->set_bool_attribute(attr_id, true); + obj->set_bool_attribute(attr_twine, true); } else if (false_flag) { - obj->set_bool_attribute(attr_id, false); + obj->set_bool_attribute(attr_twine, false); } else { - obj->attributes[attr_id] = Const::from_string(std::string(Tcl_GetString(objv[i++]))); + obj->attributes[attr_twine] = Const::from_string(std::string(Tcl_GetString(objv[i++]))); } return TCL_OK; @@ -444,23 +457,27 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a (string_flag + int_flag > 1)) ERROR("bad usage: expected \"get_param [-string|-int|-sint|-uint] ") - IdString mod_id, cell_id, param_id; + std::string mod_id, cell_id, param_id; mod_id = RTLIL::escape_id(argv[i++]); cell_id = RTLIL::escape_id(argv[i++]); param_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + TwineSearch search(&yosys_design->twines); + auto mod_twine = search.find(mod_id); + RTLIL::Module *mod = yosys_design->module(mod_twine); if (!mod) ERROR("module not found") - RTLIL::Cell *cell = mod->cell(cell_id); + auto cell_twine = search.find(cell_id); + Cell* cell = mod->cell(cell_twine); if (!cell) ERROR("object not found") - if (!cell->hasParam(param_id)) + IdString param_twine = search.find(param_id); + if (!cell->hasParam(param_twine)) ERROR("parameter missing") - const RTLIL::Const &value = cell->getParam(param_id); + const RTLIL::Const &value = cell->getParam(param_twine); if (string_flag) { Tcl_SetObjResult(interp, Tcl_NewStringObj(value.decode_string().c_str(), -1)); @@ -490,21 +507,26 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons (string_flag + sint_flag + uint_flag > 1)) ERROR("bad usage: expected \"set_param [-string|-sint|-uint] ") - IdString mod_id, cell_id, param_id; + std::string mod_id, cell_id, param_id; mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); cell_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); param_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); - RTLIL::Module *mod = yosys_design->module(mod_id); + TwineSearch search(&yosys_design->twines); + auto mod_twine = search.find(mod_id); + RTLIL::Module *mod = yosys_design->module(mod_twine); if (!mod) ERROR("module not found") - RTLIL::Cell *cell = mod->cell(cell_id); + auto cell_twine = search.find(cell_id); + RTLIL::Cell *cell = mod->cell(cell_twine); if (!cell) ERROR("object not found") + IdString param_twine = yosys_design->twines.add(std::string(param_id)); + if (string_flag) { - cell->setParam(param_id, Const(std::string(Tcl_GetString(objv[i++])))); + cell->setParam(param_twine, Const(std::string(Tcl_GetString(objv[i++])))); } else if (sint_flag || uint_flag) { RTLIL::Const const_; mp_int value_mp; @@ -524,9 +546,9 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons const_.extu(32); } - cell->setParam(param_id, const_); + cell->setParam(param_twine, const_); } else { - cell->setParam(param_id, Const::from_string(std::string(Tcl_GetString(objv[i++])))); + cell->setParam(param_twine, Const::from_string(std::string(Tcl_GetString(objv[i++])))); } return TCL_OK; } diff --git a/kernel/twine.cc b/kernel/twine.cc index 9109ae8bb..0a11b908c 100644 --- a/kernel/twine.cc +++ b/kernel/twine.cc @@ -23,6 +23,22 @@ int twine_gc_count; Hasher IdString::hash_into(Hasher h) const { h.hash64(value); return h; } +std::string IdString::handle_token() const { + return stringf("%s@%zu", isPublic() ? "$pub" : "$priv", untag().raw()); +} + +size_t IdString::handle_token_prefix(std::string_view token, bool &is_public) { + if (token.substr(0, 5) == "$pub@") { + is_public = true; + return 5; + } + if (token.substr(0, 6) == "$priv@") { + is_public = false; + return 6; + } + return 0; +} + std::string ID::str(IdString ref) { IdString idx = ref.untag(); log_assert(idx.raw() < STATIC_TWINE_END); diff --git a/kernel/twine.h b/kernel/twine.h index 097172802..0568e2cc9 100644 --- a/kernel/twine.h +++ b/kernel/twine.h @@ -91,6 +91,9 @@ public: } Hasher hash_into(Hasher h) const; + + std::string handle_token() const; + static size_t handle_token_prefix(std::string_view token, bool &is_public); }; constexpr NullIdString::operator IdString() const { return IdString(); } diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h index 9e19814bd..1ae5eae54 100644 --- a/kernel/yosys_common.h +++ b/kernel/yosys_common.h @@ -200,7 +200,6 @@ struct shared_str { }; namespace RTLIL { - struct IdString; struct Const; struct SigBit; struct SigSpec; @@ -213,18 +212,16 @@ namespace RTLIL { struct Monitor; struct Selection; struct SigChunk; + struct PooledName; enum State : unsigned char; typedef std::pair SigSig; - - namespace ID {} } namespace AST { struct AstNode; } -using RTLIL::IdString; using RTLIL::Const; using RTLIL::SigBit; using RTLIL::SigSpec; @@ -236,6 +233,7 @@ using RTLIL::Design; using RTLIL::State; using RTLIL::SigChunk; using RTLIL::SigSig; +using RTLIL::PooledName; namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; @@ -267,6 +265,17 @@ inline void memhasher() { if (memhasher_active) memhasher_do(); } void yosys_banner(); int ceil_log2(int x) YS_ATTRIBUTE(const); +[[noreturn]] +void log_assert_failure(const char *expr, const char *file, int line); +#ifndef NDEBUG +static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { + if (!cond) log_assert_failure(expr, file, line); +} +# define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) +#else +# define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0) +#endif + template int GetSize(const T &obj) { return obj.size(); } inline int GetSize(RTLIL::Wire *wire); @@ -298,18 +307,17 @@ extern int yosys_xtrace; extern bool yosys_write_versions; const std::string *create_id_prefix(std::string_view file, int line, std::string_view func); -RTLIL::IdString new_id_suffix(std::string_view file, int line, std::string_view func, std::string_view suffix); #define NEW_ID \ - YOSYS_NAMESPACE_PREFIX RTLIL::IdString::new_autoidx_with_prefix([](std::string_view func) -> const std::string * { \ + YOSYS_NAMESPACE_PREFIX Twine{YOSYS_NAMESPACE_PREFIX Twine::AutoSuffix{[](std::string_view func) -> std::string_view { \ static std::unique_ptr prefix(YOSYS_NAMESPACE_PREFIX create_id_prefix(__FILE__, __LINE__, func)); \ - return prefix.get(); \ - }(__FUNCTION__)) + return *prefix; \ + }(__FUNCTION__), std::to_string(YOSYS_NAMESPACE_PREFIX autoidx++)}} #define NEW_ID_SUFFIX(suffix) \ - YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) - -namespace ID = RTLIL::ID; - + YOSYS_NAMESPACE_PREFIX Twine{YOSYS_NAMESPACE_PREFIX Twine::AutoSuffix{[](std::string_view func) -> std::string_view { \ + static std::unique_ptr prefix(YOSYS_NAMESPACE_PREFIX create_id_prefix(__FILE__, __LINE__, func)); \ + return *prefix; \ + }(__FUNCTION__), std::string(suffix) + "$" + std::to_string(YOSYS_NAMESPACE_PREFIX autoidx++)}} YOSYS_NAMESPACE_END