kernel: twine damage for utilities that key or search on names

This commit is contained in:
Emil J. Tywoniak
2026-10-02 18:42:01 +02:00
parent a028dc4330
commit ad2cbdd2be
19 changed files with 278 additions and 253 deletions
+4 -2
View File
@@ -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);
+9 -3
View File
@@ -65,10 +65,16 @@ struct CellTypes
cell_types[ct.type] = ct;
}
template<typename N, YS_NAME_STRING(N)>
void setup_type(const N &type_str, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &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<RTLIL::IdString> inputs, outputs;
for (RTLIL::IdString wire_name : module->ports) {
pool<IdString> 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)
+4
View File
@@ -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.
+3 -2
View File
@@ -29,7 +29,7 @@ bool FfMergeHelper::is_output_unused(RTLIL::SigSpec sig) {
}
bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair<Cell *, int>> &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<std::pai
}
bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair<Cell *, int>> &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<std::pair<Cell *, int>> &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));
}
}
+13 -12
View File
@@ -120,8 +120,8 @@ struct PrintVisitor : DefaultVisitor<std::string> {
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;
+34 -28
View File
@@ -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<RTLIL::Const, MemContents> _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<std::pair<IdString, IdString>, 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<class Visitor> auto visit(Visitor v) const
{
@@ -364,15 +363,21 @@ namespace Functional {
std::string to_string();
std::string to_string(std::function<std::string(Node)>);
};
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<Node> IR::iterator::operator->() { return arrow_proxy<Node>(**this); }
// AbstractVisitor provides an abstract base class for visitors
template<class T> 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 Id> 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<typename N> 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<typename N> std::string operator()(Id id, const N &suggestion) {
auto it = _by_id.find(id);
if(it != _by_id.end())
return it->second;
+10 -81
View File
@@ -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<char*> 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());
}
+1 -19
View File
@@ -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<typename T> 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);
+28 -25
View File
@@ -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<IdString, pool<Cell *>> rd_ports;
dict<IdString, pool<Cell *>> wr_ports;
dict<IdString, pool<Cell *>> inits;
dict<std::string, pool<Cell *>> rd_ports;
dict<std::string, pool<Cell *>> wr_ports;
dict<std::string, pool<Cell *>> 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<bool> rd_transparent;
std::vector<int> 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<std::pair<int, MemWr>> 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<std::pair<int, MemInit>> 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;
+4 -2
View File
@@ -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
+28 -6
View File
@@ -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<std::string> RTLIL::Module::object_names() const
pool<std::string> RTLIL::object_names(const RTLIL::Module *module)
{
const TwinePool &twines = design->twines;
const TwinePool &twines = module->design->twines;
pool<std::string> 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<IdString, RTLIL::Const> &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);
-1
View File
@@ -1507,7 +1507,6 @@ public:
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual size_t count_id(RTLIL::IdString id);
pool<std::string> object_names() const;
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual bool reprocess_if_necessary(RTLIL::Design *design);
+4
View File
@@ -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<std::string> object_names(const Module *module);
struct PooledName : NameMasqBase<PooledName> {
PooledName() = default;
explicit PooledName(IdString id) : id_(id) {}
+16 -6
View File
@@ -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<RTLIL::IdString, RTLIL::Const> scopeinfo_attributes(const RTLIL::Cell *scop
dict<RTLIL::IdString, RTLIL::Const> 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;
}
+17 -12
View File
@@ -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<ModuleItem>::Cursor cursor ) { log("%p %s", cursor.target, cursor.scope_name.unescape()); }
static inline void log_dump_val_worker(typename IdTree<ModuleItem>::Cursor cursor ) { log("%p ", cursor.target); log_dump_val_worker(cursor.scope_name); }
template<typename T>
static inline void log_dump_val_worker(const typename std::unique_ptr<T> &cursor ) { log("unique %p", cursor.get()); }
@@ -336,14 +336,18 @@ static inline void log_dump_val_worker(const typename std::unique_ptr<T> &cursor
template<typename O>
std::vector<IdString> parse_hdlname(const O* object)
{
TwinePool &twines = object->design()->twines;
IdString name = object->name;
std::vector<IdString> 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<IdString> parse_hdlname(const O* object)
template<typename O>
std::pair<std::vector<IdString>, IdString> parse_scopename(const O* object)
{
TwinePool &twines = object->design()->twines;
std::vector<IdString> 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};
}
+64 -42
View File
@@ -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] <module> <attrname>\""
" or \"get_attr [-string|-int|-sint|-uint|-bool] <module> <identifier> <attrname>\"")
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 <module> <attrname>\""
" or \"has_attr <module> <identifier> <attrname>\"")
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] <module> <identifier> <attrname>\""
" or \"set_attr -mod [-true|-false| <module> <attrname>\"")
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] <module> <cellid> <paramname>")
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] <module> <cellid> <paramname> <value>")
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;
}
+16
View File
@@ -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);
+3
View File
@@ -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(); }
+20 -12
View File
@@ -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<SigSpec, SigSpec> 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<RTLIL::Wire*> : 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<typename T> 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<const std::string> 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<const std::string> 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