This commit is contained in:
Emil J. Tywoniak 2026-06-12 00:18:53 +02:00
parent afdae7b87e
commit c3ffbf6fae
229 changed files with 3902 additions and 3835 deletions

View File

@ -672,7 +672,8 @@ OBJS += kernel/log_compat.o
endif endif
OBJS += kernel/binding.o kernel/tclapi.o OBJS += kernel/binding.o kernel/tclapi.o
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o kernel/twine.o OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o kernel/twine.o
OBJS += kernel/drivertools.o kernel/functional.o kernel/threading.o OBJS += kernel/drivertools.o kernel/threading.o
# OBJS += kernel/functional.o
ifeq ($(ENABLE_ZLIB),1) ifeq ($(ENABLE_ZLIB),1)
OBJS += kernel/fstdata.o OBJS += kernel/fstdata.o
endif endif

View File

@ -221,7 +221,7 @@ struct AigerWriter
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($_NOT_)) if (cell->type == TW($_NOT_))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit Y = sigmap(cell->getPort(TW::Y).as_bit()); SigBit Y = sigmap(cell->getPort(TW::Y).as_bit());
@ -231,7 +231,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_))) if (cell->type.in(TW($_FF_), TW($_DFF_N_), TW($_DFF_P_)))
{ {
SigBit D = sigmap(cell->getPort(TW::D).as_bit()); SigBit D = sigmap(cell->getPort(TW::D).as_bit());
SigBit Q = sigmap(cell->getPort(TW::Q).as_bit()); SigBit Q = sigmap(cell->getPort(TW::Q).as_bit());
@ -239,14 +239,14 @@ struct AigerWriter
undriven_bits.erase(Q); undriven_bits.erase(Q);
ff_map[Q] = D; ff_map[Q] = D;
if (cell->type != ID($_FF_)) { if (cell->type != TW($_FF_)) {
auto sig_clk = sigmap(cell->getPort(TW::C).as_bit()); auto sig_clk = sigmap(cell->getPort(TW::C).as_bit());
ywmap_clocks[sig_clk] |= cell->type == ID($_DFF_N_) ? 2 : 1; ywmap_clocks[sig_clk] |= cell->type == TW($_DFF_N_) ? 2 : 1;
} }
continue; continue;
} }
if (cell->type == ID($anyinit)) if (cell->type == TW($anyinit))
{ {
auto sig_d = sigmap(cell->getPort(TW::D)); auto sig_d = sigmap(cell->getPort(TW::D));
auto sig_q = sigmap(cell->getPort(TW::Q)); auto sig_q = sigmap(cell->getPort(TW::Q));
@ -257,7 +257,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($_AND_)) if (cell->type == TW($_AND_))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit B = sigmap(cell->getPort(TW::B).as_bit()); SigBit B = sigmap(cell->getPort(TW::B).as_bit());
@ -269,7 +269,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($initstate)) if (cell->type == TW($initstate))
{ {
SigBit Y = sigmap(cell->getPort(TW::Y).as_bit()); SigBit Y = sigmap(cell->getPort(TW::Y).as_bit());
undriven_bits.erase(Y); undriven_bits.erase(Y);
@ -277,7 +277,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($assert)) if (cell->type == TW($assert))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit()); SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
@ -288,7 +288,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($assume)) if (cell->type == TW($assume))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit()); SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
@ -299,7 +299,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($live)) if (cell->type == TW($live))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit()); SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
@ -309,7 +309,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($fair)) if (cell->type == TW($fair))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit()); SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
@ -319,7 +319,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($anyconst)) if (cell->type == TW($anyconst))
{ {
for (auto bit : sigmap(cell->getPort(TW::Y))) { for (auto bit : sigmap(cell->getPort(TW::Y))) {
undriven_bits.erase(bit); undriven_bits.erase(bit);
@ -328,7 +328,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type == ID($anyseq)) if (cell->type == TW($anyseq))
{ {
for (auto bit : sigmap(cell->getPort(TW::Y))) { for (auto bit : sigmap(cell->getPort(TW::Y))) {
undriven_bits.erase(bit); undriven_bits.erase(bit);
@ -337,7 +337,7 @@ struct AigerWriter
continue; continue;
} }
if (cell->type.in(ID($scopeinfo), ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($scopeinfo), TW($input_port), TW($output_port), TW($public)))
continue; continue;
log_error("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell); log_error("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell);
@ -773,10 +773,10 @@ struct AigerWriter
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_), ID($anyinit), ID($anyconst), ID($anyseq))) if (cell->type.in(TW($_FF_), TW($_DFF_N_), TW($_DFF_P_), TW($anyinit), TW($anyconst), TW($anyseq)))
{ {
// Use sig_q to get the FF output name, but sig to lookup aiger bits // Use sig_q to get the FF output name, but sig to lookup aiger bits
auto sig_qy = cell->getPort(cell->type.in(ID($anyconst), ID($anyseq)) ? TW::Y : TW::Q); auto sig_qy = cell->getPort(cell->type.in(TW($anyconst), TW($anyseq)) ? TW::Y : TW::Q);
SigSpec sig = sigmap(sig_qy); SigSpec sig = sigmap(sig_qy);
if (cell->get_bool_attribute(ID(clk2fflogic))) if (cell->get_bool_attribute(ID(clk2fflogic)))

View File

@ -187,11 +187,11 @@ struct XAigerWriter
TimingInfo timing; TimingInfo timing;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in(ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($input_port), TW($output_port), TW($public)))
continue; continue;
if (!cell->has_keep_attr()) { if (!cell->has_keep_attr()) {
if (cell->type == ID($_NOT_)) if (cell->type == TW($_NOT_))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit Y = sigmap(cell->getPort(TW::Y).as_bit()); SigBit Y = sigmap(cell->getPort(TW::Y).as_bit());
@ -201,7 +201,7 @@ struct XAigerWriter
continue; continue;
} }
if (cell->type == ID($_AND_)) if (cell->type == TW($_AND_))
{ {
SigBit A = sigmap(cell->getPort(TW::A).as_bit()); SigBit A = sigmap(cell->getPort(TW::A).as_bit());
SigBit B = sigmap(cell->getPort(TW::B).as_bit()); SigBit B = sigmap(cell->getPort(TW::B).as_bit());
@ -213,7 +213,7 @@ struct XAigerWriter
continue; continue;
} }
if (dff_mode && cell->type.in(ID($_DFF_N_), ID($_DFF_P_)) && !cell->get_bool_attribute(ID::abc9_keep)) if (dff_mode && cell->type.in(TW($_DFF_N_), TW($_DFF_P_)) && !cell->get_bool_attribute(ID::abc9_keep))
{ {
SigBit D = sigmap(cell->getPort(TW::D).as_bit()); SigBit D = sigmap(cell->getPort(TW::D).as_bit());
SigBit Q = sigmap(cell->getPort(TW::Q).as_bit()); SigBit Q = sigmap(cell->getPort(TW::Q).as_bit());
@ -224,7 +224,7 @@ struct XAigerWriter
continue; continue;
} }
if (cell->type.in(ID($specify2), ID($specify3), ID($specrule))) if (cell->type.in(TW($specify2), TW($specify3), TW($specrule)))
continue; continue;
} }
@ -248,12 +248,12 @@ struct XAigerWriter
continue; continue;
} }
auto inst_name_id = RTLIL::IdString(design->twines.str(inst_module->meta_->name)); auto inst_name_id = inst_module->meta_->name;
if (!timing.count(inst_name_id)) if (!timing.count(inst_name_id))
timing.setup_module(inst_module); timing.setup_module(inst_module);
for (auto &i : timing.at(inst_name_id).arrival) { for (auto &i : timing.at(inst_name_id).arrival) {
auto port_name_ref = design->twines.add(Twine{i.first.name.str()}); auto port_name_ref = i.first.name;
if (!cell->hasPort(port_name_ref)) if (!cell->hasPort(port_name_ref))
continue; continue;
@ -273,7 +273,7 @@ struct XAigerWriter
if (ys_debug(1)) { if (ys_debug(1)) {
static pool<std::pair<IdString,TimingInfo::NameBit>> seen; static pool<std::pair<IdString,TimingInfo::NameBit>> seen;
if (seen.emplace(inst_name_id, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n", if (seen.emplace(inst_name_id, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n",
cell->type.unescape(), i.first.name.unescape(), offset, d); cell->type.unescape(), design->twines.unescaped_str(i.first.name), offset, d);
} }
#endif #endif
arrival_times[rhs[offset]] = d; arrival_times[rhs[offset]] = d;
@ -308,7 +308,7 @@ struct XAigerWriter
} }
} }
//log_warning("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell); //log_warning("Unsupported cell type: %s (%s)\n", cell->type.unescaped(), cell);
} }
dict<IdString, std::vector<TwineRef>> box_ports; dict<IdString, std::vector<TwineRef>> box_ports;

View File

@ -32,21 +32,21 @@
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
#define BITWISE_OPS ID($buf), ID($not), ID($mux), ID($and), ID($or), ID($xor), ID($xnor), ID($fa), \ #define BITWISE_OPS TW($buf), TW($not), TW($mux), TW($and), TW($or), TW($xor), TW($xnor), TW($fa), \
ID($bwmux) TW($bwmux)
#define REDUCE_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool) #define REDUCE_OPS TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool)
#define LOGIC_OPS ID($logic_and), ID($logic_or), ID($logic_not) #define LOGIC_OPS TW($logic_and), TW($logic_or), TW($logic_not)
#define GATE_OPS ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), \ #define GATE_OPS TW($_BUF_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), \
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), \ TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_), TW($_MUX_), TW($_NMUX_), \
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_) TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)
#define CMP_OPS ID($eq), ID($ne), ID($lt), ID($le), ID($ge), ID($gt) #define CMP_OPS TW($eq), TW($ne), TW($lt), TW($le), TW($ge), TW($gt)
// TODO // TODO
//#define ARITH_OPS ID($add), ID($sub), ID($neg) //#define ARITH_OPS TW($add), TW($sub), TW($neg)
static constexpr auto known_ops = []() constexpr { static constexpr auto known_ops = []() constexpr {
StaticCellTypes::Categories::Category c{}; StaticCellTypes::Categories::Category c{};
@ -60,7 +60,7 @@ static constexpr auto known_ops = []() constexpr {
c.set_id(id); c.set_id(id);
for (auto id : {CMP_OPS}) for (auto id : {CMP_OPS})
c.set_id(id); c.set_id(id);
for (auto id : {ID($pos), ID($pmux), ID($bmux)}) for (auto id : {TW($pos), TW($pmux), TW($bmux)})
c.set_id(id); c.set_id(id);
return c; return c;
}(); }();
@ -109,7 +109,7 @@ struct Index {
int pos = index_wires(info, m); int pos = index_wires(info, m);
for (auto cell : m->cells()) { for (auto cell : m->cells()) {
if (known_ops(cell->type) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port), ID($output_port), ID($public))) if (known_ops(cell->type) || cell->type.in(TW($scopeinfo), TW($specify2), TW($specify3), TW($input_port), TW($output_port), TW($public)))
continue; continue;
Module *submodule = m->design->module(cell->type); Module *submodule = m->design->module(cell->type);
@ -128,7 +128,7 @@ struct Index {
// can't bail at this point. If they are hit by a traversal // can't bail at this point. If they are hit by a traversal
// (which can only really happen with $tribuf not // (which can only really happen with $tribuf not
// $connect), we can still detect this as an error later. // $connect), we can still detect this as an error later.
if (cell->type == ID($connect) || (cell->type == ID($tribuf) && cell->has_attribute(ID(aiger2_zbuf)))) if (cell->type == TW($connect) || (cell->type == TW($tribuf) && cell->has_attribute(ID(aiger2_zbuf))))
continue; continue;
if (!submodule || submodule->get_blackbox_attribute()) if (!submodule || submodule->get_blackbox_attribute())
log_error("Unsupported cell type: %s (%s in %s)\n", log_error("Unsupported cell type: %s (%s in %s)\n",
@ -292,18 +292,18 @@ struct Index {
aport.extend_u0(width, asigned); aport.extend_u0(width, asigned);
bport.extend_u0(width, bsigned); bport.extend_u0(width, bsigned);
if (cell->type.in(ID($eq), ID($ne))) { if (cell->type.in(TW($eq), TW($ne))) {
int carry = CTRUE; int carry = CTRUE;
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
Lit a = visit(cursor, aport[i]); Lit a = visit(cursor, aport[i]);
Lit b = visit(cursor, bport[i]); Lit b = visit(cursor, bport[i]);
carry = AND(carry, XNOR(a, b)); carry = AND(carry, XNOR(a, b));
} }
return (cell->type == ID($eq)) ? carry : /* $ne */ NOT(carry); return (cell->type == TW($eq)) ? carry : /* $ne */ NOT(carry);
} else if (cell->type.in(ID($lt), ID($le), ID($gt), ID($ge))) { } else if (cell->type.in(TW($lt), TW($le), TW($gt), TW($ge))) {
if (cell->type.in(ID($gt), ID($ge))) if (cell->type.in(TW($gt), TW($ge)))
std::swap(aport, bport); std::swap(aport, bport);
int carry = cell->type.in(ID($le), ID($ge)) ? CFALSE : CTRUE; int carry = cell->type.in(TW($le), TW($ge)) ? CFALSE : CTRUE;
Lit a = Writer::EMPTY_LIT; Lit a = Writer::EMPTY_LIT;
Lit b = Writer::EMPTY_LIT; Lit b = Writer::EMPTY_LIT;
// TODO: this might not be the most economic structure; revisit at a later date // TODO: this might not be the most economic structure; revisit at a later date
@ -317,28 +317,28 @@ struct Index {
} else { } else {
log_abort(); log_abort();
} }
} else if (cell->type.in(REDUCE_OPS, ID($logic_not))) { } else if (cell->type.in(REDUCE_OPS, TW($logic_not))) {
SigSpec inport = cell->getPort(TW::A); SigSpec inport = cell->getPort(TW::A);
std::vector<Lit> lits; std::vector<Lit> lits;
for (int i = 0; i < inport.size(); i++) { for (int i = 0; i < inport.size(); i++) {
Lit lit = visit(cursor, inport[i]); Lit lit = visit(cursor, inport[i]);
if (cell->type.in(ID($reduce_and), ID($reduce_xor), ID($reduce_xnor))) { if (cell->type.in(TW($reduce_and), TW($reduce_xor), TW($reduce_xnor))) {
lits.push_back(lit); lits.push_back(lit);
} else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) { } else if (cell->type.in(TW($reduce_or), TW($reduce_bool), TW($logic_not))) {
lits.push_back(NOT(lit)); lits.push_back(NOT(lit));
} else { } else {
log_abort(); log_abort();
} }
} }
Lit acc = REDUCE(lits, cell->type.in(ID($reduce_xor), ID($reduce_xnor))); Lit acc = REDUCE(lits, cell->type.in(TW($reduce_xor), TW($reduce_xnor)));
if (!cell->type.in(ID($reduce_xnor), ID($reduce_or), ID($reduce_bool))) if (!cell->type.in(TW($reduce_xnor), TW($reduce_or), TW($reduce_bool)))
return acc; return acc;
else else
return NOT(acc); return NOT(acc);
} else if (cell->type.in(ID($logic_and), ID($logic_or))) { } else if (cell->type.in(TW($logic_and), TW($logic_or))) {
SigSpec aport = cell->getPort(TW::A); SigSpec aport = cell->getPort(TW::A);
SigSpec bport = cell->getPort(TW::B); SigSpec bport = cell->getPort(TW::B);
@ -356,13 +356,13 @@ struct Index {
b = OR(b, l); b = OR(b, l);
} }
if (cell->type == ID($logic_and)) if (cell->type == TW($logic_and))
return AND(a, b); return AND(a, b);
else if (cell->type == ID($logic_or)) else if (cell->type == TW($logic_or))
return OR(a, b); return OR(a, b);
else else
log_abort(); log_abort();
} else if (cell->type.in(BITWISE_OPS, GATE_OPS, ID($pos))) { } else if (cell->type.in(BITWISE_OPS, GATE_OPS, TW($pos))) {
SigSpec aport = cell->getPort(TW::A); SigSpec aport = cell->getPort(TW::A);
Lit a; Lit a;
if (obit < aport.size()) { if (obit < aport.size()) {
@ -374,9 +374,9 @@ struct Index {
a = CFALSE; a = CFALSE;
} }
if (cell->type.in(ID($buf), ID($pos), ID($_BUF_))) { if (cell->type.in(TW($buf), TW($pos), TW($_BUF_))) {
return a; return a;
} else if (cell->type.in(ID($not), ID($_NOT_))) { } else if (cell->type.in(TW($not), TW($_NOT_))) {
return NOT(a); return NOT(a);
} else { } else {
SigSpec bport = cell->getPort(TW::B); SigSpec bport = cell->getPort(TW::B);
@ -390,32 +390,32 @@ struct Index {
b = CFALSE; b = CFALSE;
} }
if (cell->type.in(ID($and), ID($_AND_))) { if (cell->type.in(TW($and), TW($_AND_))) {
return AND(a, b); return AND(a, b);
} else if (cell->type.in(ID($_NAND_))) { } else if (cell->type.in(TW($_NAND_))) {
return NOT(AND(a, b)); return NOT(AND(a, b));
} else if (cell->type.in(ID($or), ID($_OR_))) { } else if (cell->type.in(TW($or), TW($_OR_))) {
return OR(a, b); return OR(a, b);
} else if (cell->type.in(ID($_NOR_))) { } else if (cell->type.in(TW($_NOR_))) {
return NOT(OR(a, b)); return NOT(OR(a, b));
} else if (cell->type.in(ID($xor), ID($_XOR_))) { } else if (cell->type.in(TW($xor), TW($_XOR_))) {
return XOR(a, b); return XOR(a, b);
} else if (cell->type.in(ID($xnor), ID($_XNOR_))) { } else if (cell->type.in(TW($xnor), TW($_XNOR_))) {
return XNOR(a, b); return XNOR(a, b);
} else if (cell->type.in(ID($_ANDNOT_))) { } else if (cell->type.in(TW($_ANDNOT_))) {
return AND(a, NOT(b)); return AND(a, NOT(b));
} else if (cell->type.in(ID($_ORNOT_))) { } else if (cell->type.in(TW($_ORNOT_))) {
return OR(a, NOT(b)); return OR(a, NOT(b));
} else if (cell->type.in(ID($mux), ID($_MUX_))) { } else if (cell->type.in(TW($mux), TW($_MUX_))) {
Lit s = visit(cursor, cell->getPort(TW::S)); Lit s = visit(cursor, cell->getPort(TW::S));
return MUX(a, b, s); return MUX(a, b, s);
} else if (cell->type.in(ID($bwmux))) { } else if (cell->type.in(TW($bwmux))) {
Lit s = visit(cursor, cell->getPort(TW::S)[obit]); Lit s = visit(cursor, cell->getPort(TW::S)[obit]);
return MUX(a, b, s); return MUX(a, b, s);
} else if (cell->type.in(ID($_NMUX_))) { } else if (cell->type.in(TW($_NMUX_))) {
Lit s = visit(cursor, cell->getPort(TW::S)[obit]); Lit s = visit(cursor, cell->getPort(TW::S)[obit]);
return NOT(MUX(a, b, s)); return NOT(MUX(a, b, s));
} else if (cell->type.in(ID($fa))) { } else if (cell->type.in(TW($fa))) {
Lit c = visit(cursor, cell->getPort(TW::C)[obit]); Lit c = visit(cursor, cell->getPort(TW::C)[obit]);
Lit ab = XOR(a, b); Lit ab = XOR(a, b);
if (oport == TW::Y) { if (oport == TW::Y) {
@ -425,16 +425,16 @@ struct Index {
Lit c_and_ab = AND(c, ab); Lit c_and_ab = AND(c, ab);
return OR(a_and_b, c_and_ab); return OR(a_and_b, c_and_ab);
} }
} else if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { } else if (cell->type.in(TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_))) {
Lit c, d; Lit c, d;
c = visit(cursor, cell->getPort(TW::C)[obit]); c = visit(cursor, cell->getPort(TW::C)[obit]);
if (/* 4 input types */ cell->type.in(ID($_AOI4_), ID($_OAI4_))) if (/* 4 input types */ cell->type.in(TW($_AOI4_), TW($_OAI4_)))
d = visit(cursor, cell->getPort(TW::D)[obit]); d = visit(cursor, cell->getPort(TW::D)[obit]);
else else
d = cell->type == ID($_AOI3_) ? CTRUE : CFALSE; d = cell->type == TW($_AOI3_) ? CTRUE : CFALSE;
if (/* aoi */ cell->type.in(ID($_AOI3_), ID($_AOI4_))) { if (/* aoi */ cell->type.in(TW($_AOI3_), TW($_AOI4_))) {
Lit a_and_b = AND(a, b); Lit a_and_b = AND(a, b);
Lit c_and_d = AND(c, d); Lit c_and_d = AND(c, d);
return NOT(OR(a_and_b, c_and_d)); return NOT(OR(a_and_b, c_and_d));
@ -447,7 +447,7 @@ struct Index {
log_abort(); log_abort();
} }
} }
} else if (cell->type == ID($pmux)) { } else if (cell->type == TW($pmux)) {
SigSpec aport = cell->getPort(TW::A); SigSpec aport = cell->getPort(TW::A);
SigSpec bport = cell->getPort(TW::B); SigSpec bport = cell->getPort(TW::B);
SigSpec sport = cell->getPort(TW::S); SigSpec sport = cell->getPort(TW::S);
@ -468,7 +468,7 @@ struct Index {
Lit reduce_bar = NOT(REDUCE(bar)); Lit reduce_bar = NOT(REDUCE(bar));
return OR(reduce_sels_and_a, reduce_bar); return OR(reduce_sels_and_a, reduce_bar);
} else if (cell->type == ID($bmux)) { } else if (cell->type == TW($bmux)) {
SigSpec aport = cell->getPort(TW::A); SigSpec aport = cell->getPort(TW::A);
SigSpec sport = cell->getPort(TW::S); SigSpec sport = cell->getPort(TW::S);
int width = cell->getParam(ID::WIDTH).as_int(); int width = cell->getParam(ID::WIDTH).as_int();
@ -537,7 +537,7 @@ struct Index {
Design *design = index.design; Design *design = index.design;
auto &minfo = leaf_minfo(index); auto &minfo = leaf_minfo(index);
if (!minfo.suboffsets.count(cell)) if (!minfo.suboffsets.count(cell))
log_error("Reached unsupported cell %s (%s in %s)\n", cell->type.unescape(), cell, cell->module); log_error("Reached unsupported cell %s (%s in %s)\n", cell->type.unescaped(), cell, cell->module);
Module *def = design->module(cell->type); Module *def = design->module(cell->type);
log_assert(def); log_assert(def);
levels.push_back(Level(index.modules.at(def), cell)); levels.push_back(Level(index.modules.at(def), cell));
@ -660,7 +660,7 @@ struct Index {
auto &port = instance->getPort(portname); auto &port = instance->getPort(portname);
if (bit.offset >= port.size()) if (bit.offset >= port.size())
log_error("Bit %d of input port %s on instance %s of %s unconnected\n", log_error("Bit %d of input port %s on instance %s of %s unconnected\n",
bit.offset, design->twines.str(portname).c_str(), instance, instance->type.unescape()); bit.offset, design->twines.str(portname).c_str(), instance, design->twines.unescaped_str(instance->type));
ret = visit(cursor, port[bit.offset]); ret = visit(cursor, port[bit.offset]);
} }
cursor.enter(*this, instance); cursor.enter(*this, instance);
@ -845,7 +845,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "o%d ", i); snprintf(buf, sizeof(buf), "o%d ", i);
f->write(buf, strlen(buf)); f->write(buf, strlen(buf));
std::string name = bit.wire->name.unescape(); std::string name = design->twines.unescaped_str(bit.wire->name);
f->write(name.data(), name.size()); f->write(name.data(), name.size());
f->put('\n'); f->put('\n');
} }
@ -858,7 +858,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "i%d ", i); snprintf(buf, sizeof(buf), "i%d ", i);
f->write(buf, strlen(buf)); f->write(buf, strlen(buf));
std::string name = bit.wire->name.unescape(); std::string name = design->twines.unescaped_str(bit.wire->name);
f->write(name.data(), name.size()); f->write(name.data(), name.size());
f->put('\n'); f->put('\n');
} }
@ -1090,7 +1090,7 @@ struct XAigerWriter : AigerWriter {
for (auto box : minfo.found_blackboxes) { for (auto box : minfo.found_blackboxes) {
log_debug(" - %s.%s (type %s): ", cursor.path(), log_debug(" - %s.%s (type %s): ", cursor.path(),
box, box,
box->type.unescape()); design->twines.unescaped_str(box->type));
Module *box_module = design->module(box->type), *box_derived; Module *box_module = design->module(box->type), *box_derived;
@ -1159,7 +1159,7 @@ struct XAigerWriter : AigerWriter {
} else { } else {
// FIXME: hierarchical path // FIXME: hierarchical path
log_warning("connection on port %s[%d] of instance %s (type %s) missing, using 1'bx\n", log_warning("connection on port %s[%d] of instance %s (type %s) missing, using 1'bx\n",
design->twines.str(port_id).c_str(), i, box, box->type.unescape()); design->twines.str(port_id).c_str(), i, box, design->twines.unescaped_str(box->type));
bit = RTLIL::Sx; bit = RTLIL::Sx;
} }
@ -1194,7 +1194,7 @@ struct XAigerWriter : AigerWriter {
} else { } else {
// FIXME: hierarchical path // FIXME: hierarchical path
log_warning("connection on port %s[%d] of instance %s (type %s) missing\n", log_warning("connection on port %s[%d] of instance %s (type %s) missing\n",
design->twines.str(port_id).c_str(), i, box, box->type.unescape()); design->twines.str(port_id).c_str(), i, box, design->twines.unescaped_str(box->type));
pad_pi(); pad_pi();
continue; continue;
} }
@ -1211,7 +1211,7 @@ struct XAigerWriter : AigerWriter {
holes_wb->setPort(port_id, w); holes_wb->setPort(port_id, w);
} else { } else {
log_error("Ambiguous port direction on %s/%s\n", log_error("Ambiguous port direction on %s/%s\n",
box->type.unescape(), design->twines.str(port_id).c_str()); design->twines.unescaped_str(box->type), design->twines.str(port_id).c_str());
} }
} }
} }
@ -1406,7 +1406,7 @@ struct Aiger2Backend : Backend {
continue; continue;
if (known_ops(cell.type)) if (known_ops(cell.type))
continue; continue;
std::string name = cell.type.unescape(); std::string name = design->twines.unescaped_str(cell.type);
if (col + name.size() + 2 > 72) { if (col + name.size() + 2 > 72) {
log("\n "); log("\n ");
col = 0; col = 0;
@ -1428,7 +1428,7 @@ struct Aiger2Backend : Backend {
continue; continue;
if (known_ops(cell.type)) if (known_ops(cell.type))
continue; continue;
std::string name = cell.type.unescape(); std::string name = design->twines.unescaped_str(cell.type);
if (col + name.size() + 2 > 72) { if (col + name.size() + 2 > 72) {
log("\n "); log("\n ");
col = 0; col = 0;

View File

@ -91,7 +91,7 @@ struct BlifDumper
const std::string str(RTLIL::IdString id) const std::string str(RTLIL::IdString id)
{ {
std::string str = id.unescape(); std::string str = design->twines.unescaped_str(id);
for (size_t i = 0; i < str.size(); i++) for (size_t i = 0; i < str.size(); i++)
if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>') if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>')
str[i] = '?'; str[i] = '?';
@ -108,7 +108,7 @@ struct BlifDumper
return config->undef_type == "-" || config->undef_type == "+" ? config->undef_out.c_str() : "$undef"; return config->undef_type == "-" || config->undef_type == "+" ? config->undef_out.c_str() : "$undef";
} }
std::string str = sig.wire->name.unescape(); std::string str = design->twines.unescaped_str(sig.wire->name);
for (size_t i = 0; i < str.size(); i++) for (size_t i = 0; i < str.size(); i++)
if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>') if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>')
str[i] = '?'; str[i] = '?';
@ -150,7 +150,7 @@ struct BlifDumper
void dump_params(const char *command, dict<IdString, Const> &params) void dump_params(const char *command, dict<IdString, Const> &params)
{ {
for (auto &param : params) { for (auto &param : params) {
f << stringf("%s %s ", command, param.first.unescape()); f << stringf("%s %s ", command, design->twines.unescaped_str(param.first));
if (param.second.flags & RTLIL::CONST_FLAG_STRING) { if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
std::string str = param.second.decode_string(); std::string str = param.second.decode_string();
f << stringf("\""); f << stringf("\"");
@ -232,7 +232,7 @@ struct BlifDumper
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
continue; continue;
if (config->unbuf_types.count(cell->type)) { if (config->unbuf_types.count(cell->type)) {
@ -244,131 +244,131 @@ struct BlifDumper
continue; continue;
} }
if (!config->icells_mode && cell->type == ID($_NOT_)) { if (!config->icells_mode && cell->type == TW($_NOT_)) {
f << stringf(".names %s %s\n0 1\n", f << stringf(".names %s %s\n0 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_AND_)) { if (!config->icells_mode && cell->type == TW($_AND_)) {
f << stringf(".names %s %s %s\n11 1\n", f << stringf(".names %s %s %s\n11 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_OR_)) { if (!config->icells_mode && cell->type == TW($_OR_)) {
f << stringf(".names %s %s %s\n1- 1\n-1 1\n", f << stringf(".names %s %s %s\n1- 1\n-1 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_XOR_)) { if (!config->icells_mode && cell->type == TW($_XOR_)) {
f << stringf(".names %s %s %s\n10 1\n01 1\n", f << stringf(".names %s %s %s\n10 1\n01 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_NAND_)) { if (!config->icells_mode && cell->type == TW($_NAND_)) {
f << stringf(".names %s %s %s\n0- 1\n-0 1\n", f << stringf(".names %s %s %s\n0- 1\n-0 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_NOR_)) { if (!config->icells_mode && cell->type == TW($_NOR_)) {
f << stringf(".names %s %s %s\n00 1\n", f << stringf(".names %s %s %s\n00 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_XNOR_)) { if (!config->icells_mode && cell->type == TW($_XNOR_)) {
f << stringf(".names %s %s %s\n11 1\n00 1\n", f << stringf(".names %s %s %s\n11 1\n00 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_ANDNOT_)) { if (!config->icells_mode && cell->type == TW($_ANDNOT_)) {
f << stringf(".names %s %s %s\n10 1\n", f << stringf(".names %s %s %s\n10 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_ORNOT_)) { if (!config->icells_mode && cell->type == TW($_ORNOT_)) {
f << stringf(".names %s %s %s\n1- 1\n-0 1\n", f << stringf(".names %s %s %s\n1- 1\n-0 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_AOI3_)) { if (!config->icells_mode && cell->type == TW($_AOI3_)) {
f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n", f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_OAI3_)) { if (!config->icells_mode && cell->type == TW($_OAI3_)) {
f << stringf(".names %s %s %s %s\n00- 1\n--0 1\n", f << stringf(".names %s %s %s %s\n00- 1\n--0 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_AOI4_)) { if (!config->icells_mode && cell->type == TW($_AOI4_)) {
f << stringf(".names %s %s %s %s %s\n-0-0 1\n-00- 1\n0--0 1\n0-0- 1\n", f << stringf(".names %s %s %s %s %s\n-0-0 1\n-00- 1\n0--0 1\n0-0- 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(),
str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::D)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::D)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_OAI4_)) { if (!config->icells_mode && cell->type == TW($_OAI4_)) {
f << stringf(".names %s %s %s %s %s\n00-- 1\n--00 1\n", f << stringf(".names %s %s %s %s %s\n00-- 1\n--00 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(),
str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::D)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::C)).c_str(), str(cell->getPort(TW::D)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_MUX_)) { if (!config->icells_mode && cell->type == TW($_MUX_)) {
f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n", f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(),
str(cell->getPort(TW::S)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::S)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_NMUX_)) { if (!config->icells_mode && cell->type == TW($_NMUX_)) {
f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n", f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n",
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(),
str(cell->getPort(TW::S)).c_str(), str(cell->getPort(TW::Y)).c_str()); str(cell->getPort(TW::S)).c_str(), str(cell->getPort(TW::Y)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_FF_)) { if (!config->icells_mode && cell->type == TW($_FF_)) {
f << stringf(".latch %s %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)), f << stringf(".latch %s %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)),
str_init(cell->getPort(TW::Q)).c_str()); str_init(cell->getPort(TW::Q)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_DFF_N_)) { if (!config->icells_mode && cell->type == TW($_DFF_N_)) {
f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)), f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)),
str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str()); str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_DFF_P_)) { if (!config->icells_mode && cell->type == TW($_DFF_P_)) {
f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)), f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)),
str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str()); str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) { if (!config->icells_mode && cell->type == TW($_DLATCH_N_)) {
f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)), f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)),
str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str()); str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) { if (!config->icells_mode && cell->type == TW($_DLATCH_P_)) {
f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)), f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(TW::D)), str(cell->getPort(TW::Q)),
str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str()); str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($lut)) { if (!config->icells_mode && cell->type == TW($lut)) {
f << stringf(".names"); f << stringf(".names");
auto &inputs = cell->getPort(TW::A); auto &inputs = cell->getPort(TW::A);
auto width = cell->parameters.at(ID::WIDTH).as_int(); auto width = cell->parameters.at(ID::WIDTH).as_int();
@ -390,7 +390,7 @@ struct BlifDumper
goto internal_cell; goto internal_cell;
} }
if (!config->icells_mode && cell->type == ID($sop)) { if (!config->icells_mode && cell->type == TW($sop)) {
f << stringf(".names"); f << stringf(".names");
auto &inputs = cell->getPort(TW::A); auto &inputs = cell->getPort(TW::A);
auto width = cell->parameters.at(ID::WIDTH).as_int(); auto width = cell->parameters.at(ID::WIDTH).as_int();

View File

@ -119,7 +119,7 @@ struct BtorWorker
template<typename T> template<typename T>
string getinfo(T *obj, bool srcsym = false) string getinfo(T *obj, bool srcsym = false)
{ {
string infostr = obj->name.unescape(); string infostr = design->twines.unescaped_str(obj->name);
if (!srcsym && !print_internal_names && infostr[0] == '$') return ""; if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
if (obj->has_attribute(ID::src)) { if (obj->has_attribute(ID::src)) {
string src = module && module->design ? module->design->get_src_attribute(obj) : std::string(); string src = module && module->design ? module->design->get_src_attribute(obj) : std::string();
@ -147,7 +147,7 @@ struct BtorWorker
string getinfo(Mem *mem, bool srcsym = false) string getinfo(Mem *mem, bool srcsym = false)
{ {
string infostr = mem->memid.unescape(); string infostr = design->twines.unescaped_str(mem->memid);
if (!srcsym && !print_internal_names && infostr[0] == '$') return ""; if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
if (mem->has_attribute(ID::src)) { if (mem->has_attribute(ID::src)) {
string src = module && module->design ? module->design->get_src_attribute(mem) : std::string(); string src = module && module->design ? module->design->get_src_attribute(mem) : std::string();
@ -280,24 +280,24 @@ struct BtorWorker
cell_recursion_guard.insert(cell); cell_recursion_guard.insert(cell);
btorf_push(cell->module->design->twines.str(cell->meta_->name)); btorf_push(cell->module->design->twines.str(cell->meta_->name));
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), if (cell->type.in(TW($add), TW($sub), TW($mul), TW($and), TW($or), TW($xor), TW($xnor), TW($shl), TW($sshl), TW($shr), TW($sshr), TW($shift), TW($shiftx),
ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_))) TW($concat), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_)))
{ {
string btor_op; string btor_op;
if (cell->type == ID($add)) btor_op = "add"; if (cell->type == TW($add)) btor_op = "add";
if (cell->type == ID($sub)) btor_op = "sub"; if (cell->type == TW($sub)) btor_op = "sub";
if (cell->type == ID($mul)) btor_op = "mul"; if (cell->type == TW($mul)) btor_op = "mul";
if (cell->type.in(ID($shl), ID($sshl))) btor_op = "sll"; if (cell->type.in(TW($shl), TW($sshl))) btor_op = "sll";
if (cell->type == ID($shr)) btor_op = "srl"; if (cell->type == TW($shr)) btor_op = "srl";
if (cell->type == ID($sshr)) btor_op = "sra"; if (cell->type == TW($sshr)) btor_op = "sra";
if (cell->type.in(ID($shift), ID($shiftx))) btor_op = "shift"; if (cell->type.in(TW($shift), TW($shiftx))) btor_op = "shift";
if (cell->type.in(ID($and), ID($_AND_))) btor_op = "and"; if (cell->type.in(TW($and), TW($_AND_))) btor_op = "and";
if (cell->type.in(ID($or), ID($_OR_))) btor_op = "or"; if (cell->type.in(TW($or), TW($_OR_))) btor_op = "or";
if (cell->type.in(ID($xor), ID($_XOR_))) btor_op = "xor"; if (cell->type.in(TW($xor), TW($_XOR_))) btor_op = "xor";
if (cell->type == ID($concat)) btor_op = "concat"; if (cell->type == TW($concat)) btor_op = "concat";
if (cell->type == ID($_NAND_)) btor_op = "nand"; if (cell->type == TW($_NAND_)) btor_op = "nand";
if (cell->type == ID($_NOR_)) btor_op = "nor"; if (cell->type == TW($_NOR_)) btor_op = "nor";
if (cell->type.in(ID($xnor), ID($_XNOR_))) btor_op = "xnor"; if (cell->type.in(TW($xnor), TW($_XNOR_))) btor_op = "xnor";
log_assert(!btor_op.empty()); log_assert(!btor_op.empty());
int width_ay = std::max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::Y))); int width_ay = std::max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::Y)));
@ -309,17 +309,17 @@ struct BtorWorker
if (btor_op == "shift" && !b_signed) if (btor_op == "shift" && !b_signed)
btor_op = "srl"; btor_op = "srl";
if (cell->type.in(ID($shl), ID($sshl), ID($shr), ID($sshr))) if (cell->type.in(TW($shl), TW($sshl), TW($shr), TW($sshr)))
b_signed = false; b_signed = false;
if (cell->type == ID($sshr) && !a_signed) if (cell->type == TW($sshr) && !a_signed)
btor_op = "srl"; btor_op = "srl";
int sid = get_bv_sid(width); int sid = get_bv_sid(width);
int nid; int nid;
int nid_a; int nid_a;
if (cell->type.in(ID($shl), ID($shr), ID($shift), ID($shiftx)) && a_signed && width_ay < width) { if (cell->type.in(TW($shl), TW($shr), TW($shift), TW($shiftx)) && a_signed && width_ay < width) {
// sign-extend A up to the width of Y // sign-extend A up to the width of Y
int nid_a_padded = get_sig_nid(cell->getPort(TW::A), width_ay, a_signed); int nid_a_padded = get_sig_nid(cell->getPort(TW::A), width_ay, a_signed);
@ -371,17 +371,17 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($div), ID($mod), ID($modfloor))) if (cell->type.in(TW($div), TW($mod), TW($modfloor)))
{ {
bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false; bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false; bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
string btor_op; string btor_op;
if (cell->type == ID($div)) btor_op = "div"; if (cell->type == TW($div)) btor_op = "div";
// "rem" = truncating modulo // "rem" = truncating modulo
if (cell->type == ID($mod)) btor_op = "rem"; if (cell->type == TW($mod)) btor_op = "rem";
// "mod" = flooring modulo // "mod" = flooring modulo
if (cell->type == ID($modfloor)) { if (cell->type == TW($modfloor)) {
// "umod" doesn't exist because it's the same as "urem" // "umod" doesn't exist because it's the same as "urem"
btor_op = a_signed || b_signed ? "mod" : "rem"; btor_op = a_signed || b_signed ? "mod" : "rem";
} }
@ -411,7 +411,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
{ {
int sid = get_bv_sid(1); int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(TW::A)); int nid_a = get_sig_nid(cell->getPort(TW::A));
@ -420,12 +420,12 @@ struct BtorWorker
int nid1 = next_nid++; int nid1 = next_nid++;
int nid2 = next_nid++; int nid2 = next_nid++;
if (cell->type == ID($_ANDNOT_)) { if (cell->type == TW($_ANDNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b); btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell)); btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
} }
if (cell->type == ID($_ORNOT_)) { if (cell->type == TW($_ORNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b); btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell)); btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
} }
@ -435,7 +435,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($_OAI3_), ID($_AOI3_))) if (cell->type.in(TW($_OAI3_), TW($_AOI3_)))
{ {
int sid = get_bv_sid(1); int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(TW::A)); int nid_a = get_sig_nid(cell->getPort(TW::A));
@ -446,13 +446,13 @@ struct BtorWorker
int nid2 = next_nid++; int nid2 = next_nid++;
int nid3 = next_nid++; int nid3 = next_nid++;
if (cell->type == ID($_OAI3_)) { if (cell->type == TW($_OAI3_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c); btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell)); btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
} }
if (cell->type == ID($_AOI3_)) { if (cell->type == TW($_AOI3_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c); btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell)); btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
@ -463,7 +463,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($_OAI4_), ID($_AOI4_))) if (cell->type.in(TW($_OAI4_), TW($_AOI4_)))
{ {
int sid = get_bv_sid(1); int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(TW::A)); int nid_a = get_sig_nid(cell->getPort(TW::A));
@ -476,14 +476,14 @@ struct BtorWorker
int nid3 = next_nid++; int nid3 = next_nid++;
int nid4 = next_nid++; int nid4 = next_nid++;
if (cell->type == ID($_OAI4_)) { if (cell->type == TW($_OAI4_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d); btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2); btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell)); btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell));
} }
if (cell->type == ID($_AOI4_)) { if (cell->type == TW($_AOI4_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d); btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2); btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
@ -495,15 +495,15 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($eqx), ID($ne), ID($nex), ID($ge), ID($gt))) if (cell->type.in(TW($lt), TW($le), TW($eq), TW($eqx), TW($ne), TW($nex), TW($ge), TW($gt)))
{ {
string btor_op; string btor_op;
if (cell->type == ID($lt)) btor_op = "lt"; if (cell->type == TW($lt)) btor_op = "lt";
if (cell->type == ID($le)) btor_op = "lte"; if (cell->type == TW($le)) btor_op = "lte";
if (cell->type.in(ID($eq), ID($eqx))) btor_op = "eq"; if (cell->type.in(TW($eq), TW($eqx))) btor_op = "eq";
if (cell->type.in(ID($ne), ID($nex))) btor_op = "neq"; if (cell->type.in(TW($ne), TW($nex))) btor_op = "neq";
if (cell->type == ID($ge)) btor_op = "gte"; if (cell->type == TW($ge)) btor_op = "gte";
if (cell->type == ID($gt)) btor_op = "gt"; if (cell->type == TW($gt)) btor_op = "gt";
log_assert(!btor_op.empty()); log_assert(!btor_op.empty());
int width = 1; int width = 1;
@ -518,7 +518,7 @@ struct BtorWorker
int nid_b = get_sig_nid(cell->getPort(TW::B), width, b_signed); int nid_b = get_sig_nid(cell->getPort(TW::B), width, b_signed);
int nid = next_nid++; int nid = next_nid++;
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) { if (cell->type.in(TW($lt), TW($le), TW($ge), TW($gt))) {
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell)); btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell));
} else { } else {
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell)); btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
@ -537,11 +537,11 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_))) if (cell->type.in(TW($not), TW($neg), TW($_NOT_), TW($pos), TW($buf), TW($_BUF_)))
{ {
string btor_op; string btor_op;
if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not"; if (cell->type.in(TW($not), TW($_NOT_))) btor_op = "not";
if (cell->type == ID($neg)) btor_op = "neg"; if (cell->type == TW($neg)) btor_op = "neg";
int width = std::max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::Y))); int width = std::max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::Y)));
@ -551,7 +551,7 @@ struct BtorWorker
// the $pos/$buf cells just pass through, all other cells need an actual operation applied // the $pos/$buf cells just pass through, all other cells need an actual operation applied
int nid = nid_a; int nid = nid_a;
if (!cell->type.in(ID($pos), ID($buf), ID($_BUF_))) if (!cell->type.in(TW($pos), TW($buf), TW($_BUF_)))
{ {
log_assert(!btor_op.empty()); log_assert(!btor_op.empty());
int sid = get_bv_sid(width); int sid = get_bv_sid(width);
@ -570,12 +570,12 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($logic_and), ID($logic_or), ID($logic_not))) if (cell->type.in(TW($logic_and), TW($logic_or), TW($logic_not)))
{ {
string btor_op; string btor_op;
if (cell->type == ID($logic_and)) btor_op = "and"; if (cell->type == TW($logic_and)) btor_op = "and";
if (cell->type == ID($logic_or)) btor_op = "or"; if (cell->type == TW($logic_or)) btor_op = "or";
if (cell->type == ID($logic_not)) btor_op = "not"; if (cell->type == TW($logic_not)) btor_op = "not";
log_assert(!btor_op.empty()); log_assert(!btor_op.empty());
int sid = get_bv_sid(1); int sid = get_bv_sid(1);
@ -614,12 +614,12 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor))) if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_bool), TW($reduce_xor), TW($reduce_xnor)))
{ {
string btor_op; string btor_op;
if (cell->type == ID($reduce_and)) btor_op = "redand"; if (cell->type == TW($reduce_and)) btor_op = "redand";
if (cell->type.in(ID($reduce_or), ID($reduce_bool))) btor_op = "redor"; if (cell->type.in(TW($reduce_or), TW($reduce_bool))) btor_op = "redor";
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) btor_op = "redxor"; if (cell->type.in(TW($reduce_xor), TW($reduce_xnor))) btor_op = "redxor";
log_assert(!btor_op.empty()); log_assert(!btor_op.empty());
int sid = get_bv_sid(1); int sid = get_bv_sid(1);
@ -627,7 +627,7 @@ struct BtorWorker
int nid = next_nid++; int nid = next_nid++;
if (cell->type == ID($reduce_xnor)) { if (cell->type == TW($reduce_xnor)) {
int nid2 = next_nid++; int nid2 = next_nid++;
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell)); btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
btorf("%d not %d %d\n", nid2, sid, nid); btorf("%d not %d %d\n", nid2, sid, nid);
@ -650,7 +650,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_))) if (cell->type.in(TW($mux), TW($_MUX_), TW($_NMUX_)))
{ {
SigSpec sig_a = sigmap(cell->getPort(TW::A)); SigSpec sig_a = sigmap(cell->getPort(TW::A));
SigSpec sig_b = sigmap(cell->getPort(TW::B)); SigSpec sig_b = sigmap(cell->getPort(TW::B));
@ -664,7 +664,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig_y)); int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++; int nid = next_nid++;
if (cell->type == ID($_NMUX_)) { if (cell->type == TW($_NMUX_)) {
int tmp = nid; int tmp = nid;
nid = next_nid++; nid = next_nid++;
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a); btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
@ -677,7 +677,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type == ID($pmux)) if (cell->type == TW($pmux))
{ {
SigSpec sig_a = sigmap(cell->getPort(TW::A)); SigSpec sig_a = sigmap(cell->getPort(TW::A));
SigSpec sig_b = sigmap(cell->getPort(TW::B)); SigSpec sig_b = sigmap(cell->getPort(TW::B));
@ -703,21 +703,21 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($dff), ID($ff), ID($anyinit), ID($_DFF_P_), ID($_DFF_N), ID($_FF_))) if (cell->type.in(TW($dff), TW($ff), TW($anyinit), TW($_DFF_P_), TW($_DFF_N), TW($_FF_)))
{ {
SigSpec sig_d = sigmap(cell->getPort(TW::D)); SigSpec sig_d = sigmap(cell->getPort(TW::D));
SigSpec sig_q = sigmap(cell->getPort(TW::Q)); SigSpec sig_q = sigmap(cell->getPort(TW::Q));
if ((!info_filename.empty() || ywmap_json.active()) && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_))) if ((!info_filename.empty() || ywmap_json.active()) && cell->type.in(TW($dff), TW($_DFF_P_), TW($_DFF_N_)))
{ {
SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? TW::CLK : TW::C)); SigSpec sig_c = sigmap(cell->getPort(cell->type == TW($dff) ? TW::CLK : TW::C));
int nid = get_sig_nid(sig_c); int nid = get_sig_nid(sig_c);
bool negedge = false; bool negedge = false;
if (cell->type == ID($_DFF_N_)) if (cell->type == TW($_DFF_N_))
negedge = true; negedge = true;
if (cell->type == ID($dff) && !cell->getParam(ID::CLK_POLARITY).as_bool()) if (cell->type == TW($dff) && !cell->getParam(ID::CLK_POLARITY).as_bool())
negedge = true; negedge = true;
if (!info_filename.empty()) if (!info_filename.empty())
@ -756,7 +756,7 @@ struct BtorWorker
if (symbol.empty() || (!print_internal_names && symbol[0] == '$')) if (symbol.empty() || (!print_internal_names && symbol[0] == '$'))
btorf("%d state %d\n", nid, sid); btorf("%d state %d\n", nid, sid);
else else
btorf("%d state %d %s\n", nid, sid, symbol.unescape()); btorf("%d state %d %s\n", nid, sid, design->twines.unescaped_str(symbol));
if (cell->get_bool_attribute(ID(clk2fflogic))) if (cell->get_bool_attribute(ID(clk2fflogic)))
ywmap_state(cell->getPort(TW::D)); // For a clk2fflogic FF the named signal is the D input not the Q output ywmap_state(cell->getPort(TW::D)); // For a clk2fflogic FF the named signal is the D input not the Q output
@ -775,7 +775,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($anyconst), ID($anyseq))) if (cell->type.in(TW($anyconst), TW($anyseq)))
{ {
SigSpec sig_y = sigmap(cell->getPort(TW::Y)); SigSpec sig_y = sigmap(cell->getPort(TW::Y));
@ -786,7 +786,7 @@ struct BtorWorker
ywmap_state(sig_y); ywmap_state(sig_y);
if (cell->type == ID($anyconst)) { if (cell->type == TW($anyconst)) {
int nid2 = next_nid++; int nid2 = next_nid++;
btorf("%d next %d %d %d\n", nid2, sid, nid, nid); btorf("%d next %d %d %d\n", nid2, sid, nid, nid);
} }
@ -795,7 +795,7 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type == ID($initstate)) if (cell->type == TW($initstate))
{ {
SigSpec sig_y = sigmap(cell->getPort(TW::Y)); SigSpec sig_y = sigmap(cell->getPort(TW::Y));
@ -834,12 +834,12 @@ struct BtorWorker
if (asyncwr && syncwr) if (asyncwr && syncwr)
log_error("Memory %s.%s has mixed async/sync write ports.\n", log_error("Memory %s.%s has mixed async/sync write ports.\n",
module, mem->memid.unescape()); module, design->twines.unescaped_str(mem->memid));
for (auto &port : mem->rd_ports) { for (auto &port : mem->rd_ports) {
if (port.clk_enable) if (port.clk_enable)
log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n", log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n",
module, mem->memid.unescape()); module, design->twines.unescaped_str(mem->memid));
} }
int data_sid = get_bv_sid(mem->width); int data_sid = get_bv_sid(mem->width);
@ -901,7 +901,7 @@ struct BtorWorker
if (mem->memid[0] == '$') if (mem->memid[0] == '$')
btorf("%d state %d\n", nid, sid); btorf("%d state %d\n", nid, sid);
else else
btorf("%d state %d %s\n", nid, sid, mem->memid.unescape()); btorf("%d state %d %s\n", nid, sid, design->twines.unescaped_str(mem->memid));
ywmap_state(cell); ywmap_state(cell);
@ -976,15 +976,15 @@ struct BtorWorker
goto okay; goto okay;
} }
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { if (cell->type.in(TW($dffe), TW($sdff), TW($sdffe), TW($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { if (cell->type.in(TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($dffsr), TW($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { if (cell->type.in(TW($sr), TW($dlatch), TW($adlatch), TW($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
@ -1296,7 +1296,7 @@ struct BtorWorker
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($assume)) if (cell->type == TW($assume))
{ {
btorf_push(cell->module->design->twines.str(cell->meta_->name)); btorf_push(cell->module->design->twines.str(cell->meta_->name));
@ -1316,7 +1316,7 @@ struct BtorWorker
btorf_pop(cell->module->design->twines.str(cell->meta_->name)); btorf_pop(cell->module->design->twines.str(cell->meta_->name));
} }
if (cell->type == ID($assert)) if (cell->type == TW($assert))
{ {
btorf_push(cell->module->design->twines.str(cell->meta_->name)); btorf_push(cell->module->design->twines.str(cell->meta_->name));
@ -1345,7 +1345,7 @@ struct BtorWorker
btorf_pop(cell->module->design->twines.str(cell->meta_->name)); btorf_pop(cell->module->design->twines.str(cell->meta_->name));
} }
if (cell->type == ID($cover) && cover_mode) if (cell->type == TW($cover) && cover_mode)
{ {
btorf_push(cell->module->design->twines.str(cell->meta_->name)); btorf_push(cell->module->design->twines.str(cell->meta_->name));
@ -1417,7 +1417,7 @@ struct BtorWorker
int nid = it.first; int nid = it.first;
Mem *mem = it.second; Mem *mem = it.second;
btorf_push(stringf("next %s", mem->memid.unescape())); btorf_push(stringf("next %s", design->twines.unescaped_str(mem->memid)));
int abits = ceil_log2(mem->size); int abits = ceil_log2(mem->size);
@ -1465,7 +1465,7 @@ struct BtorWorker
int nid2 = next_nid++; int nid2 = next_nid++;
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, getinfo(mem)); btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, getinfo(mem));
btorf_pop(stringf("next %s", mem->memid.unescape())); btorf_pop(stringf("next %s", design->twines.unescaped_str(mem->memid)));
} }
} }

View File

@ -177,39 +177,39 @@ struct Scheduler {
bool is_unary_cell(TwineRef type) bool is_unary_cell(TwineRef type)
{ {
return type.in( return type.in(
ID($not), ID($logic_not), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), TW($not), TW($logic_not), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool),
ID($pos), ID($neg)); TW($pos), TW($neg));
} }
bool is_binary_cell(TwineRef type) bool is_binary_cell(TwineRef type)
{ {
return type.in( return type.in(
ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or), TW($and), TW($or), TW($xor), TW($xnor), TW($logic_and), TW($logic_or),
ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), TW($shl), TW($sshl), TW($shr), TW($sshr), TW($shift), TW($shiftx),
ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($gt), TW($ge), TW($lt), TW($le),
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor), ID($divfloor)); TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($modfloor), TW($divfloor));
} }
bool is_extending_cell(TwineRef type) bool is_extending_cell(TwineRef type)
{ {
return !type.in( return !type.in(
ID($logic_not), ID($logic_and), ID($logic_or), TW($logic_not), TW($logic_and), TW($logic_or),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)); TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool));
} }
bool is_inlinable_cell(TwineRef type) bool is_inlinable_cell(TwineRef type)
{ {
return is_unary_cell(type) || is_binary_cell(type) || type.in( return is_unary_cell(type) || is_binary_cell(type) || type.in(
ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux), ID($bwmux)); TW($mux), TW($concat), TW($slice), TW($pmux), TW($bmux), TW($demux), TW($bwmux));
} }
bool is_ff_cell(TwineRef type) bool is_ff_cell(TwineRef type)
{ {
return type.in( return type.in(
ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce), TW($dff), TW($dffe), TW($sdff), TW($sdffe), TW($sdffce),
ID($adff), ID($adffe), ID($dffsr), ID($dffsre), TW($adff), TW($adffe), TW($dffsr), TW($dffsre),
ID($aldff), ID($aldffe), TW($aldff), TW($aldffe),
ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr)); TW($dlatch), TW($adlatch), TW($dlatchsr), TW($sr));
} }
bool is_internal_cell(TwineRef type) bool is_internal_cell(TwineRef type)
@ -219,7 +219,7 @@ bool is_internal_cell(TwineRef type)
bool is_effectful_cell(TwineRef type) bool is_effectful_cell(TwineRef type)
{ {
return type.in(ID($print), ID($check)); return type.in(TW($print), TW($check));
} }
bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell)
@ -1169,7 +1169,7 @@ struct CxxrtlWorker {
dump_sigspec_rhs(cell->getPort(TW::B), for_debug); dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
f << ")"; f << ")";
// Muxes // Muxes
} else if (cell->type == ID($mux)) { } else if (cell->type == TW($mux)) {
f << "("; f << "(";
dump_sigspec_rhs(cell->getPort(TW::S), for_debug); dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
f << " ? "; f << " ? ";
@ -1178,7 +1178,7 @@ struct CxxrtlWorker {
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ")"; f << ")";
// Parallel (one-hot) muxes // Parallel (one-hot) muxes
} else if (cell->type == ID($pmux)) { } else if (cell->type == TW($pmux)) {
int width = cell->getParam(ID::WIDTH).as_int(); int width = cell->getParam(ID::WIDTH).as_int();
int s_width = cell->getParam(ID::S_WIDTH).as_int(); int s_width = cell->getParam(ID::S_WIDTH).as_int();
for (int part = 0; part < s_width; part++) { for (int part = 0; part < s_width; part++) {
@ -1193,7 +1193,7 @@ struct CxxrtlWorker {
f << ")"; f << ")";
} }
// Big muxes // Big muxes
} else if (cell->type == ID($bmux)) { } else if (cell->type == TW($bmux)) {
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ".bmux<"; f << ".bmux<";
f << cell->getParam(ID::WIDTH).as_int(); f << cell->getParam(ID::WIDTH).as_int();
@ -1201,7 +1201,7 @@ struct CxxrtlWorker {
dump_sigspec_rhs(cell->getPort(TW::S), for_debug); dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
f << ").val()"; f << ").val()";
// Bitwise muxes // Bitwise muxes
} else if (cell->type == ID($bwmux)) { } else if (cell->type == TW($bwmux)) {
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ".bwmux("; f << ".bwmux(";
dump_sigspec_rhs(cell->getPort(TW::B), for_debug); dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
@ -1209,7 +1209,7 @@ struct CxxrtlWorker {
dump_sigspec_rhs(cell->getPort(TW::S), for_debug); dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
f << ").val()"; f << ").val()";
// Demuxes // Demuxes
} else if (cell->type == ID($demux)) { } else if (cell->type == TW($demux)) {
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ".demux<"; f << ".demux<";
f << GetSize(cell->getPort(TW::Y)); f << GetSize(cell->getPort(TW::Y));
@ -1217,13 +1217,13 @@ struct CxxrtlWorker {
dump_sigspec_rhs(cell->getPort(TW::S), for_debug); dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
f << ").val()"; f << ").val()";
// Concats // Concats
} else if (cell->type == ID($concat)) { } else if (cell->type == TW($concat)) {
dump_sigspec_rhs(cell->getPort(TW::B), for_debug); dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
f << ".concat("; f << ".concat(";
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ").val()"; f << ").val()";
// Slices // Slices
} else if (cell->type == ID($slice)) { } else if (cell->type == TW($slice)) {
dump_sigspec_rhs(cell->getPort(TW::A), for_debug); dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
f << ".slice<"; f << ".slice<";
f << cell->getParam(ID::OFFSET).as_int() + cell->getParam(ID::Y_WIDTH).as_int() - 1; f << cell->getParam(ID::OFFSET).as_int() + cell->getParam(ID::Y_WIDTH).as_int() - 1;
@ -1333,9 +1333,9 @@ struct CxxrtlWorker {
f << indent << "static const metadata_map attributes = "; f << indent << "static const metadata_map attributes = ";
dump_metadata_map(cell->attributes); dump_metadata_map(cell->attributes);
f << ";\n"; f << ";\n";
if (cell->type == ID($print)) { if (cell->type == TW($print)) {
f << indent << "performer->on_print(formatter, attributes);\n"; f << indent << "performer->on_print(formatter, attributes);\n";
} else if (cell->type == ID($check)) { } else if (cell->type == TW($check)) {
std::string flavor = cell->getParam(ID::FLAVOR).decode_string(); std::string flavor = cell->getParam(ID::FLAVOR).decode_string();
f << indent << "performer->on_check("; f << indent << "performer->on_check(";
if (flavor == "assert") if (flavor == "assert")
@ -1354,9 +1354,9 @@ struct CxxrtlWorker {
dec_indent(); dec_indent();
f << indent << "} else {\n"; f << indent << "} else {\n";
inc_indent(); inc_indent();
if (cell->type == ID($print)) { if (cell->type == TW($print)) {
f << indent << print_output << " << formatter();\n"; f << indent << print_output << " << formatter();\n";
} else if (cell->type == ID($check)) { } else if (cell->type == TW($check)) {
std::string flavor = cell->getParam(ID::FLAVOR).decode_string(); std::string flavor = cell->getParam(ID::FLAVOR).decode_string();
if (flavor == "assert" || flavor == "assume") { if (flavor == "assert" || flavor == "assume") {
f << indent << "if (!condition) {\n"; f << indent << "if (!condition) {\n";
@ -1397,9 +1397,9 @@ struct CxxrtlWorker {
f << indent << "auto " << mangle(cell) << "_next = "; f << indent << "auto " << mangle(cell) << "_next = ";
dump_sigspec_rhs(cell->getPort(TW::EN)); dump_sigspec_rhs(cell->getPort(TW::EN));
f << ".concat("; f << ".concat(";
if (cell->type == ID($print)) if (cell->type == TW($print))
dump_sigspec_rhs(cell->getPort(TW::ARGS)); dump_sigspec_rhs(cell->getPort(TW::ARGS));
else if (cell->type == ID($check)) else if (cell->type == TW($check))
dump_sigspec_rhs(cell->getPort(TW::A)); dump_sigspec_rhs(cell->getPort(TW::A));
else log_assert(false); else log_assert(false);
f << ").val();\n"; f << ").val();\n";
@ -1444,7 +1444,7 @@ struct CxxrtlWorker {
f << " = "; f << " = ";
dump_sigspec_rhs(cell->getPort(TW::D)); dump_sigspec_rhs(cell->getPort(TW::D));
f << ";\n"; f << ";\n";
if (cell->hasPort(TW::EN) && cell->type != ID($sdffce)) { if (cell->hasPort(TW::EN) && cell->type != TW($sdffce)) {
dec_indent(); dec_indent();
f << indent << "}\n"; f << indent << "}\n";
} }
@ -1461,7 +1461,7 @@ struct CxxrtlWorker {
dec_indent(); dec_indent();
f << indent << "}\n"; f << indent << "}\n";
} }
if (cell->hasPort(TW::EN) && cell->type == ID($sdffce)) { if (cell->hasPort(TW::EN) && cell->type == TW($sdffce)) {
dec_indent(); dec_indent();
f << indent << "}\n"; f << indent << "}\n";
} }
@ -1534,7 +1534,7 @@ struct CxxrtlWorker {
f << (cell->getParam(ID::CLR_POLARITY).as_bool() ? "" : ".bit_not()") << ");\n"; f << (cell->getParam(ID::CLR_POLARITY).as_bool() ? "" : ".bit_not()") << ");\n";
} }
// Internal cells // Internal cells
} else if (cell->type.in(ID($input_port), ID($output_port), ID($public))) { } else if (cell->type.in(TW($input_port), TW($output_port), TW($public))) {
} else if (is_internal_cell(cell->type)) { } else if (is_internal_cell(cell->type)) {
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type); log_cmd_error("Unsupported internal cell `%s'.\n", cell->type);
// User cells // User cells
@ -2412,7 +2412,7 @@ struct CxxrtlWorker {
count_scopes++; count_scopes++;
// If there were any submodules that were flattened, the module is also responsible for adding them. // If there were any submodules that were flattened, the module is also responsible for adding them.
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type != ID($scopeinfo)) continue; if (cell->type != TW($scopeinfo)) continue;
if (cell->getParam(ID::TYPE).decode_string() == "module") { if (cell->getParam(ID::TYPE).decode_string() == "module") {
auto module_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Module); auto module_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Module);
auto cell_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Cell); auto cell_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Cell);
@ -2697,9 +2697,9 @@ struct CxxrtlWorker {
if (is_effectful_cell(cell->type)) { if (is_effectful_cell(cell->type)) {
if (cell->getParam(ID::TRG_ENABLE).as_bool() && cell->getParam(ID::TRG_WIDTH).as_int() == 0) if (cell->getParam(ID::TRG_ENABLE).as_bool() && cell->getParam(ID::TRG_WIDTH).as_int() == 0)
f << indent << "value<1> " << mangle(cell) << ";\n"; // async initial cell f << indent << "value<1> " << mangle(cell) << ";\n"; // async initial cell
if (!cell->getParam(ID::TRG_ENABLE).as_bool() && cell->type == ID($print)) if (!cell->getParam(ID::TRG_ENABLE).as_bool() && cell->type == TW($print))
f << indent << "value<" << (1 + cell->getParam(ID::ARGS_WIDTH).as_int()) << "> " << mangle(cell) << ";\n"; // {EN, ARGS} f << indent << "value<" << (1 + cell->getParam(ID::ARGS_WIDTH).as_int()) << "> " << mangle(cell) << ";\n"; // {EN, ARGS}
if (!cell->getParam(ID::TRG_ENABLE).as_bool() && cell->type == ID($check)) if (!cell->getParam(ID::TRG_ENABLE).as_bool() && cell->type == TW($check))
f << indent << "value<2> " << mangle(cell) << ";\n"; // {EN, A} f << indent << "value<2> " << mangle(cell) << ";\n"; // {EN, A}
} }
if (is_internal_cell(cell->type)) if (is_internal_cell(cell->type))
@ -3017,7 +3017,7 @@ struct CxxrtlWorker {
if (cell_module && if (cell_module &&
cell_module->get_blackbox_attribute() && cell_module->get_blackbox_attribute() &&
!cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) !cell_module->get_bool_attribute(ID(cxxrtl_blackbox)))
log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", cell->type.unescape()); log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", cell->type.unescaped());
if (cell_module && if (cell_module &&
cell_module->get_bool_attribute(ID(cxxrtl_blackbox)) && cell_module->get_bool_attribute(ID(cxxrtl_blackbox)) &&
@ -3027,7 +3027,7 @@ struct CxxrtlWorker {
flow.add_node(cell); flow.add_node(cell);
// Various DFF cells are treated like posedge/negedge processes, see above for details. // Various DFF cells are treated like posedge/negedge processes, see above for details.
if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { if (cell->type.in(TW($dff), TW($dffe), TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($dffsr), TW($dffsre), TW($sdff), TW($sdffe), TW($sdffce))) {
if (is_valid_clock(cell->getPort(TW::CLK))) if (is_valid_clock(cell->getPort(TW::CLK)))
register_edge_signal(sigmap, cell->getPort(TW::CLK), register_edge_signal(sigmap, cell->getPort(TW::CLK),
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);

View File

@ -30,9 +30,9 @@
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
#define EDIF_DEF(_id) edif_names(_id.unescape(), true) #define EDIF_DEF(_id) design->twines.unescaped_str(edif_names(_id), true)
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(_id.unescape(), true, _ren, _bl, _br) #define EDIF_DEFR(_id, _ren, _bl, _br) design->twines.unescaped_str(edif_names(_id), true, _ren, _bl, _br)
#define EDIF_REF(_id) edif_names(_id.unescape(), false) #define EDIF_REF(_id) design->twines.unescaped_str(edif_names(_id), false)
#define EDIF_DEF_STR(_id) edif_names(RTLIL::unescape_id(_id), true) #define EDIF_DEF_STR(_id) edif_names(RTLIL::unescape_id(_id), true)
#define EDIF_REF_STR(_id) edif_names(RTLIL::unescape_id(_id), false) #define EDIF_REF_STR(_id) edif_names(RTLIL::unescape_id(_id), false)
@ -216,7 +216,7 @@ struct EdifBackend : public Backend {
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
continue; continue;
if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) { if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) {
@ -321,7 +321,7 @@ struct EdifBackend : public Backend {
for (auto &dep : it.second) for (auto &dep : it.second)
if (module_deps.count(dep) > 0) if (module_deps.count(dep) > 0)
goto not_ready_yet; goto not_ready_yet;
// log("Next in topological sort: %s\n", it.first->name.unescape()); // log("Next in topological sort: %s\n", design->twines.unescaped_str(it.first->name));
sorted_modules.push_back(it.first); sorted_modules.push_back(it.first);
not_ready_yet:; not_ready_yet:;
} }

View File

@ -82,7 +82,7 @@ const char *make_id(IdString id)
if (namecache.count(id) != 0) if (namecache.count(id) != 0)
return namecache.at(id).c_str(); return namecache.at(id).c_str();
string new_id = id.unescape(); string new_id = design->twines.unescaped_str(id);
for (int i = 0; i < GetSize(new_id); i++) for (int i = 0; i < GetSize(new_id); i++)
{ {
@ -599,7 +599,7 @@ struct FirrtlWorker
string y_id = make_id(cell->name); string y_id = make_id(cell->name);
std::string cellFileinfo = getFileinfo(cell); std::string cellFileinfo = getFileinfo(cell);
if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor))) if (cell->type.in(TW($not), TW($logic_not), TW($_NOT_), TW($neg), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_bool), TW($reduce_xnor)))
{ {
string a_expr = make_expr(cell->getPort(TW::A)); string a_expr = make_expr(cell->getPort(TW::A));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo)); wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo));
@ -609,29 +609,29 @@ struct FirrtlWorker
} }
// Don't use the results of logical operations (a single bit) to control padding // Don't use the results of logical operations (a single bit) to control padding
if (!(cell->type.in(ID($eq), ID($eqx), ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($reduce_bool), ID($logic_not)) && y_width == 1) ) { if (!(cell->type.in(TW($eq), TW($eqx), TW($gt), TW($ge), TW($lt), TW($le), TW($ne), TW($nex), TW($reduce_bool), TW($logic_not)) && y_width == 1) ) {
a_expr = stringf("pad(%s, %d)", a_expr, y_width); a_expr = stringf("pad(%s, %d)", a_expr, y_width);
} }
// Assume the FIRRTL width is a single bit. // Assume the FIRRTL width is a single bit.
firrtl_width = 1; firrtl_width = 1;
if (cell->type.in(ID($not), ID($_NOT_))) primop = "not"; if (cell->type.in(TW($not), TW($_NOT_))) primop = "not";
else if (cell->type == ID($neg)) { else if (cell->type == TW($neg)) {
primop = "neg"; primop = "neg";
firrtl_is_signed = true; // Result of "neg" is signed (an SInt). firrtl_is_signed = true; // Result of "neg" is signed (an SInt).
firrtl_width = a_width; firrtl_width = a_width;
} else if (cell->type == ID($logic_not)) { } else if (cell->type == TW($logic_not)) {
primop = "eq"; primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr); a_expr = stringf("%s, UInt(0)", a_expr);
} }
else if (cell->type == ID($reduce_and)) primop = "andr"; else if (cell->type == TW($reduce_and)) primop = "andr";
else if (cell->type == ID($reduce_or)) primop = "orr"; else if (cell->type == TW($reduce_or)) primop = "orr";
else if (cell->type == ID($reduce_xor)) primop = "xorr"; else if (cell->type == TW($reduce_xor)) primop = "xorr";
else if (cell->type == ID($reduce_xnor)) { else if (cell->type == TW($reduce_xnor)) {
primop = "not"; primop = "not";
a_expr = stringf("xorr(%s)", a_expr); a_expr = stringf("xorr(%s)", a_expr);
} }
else if (cell->type == ID($reduce_bool)) { else if (cell->type == TW($reduce_bool)) {
primop = "neq"; primop = "neq";
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand. // Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
a_expr = stringf("%s, %cInt<%d>(0)", a_expr, a_signed ? 'S' : 'U', a_width); a_expr = stringf("%s, %cInt<%d>(0)", a_expr, a_signed ? 'S' : 'U', a_width);
@ -647,9 +647,9 @@ struct FirrtlWorker
continue; continue;
} }
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($_XOR_), ID($xnor), ID($and), ID($_AND_), ID($or), ID($_OR_), ID($eq), ID($eqx), if (cell->type.in(TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($xor), TW($_XOR_), TW($xnor), TW($and), TW($_AND_), TW($or), TW($_OR_), TW($eq), TW($eqx),
ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($shr), ID($sshr), ID($sshl), ID($shl), TW($gt), TW($ge), TW($lt), TW($le), TW($ne), TW($nex), TW($shr), TW($sshr), TW($sshl), TW($shl),
ID($logic_and), ID($logic_or), ID($pow))) TW($logic_and), TW($logic_or), TW($pow)))
{ {
string a_expr = make_expr(cell->getPort(TW::A)); string a_expr = make_expr(cell->getPort(TW::A));
string b_expr = make_expr(cell->getPort(TW::B)); string b_expr = make_expr(cell->getPort(TW::B));
@ -666,7 +666,7 @@ struct FirrtlWorker
} }
// Shift amount is always unsigned, and needn't be padded to result width, // Shift amount is always unsigned, and needn't be padded to result width,
// otherwise, we need to cast the b_expr appropriately // otherwise, we need to cast the b_expr appropriately
if (b_signed && !cell->type.in(ID($shr), ID($sshr), ID($shl), ID($sshl), ID($pow))) { if (b_signed && !cell->type.in(TW($shr), TW($sshr), TW($shl), TW($sshl), TW($pow))) {
b_expr = "asSInt(" + b_expr + ")"; b_expr = "asSInt(" + b_expr + ")";
// Expand the "B" operand to the result width // Expand the "B" operand to the result width
if (b_width < y_width) { if (b_width < y_width) {
@ -677,7 +677,7 @@ struct FirrtlWorker
// For the arithmetic ops, expand operand widths to result widths befor performing the operation. // For the arithmetic ops, expand operand widths to result widths befor performing the operation.
// This corresponds (according to iverilog) to what verilog compilers implement. // This corresponds (according to iverilog) to what verilog compilers implement.
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($_XOR_), ID($xnor), ID($and), ID($_AND_), ID($or), ID($_OR_))) if (cell->type.in(TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($xor), TW($_XOR_), TW($xnor), TW($and), TW($_AND_), TW($or), TW($_OR_)))
{ {
if (a_width < y_width) { if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr, y_width); a_expr = stringf("pad(%s, %d)", a_expr, y_width);
@ -692,79 +692,79 @@ struct FirrtlWorker
firrtl_width = a_width; firrtl_width = a_width;
auto a_sig = cell->getPort(TW::A); auto a_sig = cell->getPort(TW::A);
if (cell->type == ID($add)) { if (cell->type == TW($add)) {
primop = "add"; primop = "add";
firrtl_is_signed = a_signed | b_signed; firrtl_is_signed = a_signed | b_signed;
firrtl_width = max(a_width, b_width); firrtl_width = max(a_width, b_width);
} else if (cell->type == ID($sub)) { } else if (cell->type == TW($sub)) {
primop = "sub"; primop = "sub";
firrtl_is_signed = true; firrtl_is_signed = true;
int a_widthInc = (!a_signed && b_signed) ? 2 : (a_signed && !b_signed) ? 1 : 0; int a_widthInc = (!a_signed && b_signed) ? 2 : (a_signed && !b_signed) ? 1 : 0;
int b_widthInc = (a_signed && !b_signed) ? 2 : (!a_signed && b_signed) ? 1 : 0; int b_widthInc = (a_signed && !b_signed) ? 2 : (!a_signed && b_signed) ? 1 : 0;
firrtl_width = max(a_width + a_widthInc, b_width + b_widthInc); firrtl_width = max(a_width + a_widthInc, b_width + b_widthInc);
} else if (cell->type == ID($mul)) { } else if (cell->type == TW($mul)) {
primop = "mul"; primop = "mul";
firrtl_is_signed = a_signed | b_signed; firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width + b_width; firrtl_width = a_width + b_width;
} else if (cell->type == ID($div)) { } else if (cell->type == TW($div)) {
primop = "div"; primop = "div";
firrtl_is_signed = a_signed | b_signed; firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width; firrtl_width = a_width;
} else if (cell->type == ID($mod)) { } else if (cell->type == TW($mod)) {
// "rem" = truncating modulo // "rem" = truncating modulo
primop = "rem"; primop = "rem";
firrtl_width = min(a_width, b_width); firrtl_width = min(a_width, b_width);
} else if (cell->type.in(ID($and), ID($_AND_))) { } else if (cell->type.in(TW($and), TW($_AND_))) {
primop = "and"; primop = "and";
always_uint = true; always_uint = true;
firrtl_width = max(a_width, b_width); firrtl_width = max(a_width, b_width);
} }
else if (cell->type.in(ID($or), ID($_OR_))) { else if (cell->type.in(TW($or), TW($_OR_))) {
primop = "or"; primop = "or";
always_uint = true; always_uint = true;
firrtl_width = max(a_width, b_width); firrtl_width = max(a_width, b_width);
} }
else if (cell->type.in(ID($xor), ID($_XOR_))) { else if (cell->type.in(TW($xor), TW($_XOR_))) {
primop = "xor"; primop = "xor";
always_uint = true; always_uint = true;
firrtl_width = max(a_width, b_width); firrtl_width = max(a_width, b_width);
} }
else if (cell->type == ID($xnor)) { else if (cell->type == TW($xnor)) {
primop = "xnor"; primop = "xnor";
always_uint = true; always_uint = true;
firrtl_width = max(a_width, b_width); firrtl_width = max(a_width, b_width);
} }
else if ((cell->type == ID($eq)) || (cell->type == ID($eqx))) { else if ((cell->type == TW($eq)) || (cell->type == TW($eqx))) {
primop = "eq"; primop = "eq";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if ((cell->type == ID($ne)) || (cell->type == ID($nex))) { else if ((cell->type == TW($ne)) || (cell->type == TW($nex))) {
primop = "neq"; primop = "neq";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if (cell->type == ID($gt)) { else if (cell->type == TW($gt)) {
primop = "gt"; primop = "gt";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if (cell->type == ID($ge)) { else if (cell->type == TW($ge)) {
primop = "geq"; primop = "geq";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if (cell->type == ID($lt)) { else if (cell->type == TW($lt)) {
primop = "lt"; primop = "lt";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if (cell->type == ID($le)) { else if (cell->type == TW($le)) {
primop = "leq"; primop = "leq";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if ((cell->type == ID($shl)) || (cell->type == ID($sshl))) { else if ((cell->type == TW($shl)) || (cell->type == TW($sshl))) {
// FIRRTL will widen the result (y) by the amount of the shift. // FIRRTL will widen the result (y) by the amount of the shift.
// We'll need to offset this by extracting the un-widened portion as Verilog would do. // We'll need to offset this by extracting the un-widened portion as Verilog would do.
extract_y_bits = true; extract_y_bits = true;
@ -782,7 +782,7 @@ struct FirrtlWorker
firrtl_width = a_width + (1 << b_width) - 1; firrtl_width = a_width + (1 << b_width) - 1;
} }
} }
else if ((cell->type == ID($shr)) || (cell->type == ID($sshr))) { else if ((cell->type == TW($shr)) || (cell->type == TW($sshr))) {
// We don't need to extract a specific range of bits. // We don't need to extract a specific range of bits.
extract_y_bits = false; extract_y_bits = false;
// Is the shift amount constant? // Is the shift amount constant?
@ -799,26 +799,26 @@ struct FirrtlWorker
// We'll need to do some special fixups if the source (and thus result) is signed. // We'll need to do some special fixups if the source (and thus result) is signed.
if (firrtl_is_signed) { if (firrtl_is_signed) {
// If this is a "logical" shift right, pretend the source is unsigned. // If this is a "logical" shift right, pretend the source is unsigned.
if (cell->type == ID($shr)) { if (cell->type == TW($shr)) {
a_expr = "asUInt(" + a_expr + ")"; a_expr = "asUInt(" + a_expr + ")";
} }
} }
} }
else if ((cell->type == ID($logic_and))) { else if ((cell->type == TW($logic_and))) {
primop = "and"; primop = "and";
a_expr = "neq(" + a_expr + ", UInt(0))"; a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))"; b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if ((cell->type == ID($logic_or))) { else if ((cell->type == TW($logic_or))) {
primop = "or"; primop = "or";
a_expr = "neq(" + a_expr + ", UInt(0))"; a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))"; b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true; always_uint = true;
firrtl_width = 1; firrtl_width = 1;
} }
else if ((cell->type == ID($pow))) { else if ((cell->type == TW($pow))) {
if (a_sig.is_fully_const() && a_sig.as_int() == 2) { if (a_sig.is_fully_const() && a_sig.as_int() == 2) {
// We'll convert this to a shift. To simplify things, change the a_expr to "1" // We'll convert this to a shift. To simplify things, change the a_expr to "1"
// so we can use b_expr directly as a shift amount. // so we can use b_expr directly as a shift amount.
@ -878,7 +878,7 @@ struct FirrtlWorker
continue; continue;
} }
if (cell->type.in(ID($mux), ID($_MUX_))) if (cell->type.in(TW($mux), TW($_MUX_)))
{ {
auto it = cell->parameters.find(ID::WIDTH); auto it = cell->parameters.find(ID::WIDTH);
int width = it == cell->parameters.end()? 1 : it->second.as_int(); int width = it == cell->parameters.end()? 1 : it->second.as_int();
@ -901,7 +901,7 @@ struct FirrtlWorker
continue; continue;
} }
if (cell->type.in(ID($dff))) if (cell->type.in(TW($dff)))
{ {
bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool(); bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool();
if (clkpol == false) if (clkpol == false)
@ -919,7 +919,7 @@ struct FirrtlWorker
continue; continue;
} }
if (cell->type == ID($shiftx)) { if (cell->type == TW($shiftx)) {
// assign y = a[b +: y_width]; // assign y = a[b +: y_width];
// We'll extract the correct bits as part of the primop. // We'll extract the correct bits as part of the primop.
@ -940,7 +940,7 @@ struct FirrtlWorker
register_reverse_wire_map(y_id, cell->getPort(TW::Y)); register_reverse_wire_map(y_id, cell->getPort(TW::Y));
continue; continue;
} }
if (cell->type == ID($shift)) { if (cell->type == TW($shift)) {
// assign y = a >> b; // assign y = a >> b;
// where b may be negative // where b may be negative
@ -966,7 +966,7 @@ struct FirrtlWorker
register_reverse_wire_map(y_id, cell->getPort(TW::Y)); register_reverse_wire_map(y_id, cell->getPort(TW::Y));
continue; continue;
} }
if (cell->type == ID($pos)) { if (cell->type == TW($pos)) {
// assign y = a; // assign y = a;
// printCell(cell); // printCell(cell);
string a_expr = make_expr(cell->getPort(TW::A)); string a_expr = make_expr(cell->getPort(TW::A));
@ -981,9 +981,9 @@ struct FirrtlWorker
continue; continue;
} }
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
continue; continue;
log_error("Cell type not supported: %s (%s.%s)\n", cell->type.unescape(), module, cell); log_error("Cell type not supported: %s (%s.%s)\n", cell->type.unescaped(), module, cell);
} }
for (auto &mem : memories) { for (auto &mem : memories) {
@ -991,10 +991,10 @@ struct FirrtlWorker
Const init_data = mem.get_init_data(); Const init_data = mem.get_init_data();
if (!init_data.is_fully_undef()) if (!init_data.is_fully_undef())
log_error("Memory with initialization data: %s.%s\n", module, mem.memid.unescape()); log_error("Memory with initialization data: %s.%s\n", module, design->twines.unescaped_str(mem.memid));
if (mem.start_offset != 0) if (mem.start_offset != 0)
log_error("Memory with nonzero offset: %s.%s\n", module, mem.memid.unescape()); log_error("Memory with nonzero offset: %s.%s\n", module, design->twines.unescaped_str(mem.memid));
for (int i = 0; i < GetSize(mem.rd_ports); i++) for (int i = 0; i < GetSize(mem.rd_ports); i++)
{ {
@ -1002,7 +1002,7 @@ struct FirrtlWorker
string port_name(stringf("%s.r%d", mem_id, i)); string port_name(stringf("%s.r%d", mem_id, i));
if (port.clk_enable) if (port.clk_enable)
log_error("Clocked read port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); log_error("Clocked read port %d on memory %s.%s.\n", i, module, design->twines.unescaped_str(mem.memid));
std::ostringstream rpe; std::ostringstream rpe;
@ -1023,12 +1023,12 @@ struct FirrtlWorker
string port_name(stringf("%s.w%d", mem_id, i)); string port_name(stringf("%s.w%d", mem_id, i));
if (!port.clk_enable) if (!port.clk_enable)
log_error("Unclocked write port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); log_error("Unclocked write port %d on memory %s.%s.\n", i, module, design->twines.unescaped_str(mem.memid));
if (!port.clk_polarity) if (!port.clk_polarity)
log_error("Negedge write port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); log_error("Negedge write port %d on memory %s.%s.\n", i, module, design->twines.unescaped_str(mem.memid));
for (int i = 1; i < GetSize(port.en); i++) for (int i = 1; i < GetSize(port.en); i++)
if (port.en[0] != port.en[i]) if (port.en[0] != port.en[i])
log_error("Complex write enable on port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); log_error("Complex write enable on port %d on memory %s.%s.\n", i, module, design->twines.unescaped_str(mem.memid));
std::ostringstream wpe; std::ostringstream wpe;

View File

@ -89,7 +89,7 @@ struct CxxStruct {
} }
f.print("\n\t\ttemplate <typename T> void visit(T &&fn) {{\n"); f.print("\n\t\ttemplate <typename T> void visit(T &&fn) {{\n");
for (auto p : types) { for (auto p : types) {
f.print("\t\t\tfn(\"{}\", {});\n", p.first.unescape(), scope(p.first, p.first)); f.print("\t\t\tfn(\"{}\", {});\n", design->twines.unescaped_str(p.first), scope(p.first, p.first));
} }
f.print("\t\t}}\n"); f.print("\t\t}}\n");
f.print("\t}};\n\n"); f.print("\t}};\n\n");
@ -151,8 +151,8 @@ template<class NodePrinter> struct CxxPrintVisitor : public Functional::Abstract
void arithmetic_shift_right(Node, Node a, Node b) override { print("{}.arithmetic_shift_right({})", a, b); } void arithmetic_shift_right(Node, Node a, Node b) override { print("{}.arithmetic_shift_right({})", a, b); }
void mux(Node, Node a, Node b, Node s) override { print("{2}.any() ? {1} : {0}", a, b, s); } void mux(Node, Node a, Node b, Node s) override { print("{2}.any() ? {1} : {0}", a, b, s); }
void constant(Node, RTLIL::Const const & value) override { print("{}", cxx_const(value)); } void constant(Node, RTLIL::Const const & value) override { print("{}", cxx_const(value)); }
void input(Node, IdString name, IdString kind) override { log_assert(kind == ID($input)); print("input.{}", input_struct[name]); } void input(Node, IdString name, IdString kind) override { log_assert(kind == TW($input)); print("input.{}", input_struct[name]); }
void state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); print("current_state.{}", state_struct[name]); } void state(Node, IdString name, IdString kind) override { log_assert(kind == TW($state)); print("current_state.{}", state_struct[name]); }
void memory_read(Node, Node mem, Node addr) override { print("{}.read({})", mem, addr); } void memory_read(Node, Node mem, Node addr) override { print("{}.read({})", mem, addr); }
void memory_write(Node, Node mem, Node addr, Node data) override { print("{}.write({}, {})", mem, addr, data); } void memory_write(Node, Node mem, Node addr, Node data) override { print("{}.write({}, {})", mem, addr, data); }
}; };

View File

@ -80,7 +80,7 @@ public:
SmtStruct(std::string name, SmtScope &scope) : scope(scope), name(name) {} SmtStruct(std::string name, SmtScope &scope) : scope(scope), name(name) {}
void insert(IdString field_name, SmtSort sort) { void insert(IdString field_name, SmtSort sort) {
field_names(field_name); field_names(field_name);
auto accessor = scope.unique_name("\\" + name + "_" + field_name.unescape()); auto accessor = scope.unique_name("\\" + name + "_" + design->twines.unescaped_str(field_name));
fields.emplace_back(Field{sort, accessor}); fields.emplace_back(Field{sort, accessor});
} }
void write_definition(SExprWriter &w) { void write_definition(SExprWriter &w) {
@ -179,8 +179,8 @@ struct SmtPrintVisitor : public Functional::AbstractVisitor<SExpr> {
SExpr memory_read(Node, Node mem, Node addr) override { return list("select", n(mem), n(addr)); } SExpr memory_read(Node, Node mem, Node addr) override { return list("select", n(mem), n(addr)); }
SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("store", n(mem), n(addr), n(data)); } SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("store", n(mem), n(addr), n(data)); }
SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == ID($input)); return input_struct.access("inputs", name); } SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == TW($input)); return input_struct.access("inputs", name); }
SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", name); } SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == TW($state)); return state_struct.access("state", name); }
}; };
struct SmtModule { struct SmtModule {

View File

@ -180,8 +180,8 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
SExpr memory_read(Node, Node mem, Node addr) override { return list("list-ref-bv", n(mem), n(addr)); } SExpr memory_read(Node, Node mem, Node addr) override { return list("list-ref-bv", n(mem), n(addr)); }
SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("list-set-bv", n(mem), n(addr), n(data)); } SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("list-set-bv", n(mem), n(addr), n(data)); }
SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == ID($input)); return input_struct.access("inputs", name); } SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == TW($input)); return input_struct.access("inputs", name); }
SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", name); } SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == TW($state)); return state_struct.access("state", name); }
}; };
struct SmtrModule { struct SmtrModule {
@ -281,7 +281,7 @@ struct SmtrModule {
w.push(); w.push();
w.open(list()); w.open(list());
w.open(list("assoc-result")); w.open(list("assoc-result"));
w << list("assoc", "\"" + input->name.unescape() + "\"", inputs_name); w << list("assoc", "\"" + design->twines.unescaped_str(input->name) + "\"", inputs_name);
w.pop(); w.pop();
w.open(list("if", "assoc-result")); w.open(list("if", "assoc-result"));
w << list("cdr", "assoc-result"); w << list("cdr", "assoc-result");
@ -298,7 +298,7 @@ struct SmtrModule {
w << list(*output_helper_name, outputs_name); w << list(*output_helper_name, outputs_name);
w.open(list("list")); w.open(list("list"));
for (auto output : ir.outputs()) { for (auto output : ir.outputs()) {
w << list("cons", "\"" + output->name.unescape() + "\"", output_struct.access("outputs", output->name)); w << list("cons", "\"" + design->twines.unescaped_str(output->name) + "\"", output_struct.access("outputs", output->name));
} }
w.pop(); w.pop();
} }

View File

@ -146,11 +146,11 @@ struct FunctionalTestGeneric : public Pass
log("Dumping module `%s'.\n", module->name); log("Dumping module `%s'.\n", module->name);
auto fir = Functional::IR::from_module(module); auto fir = Functional::IR::from_module(module);
for(auto node : fir) for(auto node : fir)
std::cout << node.name().unescape() << " = " << node.to_string([](auto n) { return n.name().unescape(); }) << "\n"; std::cout << design->twines.unescaped_str(node.name()) << " = " << node.to_string([](auto n) { return design->twines.unescaped_str(n.name()); }) << "\n";
for(auto output : fir.all_outputs()) for(auto output : fir.all_outputs())
std::cout << output->kind.unescape() << " " << output->name.unescape() << " = " << output->value().name().unescape() << "\n"; std::cout << design->twines.unescaped_str(output->kind) << " " << design->twines.unescaped_str(output->name) << " = " << design->twines.unescaped_str(output->value().name()) << "\n";
for(auto state : fir.all_states()) for(auto state : fir.all_states())
std::cout << state->kind.unescape() << " " << state->name.unescape() << " = " << state->next_value().name().unescape() << "\n"; std::cout << design->twines.unescaped_str(state->kind) << " " << design->twines.unescaped_str(state->name) << " = " << design->twines.unescaped_str(state->next_value().name()) << "\n";
} }
} }
} FunctionalCxxBackend; } FunctionalCxxBackend;

View File

@ -41,7 +41,7 @@ static std::string netname(std::set<std::string> &conntypes_code, std::set<std::
return stringf("CONST_%d_0x%x", sig.size(), sig.as_int()); return stringf("CONST_%d_0x%x", sig.size(), sig.as_int());
} }
return sig.as_wire()->name.unescape(); return design->twines.unescaped_str(sig.as_wire()->name);
} }
struct IntersynthBackend : public Backend { struct IntersynthBackend : public Backend {
@ -151,8 +151,8 @@ struct IntersynthBackend : public Backend {
if (wire->port_input || wire->port_output) { if (wire->port_input || wire->port_output) {
celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n", celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
wire->name.unescape(), wire->width, wire->port_input ? "*" : "", wire->name.unescape(), wire->width, wire->port_input ? "*" : "",
wire->port_input ? "input" : "output", wire->name.unescape(), wire->width, wire->name.unescape())); wire->port_input ? "input" : "output", design->twines.unescaped_str(wire->name), wire->width, design->twines.unescaped_str(wire->name)));
netlists_code += stringf("node %s %s PORT %s\n", wire->name.unescape(), wire->name.unescape(), netlists_code += stringf("node %s %s PORT %s\n", design->twines.unescaped_str(wire->name), design->twines.unescaped_str(wire->name),
netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str()); netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str());
} }
} }
@ -162,28 +162,28 @@ struct IntersynthBackend : public Backend {
{ {
std::string celltype_code, node_code; std::string celltype_code, node_code;
if (!ct.cell_known(cell->type)) if (!ct.cell_known(cell->type_impl))
log_error("Found unknown cell type %s in module!\n", cell->type.unescape()); log_error("Found unknown cell type %s in module!\n", cell->type.unescaped());
celltype_code = stringf("celltype %s", cell->type.unescape()); celltype_code = stringf("celltype %s", cell->type.unescaped());
node_code = stringf("node %s %s", cell->module->design->twines.str(cell->meta_->name), cell->type.unescape()); node_code = stringf("node %s %s", cell->module->design->twines.str(cell->meta_->name), cell->type.unescaped());
for (auto &port : cell->connections()) { for (auto &port : cell->connections()) {
RTLIL::SigSpec sig = sigmap(port.second); RTLIL::SigSpec sig = sigmap(port.second);
if (sig.size() != 0) { if (sig.size() != 0) {
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
std::string port_name = design->twines.str(port.first); std::string port_name = design->twines.str(port.first);
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", port_name.c_str()); celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type_impl, port.first) ? "*" : "", port_name.c_str());
node_code += stringf(" %s %s", port_name.c_str(), netname(conntypes_code, celltypes_code, constcells_code, sig)); node_code += stringf(" %s %s", port_name.c_str(), netname(conntypes_code, celltypes_code, constcells_code, sig));
} }
} }
for (auto &param : cell->parameters) { for (auto &param : cell->parameters) {
celltype_code += stringf(" cfg:%d %s", int(param.second.size()), param.first.unescape()); celltype_code += stringf(" cfg:%d %s", int(param.second.size()), design->twines.unescaped_str(param.first));
if (param.second.size() != 32) { if (param.second.size() != 32) {
node_code += stringf(" %s '", param.first.unescape()); node_code += stringf(" %s '", design->twines.unescaped_str(param.first));
for (int i = param.second.size()-1; i >= 0; i--) for (int i = param.second.size()-1; i >= 0; i--)
node_code += param.second[i] == State::S1 ? "1" : "0"; node_code += param.second[i] == State::S1 ? "1" : "0";
} else } else
node_code += stringf(" %s 0x%x", param.first.unescape(), param.second.as_int()); node_code += stringf(" %s 0x%x", design->twines.unescaped_str(param.first), param.second.as_int());
} }
celltypes_code.insert(celltype_code + "\n"); celltypes_code.insert(celltype_code + "\n");

View File

@ -91,7 +91,7 @@ struct JnyWriter
{ {
_cells.clear(); _cells.clear();
for (auto cell : mod->cells()) { for (auto cell : mod->cells()) {
const auto cell_type = escape_string(cell->type.unescape()); const auto cell_type = design->twines.unescaped_str(escape_string(cell->type));
if (_cells.find(cell_type) == _cells.end()) if (_cells.find(cell_type) == _cells.end())
_cells.emplace(cell_type, std::vector<Cell*>()); _cells.emplace(cell_type, std::vector<Cell*>());
@ -353,10 +353,10 @@ struct JnyWriter
f << stringf(",\n"); f << stringf(",\n");
const auto param_val = param.second; const auto param_val = param.second;
if (!param_val.empty()) { if (!param_val.empty()) {
f << stringf(" %s\"%s\": ", _indent, escape_string(param.first.unescape())); f << stringf(" %s\"%s\": ", _indent, design->twines.unescaped_str(escape_string(param.first)));
write_param_val(param_val); write_param_val(param_val);
} else { } else {
f << stringf(" %s\"%s\": true", _indent, escape_string(param.first.unescape())); f << stringf(" %s\"%s\": true", _indent, design->twines.unescaped_str(escape_string(param.first)));
} }
first_param = false; first_param = false;

View File

@ -76,7 +76,7 @@ struct JsonWriter
string get_name(IdString name) string get_name(IdString name)
{ {
return get_string(name.unescape()); return design->twines.unescaped_str(get_string(name));
} }
string get_name(TwineRef name) string get_name(TwineRef name)
@ -205,7 +205,7 @@ struct JsonWriter
for (auto c : module->cells()) { for (auto c : module->cells()) {
if (use_selection && !module->selected(c)) if (use_selection && !module->selected(c))
continue; continue;
if (!scopeinfo_mode && c->type == ID($scopeinfo)) if (!scopeinfo_mode && c->type == TW($scopeinfo))
continue; continue;
f << stringf("%s\n", first ? "" : ","); f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(c->name)); f << stringf(" %s: {\n", get_name(c->name));

View File

@ -378,7 +378,7 @@ struct SimplecWorker
void eval_cell(HierDirtyFlags *work, Cell *cell) void eval_cell(HierDirtyFlags *work, Cell *cell)
{ {
if (cell->type.in(ID($_BUF_), ID($_NOT_))) if (cell->type.in(TW($_BUF_), TW($_NOT_)))
{ {
SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A)); SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A));
SigBit y = sigmaps.at(work->module)(cell->getPort(TW::Y)); SigBit y = sigmaps.at(work->module)(cell->getPort(TW::Y));
@ -386,18 +386,18 @@ struct SimplecWorker
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0"; string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string expr; string expr;
if (cell->type == ID($_BUF_)) expr = a_expr; if (cell->type == TW($_BUF_)) expr = a_expr;
if (cell->type == ID($_NOT_)) expr = "!" + a_expr; if (cell->type == TW($_NOT_)) expr = "!" + a_expr;
log_assert(y.wire); log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", cell, cell->type.unescape())); stringf(" // %s (%s)", cell, cell->type.unescaped()));
work->set_dirty(y); work->set_dirty(y);
return; return;
} }
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_)))
{ {
SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A)); SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B)); SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B));
@ -407,24 +407,24 @@ struct SimplecWorker
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0"; string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string expr; string expr;
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr, b_expr); if (cell->type == TW($_AND_)) expr = stringf("%s & %s", a_expr, b_expr);
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr, b_expr); if (cell->type == TW($_NAND_)) expr = stringf("!(%s & %s)", a_expr, b_expr);
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr, b_expr); if (cell->type == TW($_OR_)) expr = stringf("%s | %s", a_expr, b_expr);
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr, b_expr); if (cell->type == TW($_NOR_)) expr = stringf("!(%s | %s)", a_expr, b_expr);
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr, b_expr); if (cell->type == TW($_XOR_)) expr = stringf("%s ^ %s", a_expr, b_expr);
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr, b_expr); if (cell->type == TW($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr, b_expr);
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr, b_expr); if (cell->type == TW($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr, b_expr);
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr, b_expr); if (cell->type == TW($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr, b_expr);
log_assert(y.wire); log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", cell, cell->type.unescape())); stringf(" // %s (%s)", cell, cell->type.unescaped()));
work->set_dirty(y); work->set_dirty(y);
return; return;
} }
if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) if (cell->type.in(TW($_AOI3_), TW($_OAI3_)))
{ {
SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A)); SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B)); SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B));
@ -436,18 +436,18 @@ struct SimplecWorker
string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0"; string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0";
string expr; string expr;
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr, b_expr, c_expr); if (cell->type == TW($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr, b_expr, c_expr);
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr, b_expr, c_expr); if (cell->type == TW($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr, b_expr, c_expr);
log_assert(y.wire); log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", cell, cell->type.unescape())); stringf(" // %s (%s)", cell, cell->type.unescaped()));
work->set_dirty(y); work->set_dirty(y);
return; return;
} }
if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) if (cell->type.in(TW($_AOI4_), TW($_OAI4_)))
{ {
SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A)); SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B)); SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B));
@ -461,18 +461,18 @@ struct SimplecWorker
string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0"; string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0";
string expr; string expr;
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr, b_expr, c_expr, d_expr); if (cell->type == TW($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr, b_expr, c_expr, d_expr);
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr, b_expr, c_expr, d_expr); if (cell->type == TW($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr, b_expr, c_expr, d_expr);
log_assert(y.wire); log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", cell, cell->type.unescape())); stringf(" // %s (%s)", cell, cell->type.unescaped()));
work->set_dirty(y); work->set_dirty(y);
return; return;
} }
if (cell->type.in(ID($_MUX_), ID($_NMUX_))) if (cell->type.in(TW($_MUX_), TW($_NMUX_)))
{ {
SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A)); SigBit a = sigmaps.at(work->module)(cell->getPort(TW::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B)); SigBit b = sigmaps.at(work->module)(cell->getPort(TW::B));
@ -485,18 +485,18 @@ struct SimplecWorker
// casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933) // casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933)
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr, string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr,
cell->type == ID($_NMUX_) ? "!" : "", b_expr, cell->type == TW($_NMUX_) ? "!" : "", b_expr,
cell->type == ID($_NMUX_) ? "!" : "", a_expr); cell->type == TW($_NMUX_) ? "!" : "", a_expr);
log_assert(y.wire); log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", cell, cell->type.unescape())); stringf(" // %s (%s)", cell, cell->type.unescaped()));
work->set_dirty(y); work->set_dirty(y);
return; return;
} }
log_error("No C model for %s available at the moment (FIXME).\n", cell->type.unescape()); log_error("No C model for %s available at the moment (FIXME).\n", cell->type.unescaped());
} }
void eval_dirty(HierDirtyFlags *work) void eval_dirty(HierDirtyFlags *work)
@ -579,7 +579,7 @@ struct SimplecWorker
string hiername = work->log_prefix + "." + cell->module->design->twines.str(cell->meta_->name); string hiername = work->log_prefix + "." + cell->module->design->twines.str(cell->meta_->name);
if (verbose) if (verbose)
log(" Evaluating %s (%s, best of %d).\n", hiername, cell->type.unescape(), GetSize(work->dirty_cells)); log(" Evaluating %s (%s, best of %d).\n", hiername, cell->type.unescaped(), GetSize(work->dirty_cells));
if (activated_cells.count(hiername)) if (activated_cells.count(hiername))
reactivated_cells.insert(hiername); reactivated_cells.insert(hiername);

View File

@ -60,7 +60,7 @@ struct Smt2Worker
const char *get_id(IdString n) const char *get_id(IdString n)
{ {
if (ids.count(n) == 0) { if (ids.count(n) == 0) {
std::string str = n.unescape(); std::string str = design->twines.unescaped_str(n);
for (int i = 0; i < GetSize(str); i++) { for (int i = 0; i < GetSize(str); i++) {
if (str[i] == '\\') if (str[i] == '\\')
str[i] = '/'; str[i] = '/';
@ -196,8 +196,8 @@ struct Smt2Worker
continue; continue;
} }
bool is_input = ct.cell_input(cell->type, conn.first); bool is_input = ct.cell_input(cell->type_impl, conn.first);
bool is_output = ct.cell_output(cell->type, conn.first); bool is_output = ct.cell_output(cell->type_impl, conn.first);
if (is_output && !is_input) if (is_output && !is_input)
for (auto bit : sigmap(conn.second)) { for (auto bit : sigmap(conn.second)) {
@ -207,11 +207,11 @@ struct Smt2Worker
} }
else if (is_output || !is_input) else if (is_output || !is_input)
log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n", log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n",
module->design->twines.str(conn.first).c_str(), module, cell, cell->type.unescape()); module->design->twines.str(conn.first).c_str(), module, cell, cell->type.unescaped());
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && (conn.first == TW::CLK || conn.first == TW::C)) if (cell->type.in(TW($dff), TW($_DFF_P_), TW($_DFF_N_)) && (conn.first == TW::CLK || conn.first == TW::C))
{ {
bool posedge = (cell->type == ID($_DFF_N_)) || (cell->type == ID($dff) && cell->getParam(ID::CLK_POLARITY).as_bool()); bool posedge = (cell->type == TW($_DFF_N_)) || (cell->type == TW($dff) && cell->getParam(ID::CLK_POLARITY).as_bool());
for (auto bit : sigmap(conn.second)) { for (auto bit : sigmap(conn.second)) {
if (posedge) if (posedge)
clock_posedge.insert(bit); clock_posedge.insert(bit);
@ -546,7 +546,7 @@ struct Smt2Worker
{ {
if (verbose) if (verbose)
log("%*s=> export_cell %s (%s) [%s]\n", 2+2*GetSize(recursive_cells), "", log("%*s=> export_cell %s (%s) [%s]\n", 2+2*GetSize(recursive_cells), "",
cell, cell->type.unescape(), exported_cells.count(cell) ? "old" : "new"); cell, cell->type.unescaped(), exported_cells.count(cell) ? "old" : "new");
if (recursive_cells.count(cell)) if (recursive_cells.count(cell))
log_error("Found logic loop in module %s! See cell %s.\n", get_id(module), get_id(cell)); log_error("Found logic loop in module %s! See cell %s.\n", get_id(module), get_id(cell));
@ -557,7 +557,7 @@ struct Smt2Worker
exported_cells.insert(cell); exported_cells.insert(cell);
recursive_cells.insert(cell); recursive_cells.insert(cell);
if (cell->type == ID($initstate)) if (cell->type == TW($initstate))
{ {
SigBit bit = sigmap(cell->getPort(TW::Y).as_bit()); SigBit bit = sigmap(cell->getPort(TW::Y).as_bit());
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool (|%s_is| state)) ; %s\n", decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool (|%s_is| state)) ; %s\n",
@ -567,7 +567,7 @@ struct Smt2Worker
return; return;
} }
if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) if (cell->type.in(TW($_FF_), TW($_DFF_P_), TW($_DFF_N_)))
{ {
registers.insert(cell); registers.insert(cell);
SigBit q_bit = cell->getPort(TW::Q); SigBit q_bit = cell->getPort(TW::Q);
@ -579,28 +579,28 @@ struct Smt2Worker
return; return;
} }
if (cell->type == ID($_BUF_)) return export_gate(cell, "A"); if (cell->type == TW($_BUF_)) return export_gate(cell, "A");
if (cell->type == ID($_NOT_)) return export_gate(cell, "(not A)"); if (cell->type == TW($_NOT_)) return export_gate(cell, "(not A)");
if (cell->type == ID($_AND_)) return export_gate(cell, "(and A B)"); if (cell->type == TW($_AND_)) return export_gate(cell, "(and A B)");
if (cell->type == ID($_NAND_)) return export_gate(cell, "(not (and A B))"); if (cell->type == TW($_NAND_)) return export_gate(cell, "(not (and A B))");
if (cell->type == ID($_OR_)) return export_gate(cell, "(or A B)"); if (cell->type == TW($_OR_)) return export_gate(cell, "(or A B)");
if (cell->type == ID($_NOR_)) return export_gate(cell, "(not (or A B))"); if (cell->type == TW($_NOR_)) return export_gate(cell, "(not (or A B))");
if (cell->type == ID($_XOR_)) return export_gate(cell, "(xor A B)"); if (cell->type == TW($_XOR_)) return export_gate(cell, "(xor A B)");
if (cell->type == ID($_XNOR_)) return export_gate(cell, "(not (xor A B))"); if (cell->type == TW($_XNOR_)) return export_gate(cell, "(not (xor A B))");
if (cell->type == ID($_ANDNOT_)) return export_gate(cell, "(and A (not B))"); if (cell->type == TW($_ANDNOT_)) return export_gate(cell, "(and A (not B))");
if (cell->type == ID($_ORNOT_)) return export_gate(cell, "(or A (not B))"); if (cell->type == TW($_ORNOT_)) return export_gate(cell, "(or A (not B))");
if (cell->type == ID($_MUX_)) return export_gate(cell, "(ite S B A)"); if (cell->type == TW($_MUX_)) return export_gate(cell, "(ite S B A)");
if (cell->type == ID($_NMUX_)) return export_gate(cell, "(not (ite S B A))"); if (cell->type == TW($_NMUX_)) return export_gate(cell, "(not (ite S B A))");
if (cell->type == ID($_AOI3_)) return export_gate(cell, "(not (or (and A B) C))"); if (cell->type == TW($_AOI3_)) return export_gate(cell, "(not (or (and A B) C))");
if (cell->type == ID($_OAI3_)) return export_gate(cell, "(not (and (or A B) C))"); if (cell->type == TW($_OAI3_)) return export_gate(cell, "(not (and (or A B) C))");
if (cell->type == ID($_AOI4_)) return export_gate(cell, "(not (or (and A B) (and C D)))"); if (cell->type == TW($_AOI4_)) return export_gate(cell, "(not (or (and A B) (and C D)))");
if (cell->type == ID($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))"); if (cell->type == TW($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))");
// FIXME: $lut // FIXME: $lut
if (bvmode) if (bvmode)
{ {
if (cell->type.in(ID($ff), ID($dff))) if (cell->type.in(TW($ff), TW($dff)))
{ {
registers.insert(cell); registers.insert(cell);
int smtoffset = 0; int smtoffset = 0;
@ -615,9 +615,9 @@ struct Smt2Worker
return; return;
} }
if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) if (cell->type.in(TW($anyconst), TW($anyseq), TW($anyinit), TW($allconst), TW($allseq)))
{ {
auto QY = cell->type == ID($anyinit) ? TW::Q : TW::Y; auto QY = cell->type == TW($anyinit) ? TW::Q : TW::Y;
registers.insert(cell); registers.insert(cell);
string infostr; string infostr;
if (cell->has_attribute(ID::src)) { if (cell->has_attribute(ID::src)) {
@ -637,8 +637,8 @@ struct Smt2Worker
log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str()); log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str());
} }
bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst)); bool init_only = cell->type.in(TW($anyconst), TW($anyinit), TW($allconst));
bool clk2fflogic = cell->type == ID($anyinit) && cell->get_bool_attribute(ID(clk2fflogic)); bool clk2fflogic = cell->type == TW($anyinit) && cell->get_bool_attribute(ID(clk2fflogic));
int smtoffset = 0; int smtoffset = 0;
for (auto chunk : cell->getPort(clk2fflogic ? TW::D : QY).chunks()) { for (auto chunk : cell->getPort(clk2fflogic ? TW::D : QY).chunks()) {
if (chunk.is_wire()) if (chunk.is_wire())
@ -647,27 +647,27 @@ struct Smt2Worker
} }
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(QY)), log_signal(cell->getPort(QY))); makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(QY)), log_signal(cell->getPort(QY)));
if (cell->type == ID($anyseq)) if (cell->type == TW($anyseq))
ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter)); ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter));
register_bv(cell->getPort(QY), idcounter++); register_bv(cell->getPort(QY), idcounter++);
recursive_cells.erase(cell); recursive_cells.erase(cell);
return; return;
} }
if (cell->type == ID($and)) return export_bvop(cell, "(bvand A B)"); if (cell->type == TW($and)) return export_bvop(cell, "(bvand A B)");
if (cell->type == ID($or)) return export_bvop(cell, "(bvor A B)"); if (cell->type == TW($or)) return export_bvop(cell, "(bvor A B)");
if (cell->type == ID($xor)) return export_bvop(cell, "(bvxor A B)"); if (cell->type == TW($xor)) return export_bvop(cell, "(bvxor A B)");
if (cell->type == ID($xnor)) return export_bvop(cell, "(bvxnor A B)"); if (cell->type == TW($xnor)) return export_bvop(cell, "(bvxnor A B)");
if (cell->type == ID($bweqx)) return export_bvop(cell, "(bvxnor A B)", 'U'); if (cell->type == TW($bweqx)) return export_bvop(cell, "(bvxnor A B)", 'U');
if (cell->type == ID($bwmux)) return export_bvop(cell, "(bvor (bvand A (bvnot S)) (bvand B S))", 'U'); if (cell->type == TW($bwmux)) return export_bvop(cell, "(bvor (bvand A (bvnot S)) (bvand B S))", 'U');
if (cell->type == ID($shl)) return export_bvop(cell, "(bvshl A B)", 's'); if (cell->type == TW($shl)) return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == ID($shr)) return export_bvop(cell, "(bvlshr A B)", 's'); if (cell->type == TW($shr)) return export_bvop(cell, "(bvlshr A B)", 's');
if (cell->type == ID($sshl)) return export_bvop(cell, "(bvshl A B)", 's'); if (cell->type == TW($sshl)) return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == ID($sshr)) return export_bvop(cell, "(bvLshr A B)", 's'); if (cell->type == TW($sshr)) return export_bvop(cell, "(bvLshr A B)", 's');
if (cell->type.in(ID($shift), ID($shiftx))) { if (cell->type.in(TW($shift), TW($shiftx))) {
if (cell->getParam(ID::B_SIGNED).as_bool()) { if (cell->getParam(ID::B_SIGNED).as_bool()) {
return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) " return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) "
"(bvlshr A B) (bvshl A (bvneg B)))", "(bvlshr A B) (bvshl A (bvneg B)))",
@ -677,28 +677,28 @@ struct Smt2Worker
} }
} }
if (cell->type == ID($lt)) return export_bvop(cell, "(bvUlt A B)", 'b'); if (cell->type == TW($lt)) return export_bvop(cell, "(bvUlt A B)", 'b');
if (cell->type == ID($le)) return export_bvop(cell, "(bvUle A B)", 'b'); if (cell->type == TW($le)) return export_bvop(cell, "(bvUle A B)", 'b');
if (cell->type == ID($ge)) return export_bvop(cell, "(bvUge A B)", 'b'); if (cell->type == TW($ge)) return export_bvop(cell, "(bvUge A B)", 'b');
if (cell->type == ID($gt)) return export_bvop(cell, "(bvUgt A B)", 'b'); if (cell->type == TW($gt)) return export_bvop(cell, "(bvUgt A B)", 'b');
if (cell->type == ID($ne)) return export_bvop(cell, "(distinct A B)", 'b'); if (cell->type == TW($ne)) return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == ID($nex)) return export_bvop(cell, "(distinct A B)", 'b'); if (cell->type == TW($nex)) return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == ID($eq)) return export_bvop(cell, "(= A B)", 'b'); if (cell->type == TW($eq)) return export_bvop(cell, "(= A B)", 'b');
if (cell->type == ID($eqx)) return export_bvop(cell, "(= A B)", 'b'); if (cell->type == TW($eqx)) return export_bvop(cell, "(= A B)", 'b');
if (cell->type == ID($not)) return export_bvop(cell, "(bvnot A)"); if (cell->type == TW($not)) return export_bvop(cell, "(bvnot A)");
if (cell->type == ID($pos)) return export_bvop(cell, "A"); if (cell->type == TW($pos)) return export_bvop(cell, "A");
if (cell->type == ID($neg)) return export_bvop(cell, "(bvneg A)"); if (cell->type == TW($neg)) return export_bvop(cell, "(bvneg A)");
if (cell->type == ID($add)) return export_bvop(cell, "(bvadd A B)"); if (cell->type == TW($add)) return export_bvop(cell, "(bvadd A B)");
if (cell->type == ID($sub)) return export_bvop(cell, "(bvsub A B)"); if (cell->type == TW($sub)) return export_bvop(cell, "(bvsub A B)");
if (cell->type == ID($mul)) return export_bvop(cell, "(bvmul A B)"); if (cell->type == TW($mul)) return export_bvop(cell, "(bvmul A B)");
if (cell->type == ID($div)) return export_bvop(cell, "(bvUdiv A B)", 'd'); if (cell->type == TW($div)) return export_bvop(cell, "(bvUdiv A B)", 'd');
// "rem" = truncating modulo // "rem" = truncating modulo
if (cell->type == ID($mod)) return export_bvop(cell, "(bvUrem A B)", 'd'); if (cell->type == TW($mod)) return export_bvop(cell, "(bvUrem A B)", 'd');
// "mod" = flooring modulo // "mod" = flooring modulo
if (cell->type == ID($modfloor)) { if (cell->type == TW($modfloor)) {
// bvumod doesn't exist because it's the same as bvurem // bvumod doesn't exist because it's the same as bvurem
if (cell->getParam(ID::A_SIGNED).as_bool()) { if (cell->getParam(ID::A_SIGNED).as_bool()) {
return export_bvop(cell, "(bvsmod A B)", 'd'); return export_bvop(cell, "(bvsmod A B)", 'd');
@ -707,7 +707,7 @@ struct Smt2Worker
} }
} }
// "div" = flooring division // "div" = flooring division
if (cell->type == ID($divfloor)) { if (cell->type == TW($divfloor)) {
if (cell->getParam(ID::A_SIGNED).as_bool()) { if (cell->getParam(ID::A_SIGNED).as_bool()) {
// bvsdiv is truncating division, so we can't use it here. // bvsdiv is truncating division, so we can't use it here.
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B))); int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
@ -728,24 +728,24 @@ struct Smt2Worker
} }
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)) && if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_bool)) &&
2*GetSize(cell->getPort(TW::A).chunks()) < GetSize(cell->getPort(TW::A))) { 2*GetSize(cell->getPort(TW::A).chunks()) < GetSize(cell->getPort(TW::A))) {
bool is_and = cell->type == ID($reduce_and); bool is_and = cell->type == TW($reduce_and);
string bits(GetSize(cell->getPort(TW::A)), is_and ? '1' : '0'); string bits(GetSize(cell->getPort(TW::A)), is_and ? '1' : '0');
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits), 'b'); return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits), 'b');
} }
if (cell->type == ID($reduce_and)) return export_reduce(cell, "(and A)", true); if (cell->type == TW($reduce_and)) return export_reduce(cell, "(and A)", true);
if (cell->type == ID($reduce_or)) return export_reduce(cell, "(or A)", false); if (cell->type == TW($reduce_or)) return export_reduce(cell, "(or A)", false);
if (cell->type == ID($reduce_xor)) return export_reduce(cell, "(xor A)", false); if (cell->type == TW($reduce_xor)) return export_reduce(cell, "(xor A)", false);
if (cell->type == ID($reduce_xnor)) return export_reduce(cell, "(not (xor A))", false); if (cell->type == TW($reduce_xnor)) return export_reduce(cell, "(not (xor A))", false);
if (cell->type == ID($reduce_bool)) return export_reduce(cell, "(or A)", false); if (cell->type == TW($reduce_bool)) return export_reduce(cell, "(or A)", false);
if (cell->type == ID($logic_not)) return export_reduce(cell, "(not (or A))", false); if (cell->type == TW($logic_not)) return export_reduce(cell, "(not (or A))", false);
if (cell->type == ID($logic_and)) return export_reduce(cell, "(and (or A) (or B))", false); if (cell->type == TW($logic_and)) return export_reduce(cell, "(and (or A) (or B))", false);
if (cell->type == ID($logic_or)) return export_reduce(cell, "(or A B)", false); if (cell->type == TW($logic_or)) return export_reduce(cell, "(or A B)", false);
if (cell->type.in(ID($mux), ID($pmux))) if (cell->type.in(TW($mux), TW($pmux)))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
std::string processed_expr = get_bv(cell->getPort(TW::A)); std::string processed_expr = get_bv(cell->getPort(TW::A));
@ -798,7 +798,7 @@ struct Smt2Worker
if (has_async_wr && has_sync_wr) if (has_async_wr && has_sync_wr)
log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", cell, module); log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", cell, module);
decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", mem->memid.unescape(), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", design->twines.unescaped_str(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync"));
decls.push_back(witness_memory(get_id(mem->memid), cell, mem)); decls.push_back(witness_memory(get_id(mem->memid), cell, mem));
string memstate; string memstate;
@ -823,7 +823,7 @@ struct Smt2Worker
if (port.clk_enable) if (port.clk_enable)
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module); "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), design->twines.unescaped_str(mem->memid), module);
decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig)));
@ -867,7 +867,7 @@ struct Smt2Worker
if (port.clk_enable) if (port.clk_enable)
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module); "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), design->twines.unescaped_str(mem->memid), module);
decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig)));
@ -936,15 +936,15 @@ struct Smt2Worker
return; return;
} }
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { if (cell->type.in(TW($dffe), TW($sdff), TW($sdffe), TW($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { if (cell->type.in(TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($dffsr), TW($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { if (cell->type.in(TW($sr), TW($dlatch), TW($adlatch), TW($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n",
cell->type, module, cell); cell->type, module, cell);
} }
@ -973,7 +973,7 @@ struct Smt2Worker
pool<SigBit> reg_bits; pool<SigBit> reg_bits;
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_P_), ID($_DFF_N_), ID($anyinit))) { if (cell->type.in(TW($ff), TW($dff), TW($_FF_), TW($_DFF_P_), TW($_DFF_N_), TW($anyinit))) {
// not using sigmap -- we want the net directly at the dff output // not using sigmap -- we want the net directly at the dff output
for (auto bit : cell->getPort(TW::Q)) for (auto bit : cell->getPort(TW::Q))
reg_bits.insert(bit); reg_bits.insert(bit);
@ -1117,15 +1117,15 @@ struct Smt2Worker
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($assert), ID($assume), ID($cover))) if (cell->type.in(TW($assert), TW($assume), TW($cover)))
{ {
int &id = cell->type == ID($assert) ? assert_id : int &id = cell->type == TW($assert) ? assert_id :
cell->type == ID($assume) ? assume_id : cell->type == TW($assume) ? assume_id :
cell->type == ID($cover) ? cover_id : *(int*)nullptr; cell->type == TW($cover) ? cover_id : *(int*)nullptr;
char postfix = cell->type == ID($assert) ? 'a' : char postfix = cell->type == TW($assert) ? 'a' :
cell->type == ID($assume) ? 'u' : cell->type == TW($assume) ? 'u' :
cell->type == ID($cover) ? 'c' : 0; cell->type == TW($cover) ? 'c' : 0;
string name_a = get_bool(cell->getPort(TW::A)); string name_a = get_bool(cell->getPort(TW::A));
string name_en = get_bool(cell->getPort(TW::EN)); string name_en = get_bool(cell->getPort(TW::EN));
@ -1147,16 +1147,16 @@ struct Smt2Worker
else else
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell))); decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
if (cell->type == ID($cover)) if (cell->type == TW($cover))
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (and %s %s)) ; %s\n", decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (and %s %s)) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell))); get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
else else
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (or %s (not %s))) ; %s\n", decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (or %s (not %s))) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell))); get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
if (cell->type == ID($assert)) if (cell->type == TW($assert))
assert_list.push_back(stringf("(|%s_a %d| state)", get_id(module), id)); assert_list.push_back(stringf("(|%s_a %d| state)", get_id(module), id));
else if (cell->type == ID($assume)) else if (cell->type == TW($assume))
assume_list.push_back(stringf("(|%s_u %d| state)", get_id(module), id)); assume_list.push_back(stringf("(|%s_u %d| state)", get_id(module), id));
id++; id++;
@ -1212,7 +1212,7 @@ struct Smt2Worker
for (auto cell : this_regs) for (auto cell : this_regs)
{ {
if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) if (cell->type.in(TW($_FF_), TW($_DFF_P_), TW($_DFF_N_)))
{ {
std::string expr_d = get_bool(cell->getPort(TW::D)); std::string expr_d = get_bool(cell->getPort(TW::D));
std::string expr_q = get_bool(cell->getPort(TW::Q), "next_state"); std::string expr_q = get_bool(cell->getPort(TW::Q), "next_state");
@ -1220,7 +1220,7 @@ struct Smt2Worker
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(TW::Q)), get_bool(cell->getPort(TW::Q), "other_state"))); ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(TW::Q)), get_bool(cell->getPort(TW::Q), "other_state")));
} }
if (cell->type.in(ID($ff), ID($dff), ID($anyinit))) if (cell->type.in(TW($ff), TW($dff), TW($anyinit)))
{ {
std::string expr_d = get_bv(cell->getPort(TW::D)); std::string expr_d = get_bv(cell->getPort(TW::D));
std::string expr_q = get_bv(cell->getPort(TW::Q), "next_state"); std::string expr_q = get_bv(cell->getPort(TW::Q), "next_state");
@ -1228,12 +1228,12 @@ struct Smt2Worker
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(TW::Q)), get_bv(cell->getPort(TW::Q), "other_state"))); ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(TW::Q)), get_bv(cell->getPort(TW::Q), "other_state")));
} }
if (cell->type.in(ID($anyconst), ID($allconst))) if (cell->type.in(TW($anyconst), TW($allconst)))
{ {
std::string expr_d = get_bv(cell->getPort(TW::Y)); std::string expr_d = get_bv(cell->getPort(TW::Y));
std::string expr_q = get_bv(cell->getPort(TW::Y), "next_state"); std::string expr_q = get_bv(cell->getPort(TW::Y), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(TW::Y)))); trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(TW::Y))));
if (cell->type == ID($anyconst)) if (cell->type == TW($anyconst))
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(TW::Y)), get_bv(cell->getPort(TW::Y), "other_state"))); ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(TW::Y)), get_bv(cell->getPort(TW::Y), "other_state")));
} }
} }
@ -1882,7 +1882,7 @@ struct Smt2Backend : public Backend {
for (auto &dep : it.second) for (auto &dep : it.second)
if (module_deps.count(dep) > 0) if (module_deps.count(dep) > 0)
goto not_ready_yet; goto not_ready_yet;
// log("Next in topological sort: %s\n", it.first->name.unescape()); // log("Next in topological sort: %s\n", design->twines.unescaped_str(it.first->name));
sorted_modules.push_back(it.first); sorted_modules.push_back(it.first);
not_ready_yet:; not_ready_yet:;
} }
@ -1899,7 +1899,7 @@ struct Smt2Backend : public Backend {
for (auto module : sorted_modules) for (auto module : sorted_modules)
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type.in(ID($allconst), ID($allseq))) if (cell->type.in(TW($allconst), TW($allseq)))
goto found_forall; goto found_forall;
if (0) { if (0) {
found_forall: found_forall:

View File

@ -227,7 +227,7 @@ struct SmvWorker
{ {
// FIXME: $slice, $concat, $mem // FIXME: $slice, $concat, $mem
if (cell->type.in(ID($assert))) if (cell->type.in(TW($assert)))
{ {
SigSpec sig_a = cell->getPort(TW::A); SigSpec sig_a = cell->getPort(TW::A);
SigSpec sig_en = cell->getPort(TW::EN); SigSpec sig_en = cell->getPort(TW::EN);
@ -237,7 +237,7 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx)))
{ {
SigSpec sig_a = cell->getPort(TW::A); SigSpec sig_a = cell->getPort(TW::A);
SigSpec sig_b = cell->getPort(TW::B); SigSpec sig_b = cell->getPort(TW::B);
@ -256,10 +256,10 @@ struct SmvWorker
bool signed_a = cell->getParam(ID::A_SIGNED).as_bool(); bool signed_a = cell->getParam(ID::A_SIGNED).as_bool();
bool signed_b = cell->getParam(ID::B_SIGNED).as_bool(); bool signed_b = cell->getParam(ID::B_SIGNED).as_bool();
string op = cell->type.in(ID($shl), ID($sshl)) ? "<<" : ">>"; string op = cell->type.in(TW($shl), TW($sshl)) ? "<<" : ">>";
string expr, expr_a; string expr, expr_a;
if (cell->type == ID($sshr) && signed_a) if (cell->type == TW($sshr) && signed_a)
{ {
expr_a = rvalue_s(sig_a, width); expr_a = rvalue_s(sig_a, width);
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a, op, rvalue(sig_b.extract(0, shift_b_width)), width_y); expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a, op, rvalue(sig_b.extract(0, shift_b_width)), width_y);
@ -268,7 +268,7 @@ struct SmvWorker
rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width, rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width,
rvalue(sig_a[GetSize(sig_a)-1]), width_y, width_y, expr.c_str()); rvalue(sig_a[GetSize(sig_a)-1]), width_y, width_y, expr.c_str());
} }
else if (cell->type.in(ID($shift), ID($shiftx)) && signed_b) else if (cell->type.in(TW($shift), TW($shiftx)) && signed_b)
{ {
expr_a = rvalue_u(sig_a, width); expr_a = rvalue_u(sig_a, width);
@ -292,7 +292,7 @@ struct SmvWorker
} }
else else
{ {
if (cell->type.in(ID($shift), ID($shiftx)) || !signed_a) if (cell->type.in(TW($shift), TW($shiftx)) || !signed_a)
expr_a = rvalue_u(sig_a, width); expr_a = rvalue_u(sig_a, width);
else else
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width); expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
@ -308,14 +308,14 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($not), ID($pos), ID($neg))) if (cell->type.in(TW($not), TW($pos), TW($neg)))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
string expr_a, op; string expr_a, op;
if (cell->type == ID($not)) op = "!"; if (cell->type == TW($not)) op = "!";
if (cell->type == ID($pos)) op = ""; if (cell->type == TW($pos)) op = "";
if (cell->type == ID($neg)) op = "-"; if (cell->type == TW($neg)) op = "-";
if (cell->getParam(ID::A_SIGNED).as_bool()) if (cell->getParam(ID::A_SIGNED).as_bool())
{ {
@ -331,18 +331,18 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor))) if (cell->type.in(TW($add), TW($sub), TW($mul), TW($and), TW($or), TW($xor), TW($xnor)))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
string expr_a, expr_b, op; string expr_a, expr_b, op;
if (cell->type == ID($add)) op = "+"; if (cell->type == TW($add)) op = "+";
if (cell->type == ID($sub)) op = "-"; if (cell->type == TW($sub)) op = "-";
if (cell->type == ID($mul)) op = "*"; if (cell->type == TW($mul)) op = "*";
if (cell->type == ID($and)) op = "&"; if (cell->type == TW($and)) op = "&";
if (cell->type == ID($or)) op = "|"; if (cell->type == TW($or)) op = "|";
if (cell->type == ID($xor)) op = "xor"; if (cell->type == TW($xor)) op = "xor";
if (cell->type == ID($xnor)) op = "xnor"; if (cell->type == TW($xnor)) op = "xnor";
if (cell->getParam(ID::A_SIGNED).as_bool()) if (cell->getParam(ID::A_SIGNED).as_bool())
{ {
@ -359,15 +359,15 @@ struct SmvWorker
} }
// SMV has a "mod" operator, but its semantics don't seem to be well-defined - to be safe, don't generate it at all // SMV has a "mod" operator, but its semantics don't seem to be well-defined - to be safe, don't generate it at all
if (cell->type.in(ID($div)/*, ID($mod), ID($modfloor)*/)) if (cell->type.in(TW($div)/*, TW($mod), TW($modfloor)*/))
{ {
int width_y = GetSize(cell->getPort(TW::Y)); int width_y = GetSize(cell->getPort(TW::Y));
int width = max(width_y, GetSize(cell->getPort(TW::A))); int width = max(width_y, GetSize(cell->getPort(TW::A)));
width = max(width, GetSize(cell->getPort(TW::B))); width = max(width, GetSize(cell->getPort(TW::B)));
string expr_a, expr_b, op; string expr_a, expr_b, op;
if (cell->type == ID($div)) op = "/"; if (cell->type == TW($div)) op = "/";
//if (cell->type == ID($mod)) op = "mod"; //if (cell->type == TW($mod)) op = "mod";
if (cell->getParam(ID::A_SIGNED).as_bool()) if (cell->getParam(ID::A_SIGNED).as_bool())
{ {
@ -383,19 +383,19 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($lt), ID($le), ID($ge), ID($gt))) if (cell->type.in(TW($eq), TW($ne), TW($eqx), TW($nex), TW($lt), TW($le), TW($ge), TW($gt)))
{ {
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B))); int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
string expr_a, expr_b, op; string expr_a, expr_b, op;
if (cell->type == ID($eq)) op = "="; if (cell->type == TW($eq)) op = "=";
if (cell->type == ID($ne)) op = "!="; if (cell->type == TW($ne)) op = "!=";
if (cell->type == ID($eqx)) op = "="; if (cell->type == TW($eqx)) op = "=";
if (cell->type == ID($nex)) op = "!="; if (cell->type == TW($nex)) op = "!=";
if (cell->type == ID($lt)) op = "<"; if (cell->type == TW($lt)) op = "<";
if (cell->type == ID($le)) op = "<="; if (cell->type == TW($le)) op = "<=";
if (cell->type == ID($ge)) op = ">="; if (cell->type == TW($ge)) op = ">=";
if (cell->type == ID($gt)) op = ">"; if (cell->type == TW($gt)) op = ">";
if (cell->getParam(ID::A_SIGNED).as_bool()) if (cell->getParam(ID::A_SIGNED).as_bool())
{ {
@ -414,7 +414,7 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_bool)))
{ {
int width_a = GetSize(cell->getPort(TW::A)); int width_a = GetSize(cell->getPort(TW::A));
int width_y = GetSize(cell->getPort(TW::Y)); int width_y = GetSize(cell->getPort(TW::Y));
@ -422,15 +422,15 @@ struct SmvWorker
const char *expr_y = lvalue(cell->getPort(TW::Y)); const char *expr_y = lvalue(cell->getPort(TW::Y));
string expr; string expr;
if (cell->type == ID($reduce_and)) expr = stringf("%s = !0ub%d_0", expr_a, width_a); if (cell->type == TW($reduce_and)) expr = stringf("%s = !0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a); if (cell->type == TW($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a); if (cell->type == TW($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y)); definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
continue; continue;
} }
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) if (cell->type.in(TW($reduce_xor), TW($reduce_xnor)))
{ {
int width_y = GetSize(cell->getPort(TW::Y)); int width_y = GetSize(cell->getPort(TW::Y));
const char *expr_y = lvalue(cell->getPort(TW::Y)); const char *expr_y = lvalue(cell->getPort(TW::Y));
@ -442,14 +442,14 @@ struct SmvWorker
expr += rvalue(bit); expr += rvalue(bit);
} }
if (cell->type == ID($reduce_xnor)) if (cell->type == TW($reduce_xnor))
expr = "!(" + expr + ")"; expr = "!(" + expr + ")";
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr, width_y)); definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr, width_y));
continue; continue;
} }
if (cell->type.in(ID($logic_and), ID($logic_or))) if (cell->type.in(TW($logic_and), TW($logic_or)))
{ {
int width_a = GetSize(cell->getPort(TW::A)); int width_a = GetSize(cell->getPort(TW::A));
int width_b = GetSize(cell->getPort(TW::B)); int width_b = GetSize(cell->getPort(TW::B));
@ -460,14 +460,14 @@ struct SmvWorker
const char *expr_y = lvalue(cell->getPort(TW::Y)); const char *expr_y = lvalue(cell->getPort(TW::Y));
string expr; string expr;
if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b; if (cell->type == TW($logic_and)) expr = expr_a + " & " + expr_b;
if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b; if (cell->type == TW($logic_or)) expr = expr_a + " | " + expr_b;
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y)); definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
continue; continue;
} }
if (cell->type.in(ID($logic_not))) if (cell->type.in(TW($logic_not)))
{ {
int width_a = GetSize(cell->getPort(TW::A)); int width_a = GetSize(cell->getPort(TW::A));
int width_y = GetSize(cell->getPort(TW::Y)); int width_y = GetSize(cell->getPort(TW::Y));
@ -479,7 +479,7 @@ struct SmvWorker
continue; continue;
} }
if (cell->type.in(ID($mux), ID($pmux))) if (cell->type.in(TW($mux), TW($pmux)))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
SigSpec sig_a = cell->getPort(TW::A); SigSpec sig_a = cell->getPort(TW::A);
@ -495,34 +495,34 @@ struct SmvWorker
continue; continue;
} }
if (cell->type == ID($dff)) if (cell->type == TW($dff))
{ {
vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort(TW::Q)), GetSize(cell->getPort(TW::Q)), log_signal(cell->getPort(TW::Q)))); vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort(TW::Q)), GetSize(cell->getPort(TW::Q)), log_signal(cell->getPort(TW::Q))));
assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort(TW::Q)), rvalue(cell->getPort(TW::D)))); assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort(TW::Q)), rvalue(cell->getPort(TW::D))));
continue; continue;
} }
if (cell->type.in(ID($_BUF_), ID($_NOT_))) if (cell->type.in(TW($_BUF_), TW($_NOT_)))
{ {
string op = cell->type == ID($_NOT_) ? "!" : ""; string op = cell->type == TW($_NOT_) ? "!" : "";
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(TW::Y)), op, rvalue(cell->getPort(TW::A)))); definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(TW::Y)), op, rvalue(cell->getPort(TW::A))));
continue; continue;
} }
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_)))
{ {
string op; string op;
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_))) op = "&"; if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_ANDNOT_))) op = "&";
if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_))) op = "|"; if (cell->type.in(TW($_OR_), TW($_NOR_), TW($_ORNOT_))) op = "|";
if (cell->type.in(ID($_XOR_))) op = "xor"; if (cell->type.in(TW($_XOR_))) op = "xor";
if (cell->type.in(ID($_XNOR_))) op = "xnor"; if (cell->type.in(TW($_XNOR_))) op = "xnor";
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B)))); rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B))));
else else
if (cell->type.in(ID($_NAND_), ID($_NOR_))) if (cell->type.in(TW($_NAND_), TW($_NOR_)))
definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B)))); rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B))));
else else
@ -531,61 +531,61 @@ struct SmvWorker
continue; continue;
} }
if (cell->type == ID($_MUX_)) if (cell->type == TW($_MUX_))
{ {
definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A)))); rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A))));
continue; continue;
} }
if (cell->type == ID($_NMUX_)) if (cell->type == TW($_NMUX_))
{ {
definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A)))); rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A))));
continue; continue;
} }
if (cell->type == ID($_AOI3_)) if (cell->type == TW($_AOI3_))
{ {
definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)))); rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C))));
continue; continue;
} }
if (cell->type == ID($_OAI3_)) if (cell->type == TW($_OAI3_))
{ {
definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)))); rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C))));
continue; continue;
} }
if (cell->type == ID($_AOI4_)) if (cell->type == TW($_AOI4_))
{ {
definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D)))); rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D))));
continue; continue;
} }
if (cell->type == ID($_OAI4_)) if (cell->type == TW($_OAI4_))
{ {
definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort(TW::Y)), definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort(TW::Y)),
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D)))); rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D))));
continue; continue;
} }
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
continue; continue;
if (cell->type[0] == '$') { if (cell->type[0] == '$') {
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { if (cell->type.in(TW($dffe), TW($sdff), TW($sdffe), TW($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { if (cell->type.in(TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($dffsr), TW($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { if (cell->type.in(TW($sr), TW($dlatch), TW($adlatch), TW($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n", log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n",
cell->type.unescape(), module, cell); cell->type.unescape(), module, cell);
} }

View File

@ -30,7 +30,7 @@ PRIVATE_NAMESPACE_BEGIN
static string spice_id2str(IdString id) static string spice_id2str(IdString id)
{ {
static const char *escape_chars = "$\\[]()<>="; static const char *escape_chars = "$\\[]()<>=";
string s = id.unescape(); string s = design->twines.unescaped_str(id);
for (auto &ch : s) for (auto &ch : s)
if (strchr(escape_chars, ch) != nullptr) ch = '_'; if (strchr(escape_chars, ch) != nullptr) ch = '_';
@ -72,7 +72,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
continue; continue;
f << stringf("X%d", cell_counter++); f << stringf("X%d", cell_counter++);

View File

@ -78,7 +78,7 @@ struct TableBackend : public Backend {
continue; continue;
*f << design->twines.str(module->meta_->name) << "\t"; *f << design->twines.str(module->meta_->name) << "\t";
*f << wire->name.unescape() << "\t"; *f << design->twines.unescaped_str(wire->name) << "\t";
*f << "-" << "\t"; *f << "-" << "\t";
*f << "-" << "\t"; *f << "-" << "\t";
@ -99,7 +99,7 @@ struct TableBackend : public Backend {
{ {
*f << design->twines.str(module->meta_->name) << "\t"; *f << design->twines.str(module->meta_->name) << "\t";
*f << cell->module->design->twines.str(cell->meta_->name) << "\t"; *f << cell->module->design->twines.str(cell->meta_->name) << "\t";
*f << cell->type.unescape() << "\t"; *f << cell->type.unescaped() << "\t";
*f << design->twines.str(conn.first) << "\t"; *f << design->twines.str(conn.first) << "\t";
if (cell->input(conn.first) && cell->output(conn.first)) if (cell->input(conn.first) && cell->output(conn.first))

View File

@ -992,7 +992,7 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
std::string cellname(RTLIL::Cell *cell) std::string cellname(RTLIL::Cell *cell)
{ {
if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(ID($ff), ID($_FF_))) if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(TW($ff), TW($_FF_)))
{ {
RTLIL::SigSpec sig = cell->getPort(TW::Q); RTLIL::SigSpec sig = cell->getPort(TW::Q);
if (GetSize(sig) != 1 || sig.is_fully_const()) if (GetSize(sig) != 1 || sig.is_fully_const())
@ -1109,7 +1109,7 @@ void dump_cell_expr_check(std::ostream &f, std::string indent, const RTLIL::Cell
bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{ {
if (cell->type == ID($_NOT_)) { if (cell->type == TW($_NOT_)) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = "); f << stringf(" = ");
@ -1120,8 +1120,8 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($_BUF_), ID($buf))) { if (cell->type.in(TW($_BUF_), TW($buf))) {
if (cell->type == ID($buf) && cell->getPort(TW::A).has_const(State::Sz)) { if (cell->type == TW($buf) && cell->getPort(TW::A).has_const(State::Sz)) {
RTLIL::SigSpec a = cell->getPort(TW::A); RTLIL::SigSpec a = cell->getPort(TW::A);
RTLIL::SigSpec y = cell->getPort(TW::Y); RTLIL::SigSpec y = cell->getPort(TW::Y);
a.extend_u0(GetSize(y)); a.extend_u0(GetSize(y));
@ -1156,32 +1156,32 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) { if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_))) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = "); f << stringf(" = ");
if (cell->type.in(ID($_NAND_), ID($_NOR_), ID($_XNOR_))) if (cell->type.in(TW($_NAND_), TW($_NOR_), TW($_XNOR_)))
f << stringf("~("); f << stringf("~(");
dump_cell_expr_port(f, cell, "A", false); dump_cell_expr_port(f, cell, "A", false);
f << stringf(" "); f << stringf(" ");
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_))) if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_ANDNOT_)))
f << stringf("&"); f << stringf("&");
if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_))) if (cell->type.in(TW($_OR_), TW($_NOR_), TW($_ORNOT_)))
f << stringf("|"); f << stringf("|");
if (cell->type.in(ID($_XOR_), ID($_XNOR_))) if (cell->type.in(TW($_XOR_), TW($_XNOR_)))
f << stringf("^"); f << stringf("^");
dump_attributes(f, "", cell->attributes, " "); dump_attributes(f, "", cell->attributes, " ");
f << stringf(" "); f << stringf(" ");
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
f << stringf("~("); f << stringf("~(");
dump_cell_expr_port(f, cell, "B", false); dump_cell_expr_port(f, cell, "B", false);
if (cell->type.in(ID($_NAND_), ID($_NOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_NAND_), TW($_NOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_)))
f << stringf(")"); f << stringf(")");
f << stringf(";\n"); f << stringf(";\n");
return true; return true;
} }
if (cell->type == ID($_MUX_)) { if (cell->type == TW($_MUX_)) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = "); f << stringf(" = ");
@ -1195,7 +1195,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($_NMUX_)) { if (cell->type == TW($_NMUX_)) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = !("); f << stringf(" = !(");
@ -1209,14 +1209,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) { if (cell->type.in(TW($_AOI3_), TW($_OAI3_))) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = ~(("); f << stringf(" = ~((");
dump_cell_expr_port(f, cell, "A", false); dump_cell_expr_port(f, cell, "A", false);
f << (cell->type == ID($_AOI3_) ? " & " : " | "); f << (cell->type == TW($_AOI3_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "B", false); dump_cell_expr_port(f, cell, "B", false);
f << (cell->type == ID($_AOI3_) ? ") |" : ") &"); f << (cell->type == TW($_AOI3_) ? ") |" : ") &");
dump_attributes(f, "", cell->attributes, " "); dump_attributes(f, "", cell->attributes, " ");
f << stringf(" "); f << stringf(" ");
dump_cell_expr_port(f, cell, "C", false); dump_cell_expr_port(f, cell, "C", false);
@ -1224,18 +1224,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) { if (cell->type.in(TW($_AOI4_), TW($_OAI4_))) {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
f << stringf(" = ~(("); f << stringf(" = ~((");
dump_cell_expr_port(f, cell, "A", false); dump_cell_expr_port(f, cell, "A", false);
f << (cell->type == ID($_AOI4_) ? " & " : " | "); f << (cell->type == TW($_AOI4_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "B", false); dump_cell_expr_port(f, cell, "B", false);
f << (cell->type == ID($_AOI4_) ? ") |" : ") &"); f << (cell->type == TW($_AOI4_) ? ") |" : ") &");
dump_attributes(f, "", cell->attributes, " "); dump_attributes(f, "", cell->attributes, " ");
f << stringf(" ("); f << stringf(" (");
dump_cell_expr_port(f, cell, "C", false); dump_cell_expr_port(f, cell, "C", false);
f << (cell->type == ID($_AOI4_) ? " & " : " | "); f << (cell->type == TW($_AOI4_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "D", false); dump_cell_expr_port(f, cell, "D", false);
f << stringf("));\n"); f << stringf("));\n");
return true; return true;
@ -1246,50 +1246,50 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
#define HANDLE_BINOP(_type, _operator) \ #define HANDLE_BINOP(_type, _operator) \
if (cell->type ==_type) { dump_cell_expr_binop(f, indent, cell, _operator); return true; } if (cell->type ==_type) { dump_cell_expr_binop(f, indent, cell, _operator); return true; }
HANDLE_UNIOP(ID($not), "~") HANDLE_UNIOP(TW($not), "~")
HANDLE_UNIOP(ID($pos), "+") HANDLE_UNIOP(TW($pos), "+")
HANDLE_UNIOP(ID($neg), "-") HANDLE_UNIOP(TW($neg), "-")
HANDLE_BINOP(ID($and), "&") HANDLE_BINOP(TW($and), "&")
HANDLE_BINOP(ID($or), "|") HANDLE_BINOP(TW($or), "|")
HANDLE_BINOP(ID($xor), "^") HANDLE_BINOP(TW($xor), "^")
HANDLE_BINOP(ID($xnor), "~^") HANDLE_BINOP(TW($xnor), "~^")
HANDLE_UNIOP(ID($reduce_and), "&") HANDLE_UNIOP(TW($reduce_and), "&")
HANDLE_UNIOP(ID($reduce_or), "|") HANDLE_UNIOP(TW($reduce_or), "|")
HANDLE_UNIOP(ID($reduce_xor), "^") HANDLE_UNIOP(TW($reduce_xor), "^")
HANDLE_UNIOP(ID($reduce_xnor), "~^") HANDLE_UNIOP(TW($reduce_xnor), "~^")
HANDLE_UNIOP(ID($reduce_bool), "|") HANDLE_UNIOP(TW($reduce_bool), "|")
HANDLE_BINOP(ID($shl), "<<") HANDLE_BINOP(TW($shl), "<<")
HANDLE_BINOP(ID($shr), ">>") HANDLE_BINOP(TW($shr), ">>")
HANDLE_BINOP(ID($sshl), "<<<") HANDLE_BINOP(TW($sshl), "<<<")
HANDLE_BINOP(ID($sshr), ">>>") HANDLE_BINOP(TW($sshr), ">>>")
HANDLE_BINOP(ID($lt), "<") HANDLE_BINOP(TW($lt), "<")
HANDLE_BINOP(ID($le), "<=") HANDLE_BINOP(TW($le), "<=")
HANDLE_BINOP(ID($eq), "==") HANDLE_BINOP(TW($eq), "==")
HANDLE_BINOP(ID($ne), "!=") HANDLE_BINOP(TW($ne), "!=")
HANDLE_BINOP(ID($eqx), "===") HANDLE_BINOP(TW($eqx), "===")
HANDLE_BINOP(ID($nex), "!==") HANDLE_BINOP(TW($nex), "!==")
HANDLE_BINOP(ID($ge), ">=") HANDLE_BINOP(TW($ge), ">=")
HANDLE_BINOP(ID($gt), ">") HANDLE_BINOP(TW($gt), ">")
HANDLE_BINOP(ID($add), "+") HANDLE_BINOP(TW($add), "+")
HANDLE_BINOP(ID($sub), "-") HANDLE_BINOP(TW($sub), "-")
HANDLE_BINOP(ID($mul), "*") HANDLE_BINOP(TW($mul), "*")
HANDLE_BINOP(ID($div), "/") HANDLE_BINOP(TW($div), "/")
HANDLE_BINOP(ID($mod), "%") HANDLE_BINOP(TW($mod), "%")
HANDLE_BINOP(ID($pow), "**") HANDLE_BINOP(TW($pow), "**")
HANDLE_UNIOP(ID($logic_not), "!") HANDLE_UNIOP(TW($logic_not), "!")
HANDLE_BINOP(ID($logic_and), "&&") HANDLE_BINOP(TW($logic_and), "&&")
HANDLE_BINOP(ID($logic_or), "||") HANDLE_BINOP(TW($logic_or), "||")
#undef HANDLE_UNIOP #undef HANDLE_UNIOP
#undef HANDLE_BINOP #undef HANDLE_BINOP
if (cell->type == ID($divfloor)) if (cell->type == TW($divfloor))
{ {
// wire [MAXLEN+1:0] _0_, _1_, _2_; // wire [MAXLEN+1:0] _0_, _1_, _2_;
// assign _0_ = $signed(A); // assign _0_ = $signed(A);
@ -1344,7 +1344,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
} }
} }
if (cell->type == ID($modfloor)) if (cell->type == TW($modfloor))
{ {
// wire truncated = $signed(A) % $signed(B); // wire truncated = $signed(A) % $signed(B);
// assign Y = (A[-1] == B[-1]) || truncated == 0 ? $signed(truncated) : $signed(B) + $signed(truncated); // assign Y = (A[-1] == B[-1]) || truncated == 0 ? $signed(truncated) : $signed(B) + $signed(truncated);
@ -1378,7 +1378,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
} }
} }
if (cell->type == ID($shift)) if (cell->type == TW($shift))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1405,7 +1405,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($shiftx)) if (cell->type == TW($shiftx))
{ {
std::string temp_id = next_auto_id(); std::string temp_id = next_auto_id();
f << stringf("%s" "wire [%d:0] %s = ", indent, GetSize(cell->getPort(TW::A))-1, temp_id); f << stringf("%s" "wire [%d:0] %s = ", indent, GetSize(cell->getPort(TW::A))-1, temp_id);
@ -1425,7 +1425,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($mux)) if (cell->type == TW($mux))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1440,7 +1440,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($pmux)) if (cell->type == TW($pmux))
{ {
int width = cell->parameters[ID::WIDTH].as_int(); int width = cell->parameters[ID::WIDTH].as_int();
int s_width = cell->getPort(TW::S).size(); int s_width = cell->getPort(TW::S).size();
@ -1500,7 +1500,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($tribuf)) if (cell->type == TW($tribuf))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1512,7 +1512,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($slice)) if (cell->type == TW($slice))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1522,7 +1522,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($concat)) if (cell->type == TW($concat))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1534,7 +1534,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($lut)) if (cell->type == TW($lut))
{ {
f << stringf("%s" "assign ", indent); f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(TW::Y)); dump_sigspec(f, cell->getPort(TW::Y));
@ -1547,10 +1547,10 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($input_port), TW($output_port), TW($public)))
return true; return true;
if (cell->type == ID($connect)) if (cell->type == TW($connect))
{ {
int width = cell->getParam(ID::WIDTH).as_int() ; int width = cell->getParam(ID::WIDTH).as_int() ;
if (width == 1) { if (width == 1) {
@ -1794,7 +1794,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($assert), ID($assume), ID($cover))) if (cell->type.in(TW($assert), TW($assume), TW($cover)))
{ {
f << stringf("%s" "always%s if (", indent, systemverilog ? "_comb" : " @*"); f << stringf("%s" "always%s if (", indent, systemverilog ? "_comb" : " @*");
dump_sigspec(f, cell->getPort(TW::EN)); dump_sigspec(f, cell->getPort(TW::EN));
@ -1804,7 +1804,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type.in(ID($specify2), ID($specify3))) if (cell->type.in(TW($specify2), TW($specify3)))
{ {
f << stringf("%s" "specify\n%s ", indent, indent); f << stringf("%s" "specify\n%s ", indent, indent);
@ -1816,7 +1816,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
} }
f << "("; f << "(";
if (cell->type == ID($specify3) && cell->getParam(ID::EDGE_EN).as_bool()) if (cell->type == TW($specify3) && cell->getParam(ID::EDGE_EN).as_bool())
f << (cell->getParam(ID::EDGE_POL).as_bool() ? "posedge ": "negedge "); f << (cell->getParam(ID::EDGE_POL).as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort(TW::SRC)); dump_sigspec(f, cell->getPort(TW::SRC));
@ -1826,7 +1826,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
f << (cell->getParam(ID::SRC_DST_POL).as_bool() ? "+": "-"); f << (cell->getParam(ID::SRC_DST_POL).as_bool() ? "+": "-");
f << (cell->getParam(ID::FULL).as_bool() ? "*> ": "=> "); f << (cell->getParam(ID::FULL).as_bool() ? "*> ": "=> ");
if (cell->type == ID($specify3)) { if (cell->type == TW($specify3)) {
f << "("; f << "(";
dump_sigspec(f, cell->getPort(TW::DST)); dump_sigspec(f, cell->getPort(TW::DST));
f << " "; f << " ";
@ -1862,7 +1862,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($specrule)) if (cell->type == TW($specrule))
{ {
f << stringf("%s" "specify\n%s ", indent, indent); f << stringf("%s" "specify\n%s ", indent, indent);
@ -1898,7 +1898,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
f << ": "; f << ": ";
dump_const(f, cell->getParam(ID::T_LIMIT_MAX)); dump_const(f, cell->getParam(ID::T_LIMIT_MAX));
if (spec_type.in(ID($setuphold), ID($recrem), ID($fullskew))) { if (spec_type.in(TW($setuphold), TW($recrem), TW($fullskew))) {
f << ", "; f << ", ";
dump_const(f, cell->getParam(ID::T_LIMIT2_MIN)); dump_const(f, cell->getParam(ID::T_LIMIT2_MIN));
f << ": "; f << ": ";
@ -1914,7 +1914,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($print)) if (cell->type == TW($print))
{ {
// Sync $print cells are accumulated and handled in dump_module. // Sync $print cells are accumulated and handled in dump_module.
if (cell->getParam(ID::TRG_ENABLE).as_bool()) if (cell->getParam(ID::TRG_ENABLE).as_bool())
@ -1930,7 +1930,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true; return true;
} }
if (cell->type == ID($check)) if (cell->type == TW($check))
{ {
// Sync $check cells are accumulated and handled in dump_module. // Sync $check cells are accumulated and handled in dump_module.
if (cell->getParam(ID::TRG_ENABLE).as_bool()) if (cell->getParam(ID::TRG_ENABLE).as_bool())
@ -1974,7 +1974,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
// cells that exist only to hold metadata. If in the future that metadata // cells that exist only to hold metadata. If in the future that metadata
// should be exposed as part of the write_verilog output it should be // should be exposed as part of the write_verilog output it should be
// opt-in and/or represented as something else than a $scopeinfo cell. // opt-in and/or represented as something else than a $scopeinfo cell.
if (cell->type == ID($scopeinfo)) if (cell->type == TW($scopeinfo))
return; return;
// Handled by dump_memory // Handled by dump_memory
@ -2052,7 +2052,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
} }
} }
if (siminit && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(ID($ff), ID($_FF_))) { if (siminit && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(TW($ff), TW($_FF_))) {
std::stringstream ss; std::stringstream ss;
dump_reg_init(ss, cell->getPort(TW::Q)); dump_reg_init(ss, cell->getPort(TW::Q));
if (!ss.str().empty()) { if (!ss.str().empty()) {
@ -2089,9 +2089,9 @@ void dump_sync_effect(std::ostream &f, std::string indent, const RTLIL::SigSpec
dump_sigspec(f, cell->getPort(TW::EN)); dump_sigspec(f, cell->getPort(TW::EN));
f << stringf(") begin\n"); f << stringf(") begin\n");
if (cell->type == ID($print)) { if (cell->type == TW($print)) {
dump_cell_expr_print(f, indent + " ", cell); dump_cell_expr_print(f, indent + " ", cell);
} else if (cell->type == ID($check)) { } else if (cell->type == TW($check)) {
std::string flavor = cell->getParam(ID::FLAVOR).decode_string(); std::string flavor = cell->getParam(ID::FLAVOR).decode_string();
if (flavor == "assert" || flavor == "assume") { if (flavor == "assert" || flavor == "assume") {
Fmt fmt; Fmt fmt;
@ -2408,12 +2408,12 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
std::set<std::pair<RTLIL::Wire*,int>> reg_bits; std::set<std::pair<RTLIL::Wire*,int>> reg_bits;
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($print), ID($check)) && cell->getParam(ID::TRG_ENABLE).as_bool()) { if (cell->type.in(TW($print), TW($check)) && cell->getParam(ID::TRG_ENABLE).as_bool()) {
sync_effect_cells[make_pair(cell->getPort(TW::TRG), cell->getParam(ID::TRG_POLARITY))].push_back(cell); sync_effect_cells[make_pair(cell->getPort(TW::TRG), cell->getParam(ID::TRG_POLARITY))].push_back(cell);
continue; continue;
} }
if (!cell->is_builtin_ff() || !cell->hasPort(TW::Q) || cell->type.in(ID($ff), ID($_FF_))) if (!cell->is_builtin_ff() || !cell->hasPort(TW::Q) || cell->type.in(TW($ff), TW($_FF_)))
continue; continue;
RTLIL::SigSpec sig = cell->getPort(TW::Q); RTLIL::SigSpec sig = cell->getPort(TW::Q);

View File

@ -24,19 +24,19 @@ struct FunctionalDummyBackend : public Backend {
// write node functions // write node functions
for (auto node : ir) for (auto node : ir)
*f << " assign " << node.name().unescape() *f << " assign " << design->twines.unescaped_str(node.name())
<< " = " << node.to_string() << "\n"; << " = " << node.to_string() << "\n";
*f << "\n"; *f << "\n";
// write outputs and next state // write outputs and next state
for (auto output : ir.outputs()) for (auto output : ir.outputs())
*f << " " << output->kind.unescape() *f << " " << design->twines.unescaped_str(output->kind)
<< " " << output->name.unescape() << " " << design->twines.unescaped_str(output->name)
<< " = " << output->value().name().unescape() << "\n"; << " = " << design->twines.unescaped_str(output->value().name()) << "\n";
for (auto state : ir.states()) for (auto state : ir.states())
*f << " " << state->kind.unescape() *f << " " << design->twines.unescaped_str(state->kind)
<< " " << state->name.unescape() << " " << design->twines.unescaped_str(state->name)
<< " = " << state->next_value().name().unescape() << "\n"; << " = " << design->twines.unescaped_str(state->next_value().name()) << "\n";
} }
} }
} FunctionalDummyBackend; } FunctionalDummyBackend;

View File

@ -76,10 +76,10 @@ struct ConstEvalAig
ConstEvalAig(RTLIL::Module *module) : module(module) ConstEvalAig(RTLIL::Module *module) : module(module)
{ {
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
if (!yosys_celltypes.cell_known(it.second->type)) if (!yosys_celltypes.cell_known(it.second->type.ref()))
continue; continue;
for (auto &it2 : it.second->connections()) for (auto &it2 : it.second->connections())
if (yosys_celltypes.cell_output(it.second->type, it2.first)) { if (yosys_celltypes.cell_output(it.second->type.ref(), it2.first)) {
auto r = sig2driver.insert(std::make_pair(it2.second, it.second)); auto r = sig2driver.insert(std::make_pair(it2.second, it.second));
log_assert(r.second); log_assert(r.second);
} }
@ -138,7 +138,7 @@ struct ConstEvalAig
if (!inputs.count(sig_a)) if (!inputs.count(sig_a))
compute_deps(sig_a, inputs); compute_deps(sig_a, inputs);
if (cell->type == ID($_AND_)) { if (cell->type == TW($_AND_)) {
RTLIL::SigSpec sig_b = cell->getPort(TW::B); RTLIL::SigSpec sig_b = cell->getPort(TW::B);
sig2deps[sig_b].reserve(sig2deps[sig_b].size() + sig2deps[output].size()); // Reserve so that any invalidation sig2deps[sig_b].reserve(sig2deps[sig_b].size() + sig2deps[output].size()); // Reserve so that any invalidation
// that may occur does so here, and // that may occur does so here, and
@ -148,7 +148,7 @@ struct ConstEvalAig
if (!inputs.count(sig_b)) if (!inputs.count(sig_b))
compute_deps(sig_b, inputs); compute_deps(sig_b, inputs);
} }
else if (cell->type == ID($_NOT_)) { else if (cell->type == TW($_NOT_)) {
} }
else log_abort(); else log_abort();
} }
@ -164,11 +164,11 @@ struct ConstEvalAig
return false; return false;
RTLIL::State eval_ret = RTLIL::Sx; RTLIL::State eval_ret = RTLIL::Sx;
if (cell->type == ID($_NOT_)) { if (cell->type == TW($_NOT_)) {
if (sig_a == State::S0) eval_ret = State::S1; if (sig_a == State::S0) eval_ret = State::S1;
else if (sig_a == State::S1) eval_ret = State::S0; else if (sig_a == State::S1) eval_ret = State::S0;
} }
else if (cell->type == ID($_AND_)) { else if (cell->type == TW($_AND_)) {
if (sig_a == State::S0) { if (sig_a == State::S0) {
eval_ret = State::S0; eval_ret = State::S0;
goto eval_end; goto eval_end;
@ -504,7 +504,8 @@ void AigerReader::parse_xaiger()
uint32_t boxUniqueId = parse_xaiger_literal(f); uint32_t boxUniqueId = parse_xaiger_literal(f);
log_assert(boxUniqueId > 0); log_assert(boxUniqueId > 0);
uint32_t oldBoxNum = parse_xaiger_literal(f); uint32_t oldBoxNum = parse_xaiger_literal(f);
RTLIL::Cell* cell = module->addCell(Twine{stringf("$box%u", oldBoxNum)}, ID(stringf("$__boxid%u", boxUniqueId))); TwineRef _type = module->design->twines.add(Twine{stringf("$__boxid%u", boxUniqueId)});
RTLIL::Cell* cell = module->addCell(Twine{stringf("$box%u", oldBoxNum)}, _type);
cell->setPort(TW::I, SigSpec(State::S0, boxInputs)); cell->setPort(TW::I, SigSpec(State::S0, boxInputs));
cell->setPort(TW::O, SigSpec(State::S0, boxOutputs)); cell->setPort(TW::O, SigSpec(State::S0, boxOutputs));
cell->attributes[ID::abc9_box_seq] = oldBoxNum; cell->attributes[ID::abc9_box_seq] = oldBoxNum;
@ -836,7 +837,7 @@ void AigerReader::post_process()
wire->port_input = false; wire->port_input = false;
module->connect(wire, existing); module->connect(wire, existing);
} }
log_debug(" -> %s\n", escaped_s.unescape()); log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s));
} }
else { else {
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
@ -847,7 +848,7 @@ void AigerReader::post_process()
module->connect(wire, existing); module->connect(wire, existing);
wire->port_input = false; wire->port_input = false;
} }
log_debug(" -> %s\n", indexed_name.unescape()); log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name));
} }
if (wideports && !existing) { if (wideports && !existing) {
@ -883,7 +884,7 @@ void AigerReader::post_process()
module->connect(wire, existing); module->connect(wire, existing);
wire = existing; wire = existing;
} }
log_debug(" -> %s\n", escaped_s.unescape()); log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s));
} }
else { else {
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
@ -895,7 +896,7 @@ void AigerReader::post_process()
existing->port_output = true; existing->port_output = true;
module->connect(wire, existing); module->connect(wire, existing);
} }
log_debug(" -> %s\n", indexed_name.unescape()); log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name));
} }
if (wideports && !existing) { if (wideports && !existing) {
@ -913,7 +914,7 @@ void AigerReader::post_process()
else if (type == "box") { else if (type == "box") {
RTLIL::Cell* cell = module->cell(design->twines.lookup(stringf("$box%d", variable))); RTLIL::Cell* cell = module->cell(design->twines.lookup(stringf("$box%d", variable)));
if (!cell) if (!cell)
log_debug("Box %d (%s) no longer exists.\n", variable, escaped_s.unescape()); log_debug("Box %d (%s) no longer exists.\n", variable, design->twines.unescaped_str(escaped_s));
else else
module->rename(cell, design->twines.add(Twine{escaped_s.str()})); module->rename(cell, design->twines.add(Twine{escaped_s.str()}));
} }
@ -977,7 +978,7 @@ void AigerReader::post_process()
design->add(module); design->add(module);
for (auto cell : module->cells().to_vector()) { for (auto cell : module->cells().to_vector()) {
if (cell->type != ID($lut)) continue; if (cell->type != TW($lut)) continue;
auto y_port = cell->getPort(TW::Y).as_bit(); auto y_port = cell->getPort(TW::Y).as_bit();
if (y_port.wire->width == 1) if (y_port.wire->width == 1)
module->rename(cell, design->twines.add(Twine{stringf("$lut%s", design->twines.str(y_port.wire->meta_->name).c_str())})); module->rename(cell, design->twines.add(Twine{stringf("$lut%s", design->twines.str(y_port.wire->meta_->name).c_str())}));

View File

@ -28,7 +28,7 @@ uint32_t read_be32(std::istream &f) {
((uint32_t) f.get() << 8) | (uint32_t) f.get(); ((uint32_t) f.get() << 8) | (uint32_t) f.get();
} }
IdString read_idstring(std::istream &f) std::string read_idstring(std::istream &f)
{ {
std::string str; std::string str;
std::getline(f, str, '\0'); std::getline(f, str, '\0');
@ -61,14 +61,15 @@ struct Xaiger2Frontend : public Frontend {
void read_sc_mapping(std::istream *&f, std::string filename, std::vector<std::string> args, Design *design) void read_sc_mapping(std::istream *&f, std::string filename, std::vector<std::string> args, Design *design)
{ {
IdString module_name; std::optional<TwineRef> module_name;
TwineSearch search(&design->twines);
std::string map_filename; std::string map_filename;
size_t argidx; size_t argidx;
for (argidx = 2; argidx < args.size(); argidx++) { for (argidx = 2; argidx < args.size(); argidx++) {
std::string arg = args[argidx]; std::string arg = args[argidx];
if (arg == "-module_name" && argidx + 1 < args.size()) { if (arg == "-module_name" && argidx + 1 < args.size()) {
module_name = RTLIL::escape_id(args[++argidx]); module_name = search.find(RTLIL::escape_id(args[++argidx]));
continue; continue;
} }
if (arg == "-map2" && argidx + 1 < args.size()) { if (arg == "-map2" && argidx + 1 < args.size()) {
@ -81,12 +82,12 @@ struct Xaiger2Frontend : public Frontend {
if (map_filename.empty()) if (map_filename.empty())
log_error("A '-map2' argument is required\n"); log_error("A '-map2' argument is required\n");
if (module_name.empty()) if (!module_name)
log_error("A '-module_name' argument is required\n"); log_error("A '-module_name' argument is required\n");
Module *module = design->module(module_name); Module *module = design->module(*module_name);
if (!module) if (!module)
log_error("Module '%s' not found\n", module_name.unescape()); log_error("Module '%s' not found\n", design->twines.unescaped_str(*module_name));
std::ifstream map_file; std::ifstream map_file;
map_file.open(map_filename); map_file.open(map_filename);
@ -122,7 +123,6 @@ struct Xaiger2Frontend : public Frontend {
bits[1] = RTLIL::S1; bits[1] = RTLIL::S1;
std::string type; std::string type;
TwineSearch search(&design->twines);
while (map_file >> type) { while (map_file >> type) {
if (type == "pi") { if (type == "pi") {
int pi_idx; int pi_idx;
@ -159,7 +159,7 @@ struct Xaiger2Frontend : public Frontend {
} }
if (!def) if (!def)
log_error("Bad map file: no module found for box type '%s'\n", box->type.unescape()); log_error("Bad map file: no module found for box type '%s'\n", design->twines.unescaped_str(box->type_impl));
if (box_seq >= (int) boxes.size()) { if (box_seq >= (int) boxes.size()) {
boxes.resize(box_seq + 1); boxes.resize(box_seq + 1);
@ -265,22 +265,22 @@ struct Xaiger2Frontend : public Frontend {
struct MappingCell { struct MappingCell {
TwineRef type; TwineRef type;
RTLIL::IdString out; TwineRef out;
std::vector<TwineRef ins; std::vector<TwineRef> ins;
}; };
std::vector<MappingCell> cells; std::vector<MappingCell> cells;
cells.resize(no_cells); cells.resize(no_cells);
for (unsigned i = 0; i < no_cells; ++i) { for (unsigned i = 0; i < no_cells; ++i) {
auto &cell = cells[i]; auto &cell = cells[i];
cell.type = read_idstring(*f); cell.type = design->twines.add(Twine{read_idstring(*f)});
cell.out = read_idstring(*f); cell.out = design->twines.add(Twine{read_idstring(*f)});
uint32_t nins = read_be32(*f); uint32_t nins = read_be32(*f);
for (uint32_t j = 0; j < nins; j++) for (uint32_t j = 0; j < nins; j++)
cell.ins.push_back(read_idstring(*f)); cell.ins.push_back(design->twines.add(Twine{read_idstring(*f)}));
log_debug("M: Cell %s (out %s, ins", cell.type.unescape(), cell.out.unescape()); log_debug("M: Cell %s (out %s, ins", design->twines.str(cell.type).c_str(), design->twines.unescaped_str(cell.out));
for (auto in : cell.ins) for (auto in : cell.ins)
log_debug(" %s", in.unescape()); log_debug(" %s", design->twines.str(in).c_str());
log_debug(")\n"); log_debug(")\n");
} }
@ -294,13 +294,13 @@ struct Xaiger2Frontend : public Frontend {
auto &cell = cells[cell_id]; auto &cell = cells[cell_id];
Cell *instance = module->addCell(module->uniquify(design->twines.add(Twine{stringf("$sc%d", out_lit)})), cell.type); Cell *instance = module->addCell(module->uniquify(design->twines.add(Twine{stringf("$sc%d", out_lit)})), cell.type);
auto out_w = module->addWire(module->uniquify(design->twines.add(Twine{stringf("$lit%d", out_lit)}))); auto out_w = module->addWire(module->uniquify(design->twines.add(Twine{stringf("$lit%d", out_lit)})));
instance->setPort(design->twines.add(Twine{cell.out.str()}), out_w); instance->setPort(cell.out, out_w);
bits[out_lit] = out_w; bits[out_lit] = out_w;
for (auto in : cell.ins) { for (auto in : cell.ins) {
uint32_t in_lit = read_be32(*f); uint32_t in_lit = read_be32(*f);
log_assert(out_lit < bits.size()); log_assert(out_lit < bits.size());
log_assert(bits[in_lit] != RTLIL::Sm); log_assert(bits[in_lit] != RTLIL::Sm);
instance->setPort(design->twines.add(Twine{in.str()}), bits[in_lit]); instance->setPort(in, bits[in_lit]);
} }
} }
} else if (c == '\n') { } else if (c == '\n') {

View File

@ -1573,7 +1573,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule
for (auto w : intfmodule->wires()){ for (auto w : intfmodule->wires()){
auto loc = module_ast->location; auto loc = module_ast->location;
auto wire = std::make_unique<AstNode>(loc, AST_WIRE, std::make_unique<AstNode>(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); auto wire = std::make_unique<AstNode>(loc, AST_WIRE, std::make_unique<AstNode>(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true)));
std::string origname = w->name.unescape(); std::string origname = intfmodule->design->twines.unescaped_str(w->meta_->name);
std::string newname = intfname + "." + origname; std::string newname = intfname + "." + origname;
wire->str = newname; wire->str = newname;
if (modport != NULL) { if (modport != NULL) {
@ -1637,7 +1637,7 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdStr
RTLIL::Module *intfmodule = intf.second; RTLIL::Module *intfmodule = intf.second;
for (auto w : intfmodule->wires()){ for (auto w : intfmodule->wires()){
auto wire = std::make_unique<AstNode>(loc, AST_WIRE, std::make_unique<AstNode>(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); auto wire = std::make_unique<AstNode>(loc, AST_WIRE, std::make_unique<AstNode>(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true)));
std::string newname = w->name.unescape(); std::string newname = design->twines.unescaped_str(w->meta_->name);
newname = intfname + "." + newname; newname = intfname + "." + newname;
wire->str = newname; wire->str = newname;
new_ast->children.push_back(std::move(wire)); new_ast->children.push_back(std::move(wire));
@ -1698,7 +1698,7 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdStr
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
// This method is used to explode the interface when the interface is a port of the module (not instantiated inside) // This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool /*mayfail*/) TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool /*mayfail*/)
{ {
std::unique_ptr<AstNode> new_ast = NULL; std::unique_ptr<AstNode> new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast); std::string modname = derive_common(design, parameters, &new_ast);
@ -1731,11 +1731,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
// Iterate over all interfaces which are ports in this module: // Iterate over all interfaces which are ports in this module:
for(auto &intf : interfaces) { for(auto &intf : interfaces) {
RTLIL::Module * intfmodule = intf.second; RTLIL::Module * intfmodule = intf.second;
std::string intfname = intf.first.str(); std::string intfname = design->twines.str(intf.first);
// Check if a modport applies for the interface port: // Check if a modport applies for the interface port:
AstNode *modport = NULL; AstNode *modport = NULL;
if (modports.count(intfname) > 0) { if (modports.count(intf.first) > 0) {
std::string interface_modport = modports.at(intfname).str(); std::string interface_modport = design->twines.str(modports.at(intf.first));
AstModule *ast_module_of_interface = (AstModule*)intfmodule; AstModule *ast_module_of_interface = (AstModule*)intfmodule;
AstNode *ast_node_of_interface = ast_module_of_interface->ast.get(); AstNode *ast_node_of_interface = ast_module_of_interface->ast.get();
modport = find_modport(ast_node_of_interface, interface_modport); modport = find_modport(ast_node_of_interface, interface_modport);
@ -1751,7 +1751,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
// Now that the interfaces have been exploded, we can delete the dummy port related to every interface. // Now that the interfaces have been exploded, we can delete the dummy port related to every interface.
for(auto &intf : interfaces) { for(auto &intf : interfaces) {
TwineRef intf_name = design->twines.lookup(intf.first.str()); TwineRef intf_name = design->twines.lookup(design->twines.str(intf.first));
if(mod->wire(intf_name) != nullptr) { if(mod->wire(intf_name) != nullptr) {
// Normally, removing wires would be batched together as it's an // Normally, removing wires would be batched together as it's an
// expensive operation, however, in this case doing so would mean // expensive operation, however, in this case doing so would mean
@ -1764,7 +1764,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
mod->fixup_ports(); mod->fixup_ports();
// We copy the cell of the interface to the sub-module such that it // We copy the cell of the interface to the sub-module such that it
// can further be found if it is propagated down to sub-sub-modules etc. // can further be found if it is propagated down to sub-sub-modules etc.
RTLIL::Cell *new_subcell = mod->addCell(Twine{intf.first.str()}, RTLIL::IdString(design->twines.str(intf.second->meta_->name))); RTLIL::Cell *new_subcell = mod->addCell(intf.first, intf.second->meta_->name);
new_subcell->set_bool_attribute(ID::is_interface); new_subcell->set_bool_attribute(ID::is_interface);
} }
else { else {
@ -1782,11 +1782,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
log("Found cached RTLIL representation for module `%s'.\n", modname); log("Found cached RTLIL representation for module `%s'.\n", modname);
} }
return modname; return design->twines.add(Twine{modname});
} }
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/) TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/)
{ {
bool quiet = lib || attributes.count(ID::blackbox) || attributes.count(ID::whitebox); bool quiet = lib || attributes.count(ID::blackbox) || attributes.count(ID::whitebox);
@ -1802,7 +1802,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
log("Found cached RTLIL representation for module `%s'.\n", modname); log("Found cached RTLIL representation for module `%s'.\n", modname);
} }
return modname; return design->twines.add(Twine{modname});
} }
static std::string serialize_param_value(const RTLIL::Const &val) { static std::string serialize_param_value(const RTLIL::Const &val) {
@ -1979,11 +1979,11 @@ RTLIL::Module *AstModule::clone(RTLIL::Design *dst, bool src_id_verbatim) const
return new_mod; return new_mod;
} }
RTLIL::Module *AstModule::clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim) const RTLIL::Module *AstModule::clone(RTLIL::Design *dst, TwineRef target_name, bool src_id_verbatim) const
{ {
AstModule *new_mod = new AstModule; AstModule *new_mod = new AstModule;
new_mod->design = dst; new_mod->design = dst;
new_mod->meta_->name = dst->twines.add(Twine{target_name.str()}); new_mod->meta_->name = target_name;
cloneInto(new_mod, src_id_verbatim); cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod); dst->add(new_mod);

View File

@ -397,7 +397,7 @@ namespace AST
std::unique_ptr<AstNode> ast; std::unique_ptr<AstNode> ast;
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire; bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override; TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override;
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override; TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool mayfail) override;
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, std::unique_ptr<AstNode>* new_ast_out, bool quiet = false); std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, std::unique_ptr<AstNode>* new_ast_out, bool quiet = false);
void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override; void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
bool reprocess_if_necessary(RTLIL::Design *design) override; bool reprocess_if_necessary(RTLIL::Design *design) override;

View File

@ -27,6 +27,7 @@
*/ */
#include "kernel/log.h" #include "kernel/log.h"
#include "kernel/twine.h"
#include "kernel/utils.h" #include "kernel/utils.h"
#include "kernel/binding.h" #include "kernel/binding.h"
#include "libs/sha1/sha1.h" #include "libs/sha1/sha1.h"
@ -43,13 +44,13 @@ using namespace AST;
using namespace AST_INTERNAL; using namespace AST_INTERNAL;
// helper function for creating RTLIL code for unary operations // helper function for creating RTLIL code for unary operations
static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) static RTLIL::SigSpec uniop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{ {
IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type); RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, result_width); RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width);
set_src_attr(wire, that); set_src_attr(wire, that);
wire->is_signed = that->is_signed; wire->is_signed = that->is_signed;
@ -78,7 +79,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
} }
IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, ID($pos)); RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, TW::$pos);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, width); RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, width);
@ -102,13 +103,13 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
} }
// helper function for creating RTLIL code for binary operations // helper function for creating RTLIL code for binary operations
static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) static RTLIL::SigSpec binop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{ {
IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type); RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, result_width); RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width);
set_src_attr(wire, that); set_src_attr(wire, that);
wire->is_signed = that->is_signed; wire->is_signed = that->is_signed;
@ -140,7 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
std::stringstream sstr; std::stringstream sstr;
sstr << "$ternary$" << RTLIL::encode_filename(*that->location.begin.filename) << ":" << that->location.begin.line << "$" << (autoidx++); sstr << "$ternary$" << RTLIL::encode_filename(*that->location.begin.filename) << ":" << that->location.begin.line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($mux)); RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$mux);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, left.size()); RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, left.size());
@ -837,7 +838,7 @@ struct AST_INTERNAL::ProcessGenerator
} }
RTLIL::Const polarity = polarity_builder.build(); RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($print)); RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$print);
set_src_attr(cell, ast); set_src_attr(cell, ast);
cell->setParam(ID::TRG_WIDTH, triggers.size()); cell->setParam(ID::TRG_WIDTH, triggers.size());
cell->setParam(ID::TRG_ENABLE, (always->type == AST_INITIAL) || !triggers.empty()); cell->setParam(ID::TRG_ENABLE, (always->type == AST_INITIAL) || !triggers.empty());
@ -935,7 +936,7 @@ struct AST_INTERNAL::ProcessGenerator
} }
RTLIL::Const polarity = polarity_builder.build(); RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, ID($check)); RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, TW::$check);
set_src_attr(cell, ast); set_src_attr(cell, ast);
cell->set_bool_attribute(ID(keep)); cell->set_bool_attribute(ID(keep));
for (auto &attr : ast->attributes) { for (auto &attr : ast->attributes) {
@ -1443,7 +1444,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// Clifford's Device (http://www.clifford.at/cfun/cliffdev/). In this // Clifford's Device (http://www.clifford.at/cfun/cliffdev/). In this
// cases this variable is used to hold the type of the cell that should // cases this variable is used to hold the type of the cell that should
// be instantiated for this type of AST node. // be instantiated for this type of AST node.
IdString type_name; TwineRef type_name;
switch (type) switch (type)
{ {
@ -1735,7 +1736,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
if (GetSize(shift_val) >= 32) if (GetSize(shift_val) >= 32)
fake_ast->children[1]->is_signed = true; fake_ast->children[1]->is_signed = true;
RTLIL::SigSpec sig = binop2rtlil(fake_ast.get(), ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val); RTLIL::SigSpec sig = binop2rtlil(fake_ast.get(), TW($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val);
return sig; return sig;
} else { } else {
chunk.width = children[0]->range_left - children[0]->range_right + 1; chunk.width = children[0]->range_left - children[0]->range_right + 1;
@ -1841,9 +1842,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
input_error("Assignment pattern is only supported for whole unpacked array assignments.\n"); input_error("Assignment pattern is only supported for whole unpacked array assignments.\n");
// generate cells for unary operations: $not, $pos, $neg // generate cells for unary operations: $not, $pos, $neg
if (0) { case AST_BIT_NOT: type_name = ID($not); } if (0) { case AST_BIT_NOT: type_name = TW($not); }
if (0) { case AST_POS: type_name = ID($pos); } if (0) { case AST_POS: type_name = TW($pos); }
if (0) { case AST_NEG: type_name = ID($neg); } if (0) { case AST_NEG: type_name = TW($neg); }
{ {
RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint);
is_signed = children[0]->is_signed; is_signed = children[0]->is_signed;
@ -1856,10 +1857,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
// generate cells for binary operations: $and, $or, $xor, $xnor // generate cells for binary operations: $and, $or, $xor, $xnor
if (0) { case AST_BIT_AND: type_name = ID($and); } if (0) { case AST_BIT_AND: type_name = TW($and); }
if (0) { case AST_BIT_OR: type_name = ID($or); } if (0) { case AST_BIT_OR: type_name = TW($or); }
if (0) { case AST_BIT_XOR: type_name = ID($xor); } if (0) { case AST_BIT_XOR: type_name = TW($xor); }
if (0) { case AST_BIT_XNOR: type_name = ID($xnor); } if (0) { case AST_BIT_XNOR: type_name = TW($xnor); }
{ {
if (width_hint < 0) if (width_hint < 0)
detectSignWidth(width_hint, sign_hint); detectSignWidth(width_hint, sign_hint);
@ -1873,10 +1874,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
// generate cells for unary operations: $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor // generate cells for unary operations: $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor
if (0) { case AST_REDUCE_AND: type_name = ID($reduce_and); } if (0) { case AST_REDUCE_AND: type_name = TW($reduce_and); }
if (0) { case AST_REDUCE_OR: type_name = ID($reduce_or); } if (0) { case AST_REDUCE_OR: type_name = TW($reduce_or); }
if (0) { case AST_REDUCE_XOR: type_name = ID($reduce_xor); } if (0) { case AST_REDUCE_XOR: type_name = TW($reduce_xor); }
if (0) { case AST_REDUCE_XNOR: type_name = ID($reduce_xnor); } if (0) { case AST_REDUCE_XNOR: type_name = TW($reduce_xnor); }
{ {
RTLIL::SigSpec arg = children[0]->genRTLIL(); RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = uniop2rtlil(this, type_name, max(width_hint, 1), arg); RTLIL::SigSpec sig = uniop2rtlil(this, type_name, max(width_hint, 1), arg);
@ -1885,7 +1886,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// generate cells for unary operations: $reduce_bool // generate cells for unary operations: $reduce_bool
// (this is actually just an $reduce_or, but for clarity a different cell type is used) // (this is actually just an $reduce_or, but for clarity a different cell type is used)
if (0) { case AST_REDUCE_BOOL: type_name = ID($reduce_bool); } if (0) { case AST_REDUCE_BOOL: type_name = TW($reduce_bool); }
{ {
RTLIL::SigSpec arg = children[0]->genRTLIL(); RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, max(width_hint, 1), arg) : arg; RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, max(width_hint, 1), arg) : arg;
@ -1893,12 +1894,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
// generate cells for binary operations: $shl, $shr, $sshl, $sshr // generate cells for binary operations: $shl, $shr, $sshl, $sshr
if (0) { case AST_SHIFT_LEFT: type_name = ID($shl); } if (0) { case AST_SHIFT_LEFT: type_name = TW($shl); }
if (0) { case AST_SHIFT_RIGHT: type_name = ID($shr); } if (0) { case AST_SHIFT_RIGHT: type_name = TW($shr); }
if (0) { case AST_SHIFT_SLEFT: type_name = ID($sshl); } if (0) { case AST_SHIFT_SLEFT: type_name = TW($sshl); }
if (0) { case AST_SHIFT_SRIGHT: type_name = ID($sshr); } if (0) { case AST_SHIFT_SRIGHT: type_name = TW($sshr); }
if (0) { case AST_SHIFTX: type_name = ID($shiftx); } if (0) { case AST_SHIFTX: type_name = TW($shiftx); }
if (0) { case AST_SHIFT: type_name = ID($shift); } if (0) { case AST_SHIFT: type_name = TW($shift); }
{ {
if (width_hint < 0) if (width_hint < 0)
detectSignWidth(width_hint, sign_hint); detectSignWidth(width_hint, sign_hint);
@ -1923,19 +1924,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int width = width_hint > 0 ? width_hint : left.size(); int width = width_hint > 0 ? width_hint : left.size();
is_signed = children[0]->is_signed; is_signed = children[0]->is_signed;
if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed) if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed)
return binop2rtlil(this, ID($shl), width, RTLIL::SigSpec(1, left.size()), right); return binop2rtlil(this, TW($shl), width, RTLIL::SigSpec(1, left.size()), right);
return binop2rtlil(this, ID($pow), width, left, right); return binop2rtlil(this, TW($pow), width, left, right);
} }
// generate cells for binary operations: $lt, $le, $eq, $ne, $ge, $gt // generate cells for binary operations: $lt, $le, $eq, $ne, $ge, $gt
if (0) { case AST_LT: type_name = ID($lt); } if (0) { case AST_LT: type_name = TW($lt); }
if (0) { case AST_LE: type_name = ID($le); } if (0) { case AST_LE: type_name = TW($le); }
if (0) { case AST_EQ: type_name = ID($eq); } if (0) { case AST_EQ: type_name = TW($eq); }
if (0) { case AST_NE: type_name = ID($ne); } if (0) { case AST_NE: type_name = TW($ne); }
if (0) { case AST_EQX: type_name = ID($eqx); } if (0) { case AST_EQX: type_name = TW($eqx); }
if (0) { case AST_NEX: type_name = ID($nex); } if (0) { case AST_NEX: type_name = TW($nex); }
if (0) { case AST_GE: type_name = ID($ge); } if (0) { case AST_GE: type_name = TW($ge); }
if (0) { case AST_GT: type_name = ID($gt); } if (0) { case AST_GT: type_name = TW($gt); }
{ {
int width = max(width_hint, 1); int width = max(width_hint, 1);
width_hint = -1, sign_hint = true; width_hint = -1, sign_hint = true;
@ -1948,11 +1949,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
// generate cells for binary operations: $add, $sub, $mul, $div, $mod // generate cells for binary operations: $add, $sub, $mul, $div, $mod
if (0) { case AST_ADD: type_name = ID($add); } if (0) { case AST_ADD: type_name = TW($add); }
if (0) { case AST_SUB: type_name = ID($sub); } if (0) { case AST_SUB: type_name = TW($sub); }
if (0) { case AST_MUL: type_name = ID($mul); } if (0) { case AST_MUL: type_name = TW($mul); }
if (0) { case AST_DIV: type_name = ID($div); } if (0) { case AST_DIV: type_name = TW($div); }
if (0) { case AST_MOD: type_name = ID($mod); } if (0) { case AST_MOD: type_name = TW($mod); }
{ {
if (width_hint < 0) if (width_hint < 0)
detectSignWidth(width_hint, sign_hint); detectSignWidth(width_hint, sign_hint);
@ -1978,8 +1979,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} }
// generate cells for binary operations: $logic_and, $logic_or // generate cells for binary operations: $logic_and, $logic_or
if (0) { case AST_LOGIC_AND: type_name = ID($logic_and); } if (0) { case AST_LOGIC_AND: type_name = TW($logic_and); }
if (0) { case AST_LOGIC_OR: type_name = ID($logic_or); } if (0) { case AST_LOGIC_OR: type_name = TW($logic_or); }
{ {
RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec left = children[0]->genRTLIL();
RTLIL::SigSpec right = children[1]->genRTLIL(); RTLIL::SigSpec right = children[1]->genRTLIL();
@ -1990,7 +1991,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_LOGIC_NOT: case AST_LOGIC_NOT:
{ {
RTLIL::SigSpec arg = children[0]->genRTLIL(); RTLIL::SigSpec arg = children[0]->genRTLIL();
return uniop2rtlil(this, ID($logic_not), max(width_hint, 1), arg); return uniop2rtlil(this, TW($logic_not), max(width_hint, 1), arg);
} }
// generate multiplexer for ternary operator (aka ?:-operator) // generate multiplexer for ternary operator (aka ?:-operator)
@ -2021,7 +2022,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
if (cond.size() > 1) if (cond.size() > 1)
cond = uniop2rtlil(this, ID($reduce_bool), 1, cond, false); cond = uniop2rtlil(this, TW($reduce_bool), 1, cond, false);
int width = max(val1.size(), val2.size()); int width = max(val1.size(), val2.size());
log_assert(is_signed == children[1]->is_signed); log_assert(is_signed == children[1]->is_signed);
@ -2043,7 +2044,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr; std::stringstream sstr;
sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($memrd)); RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$memrd);
set_src_attr(cell, this); set_src_attr(cell, this);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_DATA"}, current_module->memories[current_module->design->twines.lookup(str)]->width); RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_DATA"}, current_module->memories[current_module->design->twines.lookup(str)]->width);
@ -2083,7 +2084,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
SigSpec en_sig = children[2]->genRTLIL(); SigSpec en_sig = children[2]->genRTLIL();
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($meminit_v2)); RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$meminit_v2);
set_src_attr(cell, this); set_src_attr(cell, this);
int mem_width, mem_size, addr_bits; int mem_width, mem_size, addr_bits;
@ -2133,7 +2134,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (GetSize(check) != 1) if (GetSize(check) != 1)
check = current_module->ReduceBool(NEW_TWINE, check); check = current_module->ReduceBool(NEW_TWINE, check);
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, ID($check)); RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, TW::$check);
set_src_attr(cell, this); set_src_attr(cell, this);
for (auto &attr : attributes) { for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT) if (attr.second->type != AST_CONSTANT)
@ -2185,7 +2186,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::IdString id = str; RTLIL::IdString id = str;
check_unique_id(current_module, id, this, "cell"); check_unique_id(current_module, id, this, "cell");
RTLIL::Cell *cell = current_module->addCell(Twine{id.str()}, ""); RTLIL::Cell *cell = current_module->addCell(Twine{id.str()}, Twine::Null);
set_src_attr(cell, this); set_src_attr(cell, this);
for (auto it = children.begin(); it != children.end(); it++) { for (auto it = children.begin(); it != children.end(); it++) {
@ -2202,10 +2203,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
const auto* value = child->children[0].get(); const auto* value = child->children[0].get();
if (value->type == AST_REALVALUE) if (value->type == AST_REALVALUE)
log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n", log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n",
cell, paraname.unescape(), value->realvalue); cell, design->twines.unescaped_str(paraname), value->realvalue);
else if (value->type != AST_CONSTANT) else if (value->type != AST_CONSTANT)
input_error("Parameter %s.%s with non-constant value!\n", input_error("Parameter %s.%s with non-constant value!\n",
cell, paraname.unescape()); cell, design->twines.unescaped_str(paraname));
cell->parameters[paraname] = value->asParaConst(); cell->parameters[paraname] = value->asParaConst();
continue; continue;
} }
@ -2260,7 +2261,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
input_error("Attribute `%s' with non-constant value.\n", attr.first); input_error("Attribute `%s' with non-constant value.\n", attr.first);
cell->attributes[attr.first] = attr.second->asAttrConst(); cell->attributes[attr.first] = attr.second->asAttrConst();
} }
if (cell->type == ID($specify2)) { if (cell->type == TW($specify2)) {
int src_width = GetSize(cell->getPort(TW::SRC)); int src_width = GetSize(cell->getPort(TW::SRC));
int dst_width = GetSize(cell->getPort(TW::DST)); int dst_width = GetSize(cell->getPort(TW::DST));
bool full = cell->getParam(ID::FULL).as_bool(); bool full = cell->getParam(ID::FULL).as_bool();
@ -2269,7 +2270,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
cell->setParam(ID::SRC_WIDTH, Const(src_width)); cell->setParam(ID::SRC_WIDTH, Const(src_width));
cell->setParam(ID::DST_WIDTH, Const(dst_width)); cell->setParam(ID::DST_WIDTH, Const(dst_width));
} }
else if (cell->type == ID($specify3)) { else if (cell->type == TW($specify3)) {
int dat_width = GetSize(cell->getPort(TW::DAT)); int dat_width = GetSize(cell->getPort(TW::DAT));
int dst_width = GetSize(cell->getPort(TW::DST)); int dst_width = GetSize(cell->getPort(TW::DST));
if (dat_width != dst_width) if (dat_width != dst_width)
@ -2278,7 +2279,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
cell->setParam(ID::SRC_WIDTH, Const(src_width)); cell->setParam(ID::SRC_WIDTH, Const(src_width));
cell->setParam(ID::DST_WIDTH, Const(dst_width)); cell->setParam(ID::DST_WIDTH, Const(dst_width));
} }
else if (cell->type == ID($specrule)) { else if (cell->type == TW($specrule)) {
int src_width = GetSize(cell->getPort(TW::SRC)); int src_width = GetSize(cell->getPort(TW::SRC));
int dst_width = GetSize(cell->getPort(TW::DST)); int dst_width = GetSize(cell->getPort(TW::DST));
cell->setParam(ID::SRC_WIDTH, Const(src_width)); cell->setParam(ID::SRC_WIDTH, Const(src_width));
@ -2356,7 +2357,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (width <= 0) if (width <= 0)
input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str)); input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str));
Cell *cell = current_module->addCell(Twine{myid}, str.substr(1)); TwineRef _type = current_module->design->twines.add(Twine{str.substr(1)});
Cell *cell = current_module->addCell(Twine{myid}, _type);
set_src_attr(cell, this); set_src_attr(cell, this);
cell->parameters[ID::WIDTH] = width; cell->parameters[ID::WIDTH] = width;

View File

@ -228,7 +228,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
vector<Cell*> remove_cells; vector<Cell*> remove_cells;
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type == ID($lut) && cell->getParam(ID::LUT) == buffer_lut) { if (cell->type == TW($lut) && cell->getParam(ID::LUT) == buffer_lut) {
module->connect(cell->getPort(TW::Y), cell->getPort(TW::A)); module->connect(cell->getPort(TW::Y), cell->getPort(TW::A));
remove_cells.push_back(cell); remove_cells.push_back(cell);
} }
@ -381,7 +381,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (dff_name.empty()) { if (dff_name.empty()) {
cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q)); cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q));
} else { } else {
cell = module->addCell(NEW_TWINE, dff_name); cell = module->addCell(NEW_TWINE, design->twines.add(Twine{dff_name.str()}));
cell->setPort(TW::D, blif_wire(d)); cell->setPort(TW::D, blif_wire(d));
cell->setPort(TW::Q, blif_wire(q)); cell->setPort(TW::Q, blif_wire(q));
} }
@ -400,7 +400,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
goto error; goto error;
IdString celltype = RTLIL::escape_id(p); IdString celltype = RTLIL::escape_id(p);
RTLIL::Cell *cell = module->addCell(NEW_TWINE, celltype); RTLIL::Cell *cell = module->addCell(NEW_TWINE, design->twines.add(Twine{celltype.str()}));
RTLIL::Module *cell_mod = design->module(celltype); RTLIL::Module *cell_mod = design->module(celltype);
dict<TwineRef, dict<int, SigBit>> cell_wideports_cache; dict<TwineRef, dict<int, SigBit>> cell_wideports_cache;
@ -542,7 +542,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
finished_parsing_constval: finished_parsing_constval:
if (state == RTLIL::State::Sa) if (state == RTLIL::State::Sa)
state = RTLIL::State::S0; state = RTLIL::State::S0;
if (output_sig.as_wire()->name == ID($undef)) if (output_sig.as_wire()->name == TW($undef))
state = RTLIL::State::Sx; state = RTLIL::State::Sx;
module->connect(RTLIL::SigSig(output_sig, state)); module->connect(RTLIL::SigSig(output_sig, state));
goto continue_without_read; goto continue_without_read;
@ -550,7 +550,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (sop_mode) if (sop_mode)
{ {
sopcell = module->addCell(NEW_TWINE, ID($sop)); sopcell = module->addCell(NEW_TWINE, TW::$sop);
sopcell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size()); sopcell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
sopcell->parameters[ID::DEPTH] = 0; sopcell->parameters[ID::DEPTH] = 0;
sopcell->parameters[ID::TABLE] = RTLIL::Const(); sopcell->parameters[ID::TABLE] = RTLIL::Const();
@ -566,7 +566,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
} }
else else
{ {
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($lut)); RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$lut);
cell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size()); cell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
cell->parameters[ID::LUT] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); cell->parameters[ID::LUT] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
cell->setPort(TW::A, input_sig); cell->setPort(TW::A, input_sig);

View File

@ -532,7 +532,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
IdString cell_type = RTLIL::escape_id(type_node->data_string.c_str()); IdString cell_type = RTLIL::escape_id(type_node->data_string.c_str());
Cell *cell = module->addCell(Twine{cell_name.str()}, cell_type); Cell *cell = module->addCell(Twine{cell_name.str()}, Twine{cell_type.str()});
if (cell_node->data_dict.count("connections") == 0) if (cell_node->data_dict.count("connections") == 0)
log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape()); log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape());

View File

@ -186,7 +186,7 @@ static RTLIL::SigSpec create_tristate(RTLIL::Module *module, RTLIL::SigSpec func
{ {
RTLIL::SigSpec three_state = parse_func_expr(module, three_state_expr); RTLIL::SigSpec three_state = parse_func_expr(module, three_state_expr);
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($tribuf)); RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$tribuf);
cell->setParam(ID::WIDTH, GetSize(func)); cell->setParam(ID::WIDTH, GetSize(func));
cell->setPort(TW::A, func); cell->setPort(TW::A, func);
cell->setPort(TW::EN, module->NotGate(NEW_TWINE, three_state)); cell->setPort(TW::EN, module->NotGate(NEW_TWINE, three_state));
@ -246,17 +246,17 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
rerun_invert_rollback = false; rerun_invert_rollback = false;
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == clk_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == clk_sig) {
clk_sig = it.second->getPort(TW::A); clk_sig = it.second->getPort(TW::A);
clk_polarity = !clk_polarity; clk_polarity = !clk_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
} }
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == clear_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == clear_sig) {
clear_sig = it.second->getPort(TW::A); clear_sig = it.second->getPort(TW::A);
clear_polarity = !clear_polarity; clear_polarity = !clear_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
} }
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == preset_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == preset_sig) {
preset_sig = it.second->getPort(TW::A); preset_sig = it.second->getPort(TW::A);
preset_polarity = !preset_polarity; preset_polarity = !preset_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
@ -271,7 +271,7 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
module->addNotGate(NEW_TWINE, q_sig, out_sig); module->addNotGate(NEW_TWINE, q_sig, out_sig);
} }
RTLIL::Cell* cell = module->addCell(NEW_TWINE, ""); RTLIL::Cell* cell = module->addCell(NEW_TWINE, Twine::Null);
cell->setPort(TW::D, data_sig); cell->setPort(TW::D, data_sig);
cell->setPort(TW::Q, q_sig); cell->setPort(TW::Q, q_sig);
cell->setPort(TW::C, clk_sig); cell->setPort(TW::C, clk_sig);
@ -355,17 +355,17 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
rerun_invert_rollback = false; rerun_invert_rollback = false;
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == enable_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == enable_sig) {
enable_sig = it.second->getPort(TW::A); enable_sig = it.second->getPort(TW::A);
enable_polarity = !enable_polarity; enable_polarity = !enable_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
} }
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == clear_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == clear_sig) {
clear_sig = it.second->getPort(TW::A); clear_sig = it.second->getPort(TW::A);
clear_polarity = !clear_polarity; clear_polarity = !clear_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
} }
if (it.second->type == ID($_NOT_) && it.second->getPort(TW::Y) == preset_sig) { if (it.second->type == TW($_NOT_) && it.second->getPort(TW::Y) == preset_sig) {
preset_sig = it.second->getPort(TW::A); preset_sig = it.second->getPort(TW::A);
preset_polarity = !preset_polarity; preset_polarity = !preset_polarity;
rerun_invert_rollback = true; rerun_invert_rollback = true;
@ -373,7 +373,7 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
} }
} }
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($_NOT_)); RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$_NOT_);
cell->setPort(TW::A, iq_sig); cell->setPort(TW::A, iq_sig);
cell->setPort(TW::Y, iqn_sig); cell->setPort(TW::Y, iqn_sig);
@ -384,7 +384,7 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
if (clear_polarity == true || clear_polarity != enable_polarity) if (clear_polarity == true || clear_polarity != enable_polarity)
{ {
RTLIL::Cell *inv = module->addCell(NEW_TWINE, ID($_NOT_)); RTLIL::Cell *inv = module->addCell(NEW_TWINE, TW::$_NOT_);
inv->setPort(TW::A, clear_sig); inv->setPort(TW::A, clear_sig);
inv->setPort(TW::Y, module->addWire(NEW_TWINE)); inv->setPort(TW::Y, module->addWire(NEW_TWINE));
@ -394,12 +394,12 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
clear_enable = inv->getPort(TW::Y); clear_enable = inv->getPort(TW::Y);
} }
RTLIL::Cell *data_gate = module->addCell(NEW_TWINE, ID($_AND_)); RTLIL::Cell *data_gate = module->addCell(NEW_TWINE, TW::$_AND_);
data_gate->setPort(TW::A, data_sig); data_gate->setPort(TW::A, data_sig);
data_gate->setPort(TW::B, clear_negative); data_gate->setPort(TW::B, clear_negative);
data_gate->setPort(TW::Y, data_sig = module->addWire(NEW_TWINE)); data_gate->setPort(TW::Y, data_sig = module->addWire(NEW_TWINE));
RTLIL::Cell *enable_gate = module->addCell(NEW_TWINE, enable_polarity ? ID($_OR_) : ID($_AND_)); RTLIL::Cell *enable_gate = module->addCell(NEW_TWINE, enable_polarity ? TW::$_OR_ : TW::$_AND_);
enable_gate->setPort(TW::A, enable_sig); enable_gate->setPort(TW::A, enable_sig);
enable_gate->setPort(TW::B, clear_enable); enable_gate->setPort(TW::B, clear_enable);
enable_gate->setPort(TW::Y, enable_sig = module->addWire(NEW_TWINE)); enable_gate->setPort(TW::Y, enable_sig = module->addWire(NEW_TWINE));
@ -412,7 +412,7 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
if (preset_polarity == false || preset_polarity != enable_polarity) if (preset_polarity == false || preset_polarity != enable_polarity)
{ {
RTLIL::Cell *inv = module->addCell(NEW_TWINE, ID($_NOT_)); RTLIL::Cell *inv = module->addCell(NEW_TWINE, TW::$_NOT_);
inv->setPort(TW::A, preset_sig); inv->setPort(TW::A, preset_sig);
inv->setPort(TW::Y, module->addWire(NEW_TWINE)); inv->setPort(TW::Y, module->addWire(NEW_TWINE));
@ -422,18 +422,19 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla
preset_enable = inv->getPort(TW::Y); preset_enable = inv->getPort(TW::Y);
} }
RTLIL::Cell *data_gate = module->addCell(NEW_TWINE, ID($_OR_)); RTLIL::Cell *data_gate = module->addCell(NEW_TWINE, TW::$_OR_);
data_gate->setPort(TW::A, data_sig); data_gate->setPort(TW::A, data_sig);
data_gate->setPort(TW::B, preset_positive); data_gate->setPort(TW::B, preset_positive);
data_gate->setPort(TW::Y, data_sig = module->addWire(NEW_TWINE)); data_gate->setPort(TW::Y, data_sig = module->addWire(NEW_TWINE));
RTLIL::Cell *enable_gate = module->addCell(NEW_TWINE, enable_polarity ? ID($_OR_) : ID($_AND_)); RTLIL::Cell *enable_gate = module->addCell(NEW_TWINE, enable_polarity ? TW::$_OR_ : TW::$_AND_);
enable_gate->setPort(TW::A, enable_sig); enable_gate->setPort(TW::A, enable_sig);
enable_gate->setPort(TW::B, preset_enable); enable_gate->setPort(TW::B, preset_enable);
enable_gate->setPort(TW::Y, enable_sig = module->addWire(NEW_TWINE)); enable_gate->setPort(TW::Y, enable_sig = module->addWire(NEW_TWINE));
} }
cell = module->addCell(NEW_TWINE, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); TwineRef _t = module->design->twines.add(Twine{stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')});
cell = module->addCell(NEW_TWINE, _t);
cell->setPort(TW::D, data_sig); cell->setPort(TW::D, data_sig);
cell->setPort(TW::Q, iq_sig); cell->setPort(TW::Q, iq_sig);
cell->setPort(TW::E, enable_sig); cell->setPort(TW::E, enable_sig);
@ -798,7 +799,7 @@ struct LibertyFrontend : public Frontend {
if (wi->port_input) { if (wi->port_input) {
for (auto wo : module->wires()) for (auto wo : module->wires())
if (wo->port_output) { if (wo->port_output) {
RTLIL::Cell *spec = module->addCell(NEW_TWINE, ID($specify2)); RTLIL::Cell *spec = module->addCell(NEW_TWINE, TW::$specify2);
spec->setParam(ID::SRC_WIDTH, wi->width); spec->setParam(ID::SRC_WIDTH, wi->width);
spec->setParam(ID::DST_WIDTH, wo->width); spec->setParam(ID::DST_WIDTH, wo->width);
spec->setParam(ID::T_FALL_MAX, 1000); spec->setParam(ID::T_FALL_MAX, 1000);

View File

@ -157,7 +157,7 @@ struct RpcServer {
struct RpcModule : RTLIL::Module { struct RpcModule : RTLIL::Module {
std::shared_ptr<RpcServer> server; std::shared_ptr<RpcServer> server;
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/) override { TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/) override {
std::string stripped_name = design->twines.str(meta_->name); std::string stripped_name = design->twines.str(meta_->name);
if (stripped_name.compare(0, 9, "$abstract") == 0) if (stripped_name.compare(0, 9, "$abstract") == 0)
stripped_name = stripped_name.substr(9); stripped_name = stripped_name.substr(9);
@ -215,7 +215,7 @@ struct RpcModule : RTLIL::Module {
log("Importing `%s' as `%s'.\n", derived_design->twines.str(module.first), mangled_name); log("Importing `%s' as `%s'.\n", derived_design->twines.str(module.first), mangled_name);
RTLIL::IdString original_name = RTLIL::IdString(derived_design->twines.str(module.first)); RTLIL::IdString original_name = RTLIL::IdString(derived_design->twines.str(module.first));
RTLIL::Module *t = module.second->clone(design, RTLIL::IdString(mangled_name)); RTLIL::Module *t = module.second->clone(design, design->twines.add(Twine{mangled_name}));
t->attributes.erase(ID::top); t->attributes.erase(ID::top);
if (!t->has_attribute(ID::hdlname)) if (!t->has_attribute(ID::hdlname))
t->set_string_attribute(ID::hdlname, original_name.str()); t->set_string_attribute(ID::hdlname, original_name.str());
@ -224,7 +224,7 @@ struct RpcModule : RTLIL::Module {
delete derived_design; delete derived_design;
} }
return derived_name; return design->twines.add(Twine{derived_name});
} }
RTLIL::Module *clone() const override { RTLIL::Module *clone() const override {

View File

@ -341,7 +341,7 @@ struct RTLILFrontendWorker {
error("No wires found for legalization"); error("No wires found for legalization");
int hash = hash_ops<RTLIL::IdString>::hash(id).yield(); int hash = hash_ops<RTLIL::IdString>::hash(id).yield();
RTLIL::Wire *wire = current_module->wire_at(abs(hash % wires_size)); RTLIL::Wire *wire = current_module->wire_at(abs(hash % wires_size));
log("Legalizing wire `%s' to `%s'.\n", id.unescape(), wire->name.unescape()); log("Legalizing wire `%s' to `%s'.\n", design->twines.unescaped_str(id), design->twines.unescaped_str(wire->name));
return wire; return wire;
} }
@ -748,7 +748,7 @@ struct RTLILFrontendWorker {
} else } else
error("RTLIL error: redefinition of cell %s.", cell_name_str); error("RTLIL error: redefinition of cell %s.", cell_name_str);
} }
RTLIL::Cell *cell = current_module->addCell(Twine{cell_name_str}, cell_type); RTLIL::Cell *cell = current_module->addCell(cell_name_ref, design->twines.add(Twine{cell_type.str()}));
cell->absorb_attrs(std::move(attrbuf)); cell->absorb_attrs(std::move(attrbuf));
while (true) while (true)

View File

@ -302,60 +302,60 @@ Aig::Aig(Cell *cell)
} }
} }
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_))) if (cell->type.in(TW($not), TW($_NOT_), TW($pos), TW($buf), TW($_BUF_)))
{ {
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) { for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(TW::A, i); int A = mk.inport(TW::A, i);
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; int Y = cell->type.in(TW($not), TW($_NOT_)) ? mk.not_gate(A) : A;
mk.outport(Y, TW::Y, i); mk.outport(Y, TW::Y, i);
} }
goto optimize; goto optimize;
} }
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($and), TW($_AND_), TW($_NAND_), TW($or), TW($_OR_), TW($_NOR_), TW($xor), TW($xnor), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_)))
{ {
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) { for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(TW::A, i); int A = mk.inport(TW::A, i);
int B = mk.inport(TW::B, i); int B = mk.inport(TW::B, i);
int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) : int Y = cell->type.in(TW($and), TW($_AND_)) ? mk.and_gate(A, B) :
cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) : cell->type.in(TW($_NAND_)) ? mk.nand_gate(A, B) :
cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) : cell->type.in(TW($or), TW($_OR_)) ? mk.or_gate(A, B) :
cell->type.in(ID($_NOR_)) ? mk.nor_gate(A, B) : cell->type.in(TW($_NOR_)) ? mk.nor_gate(A, B) :
cell->type.in(ID($xor), ID($_XOR_)) ? mk.xor_gate(A, B) : cell->type.in(TW($xor), TW($_XOR_)) ? mk.xor_gate(A, B) :
cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : cell->type.in(TW($xnor), TW($_XNOR_)) ? mk.xnor_gate(A, B) :
cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) : cell->type.in(TW($_ANDNOT_)) ? mk.andnot_gate(A, B) :
cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1; cell->type.in(TW($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
mk.outport(Y, TW::Y, i); mk.outport(Y, TW::Y, i);
} }
goto optimize; goto optimize;
} }
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_))) if (cell->type.in(TW($mux), TW($_MUX_), TW($_NMUX_)))
{ {
int S = mk.inport(TW::S); int S = mk.inport(TW::S);
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) { for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(TW::A, i); int A = mk.inport(TW::A, i);
int B = mk.inport(TW::B, i); int B = mk.inport(TW::B, i);
int Y = mk.mux_gate(A, B, S); int Y = mk.mux_gate(A, B, S);
if (cell->type == ID($_NMUX_)) if (cell->type == TW($_NMUX_))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport(Y, TW::Y, i); mk.outport(Y, TW::Y, i);
} }
goto optimize; goto optimize;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool)))
{ {
int Y = mk.inport(TW::A, 0); int Y = mk.inport(TW::A, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++) { for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++) {
int A = mk.inport(TW::A, i); int A = mk.inport(TW::A, i);
if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y); if (cell->type == TW($reduce_and)) Y = mk.and_gate(A, Y);
if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y); if (cell->type == TW($reduce_or)) Y = mk.or_gate(A, Y);
if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); if (cell->type == TW($reduce_bool)) Y = mk.or_gate(A, Y);
if (cell->type == ID($reduce_xor)) Y = mk.xor_gate(A, Y); if (cell->type == TW($reduce_xor)) Y = mk.xor_gate(A, Y);
if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y); if (cell->type == TW($reduce_xnor)) Y = mk.xor_gate(A, Y);
} }
if (cell->type == ID($reduce_xnor)) if (cell->type == TW($reduce_xnor))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport(Y, TW::Y, 0); mk.outport(Y, TW::Y, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++) for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
@ -363,31 +363,31 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or))) if (cell->type.in(TW($logic_not), TW($logic_and), TW($logic_or)))
{ {
int A = mk.inport(TW::A, 0), Y = -1; int A = mk.inport(TW::A, 0), Y = -1;
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++) for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++)
A = mk.or_gate(mk.inport(TW::A, i), A); A = mk.or_gate(mk.inport(TW::A, i), A);
if (cell->type.in(ID($logic_and), ID($logic_or))) { if (cell->type.in(TW($logic_and), TW($logic_or))) {
int B = mk.inport(TW::B, 0); int B = mk.inport(TW::B, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++) for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++)
B = mk.or_gate(mk.inport(TW::B, i), B); B = mk.or_gate(mk.inport(TW::B, i), B);
if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); if (cell->type == TW($logic_and)) Y = mk.and_gate(A, B);
if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B); if (cell->type == TW($logic_or)) Y = mk.or_gate(A, B);
} else { } else {
if (cell->type == ID($logic_not)) Y = mk.not_gate(A); if (cell->type == TW($logic_not)) Y = mk.not_gate(A);
} }
mk.outport_bool(Y, TW::Y); mk.outport_bool(Y, TW::Y);
goto optimize; goto optimize;
} }
if (cell->type.in(ID($add), ID($sub))) if (cell->type.in(TW($add), TW($sub)))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
vector<int> A = mk.inport_vec(TW::A, width); vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width); vector<int> B = mk.inport_vec(TW::B, width);
int carry = mk.bool_node(false); int carry = mk.bool_node(false);
if (cell->type == ID($sub)) { if (cell->type == TW($sub)) {
for (auto &n : B) for (auto &n : B)
n = mk.not_gate(n); n = mk.not_gate(n);
carry = mk.not_gate(carry); carry = mk.not_gate(carry);
@ -397,17 +397,17 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) if (cell->type.in(TW($lt), TW($gt), TW($le), TW($ge)))
{ {
int width = std::max(GetSize(cell->getPort(TW::A)), int width = std::max(GetSize(cell->getPort(TW::A)),
GetSize(cell->getPort(TW::B))) + 1; GetSize(cell->getPort(TW::B))) + 1;
vector<int> A = mk.inport_vec(TW::A, width); vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width); vector<int> B = mk.inport_vec(TW::B, width);
if (cell->type.in(ID($gt), ID($ge))) if (cell->type.in(TW($gt), TW($ge)))
std::swap(A, B); std::swap(A, B);
int carry = mk.bool_node(!cell->type.in(ID($le), ID($ge))); int carry = mk.bool_node(!cell->type.in(TW($le), TW($ge)));
for (auto &n : B) for (auto &n : B)
n = mk.not_gate(n); n = mk.not_gate(n);
vector<int> Y = mk.adder(A, B, carry); vector<int> Y = mk.adder(A, B, carry);
@ -417,7 +417,7 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type == ID($alu)) if (cell->type == TW($alu))
{ {
int width = GetSize(cell->getPort(TW::Y)); int width = GetSize(cell->getPort(TW::Y));
vector<int> A = mk.inport_vec(TW::A, width); vector<int> A = mk.inport_vec(TW::A, width);
@ -436,7 +436,7 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type.in(ID($eq), ID($ne))) if (cell->type.in(TW($eq), TW($ne)))
{ {
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B))); int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
vector<int> A = mk.inport_vec(TW::A, width); vector<int> A = mk.inport_vec(TW::A, width);
@ -444,13 +444,13 @@ Aig::Aig(Cell *cell)
int Y = mk.bool_node(false); int Y = mk.bool_node(false);
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i]));
if (cell->type == ID($eq)) if (cell->type == TW($eq))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport_bool(Y, TW::Y); mk.outport_bool(Y, TW::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($_AOI3_)) if (cell->type == TW($_AOI3_))
{ {
int A = mk.inport(TW::A); int A = mk.inport(TW::A);
int B = mk.inport(TW::B); int B = mk.inport(TW::B);
@ -460,7 +460,7 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type == ID($_OAI3_)) if (cell->type == TW($_OAI3_))
{ {
int A = mk.inport(TW::A); int A = mk.inport(TW::A);
int B = mk.inport(TW::B); int B = mk.inport(TW::B);
@ -470,7 +470,7 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type == ID($_AOI4_)) if (cell->type == TW($_AOI4_))
{ {
int A = mk.inport(TW::A); int A = mk.inport(TW::A);
int B = mk.inport(TW::B); int B = mk.inport(TW::B);
@ -482,7 +482,7 @@ Aig::Aig(Cell *cell)
goto optimize; goto optimize;
} }
if (cell->type == ID($_OAI4_)) if (cell->type == TW($_OAI4_))
{ {
int A = mk.inport(TW::A); int A = mk.inport(TW::A);
int B = mk.inport(TW::B); int B = mk.inport(TW::B);

View File

@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
bool is_signed = (cell->type != ID($buf)) && cell->getParam(ID::A_SIGNED).as_bool(); bool is_signed = (cell->type != TW($buf)) && cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(TW::A)); int a_width = GetSize(cell->getPort(TW::A));
int y_width = GetSize(cell->getPort(TW::Y)); int y_width = GetSize(cell->getPort(TW::Y));
@ -44,7 +44,7 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B)); int b_width = GetSize(cell->getPort(TW::B));
int y_width = GetSize(cell->getPort(TW::Y)); int y_width = GetSize(cell->getPort(TW::Y));
if (cell->type == ID($and) && !is_signed) { if (cell->type == TW($and) && !is_signed) {
if (a_width > b_width) if (a_width > b_width)
a_width = b_width; a_width = b_width;
else else
@ -86,7 +86,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B)); int b_width = GetSize(cell->getPort(TW::B));
int y_width = GetSize(cell->getPort(TW::Y)); int y_width = GetSize(cell->getPort(TW::Y));
if (!is_signed && cell->type != ID($sub)) { if (!is_signed && cell->type != TW($sub)) {
int ab_width = std::max(a_width, b_width); int ab_width = std::max(a_width, b_width);
y_width = std::min(y_width, ab_width+1); y_width = std::min(y_width, ab_width+1);
} }
@ -252,16 +252,16 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
// lowest position of A that can be moved to Y[i] // lowest position of A that can be moved to Y[i]
int a_range_lower; int a_range_lower;
if (cell->type.in(ID($shl), ID($sshl))) { if (cell->type.in(TW($shl), TW($sshl))) {
b_range_upper = a_width + b_high; b_range_upper = a_width + b_high;
if (is_signed) b_range_upper -= 1; if (is_signed) b_range_upper -= 1;
a_range_lower = max(0, i - b_high); a_range_lower = max(0, i - b_high);
a_range_upper = min(i+1, a_width); a_range_upper = min(i+1, a_width);
} else if (cell->type.in(ID($shr), ID($sshr)) || (cell->type.in(ID($shift), ID($shiftx)) && !is_b_signed)) { } else if (cell->type.in(TW($shr), TW($sshr)) || (cell->type.in(TW($shift), TW($shiftx)) && !is_b_signed)) {
b_range_upper = a_width; b_range_upper = a_width;
a_range_lower = min(i, a_width - 1); a_range_lower = min(i, a_width - 1);
a_range_upper = min(i+1 + b_high, a_width); a_range_upper = min(i+1 + b_high, a_width);
} else if (cell->type.in(ID($shift), ID($shiftx)) && is_b_signed) { } else if (cell->type.in(TW($shift), TW($shiftx)) && is_b_signed) {
// can go both ways depending on sign of B // can go both ways depending on sign of B
// 2's complement range is different depending on direction // 2's complement range is different depending on direction
b_range_upper = a_width - b_low; b_range_upper = a_width - b_low;
@ -284,7 +284,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int k = 0; k < b_width_capped; k++) { for (int k = 0; k < b_width_capped; k++) {
// left shifts // left shifts
if (cell->type.in(ID($shl), ID($sshl))) { if (cell->type.in(TW($shl), TW($sshl))) {
if (a_width == 1 && is_signed) { if (a_width == 1 && is_signed) {
int skip = 1 << (k + 1); int skip = 1 << (k + 1);
int base = skip -1; int base = skip -1;
@ -298,21 +298,21 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
db->add_edge(cell, TW::B, k, TW::Y, i, -1); db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} }
// right shifts // right shifts
} else if (cell->type.in(ID($shr), ID($sshr)) || (cell->type.in(ID($shift), ID($shiftx)) && !is_b_signed)) { } else if (cell->type.in(TW($shr), TW($sshr)) || (cell->type.in(TW($shift), TW($shiftx)) && !is_b_signed)) {
if (is_signed) { if (is_signed) {
bool shift_in_bulk = i < a_width - 1; bool shift_in_bulk = i < a_width - 1;
// can we jump into the zero-padding by toggling B[k]? // can we jump into the zero-padding by toggling B[k]?
bool zpad_jump = (((y_width - i) & ((1 << (k + 1)) - 1)) != 0 \ bool zpad_jump = (((y_width - i) & ((1 << (k + 1)) - 1)) != 0 \
&& (((y_width - i) & ~(1 << k)) < (1 << b_width_capped))); && (((y_width - i) & ~(1 << k)) < (1 << b_width_capped)));
if (shift_in_bulk || (cell->type.in(ID($shr), ID($shift), ID($shiftx)) && zpad_jump)) if (shift_in_bulk || (cell->type.in(TW($shr), TW($shift), TW($shiftx)) && zpad_jump))
db->add_edge(cell, TW::B, k, TW::Y, i, -1); db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else { } else {
if (i < a_width) if (i < a_width)
db->add_edge(cell, TW::B, k, TW::Y, i, -1); db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} }
// bidirectional shifts (positive B shifts right, negative left) // bidirectional shifts (positive B shifts right, negative left)
} else if (cell->type.in(ID($shift), ID($shiftx)) && is_b_signed) { } else if (cell->type.in(TW($shift), TW($shiftx)) && is_b_signed) {
if (is_signed) { if (is_signed) {
if (k != b_width_capped - 1) { if (k != b_width_capped - 1) {
bool r_shift_in_bulk = i < a_width - 1; bool r_shift_in_bulk = i < a_width - 1;
@ -344,7 +344,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
log_assert(cell->type == ID($mem_v2)); log_assert(cell->type == TW($mem_v2));
Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE); Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
int n_rd_ports = cell->getParam(ID::RD_PORTS).as_int(); int n_rd_ports = cell->getParam(ID::RD_PORTS).as_int();
int abits = cell->getParam(ID::ABITS).as_int(); int abits = cell->getParam(ID::ABITS).as_int();
@ -366,12 +366,12 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
log_assert(cell->type.in(ID($memrd), ID($memrd_v2))); log_assert(cell->type.in(TW($memrd), TW($memrd_v2)));
int abits = cell->getParam(ID::ABITS).as_int(); int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int(); int width = cell->getParam(ID::WIDTH).as_int();
if (cell->getParam(ID::CLK_ENABLE).as_bool()) { if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
if (cell->type == ID($memrd_v2)) { if (cell->type == TW($memrd_v2)) {
for (int k = 0; k < width; k++) for (int k = 0; k < width; k++)
db->add_edge(cell, TW::ARST, 0, TW::DATA, k, -1); db->add_edge(cell, TW::ARST, 0, TW::DATA, k, -1);
} }
@ -385,11 +385,11 @@ void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
if (cell->type == ID($mem_v2)) if (cell->type == TW($mem_v2))
packed_mem_op(db, cell); packed_mem_op(db, cell);
else if (cell->type.in(ID($memrd), ID($memrd_v2))) else if (cell->type.in(TW($memrd), TW($memrd_v2)))
memrd_op(db, cell); memrd_op(db, cell);
else if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit))) else if (cell->type.in(TW($memwr), TW($memwr_v2), TW($meminit)))
return; /* no edges here */ return; /* no edges here */
else else
log_abort(); log_abort();
@ -399,7 +399,7 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
int width = cell->getPort(TW::Q).size(); int width = cell->getPort(TW::Q).size();
if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { if (cell->type.in(TW($dlatch), TW($adlatch), TW($dlatchsr))) {
for (int k = 0; k < width; k++) { for (int k = 0; k < width; k++) {
db->add_edge(cell, TW::D, k, TW::Q, k, -1); db->add_edge(cell, TW::D, k, TW::Q, k, -1);
db->add_edge(cell, TW::EN, 0, TW::Q, k, -1); db->add_edge(cell, TW::EN, 0, TW::Q, k, -1);
@ -485,82 +485,82 @@ PRIVATE_NAMESPACE_END
bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)
{ {
if (cell->type.in(ID($not), ID($pos), ID($buf))) { if (cell->type.in(TW($not), TW($pos), TW($buf))) {
bitwise_unary_op(this, cell); bitwise_unary_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { if (cell->type.in(TW($and), TW($or), TW($xor), TW($xnor))) {
bitwise_binary_op(this, cell); bitwise_binary_op(this, cell);
return true; return true;
} }
if (cell->type == ID($neg)) { if (cell->type == TW($neg)) {
arith_neg_op(this, cell); arith_neg_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($add), ID($sub))) { if (cell->type.in(TW($add), TW($sub))) {
arith_binary_op(this, cell); arith_binary_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) { if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($logic_not))) {
reduce_op(this, cell); reduce_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($logic_and), ID($logic_or))) { if (cell->type.in(TW($logic_and), TW($logic_or))) {
logic_op(this, cell); logic_op(this, cell);
return true; return true;
} }
if (cell->type == ID($slice)) { if (cell->type == TW($slice)) {
slice_op(this, cell); slice_op(this, cell);
return true; return true;
} }
if (cell->type == ID($concat)) { if (cell->type == TW($concat)) {
concat_op(this, cell); concat_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx))) {
shift_op(this, cell); shift_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { if (cell->type.in(TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt))) {
compare_op(this, cell); compare_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($mux), ID($pmux))) { if (cell->type.in(TW($mux), TW($pmux))) {
mux_op(this, cell); mux_op(this, cell);
return true; return true;
} }
if (cell->type == ID($bmux)) { if (cell->type == TW($bmux)) {
bmux_op(this, cell); bmux_op(this, cell);
return true; return true;
} }
if (cell->type == ID($demux)) { if (cell->type == TW($demux)) {
demux_op(this, cell); demux_op(this, cell);
return true; return true;
} }
if (cell->type == ID($bweqx)) { if (cell->type == TW($bweqx)) {
bweqx_op(this, cell); bweqx_op(this, cell);
return true; return true;
} }
if (cell->type == ID($bwmux)) { if (cell->type == TW($bwmux)) {
bwmux_op(this, cell); bwmux_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit))) { if (cell->type.in(TW($mem_v2), TW($memrd), TW($memrd_v2), TW($memwr), TW($memwr_v2), TW($meminit))) {
mem_op(this, cell); mem_op(this, cell);
return true; return true;
} }
@ -570,21 +570,21 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true; return true;
} }
if (cell->type.in(ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) { if (cell->type.in(TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow))) {
full_op(this, cell); full_op(this, cell);
return true; return true;
} }
if (cell->type.in(ID($lut), ID($sop), ID($alu), ID($lcu), ID($macc), ID($macc_v2))) { if (cell->type.in(TW($lut), TW($sop), TW($alu), TW($lcu), TW($macc), TW($macc_v2))) {
full_op(this, cell); full_op(this, cell);
return true; return true;
} }
if (cell->type.in( if (cell->type.in(
ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), TW($_BUF_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_), TW($_MUX_), TW($_NMUX_),
ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), TW($_MUX4_), TW($_MUX8_), TW($_MUX16_), TW($_AOI3_), TW($_OAI3_), TW($_AOI4_),
ID($_OAI4_), ID($_TBUF_))) { TW($_OAI4_), TW($_TBUF_))) {
full_op(this, cell); full_op(this, cell);
return true; return true;
} }
@ -592,7 +592,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
// FIXME: $specify2 $specify3 $specrule ??? // FIXME: $specify2 $specify3 $specrule ???
// FIXME: $equiv $set_tag $get_tag $overwrite_tag $original_tag // FIXME: $equiv $set_tag $get_tag $overwrite_tag $original_tag
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($initstate), ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) if (cell->type.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover), TW($initstate), TW($anyconst), TW($anyseq), TW($allconst), TW($allseq)))
return true; // no-op: these have either no inputs or no outputs return true; // no-op: these have either no inputs or no outputs
return false; return false;

View File

@ -65,6 +65,11 @@ struct CellTypes
cell_types[ct.type] = ct; cell_types[ct.type] = ct;
} }
void setup_type(const std::string &type_str, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false)
{
setup_type(TW::lookup(type_str), inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable);
}
void setup_module(RTLIL::Module *module) void setup_module(RTLIL::Module *module)
{ {
pool<TwineRef> inputs, outputs; pool<TwineRef> inputs, outputs;
@ -230,77 +235,77 @@ struct CellTypes
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
setup_type(TW($1), {TW::S, TW::R}, {TW::Q}); setup_type(stringf("$_SR_%c%c_", c1, c2), {TW::S, TW::R}, {TW::Q});
setup_type(TW($_FF_), {TW::D}, {TW::Q}); setup_type(TW($_FF_), {TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
setup_type(TW($1), {TW::C, TW::D}, {TW::Q}); setup_type(stringf("$_DFF_%c_", c1), {TW::C, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
setup_type(TW($1), {TW::C, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_DFFE_%c%c_", c1, c2), {TW::C, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q}); setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
for (auto c4 : list_np) for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}); setup_type(stringf("$_ALDFF_%c%c_", c1, c2), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_ALDFFE_%c%c%c_", c1, c2, c3), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}); setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {TW::C, TW::S, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)
for (auto c4 : list_np) for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q}); setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
for (auto c4 : list_np) for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_SDFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
for (auto c4 : list_np) for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}); setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
setup_type(TW($1), {TW::E, TW::D}, {TW::Q}); setup_type(stringf("$_DLATCH_%c_", c1), {TW::E, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_01) for (auto c3 : list_01)
setup_type(TW($1), {TW::E, TW::R, TW::D}, {TW::Q}); setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {TW::E, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)
setup_type(TW($1), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}); setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {TW::E, TW::S, TW::R, TW::D}, {TW::Q});
} }
void clear() void clear()

View File

@ -49,10 +49,10 @@ struct ConstEval
ct.static_cell_types = StaticCellTypes::Compat::nomem_noff; ct.static_cell_types = StaticCellTypes::Compat::nomem_noff;
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
if (!ct.cell_known(it.second->type)) if (!ct.cell_known(it.second->type_impl))
continue; continue;
for (auto &it2 : it.second->connections()) for (auto &it2 : it.second->connections())
if (ct.cell_output(it.second->type, it2.first)) if (ct.cell_output(it.second->type_impl, it2.first))
sig2driver.insert(assign_map(it2.second), it.second); sig2driver.insert(assign_map(it2.second), it.second);
} }
} }
@ -93,7 +93,7 @@ struct ConstEval
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
{ {
if (cell->type == ID($lcu)) if (cell->type == TW($lcu))
{ {
RTLIL::SigSpec sig_p = cell->getPort(TW::P); RTLIL::SigSpec sig_p = cell->getPort(TW::P);
RTLIL::SigSpec sig_g = cell->getPort(TW::G); RTLIL::SigSpec sig_g = cell->getPort(TW::G);
@ -147,7 +147,7 @@ struct ConstEval
if (cell->hasPort(TW::B)) if (cell->hasPort(TW::B))
sig_b = cell->getPort(TW::B); sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_))) if (cell->type.in(TW($mux), TW($pmux), TW($_MUX_), TW($_NMUX_)))
{ {
std::vector<RTLIL::SigSpec> y_candidates; std::vector<RTLIL::SigSpec> y_candidates;
int count_set_s_bits = 0; int count_set_s_bits = 0;
@ -176,7 +176,7 @@ struct ConstEval
for (auto &yc : y_candidates) { for (auto &yc : y_candidates) {
if (!eval(yc, undef, cell)) if (!eval(yc, undef, cell))
return false; return false;
if (cell->type == ID($_NMUX_)) if (cell->type == TW($_NMUX_))
y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc)));
else else
y_values.push_back(yc.as_const()); y_values.push_back(yc.as_const());
@ -199,7 +199,7 @@ struct ConstEval
else else
set(sig_y, y_values.front()); set(sig_y, y_values.front());
} }
else if (cell->type == ID($bmux)) else if (cell->type == TW($bmux))
{ {
if (!eval(sig_s, undef, cell)) if (!eval(sig_s, undef, cell))
return false; return false;
@ -217,7 +217,7 @@ struct ConstEval
set(sig_y, const_bmux(sig_a.as_const(), sig_s.as_const())); set(sig_y, const_bmux(sig_a.as_const(), sig_s.as_const()));
} }
} }
else if (cell->type == ID($demux)) else if (cell->type == TW($demux))
{ {
if (!eval(sig_a, undef, cell)) if (!eval(sig_a, undef, cell))
return false; return false;
@ -229,7 +229,7 @@ struct ConstEval
set(sig_y, const_demux(sig_a.as_const(), sig_s.as_const())); set(sig_y, const_demux(sig_a.as_const(), sig_s.as_const()));
} }
} }
else if (cell->type == ID($fa)) else if (cell->type == TW($fa))
{ {
RTLIL::SigSpec sig_c = cell->getPort(TW::C); RTLIL::SigSpec sig_c = cell->getPort(TW::C);
RTLIL::SigSpec sig_x = cell->getPort(TW::X); RTLIL::SigSpec sig_x = cell->getPort(TW::X);
@ -258,7 +258,7 @@ struct ConstEval
set(sig_y, val_y); set(sig_y, val_y);
set(sig_x, val_x); set(sig_x, val_x);
} }
else if (cell->type == ID($alu)) else if (cell->type == TW($alu))
{ {
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool(); bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool(); bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
@ -314,7 +314,7 @@ struct ConstEval
} }
} }
} }
else if (cell->type.in(ID($macc), ID($macc_v2))) else if (cell->type.in(TW($macc), TW($macc_v2)))
{ {
Macc macc; Macc macc;
macc.from_cell(cell); macc.from_cell(cell);
@ -336,7 +336,7 @@ struct ConstEval
{ {
RTLIL::SigSpec sig_c, sig_d; RTLIL::SigSpec sig_c, sig_d;
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { if (cell->type.in(TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_))) {
if (cell->hasPort(TW::C)) if (cell->hasPort(TW::C))
sig_c = cell->getPort(TW::C); sig_c = cell->getPort(TW::C);
if (cell->hasPort(TW::D)) if (cell->hasPort(TW::D))

View File

@ -22,24 +22,24 @@ static unsigned int y_coef(TwineRef type)
{ {
if ( if (
// equality // equality
type.in(ID($bweqx), ID($nex), ID($eqx)) || type.in(TW($bweqx), TW($nex), TW($eqx)) ||
// basic logic // basic logic
type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($not)) || type.in(TW($and), TW($or), TW($xor), TW($xnor), TW($not)) ||
// mux // mux
type.in(ID($bwmux), ID($mux)) || type.in(TW($bwmux), TW($mux)) ||
// others // others
type == ID($tribuf)) { type == TW($tribuf)) {
return 1; return 1;
} else if (type == ID($neg)) { } else if (type == TW($neg)) {
return 4; return 4;
} else if (type == ID($demux)) { } else if (type == TW($demux)) {
return 2; return 2;
} else if (type == ID($fa)) { } else if (type == TW($fa)) {
return 5; return 5;
} else if (type.in(ID($add), ID($sub), ID($alu))) { } else if (type.in(TW($add), TW($sub), TW($alu))) {
// multi-bit adders // multi-bit adders
return 8; return 8;
} else if (type.in(ID($shl), ID($sshl))) { } else if (type.in(TW($shl), TW($sshl))) {
// left shift // left shift
return 10; return 10;
} }
@ -50,19 +50,19 @@ static unsigned int max_inp_coef(TwineRef type)
{ {
if ( if (
// binop reduce // binop reduce
type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)) || type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool)) ||
// others // others
type.in(ID($logic_not), ID($pmux), ID($bmux))) { type.in(TW($logic_not), TW($pmux), TW($bmux))) {
return 1; return 1;
} else if ( } else if (
// equality // equality
type.in(ID($eq), ID($ne)) || type.in(TW($eq), TW($ne)) ||
// logic // logic
type.in(ID($logic_and), ID($logic_or))) { type.in(TW($logic_and), TW($logic_or))) {
return 2; return 2;
} else if (type == ID($lcu)) { } else if (type == TW($lcu)) {
return 5; return 5;
} else if (type.in(ID($lt), ID($le), ID($ge), ID($gt))) { } else if (type.in(TW($lt), TW($le), TW($ge), TW($gt))) {
// comparison // comparison
return 7; return 7;
} }
@ -71,10 +71,10 @@ static unsigned int max_inp_coef(TwineRef type)
static unsigned int sum_coef(TwineRef type) static unsigned int sum_coef(TwineRef type)
{ {
if (type.in(ID($shr), ID($sshr))) { if (type.in(TW($shr), TW($sshr))) {
// right shift // right shift
return 4; return 4;
} else if (type.in(ID($shift), ID($shiftx))) { } else if (type.in(TW($shift), TW($shiftx))) {
// shift // shift
return 8; return 8;
} }
@ -83,23 +83,23 @@ static unsigned int sum_coef(TwineRef type)
static unsigned int is_div_mod(TwineRef type) static unsigned int is_div_mod(TwineRef type)
{ {
return (type == ID($div) || type == ID($divfloor) || type == ID($mod) || type == ID($modfloor)); return (type == TW($div) || type == TW($divfloor) || type == TW($mod) || type == TW($modfloor));
} }
static bool is_free(TwineRef type) static bool is_free(TwineRef type)
{ {
return ( return (
// tags // tags
type.in(ID($overwrite_tag), ID($set_tag), ID($original_tag), ID($get_tag)) || type.in(TW($overwrite_tag), TW($set_tag), TW($original_tag), TW($get_tag)) ||
// formal // formal
type.in(ID($check), ID($equiv), ID($initstate), ID($assert), ID($assume), ID($live), ID($cover), ID($fair)) || type.in(TW($check), TW($equiv), TW($initstate), TW($assert), TW($assume), TW($live), TW($cover), TW($fair)) ||
type.in(ID($allseq), ID($allconst), ID($anyseq), ID($anyconst), ID($anyinit)) || type.in(TW($allseq), TW($allconst), TW($anyseq), TW($anyconst), TW($anyinit)) ||
// utilities // utilities
type.in(ID($scopeinfo), ID($print)) || type.in(TW($scopeinfo), TW($print)) ||
// real but free // real but free
type.in(ID($concat), ID($slice), ID($pos)) || type.in(TW($concat), TW($slice), TW($pos)) ||
// specify // specify
type.in(ID($specrule), ID($specify2), ID($specify3))); type.in(TW($specrule), TW($specify2), TW($specify3)));
} }
unsigned int max_inp_width(RTLIL::Cell *cell) unsigned int max_inp_width(RTLIL::Cell *cell)
@ -112,7 +112,7 @@ unsigned int max_inp_width(RTLIL::Cell *cell)
ID::S_WIDTH, ID::S_WIDTH,
}; };
if (cell->type == ID($bmux)) if (cell->type == TW($bmux))
return cell->getParam(ID::WIDTH).as_int() << cell->getParam(ID::S_WIDTH).as_int(); return cell->getParam(ID::WIDTH).as_int() << cell->getParam(ID::S_WIDTH).as_int();
for (RTLIL::IdString param : input_width_params) for (RTLIL::IdString param : input_width_params)
@ -139,7 +139,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
{ {
// simple 1-bit cells // simple 1-bit cells
if (cmos_gate_cost().count(cell->type)) if (cmos_gate_cost().count(cell->type_impl))
return 1; return 1;
if (design_ && design_->module(cell->type) && cell->parameters.empty()) { if (design_ && design_->module(cell->type) && cell->parameters.empty()) {
@ -149,35 +149,35 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
log_assert(cell->hasPort(TW::Q) && "Weird flip flop"); log_assert(cell->hasPort(TW::Q) && "Weird flip flop");
log_debug("%s is ff\n", cell->name); log_debug("%s is ff\n", cell->name);
return cell->getParam(ID::WIDTH).as_int(); return cell->getParam(ID::WIDTH).as_int();
} else if (cell->type.in(ID($mem), ID($mem_v2))) { } else if (cell->type.in(TW($mem), TW($mem_v2))) {
log_debug("%s is mem\n", cell->name); log_debug("%s is mem\n", cell->name);
return cell->getParam(ID::WIDTH).as_int() * cell->getParam(ID::SIZE).as_int(); return cell->getParam(ID::WIDTH).as_int() * cell->getParam(ID::SIZE).as_int();
} else if (y_coef(cell->type)) { } else if (y_coef(cell->type.ref())) {
// linear with Y_WIDTH or WIDTH // linear with Y_WIDTH or WIDTH
log_assert((cell->hasParam(ID::Y_WIDTH) || cell->hasParam(ID::WIDTH)) && "Unknown width"); log_assert((cell->hasParam(ID::Y_WIDTH) || cell->hasParam(ID::WIDTH)) && "Unknown width");
auto param = cell->hasParam(ID::Y_WIDTH) ? ID::Y_WIDTH : ID::WIDTH; auto param = cell->hasParam(ID::Y_WIDTH) ? ID::Y_WIDTH : ID::WIDTH;
int width = cell->getParam(param).as_int(); int width = cell->getParam(param).as_int();
if (cell->type == ID($demux)) if (cell->type == TW($demux))
width <<= cell->getParam(ID::S_WIDTH).as_int(); width <<= cell->getParam(ID::S_WIDTH).as_int();
log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type)); log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type.ref()));
return width * y_coef(cell->type); return width * y_coef(cell->type.ref());
} else if (sum_coef(cell->type)) { } else if (sum_coef(cell->type.ref())) {
// linear with sum of port widths // linear with sum of port widths
unsigned int sum = port_width_sum(cell); unsigned int sum = port_width_sum(cell);
log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type)); log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type.ref()));
return sum * sum_coef(cell->type); return sum * sum_coef(cell->type.ref());
} else if (max_inp_coef(cell->type)) { } else if (max_inp_coef(cell->type.ref())) {
// linear with largest input width // linear with largest input width
unsigned int max = max_inp_width(cell); unsigned int max = max_inp_width(cell);
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type)); log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type.ref()));
return max * max_inp_coef(cell->type); return max * max_inp_coef(cell->type.ref());
} else if (is_div_mod(cell->type) || cell->type == ID($mul)) { } else if (is_div_mod(cell->type.ref()) || cell->type == TW($mul)) {
// quadratic with sum of port widths // quadratic with sum of port widths
unsigned int sum = port_width_sum(cell); unsigned int sum = port_width_sum(cell);
unsigned int coef = cell->type == ID($mul) ? 3 : 5; unsigned int coef = cell->type == TW($mul) ? 3 : 5;
log_debug("%s coef*(sum**2) %d * %d\n", cell->name, coef, sum * sum); log_debug("%s coef*(sum**2) %d * %d\n", cell->name, coef, sum * sum);
return coef * sum * sum; return coef * sum * sum;
} else if (cell->type.in(ID($macc), ID($macc_v2))) { } else if (cell->type.in(TW($macc), TW($macc_v2))) {
// quadratic per term // quadratic per term
unsigned int cost_sum = 0; unsigned int cost_sum = 0;
Macc macc; Macc macc;
@ -193,17 +193,17 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
cost_sum += 3 * sum * sum; cost_sum += 3 * sum * sum;
} }
return cost_sum; return cost_sum;
} else if (cell->type == ID($lut)) { } else if (cell->type == TW($lut)) {
int width = cell->getParam(ID::WIDTH).as_int(); int width = cell->getParam(ID::WIDTH).as_int();
unsigned int cost = 1U << (unsigned int)width; unsigned int cost = 1U << (unsigned int)width;
log_debug("%s is 2**%d\n", cell->name, width); log_debug("%s is 2**%d\n", cell->name, width);
return cost; return cost;
} else if (cell->type == ID($sop)) { } else if (cell->type == TW($sop)) {
int width = cell->getParam(ID::WIDTH).as_int(); int width = cell->getParam(ID::WIDTH).as_int();
int depth = cell->getParam(ID::DEPTH).as_int(); int depth = cell->getParam(ID::DEPTH).as_int();
log_debug("%s is (2*%d + 1)*%d\n", cell->name, width, depth); log_debug("%s is (2*%d + 1)*%d\n", cell->name, width, depth);
return (2 * width + 1) * depth; return (2 * width + 1) * depth;
} else if (is_free(cell->type)) { } else if (is_free(cell->type.ref())) {
log_debug("%s is free\n", cell->name); log_debug("%s is free\n", cell->name);
return 0; return 0;
} }

View File

@ -34,52 +34,52 @@ struct CellCosts
public: public:
CellCosts(RTLIL::Design *design) : design_(design) { } CellCosts(RTLIL::Design *design) : design_(design) { }
static const dict<RTLIL::IdString, int>& default_gate_cost() { static const dict<TwineRef, int>& default_gate_cost() {
// Default size heuristics for several common PDK standard cells // Default size heuristics for several common PDK standard cells
// used by abc and stat // used by abc and stat
static const dict<RTLIL::IdString, int> db = { static const dict<TwineRef, int> db = {
{ ID($_BUF_), 1 }, { TW($_BUF_), 1 },
{ ID($_NOT_), 2 }, { TW($_NOT_), 2 },
{ ID($_AND_), 4 }, { TW($_AND_), 4 },
{ ID($_NAND_), 4 }, { TW($_NAND_), 4 },
{ ID($_OR_), 4 }, { TW($_OR_), 4 },
{ ID($_NOR_), 4 }, { TW($_NOR_), 4 },
{ ID($_ANDNOT_), 4 }, { TW($_ANDNOT_), 4 },
{ ID($_ORNOT_), 4 }, { TW($_ORNOT_), 4 },
{ ID($_XOR_), 5 }, { TW($_XOR_), 5 },
{ ID($_XNOR_), 5 }, { TW($_XNOR_), 5 },
{ ID($_AOI3_), 6 }, { TW($_AOI3_), 6 },
{ ID($_OAI3_), 6 }, { TW($_OAI3_), 6 },
{ ID($_AOI4_), 7 }, { TW($_AOI4_), 7 },
{ ID($_OAI4_), 7 }, { TW($_OAI4_), 7 },
{ ID($_MUX_), 4 }, { TW($_MUX_), 4 },
{ ID($_NMUX_), 4 }, { TW($_NMUX_), 4 },
}; };
return db; return db;
} }
static const dict<RTLIL::IdString, int>& cmos_gate_cost() { static const dict<TwineRef, int>& cmos_gate_cost() {
// Estimated CMOS transistor counts for several common PDK standard cells // Estimated CMOS transistor counts for several common PDK standard cells
// used by stat and optionally by abc // used by stat and optionally by abc
static const dict<RTLIL::IdString, int> db = { static const dict<TwineRef, int> db = {
{ ID($_BUF_), 1 }, { TW($_BUF_), 1 },
{ ID($_NOT_), 2 }, { TW($_NOT_), 2 },
{ ID($_AND_), 6 }, { TW($_AND_), 6 },
{ ID($_NAND_), 4 }, { TW($_NAND_), 4 },
{ ID($_OR_), 6 }, { TW($_OR_), 6 },
{ ID($_NOR_), 4 }, { TW($_NOR_), 4 },
{ ID($_ANDNOT_), 6 }, { TW($_ANDNOT_), 6 },
{ ID($_ORNOT_), 6 }, { TW($_ORNOT_), 6 },
{ ID($_XOR_), 12 }, { TW($_XOR_), 12 },
{ ID($_XNOR_), 12 }, { TW($_XNOR_), 12 },
{ ID($_AOI3_), 6 }, { TW($_AOI3_), 6 },
{ ID($_OAI3_), 6 }, { TW($_OAI3_), 6 },
{ ID($_AOI4_), 8 }, { TW($_AOI4_), 8 },
{ ID($_OAI4_), 8 }, { TW($_OAI4_), 8 },
{ ID($_MUX_), 12 }, { TW($_MUX_), 12 },
{ ID($_NMUX_), 10 }, { TW($_NMUX_), 10 },
{ ID($_DFF_P_), 16 }, { TW($_DFF_P_), 16 },
{ ID($_DFF_N_), 16 }, { TW($_DFF_N_), 16 },
}; };
return db; return db;
} }

View File

@ -537,8 +537,8 @@ DriverMap::BitMode DriverMap::bit_mode(DriveBit const &bit)
} }
case DriveType::PORT: { case DriveType::PORT: {
auto const &port = bit.port(); auto const &port = bit.port();
bool driver = celltypes.cell_output(port.cell->type, port.port); bool driver = celltypes.cell_output(port.cell->type.ref(), port.port);
bool driven = celltypes.cell_input(port.cell->type, port.port); bool driven = celltypes.cell_input(port.cell->type.ref(), port.port);
if (driver && !driven) if (driver && !driven)
return BitMode::DRIVER; return BitMode::DRIVER;
else if (driven && !driver) else if (driven && !driver)
@ -866,7 +866,7 @@ DriveSpec DriverMap::operator()(DriveSpec spec)
std::string log_signal(DriveChunkWire const &chunk) std::string log_signal(DriveChunkWire const &chunk)
{ {
std::string id = chunk.wire->name.unescape(); std::string id = design->twines.unescaped_str(chunk.wire->name);
if (chunk.is_whole()) if (chunk.is_whole())
return id; return id;
if (chunk.width == 1) if (chunk.width == 1)

View File

@ -54,19 +54,19 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
std::string type_str = type.str(); std::string type_str = type.str();
if (type.in(ID($anyinit), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { if (type.in(TW($anyinit), TW($ff), TW($dff), TW($dffe), TW($dffsr), TW($dffsre), TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($sdff), TW($sdffe), TW($sdffce), TW($dlatch), TW($adlatch), TW($dlatchsr), TW($sr))) {
if (type.in(ID($anyinit), ID($ff))) { if (type.in(TW($anyinit), TW($ff))) {
info.has_gclk = true; info.has_gclk = true;
if constexpr (have_cell) if constexpr (have_cell)
info.sig_d = cell->getPort(TW::D); info.sig_d = cell->getPort(TW::D);
if (type == ID($anyinit)) { if (type == TW($anyinit)) {
info.is_anyinit = true; info.is_anyinit = true;
if constexpr (have_cell) if constexpr (have_cell)
log_assert(info.val_init.is_fully_undef()); log_assert(info.val_init.is_fully_undef());
} }
} else if (type == ID($sr)) { } else if (type == TW($sr)) {
// No data input at all. // No data input at all.
} else if (type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { } else if (type.in(TW($dlatch), TW($adlatch), TW($dlatchsr))) {
info.has_aload = true; info.has_aload = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_aload = cell->getPort(TW::EN); info.sig_aload = cell->getPort(TW::EN);
@ -81,14 +81,14 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.sig_d = cell->getPort(TW::D); info.sig_d = cell->getPort(TW::D);
} }
} }
if (type.in(ID($dffe), ID($dffsre), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce))) { if (type.in(TW($dffe), TW($dffsre), TW($adffe), TW($aldffe), TW($sdffe), TW($sdffce))) {
info.has_ce = true; info.has_ce = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_ce = cell->getPort(TW::EN); info.sig_ce = cell->getPort(TW::EN);
info.pol_ce = cell->getParam(ID::EN_POLARITY).as_bool(); info.pol_ce = cell->getParam(ID::EN_POLARITY).as_bool();
} }
} }
if (type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) { if (type.in(TW($dffsr), TW($dffsre), TW($dlatchsr), TW($sr))) {
info.has_sr = true; info.has_sr = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_clr = cell->getPort(TW::CLR); info.sig_clr = cell->getPort(TW::CLR);
@ -97,7 +97,7 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.pol_set = cell->getParam(ID::SET_POLARITY).as_bool(); info.pol_set = cell->getParam(ID::SET_POLARITY).as_bool();
} }
} }
if (type.in(ID($aldff), ID($aldffe))) { if (type.in(TW($aldff), TW($aldffe))) {
info.has_aload = true; info.has_aload = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_aload = cell->getPort(TW::ALOAD); info.sig_aload = cell->getPort(TW::ALOAD);
@ -105,7 +105,7 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.sig_ad = cell->getPort(TW::AD); info.sig_ad = cell->getPort(TW::AD);
} }
} }
if (type.in(ID($adff), ID($adffe), ID($adlatch))) { if (type.in(TW($adff), TW($adffe), TW($adlatch))) {
info.has_arst = true; info.has_arst = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_arst = cell->getPort(TW::ARST); info.sig_arst = cell->getPort(TW::ARST);
@ -113,16 +113,16 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.val_arst = cell->getParam(ID::ARST_VALUE); info.val_arst = cell->getParam(ID::ARST_VALUE);
} }
} }
if (type.in(ID($sdff), ID($sdffe), ID($sdffce))) { if (type.in(TW($sdff), TW($sdffe), TW($sdffce))) {
info.has_srst = true; info.has_srst = true;
if constexpr (have_cell) { if constexpr (have_cell) {
info.sig_srst = cell->getPort(TW::SRST); info.sig_srst = cell->getPort(TW::SRST);
info.pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool(); info.pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool();
info.val_srst = cell->getParam(ID::SRST_VALUE); info.val_srst = cell->getParam(ID::SRST_VALUE);
} }
info.ce_over_srst = type == ID($sdffce); info.ce_over_srst = type == TW($sdffce);
} }
} else if (type == ID($_FF_)) { } else if (type == TW($_FF_)) {
info.is_fine = true; info.is_fine = true;
info.has_gclk = true; info.has_gclk = true;
if constexpr (have_cell) if constexpr (have_cell)
@ -815,7 +815,7 @@ void FfData::flip_bits(const pool<int> &bits) {
Wire *new_q = module->addWire(NEW_TWINE, width); Wire *new_q = module->addWire(NEW_TWINE, width);
if (has_sr && cell) { if (has_sr && cell) {
log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", module->design->twines.str(module->meta_->name).c_str(), cell->module->design->twines.str(cell->meta_->name), cell->type.unescape()); log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", module->design->twines.str(module->meta_->name).c_str(), cell->name, cell->type.unescape());
} }
if (is_fine) { if (is_fine) {

View File

@ -67,7 +67,7 @@ const char *fn_to_string(Fn fn) {
log_error("fn_to_string: unknown Functional::Fn value %d", (int)fn); log_error("fn_to_string: unknown Functional::Fn value %d", (int)fn);
} }
vector<IRInput const*> IR::inputs(IdString kind) const { vector<IRInput const*> IR::inputs(TwineRef kind) const {
vector<IRInput const*> ret; vector<IRInput const*> ret;
for (const auto &[name, input] : _inputs) for (const auto &[name, input] : _inputs)
if(input.kind == kind) if(input.kind == kind)
@ -75,7 +75,7 @@ vector<IRInput const*> IR::inputs(IdString kind) const {
return ret; return ret;
} }
vector<IROutput const*> IR::outputs(IdString kind) const { vector<IROutput const*> IR::outputs(TwineRef kind) const {
vector<IROutput const*> ret; vector<IROutput const*> ret;
for (const auto &[name, output] : _outputs) for (const auto &[name, output] : _outputs)
if(output.kind == kind) if(output.kind == kind)
@ -83,7 +83,7 @@ vector<IROutput const*> IR::outputs(IdString kind) const {
return ret; return ret;
} }
vector<IRState const*> IR::states(IdString kind) const { vector<IRState const*> IR::states(TwineRef kind) const {
vector<IRState const*> ret; vector<IRState const*> ret;
for (const auto &[name, state] : _states) for (const auto &[name, state] : _states)
if(state.kind == kind) if(state.kind == kind)
@ -136,7 +136,7 @@ struct PrintVisitor : DefaultVisitor<std::string> {
std::string Node::to_string() std::string Node::to_string()
{ {
return to_string([](Node n) { return n.name().unescape(); }); return to_string([](Node n) { return design->twines.unescaped_str(n.name()); });
} }
std::string Node::to_string(std::function<std::string(Node)> np) std::string Node::to_string(std::function<std::string(Node)> np)
@ -253,87 +253,87 @@ public:
int y_width = parameters.at(ID(Y_WIDTH), Const(-1)).as_int(); int y_width = parameters.at(ID(Y_WIDTH), Const(-1)).as_int();
bool a_signed = parameters.at(ID(A_SIGNED), Const(0)).as_bool(); bool a_signed = parameters.at(ID(A_SIGNED), Const(0)).as_bool();
bool b_signed = parameters.at(ID(B_SIGNED), Const(0)).as_bool(); bool b_signed = parameters.at(ID(B_SIGNED), Const(0)).as_bool();
if(cellType.in(ID($add), ID($sub), ID($and), ID($or), ID($xor), ID($xnor), ID($mul))){ if(cellType.in(TW($add), TW($sub), TW($and), TW($or), TW($xor), TW($xnor), TW($mul))){
bool is_signed = a_signed && b_signed; bool is_signed = a_signed && b_signed;
Node a = factory.extend(inputs.at(TW::A), y_width, is_signed); Node a = factory.extend(inputs.at(TW::A), y_width, is_signed);
Node b = factory.extend(inputs.at(TW::B), y_width, is_signed); Node b = factory.extend(inputs.at(TW::B), y_width, is_signed);
if(cellType == ID($add)) if(cellType == TW($add))
return factory.add(a, b); return factory.add(a, b);
else if(cellType == ID($sub)) else if(cellType == TW($sub))
return factory.sub(a, b); return factory.sub(a, b);
else if(cellType == ID($mul)) else if(cellType == TW($mul))
return factory.mul(a, b); return factory.mul(a, b);
else if(cellType == ID($and)) else if(cellType == TW($and))
return factory.bitwise_and(a, b); return factory.bitwise_and(a, b);
else if(cellType == ID($or)) else if(cellType == TW($or))
return factory.bitwise_or(a, b); return factory.bitwise_or(a, b);
else if(cellType == ID($xor)) else if(cellType == TW($xor))
return factory.bitwise_xor(a, b); return factory.bitwise_xor(a, b);
else if(cellType == ID($xnor)) else if(cellType == TW($xnor))
return factory.bitwise_not(factory.bitwise_xor(a, b)); return factory.bitwise_not(factory.bitwise_xor(a, b));
else else
log_abort(); log_abort();
}else if(cellType.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($le), ID($lt), ID($ge), ID($gt))){ }else if(cellType.in(TW($eq), TW($ne), TW($eqx), TW($nex), TW($le), TW($lt), TW($ge), TW($gt))){
bool is_signed = a_signed && b_signed; bool is_signed = a_signed && b_signed;
int width = max(a_width, b_width); int width = max(a_width, b_width);
Node a = factory.extend(inputs.at(TW::A), width, is_signed); Node a = factory.extend(inputs.at(TW::A), width, is_signed);
Node b = factory.extend(inputs.at(TW::B), width, is_signed); Node b = factory.extend(inputs.at(TW::B), width, is_signed);
if(cellType.in(ID($eq), ID($eqx))) if(cellType.in(TW($eq), TW($eqx)))
return factory.extend(factory.equal(a, b), y_width, false); return factory.extend(factory.equal(a, b), y_width, false);
else if(cellType.in(ID($ne), ID($nex))) else if(cellType.in(TW($ne), TW($nex)))
return factory.extend(factory.not_equal(a, b), y_width, false); return factory.extend(factory.not_equal(a, b), y_width, false);
else if(cellType == ID($lt)) else if(cellType == TW($lt))
return factory.extend(is_signed ? factory.signed_greater_than(b, a) : factory.unsigned_greater_than(b, a), y_width, false); return factory.extend(is_signed ? factory.signed_greater_than(b, a) : factory.unsigned_greater_than(b, a), y_width, false);
else if(cellType == ID($le)) else if(cellType == TW($le))
return factory.extend(is_signed ? factory.signed_greater_equal(b, a) : factory.unsigned_greater_equal(b, a), y_width, false); return factory.extend(is_signed ? factory.signed_greater_equal(b, a) : factory.unsigned_greater_equal(b, a), y_width, false);
else if(cellType == ID($gt)) else if(cellType == TW($gt))
return factory.extend(is_signed ? factory.signed_greater_than(a, b) : factory.unsigned_greater_than(a, b), y_width, false); return factory.extend(is_signed ? factory.signed_greater_than(a, b) : factory.unsigned_greater_than(a, b), y_width, false);
else if(cellType == ID($ge)) else if(cellType == TW($ge))
return factory.extend(is_signed ? factory.signed_greater_equal(a, b) : factory.unsigned_greater_equal(a, b), y_width, false); return factory.extend(is_signed ? factory.signed_greater_equal(a, b) : factory.unsigned_greater_equal(a, b), y_width, false);
else else
log_abort(); log_abort();
}else if(cellType.in(ID($logic_or), ID($logic_and))){ }else if(cellType.in(TW($logic_or), TW($logic_and))){
Node a = factory.reduce_or(inputs.at(TW::A)); Node a = factory.reduce_or(inputs.at(TW::A));
Node b = factory.reduce_or(inputs.at(TW::B)); Node b = factory.reduce_or(inputs.at(TW::B));
Node y = cellType == ID($logic_and) ? factory.bitwise_and(a, b) : factory.bitwise_or(a, b); Node y = cellType == TW($logic_and) ? factory.bitwise_and(a, b) : factory.bitwise_or(a, b);
return factory.extend(y, y_width, false); return factory.extend(y, y_width, false);
}else if(cellType == ID($not)){ }else if(cellType == TW($not)){
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed); Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.bitwise_not(a); return factory.bitwise_not(a);
}else if(cellType == ID($pos)){ }else if(cellType == TW($pos)){
return factory.extend(inputs.at(TW::A), y_width, a_signed); return factory.extend(inputs.at(TW::A), y_width, a_signed);
}else if(cellType == ID($neg)){ }else if(cellType == TW($neg)){
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed); Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.unary_minus(a); return factory.unary_minus(a);
}else if(cellType == ID($logic_not)){ }else if(cellType == TW($logic_not)){
Node a = factory.reduce_or(inputs.at(TW::A)); Node a = factory.reduce_or(inputs.at(TW::A));
Node y = factory.bitwise_not(a); Node y = factory.bitwise_not(a);
return factory.extend(y, y_width, false); return factory.extend(y, y_width, false);
}else if(cellType.in(ID($reduce_or), ID($reduce_bool))){ }else if(cellType.in(TW($reduce_or), TW($reduce_bool))){
Node a = factory.reduce_or(inputs.at(TW::A)); Node a = factory.reduce_or(inputs.at(TW::A));
return factory.extend(a, y_width, false); return factory.extend(a, y_width, false);
}else if(cellType == ID($reduce_and)){ }else if(cellType == TW($reduce_and)){
Node a = factory.reduce_and(inputs.at(TW::A)); Node a = factory.reduce_and(inputs.at(TW::A));
return factory.extend(a, y_width, false); return factory.extend(a, y_width, false);
}else if(cellType.in(ID($reduce_xor), ID($reduce_xnor))){ }else if(cellType.in(TW($reduce_xor), TW($reduce_xnor))){
Node a = factory.reduce_xor(inputs.at(TW::A)); Node a = factory.reduce_xor(inputs.at(TW::A));
Node y = cellType == ID($reduce_xnor) ? factory.bitwise_not(a) : a; Node y = cellType == TW($reduce_xnor) ? factory.bitwise_not(a) : a;
return factory.extend(y, y_width, false); return factory.extend(y, y_width, false);
}else if(cellType == ID($shl) || cellType == ID($sshl)){ }else if(cellType == TW($shl) || cellType == TW($sshl)){
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed); Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
return logical_shift_left(a, b); return logical_shift_left(a, b);
}else if(cellType == ID($shr) || cellType == ID($sshr)){ }else if(cellType == TW($shr) || cellType == TW($sshr)){
int width = max(a_width, y_width); int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(TW::A), width, a_signed); Node a = factory.extend(inputs.at(TW::A), width, a_signed);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
Node y = a_signed && cellType == ID($sshr) ? Node y = a_signed && cellType == TW($sshr) ?
arithmetic_shift_right(a, b) : arithmetic_shift_right(a, b) :
logical_shift_right(a, b); logical_shift_right(a, b);
return factory.extend(y, y_width, a_signed); return factory.extend(y, y_width, a_signed);
}else if(cellType == ID($shiftx) || cellType == ID($shift)){ }else if(cellType == TW($shiftx) || cellType == TW($shift)){
int width = max(a_width, y_width); int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(TW::A), width, cellType == ID($shift) && a_signed); Node a = factory.extend(inputs.at(TW::A), width, cellType == TW($shift) && a_signed);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
Node shr = logical_shift_right(a, b); Node shr = logical_shift_right(a, b);
if(b_signed) { if(b_signed) {
@ -343,35 +343,35 @@ public:
} else { } else {
return factory.extend(shr, y_width, false); return factory.extend(shr, y_width, false);
} }
}else if(cellType == ID($mux)){ }else if(cellType == TW($mux)){
return factory.mux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S)); return factory.mux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($pmux)){ }else if(cellType == TW($pmux)){
return handle_pmux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S)); return handle_pmux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($concat)){ }else if(cellType == TW($concat)){
Node a = inputs.at(TW::A); Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
return factory.concat(a, b); return factory.concat(a, b);
}else if(cellType == ID($slice)){ }else if(cellType == TW($slice)){
int offset = parameters.at(ID(OFFSET)).as_int(); int offset = parameters.at(ID(OFFSET)).as_int();
Node a = inputs.at(TW::A); Node a = inputs.at(TW::A);
return factory.slice(a, offset, y_width); return factory.slice(a, offset, y_width);
}else if(cellType.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { }else if(cellType.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
int width = max(a_width, b_width); int width = max(a_width, b_width);
bool is_signed = a_signed && b_signed; bool is_signed = a_signed && b_signed;
Node a = factory.extend(inputs.at(TW::A), width, is_signed); Node a = factory.extend(inputs.at(TW::A), width, is_signed);
Node b = factory.extend(inputs.at(TW::B), width, is_signed); Node b = factory.extend(inputs.at(TW::B), width, is_signed);
if(is_signed) { if(is_signed) {
if(cellType == ID($div)) { if(cellType == TW($div)) {
// divide absolute values, then flip the sign if input signs differ // divide absolute values, then flip the sign if input signs differ
// but extend the width first, to handle the case (most negative value) / (-1) // but extend the width first, to handle the case (most negative value) / (-1)
Node abs_y = factory.unsigned_div(abs(a), abs(b)); Node abs_y = factory.unsigned_div(abs(a), abs(b));
Node out_sign = factory.not_equal(sign(a), sign(b)); Node out_sign = factory.not_equal(sign(a), sign(b));
return neg_if(factory.extend(abs_y, y_width, false), out_sign); return neg_if(factory.extend(abs_y, y_width, false), out_sign);
} else if(cellType == ID($mod)) { } else if(cellType == TW($mod)) {
// similar to division but output sign == divisor sign // similar to division but output sign == divisor sign
Node abs_y = factory.unsigned_mod(abs(a), abs(b)); Node abs_y = factory.unsigned_mod(abs(a), abs(b));
return neg_if(factory.extend(abs_y, y_width, false), sign(a)); return neg_if(factory.extend(abs_y, y_width, false), sign(a));
} else if(cellType == ID($divfloor)) { } else if(cellType == TW($divfloor)) {
// if b is negative, flip both signs so that b is positive // if b is negative, flip both signs so that b is positive
Node b_sign = sign(b); Node b_sign = sign(b);
Node a1 = neg_if(a, b_sign); Node a1 = neg_if(a, b_sign);
@ -385,7 +385,7 @@ public:
Node y1 = factory.unsigned_div(a2, b1); Node y1 = factory.unsigned_div(a2, b1);
Node y2 = factory.extend(y1, y_width, false); Node y2 = factory.extend(y1, y_width, false);
return factory.mux(y2, factory.bitwise_not(y2), a1_sign); return factory.mux(y2, factory.bitwise_not(y2), a1_sign);
} else if(cellType == ID($modfloor)) { } else if(cellType == TW($modfloor)) {
// calculate |a| % |b| and then subtract from |b| if input signs differ and the remainder is non-zero // calculate |a| % |b| and then subtract from |b| if input signs differ and the remainder is non-zero
Node abs_b = abs(b); Node abs_b = abs(b);
Node abs_y = factory.unsigned_mod(abs(a), abs_b); Node abs_y = factory.unsigned_mod(abs(a), abs_b);
@ -397,34 +397,34 @@ public:
} else } else
log_error("unhandled cell in CellSimplifier %s\n", cellType); log_error("unhandled cell in CellSimplifier %s\n", cellType);
} else { } else {
if(cellType.in(ID($mod), ID($modfloor))) if(cellType.in(TW($mod), TW($modfloor)))
return factory.extend(factory.unsigned_mod(a, b), y_width, false); return factory.extend(factory.unsigned_mod(a, b), y_width, false);
else else
return factory.extend(factory.unsigned_div(a, b), y_width, false); return factory.extend(factory.unsigned_div(a, b), y_width, false);
} }
} else if(cellType == ID($pow)) { } else if(cellType == TW($pow)) {
return handle_pow(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed); return handle_pow(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed);
} else if (cellType == ID($lut)) { } else if (cellType == TW($lut)) {
int width = parameters.at(ID(WIDTH)).as_int(); int width = parameters.at(ID(WIDTH)).as_int();
Const lut_table = parameters.at(ID(LUT)); Const lut_table = parameters.at(ID(LUT));
lut_table.extu(1 << width); lut_table.extu(1 << width);
return handle_bmux(factory.constant(lut_table), inputs.at(TW::A), 0, 1, width); return handle_bmux(factory.constant(lut_table), inputs.at(TW::A), 0, 1, width);
} else if (cellType == ID($bwmux)) { } else if (cellType == TW($bwmux)) {
Node a = inputs.at(TW::A); Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
Node s = inputs.at(TW::S); Node s = inputs.at(TW::S);
return factory.bitwise_or( return factory.bitwise_or(
factory.bitwise_and(a, factory.bitwise_not(s)), factory.bitwise_and(a, factory.bitwise_not(s)),
factory.bitwise_and(b, s)); factory.bitwise_and(b, s));
} else if (cellType == ID($bweqx)) { } else if (cellType == TW($bweqx)) {
Node a = inputs.at(TW::A); Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B); Node b = inputs.at(TW::B);
return factory.bitwise_not(factory.bitwise_xor(a, b)); return factory.bitwise_not(factory.bitwise_xor(a, b));
} else if(cellType == ID($bmux)) { } else if(cellType == TW($bmux)) {
int width = parameters.at(ID(WIDTH)).as_int(); int width = parameters.at(ID(WIDTH)).as_int();
int s_width = parameters.at(ID(S_WIDTH)).as_int(); int s_width = parameters.at(ID(S_WIDTH)).as_int();
return handle_bmux(inputs.at(TW::A), inputs.at(TW::S), 0, width, s_width); return handle_bmux(inputs.at(TW::A), inputs.at(TW::S), 0, width, s_width);
} else if(cellType == ID($demux)) { } else if(cellType == TW($demux)) {
int width = parameters.at(ID(WIDTH)).as_int(); int width = parameters.at(ID(WIDTH)).as_int();
int s_width = parameters.at(ID(S_WIDTH)).as_int(); int s_width = parameters.at(ID(S_WIDTH)).as_int();
int y_width = width << s_width; int y_width = width << s_width;
@ -433,31 +433,31 @@ public:
Node s = factory.extend(inputs.at(TW::S), b_width, false); Node s = factory.extend(inputs.at(TW::S), b_width, false);
Node b = factory.mul(s, factory.constant(Const(width, b_width))); Node b = factory.mul(s, factory.constant(Const(width, b_width)));
return factory.logical_shift_left(a, b); return factory.logical_shift_left(a, b);
} else if(cellType == ID($fa)) { } else if(cellType == TW($fa)) {
return handle_fa(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::C)); return handle_fa(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::C));
} else if(cellType == ID($lcu)) { } else if(cellType == TW($lcu)) {
return handle_lcu(inputs.at(TW::P), inputs.at(TW::G), inputs.at(TW::CI)); return handle_lcu(inputs.at(TW::P), inputs.at(TW::G), inputs.at(TW::CI));
} else if(cellType == ID($alu)) { } else if(cellType == TW($alu)) {
return handle_alu(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed, inputs.at(TW::CI), inputs.at(TW::BI)); return handle_alu(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed, inputs.at(TW::CI), inputs.at(TW::BI));
} else if(cellType.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) { } else if(cellType.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover))) {
Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(TW::A), inputs.at(TW::EN)); Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(TW::A), inputs.at(TW::EN));
auto &output = factory.add_output(cellName, cellType, Sort(1)); auto &output = factory.add_output(cellName, cellType, Sort(1));
output.set_value(a); output.set_value(a);
return {}; return {};
} else if(cellType.in(ID($anyconst), ID($allconst), ID($anyseq), ID($allseq))) { } else if(cellType.in(TW($anyconst), TW($allconst), TW($anyseq), TW($allseq))) {
int width = parameters.at(ID(WIDTH)).as_int(); int width = parameters.at(ID(WIDTH)).as_int();
auto &input = factory.add_input(cellName, cellType, Sort(width)); auto &input = factory.add_input(cellName, cellType, Sort(width));
return factory.value(input); return factory.value(input);
} else if(cellType == ID($initstate)) { } else if(cellType == TW($initstate)) {
if(factory.ir().has_state(ID($initstate), ID($state))) if(factory.ir().has_state(TW($initstate), TW($state)))
return factory.value(factory.ir().state(ID($initstate))); return factory.value(factory.ir().state(TW($initstate)));
else { else {
auto &state = factory.add_state(ID($initstate), ID($state), Sort(1)); auto &state = factory.add_state(TW($initstate), TW($state), Sort(1));
state.set_initial_value(RTLIL::Const(State::S1, 1)); state.set_initial_value(RTLIL::Const(State::S1, 1));
state.set_next_value(factory.constant(RTLIL::Const(State::S0, 1))); state.set_next_value(factory.constant(RTLIL::Const(State::S0, 1)));
return factory.value(state); return factory.value(state);
} }
} else if(cellType == ID($check)) { } else if(cellType == TW($check)) {
log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName); log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName);
} else { } else {
log_error("`%s' cells are not supported by the functional backend\n", cellType); log_error("`%s' cells are not supported by the functional backend\n", cellType);
@ -495,7 +495,7 @@ class FunctionalIRConstruction {
queue.emplace_back(cell); queue.emplace_back(cell);
std::optional<Node> rv; std::optional<Node> rv;
for(auto const &[name, sigspec] : cell->connections()) for(auto const &[name, sigspec] : cell->connections())
if(driver_map.celltypes.cell_output(cell->type, name)) { if(driver_map.celltypes.cell_output(cell->type.ref(), name)) {
auto node = factory.create_pending(sigspec.size()); auto node = factory.create_pending(sigspec.size());
factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name)); factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name));
cell_outputs.emplace({cell, name}, node); cell_outputs.emplace({cell, name}, node);
@ -515,17 +515,17 @@ public:
{ {
driver_map.add(module); driver_map.add(module);
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($check))) if (cell->type.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover), TW($check)))
queue.emplace_back(cell); queue.emplace_back(cell);
} }
// we are relying here on unsorted pools iterating last-in-first-out // we are relying here on unsorted pools iterating last-in-first-out
for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) { for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) {
auto *wire = module->wire(*riter); auto *wire = module->wire(*riter);
if (wire && wire->port_input) { if (wire && wire->port_input) {
factory.add_input(wire->name, ID($input), Sort(wire->width)); factory.add_input(wire->name, TW($input), Sort(wire->width));
} }
if (wire && wire->port_output) { if (wire && wire->port_output) {
auto &output = factory.add_output(wire->name, ID($output), Sort(wire->width)); auto &output = factory.add_output(wire->name, TW($output), Sort(wire->width));
output.set_value(enqueue(DriveChunk(DriveChunkWire(wire, 0, wire->width)))); output.set_value(enqueue(DriveChunk(DriveChunkWire(wire, 0, wire->width))));
} }
} }
@ -565,14 +565,14 @@ private:
// - Since wr port j can only have priority over wr port i if j > i, if we do writes in // - Since wr port j can only have priority over wr port i if j > i, if we do writes in
// ascending index order the result will obey the priorty relation. // ascending index order the result will obey the priorty relation.
vector<Node> read_results; vector<Node> read_results;
auto &state = factory.add_state(mem->cell->name, ID($state), Sort(ceil_log2(mem->size), mem->width)); auto &state = factory.add_state(mem->cell->name, TW($state), Sort(ceil_log2(mem->size), mem->width));
state.set_initial_value(MemContents(mem)); state.set_initial_value(MemContents(mem));
Node node = factory.value(state); Node node = factory.value(state);
for (size_t i = 0; i < mem->wr_ports.size(); i++) { for (size_t i = 0; i < mem->wr_ports.size(); i++) {
const auto &wr = mem->wr_ports[i]; const auto &wr = mem->wr_ports[i];
if (wr.clk_enable) if (wr.clk_enable)
log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
"Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, mem->memid.unescape()); "Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
Node en = enqueue(driver_map(DriveSpec(wr.en))); Node en = enqueue(driver_map(DriveSpec(wr.en)));
Node addr = enqueue(driver_map(DriveSpec(wr.addr))); Node addr = enqueue(driver_map(DriveSpec(wr.addr)));
Node new_data = enqueue(driver_map(DriveSpec(wr.data))); Node new_data = enqueue(driver_map(DriveSpec(wr.data)));
@ -582,12 +582,12 @@ private:
} }
if (mem->rd_ports.empty()) if (mem->rd_ports.empty())
log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. " log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. "
"Call opt_clean to remove it.", mem->module, mem->memid.unescape()); "Call opt_clean to remove it.", mem->module, design->twines.unescaped_str(mem->memid));
for (size_t i = 0; i < mem->rd_ports.size(); i++) { for (size_t i = 0; i < mem->rd_ports.size(); i++) {
const auto &rd = mem->rd_ports[i]; const auto &rd = mem->rd_ports[i];
if (rd.clk_enable) if (rd.clk_enable)
log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
"Call memory_nordff to avoid this error.\n", i, mem->module, mem->memid.unescape()); "Call memory_nordff to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
Node addr = enqueue(driver_map(DriveSpec(rd.addr))); Node addr = enqueue(driver_map(DriveSpec(rd.addr)));
read_results.push_back(factory.memory_read(node, addr)); read_results.push_back(factory.memory_read(node, addr));
} }
@ -609,8 +609,8 @@ private:
FfData ff(&ff_initvals, cell); FfData ff(&ff_initvals, cell);
if (!ff.has_gclk) if (!ff.has_gclk)
log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. " log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. "
"Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescape(), cell); "Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescaped(), cell);
auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width)); auto &state = factory.add_state(ff.name, TW($state), Sort(ff.width));
Node q_value = factory.value(state); Node q_value = factory.value(state);
factory.suggest_name(q_value, ff.name); factory.suggest_name(q_value, ff.name);
factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value); factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value);
@ -621,9 +621,9 @@ private:
TwineRef output_name; // for the single output case TwineRef output_name; // for the single output case
int n_outputs = 0; int n_outputs = 0;
for(auto const &[name, sigspec] : cell->connections()) { for(auto const &[name, sigspec] : cell->connections()) {
if(driver_map.celltypes.cell_input(cell->type, name) && sigspec.size() > 0) if(driver_map.celltypes.cell_input(cell->type.ref(), name) && sigspec.size() > 0)
connections.insert({ name, enqueue(DriveChunkPort(cell, {name, sigspec})) }); connections.insert({ name, enqueue(DriveChunkPort(cell, {name, sigspec})) });
if(driver_map.celltypes.cell_output(cell->type, name)) { if(driver_map.celltypes.cell_output(cell->type.ref(), name)) {
output_name = name; output_name = name;
n_outputs++; n_outputs++;
} }
@ -677,7 +677,7 @@ public:
factory.update_pending(pending, node); factory.update_pending(pending, node);
} else { } else {
DriveSpec driver = driver_map(DriveSpec(wire_chunk)); DriveSpec driver = driver_map(DriveSpec(wire_chunk));
check_undriven(driver, wire_chunk.wire->name.unescape()); check_undriven(driver, design->twines.unescaped_str(wire_chunk.wire->name));
Node node = enqueue(driver); Node node = enqueue(driver);
factory.suggest_name(node, wire_chunk.wire->name); factory.suggest_name(node, wire_chunk.wire->name);
factory.update_pending(pending, node); factory.update_pending(pending, node);
@ -690,7 +690,7 @@ public:
} else if (chunk.is_port()) { } else if (chunk.is_port()) {
DriveChunkPort port_chunk = chunk.port(); DriveChunkPort port_chunk = chunk.port();
if (port_chunk.is_whole()) { if (port_chunk.is_whole()) {
if (driver_map.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) { if (driver_map.celltypes.cell_output(port_chunk.cell->type.ref(), port_chunk.port)) {
Node node = enqueue_cell(port_chunk.cell, port_chunk.port); Node node = enqueue_cell(port_chunk.cell, port_chunk.port);
factory.update_pending(pending, node); factory.update_pending(pending, node);
} else { } else {
@ -745,7 +745,7 @@ void IR::topological_sort() {
log_warning("Combinational loop:\n"); log_warning("Combinational loop:\n");
for (int *i = begin; i != end; ++i) { for (int *i = begin; i != end; ++i) {
Node node(_graph[*i]); Node node(_graph[*i]);
log("- %s = %s\n", node.name().unescape(), node.to_string()); log("- %s = %s\n", design->twines.unescaped_str(node.name()), node.to_string());
} }
log("\n"); log("\n");
scc = true; scc = true;

File diff suppressed because it is too large Load Diff

View File

@ -138,11 +138,11 @@ struct Macc
void from_cell(RTLIL::Cell *cell) void from_cell(RTLIL::Cell *cell)
{ {
if (cell->type == ID($macc)) { if (cell->type == TW($macc)) {
from_cell_v1(cell); from_cell_v1(cell);
return; return;
} }
log_assert(cell->type == ID($macc_v2)); log_assert(cell->type == TW($macc_v2));
RTLIL::SigSpec port_a = cell->getPort(TW::A); RTLIL::SigSpec port_a = cell->getPort(TW::A);
RTLIL::SigSpec port_b = cell->getPort(TW::B); RTLIL::SigSpec port_b = cell->getPort(TW::B);

View File

@ -123,7 +123,7 @@ void Mem::emit() {
if (!cell) { if (!cell) {
if (memid.empty()) if (memid.empty())
memid = NEW_ID; memid = NEW_ID;
cell = module->addCell(Twine{memid.str()}, ID($mem_v2)); cell = module->addCell(Twine{memid.str()}, TW::$mem_v2);
} }
cell->type_impl = TW::$mem_v2; cell->type_impl = TW::$mem_v2;
cell->attributes = attributes; cell->attributes = attributes;
@ -300,7 +300,7 @@ void Mem::emit() {
mem->attributes = attributes; mem->attributes = attributes;
for (auto &port : rd_ports) { for (auto &port : rd_ports) {
if (!port.cell) if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memrd_v2)); port.cell = module->addCell(NEW_TWINE, TW::$memrd_v2);
port.cell->type_impl = TW::$memrd_v2; port.cell->type_impl = TW::$memrd_v2;
port.cell->attributes = port.attributes; port.cell->attributes = port.attributes;
port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::MEMID] = memid.str();
@ -325,7 +325,7 @@ void Mem::emit() {
int idx = 0; int idx = 0;
for (auto &port : wr_ports) { for (auto &port : wr_ports) {
if (!port.cell) if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memwr_v2)); port.cell = module->addCell(NEW_TWINE, TW::$memwr_v2);
port.cell->type_impl = TW::$memwr_v2; port.cell->type_impl = TW::$memwr_v2;
port.cell->attributes = port.attributes; port.cell->attributes = port.attributes;
if (port.cell->parameters.count(ID::PRIORITY)) if (port.cell->parameters.count(ID::PRIORITY))
@ -346,7 +346,7 @@ void Mem::emit() {
for (auto &init : inits) { for (auto &init : inits) {
bool v2 = !init.en.is_fully_ones(); bool v2 = !init.en.is_fully_ones();
if (!init.cell) if (!init.cell)
init.cell = module->addCell(NEW_TWINE, v2 ? ID($meminit_v2) : ID($meminit)); init.cell = module->addCell(NEW_TWINE, v2 ? TW::$meminit_v2 : TW::$meminit);
else { else {
if (!v2) if (!v2)
init.cell->unsetPort(TW::EN); init.cell->unsetPort(TW::EN);
@ -548,11 +548,11 @@ namespace {
dict<IdString, pool<Cell *>> inits; dict<IdString, pool<Cell *>> inits;
MemIndex (Module *module) { MemIndex (Module *module) {
for (auto cell: module->cells()) { for (auto cell: module->cells()) {
if (cell->type.in(ID($memwr), ID($memwr_v2))) if (cell->type.in(TW($memwr), TW($memwr_v2)))
wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
else if (cell->type.in(ID($memrd), ID($memrd_v2))) else if (cell->type.in(TW($memrd), TW($memrd_v2)))
rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
else if (cell->type.in(ID($meminit), ID($meminit_v2))) else if (cell->type.in(TW($meminit), TW($meminit_v2)))
inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
} }
} }
@ -568,7 +568,7 @@ namespace {
if (index.rd_ports.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) { if (index.rd_ports.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
for (auto cell : index.rd_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) { for (auto cell : index.rd_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
MemRd mrd; MemRd mrd;
bool is_compat = cell->type == ID($memrd); bool is_compat = cell->type == TW($memrd);
mrd.cell = cell; mrd.cell = cell;
mrd.attributes = cell->attributes; mrd.attributes = cell->attributes;
mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
@ -612,7 +612,7 @@ namespace {
std::vector<std::pair<int, MemWr>> ports; std::vector<std::pair<int, MemWr>> ports;
for (auto cell : index.wr_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) { for (auto cell : index.wr_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
MemWr mwr; MemWr mwr;
bool is_compat = cell->type == ID($memwr); bool is_compat = cell->type == TW($memwr);
mwr.cell = cell; mwr.cell = cell;
mwr.attributes = cell->attributes; mwr.attributes = cell->attributes;
mwr.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); mwr.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
@ -631,7 +631,7 @@ namespace {
} }
for (int i = 0; i < GetSize(res.wr_ports); i++) { for (int i = 0; i < GetSize(res.wr_ports); i++) {
auto &port = res.wr_ports[i]; auto &port = res.wr_ports[i];
bool is_compat = port.cell->type == ID($memwr); bool is_compat = port.cell->type == TW($memwr);
if (is_compat) { if (is_compat) {
port.priority_mask.resize(GetSize(res.wr_ports)); port.priority_mask.resize(GetSize(res.wr_ports));
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
@ -667,7 +667,7 @@ namespace {
log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), cell); log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), cell);
init.addr = addr.as_const(); init.addr = addr.as_const();
init.data = data.as_const(); init.data = data.as_const();
if (cell->type == ID($meminit_v2)) { if (cell->type == TW($meminit_v2)) {
auto en = cell->getPort(TW::EN); auto en = cell->getPort(TW::EN);
if (!en.is_fully_const()) if (!en.is_fully_const())
log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), cell); log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), cell);
@ -683,7 +683,7 @@ namespace {
} }
for (int i = 0; i < GetSize(res.rd_ports); i++) { for (int i = 0; i < GetSize(res.rd_ports); i++) {
auto &port = res.rd_ports[i]; auto &port = res.rd_ports[i];
bool is_compat = port.cell->type == ID($memrd); bool is_compat = port.cell->type == TW($memrd);
if (is_compat) { if (is_compat) {
port.transparency_mask.resize(GetSize(res.wr_ports)); port.transparency_mask.resize(GetSize(res.wr_ports));
port.collision_x_mask.resize(GetSize(res.wr_ports)); port.collision_x_mask.resize(GetSize(res.wr_ports));
@ -720,7 +720,7 @@ namespace {
cell->parameters.at(ID::OFFSET).as_int(), cell->parameters.at(ID::OFFSET).as_int(),
cell->parameters.at(ID::SIZE).as_int() cell->parameters.at(ID::SIZE).as_int()
); );
bool is_compat = cell->type == ID($mem); bool is_compat = cell->type == TW($mem);
int abits = cell->parameters.at(ID::ABITS).as_int(); int abits = cell->parameters.at(ID::ABITS).as_int();
res.packed = true; res.packed = true;
res.cell = cell; res.cell = cell;
@ -860,7 +860,7 @@ std::vector<Mem> Mem::get_all_memories(Module *module) {
res.push_back(mem_from_memory(module, it.second, index)); res.push_back(mem_from_memory(module, it.second, index));
} }
for (auto cell: module->cells()) { for (auto cell: module->cells()) {
if (cell->type.in(ID($mem), ID($mem_v2))) if (cell->type.in(TW($mem), TW($mem_v2)))
res.push_back(mem_from_cell(cell)); res.push_back(mem_from_cell(cell));
} }
return res; return res;
@ -874,7 +874,7 @@ std::vector<Mem> Mem::get_selected_memories(Module *module) {
res.push_back(mem_from_memory(module, it.second, index)); res.push_back(mem_from_memory(module, it.second, index));
} }
for (auto cell: module->selected_cells()) { for (auto cell: module->selected_cells()) {
if (cell->type.in(ID($mem), ID($mem_v2))) if (cell->type.in(TW($mem), TW($mem_v2)))
res.push_back(mem_from_cell(cell)); res.push_back(mem_from_cell(cell));
} }
return res; return res;

View File

@ -321,7 +321,7 @@ struct ModIndex : public RTLIL::Monitor
log(" PRIMARY OUTPUT\n"); log(" PRIMARY OUTPUT\n");
for (auto &port : it.second.ports) for (auto &port : it.second.ports)
log(" PORT: %s.%s[%d] (%s)\n", port.cell, log(" PORT: %s.%s[%d] (%s)\n", port.cell,
module->design->twines.str(port.port), port.offset, port.cell->type.unescape()); module->design->twines.str(port.port), port.offset, port.cell->module->design->twines.unescaped_str(port.cell->type_impl));
} }
} }
}; };
@ -402,11 +402,11 @@ struct ModWalker
void add_cell(RTLIL::Cell *cell) void add_cell(RTLIL::Cell *cell)
{ {
if (ct.cell_known(cell->type)) { if (ct.cell_known(cell->type.ref())) {
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
add_cell_port(cell, conn.first, sigmap(conn.second), add_cell_port(cell, conn.first, sigmap(conn.second),
ct.cell_output(cell->type, conn.first), ct.cell_output(cell->type.ref(), conn.first),
ct.cell_input(cell->type, conn.first)); ct.cell_input(cell->type.ref(), conn.first));
} else { } else {
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
add_cell_port(cell, conn.first, sigmap(conn.second), true, true); add_cell_port(cell, conn.first, sigmap(conn.second), true, true);
@ -436,7 +436,7 @@ struct ModWalker
for (auto &it : module->wires_) for (auto &it : module->wires_)
add_wire(it.second); add_wire(it.second);
for (auto &it : module->cells_) for (auto &it : module->cells_)
if (filter_ct == NULL || filter_ct->cell_known(it.second->type)) if (filter_ct == NULL || filter_ct->cell_known(it.second->type.ref()))
add_cell(it.second); add_cell(it.second);
} }

View File

@ -555,13 +555,8 @@ struct NewCellType {
}; };
struct NewCellTypes { struct NewCellTypes {
struct IdStringHash {
std::size_t operator()(const IdString id) const {
return static_cast<size_t>(id.hash_top().yield());
}
};
StaticCellTypes::Categories::Category static_cell_types = StaticCellTypes::categories.empty; StaticCellTypes::Categories::Category static_cell_types = StaticCellTypes::categories.empty;
std::unordered_map<TwineRef, NewCellType, IdStringHash> custom_cell_types {}; dict<TwineRef, NewCellType> custom_cell_types {};
NewCellTypes() { NewCellTypes() {
static_cell_types = StaticCellTypes::categories.empty; static_cell_types = StaticCellTypes::categories.empty;

View File

@ -12,7 +12,7 @@ struct PmuxBPortIterator {
int port_idx; int port_idx;
int port_count; int port_count;
PmuxBPortIterator(Cell* mux) : cell(mux) { PmuxBPortIterator(Cell* mux) : cell(mux) {
log_assert(mux->type == ID($mux) || mux->type == ID($pmux)); log_assert(mux->type == TW($mux) || mux->type == TW($pmux));
port_idx = 0; port_idx = 0;
b = mux->getPort(TW::B).to_sigbit_vector(); b = mux->getPort(TW::B).to_sigbit_vector();

View File

@ -77,25 +77,25 @@ void QuickConeSat::prepare()
int QuickConeSat::cell_complexity(RTLIL::Cell *cell) int QuickConeSat::cell_complexity(RTLIL::Cell *cell)
{ {
if (cell->type.in(ID($concat), ID($slice), ID($pos), ID($buf), ID($_BUF_))) if (cell->type.in(TW($concat), TW($slice), TW($pos), TW($buf), TW($_BUF_)))
return 0; return 0;
if (cell->type.in(ID($not), ID($and), ID($or), ID($xor), ID($xnor), if (cell->type.in(TW($not), TW($and), TW($or), TW($xor), TW($xnor),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), TW($reduce_and), TW($reduce_or), TW($reduce_xor),
ID($reduce_xnor), ID($reduce_bool), TW($reduce_xnor), TW($reduce_bool),
ID($logic_not), ID($logic_and), ID($logic_or), TW($logic_not), TW($logic_and), TW($logic_or),
ID($eq), ID($ne), ID($eqx), ID($nex), ID($fa), TW($eq), TW($ne), TW($eqx), TW($nex), TW($fa),
ID($mux), ID($pmux), ID($bmux), ID($demux), ID($lut), ID($sop), TW($mux), TW($pmux), TW($bmux), TW($demux), TW($lut), TW($sop),
ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
ID($_MUX_), ID($_NMUX_), ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), TW($_MUX_), TW($_NMUX_), TW($_MUX4_), TW($_MUX8_), TW($_MUX16_),
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)))
return 1; return 1;
if (cell->type.in(ID($neg), ID($add), ID($sub), ID($alu), ID($lcu), if (cell->type.in(TW($neg), TW($add), TW($sub), TW($alu), TW($lcu),
ID($lt), ID($le), ID($gt), ID($ge))) TW($lt), TW($le), TW($gt), TW($ge)))
return 2; return 2;
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx)))
return 3; return 3;
if (cell->type.in(ID($mul), ID($macc), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) if (cell->type.in(TW($mul), TW($macc), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow)))
return 4; return 4;
// Unknown cell. // Unknown cell.
return 5; return 5;

View File

@ -983,7 +983,7 @@ struct HelpPass : public Pass {
for (auto it : StaticCellTypes::builder.cells) { for (auto it : StaticCellTypes::builder.cells) {
if (!StaticCellTypes::categories.is_known(it.type)) if (!StaticCellTypes::categories.is_known(it.type))
continue; continue;
auto name = it.type.str(); auto name = TW::str(it.type);
if (cell_help_messages.contains(name)) { if (cell_help_messages.contains(name)) {
auto cell_help = cell_help_messages.get(name); auto cell_help = cell_help_messages.get(name);
groups[cell_help.group].emplace_back(name); groups[cell_help.group].emplace_back(name);
@ -1021,10 +1021,10 @@ struct HelpPass : public Pass {
json.name("code"); json.value(ch.code); json.name("code"); json.value(ch.code);
vector<string> inputs, outputs; vector<string> inputs, outputs;
for (auto &input : ct.inputs) for (auto &input : ct.inputs)
inputs.push_back(RTLIL::IdString((RTLIL::StaticId)input).str()); inputs.push_back(TW::str(input));
json.name("inputs"); json.value(inputs); json.name("inputs"); json.value(inputs);
for (auto &output : ct.outputs) for (auto &output : ct.outputs)
outputs.push_back(RTLIL::IdString((RTLIL::StaticId)output).str()); outputs.push_back(TW::str(output));
json.name("outputs"); json.value(outputs); json.name("outputs"); json.value(outputs);
vector<string> properties; vector<string> properties;
// CellType properties // CellType properties

View File

@ -1948,18 +1948,18 @@ bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
return false; return false;
} }
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail) TwineRef RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
{ {
if (mayfail) if (mayfail)
return IdString(); return Twine::Null;
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str()); log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
} }
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<RTLIL::IdString, RTLIL::Module*> &, const dict<RTLIL::IdString, RTLIL::IdString> &, bool mayfail) TwineRef RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<TwineRef, RTLIL::Module*> &, const dict<TwineRef, TwineRef> &, bool mayfail)
{ {
if (mayfail) if (mayfail)
return IdString(); return Twine::Null;
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str()); log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
} }
@ -3574,6 +3574,11 @@ TwineRef RTLIL::Module::uniquify(TwineRef name)
return uniquify(name, index); return uniquify(name, index);
} }
TwineRef RTLIL::Module::uniquify(Twine&& name)
{
return uniquify(design->twines.add(Twine{std::move(name)}));
}
TwineRef RTLIL::Module::uniquify(TwineRef name, int &index) TwineRef RTLIL::Module::uniquify(TwineRef name, int &index)
{ {
if (index == 0) { if (index == 0) {
@ -3590,6 +3595,11 @@ TwineRef RTLIL::Module::uniquify(TwineRef name, int &index)
} }
} }
TwineRef RTLIL::Module::uniquify(Twine&& name, int &index)
{
return uniquify(design->twines.add(Twine{std::move(name)}), index);
}
static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
{ {
if (a->port_id && !b->port_id) if (a->port_id && !b->port_id)
@ -4524,10 +4534,14 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
return cell; return cell;
} }
static TwinePool& _cell_adder_twines(RTLIL::Module* m) { return m->design->twines; }
static TwinePool& _cell_adder_twines(RTLIL::Patch* p) { return p->mod->design->twines; }
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSrGate(Twine &&name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSrGate(Twine &&name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, TwineRef src) const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::S, sig_set); cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr); cell->setPort(TW::R, sig_clr);
cell->setPort(TW::Q, sig_q); cell->setPort(TW::Q, sig_q);
@ -4546,7 +4560,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, TwineRef src) template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
cell->setPort(TW::Q, sig_q); cell->setPort(TW::Q, sig_q);
@ -4556,7 +4571,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, TwineRef src) template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
@ -4568,7 +4584,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsrGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsrGate(Twine &&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, bool set_polarity, bool clr_polarity, TwineRef src) RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::S, sig_set); cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr); cell->setPort(TW::R, sig_clr);
@ -4581,7 +4598,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsreGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsreGate(Twine &&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, bool en_polarity, bool set_polarity, bool clr_polarity, TwineRef src) RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::S, sig_set); cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr); cell->setPort(TW::R, sig_clr);
@ -4595,7 +4613,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool clk_polarity, bool arst_polarity, TwineRef src) bool arst_value, bool clk_polarity, bool arst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_arst); cell->setPort(TW::R, sig_arst);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
@ -4607,7 +4626,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffeGate(Twine &&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, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffeGate(Twine &&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, bool clk_polarity, bool en_polarity, bool arst_polarity, TwineRef src) bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_arst); cell->setPort(TW::R, sig_arst);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
@ -4620,7 +4640,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffGate(Twine &&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, bool aload_polarity, TwineRef src) const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::L, sig_aload); cell->setPort(TW::L, sig_aload);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
@ -4633,7 +4654,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffeGate(Twine &&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, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffeGate(Twine &&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, bool en_polarity, bool aload_polarity, TwineRef src) const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::L, sig_aload); cell->setPort(TW::L, sig_aload);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
@ -4647,7 +4669,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value, bool clk_polarity, bool srst_polarity, TwineRef src) bool srst_value, bool clk_polarity, bool srst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst); cell->setPort(TW::R, sig_srst);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
@ -4659,7 +4682,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffeGate(Twine &&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, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffeGate(Twine &&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, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src) bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst); cell->setPort(TW::R, sig_srst);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
@ -4672,7 +4696,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffceGate(Twine &&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, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffceGate(Twine &&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, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src) bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk); cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst); cell->setPort(TW::R, sig_srst);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
@ -4684,7 +4709,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, TwineRef src) template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
cell->setPort(TW::Q, sig_q); cell->setPort(TW::Q, sig_q);
@ -4695,7 +4721,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool en_polarity, bool arst_polarity, TwineRef src) bool arst_value, bool en_polarity, bool arst_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
cell->setPort(TW::R, sig_arst); cell->setPort(TW::R, sig_arst);
cell->setPort(TW::D, sig_d); cell->setPort(TW::D, sig_d);
@ -4707,7 +4734,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchsrGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchsrGate(Twine &&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, bool set_polarity, bool clr_polarity, TwineRef src) RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{ {
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')}); TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en); cell->setPort(TW::E, sig_en);
cell->setPort(TW::S, sig_set); cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr); cell->setPort(TW::R, sig_clr);

View File

@ -743,7 +743,7 @@ constexpr int lookup_well_known_id(std::string_view name)
return -1; return -1;
} }
// Create a statically allocated IdString object, using for example ID::A or ID($add). // Create a statically allocated IdString object, using for example ID::A or TW($add).
// //
// Recipe for Converting old code that is using conversion of strings like ID::A and // Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for // "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
@ -3026,7 +3026,7 @@ public:
Module(); Module();
virtual ~Module(); virtual ~Module();
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false); virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false); virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool mayfail = false);
virtual size_t count_id(TwineRef id); virtual size_t count_id(TwineRef id);
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces); virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual bool reprocess_if_necessary(RTLIL::Design *design); virtual bool reprocess_if_necessary(RTLIL::Design *design);
@ -3158,7 +3158,9 @@ public:
void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2);
TwineRef uniquify(TwineRef name); TwineRef uniquify(TwineRef name);
TwineRef uniquify(Twine&& name);
TwineRef uniquify(TwineRef name, int &index); TwineRef uniquify(TwineRef name, int &index);
TwineRef uniquify(Twine&& name, int &index);
// Primary overloads: name already interned in design->twines. // Primary overloads: name already interned in design->twines.
RTLIL::Wire *addWire(TwineRef name, int width = 1); RTLIL::Wire *addWire(TwineRef name, int width = 1);
@ -3171,6 +3173,7 @@ public:
RTLIL::Cell *addCell(TwineRef name, TwineRef type); RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other); RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
// Convenience. // Convenience.
RTLIL::Cell *addCell(Twine name, Twine type);
RTLIL::Cell *addCell(Twine &&name, TwineRef type); RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type); RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other); RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);

View File

@ -81,7 +81,7 @@ struct RTLIL::SigNormIndex
dict<Wire *, Cell *> input_port_cells; dict<Wire *, Cell *> input_port_cells;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type != ID($input_port)) if (cell->type != TW($input_port))
continue; continue;
auto const &sig_y = cell->getPort(TW::Y); auto const &sig_y = cell->getPort(TW::Y);
@ -98,7 +98,7 @@ struct RTLIL::SigNormIndex
for (auto portname : module->ports) { for (auto portname : module->ports) {
Wire *wire = module->wire(portname); Wire *wire = module->wire(portname);
if (wire->port_input && !wire->port_output && !input_port_cells.count(wire)) { if (wire->port_input && !wire->port_output && !input_port_cells.count(wire)) {
Cell *cell = module->addCell(NEW_TWINE, ID($input_port)); Cell *cell = module->addCell(NEW_TWINE, TW::$input_port);
cell->setParam(ID::WIDTH, GetSize(wire)); cell->setParam(ID::WIDTH, GetSize(wire));
cell->setPort(TW::Y, wire); cell->setPort(TW::Y, wire);
input_port_cells.emplace(wire, cell); input_port_cells.emplace(wire, cell);
@ -195,7 +195,7 @@ struct RTLIL::SigNormIndex
} }
if (!connect_lhs.empty()) { if (!connect_lhs.empty()) {
Cell *cell = module->addCell(NEW_TWINE, ID($connect)); Cell *cell = module->addCell(NEW_TWINE, TW::$connect);
xlog("add connect (1) %s\n", cell->name); xlog("add connect (1) %s\n", cell->name);
cell->setParam(ID::WIDTH, GetSize(connect_lhs)); cell->setParam(ID::WIDTH, GetSize(connect_lhs));
cell->setPort(TW::A, std::move(connect_lhs)); cell->setPort(TW::A, std::move(connect_lhs));
@ -355,7 +355,7 @@ void RTLIL::Design::sigNormalize(bool enable)
// TODO inefficient? // TODO inefficient?
std::vector<Cell*> cells_snapshot = module->cells(); std::vector<Cell*> cells_snapshot = module->cells();
for (auto cell : cells_snapshot) { for (auto cell : cells_snapshot) {
if (cell->type == ID($input_port)) if (cell->type == TW($input_port))
module->remove(cell); module->remove(cell);
} }
} }
@ -560,12 +560,12 @@ void RTLIL::Module::bufNormalize()
// Ensure that every enqueued input port is represented by a cell // Ensure that every enqueued input port is represented by a cell
for (auto wire : buf_norm_wire_queue) { for (auto wire : buf_norm_wire_queue) {
if (wire->port_input && !wire->port_output) { if (wire->port_input && !wire->port_output) {
if (wire->driverCell_ != nullptr && wire->driverCell_->type != ID($input_port)) { if (wire->driverCell_ != nullptr && wire->driverCell_->type != TW($input_port)) {
wire->driverCell_ = nullptr; wire->driverCell_ = nullptr;
wire->driverPort_ = Twine::Null; wire->driverPort_ = Twine::Null;
} }
if (wire->driverCell_ == nullptr) { if (wire->driverCell_ == nullptr) {
Cell *input_port_cell = addCell(NEW_TWINE, ID($input_port)); Cell *input_port_cell = addCell(NEW_TWINE, TW::$input_port);
input_port_cell->setParam(ID::WIDTH, GetSize(wire)); input_port_cell->setParam(ID::WIDTH, GetSize(wire));
input_port_cell->setPort(TW::Y, wire); // this hits the fast path that doesn't mutate the queues input_port_cell->setPort(TW::Y, wire); // this hits the fast path that doesn't mutate the queues
} }
@ -621,7 +621,7 @@ void RTLIL::Module::bufNormalize()
if (chunk.is_wire()) if (chunk.is_wire())
wire_queue_entries(chunk.wire); wire_queue_entries(chunk.wire);
if (cell->type == ID($buf) && cell->attributes.empty() && !cell->name.isPublic()) { if (cell->type == TW($buf) && cell->attributes.empty() && !cell->name.isPublic()) {
// For a plain `$buf` cell, we enqueue all wires on its input // For a plain `$buf` cell, we enqueue all wires on its input
// side, bypass it using module level connections (skipping 'z // side, bypass it using module level connections (skipping 'z
// bits) and then remove the cell. Eventually the module level // bits) and then remove the cell. Eventually the module level
@ -662,7 +662,7 @@ void RTLIL::Module::bufNormalize()
log_assert(GetSize(buf_norm_wire_queue) <= 1); log_assert(GetSize(buf_norm_wire_queue) <= 1);
buf_norm_wire_queue.clear(); buf_norm_wire_queue.clear();
return; return;
} else if (cell->type == ID($input_port)) { } else if (cell->type == TW($input_port)) {
log_assert(port == TW::Y); log_assert(port == TW::Y);
if (sig.is_wire()) { if (sig.is_wire()) {
Wire *w = sig.as_wire(); Wire *w = sig.as_wire();
@ -744,7 +744,7 @@ void RTLIL::Module::bufNormalize()
break; break;
while (!found->second.empty()) { while (!found->second.empty()) {
Cell *connect_cell = *found->second.begin(); Cell *connect_cell = *found->second.begin();
log_assert(connect_cell->type == ID($connect)); log_assert(connect_cell->type == TW($connect));
SigSpec const &sig_a = connect_cell->getPort(TW::A); SigSpec const &sig_a = connect_cell->getPort(TW::A);
SigSpec const &sig_b = connect_cell->getPort(TW::B); SigSpec const &sig_b = connect_cell->getPort(TW::B);
xlog("found $connect cell %s: %s <-> %s\n", connect_cell, log_signal(sig_a), log_signal(sig_b)); xlog("found $connect cell %s: %s <-> %s\n", connect_cell, log_signal(sig_a), log_signal(sig_b));
@ -769,7 +769,7 @@ void RTLIL::Module::bufNormalize()
// As a first step for re-normalization we add all require intermediate // As a first step for re-normalization we add all require intermediate
// wires for cell output and inout ports. // wires for cell output and inout ports.
for (auto &[cell, port] : pending_ports) { for (auto &[cell, port] : pending_ports) {
log_assert(cell->type != ID($input_port)); log_assert(cell->type != TW($input_port));
log_assert(!cell->type.empty()); log_assert(!cell->type.empty());
log_assert(!pending_deleted_cells.count(cell)); log_assert(!pending_deleted_cells.count(cell));
SigSpec const &sig = cell->getPort(port); SigSpec const &sig = cell->getPort(port);
@ -848,7 +848,7 @@ void RTLIL::Module::bufNormalize()
auto const &[cell, port] = cellport; auto const &[cell, port] = cellport;
for (int i = 0; i != GetSize(wire); ++i) { for (int i = 0; i != GetSize(wire); ++i) {
SigBit driver = sigmap(SigBit(wire, i)); SigBit driver = sigmap(SigBit(wire, i));
if (cell->type == ID($tribuf) || cell->port_dir(port) == RTLIL::PD_INOUT) { if (cell->type == TW($tribuf) || cell->port_dir(port) == RTLIL::PD_INOUT) {
// We add inout drivers to `driven` in a separate loop below // We add inout drivers to `driven` in a separate loop below
weakly_driven.insert(driver); weakly_driven.insert(driver);
} else { } else {
@ -947,7 +947,7 @@ void RTLIL::Module::bufNormalize()
if (sig_a.empty()) if (sig_a.empty())
return; return;
xlog("connect %s <-> %s\n", log_signal(sig_a), log_signal(sig_b)); xlog("connect %s <-> %s\n", log_signal(sig_a), log_signal(sig_b));
Cell *connect_cell = addCell(NEW_TWINE, ID($connect)); Cell *connect_cell = addCell(NEW_TWINE, TW::$connect);
connect_cell->setParam(ID::WIDTH, GetSize(sig_a)); connect_cell->setParam(ID::WIDTH, GetSize(sig_a));
connect_cell->setPort(TW::A, sig_a); connect_cell->setPort(TW::A, sig_a);
connect_cell->setPort(TW::B, sig_b); connect_cell->setPort(TW::B, sig_b);
@ -1066,7 +1066,7 @@ void RTLIL::Cell::unsetPort(TwineRef portname)
} }
} }
if (type == ID($connect)) { if (type == TW($connect)) {
for (auto &[port, sig] : connections_) { for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) { for (auto &chunk : sig.chunks()) {
if (!chunk.wire) if (!chunk.wire)
@ -1097,7 +1097,7 @@ void RTLIL::Cell::unsetPort(TwineRef portname)
static bool ignored_cell(const RTLIL::IdString& type) static bool ignored_cell(const RTLIL::IdString& type)
{ {
return type == ID($specify2) || type == ID($specify3) || type == ID($specrule); return type == TW($specify2) || type == TW($specify3) || type == TW($specrule);
} }
void RTLIL::Cell::signorm_index_remove(TwineRef portname, const SigSpec &old_signal, bool is_input) void RTLIL::Cell::signorm_index_remove(TwineRef portname, const SigSpec &old_signal, bool is_input)
@ -1167,7 +1167,7 @@ bool RTLIL::Cell::bufnorm_handle_setPort(TwineRef portname, SigSpec &signal, dic
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) { if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
Wire *w = signal.as_wire(); Wire *w = signal.as_wire();
if (w->driverCell_ == nullptr && if (w->driverCell_ == nullptr &&
(w->port_input && !w->port_output) == (type == ID($input_port))) { (w->port_input && !w->port_output) == (type == TW($input_port))) {
w->driverCell_ = this; w->driverCell_ = this;
w->driverPort_ = portname; w->driverPort_ = portname;
conn_it->second = std::move(signal); conn_it->second = std::move(signal);
@ -1184,7 +1184,7 @@ bool RTLIL::Cell::bufnorm_handle_setPort(TwineRef portname, SigSpec &signal, dic
module->buf_norm_wire_queue.insert(chunk.wire); module->buf_norm_wire_queue.insert(chunk.wire);
} }
if (type == ID($connect)) { if (type == TW($connect)) {
for (auto &[port, sig] : connections_) { for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) { for (auto &chunk : sig.chunks()) {
if (!chunk.wire) continue; if (!chunk.wire) continue;
@ -1229,7 +1229,7 @@ void RTLIL::Cell::initIndex()
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) { if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
Wire *w = signal.as_wire(); Wire *w = signal.as_wire();
if (w->driverCell_ == nullptr && if (w->driverCell_ == nullptr &&
(w->port_input && !w->port_output) == (type == ID($input_port))) { (w->port_input && !w->port_output) == (type == TW($input_port))) {
w->driverCell_ = this; w->driverCell_ = this;
w->driverPort_ = portname; w->driverPort_ = portname;
continue; continue;

View File

@ -26,9 +26,9 @@ USING_YOSYS_NAMESPACE
bool SatGen::importCell(RTLIL::Cell *cell, int timestep) bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
{ {
bool arith_undef_handled = false; bool arith_undef_handled = false;
bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); bool is_arith_compare = cell->type.in(TW($lt), TW($le), TW($ge), TW($gt));
if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)) || is_arith_compare)) if (model_undef && (cell->type.in(TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor)) || is_arith_compare))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
@ -42,7 +42,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
int undef_y_bit = ez->OR(undef_any_a, undef_any_b); int undef_y_bit = ez->OR(undef_any_a, undef_any_b);
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
std::vector<int> b = importSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importSigSpec(cell->getPort(TW::B), timestep);
undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b)));
} }
@ -59,8 +59,8 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
arith_undef_handled = true; arith_undef_handled = true;
} }
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub))) TW($and), TW($or), TW($xor), TW($xnor), TW($add), TW($sub)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -69,25 +69,25 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type.in(ID($and), ID($_AND_))) if (cell->type.in(TW($and), TW($_AND_)))
ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_and(a, b), yy));
if (cell->type == ID($_NAND_)) if (cell->type == TW($_NAND_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy));
if (cell->type.in(ID($or), ID($_OR_))) if (cell->type.in(TW($or), TW($_OR_)))
ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_or(a, b), yy));
if (cell->type == ID($_NOR_)) if (cell->type == TW($_NOR_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy));
if (cell->type.in(ID($xor), ID($_XOR_))) if (cell->type.in(TW($xor), TW($_XOR_)))
ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy));
if (cell->type.in(ID($xnor), ID($_XNOR_))) if (cell->type.in(TW($xnor), TW($_XNOR_)))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy));
if (cell->type == ID($_ANDNOT_)) if (cell->type == TW($_ANDNOT_))
ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy));
if (cell->type == ID($_ORNOT_)) if (cell->type == TW($_ORNOT_))
ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy)); ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy));
if (cell->type == ID($add)) if (cell->type == TW($add))
ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_add(a, b), yy));
if (cell->type == ID($sub)) if (cell->type == TW($sub))
ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy));
if (model_undef && !arith_undef_handled) if (model_undef && !arith_undef_handled)
@ -97,30 +97,30 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell, false); extendSignalWidth(undef_a, undef_b, undef_y, cell, false);
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { if (cell->type.in(TW($and), TW($_AND_), TW($_NAND_))) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0)));
ez->assume(ez->vec_eq(yX, undef_y)); ez->assume(ez->vec_eq(yX, undef_y));
} }
else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) { else if (cell->type.in(TW($or), TW($_OR_), TW($_NOR_))) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1))); std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1)));
ez->assume(ez->vec_eq(yX, undef_y)); ez->assume(ez->vec_eq(yX, undef_y));
} }
else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) { else if (cell->type.in(TW($xor), TW($xnor), TW($_XOR_), TW($_XNOR_))) {
std::vector<int> yX = ez->vec_or(undef_a, undef_b); std::vector<int> yX = ez->vec_or(undef_a, undef_b);
ez->assume(ez->vec_eq(yX, undef_y)); ez->assume(ez->vec_eq(yX, undef_y));
} }
else if (cell->type == ID($_ANDNOT_)) { else if (cell->type == TW($_ANDNOT_)) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1))); std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1)));
ez->assume(ez->vec_eq(yX, undef_y)); ez->assume(ez->vec_eq(yX, undef_y));
} }
else if (cell->type == ID($_ORNOT_)) { else if (cell->type == TW($_ORNOT_)) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0))); std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0)));
@ -139,10 +139,10 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) if (cell->type.in(TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)))
{ {
bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); bool aoi_mode = cell->type.in(TW($_AOI3_), TW($_AOI4_));
bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); bool three_mode = cell->type.in(TW($_AOI3_), TW($_OAI3_));
int a = importDefSigSpec(cell->getPort(TW::A), timestep).at(0); int a = importDefSigSpec(cell->getPort(TW::A), timestep).at(0);
int b = importDefSigSpec(cell->getPort(TW::B), timestep).at(0); int b = importDefSigSpec(cell->getPort(TW::B), timestep).at(0);
@ -151,7 +151,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0); int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y; int yy = model_undef ? ez->literal() : y;
if (cell->type.in(ID($_AOI3_), ID($_AOI4_))) if (cell->type.in(TW($_AOI3_), TW($_AOI4_)))
ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy)); ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy));
else else
ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy)); ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy));
@ -205,7 +205,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($_NOT_), ID($not))) if (cell->type.in(TW($_NOT_), TW($not)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -224,7 +224,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($bweqx)) if (cell->type == TW($bweqx))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -250,7 +250,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_), ID($bwmux))) if (cell->type.in(TW($_MUX_), TW($mux), TW($_NMUX_), TW($bwmux)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -258,9 +258,9 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($_NMUX_)) if (cell->type == TW($_NMUX_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
else if (cell->type == ID($bwmux)) else if (cell->type == TW($bwmux))
ez->assume(ez->vec_eq(ez->vec_ite(s, b, a), yy)); ez->assume(ez->vec_eq(ez->vec_ite(s, b, a), yy));
else else
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
@ -275,7 +275,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
std::vector<int> yX; std::vector<int> yX;
if (cell->type == ID($bwmux)) if (cell->type == TW($bwmux))
yX = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a)); yX = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a));
else else
yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a)); yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a));
@ -285,7 +285,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($bmux)) if (cell->type == TW($bmux))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep); std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep);
@ -333,7 +333,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($demux)) if (cell->type == TW($demux))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep); std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep);
@ -385,7 +385,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($pmux)) if (cell->type == TW($pmux))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -431,7 +431,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($pos), ID($buf), ID($neg))) if (cell->type.in(TW($pos), TW($buf), TW($neg)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -439,7 +439,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type.in(ID($pos), ID($buf))) { if (cell->type.in(TW($pos), TW($buf))) {
ez->assume(ez->vec_eq(a, yy)); ez->assume(ez->vec_eq(a, yy));
} else { } else {
std::vector<int> zero(a.size(), ez->CONST_FALSE); std::vector<int> zero(a.size(), ez->CONST_FALSE);
@ -452,7 +452,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell); extendSignalWidthUnary(undef_a, undef_y, cell);
if (cell->type.in(ID($pos), ID($buf))) { if (cell->type.in(TW($pos), TW($buf))) {
ez->assume(ez->vec_eq(undef_a, undef_y)); ez->assume(ez->vec_eq(undef_a, undef_y));
} else { } else {
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@ -465,7 +465,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($connect))) if (cell->type.in(TW($connect)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -485,22 +485,22 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($logic_not)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($reduce_and)) if (cell->type == TW($reduce_and))
ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); ez->SET(ez->expression(ez->OpAnd, a), yy.at(0));
if (cell->type.in(ID($reduce_or), ID($reduce_bool))) if (cell->type.in(TW($reduce_or), TW($reduce_bool)))
ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); ez->SET(ez->expression(ez->OpOr, a), yy.at(0));
if (cell->type == ID($reduce_xor)) if (cell->type == TW($reduce_xor))
ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); ez->SET(ez->expression(ez->OpXor, a), yy.at(0));
if (cell->type == ID($reduce_xnor)) if (cell->type == TW($reduce_xnor))
ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0)); ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0));
if (cell->type == ID($logic_not)) if (cell->type == TW($logic_not))
ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0)); ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0));
for (size_t i = 1; i < y.size(); i++) for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i)); ez->SET(ez->CONST_FALSE, yy.at(i));
@ -511,15 +511,15 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
int aX = ez->expression(ezSAT::OpOr, undef_a); int aX = ez->expression(ezSAT::OpOr, undef_a);
if (cell->type == ID($reduce_and)) { if (cell->type == TW($reduce_and)) {
int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a))); int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0))); ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0)));
} }
else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) { else if (cell->type.in(TW($reduce_or), TW($reduce_bool), TW($logic_not))) {
int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a))); int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0))); ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0)));
} }
else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { else if (cell->type.in(TW($reduce_xor), TW($reduce_xnor))) {
ez->assume(ez->IFF(aX, undef_y.at(0))); ez->assume(ez->IFF(aX, undef_y.at(0)));
} else } else
log_abort(); log_abort();
@ -532,7 +532,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($logic_and), ID($logic_or))) if (cell->type.in(TW($logic_and), TW($logic_or)))
{ {
std::vector<int> vec_a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> vec_a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> vec_b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> vec_b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -543,7 +543,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($logic_and)) if (cell->type == TW($logic_and))
ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0)); ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0));
else else
ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0)); ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0));
@ -563,9 +563,9 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int aX = ez->expression(ezSAT::OpOr, undef_a); int aX = ez->expression(ezSAT::OpOr, undef_a);
int bX = ez->expression(ezSAT::OpOr, undef_b); int bX = ez->expression(ezSAT::OpOr, undef_b);
if (cell->type == ID($logic_and)) if (cell->type == TW($logic_and))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0)); ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0));
else if (cell->type == ID($logic_or)) else if (cell->type == TW($logic_or))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0)); ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0));
else else
log_abort(); log_abort();
@ -578,7 +578,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) if (cell->type.in(TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt)))
{ {
bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool(); bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool();
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
@ -588,7 +588,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (model_undef && cell->type.in(ID($eqx), ID($nex))) { if (model_undef && cell->type.in(TW($eqx), TW($nex))) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
@ -596,29 +596,29 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
b = ez->vec_or(b, undef_b); b = ez->vec_or(b, undef_b);
} }
if (cell->type == ID($lt)) if (cell->type == TW($lt))
ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0));
if (cell->type == ID($le)) if (cell->type == TW($le))
ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0));
if (cell->type.in(ID($eq), ID($eqx))) if (cell->type.in(TW($eq), TW($eqx)))
ez->SET(ez->vec_eq(a, b), yy.at(0)); ez->SET(ez->vec_eq(a, b), yy.at(0));
if (cell->type.in(ID($ne), ID($nex))) if (cell->type.in(TW($ne), TW($nex)))
ez->SET(ez->vec_ne(a, b), yy.at(0)); ez->SET(ez->vec_ne(a, b), yy.at(0));
if (cell->type == ID($ge)) if (cell->type == TW($ge))
ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0));
if (cell->type == ID($gt)) if (cell->type == TW($gt))
ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0));
for (size_t i = 1; i < y.size(); i++) for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i)); ez->SET(ez->CONST_FALSE, yy.at(i));
if (model_undef && cell->type.in(ID($eqx), ID($nex))) if (model_undef && cell->type.in(TW($eqx), TW($nex)))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
if (cell->type == ID($eqx)) if (cell->type == TW($eqx))
yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b)); yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b));
else else
yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b)); yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b));
@ -628,7 +628,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
ez->assume(ez->vec_eq(y, yy)); ez->assume(ez->vec_eq(y, yy));
} }
else if (model_undef && cell->type.in(ID($eq), ID($ne))) else if (model_undef && cell->type.in(TW($eq), TW($ne)))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
@ -662,7 +662,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -681,16 +681,16 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> shifted_a; std::vector<int> shifted_a;
if (cell->type.in( ID($shl), ID($sshl))) if (cell->type.in( TW($shl), TW($sshl)))
shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr)) if (cell->type == TW($shr))
shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr)) if (cell->type == TW($sshr))
shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type.in(ID($shift), ID($shiftx))) if (cell->type.in(TW($shift), TW($shiftx)))
shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
ez->assume(ez->vec_eq(shifted_a, yy)); ez->assume(ez->vec_eq(shifted_a, yy));
@ -702,7 +702,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> undef_a_shifted; std::vector<int> undef_a_shifted;
extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; extend_bit = cell->type == TW($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
if (cell->parameters[ID::A_SIGNED].as_bool()) if (cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = undef_a.back(); extend_bit = undef_a.back();
@ -711,19 +711,19 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
while (undef_y.size() > undef_a.size()) while (undef_y.size() > undef_a.size())
undef_a.push_back(extend_bit); undef_a.push_back(extend_bit);
if (cell->type.in(ID($shl), ID($sshl))) if (cell->type.in(TW($shl), TW($sshl)))
undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr)) if (cell->type == TW($shr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr)) if (cell->type == TW($sshr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shift)) if (cell->type == TW($shift))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shiftx)) if (cell->type == TW($shiftx))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
@ -734,7 +734,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($mul)) if (cell->type == TW($mul))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -761,7 +761,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($macc), ID($macc_v2))) if (cell->type.in(TW($macc), TW($macc_v2)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -811,7 +811,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
std::vector<int> undef_c; std::vector<int> undef_c;
if (cell->type == ID($macc_v2)) if (cell->type == TW($macc_v2))
undef_c = importUndefSigSpec(cell->getPort(TW::C), timestep); undef_c = importUndefSigSpec(cell->getPort(TW::C), timestep);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@ -830,7 +830,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -878,14 +878,14 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
floored_eq_trunc = ez->CONST_TRUE; floored_eq_trunc = ez->CONST_TRUE;
} }
if (cell->type == ID($div)) { if (cell->type == TW($div)) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u))); ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
else else
ez->assume(ez->vec_eq(y_tmp, y_u)); ez->assume(ez->vec_eq(y_tmp, y_u));
} else if (cell->type == ID($mod)) { } else if (cell->type == TW($mod)) {
ez->assume(ez->vec_eq(y_tmp, modulo_trunc)); ez->assume(ez->vec_eq(y_tmp, modulo_trunc));
} else if (cell->type == ID($divfloor)) { } else if (cell->type == TW($divfloor)) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite( ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(
ez->XOR(a.back(), b.back()), ez->XOR(a.back(), b.back()),
@ -898,7 +898,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
))); )));
else else
ez->assume(ez->vec_eq(y_tmp, y_u)); ez->assume(ez->vec_eq(y_tmp, y_u));
} else if (cell->type == ID($modfloor)) { } else if (cell->type == TW($modfloor)) {
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b)))); ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b))));
} }
@ -906,7 +906,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
ez->assume(ez->expression(ezSAT::OpOr, b)); ez->assume(ez->expression(ezSAT::OpOr, b));
} else { } else {
std::vector<int> div_zero_result; std::vector<int> div_zero_result;
if (cell->type.in(ID($div), ID($divfloor))) { if (cell->type.in(TW($div), TW($divfloor))) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) {
std::vector<int> all_ones(y.size(), ez->CONST_TRUE); std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
std::vector<int> only_first_one(y.size(), ez->CONST_FALSE); std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);
@ -916,7 +916,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
div_zero_result.insert(div_zero_result.end(), cell->getPort(TW::A).size(), ez->CONST_TRUE); div_zero_result.insert(div_zero_result.end(), cell->getPort(TW::A).size(), ez->CONST_TRUE);
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
} }
} else if (cell->type.in(ID($mod), ID($modfloor))) { } else if (cell->type.in(TW($mod), TW($modfloor))) {
// a mod 0 = a // a mod 0 = a
int copy_a_bits = min(cell->getPort(TW::A).size(), cell->getPort(TW::B).size()); int copy_a_bits = min(cell->getPort(TW::A).size(), cell->getPort(TW::B).size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
@ -936,7 +936,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($lut)) if (cell->type == TW($lut))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -986,7 +986,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($sop)) if (cell->type == TW($sop))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0); int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0);
@ -1068,7 +1068,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($fa)) if (cell->type == TW($fa))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -1104,7 +1104,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($lcu)) if (cell->type == TW($lcu))
{ {
std::vector<int> p = importDefSigSpec(cell->getPort(TW::P), timestep); std::vector<int> p = importDefSigSpec(cell->getPort(TW::P), timestep);
std::vector<int> g = importDefSigSpec(cell->getPort(TW::G), timestep); std::vector<int> g = importDefSigSpec(cell->getPort(TW::G), timestep);
@ -1136,7 +1136,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($alu)) if (cell->type == TW($alu))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -1202,7 +1202,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($slice)) if (cell->type == TW($slice))
{ {
RTLIL::SigSpec a = cell->getPort(TW::A); RTLIL::SigSpec a = cell->getPort(TW::A);
RTLIL::SigSpec y = cell->getPort(TW::Y); RTLIL::SigSpec y = cell->getPort(TW::Y);
@ -1210,7 +1210,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($concat)) if (cell->type == TW($concat))
{ {
RTLIL::SigSpec a = cell->getPort(TW::A); RTLIL::SigSpec a = cell->getPort(TW::A);
RTLIL::SigSpec b = cell->getPort(TW::B); RTLIL::SigSpec b = cell->getPort(TW::B);
@ -1223,7 +1223,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (timestep > 0 && (cell->is_builtin_ff() || cell->type == ID($anyinit))) if (timestep > 0 && (cell->is_builtin_ff() || cell->type == TW($anyinit)))
{ {
FfData ff(nullptr, cell); FfData ff(nullptr, cell);
@ -1303,7 +1303,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($anyconst)) if (cell->type == TW($anyconst))
{ {
if (timestep < 2) { if (timestep < 2) {
if (model_undef && def_formal) { if (model_undef && def_formal) {
@ -1335,7 +1335,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($anyseq)) if (cell->type == TW($anyseq))
{ {
if (model_undef && def_formal) { if (model_undef && def_formal) {
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> undef_q = importUndefSigSpec(cell->getPort(TW::Y), timestep);
@ -1345,7 +1345,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($_BUF_), ID($equiv))) if (cell->type.in(TW($_BUF_), TW($equiv)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -1364,7 +1364,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($initstate)) if (cell->type == TW($initstate))
{ {
auto key = make_pair(prefix, timestep); auto key = make_pair(prefix, timestep);
if (initstates.count(key) == 0) if (initstates.count(key) == 0)
@ -1383,7 +1383,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($assert)) if (cell->type == TW($assert))
{ {
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
asserts_a[pf].append((*sigmap)(cell->getPort(TW::A))); asserts_a[pf].append((*sigmap)(cell->getPort(TW::A)));
@ -1391,7 +1391,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type == ID($assume)) if (cell->type == TW($assume))
{ {
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
assumes_a[pf].append((*sigmap)(cell->getPort(TW::A))); assumes_a[pf].append((*sigmap)(cell->getPort(TW::A)));
@ -1399,7 +1399,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true; return true;
} }
if (cell->type.in(ID($scopeinfo), ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($scopeinfo), TW($input_port), TW($output_port), TW($public)))
{ {
return true; return true;
} }
@ -1415,9 +1415,9 @@ void report_missing_model(bool warn_only, RTLIL::Cell* cell)
{ {
std::string s; std::string s;
if (cell->is_builtin_ff()) if (cell->is_builtin_ff())
s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", cell, cell->type.unescape()); s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", cell, cell->type.unescaped());
else else
s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescape()); s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescaped());
if (warn_only) { if (warn_only) {
log_formatted_warning_noprefix(s); log_formatted_warning_noprefix(s);

View File

@ -102,7 +102,7 @@ struct SatGen
else else
vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE); vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE);
} else { } else {
std::string wire_name = bit.wire->name.unescape(); std::string wire_name = bit.wire->module->design->twines.unescaped_str(bit.wire->meta_->name);
std::string name = pf + std::string name = pf +
(bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset)); (bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset));
vec.push_back(ez->frozen_literal(name)); vec.push_back(ez->frozen_literal(name));

View File

@ -55,7 +55,7 @@ void ModuleHdlnameIndex::index_cells()
void ModuleHdlnameIndex::index_scopeinfo_cells() void ModuleHdlnameIndex::index_scopeinfo_cells()
{ {
auto cells = module->cells(); auto cells = module->cells();
index_items(cells.begin(), cells.end(), [](Cell *cell) { return cell->type == ID($scopeinfo); }); index_items(cells.begin(), cells.end(), [](Cell *cell) { return cell->type == TW($scopeinfo); });
} }
std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor) std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor)
@ -69,7 +69,7 @@ std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor)
continue; continue;
} }
Cell *cell = cursor.entry().cell(); Cell *cell = cursor.entry().cell();
if (cell == nullptr || cell->type != ID($scopeinfo)) { if (cell == nullptr || cell->type != TW($scopeinfo)) {
result.push_back(""); result.push_back("");
result.push_back(""); result.push_back("");
continue; continue;
@ -99,14 +99,14 @@ static const char *attr_prefix(ScopeinfoAttrs attrs)
bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id)
{ {
log_assert(scopeinfo->type == ID($scopeinfo)); log_assert(scopeinfo->type == TW($scopeinfo));
return scopeinfo->has_attribute(attr_prefix(attrs) + id.unescape()); return scopeinfo->has_attribute(attr_prefix(attrs) + design->twines.unescaped_str(id));
} }
RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id)
{ {
log_assert(scopeinfo->type == ID($scopeinfo)); log_assert(scopeinfo->type == TW($scopeinfo));
auto found = scopeinfo->attributes.find(attr_prefix(attrs) + id.unescape()); auto found = scopeinfo->attributes.find(attr_prefix(attrs) + design->twines.unescaped_str(id));
if (found == scopeinfo->attributes.end()) if (found == scopeinfo->attributes.end())
return RTLIL::Const(); return RTLIL::Const();
return found->second; return found->second;

View File

@ -29,15 +29,15 @@ struct TimingInfo
{ {
struct NameBit struct NameBit
{ {
RTLIL::IdString name; TwineRef name;
int offset; int offset;
NameBit() : offset(0) {} NameBit() : offset(0) {}
NameBit(const RTLIL::IdString name, int offset) : name(name), offset(offset) {} NameBit(TwineRef name, int offset) : name(name), offset(offset) {}
explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->name), offset(b.offset) {} explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->meta_->name), offset(b.offset) {}
bool operator==(const NameBit& nb) const { return nb.name == name && nb.offset == offset; } bool operator==(const NameBit& nb) const { return nb.name == name && nb.offset == offset; }
bool operator!=(const NameBit& nb) const { return !operator==(nb); } bool operator!=(const NameBit& nb) const { return !operator==(nb); }
std::optional<SigBit> get_connection(RTLIL::Cell *cell) { std::optional<SigBit> get_connection(RTLIL::Cell *cell) {
TwineRef port_name = cell->module->design->twines.lookup(name.str()); TwineRef port_name = name;
if (!cell->hasPort(port_name)) if (!cell->hasPort(port_name))
return {}; return {};
auto &port = cell->getPort(port_name); auto &port = cell->getPort(port_name);
@ -71,7 +71,7 @@ struct TimingInfo
bool has_inputs; bool has_inputs;
}; };
dict<RTLIL::IdString, ModuleTiming> data; dict<TwineRef, ModuleTiming> data;
TimingInfo() TimingInfo()
{ {
@ -93,12 +93,12 @@ struct TimingInfo
const ModuleTiming& setup_module(RTLIL::Module *module) const ModuleTiming& setup_module(RTLIL::Module *module)
{ {
auto r = data.insert(RTLIL::IdString(module->design->twines.str(module->meta_->name))); auto r = data.insert(module->meta_->name);
log_assert(r.second); log_assert(r.second);
auto &t = r.first->second; auto &t = r.first->second;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type == ID($specify2)) { if (cell->type == TW($specify2)) {
auto en = cell->getPort(TW::EN); auto en = cell->getPort(TW::EN);
if (en.is_fully_const() && !en.as_bool()) if (en.is_fully_const() && !en.as_bool())
continue; continue;
@ -136,7 +136,7 @@ struct TimingInfo
} }
} }
} }
else if (cell->type == ID($specify3)) { else if (cell->type == TW($specify3)) {
auto src = cell->getPort(TW::SRC).as_bit(); auto src = cell->getPort(TW::SRC).as_bit();
auto dst = cell->getPort(TW::DST); auto dst = cell->getPort(TW::DST);
if (!src.wire || !src.wire->port_input) if (!src.wire || !src.wire->port_input)
@ -160,9 +160,9 @@ struct TimingInfo
} }
} }
} }
else if (cell->type == ID($specrule)) { else if (cell->type == TW($specrule)) {
IdString type = cell->getParam(ID::TYPE).decode_string(); IdString type = cell->getParam(ID::TYPE).decode_string();
if (type != ID($setup) && type != ID($setuphold)) if (type != TW($setup) && type != TW($setuphold))
continue; continue;
auto src = cell->getPort(TW::SRC); auto src = cell->getPort(TW::SRC);
auto dst = cell->getPort(TW::DST).as_bit(); auto dst = cell->getPort(TW::DST).as_bit();
@ -198,10 +198,10 @@ struct TimingInfo
return t; return t;
} }
decltype(data)::const_iterator find(RTLIL::IdString module_name) const { return data.find(module_name); } decltype(data)::const_iterator find(TwineRef module_name) const { return data.find(module_name); }
decltype(data)::const_iterator end() const { return data.end(); } decltype(data)::const_iterator end() const { return data.end(); }
int count(RTLIL::IdString module_name) const { return data.count(module_name); } int count(TwineRef module_name) const { return data.count(module_name); }
const ModuleTiming& at(RTLIL::IdString module_name) const { return data.at(module_name); } const ModuleTiming& at(TwineRef module_name) const { return data.at(module_name); }
}; };
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View File

@ -91,6 +91,20 @@ struct TW {
throw "unknown twine id"; throw "unknown twine id";
} }
static constexpr const char* static_names[] = {
#define X(N) #N,
#include "kernel/constids.inc"
#undef X
};
static std::string str(TwineRef ref) {
TwineRef idx = ref.untag();
if (idx.value >= STATIC_TWINE_END) return {};
std::string result = ref.is_public() ? "\\" : "";
result += static_names[idx.value];
return result;
}
}; };
#define TW(id) (size_t)lookup_well_known_id(#id) #define TW(id) (size_t)lookup_well_known_id(#id)
@ -102,7 +116,6 @@ struct Twine {
struct Suffix { struct Suffix {
TwineRef prefix; TwineRef prefix;
std::string tail; std::string tail;
// TODO check
auto operator<=>(const Suffix&) const = default; auto operator<=>(const Suffix&) const = default;
}; };

View File

@ -76,9 +76,9 @@ public:
RTLIL::Cell *addCell(TwineRef name, TwineRef type); RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other); RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
RTLIL::Cell *addCell(Twine &&name, TwineRef type); RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type); RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
// NEW_ID analog for twine names; see NEW_TWINE in yosys_common.h. // NEW_ID analog for twine names; see NEW_TWINE in yosys_common.h.
// Returned refs are twine_staging-local and die at the next commit. // Returned refs are twine_staging-local and die at the next commit.

View File

@ -964,7 +964,7 @@ static char *readline_obj_generator(const char *text, int state)
RTLIL::Module *module = design->module(design->selected_active_module); RTLIL::Module *module = design->module(design->selected_active_module);
for (auto w : module->wires()) for (auto w : module->wires())
if (w->name.unescape().compare(0, len, text) == 0) if (design->twines.unescaped_str(w->meta_->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(w->name.unescape().c_str())); obj_names.push_back(strdup(w->name.unescape().c_str()));
for (auto &it : module->memories) { for (auto &it : module->memories) {

View File

@ -50,7 +50,7 @@ OBJS += passes/cmds/xprop.o
OBJS += passes/cmds/dft_tag.o OBJS += passes/cmds/dft_tag.o
OBJS += passes/cmds/future.o OBJS += passes/cmds/future.o
OBJS += passes/cmds/box_derive.o OBJS += passes/cmds/box_derive.o
OBJS += passes/cmds/example_dt.o #OBJS += passes/cmds/example_dt.o
OBJS += passes/cmds/portarcs.o OBJS += passes/cmds/portarcs.o
OBJS += passes/cmds/wrapcell.o OBJS += passes/cmds/wrapcell.o
OBJS += passes/cmds/setenv.o OBJS += passes/cmds/setenv.o

View File

@ -174,7 +174,7 @@ unsigned int abstract_state(Module* mod, EnableLogic enable, const std::vector<S
std::vector<FfData> ffs; std::vector<FfData> ffs;
// Abstract flop inputs if they're driving a selected output rep // Abstract flop inputs if they're driving a selected output rep
for (auto cell : mod->cells()) { for (auto cell : mod->cells()) {
if (!ct.cell_types.count(cell->type)) if (!ct.cell_types.count(cell->type_impl))
continue; continue;
FfData ff(nullptr, cell); FfData ff(nullptr, cell);
if (ff.has_sr) if (ff.has_sr)
@ -265,7 +265,7 @@ unsigned int abstract_value(Module* mod, EnableLogic enable, const std::vector<S
unsigned int changed = 0; unsigned int changed = 0;
std::vector<Cell*> cells_snapshot = mod->cells(); std::vector<Cell*> cells_snapshot = mod->cells();
for (auto cell : cells_snapshot) { for (auto cell : cells_snapshot) {
if (cell->type.in(ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($input_port), TW($output_port), TW($public)))
continue; continue;
for (auto conn : cell->connections()) for (auto conn : cell->connections())
if (cell->output(conn.first)) { if (cell->output(conn.first)) {

View File

@ -42,7 +42,8 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
log_error("Could not find wire with name \"%s\".\n", name); log_error("Could not find wire with name \"%s\".\n", name);
} }
else { else {
RTLIL::Cell *formal_cell = module->addCell(NEW_TWINE, "$" + celltype); TwineRef _type = module->design->twines.add(Twine{"$" + celltype});
RTLIL::Cell *formal_cell = module->addCell(NEW_TWINE, _type);
formal_cell->setPort(TW::A, wire); formal_cell->setPort(TW::A, wire);
if(enable_name == "") { if(enable_name == "") {
formal_cell->setPort(TW::EN, State::S1); formal_cell->setPort(TW::EN, State::S1);

View File

@ -100,7 +100,7 @@ struct BoxDerivePass : Pass {
continue; continue;
if (!done.count(index)) { if (!done.count(index)) {
IdString derived_type = base->derive(d, cell->parameters); TwineRef derived_type = base->derive(d, cell->parameters);
Module *derived = d->module(derived_type); Module *derived = d->module(derived_type);
log_assert(derived && "Failed to derive module\n"); log_assert(derived && "Failed to derive module\n");
log("derived %s\n", derived_type); log("derived %s\n", derived_type);

View File

@ -87,7 +87,7 @@ int check_bufnorm_wire(RTLIL::Module *module, RTLIL::Wire *wire)
if (!dsig.is_wire() || dsig.as_wire() != wire) if (!dsig.is_wire() || dsig.as_wire() != wire)
log_warning("bufNorm: wire %s.%s driverCell_ %s port %s does not connect back to this wire\n", log_warning("bufNorm: wire %s.%s driverCell_ %s port %s does not connect back to this wire\n",
log_id(module), log_id(wire), log_id(driver), module->design->twines.str(dport).c_str()), counter++; log_id(module), log_id(wire), log_id(driver), module->design->twines.str(dport).c_str()), counter++;
if (wire->port_input && !wire->port_output && driver->type != ID($input_port)) if (wire->port_input && !wire->port_output && driver->type != TW($input_port))
log_warning("bufNorm: module input wire %s.%s is driven by non-$input_port cell %s of type %s\n", log_warning("bufNorm: module input wire %s.%s is driven by non-$input_port cell %s of type %s\n",
log_id(module), log_id(wire), log_id(driver), log_id(driver->type)), counter++; log_id(module), log_id(wire), log_id(driver), log_id(driver->type)), counter++;
} }
@ -295,14 +295,14 @@ struct CheckPass : public Pass {
// Only those cell types for which the edge data can expode quadratically // Only those cell types for which the edge data can expode quadratically
// in port widths are those for us to check. // in port widths are those for us to check.
if (!cell->type.in( if (!cell->type.in(
ID($add), ID($sub), TW($add), TW($sub),
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx),
ID($pmux), ID($bmux))) TW($pmux), TW($bmux)))
return false; return false;
int in_widths = 0, out_widths = 0; int in_widths = 0, out_widths = 0;
if (cell->type.in(ID($pmux), ID($bmux))) { if (cell->type.in(TW($pmux), TW($bmux))) {
// We're skipping inputs A and B, since each of their bits contributes only one edge // We're skipping inputs A and B, since each of their bits contributes only one edge
in_widths = GetSize(cell->getPort(TW::S)); in_widths = GetSize(cell->getPort(TW::S));
out_widths = GetSize(cell->getPort(TW::Y)); out_widths = GetSize(cell->getPort(TW::Y));
@ -358,17 +358,17 @@ struct CheckPass : public Pass {
pool<Cell *> coarsened_cells; pool<Cell *> coarsened_cells;
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($input_port), ID($output_port), ID($public))) if (cell->type.in(TW($input_port), TW($output_port), TW($public)))
continue; continue;
if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) {
if (allow_tbuf && cell->type == ID($_TBUF_)) goto cell_allowed; if (allow_tbuf && cell->type == TW($_TBUF_)) goto cell_allowed;
log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", module, cell, cell->type.unescape()); log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", module, cell, cell->type.unescaped());
counter++; counter++;
cell_allowed:; cell_allowed:;
} }
if (cell->type == ID($connect)) { if (cell->type == TW($connect)) {
// Inefficient, but rare case in sane design // Inefficient, but rare case in sane design
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -406,13 +406,13 @@ struct CheckPass : public Pass {
wire_drivers_count[bit]++; wire_drivers_count[bit]++;
if (output && (bit.wire || !input)) if (output && (bit.wire || !input))
wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", cell->module->design->twines.str(conn.first).c_str(), i, wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", cell->module->design->twines.str(conn.first).c_str(), i,
cell, cell->type.unescape())); cell, cell->type.unescaped()));
if (output) if (output)
driver_cells[bit] = cell; driver_cells[bit] = cell;
} }
} }
if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2)) \ if (yosys_celltypes.cell_evaluable(cell->type.ref()) || cell->type.in(TW($mem_v2), TW($memrd), TW($memrd_v2)) \
|| cell->is_builtin_ff()) { || cell->is_builtin_ff()) {
if (!edges_db.add_edges_from_cell(cell)) if (!edges_db.add_edges_from_cell(cell))
coarsened_cells.insert(cell); coarsened_cells.insert(cell);
@ -529,7 +529,7 @@ struct CheckPass : public Pass {
driver_src = stringf(" source: %s", src_attr); driver_src = stringf(" source: %s", src_attr);
} }
message += stringf(" cell %s (%s)%s\n", driver, driver->type.unescape(), driver_src); message += stringf(" cell %s (%s)%s\n", driver, design->twines.unescaped_str(driver->type), driver_src);
if (!coarsened_cells.count(driver)) { if (!coarsened_cells.count(driver)) {
MatchingEdgePrinter printer(message, sigmap, prev, bit); MatchingEdgePrinter printer(message, sigmap, prev, bit);

View File

@ -24,42 +24,42 @@
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
static RTLIL::IdString formal_flavor(RTLIL::Cell *cell) static TwineRef formal_flavor(RTLIL::Cell *cell)
{ {
if (cell->type != ID($check)) if (cell->type != TW($check))
return cell->type; return cell->type_impl;
std::string flavor_param = cell->getParam(ID(FLAVOR)).decode_string(); std::string flavor_param = cell->getParam(ID(FLAVOR)).decode_string();
if (flavor_param == "assert") if (flavor_param == "assert")
return ID($assert); return TW($assert);
else if (flavor_param == "assume") else if (flavor_param == "assume")
return ID($assume); return TW($assume);
else if (flavor_param == "cover") else if (flavor_param == "cover")
return ID($cover); return TW($cover);
else if (flavor_param == "live") else if (flavor_param == "live")
return ID($live); return TW($live);
else if (flavor_param == "fair") else if (flavor_param == "fair")
return ID($fair); return TW($fair);
else else
log_abort(); log_abort();
} }
static void set_formal_flavor(RTLIL::Cell *cell, RTLIL::IdString flavor) static void set_formal_flavor(RTLIL::Cell *cell, TwineRef flavor)
{ {
if (cell->type != ID($check)) { if (cell->type != TW($check)) {
cell->type_impl = cell->module->design->twines.add(Twine{flavor.str()}); cell->type_impl = flavor;
return; return;
} }
if (flavor == ID($assert)) if (flavor == TW($assert))
cell->setParam(ID(FLAVOR), std::string("assert")); cell->setParam(ID(FLAVOR), std::string("assert"));
else if (flavor == ID($assume)) else if (flavor == TW($assume))
cell->setParam(ID(FLAVOR), std::string("assume")); cell->setParam(ID(FLAVOR), std::string("assume"));
else if (flavor == ID($cover)) else if (flavor == TW($cover))
cell->setParam(ID(FLAVOR), std::string("cover")); cell->setParam(ID(FLAVOR), std::string("cover"));
else if (flavor == ID($live)) else if (flavor == TW($live))
cell->setParam(ID(FLAVOR), std::string("live")); cell->setParam(ID(FLAVOR), std::string("live"));
else if (flavor == ID($fair)) else if (flavor == TW($fair))
cell->setParam(ID(FLAVOR), std::string("fair")); cell->setParam(ID(FLAVOR), std::string("fair"));
else else
log_abort(); log_abort();
@ -67,7 +67,7 @@ static void set_formal_flavor(RTLIL::Cell *cell, RTLIL::IdString flavor)
static bool is_triggered_check_cell(RTLIL::Cell * cell) static bool is_triggered_check_cell(RTLIL::Cell * cell)
{ {
return cell->type == ID($check) && cell->getParam(ID(TRG_ENABLE)).as_bool(); return cell->type == TW($check) && cell->getParam(ID(TRG_ENABLE)).as_bool();
} }
struct ChformalPass : public Pass { struct ChformalPass : public Pass {
@ -136,7 +136,7 @@ struct ChformalPass : public Pass {
bool live2fair = false; bool live2fair = false;
bool fair2live = false; bool fair2live = false;
pool<IdString> constr_types; pool<TwineRef> constr_types;
char mode = 0; char mode = 0;
int mode_arg = 0; int mode_arg = 0;
@ -144,23 +144,23 @@ struct ChformalPass : public Pass {
for (argidx = 1; argidx < args.size(); argidx++) for (argidx = 1; argidx < args.size(); argidx++)
{ {
if (args[argidx] == "-assert") { if (args[argidx] == "-assert") {
constr_types.insert(ID($assert)); constr_types.insert(TW($assert));
continue; continue;
} }
if (args[argidx] == "-assume") { if (args[argidx] == "-assume") {
constr_types.insert(ID($assume)); constr_types.insert(TW($assume));
continue; continue;
} }
if (args[argidx] == "-live") { if (args[argidx] == "-live") {
constr_types.insert(ID($live)); constr_types.insert(TW($live));
continue; continue;
} }
if (args[argidx] == "-fair") { if (args[argidx] == "-fair") {
constr_types.insert(ID($fair)); constr_types.insert(TW($fair));
continue; continue;
} }
if (args[argidx] == "-cover") { if (args[argidx] == "-cover") {
constr_types.insert(ID($cover)); constr_types.insert(TW($cover));
continue; continue;
} }
if (mode == 0 && args[argidx] == "-remove") { if (mode == 0 && args[argidx] == "-remove") {
@ -222,11 +222,11 @@ struct ChformalPass : public Pass {
design->sigNormalize(false); design->sigNormalize(false);
if (constr_types.empty()) { if (constr_types.empty()) {
constr_types.insert(ID($assert)); constr_types.insert(TW($assert));
constr_types.insert(ID($assume)); constr_types.insert(TW($assume));
constr_types.insert(ID($live)); constr_types.insert(TW($live));
constr_types.insert(ID($fair)); constr_types.insert(TW($fair));
constr_types.insert(ID($cover)); constr_types.insert(TW($cover));
} }
if (assert2assume && assert2cover) { if (assert2assume && assert2cover) {
@ -274,13 +274,13 @@ struct ChformalPass : public Pass {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (cell->type == ID($ff)) { if (cell->type == TW($ff)) {
SigSpec D = sigmap(cell->getPort(TW::D)); SigSpec D = sigmap(cell->getPort(TW::D));
SigSpec Q = sigmap(cell->getPort(TW::Q)); SigSpec Q = sigmap(cell->getPort(TW::Q));
for (int i = 0; i < GetSize(D); i++) for (int i = 0; i < GetSize(D); i++)
ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false)); ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
} }
if (cell->type == ID($dff)) { if (cell->type == TW($dff)) {
SigSpec D = sigmap(cell->getPort(TW::D)); SigSpec D = sigmap(cell->getPort(TW::D));
SigSpec Q = sigmap(cell->getPort(TW::Q)); SigSpec Q = sigmap(cell->getPort(TW::Q));
SigSpec C = sigmap(cell->getPort(TW::CLK)); SigSpec C = sigmap(cell->getPort(TW::CLK));
@ -301,7 +301,7 @@ struct ChformalPass : public Pass {
cell->setParam(ID::TRG_POLARITY, false); cell->setParam(ID::TRG_POLARITY, false);
} }
IdString flavor = formal_flavor(cell); TwineRef flavor = formal_flavor(cell);
while (true) while (true)
{ {
@ -312,8 +312,8 @@ struct ChformalPass : public Pass {
break; break;
if (!init_zero.count(EN)) { if (!init_zero.count(EN)) {
if (flavor == ID($cover)) break; if (flavor == TW($cover)) break;
if (flavor.in(ID($assert), ID($assume)) && !init_one.count(A)) break; if (flavor.in(TW($assert), TW($assume)) && !init_one.count(A)) break;
} }
const auto &A_map = ffmap.at(A); const auto &A_map = ffmap.at(A);
@ -372,8 +372,8 @@ struct ChformalPass : public Pass {
{ {
for (auto cell : constr_cells) for (auto cell : constr_cells)
{ {
if (cell->type == ID($check)) { if (cell->type == TW($check)) {
Cell *cover = module->addCell(NEW_TWINE_SUFFIX("coverenable"), ID($check)); Cell *cover = module->addCell(NEW_TWINE_SUFFIX("coverenable"), TW::$check);
cover->attributes = cell->attributes; cover->attributes = cell->attributes;
if (cell->src_id() != Twine::Null && module->design) if (cell->src_id() != Twine::Null && module->design)
cover->set_src_id(cell->src_id()); cover->set_src_id(cell->src_id());
@ -395,24 +395,24 @@ struct ChformalPass : public Pass {
if (mode == 'c') if (mode == 'c')
{ {
for (auto cell : constr_cells) { for (auto cell : constr_cells) {
IdString flavor = formal_flavor(cell); TwineRef flavor = formal_flavor(cell);
if (assert2assume && flavor == ID($assert)) if (assert2assume && flavor == TW($assert))
set_formal_flavor(cell, ID($assume)); set_formal_flavor(cell, TW($assume));
if (assert2cover && flavor == ID($assert)) if (assert2cover && flavor == TW($assert))
set_formal_flavor(cell, ID($cover)); set_formal_flavor(cell, TW($cover));
else if (assume2assert && flavor == ID($assume)) else if (assume2assert && flavor == TW($assume))
set_formal_flavor(cell, ID($assert)); set_formal_flavor(cell, TW($assert));
else if (live2fair && flavor == ID($live)) else if (live2fair && flavor == TW($live))
set_formal_flavor(cell, ID($fair)); set_formal_flavor(cell, TW($fair));
else if (fair2live && flavor == ID($fair)) else if (fair2live && flavor == TW($fair))
set_formal_flavor(cell, ID($live)); set_formal_flavor(cell, TW($live));
} }
} }
else else
if (mode == 'l') if (mode == 'l')
{ {
for (auto cell : constr_cells) { for (auto cell : constr_cells) {
if (cell->type != ID($check)) if (cell->type != TW($check))
continue; continue;
if (is_triggered_check_cell(cell)) if (is_triggered_check_cell(cell))
@ -431,7 +431,7 @@ struct ChformalPass : public Pass {
plain_cell->setPort(TW::A, sig_a); plain_cell->setPort(TW::A, sig_a);
plain_cell->setPort(TW::EN, sig_en); plain_cell->setPort(TW::EN, sig_en);
if (plain_cell->type.in(ID($assert), ID($assume))) if (plain_cell->type.in(TW($assert), TW($assume)))
sig_a = module->Not(NEW_TWINE, sig_a); sig_a = module->Not(NEW_TWINE, sig_a);
SigBit combined_en = module->And(NEW_TWINE, sig_a, sig_en); SigBit combined_en = module->And(NEW_TWINE, sig_a, sig_en);

View File

@ -66,7 +66,7 @@ struct CleanZeroWidthPass : public Pass {
{ {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (!ct.cell_known(cell->type)) { if (!ct.cell_known(cell->type_impl)) {
// User-defined cell: just prune zero-width connections. // User-defined cell: just prune zero-width connections.
for (auto it: cell->connections()) { for (auto it: cell->connections()) {
if (GetSize(it.second) == 0) { if (GetSize(it.second) == 0) {
@ -80,7 +80,7 @@ struct CleanZeroWidthPass : public Pass {
if (GetSize(cell->getPort(TW::Q)) == 0) { if (GetSize(cell->getPort(TW::Q)) == 0) {
module->remove(cell); module->remove(cell);
} }
} else if (cell->type.in(ID($pmux), ID($bmux), ID($demux))) { } else if (cell->type.in(TW($pmux), TW($bmux), TW($demux))) {
// Remove altogether if WIDTH is 0, replace with // Remove altogether if WIDTH is 0, replace with
// a connection if S_WIDTH is 0. // a connection if S_WIDTH is 0.
if (cell->getParam(ID::WIDTH).as_int() == 0) { if (cell->getParam(ID::WIDTH).as_int() == 0) {
@ -90,7 +90,7 @@ struct CleanZeroWidthPass : public Pass {
module->connect(cell->getPort(TW::Y), cell->getPort(TW::A)); module->connect(cell->getPort(TW::Y), cell->getPort(TW::A));
module->remove(cell); module->remove(cell);
} }
} else if (cell->type == ID($concat)) { } else if (cell->type == TW($concat)) {
// If a concat has a zero-width input: replace with direct // If a concat has a zero-width input: replace with direct
// connection to the other input. // connection to the other input.
if (cell->getParam(ID::A_WIDTH).as_int() == 0) { if (cell->getParam(ID::A_WIDTH).as_int() == 0) {
@ -100,17 +100,17 @@ struct CleanZeroWidthPass : public Pass {
module->connect(cell->getPort(TW::Y), cell->getPort(TW::A)); module->connect(cell->getPort(TW::Y), cell->getPort(TW::A));
module->remove(cell); module->remove(cell);
} }
} else if (cell->type == ID($fsm)) { } else if (cell->type == TW($fsm)) {
// TODO: not supported // TODO: not supported
} else if (cell->is_mem_cell()) { } else if (cell->is_mem_cell()) {
// Skip — will be handled below. // Skip — will be handled below.
} else if (cell->type == ID($lut)) { } else if (cell->type == TW($lut)) {
// Zero-width LUT is just a const driver. // Zero-width LUT is just a const driver.
if (cell->getParam(ID::WIDTH).as_int() == 0) { if (cell->getParam(ID::WIDTH).as_int() == 0) {
module->connect(cell->getPort(TW::Y), cell->getParam(ID::LUT)[0]); module->connect(cell->getPort(TW::Y), cell->getParam(ID::LUT)[0]);
module->remove(cell); module->remove(cell);
} }
} else if (cell->type == ID($sop)) { } else if (cell->type == TW($sop)) {
// Zero-width SOP is just a const driver. // Zero-width SOP is just a const driver.
if (cell->getParam(ID::WIDTH).as_int() == 0) { if (cell->getParam(ID::WIDTH).as_int() == 0) {
// The value is 1 iff DEPTH is non-0. // The value is 1 iff DEPTH is non-0.
@ -128,7 +128,7 @@ struct CleanZeroWidthPass : public Pass {
// A and B to 1-bit if their width is 0. // A and B to 1-bit if their width is 0.
if (cell->getParam(ID::Y_WIDTH).as_int() == 0) { if (cell->getParam(ID::Y_WIDTH).as_int() == 0) {
module->remove(cell); module->remove(cell);
} else if (cell->type.in(ID($macc), ID($macc_v2))) { } else if (cell->type.in(TW($macc), TW($macc_v2))) {
// TODO: fixing zero-width A and B not supported. // TODO: fixing zero-width A and B not supported.
} else { } else {
if (cell->getParam(ID::A_WIDTH).as_int() == 0) { if (cell->getParam(ID::A_WIDTH).as_int() == 0) {

View File

@ -36,7 +36,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap &
for (auto cell : module->cells()) for (auto cell : module->cells())
for (auto &port : cell->connections_) for (auto &port : cell->connections_)
if (ct.cell_output(cell->type, port.first)) if (ct.cell_output(cell->type.ref(), port.first))
sigmap(port.second).replace(sig, dummy_wire, &port.second); sigmap(port.second).replace(sig, dummy_wire, &port.second);
bool need_fixup = false; bool need_fixup = false;

View File

@ -268,7 +268,7 @@ struct DesignPass : public Pass {
{ {
log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix)); log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix));
RTLIL::Module *t = mod->clone(copy_to_design, RTLIL::IdString(prefix)); RTLIL::Module *t = mod->clone(copy_to_design, copy_to_design->twines.add(Twine{prefix}));
t->attributes.erase(ID::top); t->attributes.erase(ID::top);
queue.insert(t); queue.insert(t);
@ -297,7 +297,7 @@ struct DesignPass : public Pass {
if (copy_to_design->module(trg_name) != nullptr) if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name)); copy_to_design->remove(copy_to_design->module(trg_name));
RTLIL::Module *t = fmod->clone(copy_to_design, RTLIL::IdString(trg_name)); RTLIL::Module *t = fmod->clone(copy_to_design, copy_to_design->twines.add(Twine{trg_name}));
t->attributes.erase(ID::top); t->attributes.erase(ID::top);
queue.insert(t); queue.insert(t);
@ -321,7 +321,7 @@ struct DesignPass : public Pass {
if (copy_to_design->module(trg_name) != nullptr) if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name)); copy_to_design->remove(copy_to_design->module(trg_name));
mod->clone(copy_to_design, RTLIL::IdString(trg_name)); mod->clone(copy_to_design, copy_to_design->twines.add(Twine{trg_name}));
} }
} }

View File

@ -90,10 +90,10 @@ struct DftTagWorker {
bool design_changed = false; bool design_changed = false;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type == ID($overwrite_tag)) if (cell->type == TW($overwrite_tag))
overwrite_cells.push_back(cell); overwrite_cells.push_back(cell);
if (cell->type == ID($original_tag)) if (cell->type == TW($original_tag))
original_cells.push_back(cell); original_cells.push_back(cell);
} }
@ -137,7 +137,7 @@ struct DftTagWorker {
if (found == modwalker.signal_consumers.end()) if (found == modwalker.signal_consumers.end())
return; return;
for (auto &consumer : found->second) { for (auto &consumer : found->second) {
if (consumer.cell->type.in(ID($original_tag))) if (consumer.cell->type.in(TW($original_tag)))
continue; continue;
if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit) if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit)
continue; continue;
@ -249,7 +249,7 @@ struct DftTagWorker {
void propagate_tags() void propagate_tags()
{ {
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type == ID($set_tag)) { if (cell->type == TW($set_tag)) {
pending_cells.insert(cell); pending_cells.insert(cell);
pending_cell_queue.push_back(cell); pending_cell_queue.push_back(cell);
} }
@ -371,7 +371,7 @@ struct DftTagWorker {
void propagate_tags(Cell *cell) void propagate_tags(Cell *cell)
{ {
if (cell->type == ID($set_tag)) { if (cell->type == TW($set_tag)) {
IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string()); IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
if (all_tags.insert(tag).second) { if (all_tags.insert(tag).second) {
auto group_sep = tag.str().find(':'); auto group_sep = tag.str().find(':');
@ -388,25 +388,25 @@ struct DftTagWorker {
return; return;
} }
if (cell->type == ID($get_tag)) { if (cell->type == TW($get_tag)) {
return; return;
} }
if (cell->type.in(ID($not), ID($pos))) { if (cell->type.in(TW($not), TW($pos))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
if (cell->type.in(ID($not), ID($or))) { if (cell->type.in(TW($not), TW($or))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
} }
forward_tags(sig_y, sig_a); forward_tags(sig_y, sig_a);
return; return;
} }
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($bweqx))) { if (cell->type.in(TW($and), TW($or), TW($xor), TW($xnor), TW($bweqx))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { if (cell->type.in(TW($and), TW($or), TW($xor), TW($xnor))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
} }
@ -415,13 +415,13 @@ struct DftTagWorker {
return; return;
} }
if (cell->type.in(ID($mux), ID($bwmux))) { if (cell->type.in(TW($mux), TW($bwmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
auto sig_s = cell->getPort(TW::S); auto sig_s = cell->getPort(TW::S);
if (cell->type == ID($mux)) if (cell->type == TW($mux))
sig_s = SigSpec(sig_s[0], GetSize(sig_y)); sig_s = SigSpec(sig_s[0], GetSize(sig_y));
forward_tags(sig_y, sig_a); forward_tags(sig_y, sig_a);
@ -430,7 +430,7 @@ struct DftTagWorker {
return; return;
} }
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
FfData ff(&initvals, cell); FfData ff(&initvals, cell);
if (ff.has_clk || ff.has_gclk) if (ff.has_clk || ff.has_gclk)
@ -440,10 +440,10 @@ struct DftTagWorker {
// Single output but, sensitive to all inputs // Single output but, sensitive to all inputs
if (cell->type.in( if (cell->type.in(
ID($le), ID($lt), ID($ge), ID($gt), TW($le), TW($lt), TW($ge), TW($gt),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor),
ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and), TW($reduce_bool), TW($logic_not), TW($logic_or), TW($logic_and),
ID($eq), ID($ne) TW($eq), TW($ne)
)) { )) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
@ -456,10 +456,10 @@ struct DftTagWorker {
add_tags(cell, tags(cell)); add_tags(cell, tags(cell));
if (cell->type.in( if (cell->type.in(
ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_), TW($_AND_), TW($_OR_), TW($_NAND_), TW($_NOR_), TW($_ANDNOT_), TW($_ORNOT_),
ID($_XOR_), ID($_XNOR_), ID($_NOT_), ID($_BUF_), ID($_MUX_), TW($_XOR_), TW($_XNOR_), TW($_NOT_), TW($_BUF_), TW($_MUX_),
ID($assert), ID($assume) TW($assert), TW($assume)
)) { )) {
return; return;
} }
@ -477,7 +477,7 @@ struct DftTagWorker {
void process_cell(IdString tag, Cell *cell) void process_cell(IdString tag, Cell *cell)
{ {
if (cell->type == ID($set_tag)) { if (cell->type == TW($set_tag)) {
IdString cell_tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string()); IdString cell_tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
auto tag_sig_a = tag_signal(tag, cell->getPort(TW::A)); auto tag_sig_a = tag_signal(tag, cell->getPort(TW::A));
@ -494,14 +494,14 @@ struct DftTagWorker {
return; return;
} }
if (cell->type == ID($get_tag)) { if (cell->type == TW($get_tag)) {
log_assert(false); log_assert(false);
} }
if (cell->type.in(ID($not), ID($pos), ID($_NOT_), ID($_BUF_))) { if (cell->type.in(TW($not), TW($pos), TW($_NOT_), TW($_BUF_))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
if (cell->type.in(ID($not), ID($or))) { if (cell->type.in(TW($not), TW($or))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
} }
emit_tag_signal(tag, sig_y, tag_signal(tag, sig_a)); emit_tag_signal(tag, sig_y, tag_signal(tag, sig_a));
@ -509,13 +509,13 @@ struct DftTagWorker {
} }
if (cell->type.in( if (cell->type.in(
ID($and), ID($or), TW($and), TW($or),
ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_) TW($_AND_), TW($_OR_), TW($_NAND_), TW($_NOR_), TW($_ANDNOT_), TW($_ORNOT_)
)) { )) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($and), ID($or))) { if (cell->type.in(TW($and), TW($or))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
} }
@ -523,9 +523,9 @@ struct DftTagWorker {
bool inv_a = false; bool inv_a = false;
bool inv_b = false; bool inv_b = false;
if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) if (cell->type.in(TW($or), TW($_OR_), TW($_NOR_), TW($_ORNOT_)))
inv_a ^= true, inv_b ^= true; inv_a ^= true, inv_b ^= true;
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
inv_b ^= true; inv_b ^= true;
if (inv_a) if (inv_a)
@ -554,11 +554,11 @@ struct DftTagWorker {
return; return;
} }
if (cell->type.in(ID($xor), ID($xnor), ID($bweqx), ID($_XOR_), ID($_XNOR_))) { if (cell->type.in(TW($xor), TW($xnor), TW($bweqx), TW($_XOR_), TW($_XNOR_))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($xor), ID($xnor))) { if (cell->type.in(TW($xor), TW($xnor))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
} }
@ -572,13 +572,13 @@ struct DftTagWorker {
} }
if (cell->type.in(ID($_MUX_), ID($mux), ID($bwmux))) { if (cell->type.in(TW($_MUX_), TW($mux), TW($bwmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
auto sig_s = cell->getPort(TW::S); auto sig_s = cell->getPort(TW::S);
if (cell->type == ID($mux)) if (cell->type == TW($mux))
sig_s = SigSpec(sig_s[0], GetSize(sig_y)); sig_s = SigSpec(sig_s[0], GetSize(sig_y));
auto group_sig_a = tag_group_signal(tag, sig_a); auto group_sig_a = tag_group_signal(tag, sig_a);
@ -606,7 +606,7 @@ struct DftTagWorker {
return; return;
} }
if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { if (cell->type.in(TW($eq), TW($ne), TW($eqx), TW($nex))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -635,7 +635,7 @@ struct DftTagWorker {
} }
if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) { if (cell->type.in(TW($lt), TW($gt), TW($le), TW($ge))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -643,7 +643,7 @@ struct DftTagWorker {
sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool());
if (cell->type.in(ID($gt), ID($le))) if (cell->type.in(TW($gt), TW($le)))
std::swap(sig_a, sig_b); std::swap(sig_a, sig_b);
auto group_sig_a = tag_group_signal(tag, sig_a); auto group_sig_a = tag_group_signal(tag, sig_a);
@ -666,14 +666,14 @@ struct DftTagWorker {
return; return;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($logic_not))) { if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_bool), TW($logic_not))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto group_sig_a = tag_group_signal(tag, sig_a); auto group_sig_a = tag_group_signal(tag, sig_a);
auto tag_sig_a = tag_signal(tag, sig_a); auto tag_sig_a = tag_signal(tag, sig_a);
if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) if (cell->type.in(TW($reduce_or), TW($reduce_bool), TW($logic_not)))
sig_a = autoNot(NEW_TWINE, sig_a); sig_a = autoNot(NEW_TWINE, sig_a);
auto filled = autoOr(NEW_TWINE, sig_a, group_sig_a); auto filled = autoOr(NEW_TWINE, sig_a, group_sig_a);
@ -686,12 +686,12 @@ struct DftTagWorker {
return; return;
} }
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
FfData ff(&initvals, cell); FfData ff(&initvals, cell);
// TODO handle some more variants // TODO handle some more variants
if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) {
if (ff.has_clk && !tags(ff.sig_clk).empty()) if (ff.has_clk && !tags(ff.sig_clk).empty())
log_warning("Tags on CLK input ignored for %s (%s)\n", cell, cell->type.unescape()); log_warning("Tags on CLK input ignored for %s (%s)\n", cell, cell->type);
int width = ff.width; int width = ff.width;
@ -709,7 +709,7 @@ struct DftTagWorker {
emit_tag_signal(tag, sig_q, ff.sig_q); emit_tag_signal(tag, sig_q, ff.sig_q);
return; return;
} else { } else {
log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type.unescape()); log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type);
// For unhandled FFs, the default propagation would cause combinational loops // For unhandled FFs, the default propagation would cause combinational loops
emit_tag_signal(tag, ff.sig_q, Const(0, ff.width)); emit_tag_signal(tag, ff.sig_q, Const(0, ff.width));
@ -739,7 +739,7 @@ struct DftTagWorker {
// which is an over-approximation (unless the cell is a module that // which is an over-approximation (unless the cell is a module that
// generates tags itself in which case it could be arbitrary). // generates tags itself in which case it could be arbitrary).
if (warned_cells.insert(cell).second) if (warned_cells.insert(cell).second)
log_warning("Unhandled cell %s (%s) while emitting tag signals\n", cell, cell->type.unescape()); log_warning("Unhandled cell %s (%s) while emitting tag signals\n", cell, cell->type);
} }
void emit_tags() void emit_tags()
@ -747,7 +747,7 @@ struct DftTagWorker {
warned_cells.clear(); warned_cells.clear();
std::vector<Cell *> get_tag_cells; std::vector<Cell *> get_tag_cells;
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
if (cell->type == ID($get_tag)) if (cell->type == TW($get_tag))
get_tag_cells.push_back(cell); get_tag_cells.push_back(cell);
for (auto cell : get_tag_cells) { for (auto cell : get_tag_cells) {
@ -798,13 +798,13 @@ struct DftTagWorker {
std::vector<Cell *> get_tag_cells; std::vector<Cell *> get_tag_cells;
std::vector<Cell *> set_tag_cells; std::vector<Cell *> set_tag_cells;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type == ID($get_tag)) if (cell->type == TW($get_tag))
get_tag_cells.push_back(cell); get_tag_cells.push_back(cell);
if (cell->type == ID($set_tag)) if (cell->type == TW($set_tag))
set_tag_cells.push_back(cell); set_tag_cells.push_back(cell);
log_assert(!cell->type.in(ID($overwrite_tag), ID($original_tag))); log_assert(!cell->type.in(TW($overwrite_tag), TW($original_tag)));
} }
for (auto cell : set_tag_cells) { for (auto cell : set_tag_cells) {

View File

@ -92,12 +92,12 @@ struct EdgetypePass : public Pass {
auto sink_bit_index = std::get<2>(sink); auto sink_bit_index = std::get<2>(sink);
string source_str = multibit_ports.count(std::pair<IdString, TwineRef>(source_cell_type, source_port_name)) ? string source_str = multibit_ports.count(std::pair<IdString, TwineRef>(source_cell_type, source_port_name)) ?
stringf("%s.%s[%d]", source_cell_type.unescape(), module->design->twines.str(source_port_name).c_str(), source_bit_index) : stringf("%s.%s[%d]", design->twines.unescaped_str(source_cell_type), module->design->twines.str(source_port_name).c_str(), source_bit_index) :
stringf("%s.%s", source_cell_type.unescape(), module->design->twines.str(source_port_name).c_str()); stringf("%s.%s", design->twines.unescaped_str(source_cell_type), module->design->twines.str(source_port_name).c_str());
string sink_str = multibit_ports.count(std::pair<IdString, TwineRef>(sink_cell_type, sink_port_name)) ? string sink_str = multibit_ports.count(std::pair<IdString, TwineRef>(sink_cell_type, sink_port_name)) ?
stringf("%s.%s[%d]", sink_cell_type.unescape(), module->design->twines.str(sink_port_name).c_str(), sink_bit_index) : stringf("%s.%s[%d]", design->twines.unescaped_str(sink_cell_type), module->design->twines.str(sink_port_name).c_str(), sink_bit_index) :
stringf("%s.%s", sink_cell_type.unescape(), module->design->twines.str(sink_port_name).c_str()); stringf("%s.%s", design->twines.unescaped_str(sink_cell_type), module->design->twines.str(sink_port_name).c_str());
edge_cache.insert(source_str + " " + sink_str); edge_cache.insert(source_str + " " + sink_str);
} }

View File

@ -77,13 +77,13 @@ struct ExampleDtPass : public Pass
auto enqueue = [&](DriveSpec const &spec) { auto enqueue = [&](DriveSpec const &spec) {
int index = queue(spec); int index = queue(spec);
if (index == GetSize(graph_nodes)) if (index == GetSize(graph_nodes))
graph_nodes.emplace_back(compute_graph.add(ID($pending), index).index()); graph_nodes.emplace_back(compute_graph.add(TW($pending), index).index());
//if (index >= GetSize(graph_nodes)) //if (index >= GetSize(graph_nodes))
return compute_graph[graph_nodes[index]]; return compute_graph[graph_nodes[index]];
}; };
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in(ID($assert), ID($assume), ID($cover), ID($check))) if (cell->type.in(TW($assert), TW($assume), TW($cover), TW($check)))
enqueue(DriveBitMarker(cells(cell), 0)); enqueue(DriveBitMarker(cells(cell), 0));
} }
@ -99,7 +99,7 @@ struct ExampleDtPass : public Pass
ExampleGraph::Ref node = compute_graph[i]; ExampleGraph::Ref node = compute_graph[i];
if (spec.chunks().size() > 1) { if (spec.chunks().size() > 1) {
node.set_function(ID($$concat)); node.set_function(TW($$concat));
for (auto const &chunk : spec.chunks()) { for (auto const &chunk : spec.chunks()) {
node.append_arg(enqueue(chunk)); node.append_arg(enqueue(chunk));
@ -111,39 +111,39 @@ struct ExampleDtPass : public Pass
if (wire_chunk.is_whole()) { if (wire_chunk.is_whole()) {
node.sparse_attr() = wire_chunk.wire->name; node.sparse_attr() = wire_chunk.wire->name;
if (wire_chunk.wire->port_input) { if (wire_chunk.wire->port_input) {
node.set_function(ExampleFn(ID($$input), {{wire_chunk.wire->name, {}}})); node.set_function(ExampleFn(TW($$input), {{wire_chunk.wire->name, {}}}));
} else { } else {
DriveSpec driver = dm(DriveSpec(wire_chunk)); DriveSpec driver = dm(DriveSpec(wire_chunk));
node.set_function(ID($$buf)); node.set_function(TW($$buf));
node.append_arg(enqueue(driver)); node.append_arg(enqueue(driver));
} }
} else { } else {
DriveChunkWire whole_wire(wire_chunk.wire, 0, wire_chunk.wire->width); DriveChunkWire whole_wire(wire_chunk.wire, 0, wire_chunk.wire->width);
node.set_function(ExampleFn(ID($$slice), {{ID(offset), wire_chunk.offset}, {ID(width), wire_chunk.width}})); node.set_function(ExampleFn(TW($$slice), {{ID(offset), wire_chunk.offset}, {ID(width), wire_chunk.width}}));
node.append_arg(enqueue(whole_wire)); node.append_arg(enqueue(whole_wire));
} }
} else if (chunk.is_port()) { } else if (chunk.is_port()) {
DriveChunkPort port_chunk = chunk.port(); DriveChunkPort port_chunk = chunk.port();
if (port_chunk.is_whole()) { if (port_chunk.is_whole()) {
if (dm.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) { if (dm.celltypes.cell_output(port_chunk.cell->type_impl, port_chunk.port)) {
if (port_chunk.cell->type.in(ID($dff), ID($ff))) if (port_chunk.cell->type.in(TW($dff), TW($ff)))
{ {
Cell *cell = port_chunk.cell; Cell *cell = port_chunk.cell;
node.set_function(ExampleFn(ID($$state), {{cell->name, {}}})); node.set_function(ExampleFn(TW($$state), {{cell->name, {}}}));
for (auto const &conn : cell->connections()) { for (auto const &conn : cell->connections()) {
if (!dm.celltypes.cell_input(cell->type, conn.first)) if (!dm.celltypes.cell_input(cell->type_impl, conn.first))
continue; continue;
enqueue(DriveChunkPort(cell, conn)).assign_key(cell->name); enqueue(DriveChunkPort(cell, conn)).assign_key(cell->name);
} }
} }
else else
{ {
node.set_function(ExampleFn(ID($$cell_output), {{RTLIL::escape_id(module->design->twines.str(port_chunk.port)), {}}})); node.set_function(ExampleFn(TW($$cell_output), {{RTLIL::escape_id(module->design->twines.str(port_chunk.port)), {}}}));
node.append_arg(enqueue(DriveBitMarker(cells(port_chunk.cell), 0))); node.append_arg(enqueue(DriveBitMarker(cells(port_chunk.cell), 0)));
} }
} else { } else {
node.set_function(ID($$buf)); node.set_function(TW($$buf));
DriveSpec driver = dm(DriveSpec(port_chunk)); DriveSpec driver = dm(DriveSpec(port_chunk));
node.append_arg(enqueue(driver)); node.append_arg(enqueue(driver));
@ -151,14 +151,14 @@ struct ExampleDtPass : public Pass
} else { } else {
DriveChunkPort whole_port(port_chunk.cell, port_chunk.port, 0, GetSize(port_chunk.cell->connections().at(port_chunk.port))); DriveChunkPort whole_port(port_chunk.cell, port_chunk.port, 0, GetSize(port_chunk.cell->connections().at(port_chunk.port)));
node.set_function(ExampleFn(ID($$slice), {{ID(offset), port_chunk.offset}})); node.set_function(ExampleFn(TW($$slice), {{ID(offset), port_chunk.offset}}));
node.append_arg(enqueue(whole_port)); node.append_arg(enqueue(whole_port));
} }
} else if (chunk.is_constant()) { } else if (chunk.is_constant()) {
node.set_function(ExampleFn(ID($$const), {{ID(value), chunk.constant()}})); node.set_function(ExampleFn(TW($$const), {{ID(value), chunk.constant()}}));
} else if (chunk.is_multiple()) { } else if (chunk.is_multiple()) {
node.set_function(ID($$multi)); node.set_function(TW($$multi));
for (auto const &driver : chunk.multiple().multiple()) for (auto const &driver : chunk.multiple().multiple())
node.append_arg(enqueue(driver)); node.append_arg(enqueue(driver));
} else if (chunk.is_marker()) { } else if (chunk.is_marker()) {
@ -166,13 +166,13 @@ struct ExampleDtPass : public Pass
node.set_function(ExampleFn(cell->type, cell->parameters)); node.set_function(ExampleFn(cell->type, cell->parameters));
for (auto const &conn : cell->connections()) { for (auto const &conn : cell->connections()) {
if (!dm.celltypes.cell_input(cell->type, conn.first)) if (!dm.celltypes.cell_input(cell->type_impl, conn.first))
continue; continue;
node.append_arg(enqueue(DriveChunkPort(cell, conn))); node.append_arg(enqueue(DriveChunkPort(cell, conn)));
} }
} else if (chunk.is_none()) { } else if (chunk.is_none()) {
node.set_function(ID($$undriven)); node.set_function(TW($$undriven));
} else { } else {
log_error("unhandled drivespec: %s\n", log_signal(chunk)); log_error("unhandled drivespec: %s\n", log_signal(chunk));
@ -208,7 +208,7 @@ struct ExampleDtPass : public Pass
for (int i = 0; i < compute_graph.size(); ++i) for (int i = 0; i < compute_graph.size(); ++i)
{ {
if (compute_graph[i].function().name == ID($$buf) && !compute_graph[i].has_sparse_attr() && compute_graph[i].arg(0).index() < i) if (compute_graph[i].function().name == TW($$buf) && !compute_graph[i].has_sparse_attr() && compute_graph[i].arg(0).index() < i)
{ {
alias.push_back(alias[compute_graph[i].arg(0).index()]); alias.push_back(alias[compute_graph[i].arg(0).index()]);

View File

@ -50,7 +50,7 @@ struct FutureWorker {
std::vector<Cell *> replaced_cells; std::vector<Cell *> replaced_cells;
for (auto cell : module->selected_cells()) { for (auto cell : module->selected_cells()) {
if (cell->type != ID($future_ff)) if (cell->type != TW($future_ff))
continue; continue;
module->connect(cell->getPort(TW::Y), future_ff(cell->getPort(TW::A))); module->connect(cell->getPort(TW::Y), future_ff(cell->getPort(TW::A)));
@ -92,7 +92,7 @@ struct FutureWorker {
if (!ff.has_clk && !ff.has_gclk) if (!ff.has_clk && !ff.has_gclk)
log_error("Driver for future_ff target signal %s has cell type %s, which is not clocked\n", log_signal(bit), log_error("Driver for future_ff target signal %s has cell type %s, which is not clocked\n", log_signal(bit),
driver.cell->type.unescape()); driver.cell->type);
ff.unmap_ce_srst(); ff.unmap_ce_srst();

View File

@ -70,7 +70,7 @@ private:
void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) {
//AKA AN2_SH2 or OR2_SH2 //AKA AN2_SH2 or OR2_SH2
bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); bool is_and = cell->type.in(TW($_AND_), TW($_NAND_));
RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_1_1"}, port_a, false, cell->src_ref()); RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_1_1"}, port_a, false, cell->src_ref());
RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_1_2"}, port_b, false, cell->src_ref()); RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_1_2"}, port_b, false, cell->src_ref());
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_1_3"}, is_and? port_a : n_port_a, port_b_taint, false, cell->src_ref()); auto subexpr1 = module->And(Twine{cell->name.str() + "_t_1_3"}, is_and? port_a : n_port_a, port_b_taint, false, cell->src_ref());
@ -82,7 +82,7 @@ private:
void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) {
//AKA AN2_SH3 or OR2_SH3 //AKA AN2_SH3 or OR2_SH3
bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); bool is_and = cell->type.in(TW($_AND_), TW($_NAND_));
RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_2_1"}, port_a, false, cell->src_ref()); RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_2_1"}, port_a, false, cell->src_ref());
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_2_2"}, is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->src_ref()); auto subexpr1 = module->And(Twine{cell->name.str() + "_t_2_2"}, is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->src_ref());
module->addOr(Twine{cell->name.str() + "_t_2_3"}, is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->src_ref()); module->addOr(Twine{cell->name.str() + "_t_2_3"}, is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->src_ref());
@ -90,7 +90,7 @@ private:
void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) {
//AKA AN2_SH4 or OR2_SH4 //AKA AN2_SH4 or OR2_SH4
bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); bool is_and = cell->type.in(TW($_AND_), TW($_NAND_));
RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_3_1"}, port_b, false, cell->src_ref()); RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_3_1"}, port_b, false, cell->src_ref());
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_3_2"}, is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->src_ref()); auto subexpr1 = module->And(Twine{cell->name.str() + "_t_3_2"}, is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->src_ref());
module->addOr(Twine{cell->name.str() + "_t_3_3"}, is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->src_ref()); module->addOr(Twine{cell->name.str() + "_t_3_3"}, is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->src_ref());
@ -150,13 +150,13 @@ private:
auto select_width = metamux_select.as_wire()->width; auto select_width = metamux_select.as_wire()->width;
std::vector<RTLIL::Const> costs; std::vector<RTLIL::Const> costs;
if (celltype == ID($_AND_) || celltype == ID($_OR_)) { if (celltype == TW($_AND_) || celltype == TW($_OR_)) {
costs = {5, 2, 2, 1, 0, 0, 0, 0}; costs = {5, 2, 2, 1, 0, 0, 0, 0};
log_assert(select_width == 2 || select_width == 3); log_assert(select_width == 2 || select_width == 3);
log_assert(opt_instrumentmore || select_width == 2); log_assert(opt_instrumentmore || select_width == 2);
log_assert(!opt_instrumentmore || select_width == 3); log_assert(!opt_instrumentmore || select_width == 3);
} }
else if (celltype == ID($_XOR_) || celltype == ID($_XNOR_)) { else if (celltype == TW($_XOR_) || celltype == TW($_XNOR_)) {
costs = {1, 0, 0, 0}; costs = {1, 0, 0, 0};
log_assert(select_width == 2); log_assert(select_width == 2);
} }
@ -184,10 +184,10 @@ private:
std::vector<RTLIL::SigSig> connections(module->connections()); std::vector<RTLIL::SigSig> connections(module->connections());
for(auto &cell : module->cells().to_vector()) { for(auto &cell : module->cells().to_vector()) {
if (!cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_MUX_), ID($_NMUX_), ID($_NOT_), ID($anyconst), ID($allconst), ID($assume), ID($assert)) && module->design->module(cell->type) == nullptr) { if (!cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_MUX_), TW($_NMUX_), TW($_NOT_), TW($anyconst), TW($allconst), TW($assume), TW($assert)) && module->design->module(cell->type) == nullptr) {
log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type); log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type);
} }
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_))) { if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_))) {
const unsigned int A = 0, B = 1, Y = 2; const unsigned int A = 0, B = 1, Y = 2;
const unsigned int NUM_PORTS = 3; const unsigned int NUM_PORTS = 3;
RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::Y)}; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::Y)};
@ -234,7 +234,7 @@ private:
auto select_width = log2(num_versions); auto select_width = log2(num_versions);
log_assert(exp2(select_width) == num_versions); log_assert(exp2(select_width) == num_versions);
RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width)); RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width));
meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); meta_mux_selects.push_back(make_pair(meta_mux_select, RTLIL::IdString(cell->type)));
module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref())); module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref()));
std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version); std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version);
@ -252,7 +252,7 @@ private:
} }
else log_cmd_error("This is a bug (1).\n"); else log_cmd_error("This is a bug (1).\n");
} }
else if (cell->type.in(ID($_XOR_), ID($_XNOR_))) { else if (cell->type.in(TW($_XOR_), TW($_XNOR_))) {
const unsigned int A = 0, B = 1, Y = 2; const unsigned int A = 0, B = 1, Y = 2;
const unsigned int NUM_PORTS = 3; const unsigned int NUM_PORTS = 3;
RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::Y)}; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::Y)};
@ -289,7 +289,7 @@ private:
} }
RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width)); RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width));
meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); meta_mux_selects.push_back(make_pair(meta_mux_select, RTLIL::IdString(cell->type)));
module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref())); module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref()));
std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version); std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version);
@ -308,7 +308,7 @@ private:
else log_cmd_error("This is a bug (2).\n"); else log_cmd_error("This is a bug (2).\n");
} }
else if (cell->type.in(ID($_MUX_), ID($_NMUX_))) { else if (cell->type.in(TW($_MUX_), TW($_NMUX_))) {
const unsigned int A = 0, B = 1, S = 2, Y = 3; const unsigned int A = 0, B = 1, S = 2, Y = 3;
const unsigned int NUM_PORTS = 4; const unsigned int NUM_PORTS = 4;
RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::S), cell->getPort(TW::Y)}; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::B), cell->getPort(TW::S), cell->getPort(TW::Y)};
@ -321,7 +321,7 @@ private:
add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]); add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]);
} }
else if (cell->type.in(ID($_NOT_))) { else if (cell->type.in(TW($_NOT_))) {
const unsigned int A = 0, Y = 1; const unsigned int A = 0, Y = 1;
const unsigned int NUM_PORTS = 2; const unsigned int NUM_PORTS = 2;
RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::Y)}; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(TW::A), cell->getPort(TW::Y)};
@ -332,7 +332,7 @@ private:
for (unsigned int i = 0; i < NUM_PORTS; ++i) for (unsigned int i = 0; i < NUM_PORTS; ++i)
port_taints[i] = get_corresponding_taint_signal(ports[i]); port_taints[i] = get_corresponding_taint_signal(ports[i]);
if (cell->type == ID($_NOT_)) { if (cell->type == TW($_NOT_)) {
module->connect(port_taints[Y], port_taints[A]); module->connect(port_taints[Y], port_taints[A]);
} }
else log_cmd_error("This is a bug (3).\n"); else log_cmd_error("This is a bug (3).\n");

View File

@ -63,7 +63,7 @@ struct LibertyStubber {
} }
f << "\tcell (\"" << derived_name << "\") {\n"; f << "\tcell (\"" << derived_name << "\") {\n";
auto& base_type = ct.cell_types[base_name]; auto& base_type = ct.cell_types[base->name];
i.indent = 3; i.indent = 3;
auto sorted_ports = derived->ports; auto sorted_ports = derived->ports;
// Hack for CLK and C coming before Q does // Hack for CLK and C coming before Q does
@ -117,17 +117,17 @@ struct LibertyStubber {
} }
void liberty_cell(Module* base, Module* derived, std::ostream& f) void liberty_cell(Module* base, Module* derived, std::ostream& f)
{ {
auto base_name = base->design->twines.str(base->meta_->name).substr(1); auto base_name = base->name.substr(1);
auto derived_name = derived->design->twines.str(derived->meta_->name).substr(1); auto derived_name = derived->design->twines.str(derived->meta_->name).substr(1);
if (!ct.cell_types.count(base_name)) { if (!ct.cell_types.count(base->name)) {
log_debug("skip skeleton for %s\n", base_name.c_str()); log_debug("skip skeleton for %s\n", base_name.c_str());
return; return;
} }
if (StaticCellTypes::categories.is_ff(base_name)) if (StaticCellTypes::categories.is_ff(base->name))
return liberty_flop(base, derived, f); return liberty_flop(base, derived, f);
auto& base_type = ct.cell_types[base_name]; auto& base_type = ct.cell_types[base->name];
f << "\tcell (\"" << derived_name << "\") {\n"; f << "\tcell (\"" << derived_name << "\") {\n";
for (auto x : derived->ports) { for (auto x : derived->ports) {
std::string port_name = derived->design->twines.str(x); std::string port_name = derived->design->twines.str(x);

View File

@ -95,7 +95,7 @@ struct CoveragePass : public Pass {
{ {
log_debug("Module %s:\n", module); log_debug("Module %s:\n", module);
for (auto wire: module->wires()) { for (auto wire: module->wires()) {
log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), wire->name.unescape()); log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), design->twines.unescaped_str(wire->name));
for (auto src: design->src_leaves(wire)) { for (auto src: design->src_leaves(wire)) {
auto filename = extract_src_filename(src); auto filename = extract_src_filename(src);
if (filename.empty()) continue; if (filename.empty()) continue;

View File

@ -64,7 +64,7 @@ struct LtpWorker
dst_bits.insert(bit); dst_bits.insert(bit);
} }
if (noff && ff_celltypes.cell_known(cell->type)) { if (noff && ff_celltypes.cell_known(cell->type_impl)) {
for (auto s : src_bits) for (auto s : src_bits)
for (auto d : dst_bits) { for (auto d : dst_bits) {
bit2ff[s] = tuple<SigBit, Cell*>(d, cell); bit2ff[s] = tuple<SigBit, Cell*>(d, cell);

View File

@ -31,7 +31,7 @@ static RTLIL::SigBit canonical_bit(RTLIL::SigBit bit)
{ {
RTLIL::Wire *w; RTLIL::Wire *w;
while ((w = bit.wire) != NULL && !w->port_input && while ((w = bit.wire) != NULL && !w->port_input &&
w->driverCell()->type.in(ID($buf), ID($_BUF_))) { w->driverCell()->type.in(TW($buf), TW($_BUF_))) {
bit = w->driverCell()->getPort(TW::A)[bit.offset]; bit = w->driverCell()->getPort(TW::A)[bit.offset];
} }
return bit; return bit;
@ -125,10 +125,10 @@ struct PortarcsPass : Pass {
for (auto cell : m->cells()) for (auto cell : m->cells())
// Ignore all bufnorm helper cells // Ignore all bufnorm helper cells
if (!cell->type.in(ID($buf), ID($input_port), ID($output_port), ID($public), ID($connect), ID($tribuf))) { if (!cell->type.in(TW($buf), TW($input_port), TW($output_port), TW($public), TW($connect), TW($tribuf))) {
auto tdata = tinfo.find(cell->type); auto tdata = tinfo.find(cell->type);
if (tdata == tinfo.end()) if (tdata == tinfo.end())
log_cmd_error("Missing timing data for module '%s'.\n", cell->type.unescape()); log_cmd_error("Missing timing data for module '%s'.\n", cell->type.unescaped());
for (auto [edge, delay] : tdata->second.comb) { for (auto [edge, delay] : tdata->second.comb) {
auto from = edge.first.get_connection(cell); auto from = edge.first.get_connection(cell);
auto to = edge.second.get_connection(cell); auto to = edge.second.get_connection(cell);
@ -292,7 +292,7 @@ struct PortarcsPass : Pass {
int *p = annotations.at(canonical_bit(bit)); int *p = annotations.at(canonical_bit(bit));
for (auto i = 0; i < inputs.size(); i++) { for (auto i = 0; i < inputs.size(); i++) {
if (p[i] >= 0) { if (p[i] >= 0) {
Cell *spec = m->addCell(NEW_TWINE, ID($specify2)); Cell *spec = m->addCell(NEW_TWINE, TW($specify2));
spec->setParam(ID::SRC_WIDTH, 1); spec->setParam(ID::SRC_WIDTH, 1);
spec->setParam(ID::DST_WIDTH, 1); spec->setParam(ID::DST_WIDTH, 1);
spec->setParam(ID::T_FALL_MAX, p[i]); spec->setParam(ID::T_FALL_MAX, p[i]);

View File

@ -47,9 +47,9 @@ struct PrintAttrsPass : public Pass {
static void log_const(RTLIL::IdString s, const RTLIL::Const &x, const unsigned int indent) { static void log_const(RTLIL::IdString s, const RTLIL::Const &x, const unsigned int indent) {
if (x.flags & RTLIL::CONST_FLAG_STRING) if (x.flags & RTLIL::CONST_FLAG_STRING)
log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), s.unescape(), x.decode_string()); log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), design->twines.unescaped_str(s), x.decode_string());
else if (x.flags == RTLIL::CONST_FLAG_NONE || x.flags == RTLIL::CONST_FLAG_SIGNED) else if (x.flags == RTLIL::CONST_FLAG_NONE || x.flags == RTLIL::CONST_FLAG_SIGNED)
log("%s(* %s=%s *)\n", get_indent_str(indent), s.unescape(), x.as_string()); log("%s(* %s=%s *)\n", get_indent_str(indent), design->twines.unescaped_str(s), x.as_string());
else else
log_assert(x.flags & RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail log_assert(x.flags & RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail
} }
@ -88,7 +88,7 @@ struct PrintAttrsPass : public Pass {
} }
for (auto wire : mod->selected_wires()) { for (auto wire : mod->selected_wires()) {
log("%s%s\n", get_indent_str(indent), wire->name.unescape()); log("%s%s\n", get_indent_str(indent), design->twines.unescaped_str(wire->name));
indent += 2; indent += 2;
log_src(design, wire, indent); log_src(design, wire, indent);
for (auto &it : wire->attributes) for (auto &it : wire->attributes)

View File

@ -21,6 +21,7 @@
#include "kernel/rtlil.h" #include "kernel/rtlil.h"
#include "kernel/log.h" #include "kernel/log.h"
#include "backends/verilog/verilog_backend.h" #include "backends/verilog/verilog_backend.h"
#include "kernel/twine.h"
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
@ -149,11 +150,11 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
} }
} }
if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) { if (cell->type.in(TW($anyconst), TW($anyseq), TW($anyinit), TW($allconst), TW($allseq))) {
has_witness_signals = true; has_witness_signals = true;
IdString QY; IdString QY;
bool clk2fflogic = false; bool clk2fflogic = false;
if (cell->type == ID($anyinit)) if (cell->type == TW($anyinit))
QY = (clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic))) ? ID::D : ID::Q; QY = (clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic))) ? ID::D : ID::Q;
else else
QY = ID::Y; QY = ID::Y;
@ -179,7 +180,7 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
} }
if (cell->type.in(ID($assert), ID($assume), ID($cover), ID($live), ID($fair), ID($check))) { if (cell->type.in(TW($assert), TW($assume), TW($cover), TW($live), TW($fair), TW($check))) {
has_witness_signals = true; has_witness_signals = true;
if (cell->name.isPublic()) if (cell->name.isPublic())
continue; continue;
@ -386,6 +387,7 @@ struct RenamePass : public Pass {
// TODO disable signorm due to rename I think? // TODO disable signorm due to rename I think?
design->sigNormalize(false); design->sigNormalize(false);
TwineSearch search(&design->twines);
if (flag_src) if (flag_src)
{ {
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -527,14 +529,14 @@ struct RenamePass : public Pass {
if (argidx+1 != args.size()) if (argidx+1 != args.size())
log_cmd_error("Invalid number of arguments!\n"); log_cmd_error("Invalid number of arguments!\n");
IdString new_name = RTLIL::escape_id(args[argidx]); TwineRef new_name = design->twines.add(Twine{RTLIL::escape_id(args[argidx])});
RTLIL::Module *module = design->top_module(); RTLIL::Module *module = design->top_module();
if (module == nullptr) if (module == nullptr)
log_cmd_error("No top module found!\n"); log_cmd_error("No top module found!\n");
log("Renaming module %s to %s.\n", log_id(module), new_name.unescape()); log("Renaming module %s to %s.\n", log_id(module), design->twines.unescaped_str(new_name));
design->rename(module, design->twines.add(Twine{new_name.str()})); design->rename(module, new_name);
} }
else else
if (flag_scramble_name) if (flag_scramble_name)

View File

@ -53,7 +53,7 @@ struct ScatterPass : public Pass {
for (auto conn : cell->connections()) for (auto conn : cell->connections())
new_connections.emplace(conn.first, RTLIL::SigSig(conn.second, module->addWire(NEW_TWINE, GetSize(conn.second)))); new_connections.emplace(conn.first, RTLIL::SigSig(conn.second, module->addWire(NEW_TWINE, GetSize(conn.second))));
for (auto &it : new_connections) { for (auto &it : new_connections) {
if (ct.cell_output(cell->type, it.first)) if (ct.cell_output(cell->type.ref(), it.first))
module->connect(RTLIL::SigSig(it.second.first, it.second.second)); module->connect(RTLIL::SigSig(it.second.first, it.second.second));
else else
module->connect(RTLIL::SigSig(it.second.second, it.second.first)); module->connect(RTLIL::SigSig(it.second.second, it.second.first));

View File

@ -117,7 +117,7 @@ struct SccWorker
for (auto mod : design->modules()) for (auto mod : design->modules())
if (mod->get_blackbox_attribute(false)) if (mod->get_blackbox_attribute(false))
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (cell->type == ID($specify2)) if (cell->type == TW($specify2))
{ {
specifyCells.setup_module(mod); specifyCells.setup_module(mod);
break; break;
@ -138,18 +138,18 @@ struct SccWorker
if (!design->selected(module, cell)) if (!design->selected(module, cell))
continue; continue;
if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type)) if (!allCellTypes && !ct.cell_known(cell->type.ref()) && !specifyCells.cell_known(cell->type.ref()))
continue; continue;
workQueue.insert(cell); workQueue.insert(cell);
RTLIL::SigSpec inputSignals, outputSignals; RTLIL::SigSpec inputSignals, outputSignals;
if (specifyCells.cell_known(cell->type)) { if (specifyCells.cell_known(cell->type.ref())) {
// Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes. // Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes.
for (auto subcell : design->module(cell->type)->cells()) for (auto subcell : design->module(cell->type)->cells())
{ {
if (subcell->type != ID($specify2)) if (subcell->type != TW($specify2))
continue; continue;
for (auto bit : subcell->getPort(TW::SRC)) for (auto bit : subcell->getPort(TW::SRC))
@ -171,9 +171,9 @@ struct SccWorker
{ {
bool isInput = true, isOutput = true; bool isInput = true, isOutput = true;
if (ct.cell_known(cell->type)) { if (ct.cell_known(cell->type.ref())) {
isInput = ct.cell_input(cell->type, conn.first); isInput = ct.cell_input(cell->type.ref(), conn.first);
isOutput = ct.cell_output(cell->type, conn.first); isOutput = ct.cell_output(cell->type.ref(), conn.first);
} }
RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));

View File

@ -1,3 +1,4 @@
#include "kernel/twine.h"
#ifdef YOSYS_ENABLE_TCL #ifdef YOSYS_ENABLE_TCL
#include "kernel/register.h" #include "kernel/register.h"
@ -97,7 +98,7 @@ struct SdcObjects {
// constraint-side tracking // constraint-side tracking
FullConstraint, FullConstraint,
} collect_mode; } collect_mode;
using CellPin = std::pair<Cell*, IdString>; using CellPin = std::pair<Cell*, TwineRef>;
Design* design; Design* design;
std::vector<std::pair<std::string, Wire*>> design_ports; std::vector<std::pair<std::string, Wire*>> design_ports;
std::vector<std::pair<std::string, Cell*>> design_cells; std::vector<std::pair<std::string, Cell*>> design_cells;
@ -149,8 +150,8 @@ struct SdcObjects {
path += name; path += name;
design_cells.push_back(std::make_pair(path, cell)); design_cells.push_back(std::make_pair(path, cell));
for (auto pin : cell->connections()) { for (auto pin : cell->connections()) {
IdString pin_name = pin.first; TwineRef pin_name = pin.first;
std::string pin_name_sdc = path + "/" + pin.first.str().substr(1); std::string pin_name_sdc = path + "/" + design->twines.unescaped_str(pin.first);
design_pins.push_back(std::make_pair(pin_name_sdc, std::make_pair(cell, pin_name))); design_pins.push_back(std::make_pair(pin_name_sdc, std::make_pair(cell, pin_name)));
} }
if (auto sub_mod = mod->design->module(cell->type)) { if (auto sub_mod = mod->design->module(cell->type)) {
@ -168,9 +169,9 @@ struct SdcObjects {
RTLIL::Wire *wire = top->wire(port); RTLIL::Wire *wire = top->wire(port);
if (!wire) { if (!wire) {
// This should not be possible. See https://github.com/YosysHQ/yosys/pull/5594#issue-3791198573 // This should not be possible. See https://github.com/YosysHQ/yosys/pull/5594#issue-3791198573
log_error("Port %s doesn't exist", port.unescape()); log_error("Port %s doesn't exist", design->twines.unescaped_str(port));
} }
design_ports.push_back(std::make_pair(port.str().substr(1), wire)); design_ports.push_back(std::make_pair(design->twines.unescaped_str(port), wire));
} }
std::list<std::string> hierarchy{}; std::list<std::string> hierarchy{};
sniff_module(hierarchy, top); sniff_module(hierarchy, top);

View File

@ -17,6 +17,8 @@
* *
*/ */
#include "kernel/rtlil.h"
#include "kernel/twine.h"
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include "kernel/newcelltypes.h" #include "kernel/newcelltypes.h"
#include "kernel/sigtools.h" #include "kernel/sigtools.h"
@ -450,7 +452,7 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
select_all(design, lhs); select_all(design, lhs);
std::vector<RTLIL::IdString> del_list; std::vector<TwineRef> del_list;
for (auto mod_name : lhs.selected_modules) { for (auto mod_name : lhs.selected_modules) {
if (rhs.selected_whole_module(mod_name)) if (rhs.selected_whole_module(mod_name))
@ -471,7 +473,7 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
del_list.push_back(it.first); del_list.push_back(it.first);
continue; continue;
} }
std::vector<RTLIL::IdString> del_list2; std::vector<TwineRef> del_list2;
for (auto &it2 : it.second) for (auto &it2 : it.second)
if (!rhs.selected_member(it.first, it2)) if (!rhs.selected_member(it.first, it2))
del_list2.push_back(it2); del_list2.push_back(it2);
@ -487,11 +489,11 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
namespace { namespace {
struct expand_rule_t { struct expand_rule_t {
char mode; char mode;
std::set<RTLIL::IdString> cell_types, port_names; std::set<std::string> cell_types, port_names;
}; };
} }
static int parse_comma_list(std::set<RTLIL::IdString> &tokens, const std::string &str, size_t pos, std::string stopchar) static int parse_comma_list(std::set<std::string> &tokens, const std::string &str, size_t pos, std::string stopchar)
{ {
stopchar += ','; stopchar += ',';
while (1) { while (1) {
@ -520,7 +522,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
auto selected_members = lhs.selected_members[mod->meta_->name]; auto selected_members = lhs.selected_members[mod->meta_->name];
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (lhs.selected_member(mod->meta_->name, wire->meta_->name) && limits.count(wire->meta_->name) == 0) if (lhs.selected_member(mod->meta_->name, wire->meta_->name) && limits.count(RTLIL::IdString(design->twines.str(wire->meta_->name))) == 0)
selected_wires.insert(wire); selected_wires.insert(wire);
for (auto &conn : mod->connections()) for (auto &conn : mod->connections())
@ -538,17 +540,18 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
} }
} }
auto twines = design->twines;
for (auto cell : mod->cells()) for (auto cell : mod->cells())
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
{ {
char last_mode = '-'; char last_mode = '-';
if (eval_only && !yosys_celltypes.cell_evaluable(cell->type)) if (eval_only && !yosys_celltypes.cell_evaluable(cell->type.ref()))
goto exclude_match; goto exclude_match;
for (auto &rule : rules) { for (auto &rule : rules) {
last_mode = rule.mode; last_mode = rule.mode;
if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0) if (rule.cell_types.size() > 0 && rule.cell_types.count(twines.unescaped_str(cell->type_impl)) == 0)
continue; continue;
if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0) if (rule.port_names.size() > 0 && rule.port_names.count(twines.unescaped_str(conn.first)) == 0)
continue; continue;
if (rule.mode == '+') if (rule.mode == '+')
goto include_match; goto include_match;
@ -558,16 +561,16 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
if (last_mode == '+') if (last_mode == '+')
goto exclude_match; goto exclude_match;
include_match: include_match:
is_input = mode == 'x' || ct.cell_input(cell->type, conn.first); is_input = mode == 'x' || ct.cell_input(cell->type.ref(), conn.first);
is_output = mode == 'x' || ct.cell_output(cell->type, conn.first); is_output = mode == 'x' || ct.cell_output(cell->type.ref(), conn.first);
for (auto &chunk : conn.second.chunks()) for (auto &chunk : conn.second.chunks())
if (chunk.wire != nullptr) { if (chunk.wire != nullptr) {
if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name) == 0) if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name.ref()) == 0)
if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input)) if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input))
lhs.selected_members[mod->name].insert(cell->name), sel_objects++, max_objects--; lhs.selected_members[mod->meta_->name].insert(cell->name.ref()), sel_objects++, max_objects--;
if (max_objects != 0 && selected_members.count(cell->name) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name) == 0) if (max_objects != 0 && selected_members.count(cell->name.ref()) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name.ref()) == 0)
if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output)) if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output))
lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--; lhs.selected_members[mod->meta_->name].insert(chunk.wire->name.ref()), sel_objects++, max_objects--;
} }
exclude_match:; exclude_match:;
} }
@ -634,7 +637,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
if (design->selection_vars.count(str) > 0) { if (design->selection_vars.count(str) > 0) {
for (auto i1 : design->selection_vars.at(str).selected_members) for (auto i1 : design->selection_vars.at(str).selected_members)
for (auto i2 : i1.second) for (auto i2 : i1.second)
limits.insert(i2); limits.insert(RTLIL::IdString(design->twines.str(i2)));
} else } else
log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str)); log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str));
} else } else
@ -682,7 +685,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel) static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel)
{ {
if (design->selected_active_module.empty()) if (!design->selected_active_module)
return; return;
if (sel.full_selection) { if (sel.full_selection) {
@ -691,7 +694,7 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se
return; return;
} }
std::vector<RTLIL::IdString> del_list; std::vector<TwineRef> del_list;
for (auto mod_name : sel.selected_modules) for (auto mod_name : sel.selected_modules)
if (mod_name != design->selected_active_module) if (mod_name != design->selected_active_module)
del_list.push_back(mod_name); del_list.push_back(mod_name);
@ -845,8 +848,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
select_blackboxes = true; select_blackboxes = true;
} }
if (!design->selected_active_module.empty()) { if (design->selected_active_module) {
arg_mod = design->selected_active_module; arg_mod = design->twines.str(design->selected_active_module);
arg_memb = arg; arg_memb = arg;
if (!isprefixed(arg_memb)) if (!isprefixed(arg_memb))
arg_memb_found[arg_memb] = false; arg_memb_found[arg_memb] = false;
@ -898,29 +901,29 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
arg_mod_found[arg_mod] = true; arg_mod_found[arg_mod] = true;
if (arg_memb == "") { if (arg_memb == "") {
sel.selected_modules.insert(mod->name); sel.selected_modules.insert(mod->meta_->name);
continue; continue;
} }
if (arg_memb.compare(0, 2, "w:") == 0) { if (arg_memb.compare(0, 2, "w:") == 0) {
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (match_ids(wire->name, arg_memb.substr(2))) if (match_ids(wire->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} else } else
if (arg_memb.compare(0, 2, "i:") == 0) { if (arg_memb.compare(0, 2, "i:") == 0) {
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (wire->port_input && match_ids(wire->name, arg_memb.substr(2))) if (wire->port_input && match_ids(wire->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} else } else
if (arg_memb.compare(0, 2, "o:") == 0) { if (arg_memb.compare(0, 2, "o:") == 0) {
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (wire->port_output && match_ids(wire->name, arg_memb.substr(2))) if (wire->port_output && match_ids(wire->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} else } else
if (arg_memb.compare(0, 2, "x:") == 0) { if (arg_memb.compare(0, 2, "x:") == 0) {
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2))) if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} else } else
if (arg_memb.compare(0, 2, "s:") == 0) { if (arg_memb.compare(0, 2, "s:") == 0) {
size_t delim = arg_memb.substr(2).find(':'); size_t delim = arg_memb.substr(2).find(':');
@ -928,7 +931,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
int width = atoi(arg_memb.substr(2).c_str()); int width = atoi(arg_memb.substr(2).c_str());
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (wire->width == width) if (wire->width == width)
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} else { } else {
std::string min_str = arg_memb.substr(2, delim); std::string min_str = arg_memb.substr(2, delim);
std::string max_str = arg_memb.substr(2+delim+1); std::string max_str = arg_memb.substr(2+delim+1);
@ -936,18 +939,18 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
int max_width = max_str.empty() ? -1 : atoi(max_str.c_str()); int max_width = max_str.empty() ? -1 : atoi(max_str.c_str());
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (min_width <= wire->width && (wire->width <= max_width || max_width == -1)) if (min_width <= wire->width && (wire->width <= max_width || max_width == -1))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
} }
} else } else
if (arg_memb.compare(0, 2, "m:") == 0) { if (arg_memb.compare(0, 2, "m:") == 0) {
for (auto &it : mod->memories) for (auto &it : mod->memories)
if (match_ids(it.first, arg_memb.substr(2))) if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
} else } else
if (arg_memb.compare(0, 2, "c:") == 0) { if (arg_memb.compare(0, 2, "c:") == 0) {
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (match_ids(cell->name, arg_memb.substr(2))) if (match_ids(cell->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
} else } else
if (arg_memb.compare(0, 2, "t:") == 0) { if (arg_memb.compare(0, 2, "t:") == 0) {
if (arg_memb.compare(2, 1, "@") == 0) { if (arg_memb.compare(2, 1, "@") == 0) {
@ -957,59 +960,59 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
auto &muster = design->selection_vars[set_name]; auto &muster = design->selection_vars[set_name];
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (muster.selected_modules.count(cell->type)) if (muster.selected_modules.count(cell->type.ref()))
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
} else { } else {
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (match_ids(cell->type, arg_memb.substr(2))) if (match_ids(cell->type, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
} }
} else } else
if (arg_memb.compare(0, 2, "p:") == 0) { if (arg_memb.compare(0, 2, "p:") == 0) {
for (auto &it : mod->processes) for (auto &it : mod->processes)
if (match_ids(it.first, arg_memb.substr(2))) if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
} else } else
if (arg_memb.compare(0, 2, "a:") == 0) { if (arg_memb.compare(0, 2, "a:") == 0) {
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (match_attr(design, wire, arg_memb.substr(2))) if (match_attr(design, wire, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
for (auto &it : mod->memories) for (auto &it : mod->memories)
if (match_attr(design, it.second, arg_memb.substr(2))) if (match_attr(design, it.second, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (match_attr(design, cell, arg_memb.substr(2))) if (match_attr(design, cell, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
for (auto &it : mod->processes) for (auto &it : mod->processes)
if (match_attr(design, it.second, arg_memb.substr(2))) if (match_attr(design, it.second, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
} else } else
if (arg_memb.compare(0, 2, "r:") == 0) { if (arg_memb.compare(0, 2, "r:") == 0) {
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (match_attr(cell->parameters, arg_memb.substr(2))) if (match_attr(cell->parameters, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
} else { } else {
std::string orig_arg_memb = arg_memb; std::string orig_arg_memb = arg_memb;
if (arg_memb.compare(0, 2, "n:") == 0) if (arg_memb.compare(0, 2, "n:") == 0)
arg_memb = arg_memb.substr(2); arg_memb = arg_memb.substr(2);
for (auto wire : mod->wires()) for (auto wire : mod->wires())
if (match_ids(wire->name, arg_memb)) { if (match_ids(wire->name, arg_memb)) {
sel.selected_members[mod->name].insert(wire->name); sel.selected_members[mod->meta_->name].insert(wire->name.ref());
arg_memb_found[orig_arg_memb] = true; arg_memb_found[orig_arg_memb] = true;
} }
for (auto &it : mod->memories) for (auto &it : mod->memories)
if (match_ids(it.first, arg_memb)) { if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb)) {
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
arg_memb_found[orig_arg_memb] = true; arg_memb_found[orig_arg_memb] = true;
} }
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (match_ids(cell->name, arg_memb)) { if (match_ids(cell->name, arg_memb)) {
sel.selected_members[mod->name].insert(cell->name); sel.selected_members[mod->meta_->name].insert(cell->name.ref());
arg_memb_found[orig_arg_memb] = true; arg_memb_found[orig_arg_memb] = true;
} }
for (auto &it : mod->processes) for (auto &it : mod->processes)
if (match_ids(it.first, arg_memb)) { if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb)) {
sel.selected_members[mod->name].insert(it.first); sel.selected_members[mod->meta_->name].insert(it.first);
arg_memb_found[orig_arg_memb] = true; arg_memb_found[orig_arg_memb] = true;
} }
} }
@ -1365,6 +1368,7 @@ struct SelectPass : public Pass {
work_stack.clear(); work_stack.clear();
TwineSearch search(&design->twines);
size_t argidx; size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) for (argidx = 1; argidx < args.size(); argidx++)
{ {
@ -1431,10 +1435,11 @@ struct SelectPass : public Pass {
continue; continue;
} }
if (arg == "-module" && argidx+1 < args.size()) { if (arg == "-module" && argidx+1 < args.size()) {
RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); std::string mod_name = RTLIL::escape_id(args[++argidx]);
if (design->module(mod_name) == nullptr) TwineRef t = search.find(mod_name);
log_cmd_error("No such module: %s\n", mod_name.unescape()); if (t == Twine::Null || design->module(t) == nullptr)
design->selected_active_module = mod_name.str(); log_cmd_error("No such module: %s\n", RTLIL::unescape_id(mod_name));
design->selected_active_module = t;
got_module = true; got_module = true;
continue; continue;
} }
@ -1475,7 +1480,7 @@ struct SelectPass : public Pass {
} }
IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos)); IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1)); IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1));
sel.selected_members[mod_name].insert(obj_name); sel.selected_members[design->twines.add(Twine{mod_name.str()})].insert(design->twines.add(Twine{obj_name.str()}));
} }
select_filter_active_mod(design, sel); select_filter_active_mod(design, sel);
@ -1519,7 +1524,7 @@ struct SelectPass : public Pass {
if (clear_mode) { if (clear_mode) {
design->selection() = RTLIL::Selection::FullSelection(design); design->selection() = RTLIL::Selection::FullSelection(design);
design->selected_active_module = std::string(); design->selected_active_module = TwineRef{};
return; return;
} }
@ -1545,11 +1550,11 @@ struct SelectPass : public Pass {
sel->optimize(design); sel->optimize(design);
for (auto mod : design->all_selected_modules()) for (auto mod : design->all_selected_modules())
{ {
if (sel->selected_whole_module(mod->name) && list_mode) if (sel->selected_whole_module(mod->meta_->name) && list_mode)
log("%s\n", mod); log("%s\n", mod);
if (!list_mod_mode) if (!list_mod_mode)
for (auto it : mod->selected_members()) for (auto it : mod->selected_members())
LOG_OBJECT("%s/%s\n", mod->name.unescape().c_str(), it->name.unescape().c_str()) LOG_OBJECT("%s/%s\n", design->twines.unescaped_str(mod->name).c_str(), mod->design->twines.unescaped_str(it->meta_->name).c_str())
} }
if (count_mode) if (count_mode)
{ {
@ -1673,10 +1678,10 @@ struct SelectPass : public Pass {
if (sel.full_selection) if (sel.full_selection)
log("*\n"); log("*\n");
for (auto &it : sel.selected_modules) for (auto &it : sel.selected_modules)
log("%s\n", it.unescape()); log("%s\n", design->twines.unescaped_str(it).c_str());
for (auto &it : sel.selected_members) for (auto &it : sel.selected_members)
for (auto &it2 : it.second) for (auto &it2 : it.second)
log("%s/%s\n", it.first.unescape(), it2.unescape()); log("%s/%s\n", design->twines.unescaped_str(it.first).c_str(), design->twines.unescaped_str(it2).c_str());
return; return;
} }
@ -1728,17 +1733,17 @@ struct CdPass : public Pass {
if (args.size() == 1 || args[1] == "/") { if (args.size() == 1 || args[1] == "/") {
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
design->selected_active_module = std::string(); design->selected_active_module = TwineRef{};
return; return;
} }
if (args[1] == "..") if (args[1] == "..")
{ {
string modname = design->selected_active_module; string modname = design->twines.str(design->selected_active_module);
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
design->selected_active_module = std::string(); design->selected_active_module = TwineRef{};
while (1) while (1)
{ {
@ -1748,12 +1753,12 @@ struct CdPass : public Pass {
break; break;
modname = modname.substr(0, pos); modname = modname.substr(0, pos);
Module *mod = design->module(modname); Module *mod = design->module(RTLIL::IdString(modname));
if (mod == nullptr) if (mod == nullptr)
continue; continue;
design->selected_active_module = modname; design->selected_active_module = design->twines.add(Twine{modname});
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
select_filter_active_mod(design, design->selection()); select_filter_active_mod(design, design->selection());
@ -1766,14 +1771,15 @@ struct CdPass : public Pass {
std::string modname = RTLIL::escape_id(args[1]); std::string modname = RTLIL::escape_id(args[1]);
if (design->module(modname) == nullptr && !design->selected_active_module.empty()) { if (design->module(RTLIL::IdString(modname)) == nullptr && design->selected_active_module) {
RTLIL::Module *module = design->module(design->selected_active_module); RTLIL::Module *module = design->module(design->selected_active_module);
if (module != nullptr && module->cell(modname) != nullptr) TwineRef cell_ref = design->twines.lookup(modname);
modname = module->cell(modname)->type.str(); if (module != nullptr && cell_ref && module->cell(cell_ref) != nullptr)
modname = design->twines.str(module->cell(cell_ref)->type.ref());
} }
if (design->module(modname) != nullptr) { if (design->module(RTLIL::IdString(modname)) != nullptr) {
design->selected_active_module = modname; design->selected_active_module = design->twines.add(Twine{modname});
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
select_filter_active_mod(design, design->selection()); select_filter_active_mod(design, design->selection());
@ -1788,17 +1794,20 @@ struct CdPass : public Pass {
template<typename T> template<typename T>
static void log_matches(const char *title, Module *module, const T &list) static void log_matches(const char *title, Module *module, const T &list)
{ {
std::vector<IdString> matches; std::vector<TwineRef> matches;
for (auto &it : list) for (auto &it : list)
if (module->selected(it.second)) if (module->selected(it.second))
matches.push_back(RTLIL::IdString(it.second->name)); matches.push_back(it.first);
if (!matches.empty()) { if (!matches.empty()) {
log("\n%d %s:\n", int(matches.size()), title); log("\n%d %s:\n", int(matches.size()), title);
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); auto &twines = module->design->twines;
for (auto id : matches) std::sort(matches.begin(), matches.end(), [&](TwineRef a, TwineRef b) {
log(" %s\n", id.unescape()); return twines.str(a) < twines.str(b);
});
for (auto ref : matches)
log(" %s\n", twines.unescaped_str(ref).c_str());
} }
} }
@ -1825,7 +1834,7 @@ struct LsPass : public Pass {
size_t argidx = 1; size_t argidx = 1;
extra_args(args, argidx, design); extra_args(args, argidx, design);
if (design->selected_active_module.empty()) if (!design->selected_active_module)
{ {
std::vector<IdString> matches; std::vector<IdString> matches;
@ -1836,7 +1845,7 @@ struct LsPass : public Pass {
log("\n%d %s:\n", int(matches.size()), "modules"); log("\n%d %s:\n", int(matches.size()), "modules");
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
for (auto id : matches) for (auto id : matches)
log(" %s%s\n", id.unescape(), design->selected_whole_module(design->module(id)) ? "" : "*"); log(" %s%s\n", design->twines.unescaped_str(id), design->selected_whole_module(design->module(id)) ? "" : "*");
} }
} }
else else

View File

@ -39,7 +39,7 @@ static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width
RTLIL::Wire *wire = NULL; RTLIL::Wire *wire = NULL;
TwineRef t = module->design->twines.add(Twine{name}); TwineRef t = module->design->twines.add(Twine{name});
if (module->count_id(name) != 0) if (module->count_id(t) != 0)
{ {
log("Module %s already has such an object %s.\n", module->name, name); log("Module %s already has such an object %s.\n", module->name, name);
name += "$"; name += "$";
@ -47,7 +47,7 @@ static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width
} }
else else
{ {
wire = module->addWire(name, width); wire = module->addWire(t, width);
wire->port_input = flag_input; wire->port_input = flag_input;
wire->port_output = flag_output; wire->port_output = flag_output;
@ -305,7 +305,7 @@ struct SetundefPass : public Pass {
CellTypes ct(design); CellTypes ct(design);
for (auto &it : module->cells_) for (auto &it : module->cells_)
for (auto &conn : it.second->connections()) for (auto &conn : it.second->connections())
if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) if (!ct.cell_known(it.second->type.ref()) || ct.cell_output(it.second->type.ref(), conn.first))
undriven_signals.del(sigmap(conn.second)); undriven_signals.del(sigmap(conn.second));
RTLIL::SigSpec sig = undriven_signals.export_all(); RTLIL::SigSpec sig = undriven_signals.export_all();
@ -340,7 +340,7 @@ struct SetundefPass : public Pass {
CellTypes ct(design); CellTypes ct(design);
for (auto &it : module->cells_) for (auto &it : module->cells_)
for (auto &conn : it.second->connections()) for (auto &conn : it.second->connections())
if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) if (!ct.cell_known(it.second->type.ref()) || ct.cell_output(it.second->type.ref(), conn.first))
undriven_signals.del(sigmap(conn.second)); undriven_signals.del(sigmap(conn.second));
RTLIL::SigSpec sig = undriven_signals.export_all(); RTLIL::SigSpec sig = undriven_signals.export_all();

View File

@ -148,14 +148,15 @@ struct ShowWorker
std::string findColor(IdString member_name) std::string findColor(IdString member_name)
{ {
TwineRef member_ref = design->twines.lookup(member_name.str());
for (auto &s : color_selections) for (auto &s : color_selections)
if (s.second.selected_member(module->name, member_name)) { if (member_ref && s.second.selected_member(module->meta_->name, member_ref)) {
return stringf("color=\"%s\", fontcolor=\"%s\"", s.first, s.first); return stringf("color=\"%s\", fontcolor=\"%s\"", s.first, s.first);
} }
RTLIL::Const colorattr_value; RTLIL::Const colorattr_value;
RTLIL::Cell *cell = module->cell(member_name); RTLIL::Cell *cell = member_ref ? module->cell(member_ref) : nullptr;
RTLIL::Wire *wire = module->wire(member_name); RTLIL::Wire *wire = member_ref ? module->wire(member_ref) : nullptr;
if (cell && cell->attributes.count(colorattr)) if (cell && cell->attributes.count(colorattr))
colorattr_value = cell->attributes.at(colorattr); colorattr_value = cell->attributes.at(colorattr);
@ -174,8 +175,9 @@ struct ShowWorker
const char *findLabel(std::string member_name) const char *findLabel(std::string member_name)
{ {
TwineRef member_ref = design->twines.lookup(member_name);
for (auto &s : label_selections) for (auto &s : label_selections)
if (s.second.selected_member(module->name, member_name)) if (member_ref && s.second.selected_member(module->meta_->name, member_ref))
return escape(s.first); return escape(s.first);
return escape(member_name, true); return escape(member_name, true);
} }
@ -240,7 +242,7 @@ struct ShowWorker
if (sig.is_chunk()) { if (sig.is_chunk()) {
const RTLIL::SigChunk &c = sig.as_chunk(); const RTLIL::SigChunk &c = sig.as_chunk();
if (c.wire != nullptr && design->selected_member(module->name, c.wire->name)) { if (c.wire != nullptr && design->selected_member(module->meta_->name, c.wire->name.ref())) {
if (!range_check || c.wire->width == c.width) if (!range_check || c.wire->width == c.width)
return stringf("n%d", id2num(c.wire->name)); return stringf("n%d", id2num(c.wire->name));
} else { } else {
@ -472,10 +474,10 @@ struct ShowWorker
std::vector<std::string> in_label_pieces, out_label_pieces; std::vector<std::string> in_label_pieces, out_label_pieces;
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
if (!ct.cell_output(cell->type, conn.first)) if (!ct.cell_output(cell->type.ref(), conn.first))
in_ports.push_back(conn.first); in_ports.push_back(RTLIL::IdString(design->twines.str(conn.first)));
else else
out_ports.push_back(conn.first); out_ports.push_back(RTLIL::IdString(design->twines.str(conn.first)));
} }
std::sort(in_ports.begin(), in_ports.end(), RTLIL::sort_by_id_str()); std::sort(in_ports.begin(), in_ports.end(), RTLIL::sort_by_id_str());
@ -501,8 +503,8 @@ struct ShowWorker
std::string code; std::string code;
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(conn.first)), code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(RTLIL::IdString(design->twines.str(conn.first)))),
conn.second, ct.cell_output(cell->type, conn.first)); conn.second, ct.cell_output(cell->type.ref(), conn.first));
} }
std::string src_href; std::string src_href;
@ -523,7 +525,7 @@ struct ShowWorker
{ {
RTLIL::Process *proc = it.second; RTLIL::Process *proc = it.second;
if (!design->selected_member(module->name, proc->name)) if (!design->selected_member(module->meta_->name, it.first))
continue; continue;
std::set<RTLIL::SigSpec> input_signals, output_signals; std::set<RTLIL::SigSpec> input_signals, output_signals;
@ -549,22 +551,23 @@ struct ShowWorker
net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); net_conn_map[node].color = nextColor(sig, net_conn_map[node].color);
} }
std::string proc_src = proc->name.unescape(); std::string proc_name_str = design->twines.str(it.first);
std::string proc_src = design->twines.unescaped_str(it.first);
if (proc->has_attribute(ID::src) > 0) if (proc->has_attribute(ID::src) > 0)
proc_src = proc->get_src_attribute(); proc_src = proc->get_src_attribute();
fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\", %s];\n", pidx, findLabel(proc->name.str()), proc_src.c_str(), findColor(proc->name).c_str()); fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\", %s];\n", pidx, findLabel(proc_name_str), proc_src.c_str(), findColor(RTLIL::IdString(proc_name_str)).c_str());
} }
for (auto &conn : module->connections()) for (auto &conn : module->connections())
{ {
bool found_lhs_wire = false; bool found_lhs_wire = false;
for (auto &c : conn.first.chunks()) { for (auto &c : conn.first.chunks()) {
if (c.wire == nullptr || design->selected_member(module->name, c.wire->name)) if (c.wire == nullptr || design->selected_member(module->meta_->name, c.wire->name.ref()))
found_lhs_wire = true; found_lhs_wire = true;
} }
bool found_rhs_wire = false; bool found_rhs_wire = false;
for (auto &c : conn.second.chunks()) { for (auto &c : conn.second.chunks()) {
if (c.wire == nullptr || design->selected_member(module->name, c.wire->name)) if (c.wire == nullptr || design->selected_member(module->meta_->name, c.wire->name.ref()))
found_rhs_wire = true; found_rhs_wire = true;
} }
if (!found_lhs_wire || !found_rhs_wire) if (!found_lhs_wire || !found_rhs_wire)
@ -645,16 +648,16 @@ struct ShowWorker
module = mod; module = mod;
if (design->selected_whole_module(module->name)) { if (design->selected_whole_module(module->name)) {
if (module->get_blackbox_attribute()) { if (module->get_blackbox_attribute()) {
//log("Skipping blackbox module %s.\n", module->name.unescape()); //log("Skipping blackbox module %s.\n", design->twines.unescaped_str(module->name));
continue; continue;
} else } else
if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) { if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) {
log("Skipping empty module %s.\n", module->name.unescape()); log("Skipping empty module %s.\n", design->twines.unescaped_str(module->name));
continue; continue;
} else } else
log("Dumping module %s to page %d.\n", module->name.unescape(), ++page_counter); log("Dumping module %s to page %d.\n", design->twines.unescaped_str(module->name), ++page_counter);
} else } else
log("Dumping selected parts of module %s to page %d.\n", module->name.unescape(), ++page_counter); log("Dumping selected parts of module %s to page %d.\n", design->twines.unescaped_str(module->name), ++page_counter);
handle_module(); handle_module();
} }
} }

View File

@ -75,7 +75,7 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = sig; RTLIL::SigSpec new_sig = sig;
if (sig_a.size() != sig.size()) { if (sig_a.size() != sig.size()) {
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($slice)); RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$slice);
cell->parameters[ID::OFFSET] = offset; cell->parameters[ID::OFFSET] = offset;
cell->parameters[ID::A_WIDTH] = sig_a.size(); cell->parameters[ID::A_WIDTH] = sig_a.size();
cell->parameters[ID::Y_WIDTH] = sig.size(); cell->parameters[ID::Y_WIDTH] = sig.size();
@ -132,7 +132,7 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front()); RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
for (size_t i = 1; i < chunks.size(); i++) { for (size_t i = 1; i < chunks.size(); i++) {
RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]); RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]);
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($concat)); RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$concat);
cell->parameters[ID::A_WIDTH] = new_sig.size(); cell->parameters[ID::A_WIDTH] = new_sig.size();
cell->parameters[ID::B_WIDTH] = sig2.size(); cell->parameters[ID::B_WIDTH] = sig2.size();
cell->setPort(TW::A, new_sig); cell->setPort(TW::A, new_sig);
@ -149,7 +149,7 @@ struct SpliceWorker
void run() void run()
{ {
log("Splicing signals in module %s:\n", module->name.unescape()); log("Splicing signals in module %s:\n", design->twines.unescaped_str(module->name));
driven_bits.push_back(RTLIL::State::Sm); driven_bits.push_back(RTLIL::State::Sm);
driven_bits.push_back(RTLIL::State::Sm); driven_bits.push_back(RTLIL::State::Sm);
@ -165,7 +165,7 @@ struct SpliceWorker
for (auto cell : module->cells()) for (auto cell : module->cells())
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) { if (!ct.cell_known(cell->type.ref()) || ct.cell_output(cell->type.ref(), conn.first)) {
RTLIL::SigSpec sig = sigmap(conn.second); RTLIL::SigSpec sig = sigmap(conn.second);
driven_chunks.insert(sig); driven_chunks.insert(sig);
for (auto &bit : sig.to_sigbit_vector()) for (auto &bit : sig.to_sigbit_vector())
@ -189,10 +189,10 @@ struct SpliceWorker
if (!sel_by_wire && !design->selected(module, cell)) if (!sel_by_wire && !design->selected(module, cell))
continue; continue;
for (auto &conn : cell->connections_) for (auto &conn : cell->connections_)
if (ct.cell_input(cell->type, conn.first)) { if (ct.cell_input(cell->type.ref(), conn.first)) {
if (ports.size() > 0 && !ports.count(conn.first)) if (ports.size() > 0 && !ports.count(RTLIL::IdString(design->twines.str(conn.first))))
continue; continue;
if (no_ports.size() > 0 && no_ports.count(conn.first)) if (no_ports.size() > 0 && no_ports.count(RTLIL::IdString(design->twines.str(conn.first))))
continue; continue;
RTLIL::SigSpec sig = sigmap(conn.second); RTLIL::SigSpec sig = sigmap(conn.second);
if (!sel_by_cell) { if (!sel_by_cell) {
@ -231,8 +231,8 @@ struct SpliceWorker
for (auto &it : rework_wires) for (auto &it : rework_wires)
{ {
RTLIL::IdString orig_name = it.first->name; TwineRef orig_name = it.first->name.ref();
module->rename(it.first, NEW_ID); module->rename(it.first, design->twines.add(NEW_TWINE));
RTLIL::Wire *new_port = module->addWire(orig_name, it.first); RTLIL::Wire *new_port = module->addWire(orig_name, it.first);
it.first->port_id = 0; it.first->port_id = 0;

View File

@ -181,9 +181,9 @@ struct SplitnetsPass : public Pass {
for (auto c : module->cells()) for (auto c : module->cells())
for (auto &p : c->connections()) for (auto &p : c->connections())
{ {
if (!ct.cell_known(c->type)) if (!ct.cell_known(c->type.ref()))
continue; continue;
if (!ct.cell_output(c->type, p.first)) if (!ct.cell_output(c->type.ref(), p.first))
continue; continue;
RTLIL::SigSpec sig = p.second; RTLIL::SigSpec sig = p.second;

View File

@ -35,8 +35,8 @@ struct StaWorker
struct t_data { struct t_data {
Cell* driver; Cell* driver;
IdString dst_port, src_port; TwineRef dst_port, src_port;
vector<tuple<SigBit,int,IdString>> fanouts; vector<tuple<SigBit,int,TwineRef>> fanouts;
SigBit backtrack; SigBit backtrack;
t_data() : driver(nullptr) {} t_data() : driver(nullptr) {}
}; };
@ -44,7 +44,7 @@ struct StaWorker
std::deque<SigBit> queue; std::deque<SigBit> queue;
struct t_endpoint { struct t_endpoint {
Cell *sink; Cell *sink;
IdString port; TwineRef port;
int required; int required;
t_endpoint() : sink(nullptr), required(0) {} t_endpoint() : sink(nullptr), required(0) {}
}; };
@ -66,23 +66,23 @@ struct StaWorker
Module *inst_module = design->module(cell->type); Module *inst_module = design->module(cell->type);
if (!inst_module) { if (!inst_module) {
if (unrecognised_cells.insert(cell->type).second) if (unrecognised_cells.insert(cell->type).second)
log_warning("Cell type '%s' not recognised! Ignoring.\n", cell->type.unescape()); log_warning("Cell type '%s' not recognised! Ignoring.\n", cell->type.unescaped());
continue; continue;
} }
if (!inst_module->get_blackbox_attribute()) { if (!inst_module->get_blackbox_attribute()) {
log_warning("Cell type '%s' is not a black- nor white-box! Ignoring.\n", cell->type.unescape()); log_warning("Cell type '%s' is not a black- nor white-box! Ignoring.\n", cell->type.unescaped());
continue; continue;
} }
IdString derived_type = inst_module->derive(design, cell->parameters); TwineRef derived_type = inst_module->derive(design, cell->parameters);
inst_module = design->module(derived_type); inst_module = design->module(derived_type);
log_assert(inst_module); log_assert(inst_module);
if (!timing.count(derived_type)) { if (!timing.count(derived_type)) {
auto &t = timing.setup_module(inst_module); auto &t = timing.setup_module(inst_module);
if (t.has_inputs && t.comb.empty() && t.arrival.empty() && t.required.empty()) if (t.has_inputs && t.comb.empty() && t.arrival.empty() && t.required.empty())
log_warning("Module '%s' has no timing arcs!\n", cell->type.unescape()); log_warning("Module '%s' has no timing arcs!\n", cell->type.unescaped());
} }
auto &t = timing.at(derived_type); auto &t = timing.at(derived_type);
@ -206,7 +206,7 @@ struct StaWorker
log("Latest arrival time in '%s' is %d:\n", module, maxarrival); log("Latest arrival time in '%s' is %d:\n", module, maxarrival);
auto it = endpoints.find(maxbit); auto it = endpoints.find(maxbit);
if (it != endpoints.end() && it->second.sink) if (it != endpoints.end() && it->second.sink)
log(" %6d %s (%s.%s)\n", maxarrival, it->second.sink, it->second.sink->type.unescape(), it->second.port.unescape()); log(" %6d %s (%s.%s)\n", maxarrival, it->second.sink, design->twines.unescaped_str(it->second.sink->type), design->twines.unescaped_str(it->second.port));
else { else {
log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "<primary output>" : "<unknown>"); log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "<primary output>" : "<unknown>");
if (!b.wire->port_output) if (!b.wire->port_output)
@ -217,7 +217,7 @@ struct StaWorker
int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset];
if (jt->second.driver) { if (jt->second.driver) {
log(" %s\n", log_signal(b)); log(" %s\n", log_signal(b));
log(" %6d %s (%s.%s->%s)\n", arrival, jt->second.driver, jt->second.driver->type.unescape(), jt->second.src_port.unescape(), jt->second.dst_port.unescape()); log(" %6d %s (%s.%s->%s)\n", arrival, jt->second.driver, design->twines.unescaped_str(jt->second.driver->type), design->twines.unescaped_str(jt->second.src_port), design->twines.unescaped_str(jt->second.dst_port));
} }
else if (b.wire->port_input) else if (b.wire->port_input)
log(" %6d %s (%s)\n", arrival, log_signal(b), "<primary input>"); log(" %6d %s (%s)\n", arrival, log_signal(b), "<primary input>");

View File

@ -59,18 +59,18 @@ struct statdata_t {
double local_sequential_area = 0; double local_sequential_area = 0;
double submodule_area = 0; double submodule_area = 0;
int num_submodules = 0; int num_submodules = 0;
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> num_submodules_by_type; std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> num_submodules_by_type;
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> submodules_area_by_type; std::map<TwineRef, double, RTLIL::sort_by_id_str> submodules_area_by_type;
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type; std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type;
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> local_area_cells_by_type; std::map<TwineRef, double, RTLIL::sort_by_id_str> local_area_cells_by_type;
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type; std::map<TwineRef, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type;
string tech; string tech;
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type; std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type;
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> area_cells_by_type; std::map<TwineRef, double, RTLIL::sort_by_id_str> area_cells_by_type;
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> seq_area_cells_by_type; std::map<TwineRef, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
std::set<RTLIL::IdString> unknown_cell_area; std::set<TwineRef> unknown_cell_area;
statdata_t operator+(const statdata_t &other) const statdata_t operator+(const statdata_t &other) const
{ {
@ -141,7 +141,7 @@ struct statdata_t {
} }
} }
statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname) statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<TwineRef, cell_area_t> &cell_area, string techname)
{ {
tech = techname; tech = techname;
@ -183,35 +183,35 @@ struct statdata_t {
local_num_memory_bits += it.second->width * it.second->size; local_num_memory_bits += it.second->width * it.second->size;
} }
for (auto cell : mod->selected_cells()) { for (auto cell : mod->selected_cells()) {
RTLIL::IdString cell_type = cell->type; TwineRef cell_type = cell->type_impl;
if (width_mode) { if (width_mode) {
if (cell_type.in(ID($not), ID($pos), ID($neg), ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_and), if (cell_type.in(TW($not), TW($pos), TW($neg), TW($logic_not), TW($logic_and), TW($logic_or), TW($reduce_and),
ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($lut), ID($and), ID($or), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($lut), TW($and), TW($or),
ID($xor), ID($xnor), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), ID($lt), TW($xor), TW($xnor), TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx), TW($lt),
ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), ID($add), ID($sub), ID($mul), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt), TW($add), TW($sub), TW($mul),
ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow), ID($alu))) { TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow), TW($alu))) {
int width_a = cell->hasPort(TW::A) ? GetSize(cell->getPort(TW::A)) : 0; int width_a = cell->hasPort(TW::A) ? GetSize(cell->getPort(TW::A)) : 0;
int width_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 0; int width_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 0;
int width_y = cell->hasPort(TW::Y) ? GetSize(cell->getPort(TW::Y)) : 0; int width_y = cell->hasPort(TW::Y) ? GetSize(cell->getPort(TW::Y)) : 0;
cell_type = stringf("%s_%d", cell_type, max<int>({width_a, width_b, width_y})); cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, max<int>({width_a, width_b, width_y}))});
} else if (cell_type.in(ID($mux))) } else if (cell_type.in(TW($mux)))
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y))); cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y)))});
else if (cell_type.in(ID($bmux), ID($pmux))) else if (cell_type.in(TW($bmux), TW($pmux)))
cell_type = cell_type =
stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S))); design->twines.add(Twine{stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S)))});
else if (cell_type == ID($demux)) else if (cell_type == TW($demux))
cell_type = cell_type =
stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::S))); design->twines.add(Twine{stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::S)))});
else if (cell_type.in(ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), else if (cell_type.in(TW($sr), TW($ff), TW($dff), TW($dffe), TW($dffsr), TW($dffsre), TW($adff), TW($adffe),
ID($sdff), ID($sdffe), ID($sdffce), ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch), TW($sdff), TW($sdffe), TW($sdffce), TW($aldff), TW($aldffe), TW($dlatch), TW($adlatch),
ID($dlatchsr))) TW($dlatchsr)))
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q))); cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q)))});
} }
if (!cell_area.empty()) { if (!cell_area.empty()) {
// check if cell_area provides a area calculator // check if cell_area provides a area calculator
if (cell_area.count(cell->type)) { if (cell_area.count(cell->type_impl)) {
cell_area_t cell_data = cell_area.at(cell->type); cell_area_t cell_data = cell_area.at(cell->type_impl);
if (cell_data.single_parameter_area.size() > 0) { if (cell_data.single_parameter_area.size() > 0) {
// assume that we just take the max of the A,B,Y ports // assume that we just take the max of the A,B,Y ports
@ -337,18 +337,16 @@ struct statdata_t {
num_processes++; num_processes++;
local_num_processes++; local_num_processes++;
} }
RTLIL::IdString cell_name = mod->name;
auto s = cell_name.str();
} }
unsigned int estimate_xilinx_lc() unsigned int estimate_xilinx_lc()
{ {
unsigned int lut6_cnt = num_cells_by_type[ID(LUT6)]; unsigned int lut6_cnt = num_cells_by_type[TW::LUT6];
unsigned int lut5_cnt = num_cells_by_type[ID(LUT5)]; unsigned int lut5_cnt = num_cells_by_type[TW::LUT5];
unsigned int lut4_cnt = num_cells_by_type[ID(LUT4)]; unsigned int lut4_cnt = num_cells_by_type[TW::LUT4];
unsigned int lut3_cnt = num_cells_by_type[ID(LUT3)]; unsigned int lut3_cnt = num_cells_by_type[TW::LUT3];
unsigned int lut2_cnt = num_cells_by_type[ID(LUT2)]; unsigned int lut2_cnt = num_cells_by_type[TW::LUT2];
unsigned int lut1_cnt = num_cells_by_type[ID(LUT1)]; unsigned int lut1_cnt = num_cells_by_type[TW::LUT1];
unsigned int lc_cnt = 0; unsigned int lc_cnt = 0;
lc_cnt += lut6_cnt; lc_cnt += lut6_cnt;
@ -505,7 +503,7 @@ struct statdata_t {
} }
} }
void log_data(RTLIL::IdString mod_name, bool top_mod, bool print_area = true, bool print_hierarchical = true, bool print_global_only = false) void log_data(const TwinePool& twines, TwineRef mod_name, bool top_mod, bool print_area = true, bool print_hierarchical = true, bool print_global_only = false)
{ {
print_log_header(print_area, print_hierarchical, print_global_only); print_log_header(print_area, print_hierarchical, print_global_only);
@ -523,7 +521,7 @@ struct statdata_t {
print_log_line("cells", local_num_cells, local_area, num_cells, area, 0, print_area, print_hierarchical, print_global_only); print_log_line("cells", local_num_cells, local_area, num_cells, area, 0, print_area, print_hierarchical, print_global_only);
for (auto &it : num_cells_by_type) for (auto &it : num_cells_by_type)
if (it.second) { if (it.second) {
auto name = string(it.first.unescape()); auto name = twines.unescaped_str(it.first);
print_log_line(name, local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, print_log_line(name, local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0,
local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second,
area_cells_by_type.at(it.first), 1, print_area, print_hierarchical, print_global_only); area_cells_by_type.at(it.first), 1, print_area, print_hierarchical, print_global_only);
@ -533,7 +531,7 @@ struct statdata_t {
print_global_only); print_global_only);
for (auto &it : num_submodules_by_type) for (auto &it : num_submodules_by_type)
if (it.second) if (it.second)
print_log_line(string(it.first.unescape()), it.second, 0, it.second, print_log_line(twines.unescaped_str(it.first), it.second, 0, it.second,
submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0, 1, submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0, 1,
print_area, print_hierarchical, print_global_only); print_area, print_hierarchical, print_global_only);
} }
@ -582,7 +580,7 @@ struct statdata_t {
count_local, area_local); count_local, area_local);
} }
void log_data_json(const char *mod_name, bool first_module, bool hierarchical = false, bool global_only = false) void log_data_json(const TwinePool& twines, const char *mod_name, bool first_module, bool hierarchical = false, bool global_only = false)
{ {
if (!first_module) if (!first_module)
log(",\n"); log(",\n");
@ -607,7 +605,7 @@ struct statdata_t {
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %s", json11::Json(it.first.unescape()).dump(), log(" %s: %s", json11::Json(twines.unescaped_str(it.first)).dump(),
json_line(local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, json_line(local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0,
local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second,
area_cells_by_type.at(it.first)) area_cells_by_type.at(it.first))
@ -621,7 +619,7 @@ struct statdata_t {
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %s", json11::Json(it.first.unescape()).dump(), log(" %s: %s", json11::Json(twines.unescaped_str(it.first)).dump(),
json_line(0, 0, it.second, json_line(0, 0, it.second,
submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0) submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0)
.c_str()); .c_str());
@ -662,14 +660,14 @@ struct statdata_t {
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second);
first_line = false; first_line = false;
} }
for (auto &it : num_submodules_by_type) for (auto &it : num_submodules_by_type)
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second);
first_line = false; first_line = false;
} }
log("\n"); log("\n");
@ -697,14 +695,14 @@ struct statdata_t {
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second);
first_line = false; first_line = false;
} }
for (auto &it : num_submodules_by_type) for (auto &it : num_submodules_by_type)
if (it.second) { if (it.second) {
if (!first_line) if (!first_line)
log(",\n"); log(",\n");
log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second);
first_line = false; first_line = false;
} }
log("\n"); log("\n");
@ -726,7 +724,7 @@ struct statdata_t {
} }
}; };
statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTLIL::IdString mod, int level, bool quiet = false, bool has_area = true, statdata_t hierarchy_worker(const TwinePool& twines, std::map<TwineRef, statdata_t> &mod_stat, TwineRef mod, int level, bool quiet = false, bool has_area = true,
bool hierarchy_mode = true) bool hierarchy_mode = true)
{ {
statdata_t mod_data = mod_stat.at(mod); statdata_t mod_data = mod_stat.at(mod);
@ -734,60 +732,60 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL
for (auto &it : mod_data.num_submodules_by_type) { for (auto &it : mod_data.num_submodules_by_type) {
if (mod_stat.count(it.first) > 0) { if (mod_stat.count(it.first) > 0) {
if (!quiet) if (!quiet)
mod_data.print_log_line(string(it.first.unescape()), mod_stat.at(it.first).local_num_cells, mod_data.print_log_line(twines.unescaped_str(it.first), mod_stat.at(it.first).local_num_cells,
mod_stat.at(it.first).local_area, mod_stat.at(it.first).num_cells, mod_stat.at(it.first).area, mod_stat.at(it.first).local_area, mod_stat.at(it.first).num_cells, mod_stat.at(it.first).area,
level, has_area, hierarchy_mode); level, has_area, hierarchy_mode);
hierarchy_worker(mod_stat, it.first, level + 1, quiet, has_area, hierarchy_mode) * it.second; hierarchy_worker(twines, mod_stat, it.first, level + 1, quiet, has_area, hierarchy_mode) * it.second;
} }
} }
return mod_data; return mod_data;
} }
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat, statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<TwineRef, statdata_t> &mod_stat,
bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname) bool width_mode, dict<TwineRef, cell_area_t> &cell_area, string techname)
{ {
if (top_mod == nullptr) if (top_mod == nullptr)
top_mod = design->top_module(); top_mod = design->top_module();
statdata_t mod_data(design, top_mod, width_mode, cell_area, techname); statdata_t mod_data(design, top_mod, width_mode, cell_area, techname);
for (auto cell : top_mod->selected_cells()) { for (auto cell : top_mod->selected_cells()) {
if (cell_area.count(cell->type) == 0) { if (cell_area.count(cell->type_impl) == 0) {
if (design->has(cell->type)) { if (design->has(cell->type_impl)) {
if (!(design->module(cell->type)->attributes.count(ID::blackbox))) { if (!(design->module(cell->type)->attributes.count(ID::blackbox))) {
// deal with modules // deal with modules
mod_data.add( mod_data.add(
hierarchy_builder(design, design->module(cell->type), mod_stat, width_mode, cell_area, techname)); hierarchy_builder(design, design->module(cell->type), mod_stat, width_mode, cell_area, techname));
mod_data.num_submodules_by_type[cell->type]++; mod_data.num_submodules_by_type[cell->type_impl]++;
mod_data.submodules_area_by_type[cell->type] += mod_stat.at(cell->type).area; mod_data.submodules_area_by_type[cell->type_impl] += mod_stat.at(cell->type_impl).area;
mod_data.submodule_area += mod_stat.at(cell->type).area; mod_data.submodule_area += mod_stat.at(cell->type_impl).area;
mod_data.num_submodules++; mod_data.num_submodules++;
mod_data.unknown_cell_area.erase(cell->type); mod_data.unknown_cell_area.erase(cell->type_impl);
mod_data.num_cells -= mod_data.num_cells -=
(mod_data.num_cells_by_type.count(cell->type) != 0) ? mod_data.num_cells_by_type.at(cell->type) : 0; (mod_data.num_cells_by_type.count(cell->type_impl) != 0) ? mod_data.num_cells_by_type.at(cell->type_impl) : 0;
mod_data.num_cells_by_type.erase(cell->type); mod_data.num_cells_by_type.erase(cell->type_impl);
mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0) mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type_impl) != 0)
? mod_data.local_num_cells_by_type.at(cell->type) ? mod_data.local_num_cells_by_type.at(cell->type_impl)
: 0; : 0;
mod_data.local_num_cells_by_type.erase(cell->type); mod_data.local_num_cells_by_type.erase(cell->type_impl);
mod_data.local_area_cells_by_type.erase(cell->type); mod_data.local_area_cells_by_type.erase(cell->type_impl);
} else { } else {
// deal with blackbox cells // deal with blackbox cells
if (design->module(cell->type)->attributes.count(ID::area) && if (design->module(cell->type)->attributes.count(ID::area) &&
design->module(cell->type)->attributes.at(ID::area).size() == 0) { design->module(cell->type)->attributes.at(ID::area).size() == 0) {
mod_data.num_submodules_by_type[cell->type]++; mod_data.num_submodules_by_type[cell->type_impl]++;
mod_data.num_submodules++; mod_data.num_submodules++;
mod_data.submodules_area_by_type[cell->type] += mod_data.submodules_area_by_type[cell->type_impl] +=
double(design->module(cell->type)->attributes.at(ID::area).as_int()); double(design->module(cell->type_impl)->attributes.at(ID::area).as_int());
mod_data.area += double(design->module(cell->type)->attributes.at(ID::area).as_int()); mod_data.area += double(design->module(cell->type_impl)->attributes.at(ID::area).as_int());
mod_data.unknown_cell_area.erase(cell->type); mod_data.unknown_cell_area.erase(cell->type_impl);
mod_data.num_cells -= mod_data.num_cells -=
(mod_data.num_cells_by_type.count(cell->type) != 0) ? mod_data.num_cells_by_type.at(cell->type) : 0; (mod_data.num_cells_by_type.count(cell->type_impl) != 0) ? mod_data.num_cells_by_type.at(cell->type_impl) : 0;
mod_data.num_cells_by_type.erase(cell->type); mod_data.num_cells_by_type.erase(cell->type_impl);
mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0) mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type_impl) != 0)
? mod_data.local_num_cells_by_type.at(cell->type) ? mod_data.local_num_cells_by_type.at(cell->type_impl)
: 0; : 0;
mod_data.local_num_cells_by_type.erase(cell->type); mod_data.local_num_cells_by_type.erase(cell->type_impl);
mod_data.local_area_cells_by_type.erase(cell->type); mod_data.local_area_cells_by_type.erase(cell->type_impl);
} }
} }
} }
@ -797,7 +795,7 @@ statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod
return mod_data; return mod_data;
} }
void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string liberty_file) void read_liberty_cellarea(TwinePool& twines, dict<TwineRef, cell_area_t> &cell_area, string liberty_file)
{ {
std::istream *f = uncompressed(liberty_file.c_str()); std::istream *f = uncompressed(liberty_file.c_str());
yosys_input_files.insert(liberty_file); yosys_input_files.insert(liberty_file);
@ -874,7 +872,8 @@ void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string libert
if (ar != nullptr && !ar->value.empty()) { if (ar != nullptr && !ar->value.empty()) {
string prefix = cell->args[0].substr(0, 1) == "$" ? "" : "\\"; string prefix = cell->args[0].substr(0, 1) == "$" ? "" : "\\";
cell_area[prefix + cell->args[0]] = {atof(ar->value.c_str()), is_flip_flop, single_parameter_area, double_parameter_area, TwineRef t = twines.add(Twine{prefix + cell->args[0]});
cell_area[t] = {atof(ar->value.c_str()), is_flip_flop, single_parameter_area, double_parameter_area,
port_names}; port_names};
} }
} }
@ -927,8 +926,8 @@ struct StatPass : public Pass {
{ {
bool width_mode = false, json_mode = false, hierarchy_mode = false; bool width_mode = false, json_mode = false, hierarchy_mode = false;
RTLIL::Module *top_mod = nullptr; RTLIL::Module *top_mod = nullptr;
std::map<RTLIL::IdString, statdata_t> mod_stat; std::map<TwineRef, statdata_t> mod_stat;
dict<IdString, cell_area_t> cell_area; dict<TwineRef, cell_area_t> cell_area;
string techname; string techname;
size_t argidx; size_t argidx;
@ -940,7 +939,7 @@ struct StatPass : public Pass {
if (args[argidx] == "-liberty" && argidx + 1 < args.size()) { if (args[argidx] == "-liberty" && argidx + 1 < args.size()) {
string liberty_file = args[++argidx]; string liberty_file = args[++argidx];
rewrite_filename(liberty_file); rewrite_filename(liberty_file);
read_liberty_cellarea(cell_area, liberty_file); read_liberty_cellarea(design->twines, cell_area, liberty_file);
continue; continue;
} }
if (args[argidx] == "-tech" && argidx + 1 < args.size()) { if (args[argidx] == "-tech" && argidx + 1 < args.size()) {
@ -1005,13 +1004,13 @@ struct StatPass : public Pass {
top_mod = mod; top_mod = mod;
statdata_t data = mod_stat.at(mod->name); statdata_t data = mod_stat.at(mod->name);
if (json_mode) { if (json_mode) {
data.log_data_json(mod->name.c_str(), first_module, hierarchy_mode); data.log_data_json(design->twines, mod->name.c_str(), first_module, hierarchy_mode);
first_module = false; first_module = false;
} else { } else {
log("\n"); log("\n");
log("=== %s%s ===\n", mod->name.unescape(), mod->is_selected_whole() ? "" : " (partially selected)"); log("=== %s%s ===\n", design->twines.unescaped_str(mod->name), mod->is_selected_whole() ? "" : " (partially selected)");
log("\n"); log("\n");
data.log_data(mod->name, false, has_area, hierarchy_mode); data.log_data(design->twines, mod->name, false, has_area, hierarchy_mode);
} }
} }
@ -1031,13 +1030,13 @@ struct StatPass : public Pass {
mod_stat[top_mod->name].area, 0, has_area, hierarchy_mode, true); mod_stat[top_mod->name].area, 0, has_area, hierarchy_mode, true);
} }
statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0, /*quiet=*/json_mode, has_area, hierarchy_mode); statdata_t data = hierarchy_worker(design->twines, mod_stat, top_mod->name, 0, /*quiet=*/json_mode, has_area, hierarchy_mode);
if (json_mode) if (json_mode)
data.log_data_json("design", true, hierarchy_mode, true); data.log_data_json(design->twines, "design", true, hierarchy_mode, true);
else if (GetSize(mod_stat) > 1) { else if (GetSize(mod_stat) > 1) {
log("\n"); log("\n");
data.log_data(top_mod->name, true, has_area, hierarchy_mode, true); data.log_data(design->twines, top_mod->name, true, has_area, hierarchy_mode, true);
} }
design->scratchpad_set_int("stat.num_wires", data.num_wires); design->scratchpad_set_int("stat.num_wires", data.num_wires);

View File

@ -17,12 +17,12 @@ struct TestPatchPass : public Pass {
for (auto module : design->selected_modules()) { for (auto module : design->selected_modules()) {
SigMap sigmap(module); SigMap sigmap(module);
for (auto cell : module->selected_cells()) { for (auto cell : module->selected_cells()) {
if (cell->type == ID($add)) { if (cell->type == TW($add)) {
Cell* add = cell; Cell* add = cell;
log_assert(add->getPort(TW::B).is_wire()); log_assert(add->getPort(TW::B).is_wire());
log_assert(add->getPort(TW::B).known_driver()); log_assert(add->getPort(TW::B).known_driver());
auto neg = add->getPort(TW::B)[0].wire->driverCell(); auto neg = add->getPort(TW::B)[0].wire->driverCell();
log_assert(neg->type == ID($not)); log_assert(neg->type == TW($not));
RTLIL::Patch patcher(module, nullptr); RTLIL::Patch patcher(module, nullptr);
int width = cell->getPort(TW::A).size(); int width = cell->getPort(TW::A).size();
auto sub = patcher.addSub(NEW_TWINE, auto sub = patcher.addSub(NEW_TWINE,

View File

@ -66,8 +66,8 @@ struct EstimateSta {
// and to account for the AIG model not being balanced // and to account for the AIG model not being balanced
int cell_type_factor(IdString type) int cell_type_factor(IdString type)
{ {
if (type.in(ID($gt), ID($ge), ID($lt), ID($le), ID($add), ID($sub), if (type.in(TW($gt), TW($ge), TW($lt), TW($le), TW($add), TW($sub),
ID($logic_not), ID($reduce_and), ID($reduce_or), ID($eq))) TW($logic_not), TW($reduce_and), TW($reduce_or), TW($eq)))
return 1; return 1;
else else
return 2; return 2;
@ -97,7 +97,7 @@ struct EstimateSta {
FfData ff(nullptr, cell); FfData ff(nullptr, cell);
if (!ff.has_clk) { if (!ff.has_clk) {
log_warning("Ignoring unsupported storage element '%s' (%s)\n", log_warning("Ignoring unsupported storage element '%s' (%s)\n",
cell, cell->type.unescape()); cell, cell->type.unescaped());
continue; continue;
} }
if (!clk || ff.sig_clk.as_bit() != *clk) if (!clk || ff.sig_clk.as_bit() != *clk)
@ -112,7 +112,7 @@ struct EstimateSta {
} else if (cell->is_mem_cell()) { } else if (cell->is_mem_cell()) {
// memories handled separately // memories handled separately
continue; continue;
} else if (cell->type == ID($scopeinfo)) { } else if (cell->type == TW($scopeinfo)) {
continue; continue;
} else { } else {
// find or build AIG model of combinational cell // find or build AIG model of combinational cell
@ -121,7 +121,7 @@ struct EstimateSta {
aigs.emplace(fingerprint, Aig(cell)); aigs.emplace(fingerprint, Aig(cell));
if (aigs.at(fingerprint).name.empty()) { if (aigs.at(fingerprint).name.empty()) {
log_error("Unsupported cell '%s' in module '%s'", log_error("Unsupported cell '%s' in module '%s'",
cell->type.unescape(), m); cell->type.unescaped(), m);
} }
} }
@ -342,7 +342,7 @@ struct EstimateSta {
std::string src_attr = cell->get_src_attribute(); std::string src_attr = cell->get_src_attribute();
cell_src = stringf(" source: %s", src_attr); cell_src = stringf(" source: %s", src_attr);
} }
log(" cell %s (%s)%s\n", cell, cell->type.unescape(), cell_src); log(" cell %s (%s)%s\n", cell, cell->type.unescaped(), cell_src);
printed.insert(cell); printed.insert(cell);
} }
} else { } else {

View File

@ -83,13 +83,13 @@ struct TorderPass : public Pass {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
for (auto conn : cell->connections()) for (auto conn : cell->connections())
{ {
if (stop_db.count(cell->type) && stop_db.at(cell->type).count(conn.first)) if (stop_db.count(RTLIL::IdString(cell->type)) && stop_db.at(RTLIL::IdString(cell->type)).count(RTLIL::IdString(design->twines.str(conn.first))))
continue; continue;
if (!noautostop && yosys_celltypes.cell_known(cell->type)) { if (!noautostop && yosys_celltypes.cell_known(cell->type.ref())) {
if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
continue; continue;
if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA) if (cell->type.in(TW($memrd), TW($memrd_v2)) && conn.first == ID::DATA)
continue; continue;
} }

View File

@ -38,7 +38,7 @@ struct TraceMonitor : public RTLIL::Monitor
void notify_connect(RTLIL::Cell *cell, TwineRef port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override void notify_connect(RTLIL::Cell *cell, TwineRef port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override
{ {
log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", cell->module, cell, port.unescape(), log_signal(sig), log_signal(old_sig)); log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", cell->module, cell, cell->module->design->twines.unescaped_str(port).c_str(), log_signal(sig), log_signal(old_sig));
} }
void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override

View File

@ -309,12 +309,12 @@ struct Graph {
{ {
GraphNode *g = nullptr; GraphNode *g = nullptr;
if (!grp.second.selected_module(module->name)) if (!grp.second.selected_module(module->meta_->name))
continue; continue;
for (auto wire : module->wires()) { for (auto wire : module->wires()) {
if (!wire->name.isPublic()) continue; if (!wire->name.isPublic()) continue;
if (!grp.second.selected_member(module->name, wire->name)) continue; if (!grp.second.selected_member(module->meta_->name, wire->name.ref())) continue;
for (auto bit : sigmap(wire)) { for (auto bit : sigmap(wire)) {
auto it = wire_nodes.find(bit); auto it = wire_nodes.find(bit);
if (it == wire_nodes.end()) if (it == wire_nodes.end())
@ -708,8 +708,8 @@ struct VizWorker
c->attributes.erase(vg_id); c->attributes.erase(vg_id);
for (auto g : graph.nodes) { for (auto g : graph.nodes) {
for (auto name : g->names()) { for (auto name : g->names()) {
auto w = module->wire(name); auto w = module->wire(module->design->twines.lookup(name.str()));
auto c = module->cell(name); auto c = module->cell(module->design->twines.lookup(name.str()));
if (w) w->attributes[vg_id] = g->index; if (w) w->attributes[vg_id] = g->index;
if (c) c->attributes[vg_id] = g->index; if (c) c->attributes[vg_id] = g->index;
} }
@ -718,7 +718,7 @@ struct VizWorker
void write_dot(FILE *f) void write_dot(FILE *f)
{ {
fprintf(f, "digraph \"%s\" {\n", module->name.unescape().c_str()); fprintf(f, "digraph \"%s\" {\n", design->twines.unescaped_str(module->name).c_str());
fprintf(f, " rankdir = LR;\n"); fprintf(f, " rankdir = LR;\n");
dict<GraphNode*, std::vector<std::vector<std::string>>> extra_lines; dict<GraphNode*, std::vector<std::vector<std::string>>> extra_lines;
@ -782,7 +782,7 @@ struct VizWorker
g->names().sort(); g->names().sort();
std::string label; // = stringf("vg=%d\\n", g->index); std::string label; // = stringf("vg=%d\\n", g->index);
for (auto n : g->names()) for (auto n : g->names())
label = label + (label.empty() ? "" : "\\n") + n.unescape(); label = label + (label.empty() ? "" : "\\n") + design->twines.unescaped_str(n);
fprintf(f, "\tn%d [shape=rectangle,label=\"%s\"];\n", g->index, label.c_str()); fprintf(f, "\tn%d [shape=rectangle,label=\"%s\"];\n", g->index, label.c_str());
} else { } else {
std::string label = stringf("vg=%d | %d cells", g->index, GetSize(g->names())); std::string label = stringf("vg=%d | %d cells", g->index, GetSize(g->names()));

View File

@ -208,13 +208,13 @@ struct WrapcellPass : Pass {
Module *subm; Module *subm;
Cell *subcell; Cell *subcell;
if (!ct.cell_known(cell->type)) if (!ct.cell_known(cell->type_impl))
log_error("Non-internal cell type '%s' on cell '%s' in module '%s' unsupported\n", log_error("Non-internal cell type '%s' on cell '%s' in module '%s' unsupported\n",
cell->type.unescape(), cell, module); cell->type.unescaped(), cell, module);
std::vector<std::pair<IdString, int>> unused_outputs, used_outputs; std::vector<std::pair<IdString, int>> unused_outputs, used_outputs;
for (auto conn : cell->connections()) { for (auto conn : cell->connections()) {
if (ct.cell_output(cell->type, conn.first)) if (ct.cell_output(cell->type_impl, conn.first))
for (int i = 0; i < conn.second.size(); i++) { for (int i = 0; i < conn.second.size(); i++) {
if (tracking_unused && unused.check(conn.second[i])) if (tracking_unused && unused.check(conn.second[i]))
unused_outputs.emplace_back(conn.first, i); unused_outputs.emplace_back(conn.first, i);
@ -227,7 +227,7 @@ struct WrapcellPass : Pass {
if (!unused_outputs.empty()) { if (!unused_outputs.empty()) {
context.unused_outputs += "_unused"; context.unused_outputs += "_unused";
for (auto chunk : collect_chunks(unused_outputs)) for (auto chunk : collect_chunks(unused_outputs))
context.unused_outputs += "_" + chunk.format(cell).unescape(); context.unused_outputs += "_" + design->twines.unescaped_str(chunk.format(cell));
} }
std::optional<std::string> unescaped_name = format_with_params(name_fmt, cell->parameters, context); std::optional<std::string> unescaped_name = format_with_params(name_fmt, cell->parameters, context);
@ -242,7 +242,7 @@ struct WrapcellPass : Pass {
subm = d->addModule(name); subm = d->addModule(name);
subcell = subm->addCell("$1", cell->type); subcell = subm->addCell("$1", cell->type);
for (auto conn : cell->connections()) { for (auto conn : cell->connections()) {
if (ct.cell_output(cell->type, conn.first)) { if (ct.cell_output(cell->type_impl, conn.first)) {
// Insert marker bits as placehodlers which need to be replaced // Insert marker bits as placehodlers which need to be replaced
subcell->setPort(conn.first, SigSpec(RTLIL::Sm, conn.second.size())); subcell->setPort(conn.first, SigSpec(RTLIL::Sm, conn.second.size()));
} else { } else {
@ -286,7 +286,7 @@ struct WrapcellPass : Pass {
dict<IdString, SigSpec> new_connections; dict<IdString, SigSpec> new_connections;
for (auto conn : cell->connections()) for (auto conn : cell->connections())
if (!ct.cell_output(cell->type, conn.first)) if (!ct.cell_output(cell->type_impl, conn.first))
new_connections[conn.first] = conn.second; new_connections[conn.first] = conn.second;
for (auto chunk : collect_chunks(used_outputs)) for (auto chunk : collect_chunks(used_outputs))

View File

@ -294,18 +294,18 @@ struct XpropWorker
} }
void mark_maybe_x(Cell *cell) { void mark_maybe_x(Cell *cell) {
if (cell->type.in(ID($bweqx), ID($eqx), ID($nex), ID($initstate), ID($assert), ID($assume), ID($cover), ID($anyseq), ID($anyconst))) if (cell->type.in(TW($bweqx), TW($eqx), TW($nex), TW($initstate), TW($assert), TW($assume), TW($cover), TW($anyseq), TW($anyconst)))
return; return;
if (cell->type.in(ID($pmux))) { if (cell->type.in(TW($pmux))) {
mark_outputs_maybe_x(cell); mark_outputs_maybe_x(cell);
return; return;
} }
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
FfData ff(&initvals, cell); FfData ff(&initvals, cell);
if (cell->type != ID($anyinit)) if (cell->type != TW($anyinit))
for (int i = 0; i < ff.width; i++) for (int i = 0; i < ff.width; i++)
if (ff.val_init[i] == State::Sx) if (ff.val_init[i] == State::Sx)
mark_maybe_x(ff.sig_q[i]); mark_maybe_x(ff.sig_q[i]);
@ -318,7 +318,7 @@ struct XpropWorker
return; return;
} }
if (cell->type == ID($not)) { if (cell->type == TW($not)) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); auto sig_a = cell->getPort(TW::A); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
for (int i = 0; i < GetSize(sig_y); i++) for (int i = 0; i < GetSize(sig_y); i++)
@ -327,7 +327,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { if (cell->type.in(TW($and), TW($or), TW($xor), TW($xnor))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); auto sig_a = cell->getPort(TW::A); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
auto sig_b = cell->getPort(TW::B); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); auto sig_b = cell->getPort(TW::B); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
@ -337,7 +337,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($bwmux))) { if (cell->type.in(TW($bwmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -348,7 +348,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($_MUX_), ID($mux), ID($bmux))) { if (cell->type.in(TW($_MUX_), TW($mux), TW($bmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -372,7 +372,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($demux))) { if (cell->type.in(TW($demux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_s = cell->getPort(TW::S); auto &sig_s = cell->getPort(TW::S);
@ -387,7 +387,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift))) { if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift))) {
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
@ -407,7 +407,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($shiftx))) { if (cell->type.in(TW($shiftx))) {
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
@ -438,24 +438,24 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($neg))) { if (cell->type.in(TW($add), TW($sub), TW($mul), TW($neg))) {
if (inputs_maybe_x(cell)) if (inputs_maybe_x(cell))
mark_outputs_maybe_x(cell); mark_outputs_maybe_x(cell);
return; return;
} }
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
mark_outputs_maybe_x(cell); mark_outputs_maybe_x(cell);
return; return;
} }
if (cell->type.in( if (cell->type.in(
ID($le), ID($lt), ID($ge), ID($gt), TW($le), TW($lt), TW($ge), TW($gt),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor),
ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and), TW($reduce_bool), TW($logic_not), TW($logic_or), TW($logic_and),
ID($eq), ID($ne), TW($eq), TW($ne),
ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_ANDNOT_), ID($_OR_), ID($_NOR_), ID($_ORNOT_), ID($_XOR_), ID($_XNOR_) TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_ANDNOT_), TW($_OR_), TW($_NOR_), TW($_ORNOT_), TW($_XOR_), TW($_XNOR_)
)) { )) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
if (inputs_maybe_x(cell)) if (inputs_maybe_x(cell))
@ -463,11 +463,11 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($scopeinfo))) { if (cell->type.in(TW($scopeinfo))) {
return; return;
} }
log_warning("Unhandled cell %s (%s) during maybe-x marking\n", cell, cell->type.unescape()); log_warning("Unhandled cell %s (%s) during maybe-x marking\n", cell, cell->type.unescaped());
mark_outputs_maybe_x(cell); mark_outputs_maybe_x(cell);
} }
@ -481,7 +481,7 @@ struct XpropWorker
{ {
if (!ports_maybe_x(cell)) { if (!ports_maybe_x(cell)) {
if (cell->type == ID($bweq)) { if (cell->type == TW($bweq)) {
auto sig_y = cell->getPort(TW::Y); auto sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -492,7 +492,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($nex), ID($eqx))) { if (cell->type.in(TW($nex), TW($eqx))) {
auto sig_y = cell->getPort(TW::Y); auto sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -500,7 +500,7 @@ struct XpropWorker
RTLIL::IdString name(cell->name); RTLIL::IdString name(cell->name);
auto type = cell->type; auto type = cell->type;
module->remove(cell); module->remove(cell);
if (type == ID($eqx)) if (type == TW($eqx))
module->addEq(name, sig_a, sig_b, sig_y); module->addEq(name, sig_a, sig_b, sig_y);
else else
module->addNe(name, sig_a, sig_b, sig_y); module->addNe(name, sig_a, sig_b, sig_y);
@ -510,10 +510,10 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($not), ID($_NOT_))) { if (cell->type.in(TW($not), TW($_NOT_))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
if (cell->type == ID($not)) if (cell->type == TW($not))
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
auto enc_a = encoded(sig_a); auto enc_a = encoded(sig_a);
@ -527,11 +527,11 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($and), ID($or), ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_))) { if (cell->type.in(TW($and), TW($or), TW($_AND_), TW($_OR_), TW($_NAND_), TW($_NOR_), TW($_ANDNOT_), TW($_ORNOT_))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($and), ID($or))) { if (cell->type.in(TW($and), TW($or))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
} }
@ -540,11 +540,11 @@ struct XpropWorker
auto enc_b = encoded(sig_b); auto enc_b = encoded(sig_b);
auto enc_y = encoded(sig_y, true); auto enc_y = encoded(sig_y, true);
if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) if (cell->type.in(TW($or), TW($_OR_), TW($_NOR_), TW($_ORNOT_)))
enc_a.invert(), enc_b.invert(), enc_y.invert(); enc_a.invert(), enc_b.invert(), enc_y.invert();
if (cell->type.in(ID($_NAND_), ID($_NOR_))) if (cell->type.in(TW($_NAND_), TW($_NOR_)))
enc_y.invert(); enc_y.invert();
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
enc_b.invert(); enc_b.invert();
enc_y.connect_0(module->Or(NEW_TWINE, enc_a.is_0, enc_b.is_0)); enc_y.connect_0(module->Or(NEW_TWINE, enc_a.is_0, enc_b.is_0));
@ -554,7 +554,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($logic_not))) { if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_bool), TW($logic_not))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
@ -563,9 +563,9 @@ struct XpropWorker
enc_y.connect_as_bool(); enc_y.connect_as_bool();
if (cell->type.in(ID($reduce_or), ID($reduce_bool))) if (cell->type.in(TW($reduce_or), TW($reduce_bool)))
enc_a.invert(), enc_y.invert(); enc_a.invert(), enc_y.invert();
if (cell->type == ID($logic_not)) if (cell->type == TW($logic_not))
enc_a.invert(); enc_a.invert();
enc_y.connect_0(module->ReduceOr(NEW_TWINE, enc_a.is_0)); enc_y.connect_0(module->ReduceOr(NEW_TWINE, enc_a.is_0));
@ -576,7 +576,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { if (cell->type.in(TW($reduce_xor), TW($reduce_xnor))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
@ -584,7 +584,7 @@ struct XpropWorker
auto enc_y = encoded(sig_y, true); auto enc_y = encoded(sig_y, true);
enc_y.connect_as_bool(); enc_y.connect_as_bool();
if (cell->type == ID($reduce_xnor)) if (cell->type == TW($reduce_xnor))
enc_y.invert(); enc_y.invert();
@ -596,7 +596,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($logic_and), ID($logic_or))) { if (cell->type.in(TW($logic_and), TW($logic_or))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -612,7 +612,7 @@ struct XpropWorker
auto b_is_1 = module->ReduceOr(NEW_TWINE, enc_b.is_1); auto b_is_1 = module->ReduceOr(NEW_TWINE, enc_b.is_1);
auto b_is_0 = module->ReduceAnd(NEW_TWINE, enc_b.is_0); auto b_is_0 = module->ReduceAnd(NEW_TWINE, enc_b.is_0);
if (cell->type == ID($logic_or)) if (cell->type == TW($logic_or))
enc_y.invert(), std::swap(a_is_0, a_is_1), std::swap(b_is_0, b_is_1); enc_y.invert(), std::swap(a_is_0, a_is_1), std::swap(b_is_0, b_is_1);
enc_y.connect_0(module->Or(NEW_TWINE, a_is_0, b_is_0)); enc_y.connect_0(module->Or(NEW_TWINE, a_is_0, b_is_0));
@ -622,11 +622,11 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) { if (cell->type.in(TW($xor), TW($xnor), TW($_XOR_), TW($_XNOR_))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($xor), ID($xnor))) { if (cell->type.in(TW($xor), TW($xnor))) {
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
} }
@ -635,7 +635,7 @@ struct XpropWorker
auto enc_b = encoded(sig_b); auto enc_b = encoded(sig_b);
auto enc_y = encoded(sig_y, true); auto enc_y = encoded(sig_y, true);
if (cell->type.in(ID($xnor), ID($_XNOR_))) if (cell->type.in(TW($xnor), TW($_XNOR_)))
enc_y.invert(); enc_y.invert();
enc_y.connect_x(module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x)); enc_y.connect_x(module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x));
@ -645,7 +645,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($eq), ID($ne))) { if (cell->type.in(TW($eq), TW($ne))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -658,7 +658,7 @@ struct XpropWorker
auto enc_y = encoded(sig_y, true); auto enc_y = encoded(sig_y, true);
enc_y.connect_as_bool(); enc_y.connect_as_bool();
if (cell->type == ID($ne)) if (cell->type == TW($ne))
enc_y.invert(); enc_y.invert();
auto delta = module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1); auto delta = module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1);
@ -671,7 +671,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($eqx), ID($nex))) { if (cell->type.in(TW($eqx), TW($nex))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto sig_a = cell->getPort(TW::A); auto sig_a = cell->getPort(TW::A);
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
@ -687,7 +687,7 @@ struct XpropWorker
auto eq = module->ReduceAnd(NEW_TWINE, {delta_0, delta_1}); auto eq = module->ReduceAnd(NEW_TWINE, {delta_0, delta_1});
auto res = cell->type == ID($nex) ? module->Not(NEW_TWINE, eq) : eq; auto res = cell->type == TW($nex) ? module->Not(NEW_TWINE, eq) : eq;
module->connect(sig_y[0], res); module->connect(sig_y[0], res);
if (GetSize(sig_y) > 1) if (GetSize(sig_y) > 1)
@ -696,7 +696,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($bweqx))) { if (cell->type.in(TW($bweqx))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -711,13 +711,13 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($_MUX_), ID($mux), ID($bwmux))) { if (cell->type.in(TW($_MUX_), TW($mux), TW($bwmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
auto sig_s = cell->getPort(TW::S); auto sig_s = cell->getPort(TW::S);
if (cell->type == ID($mux)) if (cell->type == TW($mux))
sig_s = SigSpec(sig_s[0], GetSize(sig_y)); sig_s = SigSpec(sig_s[0], GetSize(sig_y));
auto enc_a = encoded(sig_a); auto enc_a = encoded(sig_a);
@ -736,7 +736,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($pmux))) { if (cell->type.in(TW($pmux))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -771,7 +771,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx))) {
auto &sig_y = cell->getPort(TW::Y); auto &sig_y = cell->getPort(TW::Y);
auto &sig_a = cell->getPort(TW::A); auto &sig_a = cell->getPort(TW::A);
auto &sig_b = cell->getPort(TW::B); auto &sig_b = cell->getPort(TW::B);
@ -787,9 +787,9 @@ struct XpropWorker
SigSpec y_1 = module->addWire(NEW_TWINE, GetSize(sig_y)); SigSpec y_1 = module->addWire(NEW_TWINE, GetSize(sig_y));
SigSpec y_x = module->addWire(NEW_TWINE, GetSize(sig_y)); SigSpec y_x = module->addWire(NEW_TWINE, GetSize(sig_y));
auto encoded_type = cell->type == ID($shiftx) ? ID($shift) : cell->type; auto encoded_type = cell->type == TW($shiftx) ? TW($shift) : cell->type;
if (cell->type == ID($shiftx)) { if (cell->type == TW($shiftx)) {
std::swap(enc_a.is_0, enc_a.is_x); std::swap(enc_a.is_0, enc_a.is_x);
} }
@ -813,7 +813,7 @@ struct XpropWorker
SigSpec y_0 = module->Not(NEW_TWINE, y_not_0); SigSpec y_0 = module->Not(NEW_TWINE, y_not_0);
if (cell->type == ID($shiftx)) if (cell->type == TW($shiftx))
std::swap(y_0, y_x); std::swap(y_0, y_x);
enc_y.connect_0(module->And(NEW_TWINE, y_0, SigSpec(not_all_x, GetSize(sig_y)))); enc_y.connect_0(module->And(NEW_TWINE, y_0, SigSpec(not_all_x, GetSize(sig_y))));
@ -824,7 +824,7 @@ struct XpropWorker
return; return;
} }
if (cell->type.in(ID($ff))) { if (cell->type.in(TW($ff))) {
auto &sig_d = cell->getPort(TW::D); auto &sig_d = cell->getPort(TW::D);
auto &sig_q = cell->getPort(TW::Q); auto &sig_q = cell->getPort(TW::Q);
@ -857,12 +857,12 @@ struct XpropWorker
return; return;
} }
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) { if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
FfData ff(&initvals, cell); FfData ff(&initvals, cell);
if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) {
if (ff.has_clk && maybe_x(ff.sig_clk)) { if (ff.has_clk && maybe_x(ff.sig_clk)) {
log_warning("Only non-x CLK inputs are currently supported for %s (%s)\n", cell, cell->type.unescape()); log_warning("Only non-x CLK inputs are currently supported for %s (%s)\n", cell, cell->type.unescaped());
} else { } else {
auto init_q = ff.val_init; auto init_q = ff.val_init;
auto init_q_is_1 = init_q; auto init_q_is_1 = init_q;
@ -907,15 +907,15 @@ struct XpropWorker
return; return;
} }
} else { } else {
log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type.unescape()); log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type.unescaped());
} }
} }
// Celltypes where any input x bit makes the whole output x // Celltypes where any input x bit makes the whole output x
if (cell->type.in( if (cell->type.in(
ID($neg), TW($neg),
ID($le), ID($lt), ID($ge), ID($gt), TW($le), TW($lt), TW($ge), TW($gt),
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor) TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor)
)) { )) {
SigSpec inbits_x; SigSpec inbits_x;
@ -927,7 +927,7 @@ struct XpropWorker
} }
} }
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
auto sig_b = cell->getPort(TW::B); auto sig_b = cell->getPort(TW::B);
auto invalid = module->LogicNot(NEW_TWINE, sig_b); auto invalid = module->LogicNot(NEW_TWINE, sig_b);
inbits_x.append(invalid); inbits_x.append(invalid);
@ -937,7 +937,7 @@ struct XpropWorker
SigBit outbits_x = (GetSize(inbits_x) == 1 ? inbits_x : module->ReduceOr(NEW_TWINE, inbits_x)); SigBit outbits_x = (GetSize(inbits_x) == 1 ? inbits_x : module->ReduceOr(NEW_TWINE, inbits_x));
bool bool_out = cell->type.in(ID($le), ID($lt), ID($ge), ID($gt)); bool bool_out = cell->type.in(TW($le), TW($lt), TW($ge), TW($gt));
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
if (cell->output(conn.first)) { if (cell->output(conn.first)) {
@ -958,15 +958,15 @@ struct XpropWorker
return; return;
} }
if (cell->type == ID($bmux)) // TODO might want to support bmux natively anyway if (cell->type == TW($bmux)) // TODO might want to support bmux natively anyway
log("Running 'bmuxmap' preserves x-propagation and can be run before 'xprop'.\n"); log("Running 'bmuxmap' preserves x-propagation and can be run before 'xprop'.\n");
if (cell->type == ID($demux)) // TODO might want to support demux natively anyway if (cell->type == TW($demux)) // TODO might want to support demux natively anyway
log("Running 'demuxmap' preserves x-propagation and can be run before 'xprop'.\n"); log("Running 'demuxmap' preserves x-propagation and can be run before 'xprop'.\n");
if (options.required) if (options.required)
log_error("Unhandled cell %s (%s)\n", cell, cell->type.unescape()); log_error("Unhandled cell %s (%s)\n", cell, cell->type.unescaped());
else else
log_warning("Unhandled cell %s (%s)\n", cell, cell->type.unescape()); log_warning("Unhandled cell %s (%s)\n", cell, cell->type.unescaped());
} }
void split_ports() void split_ports()

View File

@ -47,7 +47,7 @@ struct EquivInductWorker : public EquivWorker<>
if (!satgen.importCell(cell, step)) { if (!satgen.importCell(cell, step)) {
report_missing_model(cfg.ignore_unknown_cells, cell); report_missing_model(cfg.ignore_unknown_cells, cell);
} }
if (cell->type == ID($equiv)) { if (cell->type == TW($equiv)) {
SigBit bit_a = sigmap(cell->getPort(TW::A)).as_bit(); SigBit bit_a = sigmap(cell->getPort(TW::A)).as_bit();
SigBit bit_b = sigmap(cell->getPort(TW::B)).as_bit(); SigBit bit_b = sigmap(cell->getPort(TW::B)).as_bit();
if (bit_a != bit_b) { if (bit_a != bit_b) {
@ -88,14 +88,14 @@ struct EquivInductWorker : public EquivWorker<>
if (satgen.model_undef) { if (satgen.model_undef) {
for (auto cell : cells) for (auto cell : cells)
if (yosys_celltypes.cell_known(cell->type)) if (yosys_celltypes.cell_known(cell->type_impl))
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (yosys_celltypes.cell_input(cell->type, conn.first)) if (yosys_celltypes.cell_input(cell->type_impl, conn.first))
undriven_signals.add(sigmap(conn.second)); undriven_signals.add(sigmap(conn.second));
for (auto cell : cells) for (auto cell : cells)
if (yosys_celltypes.cell_known(cell->type)) if (yosys_celltypes.cell_known(cell->type_impl))
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (yosys_celltypes.cell_output(cell->type, conn.first)) if (yosys_celltypes.cell_output(cell->type_impl, conn.first))
undriven_signals.del(sigmap(conn.second)); undriven_signals.del(sigmap(conn.second));
} }
@ -211,7 +211,7 @@ struct EquivInductPass : public Pass {
vector<Cell*> assume_cells; vector<Cell*> assume_cells;
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
if (cell->type == ID($equiv)) { if (cell->type == TW($equiv)) {
if (cell->getPort(TW::A) != cell->getPort(TW::B)) if (cell->getPort(TW::A) != cell->getPort(TW::B))
unproven_equiv_cells.insert(cell); unproven_equiv_cells.insert(cell);
} }

View File

@ -115,7 +115,7 @@ struct EquivMakeWorker
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
cell_names.insert(it->name); cell_names.insert(it->name);
gold_clone->rename(it, gold_clone->design->twines.add(Twine{it->name.str() + "_gold"})); gold_clone->rename(it, gold_clone->design->twines.add(Twine{it->name.str() + "_gold"}));
if (it->type.in(ID($input_port), ID($output_port), ID($public))) if (it->type.in(TW($input_port), TW($output_port), TW($public)))
gold_clone->remove(it); gold_clone->remove(it);
} }
@ -129,7 +129,7 @@ struct EquivMakeWorker
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
cell_names.insert(it->name); cell_names.insert(it->name);
gate_clone->rename(it, gate_clone->design->twines.add(Twine{it->name.str() + "_gate"})); gate_clone->rename(it, gate_clone->design->twines.add(Twine{it->name.str() + "_gate"}));
if (it->type.in(ID($input_port), ID($output_port), ID($public))) if (it->type.in(TW($input_port), TW($output_port), TW($public)))
gate_clone->remove(it); gate_clone->remove(it);
} }
@ -164,7 +164,7 @@ struct EquivMakeWorker
if (encdata.count(id)) if (encdata.count(id))
{ {
log("Creating encoder/decoder for signal %s.\n", id.unescape()); log("Creating encoder/decoder for signal %s.\n", design->twines.unescaped_str(id));
Wire *dec_wire = equiv_mod->addWire(Twine{id.str() + "_decoded"}, gold_wire->width); Wire *dec_wire = equiv_mod->addWire(Twine{id.str() + "_decoded"}, gold_wire->width);
Wire *enc_wire = equiv_mod->addWire(Twine{id.str() + "_encoded"}, gate_wire->width); Wire *enc_wire = equiv_mod->addWire(Twine{id.str() + "_encoded"}, gate_wire->width);
@ -239,7 +239,7 @@ struct EquivMakeWorker
log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n", log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n",
gold_wire, log_signal(assign_map(gold_wire)), gold_wire, log_signal(assign_map(gold_wire)),
gate_wire, log_signal(assign_map(gate_wire)), id.unescape()); gate_wire, log_signal(assign_map(gate_wire)), design->twines.unescaped_str(id));
if (gold_wire->port_output || gate_wire->port_output) if (gold_wire->port_output || gate_wire->port_output)
{ {
@ -310,7 +310,7 @@ struct EquivMakeWorker
for (auto c : cells_list) for (auto c : cells_list)
for (auto &conn : c->connections()) for (auto &conn : c->connections())
if (!ct.cell_output(c->type, conn.first)) { if (!ct.cell_output(c->type_impl, conn.first)) {
SigSpec old_sig = assign_map(conn.second); SigSpec old_sig = assign_map(conn.second);
SigSpec new_sig = rd_signal_map(old_sig); SigSpec new_sig = rd_signal_map(old_sig);
for (int i = 0; i < GetSize(old_sig); i++) for (int i = 0; i < GetSize(old_sig); i++)
@ -318,7 +318,7 @@ struct EquivMakeWorker
new_sig[i] = old_sig[i]; new_sig[i] = old_sig[i];
if (old_sig != new_sig) { if (old_sig != new_sig) {
log("Changing input %s of cell %s (%s): %s -> %s\n", log("Changing input %s of cell %s (%s): %s -> %s\n",
equiv_mod->design->twines.str(conn.first).c_str(), c, c->type.unescape(), equiv_mod->design->twines.str(conn.first).c_str(), c, design->twines.unescaped_str(c->type),
log_signal(old_sig), log_signal(new_sig)); log_signal(old_sig), log_signal(new_sig));
c->setPort(conn.first, new_sig); c->setPort(conn.first, new_sig);
} }
@ -339,7 +339,7 @@ struct EquivMakeWorker
Cell *gold_cell = equiv_mod->cell(gold_id); Cell *gold_cell = equiv_mod->cell(gold_id);
Cell *gate_cell = equiv_mod->cell(gate_id); Cell *gate_cell = equiv_mod->cell(gate_id);
if (gold_cell == nullptr || gate_cell == nullptr || gold_cell->type != gate_cell->type || !ct.cell_known(gold_cell->type) || if (gold_cell == nullptr || gate_cell == nullptr || gold_cell->type != gate_cell->type || !ct.cell_known(gold_cell->type_impl) ||
gold_cell->parameters != gate_cell->parameters || GetSize(gold_cell->connections()) != GetSize(gate_cell->connections())) gold_cell->parameters != gate_cell->parameters || GetSize(gold_cell->connections()) != GetSize(gate_cell->connections()))
try_next_cell_name: try_next_cell_name:
continue; continue;
@ -349,14 +349,14 @@ struct EquivMakeWorker
goto try_next_cell_name; goto try_next_cell_name;
log("Presumably equivalent cells: %s %s (%s) -> %s\n", log("Presumably equivalent cells: %s %s (%s) -> %s\n",
gold_cell, gate_cell, gold_cell->type.unescape(), id.unescape()); gold_cell, gate_cell, design->twines.unescaped_str(gold_cell->type), design->twines.unescaped_str(id));
for (auto gold_conn : gold_cell->connections()) for (auto gold_conn : gold_cell->connections())
{ {
SigSpec gold_sig = assign_map(gold_conn.second); SigSpec gold_sig = assign_map(gold_conn.second);
SigSpec gate_sig = assign_map(gate_cell->getPort(gold_conn.first)); SigSpec gate_sig = assign_map(gate_cell->getPort(gold_conn.first));
if (ct.cell_output(gold_cell->type, gold_conn.first)) { if (ct.cell_output(gold_cell->type_impl, gold_conn.first)) {
equiv_mod->connect(gate_sig, gold_sig); equiv_mod->connect(gate_sig, gold_sig);
continue; continue;
} }
@ -403,7 +403,7 @@ struct EquivMakeWorker
for (auto cell : equiv_mod->cells()) { for (auto cell : equiv_mod->cells()) {
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) if (!ct.cell_known(cell->type_impl) || ct.cell_output(cell->type_impl, conn.first))
for (auto bit : assign_map(conn.second)) for (auto bit : assign_map(conn.second))
undriven_bits.erase(bit); undriven_bits.erase(bit);
} }

View File

@ -48,7 +48,7 @@ struct EquivMarkWorker
{ {
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type == ID($equiv)) if (cell->type == TW($equiv))
equiv_cells.insert(cell->meta_->name); equiv_cells.insert(cell->meta_->name);
for (auto &port : cell->connections()) for (auto &port : cell->connections())
@ -139,7 +139,7 @@ struct EquivMarkWorker
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell_regions.count(cell->meta_->name) || cell->type != ID($equiv)) if (cell_regions.count(cell->meta_->name) || cell->type != TW($equiv))
continue; continue;
SigSpec sig_a = sigmap(cell->getPort(TW::A)); SigSpec sig_a = sigmap(cell->getPort(TW::A));

Some files were not shown because too many files have changed in this diff Show More