3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-17 20:55:45 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-05 12:04:19 +02:00
parent 3d27e83d0f
commit 3424c00cd0
63 changed files with 2635 additions and 503 deletions

View file

@ -39,6 +39,15 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.sig_q = cell->getPort(ID::Q);
info.width = GetSize(info.sig_q);
info.attributes = cell->attributes;
// Carry src across construction → emit() as an owning Twine
// reference. Retaining a slot on the source pool keeps it
// alive even if the source cell gets removed between
// manufacture_info() and emit(); emit() then transfers the
// id verbatim into the new cell — no flatten/re-intern, no
// pipe-leaf risk for cells whose src is a Concat.
if (cell->src_id() != Twine::Null && cell->module && cell->module->design)
info.src_twine = OwnedTwine(&cell->module->design->src_twines,
cell->src_id());
if (initvals)
info.val_init = (*initvals)(info.sig_q);
}
@ -753,7 +762,24 @@ Cell *FfData::emit() {
}
}
}
// src is carried in info.src_twine (an OwnedTwine retaining the
// source slot). Transfer the id verbatim to the new cell — same
// pool, no flatten. The OwnedTwine still holds its own ref until
// FfData is destroyed; set_src_id retains on the cell's behalf.
cell->attributes = attributes;
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());
} 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);
dst_pool->release(migrated);
}
}
if (initvals && !is_anyinit)
initvals->set_init(cell->getPort(ID::Q), val_init);
return cell;

View file

@ -22,6 +22,7 @@
#include "kernel/yosys.h"
#include "kernel/ffinit.h"
#include "kernel/twine.h"
YOSYS_NAMESPACE_BEGIN
@ -169,6 +170,10 @@ struct FfData : FfTypeData {
// The FF data width in bits.
int width;
dict<IdString, Const> attributes;
// Stashed src across construction → emit. Refcount-managed so the
// source cell's pool slot survives if the cell itself is removed
// before emit() runs. Empty when the source cell had no src.
OwnedTwine src_twine;
FfData(Module *module = nullptr, FfInitVals *initvals = nullptr, IdString name = IdString()) : module(module), initvals(initvals), cell(nullptr), name(name) {
width = 0;

View file

@ -888,7 +888,14 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
if (!port.clk_enable)
return nullptr;
std::string mem_src = get_src_attribute();
// Keep src as a "@N" reference into the design's twine pool throughout
// — never flatten to a literal path string. That way every addX call
// below adopts the same slot as Mem itself (via set_src_attribute's
// "@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();
Cell *c;
@ -994,8 +1001,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
IdString name = stringf("$%s$rdreg[%d]", memid, idx);
FfData ff(module, initvals, name);
if (!mem_src.empty())
ff.attributes[ID::src] = mem_src;
// 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_);
ff.width = GetSize(port.data);
ff.has_clk = true;
ff.sig_clk = port.clk;

25
kernel/pmux.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef PMUX_H
#define PMUX_H
#include "kernel/yosys_common.h"
#include "kernel/rtlil.h"
YOSYS_NAMESPACE_BEGIN
struct PmuxBPortIterator {
Cell* cell;
std::vector<SigBit> b;
int port_idx;
int port_count;
PmuxBPortIterator(Cell* mux) : cell(mux) {
log_assert(mux->type == ID($mux) || mux->type == ID($pmux));
port_idx = 0;
b = mux->getPort(ID::B).to_sigbit_vector();
port_count = GetSize(sig_b) / s_width;
}
};
YOSYS_NAMESPACE_END
#endif

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@
#include "kernel/yosys_common.h"
#include "kernel/yosys.h"
#include "kernel/twine.h"
#include <string_view>
#include <unordered_map>
@ -125,11 +126,39 @@ namespace RTLIL
struct OwningIdString;
struct StaticIdString;
struct SigNormIndex;
struct SrcAttr;
typedef std::pair<SigSpec, SigSpec> SigSig;
struct PortBit;
};
// A small polymorphic handle representing src to be applied to an
// AttrObject by a CellAdder method or set_src_attribute call. Holds
// EITHER a pre-interned twine id (preferred — the destination just
// retains the slot, no flatten/intern) OR a literal string ("@N" or a
// raw path:line.col) for legacy callers. Implicit conversions cover
// both shapes so existing string-passing call sites keep compiling
// without changes; new code passing `cell->src_ref()` lands in the
// cheap id branch.
//
// The caller must keep any pool slot named by `id` alive for the
// duration of the call (typically: the source AttrObject still holds
// it). Empty by default — passing a default-constructed SrcAttr to
// set_src_attribute clears src_id_.
struct RTLIL::SrcAttr
{
Twine::Id id = Twine::Null;
std::string literal;
SrcAttr() = default;
SrcAttr(Twine::Id i) : id(i) {}
SrcAttr(std::string s) : literal(std::move(s)) {}
SrcAttr(const char *s) : literal(s ? s : "") {}
SrcAttr(std::string_view s) : literal(s) {}
bool empty() const { return id == Twine::Null && literal.empty(); }
};
// TODO clean up?
extern int64_t signorm_ns;
extern int signorm_count;
@ -1266,6 +1295,18 @@ 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;
bool has_attribute(RTLIL::IdString id) const;
void set_bool_attribute(RTLIL::IdString id, bool value=true);
@ -1284,12 +1325,49 @@ struct RTLIL::AttrObject
void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
pool<string> get_strpool_attribute(RTLIL::IdString id) const;
void set_src_attribute(const std::string &src) {
set_string_attribute(ID::src, src);
}
std::string get_src_attribute() const {
return get_string_attribute(ID::src);
}
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;
@ -1911,6 +1989,49 @@ struct RTLIL::Design
dict<RTLIL::IdString, RTLIL::Module*> modules_;
std::vector<RTLIL::Binding*> bindings_;
// Interns src-attribute strings and concats thereof. Cells reach this
// via cell->module->design->src_twines.
TwinePool src_twines;
// 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
// must call this whenever they emit src to a user-facing format.
std::string resolve_src(std::string_view raw) const {
Twine::Id id = TwinePool::parse_ref(raw);
if (id == Twine::Null)
return std::string(raw);
return src_twines.flatten(id);
}
// Merge `source`'s src attribute into `target`'s src attribute via the
// twine pool. After the call `target` carries the combined "@N" ref.
// Handles every case: source has a "@N" ref → reuse that Id; source
// has a legacy pipe-joined literal → split and intern each leaf;
// target had pre-existing src → its leaves are folded in too. Use
// this instead of `target->add_strpool_attribute(ID::src, source->get_strpool_attribute(ID::src))`,
// which round-trips through a flat string and corrupts "@N" refs.
void merge_src(RTLIL::AttrObject *target, const RTLIL::AttrObject *source);
// Same as merge_src but consumes a raw set of leaf strings (each of
// which may itself be either a "@N" ref or a literal path).
void merge_src(RTLIL::AttrObject *target, const pool<std::string> &leaves);
// Returns the resolved leaf-string set backing obj's src attribute.
// "@N" refs are expanded through the pool; legacy pipe-joined
// literals are split. Use this instead of get_strpool_attribute(ID::src)
// when you actually need to iterate the path:line.col entries.
pool<std::string> src_leaves(const RTLIL::AttrObject *obj) const;
// Walk the design, collect the set of "@N" ids actually referenced by
// any AttrObject's src, then compact src_twines to contain only those
// nodes plus their transitive leaf children, and rewrite every cell
// src attribute through the resulting old-id -> new-id remap.
// Intermediate concats produced by successive merges become unreferenced
// once a fresh concat takes their place on the surviving cell, so this
// is what reaps them. Returns the number of nodes freed.
size_t gc_twines();
std::vector<std::unique_ptr<AST::AstNode>> verilog_packages, verilog_globals;
std::unique_ptr<define_map_t> verilog_defines;
@ -1952,6 +2073,13 @@ struct RTLIL::Design
void check();
void optimize();
// Wholesale-copy this design into `dst`. `dst` must be empty (no
// modules). Copies src_twines verbatim and clones each module
// preserving src_id_ values directly — avoids the per-module
// copy_from pool rebuild and yields byte-identical RTLIL output
// across design -push/-pop, -save/-load, etc.
void clone_into(RTLIL::Design *dst) const;
// checks if the given module is included in the current selection
bool selected_module(RTLIL::IdString mod_name) const;
@ -2065,7 +2193,7 @@ struct RTLIL::Design
};
namespace RTLIL_BACKEND {
void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire, const RTLIL::Design *design, bool resolve_src);
}
struct RTLIL::Wire : public RTLIL::NamedObject
@ -2083,7 +2211,7 @@ public:
Wire(ConstructToken);
~Wire();
friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire, const RTLIL::Design *design, bool resolve_src);
RTLIL::Cell *driverCell_ = nullptr;
RTLIL::IdString driverPort_;
@ -2095,6 +2223,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;
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);
bool known_driver() const { return driverCell_ != nullptr; }
RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; };
@ -2172,6 +2311,17 @@ 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;
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);
// access cell ports
bool hasPort(RTLIL::IdString portname) const;
void unsetPort(RTLIL::IdString portname);
@ -2281,6 +2431,17 @@ 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;
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);
template<typename T> void rewrite_sigspecs(T &functor);
template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::Process *clone() const;
@ -2380,212 +2541,212 @@ class CellAdderMixin {
public:
// The add* methods create a cell and return the created cell. All signals must exist in advance.
RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addBuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addBuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addShl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addShr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addShift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addEq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addEqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addGe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addGt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// truncating division
RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// truncating modulo
RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addDivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addFa (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addFa (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addDemux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addBmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDemux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addBweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addBwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAldff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAldffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDffsreGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAldffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAldffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSdffceGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
bool arst_value = false, bool en_polarity = true, bool arst_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Buf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Buf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// truncating division
RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// truncating modulo
RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec DivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec DivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec ModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Bmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Demux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Bmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Demux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Bweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const std::string &src = "");
RTLIL::SigSpec Bwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Bweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Bwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
};
struct RTLIL::Module : public RTLIL::NamedObject, public CellAdderMixin<RTLIL::Module>
@ -2620,6 +2781,17 @@ 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;
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);
Module();
virtual ~Module();
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
@ -2675,8 +2847,21 @@ public:
template<typename T> void rewrite_sigspecs(T &functor);
template<typename T> void rewrite_sigspecs2(T &functor);
void cloneInto(RTLIL::Module *new_mod) const;
// `src_id_verbatim`: when true, the caller guarantees that
// `new_mod->design->src_twines` is a verbatim copy of
// `this->design->src_twines`, so src_id_ values can be transferred
// without retain/release on the destination pool (the copied refcounts
// already account for the new AttrObject references). Used by
// Design::clone_into for wholesale design copies.
void cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim = false) const;
virtual RTLIL::Module *clone() const;
// Clone variant that attaches the new module to `dst` BEFORE cloneInto
// runs. This is the right pattern when the destination design is known
// up front — it avoids the "detached module, attach later" flow and
// the pending-literal src stashing it entails. Subtypes override to
// preserve their type (AstModule). `src_id_verbatim` is forwarded to
// cloneInto.
virtual RTLIL::Module *clone(RTLIL::Design *dst, bool src_id_verbatim = false) const;
bool has_memories() const;
bool has_processes() const;
@ -2754,22 +2939,22 @@ public:
// The add* methods create a cell and return the created cell. All signals must exist in advance.
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = "");
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec Initstate (RTLIL::IdString name, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = "");
RTLIL::Cell* addSetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = "");
RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = "");
RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = "");
RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = "");
RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addSetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const RTLIL::SrcAttr &src = RTLIL::SrcAttr());
std::string to_rtlil_str() const;
#ifdef YOSYS_ENABLE_PYTHON

455
kernel/twine.cc Normal file
View file

@ -0,0 +1,455 @@
#include "kernel/twine.h"
#include "kernel/log.h"
YOSYS_NAMESPACE_BEGIN
Twine::Id TwinePool::alloc_slot_(Twine &&node)
{
if (!free_list_.empty()) {
// Pop the SMALLEST free id (not the most recent), so reuse order
// matches the original allocation order when an entire pool gets
// freed and rebuilt. That makes write_rtlil emit byte-identical
// "@N" refs across design -push;-pop and similar wholesale-clone
// cycles, even though the in-memory pool got renumbered through
// the free list.
auto it = std::min_element(free_list_.begin(), free_list_.end());
Twine::Id id = *it;
free_list_.erase(it);
nodes_[id] = std::move(node);
refcount_[id] = 0;
return id;
}
Twine::Id id = static_cast<Twine::Id>(nodes_.size());
nodes_.push_back(std::move(node));
refcount_.push_back(0);
return id;
}
Twine::Id TwinePool::intern(std::string_view leaf)
{
if (leaf.empty())
return Twine::Null;
std::string key{leaf};
if (auto it = leaf_index_.find(key); it != leaf_index_.end()) {
retain(it->second);
return it->second;
}
Twine::Id id = alloc_slot_(Twine{std::move(key)});
leaf_index_[std::get<std::string>(nodes_[id].data)] = id;
refcount_[id] = 1;
return id;
}
Twine::Id TwinePool::intern_suffix(Twine::Id parent, std::string_view tail)
{
if (parent == Twine::Null)
return intern(tail);
log_assert(parent < nodes_.size() && !nodes_[parent].is_dead());
log_assert(nodes_[parent].is_flat() && "Suffix parent must be a flat node (Leaf or Suffix)");
if (tail.empty()) {
// No tail means "the same string as parent". Hand back a fresh
// owning ref on parent — semantically equivalent to a degenerate
// suffix node, but we avoid allocating a slot for it.
retain(parent);
return parent;
}
std::pair<Twine::Id, std::string> key{parent, std::string{tail}};
if (auto it = suffix_index_.find(key); it != suffix_index_.end()) {
retain(it->second);
return it->second;
}
// Internal child ref: the suffix node owns one ref on its parent.
retain(parent);
Twine::Id id = alloc_slot_(Twine{Twine::Suffix{parent, std::string{tail}}});
const auto &stored = std::get<Twine::Suffix>(nodes_[id].data);
suffix_index_[std::make_pair(stored.parent, stored.tail)] = id;
refcount_[id] = 1;
return id;
}
Twine::Id TwinePool::concat(std::span<const Twine::Id> parts)
{
// Flat invariant: a Concat node only ever holds flat children (Leaf
// or Suffix), never another Concat. Splice in concats' children
// directly so identical sets map to byte-equal child vectors
// regardless of how callers nested concats.
std::vector<Twine::Id> children;
children.reserve(parts.size());
pool<Twine::Id> seen;
auto push_flat = [&](Twine::Id flat_id) {
if (seen.insert(flat_id).second)
children.push_back(flat_id);
};
for (Twine::Id p : parts) {
if (p == Twine::Null)
continue;
log_assert(p < nodes_.size() && !nodes_[p].is_dead());
const Twine &n = nodes_[p];
if (n.is_flat()) {
push_flat(p);
} else {
for (Twine::Id grandchild : n.children())
push_flat(grandchild);
}
}
if (children.empty())
return Twine::Null;
if (children.size() == 1) {
retain(children.front());
return children.front();
}
if (auto it = concat_index_.find(children); it != concat_index_.end()) {
retain(it->second);
return it->second;
}
// Internal child refs: the concat node owns one ref on each child.
for (Twine::Id c : children)
retain(c);
Twine::Id id = alloc_slot_(Twine{std::move(children)});
concat_index_[std::get<std::vector<Twine::Id>>(nodes_[id].data)] = id;
refcount_[id] = 1;
return id;
}
Twine::Id TwinePool::concat(Twine::Id a, Twine::Id b)
{
std::array<Twine::Id, 2> pair{a, b};
return concat(std::span<const Twine::Id>{pair});
}
void TwinePool::retain(Twine::Id id)
{
if (id == Twine::Null)
return;
log_assert(id < nodes_.size() && !nodes_[id].is_dead());
refcount_[id]++;
}
void TwinePool::release(Twine::Id id)
{
if (id == Twine::Null)
return;
log_assert(id < nodes_.size() && !nodes_[id].is_dead());
log_assert(refcount_[id] > 0);
if (--refcount_[id] == 0)
destroy_slot_(id);
}
uint32_t TwinePool::refcount(Twine::Id id) const
{
if (id == Twine::Null)
return 0;
return refcount_.at(id);
}
bool TwinePool::is_alive(Twine::Id id) const
{
if (id == Twine::Null)
return false;
return id < nodes_.size() && !nodes_[id].is_dead();
}
void TwinePool::destroy_slot_(Twine::Id id)
{
Twine &n = nodes_[id];
if (n.is_leaf()) {
leaf_index_.erase(n.leaf());
} else if (n.is_concat()) {
// Release internal child refs. Capture by move so iteration is
// stable across child destroy_slot_ side effects.
std::vector<Twine::Id> children = std::move(std::get<std::vector<Twine::Id>>(n.data));
concat_index_.erase(children);
n.data = std::monostate{};
free_list_.push_back(id);
for (Twine::Id c : children)
release(c);
return;
} else if (n.is_suffix()) {
// Capture parent by move and release after dropping the slot,
// since releasing may recursively destroy the parent and we
// want this slot's tombstone to be visible by then.
Twine::Suffix s = std::move(std::get<Twine::Suffix>(n.data));
suffix_index_.erase(std::make_pair(s.parent, s.tail));
n.data = std::monostate{};
free_list_.push_back(id);
release(s.parent);
return;
}
n.data = std::monostate{};
free_list_.push_back(id);
}
void TwinePool::collect_leaves(Twine::Id id, pool<std::string> &out) const
{
if (id == Twine::Null)
return;
const Twine &n = nodes_.at(id);
if (n.is_dead())
return;
if (n.is_leaf()) {
out.insert(n.leaf());
return;
}
if (n.is_suffix()) {
// A suffix is semantically a single flat string. Materialize it
// and insert into the set just like a leaf.
out.insert(flat_string_(id));
return;
}
for (Twine::Id c : n.children())
collect_leaves(c, out);
}
std::string TwinePool::flat_string_(Twine::Id id) const
{
// Walk the parent chain iteratively to avoid recursion depth concerns
// on deep suffix trees. Collect tails (and the root leaf) then stitch
// in root-to-tail order.
log_assert(id != Twine::Null);
std::vector<std::string_view> parts;
while (true) {
const Twine &n = nodes_.at(id);
if (n.is_leaf()) {
parts.push_back(n.leaf());
break;
}
log_assert(n.is_suffix());
parts.push_back(n.suffix().tail);
id = n.suffix().parent;
}
size_t total = 0;
for (auto p : parts)
total += p.size();
std::string out;
out.reserve(total);
for (auto it = parts.rbegin(); it != parts.rend(); ++it)
out.append(*it);
return out;
}
std::string TwinePool::flatten(Twine::Id id, char sep) const
{
if (id == Twine::Null)
return {};
pool<std::string> leaves;
collect_leaves(id, leaves);
std::string out;
for (const auto &s : leaves) {
if (s.empty())
continue;
if (!out.empty())
out += sep;
out += s;
}
return out;
}
std::string TwinePool::format_ref(Twine::Id id)
{
if (id == Twine::Null)
return {};
return "@" + std::to_string(id);
}
Twine::Id TwinePool::parse_ref(std::string_view s)
{
if (s.size() < 2 || s[0] != '@')
return Twine::Null;
uint64_t v = 0;
for (size_t i = 1; i < s.size(); i++) {
char c = s[i];
if (c < '0' || c > '9')
return Twine::Null;
v = v * 10 + static_cast<uint64_t>(c - '0');
if (v >= std::numeric_limits<Twine::Id>::max())
return Twine::Null;
}
return static_cast<Twine::Id>(v);
}
void TwinePool::dump(const char *banner) const
{
if (banner)
log("%s (%zu live nodes: %zu leaves, %zu suffixes, %zu concats, %zu free slots)\n",
banner, nodes_.size() - free_list_.size(),
leaf_index_.size(), suffix_index_.size(),
concat_index_.size(), free_list_.size());
for_each_live([&](Twine::Id id, const Twine &n) {
if (n.is_leaf()) {
log(" @%u leaf rc=%u %s\n", id, refcount_[id], n.leaf().c_str());
} else if (n.is_suffix()) {
log(" @%u suffix rc=%u @%u + %s\n", id, refcount_[id],
n.suffix().parent, n.suffix().tail.c_str());
} else {
std::string children;
for (Twine::Id c : n.children()) {
if (!children.empty())
children += ", ";
children += "@" + std::to_string(c);
}
log(" @%u concat rc=%u [%s]\n", id, refcount_[id], children.c_str());
}
});
}
dict<Twine::Id, Twine::Id> TwinePool::gc(const pool<Twine::Id> &live)
{
// Closure: mark every node reachable from `live`. Concat children
// (Leaf or Suffix) and Suffix parents (Leaf or Suffix) are both
// followed. With Suffix nodes chains can be more than one step deep,
// so use a worklist rather than a single BFS step.
pool<Twine::Id> reachable;
std::vector<Twine::Id> work;
for (Twine::Id id : live) {
if (id == Twine::Null || id >= nodes_.size() || nodes_[id].is_dead())
continue;
if (reachable.insert(id).second)
work.push_back(id);
}
while (!work.empty()) {
Twine::Id id = work.back();
work.pop_back();
const Twine &n = nodes_[id];
if (n.is_concat()) {
for (Twine::Id c : n.children())
if (reachable.insert(c).second)
work.push_back(c);
} else if (n.is_suffix()) {
Twine::Id p = n.suffix().parent;
if (reachable.insert(p).second)
work.push_back(p);
}
}
// Rebuild the pool from scratch. Process flats (Leaf, then Suffix)
// before Concats so concat-child lookups can resolve, and process
// suffixes parent-before-child via a recursive helper that memoizes
// into `remap`.
std::vector<Twine> new_nodes;
std::vector<uint32_t> new_refcount;
dict<std::string, Twine::Id> new_leaf_index;
dict<std::vector<Twine::Id>, Twine::Id> new_concat_index;
dict<std::pair<Twine::Id, std::string>, Twine::Id> new_suffix_index;
dict<Twine::Id, Twine::Id> remap;
auto intern_leaf = [&](const std::string &text) -> Twine::Id {
if (auto it = new_leaf_index.find(text); it != new_leaf_index.end())
return it->second;
Twine::Id id = static_cast<Twine::Id>(new_nodes.size());
new_nodes.push_back(Twine{text});
new_refcount.push_back(0);
new_leaf_index[std::get<std::string>(new_nodes.back().data)] = id;
return id;
};
for (Twine::Id old_id : reachable) {
const Twine &n = nodes_[old_id];
if (n.is_leaf())
remap[old_id] = intern_leaf(n.leaf());
}
std::function<Twine::Id(Twine::Id)> remap_flat = [&](Twine::Id old_id) -> Twine::Id {
if (auto it = remap.find(old_id); it != remap.end())
return it->second;
const Twine &n = nodes_[old_id];
log_assert(n.is_suffix());
Twine::Id new_parent = remap_flat(n.suffix().parent);
std::pair<Twine::Id, std::string> key{new_parent, n.suffix().tail};
if (auto sit = new_suffix_index.find(key); sit != new_suffix_index.end()) {
remap[old_id] = sit->second;
return sit->second;
}
Twine::Id new_id = static_cast<Twine::Id>(new_nodes.size());
new_nodes.push_back(Twine{Twine::Suffix{new_parent, n.suffix().tail}});
new_refcount.push_back(0);
const auto &stored = std::get<Twine::Suffix>(new_nodes.back().data);
new_suffix_index[std::make_pair(stored.parent, stored.tail)] = new_id;
remap[old_id] = new_id;
return new_id;
};
for (Twine::Id old_id : reachable) {
const Twine &n = nodes_[old_id];
if (n.is_suffix() && remap.find(old_id) == remap.end())
remap_flat(old_id);
}
for (Twine::Id old_id : reachable) {
const Twine &n = nodes_[old_id];
if (!n.is_concat())
continue;
std::vector<Twine::Id> children;
children.reserve(n.children().size());
for (Twine::Id c : n.children())
children.push_back(remap.at(c));
if (auto it = new_concat_index.find(children); it != new_concat_index.end()) {
remap[old_id] = it->second;
} else {
Twine::Id new_id = static_cast<Twine::Id>(new_nodes.size());
new_nodes.push_back(Twine{std::move(children)});
new_refcount.push_back(0);
new_concat_index[std::get<std::vector<Twine::Id>>(new_nodes.back().data)] = new_id;
remap[old_id] = new_id;
}
}
// Refcounts in the rebuilt pool: every external "live" id passed in by
// the caller corresponds to one external owner reference; concats
// hold one ref per stored child; suffixes hold one ref on their parent.
for (Twine::Id old_id : live) {
auto it = remap.find(old_id);
if (it != remap.end())
new_refcount[it->second]++;
}
for (size_t i = 0; i < new_nodes.size(); i++) {
if (new_nodes[i].is_concat()) {
for (Twine::Id c : new_nodes[i].children())
new_refcount[c]++;
} else if (new_nodes[i].is_suffix()) {
new_refcount[new_nodes[i].suffix().parent]++;
}
}
nodes_ = std::move(new_nodes);
refcount_ = std::move(new_refcount);
free_list_.clear();
leaf_index_ = std::move(new_leaf_index);
concat_index_ = std::move(new_concat_index);
suffix_index_ = std::move(new_suffix_index);
return remap;
}
Twine::Id TwinePool::copy_from(const TwinePool &src, Twine::Id src_id)
{
if (src_id == Twine::Null)
return Twine::Null;
log_assert(src_id < src.nodes_.size() && !src.nodes_[src_id].is_dead());
const Twine &n = src.nodes_[src_id];
if (n.is_leaf())
return intern(n.leaf());
if (n.is_suffix()) {
Twine::Id new_parent = copy_from(src, n.suffix().parent);
Twine::Id result = intern_suffix(new_parent, n.suffix().tail);
// intern_suffix retained the parent internally; the caller-side
// +1 ref from copy_from(parent) is surplus.
release(new_parent);
return result;
}
std::vector<Twine::Id> children;
children.reserve(n.children().size());
for (Twine::Id c : n.children())
children.push_back(copy_from(src, c));
Twine::Id result = concat(std::span<const Twine::Id>{children});
// concat retained each child internally; the caller-side +1 refs from
// copy_from(child) are surplus.
for (Twine::Id c : children)
release(c);
return result;
}
YOSYS_NAMESPACE_END

246
kernel/twine.h Normal file
View file

@ -0,0 +1,246 @@
#ifndef YOSYS_TWINE_H
#define YOSYS_TWINE_H
#include "kernel/yosys_common.h"
#include <cstdint>
#include <limits>
#include <span>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
YOSYS_NAMESPACE_BEGIN
// A Twine is an interned, possibly composite source-location string. Leaves
// are flat path:line.col substrings (the existing src-attribute literal). A
// Concat node holds an ordered sequence of child twines, so merging the src
// of N cells is O(N) lookups plus one concat-table probe — independent of
// the total path-string length the materialized result would have.
//
// Twines are valid only relative to the TwinePool that minted them. The pool
// lives on RTLIL::Design (design->src_twines).
struct Twine
{
using Id = uint32_t;
static constexpr Id Null = std::numeric_limits<Id>::max();
// Suffix shares a `parent` prefix with other suffixes and contributes
// its own `tail` string. The materialized leaf string is
// flat_string(parent) + tail, i.e. suffixes form trees whose leaves
// (string variant) are the roots — like a reverse-trie of common
// prefixes. The parent is itself flat (Leaf or Suffix), never a
// Concat.
struct Suffix {
Id parent;
std::string tail;
};
// Leaf holds the literal path:line.col string. Suffix holds a parent
// id + own tail (see above). Concat holds the ordered children.
// Concats are kept flat by TwinePool::concat — children are always
// flat (Leaf or Suffix), never other Concats. monostate is the
// tombstone marker for freed slots awaiting reuse via the free list.
std::variant<std::monostate, std::string, std::vector<Id>, Suffix> data;
bool is_dead() const { return std::holds_alternative<std::monostate>(data); }
bool is_leaf() const { return std::holds_alternative<std::string>(data); }
bool is_concat() const { return std::holds_alternative<std::vector<Id>>(data); }
bool is_suffix() const { return std::holds_alternative<Suffix>(data); }
bool is_flat() const { return is_leaf() || is_suffix(); }
const std::string &leaf() const { return std::get<std::string>(data); }
const std::vector<Id> &children() const { return std::get<std::vector<Id>>(data); }
const Suffix &suffix() const { return std::get<Suffix>(data); }
};
class TwinePool
{
public:
TwinePool() = default;
// Intern a leaf string. Returns the same Id for byte-equal inputs. The
// returned Id carries one reference for the caller — release it when
// you are done holding it. Empty input returns Twine::Null.
Twine::Id intern(std::string_view leaf);
// Intern a Suffix node. The resulting flat string is
// flat_string(parent) + tail. `parent` must be a flat node (Leaf or
// Suffix) — pass Twine::Null with a non-empty `tail` to fall back to
// intern(tail). Suffixes with the same (parent, tail) dedup. The
// returned Id carries one reference for the caller. Internally the
// new suffix retains a reference on `parent`; releasing the suffix
// releases that internal parent ref. Empty `tail` returns `parent`
// (with +1 ref for the caller).
Twine::Id intern_suffix(Twine::Id parent, std::string_view tail);
// Build a Concat node referencing `parts` in order. Concat children are
// always leaves (flat-leaf invariant): any Concat passed in `parts` has
// its leaves spliced in instead. Duplicate leaves and Twine::Null are
// dropped. If only one distinct leaf remains its Id is returned directly
// (no Concat node created). Concats with the same child sequence dedup.
// The returned Id carries one reference for the caller. Internally the
// concat retains each child it stores; releasing the concat releases
// those internal child references.
Twine::Id concat(std::span<const Twine::Id> parts);
Twine::Id concat(Twine::Id a, Twine::Id b);
// Refcount control. retain bumps; release decrements and, on reaching
// zero, marks the slot dead, drops it from the dedup indexes, releases
// any child refs the slot owned, and pushes the slot id onto the free
// list for reuse by the next intern/concat. Both no-op on Twine::Null.
void retain(Twine::Id id);
void release(Twine::Id id);
uint32_t refcount(Twine::Id id) const;
bool is_alive(Twine::Id id) const;
// Materialize a Twine to the pipe-separated flat string used by the
// existing src attribute convention. Leaves visit in left-to-right DFS
// order; duplicate leaves are skipped to match `pool`-style semantics.
std::string flatten(Twine::Id id, char sep = '|') const;
// Materialize a flat node (Leaf or Suffix) to its single string. id
// must be a flat node (not a Concat) and not Twine::Null.
std::string flat_string(Twine::Id id) const { return flat_string_(id); }
// Format an interned Id as the canonical src-attribute reference "@N".
// Twine::Null formats as the empty string.
static std::string format_ref(Twine::Id id);
// Parse an "@N" reference back to an Id. Returns Twine::Null if `s` is
// not exactly "@" followed by one or more decimal digits — so legacy
// literal src strings (which always contain ':' separators and have no
// reason to start with '@') are passed through unrecognized.
static Twine::Id parse_ref(std::string_view s);
// Lookup. Bounds-checked: out-of-range Id triggers log_assert via op.
const Twine &operator[](Twine::Id id) const { return nodes_.at(id); }
size_t size() const { return nodes_.size(); }
size_t leaf_count() const { return leaf_index_.size(); }
size_t concat_count() const { return concat_index_.size(); }
size_t suffix_count() const { return suffix_index_.size(); }
// One-shot debug dump of the entire pool to stdout via log(). Each leaf
// shows its string; each concat shows its child id list. Intended for
// `dump -twines` or ad-hoc tracing — output volume scales with size().
void dump(const char *banner = nullptr) const;
// Rebuild the pool to contain only the nodes named in `live` plus the
// transitive children of any live concats. Returns an old-id -> new-id
// remap; ids not in the result are dead. Callers must rewrite every
// stored "@N" cell src through the returned remap immediately, since
// after this call the old ids no longer mean what they used to.
dict<Twine::Id, Twine::Id> gc(const pool<Twine::Id> &live);
// Reconstruct `src->nodes_[src_id]` inside *this. Walks the structure
// — intern leaves, concat children — so a concat in `src` becomes a
// concat in this pool, not a flat literal of its leaves. Returns the
// id in this pool with +1 for the caller (release when done). Both
// pools may differ; the source is consulted read-only.
Twine::Id copy_from(const TwinePool &src, Twine::Id src_id);
// Iterate every live (non-tombstoned) node. fn is `void(Twine::Id, const Twine&)`.
template <typename Fn>
void for_each_live(Fn fn) const {
for (size_t i = 0; i < nodes_.size(); i++) {
const Twine &n = nodes_[i];
if (n.is_dead())
continue;
fn(static_cast<Twine::Id>(i), n);
}
}
private:
std::vector<Twine> nodes_;
std::vector<uint32_t> refcount_;
std::vector<Twine::Id> free_list_;
dict<std::string, Twine::Id> leaf_index_;
dict<std::vector<Twine::Id>, Twine::Id> concat_index_;
dict<std::pair<Twine::Id, std::string>, Twine::Id> suffix_index_;
Twine::Id alloc_slot_(Twine &&node);
void destroy_slot_(Twine::Id id);
void collect_leaves(Twine::Id id, pool<std::string> &out) const;
// Materialize a flat node (Leaf or Suffix) into its full string.
std::string flat_string_(Twine::Id id) const;
};
// Owning reference to a Twine slot. Retains on construction (and on copy
// of a non-empty ref), releases on destruction. Use this in transient
// container types — FfData, Mem helpers — that need to keep a src_id_
// alive across destruction of the original AttrObject that minted it,
// without having to fall back to a flattened path-string stash.
//
// Empty (no pool/no id) by default. A non-empty ref always carries a
// non-null pool and a live id.
class OwnedTwine
{
public:
OwnedTwine() = default;
// Adopt the +1 reference returned by `intern` / `concat` / `intern_suffix`
// / `copy_from`. Use OwnedTwine(pool, id, retain=true) when copying an
// id already held elsewhere (e.g. another AttrObject's src_id_).
OwnedTwine(TwinePool *pool, Twine::Id id, bool retain = true) : pool_(pool), id_(id) {
if (retain && pool_ && id_ != Twine::Null)
pool_->retain(id_);
}
OwnedTwine(const OwnedTwine &other) : pool_(other.pool_), id_(other.id_) {
if (pool_ && id_ != Twine::Null)
pool_->retain(id_);
}
OwnedTwine(OwnedTwine &&other) noexcept : pool_(other.pool_), id_(other.id_) {
other.pool_ = nullptr;
other.id_ = Twine::Null;
}
OwnedTwine &operator=(const OwnedTwine &other) {
if (this == &other)
return *this;
release_();
pool_ = other.pool_;
id_ = other.id_;
if (pool_ && id_ != Twine::Null)
pool_->retain(id_);
return *this;
}
OwnedTwine &operator=(OwnedTwine &&other) noexcept {
if (this == &other)
return *this;
release_();
pool_ = other.pool_;
id_ = other.id_;
other.pool_ = nullptr;
other.id_ = Twine::Null;
return *this;
}
~OwnedTwine() { release_(); }
void reset() {
release_();
pool_ = nullptr;
id_ = Twine::Null;
}
TwinePool *pool() const { return pool_; }
Twine::Id id() const { return id_; }
bool empty() const { return id_ == Twine::Null; }
private:
TwinePool *pool_ = nullptr;
Twine::Id id_ = Twine::Null;
void release_() {
if (pool_ && id_ != Twine::Null)
pool_->release(id_);
}
};
YOSYS_NAMESPACE_END
#endif

View file

@ -76,25 +76,39 @@ std::vector<Cell*> Patch::commit_staged() {
}
namespace {
void collect_src(Cell* root, const std::vector<Cell*>& extras,
Cell* merge_src_into, pool<std::string>& out)
{
out.insert(root->get_src_attribute());
for (Cell* c : extras)
if (c)
out.insert(c->get_src_attribute());
if (merge_src_into)
out.insert(merge_src_into->get_src_attribute());
}
void apply_src(const pool<std::string>& src_pool,
void apply_src(Module* mod, Cell* root, const std::vector<Cell*>& extras,
const std::vector<Cell*>& targets, Cell* merge_src_into)
{
std::string src_str = AttrObject::strpool_attribute_to_str(src_pool);
// Without a design there's no pool — the cells can't carry typed
// src, so silently drop merge-of-src in that path.
if (!mod || !mod->design)
return;
TwinePool& pool = mod->design->src_twines;
std::vector<Twine::Id> ids;
ids.reserve(2 + extras.size());
auto push = [&](Cell *c) {
if (c && c->src_id() != Twine::Null)
ids.push_back(c->src_id());
};
push(root);
for (Cell *c : extras)
push(c);
push(merge_src_into);
if (ids.empty())
return;
Twine::Id merged = pool.concat(std::span<const Twine::Id>{ids});
if (ys_debug()) {
log_debug("twine: merge yields %s (pool size %zu)\n",
TwinePool::format_ref(merged).c_str(), pool.size());
if (ys_debug(2))
pool.dump("twine pool state");
}
for (Cell* c : targets)
c->set_src_attribute(src_str);
c->set_src_id(&pool, merged);
if (merge_src_into)
merge_src_into->set_src_attribute(src_str);
merge_src_into->set_src_id(&pool, merged);
pool.release(merged);
}
// Verifies via newcelltypes that root_cell has exactly one output port
@ -133,11 +147,8 @@ void Patch::patch(Cell* root_cell, IdString old_port, SigSpec new_sig,
log_id(root_cell->name), log_id(old_port),
log_signal(old_sig), log_signal(new_sig));
pool<std::string> src_pool;
collect_src(root_cell, extras, merge_src_into, src_pool);
std::vector<Cell*> committed = commit_staged();
apply_src(src_pool, committed, merge_src_into);
apply_src(mod, root_cell, extras, committed, merge_src_into);
// Drop root_cell's driver on the output port BEFORE wiring old_sig to
// new_sig — otherwise old_sig would briefly have two drivers (root_cell
@ -179,11 +190,8 @@ void Patch::patch_ports(Cell* root_cell,
log_error("patch_ports: cell %s of type %s has output port %s not in port_replacements\n",
log_id(root_cell->name), log_id(root_cell->type), log_id(port));
pool<std::string> src_pool;
collect_src(root_cell, extras, merge_src_into, src_pool);
std::vector<Cell*> committed = commit_staged();
apply_src(src_pool, committed, merge_src_into);
apply_src(mod, root_cell, extras, committed, merge_src_into);
// Drop every port (inputs included) so root_cell becomes a disconnected
// shell before we wire old_sigs to new_sigs. Doing this first ensures
@ -208,11 +216,14 @@ void Patch::patch_ports(Cell* root_cell,
}
void Patch::commit_inheriting_src(Cell* src_source) {
std::string src = src_source ? src_source->get_src_attribute() : std::string();
for (auto& cell : cells_) {
cell->set_src_attribute(src);
cell->fixup_parameters();
commit_cell(std::move(cell));
Cell *committed = commit_cell(std::move(cell));
// commit_cell attaches the cell to mod, so adopt_src_from can
// now resolve the pool via committed->module->design. Direct
// id transfer — no flatten/re-intern detour.
if (src_source)
committed->adopt_src_from(src_source);
}
for (auto& wire : wires_)
commit_wire(std::move(wire));