mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
rtlil: evacuate src_id_ from AttrObject to per-Design meta vector
This commit is contained in:
parent
e70eed3296
commit
f1edb571f2
22 changed files with 668 additions and 390 deletions
|
|
@ -122,7 +122,7 @@ struct BtorWorker
|
|||
string infostr = obj->name.unescape();
|
||||
if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
|
||||
if (obj->has_attribute(ID::src)) {
|
||||
string raw_src = module && module->design ? obj->get_src_attribute(&module->design->src_twines) : std::string();
|
||||
string raw_src = module && module->design ? module->design->get_src_attribute(obj) : std::string();
|
||||
string src = module && module->design ? module->design->resolve_src(raw_src) : raw_src;
|
||||
if (srcsym && infostr[0] == '$') {
|
||||
std::replace(src.begin(), src.end(), ' ', '_');
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static const int FIRRTL_MAX_DSH_WIDTH_ERROR = 20; // For historic reasons, this
|
|||
|
||||
std::string getFileinfo(const RTLIL::AttrObject *design_entity, const RTLIL::Design *design = nullptr)
|
||||
{
|
||||
std::string src = design ? design_entity->get_src_attribute(&design->src_twines) : std::string();
|
||||
std::string src = design ? design->get_src_attribute(design_entity) : std::string();
|
||||
std::string fileinfo_str = src.empty() ? "" : "@[" + src + "]";
|
||||
return fileinfo_str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ struct JsonWriter
|
|||
bool first = true;
|
||||
// Emit the typed src field first if present — it lives outside the
|
||||
// attribute dict after the typed-src migration.
|
||||
if (src_obj && src_obj->src_id() != Twine::Null && design) {
|
||||
if (src_obj && design && design->obj_src_id(src_obj) != Twine::Null) {
|
||||
f << stringf("\n %s%s: ", for_module ? "" : " ", get_name(RTLIL::ID::src));
|
||||
write_parameter_value(RTLIL::Const(src_obj->get_src_attribute(&design->src_twines)));
|
||||
write_parameter_value(RTLIL::Const(design->get_src_attribute(src_obj)));
|
||||
first = false;
|
||||
}
|
||||
for (auto ¶m : parameters) {
|
||||
|
|
|
|||
|
|
@ -37,12 +37,13 @@ void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const R
|
|||
// Emit the typed src field first. It is not stored in obj->attributes
|
||||
// — the dict no longer holds ID::src under any circumstance. Backends
|
||||
// that want to materialize the pipe-joined literal pass resolve_src.
|
||||
if (obj->src_id() != Twine::Null && design) {
|
||||
if (design && design->obj_src_id(obj) != Twine::Null) {
|
||||
Twine::Id id = design->obj_src_id(obj);
|
||||
f << stringf("%s" "attribute \\src ", indent);
|
||||
if (resolve_src) {
|
||||
dump_const(f, RTLIL::Const(design->src_twines.flatten(obj->src_id())));
|
||||
dump_const(f, RTLIL::Const(design->src_twines.flatten(id)));
|
||||
} else {
|
||||
dump_const(f, RTLIL::Const(TwinePool::format_ref(obj->src_id())));
|
||||
dump_const(f, RTLIL::Const(TwinePool::format_ref(id)));
|
||||
}
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,7 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast)
|
|||
return;
|
||||
const auto &loc = ast->location;
|
||||
if (!loc.begin.filename || loc.begin.filename->empty()) {
|
||||
obj->set_src_attribute(¤t_module->design->src_twines, ast->loc_string());
|
||||
current_module->design->set_src_attribute(obj, ast->loc_string());
|
||||
return;
|
||||
}
|
||||
// Split filename and per-location tail so the filename interns once
|
||||
|
|
@ -1129,8 +1129,8 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast)
|
|||
loc.end.line, loc.end.column);
|
||||
Twine::Id suffix_id = pool->intern_suffix(file_id, tail);
|
||||
pool->release(file_id); // suffix internally holds a ref now
|
||||
obj->set_src_id(pool, suffix_id);
|
||||
pool->release(suffix_id); // set_src_id retained on obj's behalf
|
||||
current_module->design->obj_set_src_id(obj, suffix_id);
|
||||
pool->release(suffix_id); // obj_set_src_id retained on obj's behalf
|
||||
}
|
||||
|
||||
static bool param_has_no_default(const AstNode* param) {
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
|||
auto already_exists = [&](const RTLIL::AttrObject *existing, const char *existing_kind) {
|
||||
std::string src;
|
||||
if (module->design)
|
||||
src = existing->get_src_attribute(&module->design->src_twines);
|
||||
src = module->design->get_src_attribute(existing);
|
||||
std::string location_str = "earlier";
|
||||
if (!src.empty())
|
||||
location_str = "at " + src;
|
||||
|
|
|
|||
|
|
@ -288,9 +288,9 @@ void json_parse_attr_param(dict<IdString, Const> &results, JsonNode *node)
|
|||
}
|
||||
|
||||
// AttrObject-aware overload: extracts ID::src and routes it to the typed
|
||||
// src_id_ field via set_src_attribute. Other keys still land in the
|
||||
// attributes dict via the generic path.
|
||||
void json_parse_attributes(TwinePool *pool, RTLIL::AttrObject *obj, JsonNode *node)
|
||||
// meta-vector slot via Design::set_src_attribute. Other keys still land
|
||||
// in the attributes dict via the generic path.
|
||||
void json_parse_attributes(RTLIL::Design *design, RTLIL::AttrObject *obj, JsonNode *node)
|
||||
{
|
||||
if (node->type != 'D')
|
||||
log_error("JSON attributes or parameters node is not a dictionary.\n");
|
||||
|
|
@ -300,7 +300,7 @@ void json_parse_attributes(TwinePool *pool, RTLIL::AttrObject *obj, JsonNode *no
|
|||
IdString key = RTLIL::escape_id(it.first.c_str());
|
||||
Const value = json_parse_attr_param_value(it.second);
|
||||
if (key == ID::src && (value.flags & RTLIL::CONST_FLAG_STRING))
|
||||
obj->set_src_attribute(pool, value.decode_string());
|
||||
design->set_src_attribute(obj, value.decode_string());
|
||||
else
|
||||
obj->attributes[key] = value;
|
||||
}
|
||||
|
|
@ -319,7 +319,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
design->add(module);
|
||||
|
||||
if (node->data_dict.count("attributes"))
|
||||
json_parse_attributes(&design->src_twines, module, node->data_dict.at("attributes"));
|
||||
json_parse_attributes(design, module, node->data_dict.at("attributes"));
|
||||
|
||||
if (node->data_dict.count("parameter_default_values"))
|
||||
json_parse_attr_param(module->parameter_default_values, node->data_dict.at("parameter_default_values"));
|
||||
|
|
@ -502,7 +502,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
}
|
||||
|
||||
if (net_node->data_dict.count("attributes"))
|
||||
json_parse_attributes(&design->src_twines, wire, net_node->data_dict.at("attributes"));
|
||||
json_parse_attributes(design, wire, net_node->data_dict.at("attributes"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -583,7 +583,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
}
|
||||
|
||||
if (cell_node->data_dict.count("attributes"))
|
||||
json_parse_attributes(&design->src_twines, cell, cell_node->data_dict.at("attributes"));
|
||||
json_parse_attributes(design, cell, cell_node->data_dict.at("attributes"));
|
||||
|
||||
if (cell_node->data_dict.count("parameters"))
|
||||
json_parse_attr_param(cell->parameters, cell_node->data_dict.at("parameters"));
|
||||
|
|
@ -631,7 +631,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
}
|
||||
|
||||
if (memory_node->data_dict.count("attributes"))
|
||||
json_parse_attributes(&design->src_twines, mem, memory_node->data_dict.at("attributes"));
|
||||
json_parse_attributes(design, mem, memory_node->data_dict.at("attributes"));
|
||||
|
||||
module->memories[mem->name] = mem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ struct RTLILFrontendWorker {
|
|||
current_module->attributes = std::move(attrbuf);
|
||||
} else {
|
||||
design->add(current_module);
|
||||
current_module->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
current_module->absorb_attrs(std::move(attrbuf));
|
||||
}
|
||||
|
||||
while (true)
|
||||
|
|
@ -666,7 +666,7 @@ struct RTLILFrontendWorker {
|
|||
error("Unexpected wire option: %s", error_token());
|
||||
}
|
||||
|
||||
wire->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
wire->absorb_attrs(std::move(attrbuf));
|
||||
wire->width = width;
|
||||
wire->upto = upto;
|
||||
wire->start_offset = start_offset;
|
||||
|
|
@ -681,7 +681,7 @@ struct RTLILFrontendWorker {
|
|||
{
|
||||
RTLIL::Memory *memory = new RTLIL::Memory;
|
||||
memory->module = current_module;
|
||||
memory->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
memory->absorb_attrs(std::move(attrbuf));
|
||||
|
||||
int width = 1;
|
||||
int start_offset = 0;
|
||||
|
|
@ -749,7 +749,7 @@ struct RTLILFrontendWorker {
|
|||
error("RTLIL error: redefinition of cell %s.", cell_name);
|
||||
}
|
||||
RTLIL::Cell *cell = current_module->addCell(cell_name, cell_type);
|
||||
cell->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
cell->absorb_attrs(std::move(attrbuf));
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -839,7 +839,7 @@ struct RTLILFrontendWorker {
|
|||
{
|
||||
RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
|
||||
rule->signal = parse_sigspec();
|
||||
rule->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
rule->absorb_attrs(std::move(attrbuf));
|
||||
switch_stack.back()->push_back(rule);
|
||||
expect_eol();
|
||||
|
||||
|
|
@ -856,7 +856,7 @@ struct RTLILFrontendWorker {
|
|||
|
||||
expect_keyword("case");
|
||||
RTLIL::CaseRule *case_rule = new RTLIL::CaseRule;
|
||||
case_rule->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
case_rule->absorb_attrs(std::move(attrbuf));
|
||||
rule->cases.push_back(case_rule);
|
||||
switch_stack.push_back(&case_rule->switches);
|
||||
case_stack.push_back(case_rule);
|
||||
|
|
@ -890,7 +890,7 @@ struct RTLILFrontendWorker {
|
|||
error("RTLIL error: redefinition of process %s.", proc_name);
|
||||
}
|
||||
RTLIL::Process *proc = current_module->addProcess(std::move(proc_name));
|
||||
proc->absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
proc->absorb_attrs(std::move(attrbuf));
|
||||
|
||||
switch_stack.clear();
|
||||
switch_stack.push_back(&proc->root_case.switches);
|
||||
|
|
@ -939,13 +939,18 @@ struct RTLILFrontendWorker {
|
|||
break;
|
||||
|
||||
RTLIL::MemWriteAction act;
|
||||
act.absorb_attrs(&design->src_twines, std::move(attrbuf));
|
||||
act.module = current_module;
|
||||
design->absorb_attrs(&act, std::move(attrbuf));
|
||||
act.memid = parse_id();
|
||||
act.address = parse_sigspec();
|
||||
act.data = parse_sigspec();
|
||||
act.enable = parse_sigspec();
|
||||
act.priority_mask = parse_const();
|
||||
rule->mem_write_actions.push_back(std::move(act));
|
||||
rule->mem_write_actions.push_back(act);
|
||||
// meta_idx_ is a weak ref — drop ours so the pushed copy
|
||||
// in the vector is the sole holder. Process::~Process
|
||||
// walks the tree to actually release.
|
||||
act.meta_idx_ = RTLIL::AttrObject::NO_META;
|
||||
expect_eol();
|
||||
}
|
||||
// The old parser allowed dangling attributes before a "sync" to carry through
|
||||
|
|
|
|||
|
|
@ -770,13 +770,13 @@ Cell *FfData::emit() {
|
|||
if (!src_twine.empty() && cell->module && cell->module->design) {
|
||||
TwinePool *dst_pool = &cell->module->design->src_twines;
|
||||
if (src_twine.pool() == dst_pool) {
|
||||
cell->set_src_id(dst_pool, src_twine.id());
|
||||
cell->set_src_id(src_twine.id());
|
||||
} else {
|
||||
// Cross-pool (unusual — FfData migrated between
|
||||
// designs). Rebuild the twine structure into the
|
||||
// destination pool, then adopt that fresh id.
|
||||
Twine::Id migrated = dst_pool->copy_from(*src_twine.pool(), src_twine.id());
|
||||
cell->set_src_id(dst_pool, migrated);
|
||||
cell->set_src_id(migrated);
|
||||
dst_pool->release(migrated);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -895,8 +895,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
// "@N" parse_ref path), and there's no flatten → re-intern → pipe-
|
||||
// leaf round-trip on cells whose src is a Concat node.
|
||||
TwinePool *src_pool = (module && module->design) ? &module->design->src_twines : nullptr;
|
||||
std::string mem_src = (src_pool && src_id_ != Twine::Null) ?
|
||||
TwinePool::format_ref(src_id_) : std::string();
|
||||
Twine::Id mem_src_id = (module && module->design) ? module->design->obj_src_id(this) : Twine::Null;
|
||||
std::string mem_src = (src_pool && mem_src_id != Twine::Null) ?
|
||||
TwinePool::format_ref(mem_src_id) : std::string();
|
||||
|
||||
Cell *c;
|
||||
|
||||
|
|
@ -1004,8 +1005,8 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
FfData ff(module, initvals, name);
|
||||
// Carry mem's src into the ff via the OwnedTwine handle — same
|
||||
// pool, direct id retain. emit() transfers verbatim.
|
||||
if (src_pool && src_id_ != Twine::Null)
|
||||
ff.src_twine = OwnedTwine(src_pool, src_id_);
|
||||
if (src_pool && mem_src_id != Twine::Null)
|
||||
ff.src_twine = OwnedTwine(src_pool, mem_src_id);
|
||||
ff.width = GetSize(port.data);
|
||||
ff.has_clk = true;
|
||||
ff.sig_clk = port.clk;
|
||||
|
|
|
|||
721
kernel/rtlil.cc
721
kernel/rtlil.cc
File diff suppressed because it is too large
Load diff
204
kernel/rtlil.h
204
kernel/rtlil.h
|
|
@ -1295,17 +1295,21 @@ struct RTLIL::AttrObject
|
|||
{
|
||||
dict<RTLIL::IdString, RTLIL::Const> attributes;
|
||||
|
||||
// Typed src field. Outside the attribute dict — src is a structured
|
||||
// reference into a TwinePool. The pool is NOT stored here: every live
|
||||
// AttrObject is reachable from a Design (Cell/Wire/Process via their
|
||||
// module, Module via its design field), and inner-process AttrObjects
|
||||
// (CaseRule, SwitchRule, MemWriteAction) are owned by a Process whose
|
||||
// dtor drives their refcount on their behalf. src_id_ is a "weak"
|
||||
// integer reference — copying it does not retain; destroying the
|
||||
// AttrObject does not release. Lifecycle is driven by the leaf
|
||||
// subtype's destructor (Cell, Wire, Module, Process) walking up to
|
||||
// its owning pool, and by Process::~Process for the nested types.
|
||||
Twine::Id src_id_ = Twine::Null;
|
||||
// Per-Design metadata slot index, or NO_META. The slot lives in
|
||||
// Design::obj_meta_src_ and holds this object's Twine::Id src; the
|
||||
// slot is allocated lazily on the first non-null src write and
|
||||
// freed when src returns to null. Per-object cost is just this
|
||||
// 4-byte index (replacing the prior inline 4-byte src_id_).
|
||||
//
|
||||
// AttrObject can't resolve its owning Design on its own. Lookups
|
||||
// route either through a leaf subtype's src_id() sugar (which knows
|
||||
// its container chain — Cell/Wire/Process/Memory via module->design,
|
||||
// Module via design, CaseRule/SwitchRule/MemWriteAction via the
|
||||
// module back-pointer added in prior commits) or through the
|
||||
// Design::obj_src_id / obj_set_src_id / obj_release_src helpers
|
||||
// when generic AttrObject* code already has a Design* in hand.
|
||||
static constexpr uint32_t NO_META = ~0u;
|
||||
uint32_t meta_idx_ = NO_META;
|
||||
|
||||
bool has_attribute(RTLIL::IdString id) const;
|
||||
|
||||
|
|
@ -1325,50 +1329,6 @@ struct RTLIL::AttrObject
|
|||
void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
|
||||
pool<string> get_strpool_attribute(RTLIL::IdString id) const;
|
||||
|
||||
Twine::Id src_id() const { return src_id_; }
|
||||
|
||||
// Store an interned id and manage refcount via the provided pool:
|
||||
// retain the new id; release the previous one if any. Twine::Null
|
||||
// clears. The caller supplies the pool because AttrObject does not
|
||||
// store one — typically derived from context (cell->module->design->
|
||||
// src_twines and friends) or known directly (frontends, copy_from).
|
||||
void set_src_id(TwinePool *pool, Twine::Id id);
|
||||
|
||||
// Apply `src` to this AttrObject via `pool`. If `src` carries a
|
||||
// pre-interned id (returned by e.g. `other->src_ref()`) it is
|
||||
// retained directly — no flatten/intern. Otherwise `src.literal`
|
||||
// is interned (handling "@N" refs and splitting pipe-joined
|
||||
// multi-leaf inputs into a Concat). Empty `src` clears src_id_.
|
||||
void set_src_attribute(TwinePool *pool, const RTLIL::SrcAttr &src);
|
||||
// Flatten the held src_id_ via `pool` to its pipe-joined literal.
|
||||
std::string get_src_attribute(const TwinePool *pool) const;
|
||||
|
||||
// Transfer src verbatim from `source` to this object. The two-arg
|
||||
// form assumes same-pool: `source`'s src_id_ is retained directly
|
||||
// on the destination in `pool`. The three-arg form handles the
|
||||
// cross-pool case by rebuilding `source`'s subtree (Concat/Suffix/
|
||||
// Leaf) into `dst_pool` via copy_from. Either way no flatten/
|
||||
// re-intern round-trip on the canonical leaf strings, so a Concat
|
||||
// src never collapses into a pipe-containing Leaf.
|
||||
void adopt_src_from(TwinePool *pool, const RTLIL::AttrObject *source);
|
||||
void adopt_src_from(TwinePool *dst_pool, const RTLIL::AttrObject *source,
|
||||
const TwinePool *src_pool);
|
||||
|
||||
// The raw twine id naming this object's src. Pass this — never the
|
||||
// flattened path string from get_src_attribute() — when handing
|
||||
// src to a CellAdder method or to another object's set_src: every
|
||||
// CellAdder method has a Twine::Id overload that adopts the slot
|
||||
// directly with no flatten/intern round-trip, preserving Suffix/
|
||||
// Concat structure and never producing a pipe-containing Leaf
|
||||
// from a Concat src.
|
||||
Twine::Id src_ref() const { return src_id_; }
|
||||
|
||||
// Replace `attributes` with `buf`, extracting any ID::src entry first
|
||||
// and routing it via `pool` to the typed src_id_ field. Use this in
|
||||
// frontends instead of `obj->attributes = std::move(buf)` so file src
|
||||
// lands in the twine pool rather than the attribute dict.
|
||||
void absorb_attrs(TwinePool *pool, dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
void set_hdlname_attribute(const vector<string> &hierarchy);
|
||||
vector<string> get_hdlname_attribute() const;
|
||||
|
||||
|
|
@ -2009,6 +1969,46 @@ struct RTLIL::Design
|
|||
uint32_t alloc_obj_meta();
|
||||
void free_obj_meta(uint32_t idx);
|
||||
|
||||
// Read src for `meta_idx`. NO_META → Twine::Null.
|
||||
Twine::Id obj_src_id_by_idx(uint32_t meta_idx) const {
|
||||
if (meta_idx == RTLIL::AttrObject::NO_META)
|
||||
return Twine::Null;
|
||||
return obj_meta_src_[meta_idx];
|
||||
}
|
||||
|
||||
// Set src for `meta_idx`, allocating a slot lazily and freeing it
|
||||
// when `id` is Twine::Null. Manages retain/release on src_twines.
|
||||
// `meta_idx` is mutated as needed (NO_META -> allocated slot, or
|
||||
// allocated slot -> NO_META after clearing).
|
||||
void obj_set_src_id_by_idx(uint32_t &meta_idx, Twine::Id id);
|
||||
|
||||
// Release the slot's Twine ref and free the index. No-op if NO_META.
|
||||
// Use from destructors. `meta_idx` becomes NO_META on return.
|
||||
void obj_release_src_by_idx(uint32_t &meta_idx);
|
||||
|
||||
// AttrObject-keyed convenience overloads — dispatch to the _by_idx
|
||||
// versions on obj->meta_idx_. Use these from generic helpers that
|
||||
// already have a Design* in scope.
|
||||
Twine::Id obj_src_id(const RTLIL::AttrObject *obj) const {
|
||||
return obj_src_id_by_idx(obj->meta_idx_);
|
||||
}
|
||||
void obj_set_src_id(RTLIL::AttrObject *obj, Twine::Id id) {
|
||||
obj_set_src_id_by_idx(obj->meta_idx_, id);
|
||||
}
|
||||
void obj_release_src(RTLIL::AttrObject *obj) {
|
||||
obj_release_src_by_idx(obj->meta_idx_);
|
||||
}
|
||||
|
||||
// Replacements for the methods that used to live on AttrObject and
|
||||
// took an explicit TwinePool*. Same semantics; the pool resolves
|
||||
// to this->src_twines internally.
|
||||
void set_src_attribute(RTLIL::AttrObject *obj, const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute(const RTLIL::AttrObject *obj) const;
|
||||
void adopt_src_from(RTLIL::AttrObject *obj, const RTLIL::AttrObject *source);
|
||||
void adopt_src_from(RTLIL::AttrObject *obj, const RTLIL::AttrObject *source,
|
||||
const TwinePool *src_pool);
|
||||
void absorb_attrs(RTLIL::AttrObject *obj, dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
// Resolve a stored src-attribute string to its flat path:line.col
|
||||
// representation. If `raw` is a twine reference ("@N") returns
|
||||
// src_twines.flatten(N); otherwise returns `raw` unchanged. Backends
|
||||
|
|
@ -2239,16 +2239,17 @@ public:
|
|||
int width, start_offset, port_id;
|
||||
bool port_input, port_output, upto, is_signed;
|
||||
|
||||
// Context-aware src helpers. Resolve the destination pool via
|
||||
// `module->design->src_twines`; assert the wire is attached.
|
||||
using AttrObject::set_src_attribute;
|
||||
using AttrObject::get_src_attribute;
|
||||
using AttrObject::adopt_src_from;
|
||||
// Context-aware src helpers. Resolve Design via module->design and
|
||||
// route to the per-Design meta vector; assert the wire is attached.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
// Transfer src from `source` verbatim (same pool). Asserts attached
|
||||
// to a design — derives the pool via module->design->src_twines.
|
||||
// to a design.
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
bool known_driver() const { return driverCell_ != nullptr; }
|
||||
|
||||
|
|
@ -2285,17 +2286,26 @@ struct RTLIL::Memory : public RTLIL::NamedObject
|
|||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
||||
Memory();
|
||||
~Memory();
|
||||
|
||||
// Back-pointer to the owning module — same role as Cell::module /
|
||||
// Wire::module. Set by Module::addMemory / the frontends that
|
||||
// construct Memory free-standing before attaching to a module.
|
||||
// Lets Memory's src access (and the upcoming per-Design meta vector
|
||||
// lookup) resolve uniformly via module->design.
|
||||
// Lets Memory's src access resolve uniformly via module->design.
|
||||
RTLIL::Module *module = nullptr;
|
||||
|
||||
// Context-aware src helpers. Resolve Design via module->design and
|
||||
// route to the per-Design meta vector; assert the memory is attached.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
int width, start_offset, size;
|
||||
#ifdef YOSYS_ENABLE_PYTHON
|
||||
~Memory();
|
||||
static std::map<unsigned int, RTLIL::Memory*> *get_all_memorys(void);
|
||||
#endif
|
||||
|
||||
|
|
@ -2334,16 +2344,15 @@ public:
|
|||
dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
|
||||
dict<RTLIL::IdString, RTLIL::Const> parameters;
|
||||
|
||||
// Context-aware src helpers. Resolve the destination pool via
|
||||
// `module->design->src_twines`; assert the cell is attached.
|
||||
using AttrObject::set_src_attribute;
|
||||
using AttrObject::get_src_attribute;
|
||||
using AttrObject::adopt_src_from;
|
||||
// Context-aware src helpers. Resolve Design via module->design and
|
||||
// route to the per-Design meta vector; assert the cell is attached.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
// Transfer src from `source` verbatim (same pool). Asserts attached
|
||||
// to a design — derives the pool via module->design->src_twines.
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
// access cell ports
|
||||
bool hasPort(RTLIL::IdString portname) const;
|
||||
|
|
@ -2408,6 +2417,15 @@ struct RTLIL::CaseRule : public RTLIL::AttrObject
|
|||
// each. Idempotent.
|
||||
void setModuleRecursive(RTLIL::Module *m);
|
||||
|
||||
// Context-aware src helpers via module->design.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
template<typename T> void rewrite_sigspecs(T &functor);
|
||||
template<typename T> void rewrite_sigspecs2(T &functor);
|
||||
RTLIL::CaseRule *clone() const;
|
||||
|
|
@ -2427,6 +2445,15 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
|
|||
|
||||
void setModuleRecursive(RTLIL::Module *m);
|
||||
|
||||
// Context-aware src helpers via module->design.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
template<typename T> void rewrite_sigspecs(T &functor);
|
||||
template<typename T> void rewrite_sigspecs2(T &functor);
|
||||
RTLIL::SwitchRule *clone() const;
|
||||
|
|
@ -2442,6 +2469,15 @@ struct RTLIL::MemWriteAction : RTLIL::AttrObject
|
|||
RTLIL::SigSpec data;
|
||||
RTLIL::SigSpec enable;
|
||||
RTLIL::Const priority_mask;
|
||||
|
||||
// Context-aware src helpers via module->design.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
};
|
||||
|
||||
struct RTLIL::SyncRule
|
||||
|
|
@ -2476,16 +2512,15 @@ public:
|
|||
RTLIL::CaseRule root_case;
|
||||
std::vector<RTLIL::SyncRule*> syncs;
|
||||
|
||||
// Context-aware src helpers. Resolve the destination pool via
|
||||
// `module->design->src_twines`; assert the process is attached.
|
||||
using AttrObject::set_src_attribute;
|
||||
using AttrObject::get_src_attribute;
|
||||
using AttrObject::adopt_src_from;
|
||||
// Context-aware src helpers. Resolve Design via module->design and
|
||||
// route to the per-Design meta vector; assert the process is attached.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
// Transfer src from `source` verbatim (same pool). Asserts attached
|
||||
// to a design — derives the pool via module->design->src_twines.
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
template<typename T> void rewrite_sigspecs(T &functor);
|
||||
template<typename T> void rewrite_sigspecs2(T &functor);
|
||||
|
|
@ -2826,16 +2861,15 @@ public:
|
|||
dict<RTLIL::IdString, RTLIL::Memory*> memories;
|
||||
dict<RTLIL::IdString, RTLIL::Process*> processes;
|
||||
|
||||
// Context-aware src helpers. Resolve the destination pool via
|
||||
// `design->src_twines`; assert the module is attached.
|
||||
using AttrObject::set_src_attribute;
|
||||
using AttrObject::get_src_attribute;
|
||||
using AttrObject::adopt_src_from;
|
||||
// Context-aware src helpers. Resolve Design via this->design and
|
||||
// route to the per-Design meta vector; assert the module is attached.
|
||||
Twine::Id src_id() const;
|
||||
Twine::Id src_ref() const { return src_id(); }
|
||||
void set_src_id(Twine::Id id);
|
||||
void set_src_attribute(const RTLIL::SrcAttr &src);
|
||||
std::string get_src_attribute() const;
|
||||
// Transfer src from `source` verbatim (same pool). Asserts attached
|
||||
// to a design — derives the pool via module->design->src_twines.
|
||||
void adopt_src_from(const RTLIL::AttrObject *source);
|
||||
void absorb_attrs(dict<RTLIL::IdString, RTLIL::Const> &&buf);
|
||||
|
||||
Module();
|
||||
virtual ~Module();
|
||||
|
|
|
|||
|
|
@ -105,9 +105,9 @@ namespace {
|
|||
pool.dump("twine pool state");
|
||||
}
|
||||
for (Cell* c : targets)
|
||||
c->set_src_id(&pool, merged);
|
||||
c->set_src_id(merged);
|
||||
if (merge_src_into)
|
||||
merge_src_into->set_src_id(&pool, merged);
|
||||
merge_src_into->set_src_id(merged);
|
||||
pool.release(merged);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ struct ChformalPass : public Pass {
|
|||
Cell *cover = module->addCell(NEW_ID_SUFFIX("coverenable"), ID($check));
|
||||
cover->attributes = cell->attributes;
|
||||
if (cell->src_id() != Twine::Null && module->design)
|
||||
cover->set_src_id(&module->design->src_twines, cell->src_id());
|
||||
cover->set_src_id(cell->src_id());
|
||||
cover->parameters = cell->parameters;
|
||||
cover->setParam(ID(FLAVOR), Const("cover"));
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ struct ChformalPass : public Pass {
|
|||
|
||||
plain_cell->attributes = cell->attributes;
|
||||
if (cell->src_id() != Twine::Null && module->design)
|
||||
plain_cell->set_src_id(&module->design->src_twines, cell->src_id());
|
||||
plain_cell->set_src_id(cell->src_id());
|
||||
|
||||
SigBit sig_a = cell->getPort(ID::A);
|
||||
SigBit sig_en = cell->getPort(ID::EN);
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ struct PrintAttrsPass : public Pass {
|
|||
log_assert(x.flags & RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail
|
||||
}
|
||||
|
||||
static void log_src(const Yosys::TwinePool *pool, const RTLIL::AttrObject *obj, const unsigned int indent) {
|
||||
static void log_src(const RTLIL::Design *design, const RTLIL::AttrObject *obj, const unsigned int indent) {
|
||||
// Emit src outside the attributes loop — it lives on the typed
|
||||
// src_id_ field, not in obj->attributes.
|
||||
if (obj->src_id() != Twine::Null && pool)
|
||||
// meta-vector slot, not in obj->attributes.
|
||||
if (design && design->obj_src_id(obj) != Twine::Null)
|
||||
log("%s(* src=\"%s\" *)\n", get_indent_str(indent),
|
||||
obj->get_src_attribute(pool).c_str());
|
||||
design->get_src_attribute(obj).c_str());
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
|
|
@ -73,7 +73,7 @@ struct PrintAttrsPass : public Pass {
|
|||
if (design->selected_whole_module(mod)) {
|
||||
log("%s%s\n", get_indent_str(indent), mod->name.unescape());
|
||||
indent += 2;
|
||||
log_src(design ? &design->src_twines : nullptr, mod, indent);
|
||||
log_src(design, mod, indent);
|
||||
for (auto &it : mod->attributes)
|
||||
log_const(it.first, it.second, indent);
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ struct PrintAttrsPass : public Pass {
|
|||
for (auto cell : mod->selected_cells()) {
|
||||
log("%s%s\n", get_indent_str(indent), cell->name.unescape());
|
||||
indent += 2;
|
||||
log_src(design ? &design->src_twines : nullptr, cell, indent);
|
||||
log_src(design, cell, indent);
|
||||
for (auto &it : cell->attributes)
|
||||
log_const(it.first, it.second, indent);
|
||||
indent -= 2;
|
||||
|
|
@ -90,7 +90,7 @@ struct PrintAttrsPass : public Pass {
|
|||
for (auto wire : mod->selected_wires()) {
|
||||
log("%s%s\n", get_indent_str(indent), wire->name.unescape());
|
||||
indent += 2;
|
||||
log_src(design ? &design->src_twines : nullptr, wire, indent);
|
||||
log_src(design, wire, indent);
|
||||
for (auto &it : wire->attributes)
|
||||
log_const(it.first, it.second, indent);
|
||||
indent -= 2;
|
||||
|
|
|
|||
|
|
@ -145,14 +145,14 @@ static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, co
|
|||
// through the normal match_attr path. Other ID::src-shaped patterns like
|
||||
// wildcards still flow through the (empty) dict and won't match src — those
|
||||
// uses were rare and the dict-path migration is a separate concern.
|
||||
static bool match_attr(const Yosys::TwinePool *pool, const RTLIL::AttrObject *obj, const std::string &match_expr)
|
||||
static bool match_attr(const RTLIL::Design *design, const RTLIL::AttrObject *obj, const std::string &match_expr)
|
||||
{
|
||||
if (obj->src_id() != Twine::Null && pool) {
|
||||
if (design && obj->meta_idx_ != RTLIL::AttrObject::NO_META) {
|
||||
size_t pos = match_expr.find_first_of("<!=>");
|
||||
std::string name_part = (pos == std::string::npos) ? match_expr : match_expr.substr(0, pos);
|
||||
if (name_part == "src" || name_part == "\\src") {
|
||||
dict<RTLIL::IdString, RTLIL::Const> synthesized;
|
||||
synthesized[RTLIL::ID::src] = RTLIL::Const(obj->get_src_attribute(pool));
|
||||
synthesized[RTLIL::ID::src] = RTLIL::Const(design->get_src_attribute(obj));
|
||||
return match_attr(synthesized, match_expr);
|
||||
}
|
||||
}
|
||||
|
|
@ -971,18 +971,17 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
|||
sel.selected_members[mod->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "a:") == 0) {
|
||||
Yosys::TwinePool *pool = design ? &design->src_twines : nullptr;
|
||||
for (auto wire : mod->wires())
|
||||
if (match_attr(pool, wire, arg_memb.substr(2)))
|
||||
if (match_attr(design, wire, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(wire->name);
|
||||
for (auto &it : mod->memories)
|
||||
if (match_attr(pool, it.second, arg_memb.substr(2)))
|
||||
if (match_attr(design, it.second, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
for (auto cell : mod->cells())
|
||||
if (match_attr(pool, cell, arg_memb.substr(2)))
|
||||
if (match_attr(design, cell, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(cell->name);
|
||||
for (auto &it : mod->processes)
|
||||
if (match_attr(pool, it.second, arg_memb.substr(2)))
|
||||
if (match_attr(design, it.second, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "r:") == 0) {
|
||||
|
|
|
|||
|
|
@ -116,8 +116,10 @@ struct MemoryMapWorker
|
|||
// possibly-Concat src as a single pipe-joined leaf on every
|
||||
// new cell. set_src_attribute's parse_ref path retains the
|
||||
// pool slot directly.
|
||||
mem_src = (mem.module && mem.module->design && mem.src_id() != Twine::Null) ?
|
||||
TwinePool::format_ref(mem.src_id()) : std::string();
|
||||
{
|
||||
Twine::Id mid = (mem.module && mem.module->design) ? mem.module->design->obj_src_id(&mem) : Twine::Null;
|
||||
mem_src = (mid != Twine::Null) ? TwinePool::format_ref(mid) : std::string();
|
||||
}
|
||||
|
||||
SigSpec init_data = mem.get_init_data();
|
||||
|
||||
|
|
|
|||
|
|
@ -185,8 +185,8 @@ struct RomWorker
|
|||
mem.emit();
|
||||
|
||||
if (sw->src_id() != Twine::Null && module->design) {
|
||||
mem.inits[0].cell->set_src_id(&module->design->src_twines, sw->src_id());
|
||||
mem.rd_ports[0].cell->set_src_id(&module->design->src_twines, sw->src_id());
|
||||
mem.inits[0].cell->set_src_id(sw->src_id());
|
||||
mem.rd_ports[0].cell->set_src_id(sw->src_id());
|
||||
}
|
||||
|
||||
for (auto cs: sw->cases)
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ struct AssertpmuxWorker
|
|||
Cell *assert_cell = module->addAssert(NEW_ID, assert_a, assert_en);
|
||||
|
||||
if (pmux->src_id() != Twine::Null && module->design)
|
||||
assert_cell->set_src_id(&module->design->src_twines, pmux->src_id());
|
||||
assert_cell->set_src_id(pmux->src_id());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1552,7 +1552,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
|||
RTLIL::Wire *orig_wire = nullptr;
|
||||
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
|
||||
if (orig_wire != nullptr && orig_wire->src_id() != Twine::Null && module->design)
|
||||
wire->set_src_id(&module->design->src_twines, orig_wire->src_id());
|
||||
wire->set_src_id(orig_wire->src_id());
|
||||
if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx;
|
||||
design->select(module, wire);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ YOSYS_NAMESPACE_BEGIN
|
|||
|
||||
static void transfer_src (Cell* to, const Cell* from) {
|
||||
if (from->src_id() != Twine::Null && to->module && to->module->design)
|
||||
to->set_src_id(&to->module->design->src_twines, from->src_id());
|
||||
to->set_src_id(from->src_id());
|
||||
}
|
||||
|
||||
void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
|
|
|
|||
|
|
@ -71,11 +71,10 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
|
|||
// Propagate one of the cell-level srcs to the wrapper too so backends
|
||||
// emitting `attribute \src` see a usable value on the wrapper.
|
||||
if (cell->module && cell->module->design) {
|
||||
TwinePool *pool = &cell->module->design->src_twines;
|
||||
if (st.carry->src_id() != Twine::Null)
|
||||
cell->set_src_id(pool, st.carry->src_id());
|
||||
cell->set_src_id(st.carry->src_id());
|
||||
else if (st.lut->src_id() != Twine::Null)
|
||||
cell->set_src_id(pool, st.lut->src_id());
|
||||
cell->set_src_id(st.lut->src_id());
|
||||
}
|
||||
cell->attributes[IdString{"\\SB_LUT4.name"}] = Const(st.lut->name.str());
|
||||
if (st.carry->get_bool_attribute(ID::keep) || st.lut->get_bool_attribute(ID::keep))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue