mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
afdae7b87e
commit
c3ffbf6fae
229 changed files with 3902 additions and 3835 deletions
3
Makefile
3
Makefile
|
|
@ -672,7 +672,8 @@ OBJS += kernel/log_compat.o
|
|||
endif
|
||||
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/drivertools.o kernel/functional.o kernel/threading.o
|
||||
OBJS += kernel/drivertools.o kernel/threading.o
|
||||
# OBJS += kernel/functional.o
|
||||
ifeq ($(ENABLE_ZLIB),1)
|
||||
OBJS += kernel/fstdata.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ struct AigerWriter
|
|||
|
||||
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 Y = sigmap(cell->getPort(TW::Y).as_bit());
|
||||
|
|
@ -231,7 +231,7 @@ struct AigerWriter
|
|||
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 Q = sigmap(cell->getPort(TW::Q).as_bit());
|
||||
|
|
@ -239,14 +239,14 @@ struct AigerWriter
|
|||
undriven_bits.erase(Q);
|
||||
ff_map[Q] = D;
|
||||
|
||||
if (cell->type != ID($_FF_)) {
|
||||
if (cell->type != TW($_FF_)) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($anyinit))
|
||||
if (cell->type == TW($anyinit))
|
||||
{
|
||||
auto sig_d = sigmap(cell->getPort(TW::D));
|
||||
auto sig_q = sigmap(cell->getPort(TW::Q));
|
||||
|
|
@ -257,7 +257,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AND_))
|
||||
if (cell->type == TW($_AND_))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit B = sigmap(cell->getPort(TW::B).as_bit());
|
||||
|
|
@ -269,7 +269,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($initstate))
|
||||
if (cell->type == TW($initstate))
|
||||
{
|
||||
SigBit Y = sigmap(cell->getPort(TW::Y).as_bit());
|
||||
undriven_bits.erase(Y);
|
||||
|
|
@ -277,7 +277,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($assert))
|
||||
if (cell->type == TW($assert))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
|
||||
|
|
@ -288,7 +288,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($assume))
|
||||
if (cell->type == TW($assume))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
|
||||
|
|
@ -299,7 +299,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($live))
|
||||
if (cell->type == TW($live))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
|
||||
|
|
@ -309,7 +309,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($fair))
|
||||
if (cell->type == TW($fair))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit EN = sigmap(cell->getPort(TW::EN).as_bit());
|
||||
|
|
@ -319,7 +319,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($anyconst))
|
||||
if (cell->type == TW($anyconst))
|
||||
{
|
||||
for (auto bit : sigmap(cell->getPort(TW::Y))) {
|
||||
undriven_bits.erase(bit);
|
||||
|
|
@ -328,7 +328,7 @@ struct AigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($anyseq))
|
||||
if (cell->type == TW($anyseq))
|
||||
{
|
||||
for (auto bit : sigmap(cell->getPort(TW::Y))) {
|
||||
undriven_bits.erase(bit);
|
||||
|
|
@ -337,7 +337,7 @@ struct AigerWriter
|
|||
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;
|
||||
|
||||
log_error("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell);
|
||||
|
|
@ -773,10 +773,10 @@ struct AigerWriter
|
|||
|
||||
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
|
||||
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);
|
||||
|
||||
if (cell->get_bool_attribute(ID(clk2fflogic)))
|
||||
|
|
|
|||
|
|
@ -187,11 +187,11 @@ struct XAigerWriter
|
|||
TimingInfo timing;
|
||||
|
||||
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;
|
||||
|
||||
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 Y = sigmap(cell->getPort(TW::Y).as_bit());
|
||||
|
|
@ -201,7 +201,7 @@ struct XAigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AND_))
|
||||
if (cell->type == TW($_AND_))
|
||||
{
|
||||
SigBit A = sigmap(cell->getPort(TW::A).as_bit());
|
||||
SigBit B = sigmap(cell->getPort(TW::B).as_bit());
|
||||
|
|
@ -213,7 +213,7 @@ struct XAigerWriter
|
|||
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 Q = sigmap(cell->getPort(TW::Q).as_bit());
|
||||
|
|
@ -224,7 +224,7 @@ struct XAigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
|
||||
if (cell->type.in(TW($specify2), TW($specify3), TW($specrule)))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -248,12 +248,12 @@ struct XAigerWriter
|
|||
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))
|
||||
timing.setup_module(inst_module);
|
||||
|
||||
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))
|
||||
continue;
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ struct XAigerWriter
|
|||
if (ys_debug(1)) {
|
||||
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",
|
||||
cell->type.unescape(), i.first.name.unescape(), offset, d);
|
||||
cell->type.unescape(), design->twines.unescaped_str(i.first.name), offset, d);
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -32,21 +32,21 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
#define BITWISE_OPS ID($buf), ID($not), ID($mux), ID($and), ID($or), ID($xor), ID($xnor), ID($fa), \
|
||||
ID($bwmux)
|
||||
#define BITWISE_OPS TW($buf), TW($not), TW($mux), TW($and), TW($or), TW($xor), TW($xnor), TW($fa), \
|
||||
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_), \
|
||||
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), \
|
||||
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)
|
||||
#define GATE_OPS TW($_BUF_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), \
|
||||
TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_), TW($_MUX_), TW($_NMUX_), \
|
||||
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
|
||||
//#define ARITH_OPS ID($add), ID($sub), ID($neg)
|
||||
//#define ARITH_OPS TW($add), TW($sub), TW($neg)
|
||||
|
||||
static constexpr auto known_ops = []() constexpr {
|
||||
StaticCellTypes::Categories::Category c{};
|
||||
|
|
@ -60,7 +60,7 @@ static constexpr auto known_ops = []() constexpr {
|
|||
c.set_id(id);
|
||||
for (auto id : {CMP_OPS})
|
||||
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);
|
||||
return c;
|
||||
}();
|
||||
|
|
@ -109,7 +109,7 @@ struct Index {
|
|||
int pos = index_wires(info, m);
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
// (which can only really happen with $tribuf not
|
||||
// $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;
|
||||
if (!submodule || submodule->get_blackbox_attribute())
|
||||
log_error("Unsupported cell type: %s (%s in %s)\n",
|
||||
|
|
@ -292,18 +292,18 @@ struct Index {
|
|||
aport.extend_u0(width, asigned);
|
||||
bport.extend_u0(width, bsigned);
|
||||
|
||||
if (cell->type.in(ID($eq), ID($ne))) {
|
||||
if (cell->type.in(TW($eq), TW($ne))) {
|
||||
int carry = CTRUE;
|
||||
for (int i = 0; i < width; i++) {
|
||||
Lit a = visit(cursor, aport[i]);
|
||||
Lit b = visit(cursor, bport[i]);
|
||||
carry = AND(carry, XNOR(a, b));
|
||||
}
|
||||
return (cell->type == ID($eq)) ? carry : /* $ne */ NOT(carry);
|
||||
} else if (cell->type.in(ID($lt), ID($le), ID($gt), ID($ge))) {
|
||||
if (cell->type.in(ID($gt), ID($ge)))
|
||||
return (cell->type == TW($eq)) ? carry : /* $ne */ NOT(carry);
|
||||
} else if (cell->type.in(TW($lt), TW($le), TW($gt), TW($ge))) {
|
||||
if (cell->type.in(TW($gt), TW($ge)))
|
||||
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 b = Writer::EMPTY_LIT;
|
||||
// TODO: this might not be the most economic structure; revisit at a later date
|
||||
|
|
@ -317,28 +317,28 @@ struct Index {
|
|||
} else {
|
||||
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);
|
||||
|
||||
std::vector<Lit> lits;
|
||||
for (int i = 0; i < inport.size(); 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);
|
||||
} 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));
|
||||
} else {
|
||||
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;
|
||||
else
|
||||
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 bport = cell->getPort(TW::B);
|
||||
|
||||
|
|
@ -356,13 +356,13 @@ struct Index {
|
|||
b = OR(b, l);
|
||||
}
|
||||
|
||||
if (cell->type == ID($logic_and))
|
||||
if (cell->type == TW($logic_and))
|
||||
return AND(a, b);
|
||||
else if (cell->type == ID($logic_or))
|
||||
else if (cell->type == TW($logic_or))
|
||||
return OR(a, b);
|
||||
else
|
||||
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);
|
||||
Lit a;
|
||||
if (obit < aport.size()) {
|
||||
|
|
@ -374,9 +374,9 @@ struct Index {
|
|||
a = CFALSE;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($buf), ID($pos), ID($_BUF_))) {
|
||||
if (cell->type.in(TW($buf), TW($pos), TW($_BUF_))) {
|
||||
return a;
|
||||
} else if (cell->type.in(ID($not), ID($_NOT_))) {
|
||||
} else if (cell->type.in(TW($not), TW($_NOT_))) {
|
||||
return NOT(a);
|
||||
} else {
|
||||
SigSpec bport = cell->getPort(TW::B);
|
||||
|
|
@ -390,32 +390,32 @@ struct Index {
|
|||
b = CFALSE;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($and), ID($_AND_))) {
|
||||
if (cell->type.in(TW($and), TW($_AND_))) {
|
||||
return AND(a, b);
|
||||
} else if (cell->type.in(ID($_NAND_))) {
|
||||
} else if (cell->type.in(TW($_NAND_))) {
|
||||
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);
|
||||
} else if (cell->type.in(ID($_NOR_))) {
|
||||
} else if (cell->type.in(TW($_NOR_))) {
|
||||
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);
|
||||
} else if (cell->type.in(ID($xnor), ID($_XNOR_))) {
|
||||
} else if (cell->type.in(TW($xnor), TW($_XNOR_))) {
|
||||
return XNOR(a, b);
|
||||
} else if (cell->type.in(ID($_ANDNOT_))) {
|
||||
} else if (cell->type.in(TW($_ANDNOT_))) {
|
||||
return AND(a, NOT(b));
|
||||
} else if (cell->type.in(ID($_ORNOT_))) {
|
||||
} else if (cell->type.in(TW($_ORNOT_))) {
|
||||
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));
|
||||
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]);
|
||||
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]);
|
||||
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 ab = XOR(a, b);
|
||||
if (oport == TW::Y) {
|
||||
|
|
@ -425,16 +425,16 @@ struct Index {
|
|||
Lit c_and_ab = AND(c, 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;
|
||||
|
||||
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]);
|
||||
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 c_and_d = AND(c, d);
|
||||
return NOT(OR(a_and_b, c_and_d));
|
||||
|
|
@ -447,7 +447,7 @@ struct Index {
|
|||
log_abort();
|
||||
}
|
||||
}
|
||||
} else if (cell->type == ID($pmux)) {
|
||||
} else if (cell->type == TW($pmux)) {
|
||||
SigSpec aport = cell->getPort(TW::A);
|
||||
SigSpec bport = cell->getPort(TW::B);
|
||||
SigSpec sport = cell->getPort(TW::S);
|
||||
|
|
@ -468,7 +468,7 @@ struct Index {
|
|||
Lit reduce_bar = NOT(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 sport = cell->getPort(TW::S);
|
||||
int width = cell->getParam(ID::WIDTH).as_int();
|
||||
|
|
@ -537,7 +537,7 @@ struct Index {
|
|||
Design *design = index.design;
|
||||
auto &minfo = leaf_minfo(index);
|
||||
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);
|
||||
log_assert(def);
|
||||
levels.push_back(Level(index.modules.at(def), cell));
|
||||
|
|
@ -660,7 +660,7 @@ struct Index {
|
|||
auto &port = instance->getPort(portname);
|
||||
if (bit.offset >= port.size())
|
||||
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]);
|
||||
}
|
||||
cursor.enter(*this, instance);
|
||||
|
|
@ -845,7 +845,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
|
|||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "o%d ", i);
|
||||
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->put('\n');
|
||||
}
|
||||
|
|
@ -858,7 +858,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
|
|||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "i%d ", i);
|
||||
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->put('\n');
|
||||
}
|
||||
|
|
@ -1090,7 +1090,7 @@ struct XAigerWriter : AigerWriter {
|
|||
for (auto box : minfo.found_blackboxes) {
|
||||
log_debug(" - %s.%s (type %s): ", cursor.path(),
|
||||
box,
|
||||
box->type.unescape());
|
||||
design->twines.unescaped_str(box->type));
|
||||
|
||||
Module *box_module = design->module(box->type), *box_derived;
|
||||
|
||||
|
|
@ -1159,7 +1159,7 @@ struct XAigerWriter : AigerWriter {
|
|||
} else {
|
||||
// FIXME: hierarchical path
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1194,7 +1194,7 @@ struct XAigerWriter : AigerWriter {
|
|||
} else {
|
||||
// FIXME: hierarchical path
|
||||
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();
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1211,7 +1211,7 @@ struct XAigerWriter : AigerWriter {
|
|||
holes_wb->setPort(port_id, w);
|
||||
} else {
|
||||
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;
|
||||
if (known_ops(cell.type))
|
||||
continue;
|
||||
std::string name = cell.type.unescape();
|
||||
std::string name = design->twines.unescaped_str(cell.type);
|
||||
if (col + name.size() + 2 > 72) {
|
||||
log("\n ");
|
||||
col = 0;
|
||||
|
|
@ -1428,7 +1428,7 @@ struct Aiger2Backend : Backend {
|
|||
continue;
|
||||
if (known_ops(cell.type))
|
||||
continue;
|
||||
std::string name = cell.type.unescape();
|
||||
std::string name = design->twines.unescaped_str(cell.type);
|
||||
if (col + name.size() + 2 > 72) {
|
||||
log("\n ");
|
||||
col = 0;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct BlifDumper
|
|||
|
||||
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++)
|
||||
if (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";
|
||||
}
|
||||
|
||||
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++)
|
||||
if (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> ¶ms)
|
||||
{
|
||||
for (auto ¶m : 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) {
|
||||
std::string str = param.second.decode_string();
|
||||
f << stringf("\"");
|
||||
|
|
@ -232,7 +232,7 @@ struct BlifDumper
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
continue;
|
||||
|
||||
if (config->unbuf_types.count(cell->type)) {
|
||||
|
|
@ -244,131 +244,131 @@ struct BlifDumper
|
|||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
str(cell->getPort(TW::A)).c_str(), str(cell->getPort(TW::B)).c_str(), str(cell->getPort(TW::Y)).c_str());
|
||||
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",
|
||||
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;
|
||||
}
|
||||
|
||||
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",
|
||||
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;
|
||||
}
|
||||
|
||||
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",
|
||||
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());
|
||||
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",
|
||||
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());
|
||||
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",
|
||||
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());
|
||||
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",
|
||||
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());
|
||||
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)),
|
||||
str_init(cell->getPort(TW::Q)).c_str());
|
||||
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)),
|
||||
str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
|
||||
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)),
|
||||
str(cell->getPort(TW::C)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
|
||||
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)),
|
||||
str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
|
||||
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)),
|
||||
str(cell->getPort(TW::E)).c_str(), str_init(cell->getPort(TW::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($lut)) {
|
||||
if (!config->icells_mode && cell->type == TW($lut)) {
|
||||
f << stringf(".names");
|
||||
auto &inputs = cell->getPort(TW::A);
|
||||
auto width = cell->parameters.at(ID::WIDTH).as_int();
|
||||
|
|
@ -390,7 +390,7 @@ struct BlifDumper
|
|||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($sop)) {
|
||||
if (!config->icells_mode && cell->type == TW($sop)) {
|
||||
f << stringf(".names");
|
||||
auto &inputs = cell->getPort(TW::A);
|
||||
auto width = cell->parameters.at(ID::WIDTH).as_int();
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ struct BtorWorker
|
|||
template<typename T>
|
||||
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 (obj->has_attribute(ID::src)) {
|
||||
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 infostr = mem->memid.unescape();
|
||||
string infostr = design->twines.unescaped_str(mem->memid);
|
||||
if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
|
||||
if (mem->has_attribute(ID::src)) {
|
||||
string src = module && module->design ? module->design->get_src_attribute(mem) : std::string();
|
||||
|
|
@ -280,24 +280,24 @@ struct BtorWorker
|
|||
cell_recursion_guard.insert(cell);
|
||||
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),
|
||||
ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_)))
|
||||
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),
|
||||
TW($concat), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_)))
|
||||
{
|
||||
string btor_op;
|
||||
if (cell->type == ID($add)) btor_op = "add";
|
||||
if (cell->type == ID($sub)) btor_op = "sub";
|
||||
if (cell->type == ID($mul)) btor_op = "mul";
|
||||
if (cell->type.in(ID($shl), ID($sshl))) btor_op = "sll";
|
||||
if (cell->type == ID($shr)) btor_op = "srl";
|
||||
if (cell->type == ID($sshr)) btor_op = "sra";
|
||||
if (cell->type.in(ID($shift), ID($shiftx))) btor_op = "shift";
|
||||
if (cell->type.in(ID($and), ID($_AND_))) btor_op = "and";
|
||||
if (cell->type.in(ID($or), ID($_OR_))) btor_op = "or";
|
||||
if (cell->type.in(ID($xor), ID($_XOR_))) btor_op = "xor";
|
||||
if (cell->type == ID($concat)) btor_op = "concat";
|
||||
if (cell->type == ID($_NAND_)) btor_op = "nand";
|
||||
if (cell->type == ID($_NOR_)) btor_op = "nor";
|
||||
if (cell->type.in(ID($xnor), ID($_XNOR_))) btor_op = "xnor";
|
||||
if (cell->type == TW($add)) btor_op = "add";
|
||||
if (cell->type == TW($sub)) btor_op = "sub";
|
||||
if (cell->type == TW($mul)) btor_op = "mul";
|
||||
if (cell->type.in(TW($shl), TW($sshl))) btor_op = "sll";
|
||||
if (cell->type == TW($shr)) btor_op = "srl";
|
||||
if (cell->type == TW($sshr)) btor_op = "sra";
|
||||
if (cell->type.in(TW($shift), TW($shiftx))) btor_op = "shift";
|
||||
if (cell->type.in(TW($and), TW($_AND_))) btor_op = "and";
|
||||
if (cell->type.in(TW($or), TW($_OR_))) btor_op = "or";
|
||||
if (cell->type.in(TW($xor), TW($_XOR_))) btor_op = "xor";
|
||||
if (cell->type == TW($concat)) btor_op = "concat";
|
||||
if (cell->type == TW($_NAND_)) btor_op = "nand";
|
||||
if (cell->type == TW($_NOR_)) btor_op = "nor";
|
||||
if (cell->type.in(TW($xnor), TW($_XNOR_))) btor_op = "xnor";
|
||||
log_assert(!btor_op.empty());
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
if (cell->type == ID($sshr) && !a_signed)
|
||||
if (cell->type == TW($sshr) && !a_signed)
|
||||
btor_op = "srl";
|
||||
|
||||
int sid = get_bv_sid(width);
|
||||
int nid;
|
||||
|
||||
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
|
||||
int nid_a_padded = get_sig_nid(cell->getPort(TW::A), width_ay, a_signed);
|
||||
|
||||
|
|
@ -371,17 +371,17 @@ struct BtorWorker
|
|||
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 b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
|
||||
|
||||
string btor_op;
|
||||
if (cell->type == ID($div)) btor_op = "div";
|
||||
if (cell->type == TW($div)) btor_op = "div";
|
||||
// "rem" = truncating modulo
|
||||
if (cell->type == ID($mod)) btor_op = "rem";
|
||||
if (cell->type == TW($mod)) btor_op = "rem";
|
||||
// "mod" = flooring modulo
|
||||
if (cell->type == ID($modfloor)) {
|
||||
if (cell->type == TW($modfloor)) {
|
||||
// "umod" doesn't exist because it's the same as "urem"
|
||||
btor_op = a_signed || b_signed ? "mod" : "rem";
|
||||
}
|
||||
|
|
@ -411,7 +411,7 @@ struct BtorWorker
|
|||
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 nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -420,12 +420,12 @@ struct BtorWorker
|
|||
int nid1 = 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 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 or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
|
||||
}
|
||||
|
|
@ -435,7 +435,7 @@ struct BtorWorker
|
|||
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 nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -446,13 +446,13 @@ struct BtorWorker
|
|||
int nid2 = 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 and %d %d %d\n", nid2, sid, nid1, nid_c);
|
||||
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 or %d %d %d\n", nid2, sid, nid1, nid_c);
|
||||
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
|
||||
|
|
@ -463,7 +463,7 @@ struct BtorWorker
|
|||
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 nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -476,14 +476,14 @@ struct BtorWorker
|
|||
int nid3 = 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", nid2, sid, nid_c, nid_d);
|
||||
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
|
||||
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", nid2, sid, nid_c, nid_d);
|
||||
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
|
||||
|
|
@ -495,15 +495,15 @@ struct BtorWorker
|
|||
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;
|
||||
if (cell->type == ID($lt)) btor_op = "lt";
|
||||
if (cell->type == ID($le)) btor_op = "lte";
|
||||
if (cell->type.in(ID($eq), ID($eqx))) btor_op = "eq";
|
||||
if (cell->type.in(ID($ne), ID($nex))) btor_op = "neq";
|
||||
if (cell->type == ID($ge)) btor_op = "gte";
|
||||
if (cell->type == ID($gt)) btor_op = "gt";
|
||||
if (cell->type == TW($lt)) btor_op = "lt";
|
||||
if (cell->type == TW($le)) btor_op = "lte";
|
||||
if (cell->type.in(TW($eq), TW($eqx))) btor_op = "eq";
|
||||
if (cell->type.in(TW($ne), TW($nex))) btor_op = "neq";
|
||||
if (cell->type == TW($ge)) btor_op = "gte";
|
||||
if (cell->type == TW($gt)) btor_op = "gt";
|
||||
log_assert(!btor_op.empty());
|
||||
|
||||
int width = 1;
|
||||
|
|
@ -518,7 +518,7 @@ struct BtorWorker
|
|||
int nid_b = get_sig_nid(cell->getPort(TW::B), width, b_signed);
|
||||
|
||||
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));
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not";
|
||||
if (cell->type == ID($neg)) btor_op = "neg";
|
||||
if (cell->type.in(TW($not), TW($_NOT_))) btor_op = "not";
|
||||
if (cell->type == TW($neg)) btor_op = "neg";
|
||||
|
||||
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
|
||||
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());
|
||||
int sid = get_bv_sid(width);
|
||||
|
|
@ -570,12 +570,12 @@ struct BtorWorker
|
|||
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;
|
||||
if (cell->type == ID($logic_and)) btor_op = "and";
|
||||
if (cell->type == ID($logic_or)) btor_op = "or";
|
||||
if (cell->type == ID($logic_not)) btor_op = "not";
|
||||
if (cell->type == TW($logic_and)) btor_op = "and";
|
||||
if (cell->type == TW($logic_or)) btor_op = "or";
|
||||
if (cell->type == TW($logic_not)) btor_op = "not";
|
||||
log_assert(!btor_op.empty());
|
||||
|
||||
int sid = get_bv_sid(1);
|
||||
|
|
@ -614,12 +614,12 @@ struct BtorWorker
|
|||
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;
|
||||
if (cell->type == ID($reduce_and)) btor_op = "redand";
|
||||
if (cell->type.in(ID($reduce_or), ID($reduce_bool))) btor_op = "redor";
|
||||
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) btor_op = "redxor";
|
||||
if (cell->type == TW($reduce_and)) btor_op = "redand";
|
||||
if (cell->type.in(TW($reduce_or), TW($reduce_bool))) btor_op = "redor";
|
||||
if (cell->type.in(TW($reduce_xor), TW($reduce_xnor))) btor_op = "redxor";
|
||||
log_assert(!btor_op.empty());
|
||||
|
||||
int sid = get_bv_sid(1);
|
||||
|
|
@ -627,7 +627,7 @@ struct BtorWorker
|
|||
|
||||
int nid = next_nid++;
|
||||
|
||||
if (cell->type == ID($reduce_xnor)) {
|
||||
if (cell->type == TW($reduce_xnor)) {
|
||||
int nid2 = next_nid++;
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
|
||||
btorf("%d not %d %d\n", nid2, sid, nid);
|
||||
|
|
@ -650,7 +650,7 @@ struct BtorWorker
|
|||
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_b = sigmap(cell->getPort(TW::B));
|
||||
|
|
@ -664,7 +664,7 @@ struct BtorWorker
|
|||
int sid = get_bv_sid(GetSize(sig_y));
|
||||
int nid = next_nid++;
|
||||
|
||||
if (cell->type == ID($_NMUX_)) {
|
||||
if (cell->type == TW($_NMUX_)) {
|
||||
int tmp = nid;
|
||||
nid = next_nid++;
|
||||
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
|
||||
|
|
@ -677,7 +677,7 @@ struct BtorWorker
|
|||
goto okay;
|
||||
}
|
||||
|
||||
if (cell->type == ID($pmux))
|
||||
if (cell->type == TW($pmux))
|
||||
{
|
||||
SigSpec sig_a = sigmap(cell->getPort(TW::A));
|
||||
SigSpec sig_b = sigmap(cell->getPort(TW::B));
|
||||
|
|
@ -703,21 +703,21 @@ struct BtorWorker
|
|||
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_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);
|
||||
bool negedge = false;
|
||||
|
||||
if (cell->type == ID($_DFF_N_))
|
||||
if (cell->type == TW($_DFF_N_))
|
||||
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;
|
||||
|
||||
if (!info_filename.empty())
|
||||
|
|
@ -756,7 +756,7 @@ struct BtorWorker
|
|||
if (symbol.empty() || (!print_internal_names && symbol[0] == '$'))
|
||||
btorf("%d state %d\n", nid, sid);
|
||||
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)))
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($anyconst), ID($anyseq)))
|
||||
if (cell->type.in(TW($anyconst), TW($anyseq)))
|
||||
{
|
||||
SigSpec sig_y = sigmap(cell->getPort(TW::Y));
|
||||
|
||||
|
|
@ -786,7 +786,7 @@ struct BtorWorker
|
|||
|
||||
ywmap_state(sig_y);
|
||||
|
||||
if (cell->type == ID($anyconst)) {
|
||||
if (cell->type == TW($anyconst)) {
|
||||
int nid2 = next_nid++;
|
||||
btorf("%d next %d %d %d\n", nid2, sid, nid, nid);
|
||||
}
|
||||
|
|
@ -795,7 +795,7 @@ struct BtorWorker
|
|||
goto okay;
|
||||
}
|
||||
|
||||
if (cell->type == ID($initstate))
|
||||
if (cell->type == TW($initstate))
|
||||
{
|
||||
SigSpec sig_y = sigmap(cell->getPort(TW::Y));
|
||||
|
||||
|
|
@ -834,12 +834,12 @@ struct BtorWorker
|
|||
|
||||
if (asyncwr && syncwr)
|
||||
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) {
|
||||
if (port.clk_enable)
|
||||
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);
|
||||
|
|
@ -901,7 +901,7 @@ struct BtorWorker
|
|||
if (mem->memid[0] == '$')
|
||||
btorf("%d state %d\n", nid, sid);
|
||||
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);
|
||||
|
||||
|
|
@ -976,15 +976,15 @@ struct BtorWorker
|
|||
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",
|
||||
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",
|
||||
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",
|
||||
cell->type.unescape(), module, cell);
|
||||
}
|
||||
|
|
@ -1296,7 +1296,7 @@ struct BtorWorker
|
|||
|
||||
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));
|
||||
|
||||
|
|
@ -1316,7 +1316,7 @@ struct BtorWorker
|
|||
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));
|
||||
|
||||
|
|
@ -1345,7 +1345,7 @@ struct BtorWorker
|
|||
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));
|
||||
|
||||
|
|
@ -1417,7 +1417,7 @@ struct BtorWorker
|
|||
int nid = it.first;
|
||||
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);
|
||||
|
||||
|
|
@ -1465,7 +1465,7 @@ struct BtorWorker
|
|||
int nid2 = next_nid++;
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,39 +177,39 @@ struct Scheduler {
|
|||
bool is_unary_cell(TwineRef type)
|
||||
{
|
||||
return type.in(
|
||||
ID($not), ID($logic_not), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($pos), ID($neg));
|
||||
TW($not), TW($logic_not), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool),
|
||||
TW($pos), TW($neg));
|
||||
}
|
||||
|
||||
bool is_binary_cell(TwineRef type)
|
||||
{
|
||||
return type.in(
|
||||
ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or),
|
||||
ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx),
|
||||
ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le),
|
||||
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor), ID($divfloor));
|
||||
TW($and), TW($or), TW($xor), TW($xnor), TW($logic_and), TW($logic_or),
|
||||
TW($shl), TW($sshl), TW($shr), TW($sshr), TW($shift), TW($shiftx),
|
||||
TW($eq), TW($ne), TW($eqx), TW($nex), TW($gt), TW($ge), TW($lt), TW($le),
|
||||
TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($modfloor), TW($divfloor));
|
||||
}
|
||||
|
||||
bool is_extending_cell(TwineRef type)
|
||||
{
|
||||
return !type.in(
|
||||
ID($logic_not), ID($logic_and), ID($logic_or),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool));
|
||||
TW($logic_not), TW($logic_and), TW($logic_or),
|
||||
TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool));
|
||||
}
|
||||
|
||||
bool is_inlinable_cell(TwineRef type)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return type.in(
|
||||
ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce),
|
||||
ID($adff), ID($adffe), ID($dffsr), ID($dffsre),
|
||||
ID($aldff), ID($aldffe),
|
||||
ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr));
|
||||
TW($dff), TW($dffe), TW($sdff), TW($sdffe), TW($sdffce),
|
||||
TW($adff), TW($adffe), TW($dffsr), TW($dffsre),
|
||||
TW($aldff), TW($aldffe),
|
||||
TW($dlatch), TW($adlatch), TW($dlatchsr), TW($sr));
|
||||
}
|
||||
|
||||
bool is_internal_cell(TwineRef type)
|
||||
|
|
@ -219,7 +219,7 @@ bool is_internal_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)
|
||||
|
|
@ -1169,7 +1169,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
|
||||
f << ")";
|
||||
// Muxes
|
||||
} else if (cell->type == ID($mux)) {
|
||||
} else if (cell->type == TW($mux)) {
|
||||
f << "(";
|
||||
dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
|
||||
f << " ? ";
|
||||
|
|
@ -1178,7 +1178,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ")";
|
||||
// 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 s_width = cell->getParam(ID::S_WIDTH).as_int();
|
||||
for (int part = 0; part < s_width; part++) {
|
||||
|
|
@ -1193,7 +1193,7 @@ struct CxxrtlWorker {
|
|||
f << ")";
|
||||
}
|
||||
// Big muxes
|
||||
} else if (cell->type == ID($bmux)) {
|
||||
} else if (cell->type == TW($bmux)) {
|
||||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ".bmux<";
|
||||
f << cell->getParam(ID::WIDTH).as_int();
|
||||
|
|
@ -1201,7 +1201,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
|
||||
f << ").val()";
|
||||
// Bitwise muxes
|
||||
} else if (cell->type == ID($bwmux)) {
|
||||
} else if (cell->type == TW($bwmux)) {
|
||||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ".bwmux(";
|
||||
dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
|
||||
|
|
@ -1209,7 +1209,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
|
||||
f << ").val()";
|
||||
// Demuxes
|
||||
} else if (cell->type == ID($demux)) {
|
||||
} else if (cell->type == TW($demux)) {
|
||||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ".demux<";
|
||||
f << GetSize(cell->getPort(TW::Y));
|
||||
|
|
@ -1217,13 +1217,13 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::S), for_debug);
|
||||
f << ").val()";
|
||||
// Concats
|
||||
} else if (cell->type == ID($concat)) {
|
||||
} else if (cell->type == TW($concat)) {
|
||||
dump_sigspec_rhs(cell->getPort(TW::B), for_debug);
|
||||
f << ".concat(";
|
||||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ").val()";
|
||||
// Slices
|
||||
} else if (cell->type == ID($slice)) {
|
||||
} else if (cell->type == TW($slice)) {
|
||||
dump_sigspec_rhs(cell->getPort(TW::A), for_debug);
|
||||
f << ".slice<";
|
||||
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 = ";
|
||||
dump_metadata_map(cell->attributes);
|
||||
f << ";\n";
|
||||
if (cell->type == ID($print)) {
|
||||
if (cell->type == TW($print)) {
|
||||
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();
|
||||
f << indent << "performer->on_check(";
|
||||
if (flavor == "assert")
|
||||
|
|
@ -1354,9 +1354,9 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "} else {\n";
|
||||
inc_indent();
|
||||
if (cell->type == ID($print)) {
|
||||
if (cell->type == TW($print)) {
|
||||
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();
|
||||
if (flavor == "assert" || flavor == "assume") {
|
||||
f << indent << "if (!condition) {\n";
|
||||
|
|
@ -1397,9 +1397,9 @@ struct CxxrtlWorker {
|
|||
f << indent << "auto " << mangle(cell) << "_next = ";
|
||||
dump_sigspec_rhs(cell->getPort(TW::EN));
|
||||
f << ".concat(";
|
||||
if (cell->type == ID($print))
|
||||
if (cell->type == TW($print))
|
||||
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));
|
||||
else log_assert(false);
|
||||
f << ").val();\n";
|
||||
|
|
@ -1444,7 +1444,7 @@ struct CxxrtlWorker {
|
|||
f << " = ";
|
||||
dump_sigspec_rhs(cell->getPort(TW::D));
|
||||
f << ";\n";
|
||||
if (cell->hasPort(TW::EN) && cell->type != ID($sdffce)) {
|
||||
if (cell->hasPort(TW::EN) && cell->type != TW($sdffce)) {
|
||||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
|
|
@ -1461,7 +1461,7 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(TW::EN) && cell->type == ID($sdffce)) {
|
||||
if (cell->hasPort(TW::EN) && cell->type == TW($sdffce)) {
|
||||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
|
|
@ -1534,7 +1534,7 @@ struct CxxrtlWorker {
|
|||
f << (cell->getParam(ID::CLR_POLARITY).as_bool() ? "" : ".bit_not()") << ");\n";
|
||||
}
|
||||
// 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)) {
|
||||
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type);
|
||||
// User cells
|
||||
|
|
@ -2412,7 +2412,7 @@ struct CxxrtlWorker {
|
|||
count_scopes++;
|
||||
// If there were any submodules that were flattened, the module is also responsible for adding them.
|
||||
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") {
|
||||
auto module_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Module);
|
||||
auto cell_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Cell);
|
||||
|
|
@ -2697,9 +2697,9 @@ struct CxxrtlWorker {
|
|||
if (is_effectful_cell(cell->type)) {
|
||||
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
|
||||
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}
|
||||
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}
|
||||
}
|
||||
if (is_internal_cell(cell->type))
|
||||
|
|
@ -3017,7 +3017,7 @@ struct CxxrtlWorker {
|
|||
if (cell_module &&
|
||||
cell_module->get_blackbox_attribute() &&
|
||||
!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 &&
|
||||
cell_module->get_bool_attribute(ID(cxxrtl_blackbox)) &&
|
||||
|
|
@ -3027,7 +3027,7 @@ struct CxxrtlWorker {
|
|||
flow.add_node(cell);
|
||||
|
||||
// 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)))
|
||||
register_edge_signal(sigmap, cell->getPort(TW::CLK),
|
||||
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
#define EDIF_DEF(_id) edif_names(_id.unescape(), true)
|
||||
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(_id.unescape(), true, _ren, _bl, _br)
|
||||
#define EDIF_REF(_id) edif_names(_id.unescape(), false)
|
||||
#define EDIF_DEF(_id) design->twines.unescaped_str(edif_names(_id), true)
|
||||
#define EDIF_DEFR(_id, _ren, _bl, _br) design->twines.unescaped_str(edif_names(_id), true, _ren, _bl, _br)
|
||||
#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_REF_STR(_id) edif_names(RTLIL::unescape_id(_id), false)
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ struct EdifBackend : public Backend {
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
continue;
|
||||
|
||||
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)
|
||||
if (module_deps.count(dep) > 0)
|
||||
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);
|
||||
not_ready_yet:;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const char *make_id(IdString id)
|
|||
if (namecache.count(id) != 0)
|
||||
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++)
|
||||
{
|
||||
|
|
@ -599,7 +599,7 @@ struct FirrtlWorker
|
|||
string y_id = make_id(cell->name);
|
||||
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));
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
// Assume the FIRRTL width is a single bit.
|
||||
firrtl_width = 1;
|
||||
if (cell->type.in(ID($not), ID($_NOT_))) primop = "not";
|
||||
else if (cell->type == ID($neg)) {
|
||||
if (cell->type.in(TW($not), TW($_NOT_))) primop = "not";
|
||||
else if (cell->type == TW($neg)) {
|
||||
primop = "neg";
|
||||
firrtl_is_signed = true; // Result of "neg" is signed (an SInt).
|
||||
firrtl_width = a_width;
|
||||
} else if (cell->type == ID($logic_not)) {
|
||||
} else if (cell->type == TW($logic_not)) {
|
||||
primop = "eq";
|
||||
a_expr = stringf("%s, UInt(0)", a_expr);
|
||||
}
|
||||
else if (cell->type == ID($reduce_and)) primop = "andr";
|
||||
else if (cell->type == ID($reduce_or)) primop = "orr";
|
||||
else if (cell->type == ID($reduce_xor)) primop = "xorr";
|
||||
else if (cell->type == ID($reduce_xnor)) {
|
||||
else if (cell->type == TW($reduce_and)) primop = "andr";
|
||||
else if (cell->type == TW($reduce_or)) primop = "orr";
|
||||
else if (cell->type == TW($reduce_xor)) primop = "xorr";
|
||||
else if (cell->type == TW($reduce_xnor)) {
|
||||
primop = "not";
|
||||
a_expr = stringf("xorr(%s)", a_expr);
|
||||
}
|
||||
else if (cell->type == ID($reduce_bool)) {
|
||||
else if (cell->type == TW($reduce_bool)) {
|
||||
primop = "neq";
|
||||
// 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);
|
||||
|
|
@ -647,9 +647,9 @@ struct FirrtlWorker
|
|||
|
||||
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),
|
||||
ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($shr), ID($sshr), ID($sshl), ID($shl),
|
||||
ID($logic_and), ID($logic_or), ID($pow)))
|
||||
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),
|
||||
TW($gt), TW($ge), TW($lt), TW($le), TW($ne), TW($nex), TW($shr), TW($sshr), TW($sshl), TW($shl),
|
||||
TW($logic_and), TW($logic_or), TW($pow)))
|
||||
{
|
||||
string a_expr = make_expr(cell->getPort(TW::A));
|
||||
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,
|
||||
// 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 + ")";
|
||||
// Expand the "B" operand to the result 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.
|
||||
// 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) {
|
||||
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
|
||||
|
|
@ -692,79 +692,79 @@ struct FirrtlWorker
|
|||
firrtl_width = a_width;
|
||||
auto a_sig = cell->getPort(TW::A);
|
||||
|
||||
if (cell->type == ID($add)) {
|
||||
if (cell->type == TW($add)) {
|
||||
primop = "add";
|
||||
firrtl_is_signed = a_signed | b_signed;
|
||||
firrtl_width = max(a_width, b_width);
|
||||
} else if (cell->type == ID($sub)) {
|
||||
} else if (cell->type == TW($sub)) {
|
||||
primop = "sub";
|
||||
firrtl_is_signed = true;
|
||||
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;
|
||||
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";
|
||||
firrtl_is_signed = a_signed | b_signed;
|
||||
firrtl_width = a_width + b_width;
|
||||
} else if (cell->type == ID($div)) {
|
||||
} else if (cell->type == TW($div)) {
|
||||
primop = "div";
|
||||
firrtl_is_signed = a_signed | b_signed;
|
||||
firrtl_width = a_width;
|
||||
} else if (cell->type == ID($mod)) {
|
||||
} else if (cell->type == TW($mod)) {
|
||||
// "rem" = truncating modulo
|
||||
primop = "rem";
|
||||
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";
|
||||
always_uint = true;
|
||||
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";
|
||||
always_uint = true;
|
||||
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";
|
||||
always_uint = true;
|
||||
firrtl_width = max(a_width, b_width);
|
||||
}
|
||||
else if (cell->type == ID($xnor)) {
|
||||
else if (cell->type == TW($xnor)) {
|
||||
primop = "xnor";
|
||||
always_uint = true;
|
||||
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";
|
||||
always_uint = true;
|
||||
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";
|
||||
always_uint = true;
|
||||
firrtl_width = 1;
|
||||
}
|
||||
else if (cell->type == ID($gt)) {
|
||||
else if (cell->type == TW($gt)) {
|
||||
primop = "gt";
|
||||
always_uint = true;
|
||||
firrtl_width = 1;
|
||||
}
|
||||
else if (cell->type == ID($ge)) {
|
||||
else if (cell->type == TW($ge)) {
|
||||
primop = "geq";
|
||||
always_uint = true;
|
||||
firrtl_width = 1;
|
||||
}
|
||||
else if (cell->type == ID($lt)) {
|
||||
else if (cell->type == TW($lt)) {
|
||||
primop = "lt";
|
||||
always_uint = true;
|
||||
firrtl_width = 1;
|
||||
}
|
||||
else if (cell->type == ID($le)) {
|
||||
else if (cell->type == TW($le)) {
|
||||
primop = "leq";
|
||||
always_uint = true;
|
||||
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.
|
||||
// We'll need to offset this by extracting the un-widened portion as Verilog would do.
|
||||
extract_y_bits = true;
|
||||
|
|
@ -782,7 +782,7 @@ struct FirrtlWorker
|
|||
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.
|
||||
extract_y_bits = false;
|
||||
// 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.
|
||||
if (firrtl_is_signed) {
|
||||
// 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 + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((cell->type == ID($logic_and))) {
|
||||
else if ((cell->type == TW($logic_and))) {
|
||||
primop = "and";
|
||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||
always_uint = true;
|
||||
firrtl_width = 1;
|
||||
}
|
||||
else if ((cell->type == ID($logic_or))) {
|
||||
else if ((cell->type == TW($logic_or))) {
|
||||
primop = "or";
|
||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||
always_uint = true;
|
||||
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) {
|
||||
// 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.
|
||||
|
|
@ -878,7 +878,7 @@ struct FirrtlWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($mux), ID($_MUX_)))
|
||||
if (cell->type.in(TW($mux), TW($_MUX_)))
|
||||
{
|
||||
auto it = cell->parameters.find(ID::WIDTH);
|
||||
int width = it == cell->parameters.end()? 1 : it->second.as_int();
|
||||
|
|
@ -901,7 +901,7 @@ struct FirrtlWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($dff)))
|
||||
if (cell->type.in(TW($dff)))
|
||||
{
|
||||
bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool();
|
||||
if (clkpol == false)
|
||||
|
|
@ -919,7 +919,7 @@ struct FirrtlWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($shiftx)) {
|
||||
if (cell->type == TW($shiftx)) {
|
||||
// assign y = a[b +: y_width];
|
||||
// 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));
|
||||
continue;
|
||||
}
|
||||
if (cell->type == ID($shift)) {
|
||||
if (cell->type == TW($shift)) {
|
||||
// assign y = a >> b;
|
||||
// where b may be negative
|
||||
|
||||
|
|
@ -966,7 +966,7 @@ struct FirrtlWorker
|
|||
register_reverse_wire_map(y_id, cell->getPort(TW::Y));
|
||||
continue;
|
||||
}
|
||||
if (cell->type == ID($pos)) {
|
||||
if (cell->type == TW($pos)) {
|
||||
// assign y = a;
|
||||
// printCell(cell);
|
||||
string a_expr = make_expr(cell->getPort(TW::A));
|
||||
|
|
@ -981,9 +981,9 @@ struct FirrtlWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
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) {
|
||||
|
|
@ -991,10 +991,10 @@ struct FirrtlWorker
|
|||
|
||||
Const init_data = mem.get_init_data();
|
||||
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)
|
||||
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++)
|
||||
{
|
||||
|
|
@ -1002,7 +1002,7 @@ struct FirrtlWorker
|
|||
string port_name(stringf("%s.r%d", mem_id, i));
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -1023,12 +1023,12 @@ struct FirrtlWorker
|
|||
string port_name(stringf("%s.w%d", mem_id, i));
|
||||
|
||||
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)
|
||||
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++)
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ struct CxxStruct {
|
|||
}
|
||||
f.print("\n\t\ttemplate <typename T> void visit(T &&fn) {{\n");
|
||||
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}};\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 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 input(Node, IdString name, IdString kind) override { log_assert(kind == ID($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 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 == TW($state)); print("current_state.{}", state_struct[name]); }
|
||||
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); }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public:
|
|||
SmtStruct(std::string name, SmtScope &scope) : scope(scope), name(name) {}
|
||||
void insert(IdString field_name, SmtSort sort) {
|
||||
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});
|
||||
}
|
||||
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_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 state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", 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 == TW($state)); return state_struct.access("state", name); }
|
||||
};
|
||||
|
||||
struct SmtModule {
|
||||
|
|
|
|||
|
|
@ -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_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 state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", 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 == TW($state)); return state_struct.access("state", name); }
|
||||
};
|
||||
|
||||
struct SmtrModule {
|
||||
|
|
@ -281,7 +281,7 @@ struct SmtrModule {
|
|||
w.push();
|
||||
w.open(list());
|
||||
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.open(list("if", "assoc-result"));
|
||||
w << list("cdr", "assoc-result");
|
||||
|
|
@ -298,7 +298,7 @@ struct SmtrModule {
|
|||
w << list(*output_helper_name, outputs_name);
|
||||
w.open(list("list"));
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,11 +146,11 @@ struct FunctionalTestGeneric : public Pass
|
|||
log("Dumping module `%s'.\n", module->name);
|
||||
auto fir = Functional::IR::from_module(module);
|
||||
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())
|
||||
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())
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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 sig.as_wire()->name.unescape();
|
||||
return design->twines.unescaped_str(sig.as_wire()->name);
|
||||
}
|
||||
|
||||
struct IntersynthBackend : public Backend {
|
||||
|
|
@ -151,8 +151,8 @@ struct IntersynthBackend : public Backend {
|
|||
if (wire->port_input || wire->port_output) {
|
||||
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->port_input ? "input" : "output", wire->name.unescape(), wire->width, wire->name.unescape()));
|
||||
netlists_code += stringf("node %s %s PORT %s\n", wire->name.unescape(), 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", design->twines.unescaped_str(wire->name), design->twines.unescaped_str(wire->name),
|
||||
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;
|
||||
|
||||
if (!ct.cell_known(cell->type))
|
||||
log_error("Found unknown cell type %s in module!\n", cell->type.unescape());
|
||||
if (!ct.cell_known(cell->type_impl))
|
||||
log_error("Found unknown cell type %s in module!\n", cell->type.unescaped());
|
||||
|
||||
celltype_code = stringf("celltype %s", cell->type.unescape());
|
||||
node_code = stringf("node %s %s", cell->module->design->twines.str(cell->meta_->name), 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.unescaped());
|
||||
for (auto &port : cell->connections()) {
|
||||
RTLIL::SigSpec sig = sigmap(port.second);
|
||||
if (sig.size() != 0) {
|
||||
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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
for (auto ¶m : 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) {
|
||||
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--)
|
||||
node_code += param.second[i] == State::S1 ? "1" : "0";
|
||||
} 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");
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct JnyWriter
|
|||
{
|
||||
_cells.clear();
|
||||
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())
|
||||
_cells.emplace(cell_type, std::vector<Cell*>());
|
||||
|
|
@ -353,10 +353,10 @@ struct JnyWriter
|
|||
f << stringf(",\n");
|
||||
const auto param_val = param.second;
|
||||
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);
|
||||
} 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;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ struct JsonWriter
|
|||
|
||||
string get_name(IdString name)
|
||||
{
|
||||
return get_string(name.unescape());
|
||||
return design->twines.unescaped_str(get_string(name));
|
||||
}
|
||||
|
||||
string get_name(TwineRef name)
|
||||
|
|
@ -205,7 +205,7 @@ struct JsonWriter
|
|||
for (auto c : module->cells()) {
|
||||
if (use_selection && !module->selected(c))
|
||||
continue;
|
||||
if (!scopeinfo_mode && c->type == ID($scopeinfo))
|
||||
if (!scopeinfo_mode && c->type == TW($scopeinfo))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(c->name));
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ struct SimplecWorker
|
|||
|
||||
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 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 expr;
|
||||
|
||||
if (cell->type == ID($_BUF_)) expr = a_expr;
|
||||
if (cell->type == ID($_NOT_)) expr = "!" + a_expr;
|
||||
if (cell->type == TW($_BUF_)) expr = a_expr;
|
||||
if (cell->type == TW($_NOT_)) expr = "!" + a_expr;
|
||||
|
||||
log_assert(y.wire);
|
||||
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);
|
||||
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 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 expr;
|
||||
|
||||
if (cell->type == ID($_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 == ID($_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 == ID($_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 == ID($_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($_AND_)) expr = stringf("%s & %s", a_expr, b_expr);
|
||||
if (cell->type == TW($_NAND_)) expr = stringf("!(%s & %s)", a_expr, b_expr);
|
||||
if (cell->type == TW($_OR_)) expr = stringf("%s | %s", a_expr, b_expr);
|
||||
if (cell->type == TW($_NOR_)) expr = stringf("!(%s | %s)", a_expr, b_expr);
|
||||
if (cell->type == TW($_XOR_)) expr = stringf("%s ^ %s", a_expr, b_expr);
|
||||
if (cell->type == TW($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr, b_expr);
|
||||
if (cell->type == TW($_ANDNOT_)) 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);
|
||||
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);
|
||||
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 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 expr;
|
||||
|
||||
if (cell->type == ID($_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($_AOI3_)) 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);
|
||||
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);
|
||||
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 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 expr;
|
||||
|
||||
if (cell->type == ID($_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($_AOI4_)) 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);
|
||||
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);
|
||||
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 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)
|
||||
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr,
|
||||
cell->type == ID($_NMUX_) ? "!" : "", b_expr,
|
||||
cell->type == ID($_NMUX_) ? "!" : "", a_expr);
|
||||
cell->type == TW($_NMUX_) ? "!" : "", b_expr,
|
||||
cell->type == TW($_NMUX_) ? "!" : "", a_expr);
|
||||
|
||||
log_assert(y.wire);
|
||||
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);
|
||||
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)
|
||||
|
|
@ -579,7 +579,7 @@ struct SimplecWorker
|
|||
string hiername = work->log_prefix + "." + cell->module->design->twines.str(cell->meta_->name);
|
||||
|
||||
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))
|
||||
reactivated_cells.insert(hiername);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ struct Smt2Worker
|
|||
const char *get_id(IdString n)
|
||||
{
|
||||
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++) {
|
||||
if (str[i] == '\\')
|
||||
str[i] = '/';
|
||||
|
|
@ -196,8 +196,8 @@ struct Smt2Worker
|
|||
continue;
|
||||
}
|
||||
|
||||
bool is_input = ct.cell_input(cell->type, conn.first);
|
||||
bool is_output = ct.cell_output(cell->type, conn.first);
|
||||
bool is_input = ct.cell_input(cell->type_impl, conn.first);
|
||||
bool is_output = ct.cell_output(cell->type_impl, conn.first);
|
||||
|
||||
if (is_output && !is_input)
|
||||
for (auto bit : sigmap(conn.second)) {
|
||||
|
|
@ -207,11 +207,11 @@ struct Smt2Worker
|
|||
}
|
||||
else if (is_output || !is_input)
|
||||
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)) {
|
||||
if (posedge)
|
||||
clock_posedge.insert(bit);
|
||||
|
|
@ -546,7 +546,7 @@ struct Smt2Worker
|
|||
{
|
||||
if (verbose)
|
||||
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))
|
||||
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);
|
||||
recursive_cells.insert(cell);
|
||||
|
||||
if (cell->type == ID($initstate))
|
||||
if (cell->type == TW($initstate))
|
||||
{
|
||||
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",
|
||||
|
|
@ -567,7 +567,7 @@ struct Smt2Worker
|
|||
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);
|
||||
SigBit q_bit = cell->getPort(TW::Q);
|
||||
|
|
@ -579,28 +579,28 @@ struct Smt2Worker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_BUF_)) return export_gate(cell, "A");
|
||||
if (cell->type == ID($_NOT_)) return export_gate(cell, "(not A)");
|
||||
if (cell->type == ID($_AND_)) return export_gate(cell, "(and A B)");
|
||||
if (cell->type == ID($_NAND_)) return export_gate(cell, "(not (and A B))");
|
||||
if (cell->type == ID($_OR_)) return export_gate(cell, "(or A B)");
|
||||
if (cell->type == ID($_NOR_)) return export_gate(cell, "(not (or A B))");
|
||||
if (cell->type == ID($_XOR_)) return export_gate(cell, "(xor A B)");
|
||||
if (cell->type == ID($_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 == ID($_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 == ID($_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 == ID($_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 == ID($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))");
|
||||
if (cell->type == TW($_BUF_)) return export_gate(cell, "A");
|
||||
if (cell->type == TW($_NOT_)) return export_gate(cell, "(not A)");
|
||||
if (cell->type == TW($_AND_)) return export_gate(cell, "(and A B)");
|
||||
if (cell->type == TW($_NAND_)) return export_gate(cell, "(not (and A B))");
|
||||
if (cell->type == TW($_OR_)) return export_gate(cell, "(or A B)");
|
||||
if (cell->type == TW($_NOR_)) return export_gate(cell, "(not (or A B))");
|
||||
if (cell->type == TW($_XOR_)) return export_gate(cell, "(xor A B)");
|
||||
if (cell->type == TW($_XNOR_)) return export_gate(cell, "(not (xor A B))");
|
||||
if (cell->type == TW($_ANDNOT_)) return export_gate(cell, "(and A (not B))");
|
||||
if (cell->type == TW($_ORNOT_)) return export_gate(cell, "(or A (not B))");
|
||||
if (cell->type == TW($_MUX_)) return export_gate(cell, "(ite S B A)");
|
||||
if (cell->type == TW($_NMUX_)) return export_gate(cell, "(not (ite S B A))");
|
||||
if (cell->type == TW($_AOI3_)) return export_gate(cell, "(not (or (and A B) C))");
|
||||
if (cell->type == TW($_OAI3_)) return export_gate(cell, "(not (and (or A B) C))");
|
||||
if (cell->type == TW($_AOI4_)) return export_gate(cell, "(not (or (and A B) (and C D)))");
|
||||
if (cell->type == TW($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))");
|
||||
|
||||
// FIXME: $lut
|
||||
|
||||
if (bvmode)
|
||||
{
|
||||
if (cell->type.in(ID($ff), ID($dff)))
|
||||
if (cell->type.in(TW($ff), TW($dff)))
|
||||
{
|
||||
registers.insert(cell);
|
||||
int smtoffset = 0;
|
||||
|
|
@ -615,9 +615,9 @@ struct Smt2Worker
|
|||
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);
|
||||
string infostr;
|
||||
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());
|
||||
}
|
||||
|
||||
bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst));
|
||||
bool clk2fflogic = cell->type == ID($anyinit) && cell->get_bool_attribute(ID(clk2fflogic));
|
||||
bool init_only = cell->type.in(TW($anyconst), TW($anyinit), TW($allconst));
|
||||
bool clk2fflogic = cell->type == TW($anyinit) && cell->get_bool_attribute(ID(clk2fflogic));
|
||||
int smtoffset = 0;
|
||||
for (auto chunk : cell->getPort(clk2fflogic ? TW::D : QY).chunks()) {
|
||||
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)));
|
||||
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));
|
||||
register_bv(cell->getPort(QY), idcounter++);
|
||||
recursive_cells.erase(cell);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell->type == ID($and)) return export_bvop(cell, "(bvand A B)");
|
||||
if (cell->type == ID($or)) return export_bvop(cell, "(bvor A B)");
|
||||
if (cell->type == ID($xor)) return export_bvop(cell, "(bvxor A B)");
|
||||
if (cell->type == ID($xnor)) return export_bvop(cell, "(bvxnor A B)");
|
||||
if (cell->type == TW($and)) return export_bvop(cell, "(bvand A B)");
|
||||
if (cell->type == TW($or)) return export_bvop(cell, "(bvor A B)");
|
||||
if (cell->type == TW($xor)) return export_bvop(cell, "(bvxor 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 == ID($bwmux)) return export_bvop(cell, "(bvor (bvand A (bvnot S)) (bvand B S))", 'U');
|
||||
if (cell->type == TW($bweqx)) return export_bvop(cell, "(bvxnor A B)", '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 == ID($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 == ID($sshr)) return export_bvop(cell, "(bvLshr A B)", 's');
|
||||
if (cell->type == TW($shl)) return export_bvop(cell, "(bvshl A B)", 's');
|
||||
if (cell->type == TW($shr)) return export_bvop(cell, "(bvlshr A B)", 's');
|
||||
if (cell->type == TW($sshl)) return export_bvop(cell, "(bvshl 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()) {
|
||||
return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) "
|
||||
"(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 == ID($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 == ID($gt)) return export_bvop(cell, "(bvUgt A B)", 'b');
|
||||
if (cell->type == TW($lt)) return export_bvop(cell, "(bvUlt A B)", 'b');
|
||||
if (cell->type == TW($le)) return export_bvop(cell, "(bvUle A B)", 'b');
|
||||
if (cell->type == TW($ge)) return export_bvop(cell, "(bvUge 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 == ID($nex)) return export_bvop(cell, "(distinct A B)", 'b');
|
||||
if (cell->type == ID($eq)) return export_bvop(cell, "(= A B)", 'b');
|
||||
if (cell->type == ID($eqx)) return export_bvop(cell, "(= A B)", 'b');
|
||||
if (cell->type == TW($ne)) return export_bvop(cell, "(distinct A B)", 'b');
|
||||
if (cell->type == TW($nex)) return export_bvop(cell, "(distinct A B)", 'b');
|
||||
if (cell->type == TW($eq)) 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 == ID($pos)) return export_bvop(cell, "A");
|
||||
if (cell->type == ID($neg)) return export_bvop(cell, "(bvneg A)");
|
||||
if (cell->type == TW($not)) return export_bvop(cell, "(bvnot A)");
|
||||
if (cell->type == TW($pos)) return export_bvop(cell, "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 == ID($sub)) return export_bvop(cell, "(bvsub A B)");
|
||||
if (cell->type == ID($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($add)) return export_bvop(cell, "(bvadd A B)");
|
||||
if (cell->type == TW($sub)) return export_bvop(cell, "(bvsub A B)");
|
||||
if (cell->type == TW($mul)) return export_bvop(cell, "(bvmul A B)");
|
||||
if (cell->type == TW($div)) return export_bvop(cell, "(bvUdiv A B)", 'd');
|
||||
// "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
|
||||
if (cell->type == ID($modfloor)) {
|
||||
if (cell->type == TW($modfloor)) {
|
||||
// bvumod doesn't exist because it's the same as bvurem
|
||||
if (cell->getParam(ID::A_SIGNED).as_bool()) {
|
||||
return export_bvop(cell, "(bvsmod A B)", 'd');
|
||||
|
|
@ -707,7 +707,7 @@ struct Smt2Worker
|
|||
}
|
||||
}
|
||||
// "div" = flooring division
|
||||
if (cell->type == ID($divfloor)) {
|
||||
if (cell->type == TW($divfloor)) {
|
||||
if (cell->getParam(ID::A_SIGNED).as_bool()) {
|
||||
// bvsdiv is truncating division, so we can't use it here.
|
||||
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))) {
|
||||
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');
|
||||
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 == ID($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 == ID($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_and)) return export_reduce(cell, "(and A)", true);
|
||||
if (cell->type == TW($reduce_or)) return export_reduce(cell, "(or A)", false);
|
||||
if (cell->type == TW($reduce_xor)) return export_reduce(cell, "(xor A)", false);
|
||||
if (cell->type == TW($reduce_xnor)) return export_reduce(cell, "(not (xor 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 == ID($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_not)) return export_reduce(cell, "(not (or A))", false);
|
||||
if (cell->type == TW($logic_and)) return export_reduce(cell, "(and (or A) (or 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));
|
||||
std::string processed_expr = get_bv(cell->getPort(TW::A));
|
||||
|
|
@ -798,7 +798,7 @@ struct Smt2Worker
|
|||
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);
|
||||
|
||||
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));
|
||||
|
||||
string memstate;
|
||||
|
|
@ -823,7 +823,7 @@ struct Smt2Worker
|
|||
|
||||
if (port.clk_enable)
|
||||
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",
|
||||
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)
|
||||
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",
|
||||
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;
|
||||
}
|
||||
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
cell->type, module, cell);
|
||||
}
|
||||
|
|
@ -973,7 +973,7 @@ struct Smt2Worker
|
|||
|
||||
pool<SigBit> reg_bits;
|
||||
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
|
||||
for (auto bit : cell->getPort(TW::Q))
|
||||
reg_bits.insert(bit);
|
||||
|
|
@ -1117,15 +1117,15 @@ struct Smt2Worker
|
|||
|
||||
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 :
|
||||
cell->type == ID($assume) ? assume_id :
|
||||
cell->type == ID($cover) ? cover_id : *(int*)nullptr;
|
||||
int &id = cell->type == TW($assert) ? assert_id :
|
||||
cell->type == TW($assume) ? assume_id :
|
||||
cell->type == TW($cover) ? cover_id : *(int*)nullptr;
|
||||
|
||||
char postfix = cell->type == ID($assert) ? 'a' :
|
||||
cell->type == ID($assume) ? 'u' :
|
||||
cell->type == ID($cover) ? 'c' : 0;
|
||||
char postfix = cell->type == TW($assert) ? 'a' :
|
||||
cell->type == TW($assume) ? 'u' :
|
||||
cell->type == TW($cover) ? 'c' : 0;
|
||||
|
||||
string name_a = get_bool(cell->getPort(TW::A));
|
||||
string name_en = get_bool(cell->getPort(TW::EN));
|
||||
|
|
@ -1147,16 +1147,16 @@ struct Smt2Worker
|
|||
else
|
||||
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",
|
||||
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
|
||||
else
|
||||
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)));
|
||||
|
||||
if (cell->type == ID($assert))
|
||||
if (cell->type == TW($assert))
|
||||
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));
|
||||
|
||||
id++;
|
||||
|
|
@ -1212,7 +1212,7 @@ struct Smt2Worker
|
|||
|
||||
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_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")));
|
||||
}
|
||||
|
||||
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_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")));
|
||||
}
|
||||
|
||||
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_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))));
|
||||
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")));
|
||||
}
|
||||
}
|
||||
|
|
@ -1882,7 +1882,7 @@ struct Smt2Backend : public Backend {
|
|||
for (auto &dep : it.second)
|
||||
if (module_deps.count(dep) > 0)
|
||||
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);
|
||||
not_ready_yet:;
|
||||
}
|
||||
|
|
@ -1899,7 +1899,7 @@ struct Smt2Backend : public Backend {
|
|||
|
||||
for (auto module : sorted_modules)
|
||||
for (auto cell : module->cells())
|
||||
if (cell->type.in(ID($allconst), ID($allseq)))
|
||||
if (cell->type.in(TW($allconst), TW($allseq)))
|
||||
goto found_forall;
|
||||
if (0) {
|
||||
found_forall:
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ struct SmvWorker
|
|||
{
|
||||
// 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_en = cell->getPort(TW::EN);
|
||||
|
|
@ -237,7 +237,7 @@ struct SmvWorker
|
|||
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_b = cell->getPort(TW::B);
|
||||
|
|
@ -256,10 +256,10 @@ struct SmvWorker
|
|||
|
||||
bool signed_a = cell->getParam(ID::A_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;
|
||||
|
||||
if (cell->type == ID($sshr) && signed_a)
|
||||
if (cell->type == TW($sshr) && signed_a)
|
||||
{
|
||||
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);
|
||||
|
|
@ -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_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);
|
||||
|
||||
|
|
@ -292,7 +292,7 @@ struct SmvWorker
|
|||
}
|
||||
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);
|
||||
else
|
||||
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
|
||||
|
|
@ -308,14 +308,14 @@ struct SmvWorker
|
|||
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));
|
||||
string expr_a, op;
|
||||
|
||||
if (cell->type == ID($not)) op = "!";
|
||||
if (cell->type == ID($pos)) op = "";
|
||||
if (cell->type == ID($neg)) op = "-";
|
||||
if (cell->type == TW($not)) op = "!";
|
||||
if (cell->type == TW($pos)) op = "";
|
||||
if (cell->type == TW($neg)) op = "-";
|
||||
|
||||
if (cell->getParam(ID::A_SIGNED).as_bool())
|
||||
{
|
||||
|
|
@ -331,18 +331,18 @@ struct SmvWorker
|
|||
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));
|
||||
string expr_a, expr_b, op;
|
||||
|
||||
if (cell->type == ID($add)) op = "+";
|
||||
if (cell->type == ID($sub)) op = "-";
|
||||
if (cell->type == ID($mul)) op = "*";
|
||||
if (cell->type == ID($and)) op = "&";
|
||||
if (cell->type == ID($or)) op = "|";
|
||||
if (cell->type == ID($xor)) op = "xor";
|
||||
if (cell->type == ID($xnor)) op = "xnor";
|
||||
if (cell->type == TW($add)) op = "+";
|
||||
if (cell->type == TW($sub)) op = "-";
|
||||
if (cell->type == TW($mul)) op = "*";
|
||||
if (cell->type == TW($and)) op = "&";
|
||||
if (cell->type == TW($or)) op = "|";
|
||||
if (cell->type == TW($xor)) op = "xor";
|
||||
if (cell->type == TW($xnor)) op = "xnor";
|
||||
|
||||
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
|
||||
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 = max(width_y, GetSize(cell->getPort(TW::A)));
|
||||
width = max(width, GetSize(cell->getPort(TW::B)));
|
||||
string expr_a, expr_b, op;
|
||||
|
||||
if (cell->type == ID($div)) op = "/";
|
||||
//if (cell->type == ID($mod)) op = "mod";
|
||||
if (cell->type == TW($div)) op = "/";
|
||||
//if (cell->type == TW($mod)) op = "mod";
|
||||
|
||||
if (cell->getParam(ID::A_SIGNED).as_bool())
|
||||
{
|
||||
|
|
@ -383,19 +383,19 @@ struct SmvWorker
|
|||
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)));
|
||||
string expr_a, expr_b, op;
|
||||
|
||||
if (cell->type == ID($eq)) op = "=";
|
||||
if (cell->type == ID($ne)) op = "!=";
|
||||
if (cell->type == ID($eqx)) op = "=";
|
||||
if (cell->type == ID($nex)) op = "!=";
|
||||
if (cell->type == ID($lt)) op = "<";
|
||||
if (cell->type == ID($le)) op = "<=";
|
||||
if (cell->type == ID($ge)) op = ">=";
|
||||
if (cell->type == ID($gt)) op = ">";
|
||||
if (cell->type == TW($eq)) op = "=";
|
||||
if (cell->type == TW($ne)) op = "!=";
|
||||
if (cell->type == TW($eqx)) op = "=";
|
||||
if (cell->type == TW($nex)) op = "!=";
|
||||
if (cell->type == TW($lt)) op = "<";
|
||||
if (cell->type == TW($le)) op = "<=";
|
||||
if (cell->type == TW($ge)) op = ">=";
|
||||
if (cell->type == TW($gt)) op = ">";
|
||||
|
||||
if (cell->getParam(ID::A_SIGNED).as_bool())
|
||||
{
|
||||
|
|
@ -414,7 +414,7 @@ struct SmvWorker
|
|||
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_y = GetSize(cell->getPort(TW::Y));
|
||||
|
|
@ -422,15 +422,15 @@ struct SmvWorker
|
|||
const char *expr_y = lvalue(cell->getPort(TW::Y));
|
||||
string expr;
|
||||
|
||||
if (cell->type == ID($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 == ID($reduce_bool)) 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 == TW($reduce_or)) 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));
|
||||
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));
|
||||
const char *expr_y = lvalue(cell->getPort(TW::Y));
|
||||
|
|
@ -442,14 +442,14 @@ struct SmvWorker
|
|||
expr += rvalue(bit);
|
||||
}
|
||||
|
||||
if (cell->type == ID($reduce_xnor))
|
||||
if (cell->type == TW($reduce_xnor))
|
||||
expr = "!(" + expr + ")";
|
||||
|
||||
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr, width_y));
|
||||
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_b = GetSize(cell->getPort(TW::B));
|
||||
|
|
@ -460,14 +460,14 @@ struct SmvWorker
|
|||
const char *expr_y = lvalue(cell->getPort(TW::Y));
|
||||
|
||||
string expr;
|
||||
if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b;
|
||||
if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b;
|
||||
if (cell->type == TW($logic_and)) 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));
|
||||
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_y = GetSize(cell->getPort(TW::Y));
|
||||
|
|
@ -479,7 +479,7 @@ struct SmvWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($mux), ID($pmux)))
|
||||
if (cell->type.in(TW($mux), TW($pmux)))
|
||||
{
|
||||
int width = GetSize(cell->getPort(TW::Y));
|
||||
SigSpec sig_a = cell->getPort(TW::A);
|
||||
|
|
@ -495,34 +495,34 @@ struct SmvWorker
|
|||
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))));
|
||||
assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort(TW::Q)), rvalue(cell->getPort(TW::D))));
|
||||
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))));
|
||||
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;
|
||||
|
||||
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_))) op = "&";
|
||||
if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_))) op = "|";
|
||||
if (cell->type.in(ID($_XOR_))) op = "xor";
|
||||
if (cell->type.in(ID($_XNOR_))) op = "xnor";
|
||||
if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_ANDNOT_))) op = "&";
|
||||
if (cell->type.in(TW($_OR_), TW($_NOR_), TW($_ORNOT_))) op = "|";
|
||||
if (cell->type.in(TW($_XOR_))) op = "xor";
|
||||
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)),
|
||||
rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B))));
|
||||
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)),
|
||||
rvalue(cell->getPort(TW::A)), op.c_str(), rvalue(cell->getPort(TW::B))));
|
||||
else
|
||||
|
|
@ -531,61 +531,61 @@ struct SmvWorker
|
|||
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)),
|
||||
rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A))));
|
||||
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)),
|
||||
rvalue(cell->getPort(TW::S)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::A))));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI3_))
|
||||
if (cell->type == TW($_AOI3_))
|
||||
{
|
||||
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))));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_OAI3_))
|
||||
if (cell->type == TW($_OAI3_))
|
||||
{
|
||||
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))));
|
||||
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)),
|
||||
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D))));
|
||||
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)),
|
||||
rvalue(cell->getPort(TW::A)), rvalue(cell->getPort(TW::B)), rvalue(cell->getPort(TW::C)), rvalue(cell->getPort(TW::D))));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
continue;
|
||||
|
||||
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",
|
||||
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",
|
||||
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",
|
||||
cell->type.unescape(), module, cell);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
static string spice_id2str(IdString id)
|
||||
{
|
||||
static const char *escape_chars = "$\\[]()<>=";
|
||||
string s = id.unescape();
|
||||
string s = design->twines.unescaped_str(id);
|
||||
|
||||
for (auto &ch : s)
|
||||
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())
|
||||
{
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
continue;
|
||||
|
||||
f << stringf("X%d", cell_counter++);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ struct TableBackend : public Backend {
|
|||
continue;
|
||||
|
||||
*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";
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ struct TableBackend : public Backend {
|
|||
{
|
||||
*f << design->twines.str(module->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";
|
||||
|
||||
if (cell->input(conn.first) && cell->output(conn.first))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
if (cell->type == ID($_NOT_)) {
|
||||
if (cell->type == TW($_NOT_)) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = ");
|
||||
|
|
@ -1120,8 +1120,8 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_BUF_), ID($buf))) {
|
||||
if (cell->type == ID($buf) && cell->getPort(TW::A).has_const(State::Sz)) {
|
||||
if (cell->type.in(TW($_BUF_), TW($buf))) {
|
||||
if (cell->type == TW($buf) && cell->getPort(TW::A).has_const(State::Sz)) {
|
||||
RTLIL::SigSpec a = cell->getPort(TW::A);
|
||||
RTLIL::SigSpec y = cell->getPort(TW::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;
|
||||
}
|
||||
|
||||
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);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = ");
|
||||
if (cell->type.in(ID($_NAND_), ID($_NOR_), ID($_XNOR_)))
|
||||
if (cell->type.in(TW($_NAND_), TW($_NOR_), TW($_XNOR_)))
|
||||
f << stringf("~(");
|
||||
dump_cell_expr_port(f, cell, "A", false);
|
||||
f << stringf(" ");
|
||||
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_)))
|
||||
if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_ANDNOT_)))
|
||||
f << stringf("&");
|
||||
if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_)))
|
||||
if (cell->type.in(TW($_OR_), TW($_NOR_), TW($_ORNOT_)))
|
||||
f << stringf("|");
|
||||
if (cell->type.in(ID($_XOR_), ID($_XNOR_)))
|
||||
if (cell->type.in(TW($_XOR_), TW($_XNOR_)))
|
||||
f << stringf("^");
|
||||
dump_attributes(f, "", cell->attributes, " ");
|
||||
f << stringf(" ");
|
||||
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
|
||||
f << stringf("~(");
|
||||
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(";\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_MUX_)) {
|
||||
if (cell->type == TW($_MUX_)) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = ");
|
||||
|
|
@ -1195,7 +1195,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_NMUX_)) {
|
||||
if (cell->type == TW($_NMUX_)) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = !(");
|
||||
|
|
@ -1209,14 +1209,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) {
|
||||
if (cell->type.in(TW($_AOI3_), TW($_OAI3_))) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = ~((");
|
||||
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);
|
||||
f << (cell->type == ID($_AOI3_) ? ") |" : ") &");
|
||||
f << (cell->type == TW($_AOI3_) ? ") |" : ") &");
|
||||
dump_attributes(f, "", cell->attributes, " ");
|
||||
f << stringf(" ");
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) {
|
||||
if (cell->type.in(TW($_AOI4_), TW($_OAI4_))) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, cell->getPort(TW::Y));
|
||||
f << stringf(" = ~((");
|
||||
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);
|
||||
f << (cell->type == ID($_AOI4_) ? ") |" : ") &");
|
||||
f << (cell->type == TW($_AOI4_) ? ") |" : ") &");
|
||||
dump_attributes(f, "", cell->attributes, " ");
|
||||
f << stringf(" (");
|
||||
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);
|
||||
f << stringf("));\n");
|
||||
return true;
|
||||
|
|
@ -1246,50 +1246,50 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
#define HANDLE_BINOP(_type, _operator) \
|
||||
if (cell->type ==_type) { dump_cell_expr_binop(f, indent, cell, _operator); return true; }
|
||||
|
||||
HANDLE_UNIOP(ID($not), "~")
|
||||
HANDLE_UNIOP(ID($pos), "+")
|
||||
HANDLE_UNIOP(ID($neg), "-")
|
||||
HANDLE_UNIOP(TW($not), "~")
|
||||
HANDLE_UNIOP(TW($pos), "+")
|
||||
HANDLE_UNIOP(TW($neg), "-")
|
||||
|
||||
HANDLE_BINOP(ID($and), "&")
|
||||
HANDLE_BINOP(ID($or), "|")
|
||||
HANDLE_BINOP(ID($xor), "^")
|
||||
HANDLE_BINOP(ID($xnor), "~^")
|
||||
HANDLE_BINOP(TW($and), "&")
|
||||
HANDLE_BINOP(TW($or), "|")
|
||||
HANDLE_BINOP(TW($xor), "^")
|
||||
HANDLE_BINOP(TW($xnor), "~^")
|
||||
|
||||
HANDLE_UNIOP(ID($reduce_and), "&")
|
||||
HANDLE_UNIOP(ID($reduce_or), "|")
|
||||
HANDLE_UNIOP(ID($reduce_xor), "^")
|
||||
HANDLE_UNIOP(ID($reduce_xnor), "~^")
|
||||
HANDLE_UNIOP(ID($reduce_bool), "|")
|
||||
HANDLE_UNIOP(TW($reduce_and), "&")
|
||||
HANDLE_UNIOP(TW($reduce_or), "|")
|
||||
HANDLE_UNIOP(TW($reduce_xor), "^")
|
||||
HANDLE_UNIOP(TW($reduce_xnor), "~^")
|
||||
HANDLE_UNIOP(TW($reduce_bool), "|")
|
||||
|
||||
HANDLE_BINOP(ID($shl), "<<")
|
||||
HANDLE_BINOP(ID($shr), ">>")
|
||||
HANDLE_BINOP(ID($sshl), "<<<")
|
||||
HANDLE_BINOP(ID($sshr), ">>>")
|
||||
HANDLE_BINOP(TW($shl), "<<")
|
||||
HANDLE_BINOP(TW($shr), ">>")
|
||||
HANDLE_BINOP(TW($sshl), "<<<")
|
||||
HANDLE_BINOP(TW($sshr), ">>>")
|
||||
|
||||
HANDLE_BINOP(ID($lt), "<")
|
||||
HANDLE_BINOP(ID($le), "<=")
|
||||
HANDLE_BINOP(ID($eq), "==")
|
||||
HANDLE_BINOP(ID($ne), "!=")
|
||||
HANDLE_BINOP(ID($eqx), "===")
|
||||
HANDLE_BINOP(ID($nex), "!==")
|
||||
HANDLE_BINOP(ID($ge), ">=")
|
||||
HANDLE_BINOP(ID($gt), ">")
|
||||
HANDLE_BINOP(TW($lt), "<")
|
||||
HANDLE_BINOP(TW($le), "<=")
|
||||
HANDLE_BINOP(TW($eq), "==")
|
||||
HANDLE_BINOP(TW($ne), "!=")
|
||||
HANDLE_BINOP(TW($eqx), "===")
|
||||
HANDLE_BINOP(TW($nex), "!==")
|
||||
HANDLE_BINOP(TW($ge), ">=")
|
||||
HANDLE_BINOP(TW($gt), ">")
|
||||
|
||||
HANDLE_BINOP(ID($add), "+")
|
||||
HANDLE_BINOP(ID($sub), "-")
|
||||
HANDLE_BINOP(ID($mul), "*")
|
||||
HANDLE_BINOP(ID($div), "/")
|
||||
HANDLE_BINOP(ID($mod), "%")
|
||||
HANDLE_BINOP(ID($pow), "**")
|
||||
HANDLE_BINOP(TW($add), "+")
|
||||
HANDLE_BINOP(TW($sub), "-")
|
||||
HANDLE_BINOP(TW($mul), "*")
|
||||
HANDLE_BINOP(TW($div), "/")
|
||||
HANDLE_BINOP(TW($mod), "%")
|
||||
HANDLE_BINOP(TW($pow), "**")
|
||||
|
||||
HANDLE_UNIOP(ID($logic_not), "!")
|
||||
HANDLE_BINOP(ID($logic_and), "&&")
|
||||
HANDLE_BINOP(ID($logic_or), "||")
|
||||
HANDLE_UNIOP(TW($logic_not), "!")
|
||||
HANDLE_BINOP(TW($logic_and), "&&")
|
||||
HANDLE_BINOP(TW($logic_or), "||")
|
||||
|
||||
#undef HANDLE_UNIOP
|
||||
#undef HANDLE_BINOP
|
||||
|
||||
if (cell->type == ID($divfloor))
|
||||
if (cell->type == TW($divfloor))
|
||||
{
|
||||
// wire [MAXLEN+1:0] _0_, _1_, _2_;
|
||||
// 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);
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($shiftx))
|
||||
if (cell->type == TW($shiftx))
|
||||
{
|
||||
std::string temp_id = next_auto_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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($mux))
|
||||
if (cell->type == TW($mux))
|
||||
{
|
||||
f << stringf("%s" "assign ", indent);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($pmux))
|
||||
if (cell->type == TW($pmux))
|
||||
{
|
||||
int width = cell->parameters[ID::WIDTH].as_int();
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($tribuf))
|
||||
if (cell->type == TW($tribuf))
|
||||
{
|
||||
f << stringf("%s" "assign ", indent);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($slice))
|
||||
if (cell->type == TW($slice))
|
||||
{
|
||||
f << stringf("%s" "assign ", indent);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($concat))
|
||||
if (cell->type == TW($concat))
|
||||
{
|
||||
f << stringf("%s" "assign ", indent);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($lut))
|
||||
if (cell->type == TW($lut))
|
||||
{
|
||||
f << stringf("%s" "assign ", indent);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (cell->type == ID($connect))
|
||||
if (cell->type == TW($connect))
|
||||
{
|
||||
int width = cell->getParam(ID::WIDTH).as_int() ;
|
||||
if (width == 1) {
|
||||
|
|
@ -1794,7 +1794,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
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" : " @*");
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($specify2), ID($specify3)))
|
||||
if (cell->type.in(TW($specify2), TW($specify3)))
|
||||
{
|
||||
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 << "(";
|
||||
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 ");
|
||||
|
||||
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::FULL).as_bool() ? "*> ": "=> ");
|
||||
|
||||
if (cell->type == ID($specify3)) {
|
||||
if (cell->type == TW($specify3)) {
|
||||
f << "(";
|
||||
dump_sigspec(f, cell->getPort(TW::DST));
|
||||
f << " ";
|
||||
|
|
@ -1862,7 +1862,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($specrule))
|
||||
if (cell->type == TW($specrule))
|
||||
{
|
||||
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 << ": ";
|
||||
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 << ", ";
|
||||
dump_const(f, cell->getParam(ID::T_LIMIT2_MIN));
|
||||
f << ": ";
|
||||
|
|
@ -1914,7 +1914,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($print))
|
||||
if (cell->type == TW($print))
|
||||
{
|
||||
// Sync $print cells are accumulated and handled in dump_module.
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($check))
|
||||
if (cell->type == TW($check))
|
||||
{
|
||||
// Sync $check cells are accumulated and handled in dump_module.
|
||||
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
|
||||
// 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.
|
||||
if (cell->type == ID($scopeinfo))
|
||||
if (cell->type == TW($scopeinfo))
|
||||
return;
|
||||
|
||||
// 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;
|
||||
dump_reg_init(ss, cell->getPort(TW::Q));
|
||||
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));
|
||||
f << stringf(") begin\n");
|
||||
|
||||
if (cell->type == ID($print)) {
|
||||
if (cell->type == TW($print)) {
|
||||
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();
|
||||
if (flavor == "assert" || flavor == "assume") {
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
|
||||
RTLIL::SigSpec sig = cell->getPort(TW::Q);
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ struct FunctionalDummyBackend : public Backend {
|
|||
|
||||
// write node functions
|
||||
for (auto node : ir)
|
||||
*f << " assign " << node.name().unescape()
|
||||
*f << " assign " << design->twines.unescaped_str(node.name())
|
||||
<< " = " << node.to_string() << "\n";
|
||||
*f << "\n";
|
||||
|
||||
// write outputs and next state
|
||||
for (auto output : ir.outputs())
|
||||
*f << " " << output->kind.unescape()
|
||||
<< " " << output->name.unescape()
|
||||
<< " = " << output->value().name().unescape() << "\n";
|
||||
*f << " " << design->twines.unescaped_str(output->kind)
|
||||
<< " " << design->twines.unescaped_str(output->name)
|
||||
<< " = " << design->twines.unescaped_str(output->value().name()) << "\n";
|
||||
for (auto state : ir.states())
|
||||
*f << " " << state->kind.unescape()
|
||||
<< " " << state->name.unescape()
|
||||
<< " = " << state->next_value().name().unescape() << "\n";
|
||||
*f << " " << design->twines.unescaped_str(state->kind)
|
||||
<< " " << design->twines.unescaped_str(state->name)
|
||||
<< " = " << design->twines.unescaped_str(state->next_value().name()) << "\n";
|
||||
}
|
||||
}
|
||||
} FunctionalDummyBackend;
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ struct ConstEvalAig
|
|||
ConstEvalAig(RTLIL::Module *module) : module(module)
|
||||
{
|
||||
for (auto &it : module->cells_) {
|
||||
if (!yosys_celltypes.cell_known(it.second->type))
|
||||
if (!yosys_celltypes.cell_known(it.second->type.ref()))
|
||||
continue;
|
||||
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));
|
||||
log_assert(r.second);
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ struct ConstEvalAig
|
|||
if (!inputs.count(sig_a))
|
||||
compute_deps(sig_a, inputs);
|
||||
|
||||
if (cell->type == ID($_AND_)) {
|
||||
if (cell->type == TW($_AND_)) {
|
||||
RTLIL::SigSpec sig_b = cell->getPort(TW::B);
|
||||
sig2deps[sig_b].reserve(sig2deps[sig_b].size() + sig2deps[output].size()); // Reserve so that any invalidation
|
||||
// that may occur does so here, and
|
||||
|
|
@ -148,7 +148,7 @@ struct ConstEvalAig
|
|||
if (!inputs.count(sig_b))
|
||||
compute_deps(sig_b, inputs);
|
||||
}
|
||||
else if (cell->type == ID($_NOT_)) {
|
||||
else if (cell->type == TW($_NOT_)) {
|
||||
}
|
||||
else log_abort();
|
||||
}
|
||||
|
|
@ -164,11 +164,11 @@ struct ConstEvalAig
|
|||
return false;
|
||||
|
||||
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;
|
||||
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) {
|
||||
eval_ret = State::S0;
|
||||
goto eval_end;
|
||||
|
|
@ -504,7 +504,8 @@ void AigerReader::parse_xaiger()
|
|||
uint32_t boxUniqueId = parse_xaiger_literal(f);
|
||||
log_assert(boxUniqueId > 0);
|
||||
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::O, SigSpec(State::S0, boxOutputs));
|
||||
cell->attributes[ID::abc9_box_seq] = oldBoxNum;
|
||||
|
|
@ -836,7 +837,7 @@ void AigerReader::post_process()
|
|||
wire->port_input = false;
|
||||
module->connect(wire, existing);
|
||||
}
|
||||
log_debug(" -> %s\n", escaped_s.unescape());
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s));
|
||||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
|
|
@ -847,7 +848,7 @@ void AigerReader::post_process()
|
|||
module->connect(wire, existing);
|
||||
wire->port_input = false;
|
||||
}
|
||||
log_debug(" -> %s\n", indexed_name.unescape());
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name));
|
||||
}
|
||||
|
||||
if (wideports && !existing) {
|
||||
|
|
@ -883,7 +884,7 @@ void AigerReader::post_process()
|
|||
module->connect(wire, existing);
|
||||
wire = existing;
|
||||
}
|
||||
log_debug(" -> %s\n", escaped_s.unescape());
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s));
|
||||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
|
|
@ -895,7 +896,7 @@ void AigerReader::post_process()
|
|||
existing->port_output = true;
|
||||
module->connect(wire, existing);
|
||||
}
|
||||
log_debug(" -> %s\n", indexed_name.unescape());
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name));
|
||||
}
|
||||
|
||||
if (wideports && !existing) {
|
||||
|
|
@ -913,7 +914,7 @@ void AigerReader::post_process()
|
|||
else if (type == "box") {
|
||||
RTLIL::Cell* cell = module->cell(design->twines.lookup(stringf("$box%d", variable)));
|
||||
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
|
||||
module->rename(cell, design->twines.add(Twine{escaped_s.str()}));
|
||||
}
|
||||
|
|
@ -977,7 +978,7 @@ void AigerReader::post_process()
|
|||
design->add(module);
|
||||
|
||||
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();
|
||||
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())}));
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ uint32_t read_be32(std::istream &f) {
|
|||
((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::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)
|
||||
{
|
||||
IdString module_name;
|
||||
std::optional<TwineRef> module_name;
|
||||
TwineSearch search(&design->twines);
|
||||
std::string map_filename;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 2; argidx < args.size(); argidx++) {
|
||||
std::string arg = args[argidx];
|
||||
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;
|
||||
}
|
||||
if (arg == "-map2" && argidx + 1 < args.size()) {
|
||||
|
|
@ -81,12 +82,12 @@ struct Xaiger2Frontend : public Frontend {
|
|||
|
||||
if (map_filename.empty())
|
||||
log_error("A '-map2' argument is required\n");
|
||||
if (module_name.empty())
|
||||
if (!module_name)
|
||||
log_error("A '-module_name' argument is required\n");
|
||||
|
||||
Module *module = design->module(module_name);
|
||||
Module *module = design->module(*module_name);
|
||||
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;
|
||||
map_file.open(map_filename);
|
||||
|
|
@ -122,7 +123,6 @@ struct Xaiger2Frontend : public Frontend {
|
|||
bits[1] = RTLIL::S1;
|
||||
|
||||
std::string type;
|
||||
TwineSearch search(&design->twines);
|
||||
while (map_file >> type) {
|
||||
if (type == "pi") {
|
||||
int pi_idx;
|
||||
|
|
@ -159,7 +159,7 @@ struct Xaiger2Frontend : public Frontend {
|
|||
}
|
||||
|
||||
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()) {
|
||||
boxes.resize(box_seq + 1);
|
||||
|
|
@ -265,22 +265,22 @@ struct Xaiger2Frontend : public Frontend {
|
|||
|
||||
struct MappingCell {
|
||||
TwineRef type;
|
||||
RTLIL::IdString out;
|
||||
std::vector<TwineRef ins;
|
||||
TwineRef out;
|
||||
std::vector<TwineRef> ins;
|
||||
};
|
||||
std::vector<MappingCell> cells;
|
||||
cells.resize(no_cells);
|
||||
|
||||
for (unsigned i = 0; i < no_cells; ++i) {
|
||||
auto &cell = cells[i];
|
||||
cell.type = read_idstring(*f);
|
||||
cell.out = read_idstring(*f);
|
||||
cell.type = design->twines.add(Twine{read_idstring(*f)});
|
||||
cell.out = design->twines.add(Twine{read_idstring(*f)});
|
||||
uint32_t nins = read_be32(*f);
|
||||
for (uint32_t j = 0; j < nins; j++)
|
||||
cell.ins.push_back(read_idstring(*f));
|
||||
log_debug("M: Cell %s (out %s, ins", cell.type.unescape(), cell.out.unescape());
|
||||
cell.ins.push_back(design->twines.add(Twine{read_idstring(*f)}));
|
||||
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)
|
||||
log_debug(" %s", in.unescape());
|
||||
log_debug(" %s", design->twines.str(in).c_str());
|
||||
log_debug(")\n");
|
||||
}
|
||||
|
||||
|
|
@ -294,13 +294,13 @@ struct Xaiger2Frontend : public Frontend {
|
|||
auto &cell = cells[cell_id];
|
||||
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)})));
|
||||
instance->setPort(design->twines.add(Twine{cell.out.str()}), out_w);
|
||||
instance->setPort(cell.out, out_w);
|
||||
bits[out_lit] = out_w;
|
||||
for (auto in : cell.ins) {
|
||||
uint32_t in_lit = read_be32(*f);
|
||||
log_assert(out_lit < bits.size());
|
||||
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') {
|
||||
|
|
|
|||
|
|
@ -1573,7 +1573,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule
|
|||
for (auto w : intfmodule->wires()){
|
||||
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)));
|
||||
std::string origname = w->name.unescape();
|
||||
std::string origname = intfmodule->design->twines.unescaped_str(w->meta_->name);
|
||||
std::string newname = intfname + "." + origname;
|
||||
wire->str = newname;
|
||||
if (modport != NULL) {
|
||||
|
|
@ -1637,7 +1637,7 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdStr
|
|||
RTLIL::Module *intfmodule = intf.second;
|
||||
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)));
|
||||
std::string newname = w->name.unescape();
|
||||
std::string newname = design->twines.unescaped_str(w->meta_->name);
|
||||
newname = intfname + "." + newname;
|
||||
wire->str = newname;
|
||||
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
|
||||
// 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> ¶meters, 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> ¶meters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool /*mayfail*/)
|
||||
{
|
||||
std::unique_ptr<AstNode> new_ast = NULL;
|
||||
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:
|
||||
for(auto &intf : interfaces) {
|
||||
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:
|
||||
AstNode *modport = NULL;
|
||||
if (modports.count(intfname) > 0) {
|
||||
std::string interface_modport = modports.at(intfname).str();
|
||||
if (modports.count(intf.first) > 0) {
|
||||
std::string interface_modport = design->twines.str(modports.at(intf.first));
|
||||
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
|
||||
AstNode *ast_node_of_interface = ast_module_of_interface->ast.get();
|
||||
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.
|
||||
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) {
|
||||
// Normally, removing wires would be batched together as it's an
|
||||
// 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();
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/)
|
||||
TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return modname;
|
||||
return design->twines.add(Twine{modname});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
dst->add(new_mod);
|
||||
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ namespace AST
|
|||
std::unique_ptr<AstNode> ast;
|
||||
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
|
||||
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
||||
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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> ¶meters, 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> ¶meters, 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;
|
||||
bool reprocess_if_necessary(RTLIL::Design *design) override;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "kernel/log.h"
|
||||
#include "kernel/twine.h"
|
||||
#include "kernel/utils.h"
|
||||
#include "kernel/binding.h"
|
||||
#include "libs/sha1/sha1.h"
|
||||
|
|
@ -43,13 +44,13 @@ using namespace AST;
|
|||
using namespace AST_INTERNAL;
|
||||
|
||||
// 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++);
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
|
||||
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);
|
||||
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++);
|
||||
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);
|
||||
|
||||
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
|
||||
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++);
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
|
||||
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);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
|
|
@ -140,7 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
|
|||
std::stringstream sstr;
|
||||
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);
|
||||
|
||||
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::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);
|
||||
cell->setParam(ID::TRG_WIDTH, triggers.size());
|
||||
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::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);
|
||||
cell->set_bool_attribute(ID(keep));
|
||||
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
|
||||
// cases this variable is used to hold the type of the cell that should
|
||||
// be instantiated for this type of AST node.
|
||||
IdString type_name;
|
||||
TwineRef type_name;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -1735,7 +1736,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
}
|
||||
if (GetSize(shift_val) >= 32)
|
||||
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;
|
||||
} else {
|
||||
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");
|
||||
|
||||
// generate cells for unary operations: $not, $pos, $neg
|
||||
if (0) { case AST_BIT_NOT: type_name = ID($not); }
|
||||
if (0) { case AST_POS: type_name = ID($pos); }
|
||||
if (0) { case AST_NEG: type_name = ID($neg); }
|
||||
if (0) { case AST_BIT_NOT: type_name = TW($not); }
|
||||
if (0) { case AST_POS: type_name = TW($pos); }
|
||||
if (0) { case AST_NEG: type_name = TW($neg); }
|
||||
{
|
||||
RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint);
|
||||
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
|
||||
if (0) { case AST_BIT_AND: type_name = ID($and); }
|
||||
if (0) { case AST_BIT_OR: type_name = ID($or); }
|
||||
if (0) { case AST_BIT_XOR: type_name = ID($xor); }
|
||||
if (0) { case AST_BIT_XNOR: type_name = ID($xnor); }
|
||||
if (0) { case AST_BIT_AND: type_name = TW($and); }
|
||||
if (0) { case AST_BIT_OR: type_name = TW($or); }
|
||||
if (0) { case AST_BIT_XOR: type_name = TW($xor); }
|
||||
if (0) { case AST_BIT_XNOR: type_name = TW($xnor); }
|
||||
{
|
||||
if (width_hint < 0)
|
||||
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
|
||||
if (0) { case AST_REDUCE_AND: type_name = ID($reduce_and); }
|
||||
if (0) { case AST_REDUCE_OR: type_name = ID($reduce_or); }
|
||||
if (0) { case AST_REDUCE_XOR: type_name = ID($reduce_xor); }
|
||||
if (0) { case AST_REDUCE_XNOR: type_name = ID($reduce_xnor); }
|
||||
if (0) { case AST_REDUCE_AND: type_name = TW($reduce_and); }
|
||||
if (0) { case AST_REDUCE_OR: type_name = TW($reduce_or); }
|
||||
if (0) { case AST_REDUCE_XOR: type_name = TW($reduce_xor); }
|
||||
if (0) { case AST_REDUCE_XNOR: type_name = TW($reduce_xnor); }
|
||||
{
|
||||
RTLIL::SigSpec arg = children[0]->genRTLIL();
|
||||
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
|
||||
// (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 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
|
||||
if (0) { case AST_SHIFT_LEFT: type_name = ID($shl); }
|
||||
if (0) { case AST_SHIFT_RIGHT: type_name = ID($shr); }
|
||||
if (0) { case AST_SHIFT_SLEFT: type_name = ID($sshl); }
|
||||
if (0) { case AST_SHIFT_SRIGHT: type_name = ID($sshr); }
|
||||
if (0) { case AST_SHIFTX: type_name = ID($shiftx); }
|
||||
if (0) { case AST_SHIFT: type_name = ID($shift); }
|
||||
if (0) { case AST_SHIFT_LEFT: type_name = TW($shl); }
|
||||
if (0) { case AST_SHIFT_RIGHT: type_name = TW($shr); }
|
||||
if (0) { case AST_SHIFT_SLEFT: type_name = TW($sshl); }
|
||||
if (0) { case AST_SHIFT_SRIGHT: type_name = TW($sshr); }
|
||||
if (0) { case AST_SHIFTX: type_name = TW($shiftx); }
|
||||
if (0) { case AST_SHIFT: type_name = TW($shift); }
|
||||
{
|
||||
if (width_hint < 0)
|
||||
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();
|
||||
is_signed = children[0]->is_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, ID($pow), width, left, right);
|
||||
return binop2rtlil(this, TW($shl), width, RTLIL::SigSpec(1, left.size()), right);
|
||||
return binop2rtlil(this, TW($pow), width, left, right);
|
||||
}
|
||||
|
||||
// generate cells for binary operations: $lt, $le, $eq, $ne, $ge, $gt
|
||||
if (0) { case AST_LT: type_name = ID($lt); }
|
||||
if (0) { case AST_LE: type_name = ID($le); }
|
||||
if (0) { case AST_EQ: type_name = ID($eq); }
|
||||
if (0) { case AST_NE: type_name = ID($ne); }
|
||||
if (0) { case AST_EQX: type_name = ID($eqx); }
|
||||
if (0) { case AST_NEX: type_name = ID($nex); }
|
||||
if (0) { case AST_GE: type_name = ID($ge); }
|
||||
if (0) { case AST_GT: type_name = ID($gt); }
|
||||
if (0) { case AST_LT: type_name = TW($lt); }
|
||||
if (0) { case AST_LE: type_name = TW($le); }
|
||||
if (0) { case AST_EQ: type_name = TW($eq); }
|
||||
if (0) { case AST_NE: type_name = TW($ne); }
|
||||
if (0) { case AST_EQX: type_name = TW($eqx); }
|
||||
if (0) { case AST_NEX: type_name = TW($nex); }
|
||||
if (0) { case AST_GE: type_name = TW($ge); }
|
||||
if (0) { case AST_GT: type_name = TW($gt); }
|
||||
{
|
||||
int width = max(width_hint, 1);
|
||||
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
|
||||
if (0) { case AST_ADD: type_name = ID($add); }
|
||||
if (0) { case AST_SUB: type_name = ID($sub); }
|
||||
if (0) { case AST_MUL: type_name = ID($mul); }
|
||||
if (0) { case AST_DIV: type_name = ID($div); }
|
||||
if (0) { case AST_MOD: type_name = ID($mod); }
|
||||
if (0) { case AST_ADD: type_name = TW($add); }
|
||||
if (0) { case AST_SUB: type_name = TW($sub); }
|
||||
if (0) { case AST_MUL: type_name = TW($mul); }
|
||||
if (0) { case AST_DIV: type_name = TW($div); }
|
||||
if (0) { case AST_MOD: type_name = TW($mod); }
|
||||
{
|
||||
if (width_hint < 0)
|
||||
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
|
||||
if (0) { case AST_LOGIC_AND: type_name = ID($logic_and); }
|
||||
if (0) { case AST_LOGIC_OR: type_name = ID($logic_or); }
|
||||
if (0) { case AST_LOGIC_AND: type_name = TW($logic_and); }
|
||||
if (0) { case AST_LOGIC_OR: type_name = TW($logic_or); }
|
||||
{
|
||||
RTLIL::SigSpec left = children[0]->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:
|
||||
{
|
||||
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)
|
||||
|
|
@ -2021,7 +2022,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
|
||||
|
||||
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());
|
||||
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;
|
||||
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);
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
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);
|
||||
for (auto &attr : attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
|
|
@ -2185,7 +2186,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
RTLIL::IdString id = str;
|
||||
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);
|
||||
|
||||
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();
|
||||
if (value->type == AST_REALVALUE)
|
||||
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)
|
||||
input_error("Parameter %s.%s with non-constant value!\n",
|
||||
cell, paraname.unescape());
|
||||
cell, design->twines.unescaped_str(paraname));
|
||||
cell->parameters[paraname] = value->asParaConst();
|
||||
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);
|
||||
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 dst_width = GetSize(cell->getPort(TW::DST));
|
||||
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::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 dst_width = GetSize(cell->getPort(TW::DST));
|
||||
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::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 dst_width = GetSize(cell->getPort(TW::DST));
|
||||
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)
|
||||
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);
|
||||
cell->parameters[ID::WIDTH] = width;
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
vector<Cell*> remove_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));
|
||||
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()) {
|
||||
cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q));
|
||||
} 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::Q, blif_wire(q));
|
||||
}
|
||||
|
|
@ -400,7 +400,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
goto error;
|
||||
|
||||
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);
|
||||
|
||||
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:
|
||||
if (state == RTLIL::State::Sa)
|
||||
state = RTLIL::State::S0;
|
||||
if (output_sig.as_wire()->name == ID($undef))
|
||||
if (output_sig.as_wire()->name == TW($undef))
|
||||
state = RTLIL::State::Sx;
|
||||
module->connect(RTLIL::SigSig(output_sig, state));
|
||||
goto continue_without_read;
|
||||
|
|
@ -550,7 +550,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
|
||||
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::DEPTH] = 0;
|
||||
sopcell->parameters[ID::TABLE] = RTLIL::Const();
|
||||
|
|
@ -566,7 +566,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
}
|
||||
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::LUT] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
|
||||
cell->setPort(TW::A, input_sig);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
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)
|
||||
log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape());
|
||||
|
|
|
|||
|
|
@ -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::Cell *cell = module->addCell(NEW_TWINE, ID($tribuf));
|
||||
RTLIL::Cell *cell = module->addCell(NEW_TWINE, TW::$tribuf);
|
||||
cell->setParam(ID::WIDTH, GetSize(func));
|
||||
cell->setPort(TW::A, func);
|
||||
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;
|
||||
|
||||
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_polarity = !clk_polarity;
|
||||
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_polarity = !clear_polarity;
|
||||
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_polarity = !preset_polarity;
|
||||
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);
|
||||
}
|
||||
|
||||
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::Q, q_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;
|
||||
|
||||
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_polarity = !enable_polarity;
|
||||
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_polarity = !clear_polarity;
|
||||
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_polarity = !preset_polarity;
|
||||
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::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)
|
||||
{
|
||||
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::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);
|
||||
}
|
||||
|
||||
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::B, clear_negative);
|
||||
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::B, clear_enable);
|
||||
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)
|
||||
{
|
||||
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::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);
|
||||
}
|
||||
|
||||
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::B, preset_positive);
|
||||
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::B, preset_enable);
|
||||
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::Q, iq_sig);
|
||||
cell->setPort(TW::E, enable_sig);
|
||||
|
|
@ -798,7 +799,7 @@ struct LibertyFrontend : public Frontend {
|
|||
if (wi->port_input) {
|
||||
for (auto wo : module->wires())
|
||||
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::DST_WIDTH, wo->width);
|
||||
spec->setParam(ID::T_FALL_MAX, 1000);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ struct RpcServer {
|
|||
struct RpcModule : RTLIL::Module {
|
||||
std::shared_ptr<RpcServer> server;
|
||||
|
||||
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) override {
|
||||
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) override {
|
||||
std::string stripped_name = design->twines.str(meta_->name);
|
||||
if (stripped_name.compare(0, 9, "$abstract") == 0)
|
||||
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);
|
||||
|
||||
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);
|
||||
if (!t->has_attribute(ID::hdlname))
|
||||
t->set_string_attribute(ID::hdlname, original_name.str());
|
||||
|
|
@ -224,7 +224,7 @@ struct RpcModule : RTLIL::Module {
|
|||
delete derived_design;
|
||||
}
|
||||
|
||||
return derived_name;
|
||||
return design->twines.add(Twine{derived_name});
|
||||
}
|
||||
|
||||
RTLIL::Module *clone() const override {
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ struct RTLILFrontendWorker {
|
|||
error("No wires found for legalization");
|
||||
int hash = hash_ops<RTLIL::IdString>::hash(id).yield();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -748,7 +748,7 @@ struct RTLILFrontendWorker {
|
|||
} else
|
||||
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));
|
||||
|
||||
while (true)
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
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);
|
||||
}
|
||||
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++) {
|
||||
int A = mk.inport(TW::A, i);
|
||||
int B = mk.inport(TW::B, i);
|
||||
int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) :
|
||||
cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) :
|
||||
cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) :
|
||||
cell->type.in(ID($_NOR_)) ? mk.nor_gate(A, B) :
|
||||
cell->type.in(ID($xor), ID($_XOR_)) ? mk.xor_gate(A, B) :
|
||||
cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) :
|
||||
cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) :
|
||||
cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
|
||||
int Y = cell->type.in(TW($and), TW($_AND_)) ? mk.and_gate(A, B) :
|
||||
cell->type.in(TW($_NAND_)) ? mk.nand_gate(A, B) :
|
||||
cell->type.in(TW($or), TW($_OR_)) ? mk.or_gate(A, B) :
|
||||
cell->type.in(TW($_NOR_)) ? mk.nor_gate(A, B) :
|
||||
cell->type.in(TW($xor), TW($_XOR_)) ? mk.xor_gate(A, B) :
|
||||
cell->type.in(TW($xnor), TW($_XNOR_)) ? mk.xnor_gate(A, B) :
|
||||
cell->type.in(TW($_ANDNOT_)) ? mk.andnot_gate(A, B) :
|
||||
cell->type.in(TW($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
|
||||
mk.outport(Y, TW::Y, i);
|
||||
}
|
||||
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);
|
||||
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
|
||||
int A = mk.inport(TW::A, i);
|
||||
int B = mk.inport(TW::B, i);
|
||||
int Y = mk.mux_gate(A, B, S);
|
||||
if (cell->type == ID($_NMUX_))
|
||||
if (cell->type == TW($_NMUX_))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport(Y, TW::Y, i);
|
||||
}
|
||||
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);
|
||||
for (int i = 1; i < GetSize(cell->getPort(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 == ID($reduce_or)) Y = mk.or_gate(A, Y);
|
||||
if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y);
|
||||
if (cell->type == ID($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_and)) Y = mk.and_gate(A, Y);
|
||||
if (cell->type == TW($reduce_or)) Y = mk.or_gate(A, Y);
|
||||
if (cell->type == TW($reduce_bool)) Y = mk.or_gate(A, Y);
|
||||
if (cell->type == TW($reduce_xor)) 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);
|
||||
mk.outport(Y, TW::Y, 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
|
||||
|
|
@ -363,31 +363,31 @@ Aig::Aig(Cell *cell)
|
|||
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;
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++)
|
||||
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);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++)
|
||||
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 == ID($logic_or)) Y = mk.or_gate(A, B);
|
||||
if (cell->type == TW($logic_and)) Y = mk.and_gate(A, B);
|
||||
if (cell->type == TW($logic_or)) Y = mk.or_gate(A, B);
|
||||
} 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);
|
||||
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));
|
||||
vector<int> A = mk.inport_vec(TW::A, width);
|
||||
vector<int> B = mk.inport_vec(TW::B, width);
|
||||
int carry = mk.bool_node(false);
|
||||
if (cell->type == ID($sub)) {
|
||||
if (cell->type == TW($sub)) {
|
||||
for (auto &n : B)
|
||||
n = mk.not_gate(n);
|
||||
carry = mk.not_gate(carry);
|
||||
|
|
@ -397,17 +397,17 @@ Aig::Aig(Cell *cell)
|
|||
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)),
|
||||
GetSize(cell->getPort(TW::B))) + 1;
|
||||
vector<int> A = mk.inport_vec(TW::A, 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);
|
||||
|
||||
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)
|
||||
n = mk.not_gate(n);
|
||||
vector<int> Y = mk.adder(A, B, carry);
|
||||
|
|
@ -417,7 +417,7 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($alu))
|
||||
if (cell->type == TW($alu))
|
||||
{
|
||||
int width = GetSize(cell->getPort(TW::Y));
|
||||
vector<int> A = mk.inport_vec(TW::A, width);
|
||||
|
|
@ -436,7 +436,7 @@ Aig::Aig(Cell *cell)
|
|||
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)));
|
||||
vector<int> A = mk.inport_vec(TW::A, width);
|
||||
|
|
@ -444,13 +444,13 @@ Aig::Aig(Cell *cell)
|
|||
int Y = mk.bool_node(false);
|
||||
for (int i = 0; i < width; 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);
|
||||
mk.outport_bool(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI3_))
|
||||
if (cell->type == TW($_AOI3_))
|
||||
{
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
|
|
@ -460,7 +460,7 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_OAI3_))
|
||||
if (cell->type == TW($_OAI3_))
|
||||
{
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
|
|
@ -470,7 +470,7 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI4_))
|
||||
if (cell->type == TW($_AOI4_))
|
||||
{
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
|
|
@ -482,7 +482,7 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_OAI4_))
|
||||
if (cell->type == TW($_OAI4_))
|
||||
{
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
|
||||
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 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 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)
|
||||
a_width = b_width;
|
||||
else
|
||||
|
|
@ -86,7 +86,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int b_width = GetSize(cell->getPort(TW::B));
|
||||
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);
|
||||
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]
|
||||
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;
|
||||
if (is_signed) b_range_upper -= 1;
|
||||
a_range_lower = max(0, i - b_high);
|
||||
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;
|
||||
a_range_lower = min(i, a_width - 1);
|
||||
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
|
||||
// 2's complement range is different depending on direction
|
||||
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++) {
|
||||
// left shifts
|
||||
if (cell->type.in(ID($shl), ID($sshl))) {
|
||||
if (cell->type.in(TW($shl), TW($sshl))) {
|
||||
if (a_width == 1 && is_signed) {
|
||||
int skip = 1 << (k + 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);
|
||||
}
|
||||
// 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) {
|
||||
bool shift_in_bulk = i < a_width - 1;
|
||||
// can we jump into the zero-padding by toggling B[k]?
|
||||
bool zpad_jump = (((y_width - i) & ((1 << (k + 1)) - 1)) != 0 \
|
||||
&& (((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);
|
||||
} else {
|
||||
if (i < a_width)
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
}
|
||||
// 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 (k != b_width_capped - 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)
|
||||
{
|
||||
log_assert(cell->type == ID($mem_v2));
|
||||
log_assert(cell->type == TW($mem_v2));
|
||||
Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
|
||||
int n_rd_ports = cell->getParam(ID::RD_PORTS).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)
|
||||
{
|
||||
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 width = cell->getParam(ID::WIDTH).as_int();
|
||||
|
||||
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++)
|
||||
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)
|
||||
{
|
||||
if (cell->type == ID($mem_v2))
|
||||
if (cell->type == TW($mem_v2))
|
||||
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);
|
||||
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 */
|
||||
else
|
||||
log_abort();
|
||||
|
|
@ -399,7 +399,7 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
{
|
||||
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++) {
|
||||
db->add_edge(cell, TW::D, k, 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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($neg)) {
|
||||
if (cell->type == TW($neg)) {
|
||||
arith_neg_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($add), ID($sub))) {
|
||||
if (cell->type.in(TW($add), TW($sub))) {
|
||||
arith_binary_op(this, cell);
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($slice)) {
|
||||
if (cell->type == TW($slice)) {
|
||||
slice_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($concat)) {
|
||||
if (cell->type == TW($concat)) {
|
||||
concat_op(this, cell);
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($mux), ID($pmux))) {
|
||||
if (cell->type.in(TW($mux), TW($pmux))) {
|
||||
mux_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($bmux)) {
|
||||
if (cell->type == TW($bmux)) {
|
||||
bmux_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($demux)) {
|
||||
if (cell->type == TW($demux)) {
|
||||
demux_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($bweqx)) {
|
||||
if (cell->type == TW($bweqx)) {
|
||||
bweqx_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($bwmux)) {
|
||||
if (cell->type == TW($bwmux)) {
|
||||
bwmux_op(this, cell);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -570,21 +570,21 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
|
|||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(
|
||||
ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
|
||||
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
|
||||
ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_),
|
||||
ID($_OAI4_), ID($_TBUF_))) {
|
||||
TW($_BUF_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
|
||||
TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_), TW($_MUX_), TW($_NMUX_),
|
||||
TW($_MUX4_), TW($_MUX8_), TW($_MUX16_), TW($_AOI3_), TW($_OAI3_), TW($_AOI4_),
|
||||
TW($_OAI4_), TW($_TBUF_))) {
|
||||
full_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -592,7 +592,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
|
|||
// FIXME: $specify2 $specify3 $specrule ???
|
||||
// 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 false;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ struct CellTypes
|
|||
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)
|
||||
{
|
||||
pool<TwineRef> inputs, outputs;
|
||||
|
|
@ -230,77 +235,77 @@ struct CellTypes
|
|||
|
||||
for (auto c1 : 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});
|
||||
|
||||
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 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 c2 : list_np)
|
||||
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 c2 : list_np)
|
||||
for (auto c3 : list_01)
|
||||
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 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 c2 : 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 c2 : 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 c2 : list_np)
|
||||
for (auto c3 : 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 c2 : list_np)
|
||||
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 c2 : list_np)
|
||||
for (auto c3 : list_01)
|
||||
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 c2 : list_np)
|
||||
for (auto c3 : list_01)
|
||||
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)
|
||||
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 c2 : list_np)
|
||||
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 c2 : 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()
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ struct ConstEval
|
|||
ct.static_cell_types = StaticCellTypes::Compat::nomem_noff;
|
||||
|
||||
for (auto &it : module->cells_) {
|
||||
if (!ct.cell_known(it.second->type))
|
||||
if (!ct.cell_known(it.second->type_impl))
|
||||
continue;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ struct ConstEval
|
|||
|
||||
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_g = cell->getPort(TW::G);
|
||||
|
|
@ -147,7 +147,7 @@ struct ConstEval
|
|||
if (cell->hasPort(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;
|
||||
int count_set_s_bits = 0;
|
||||
|
|
@ -176,7 +176,7 @@ struct ConstEval
|
|||
for (auto &yc : y_candidates) {
|
||||
if (!eval(yc, undef, cell))
|
||||
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)));
|
||||
else
|
||||
y_values.push_back(yc.as_const());
|
||||
|
|
@ -199,7 +199,7 @@ struct ConstEval
|
|||
else
|
||||
set(sig_y, y_values.front());
|
||||
}
|
||||
else if (cell->type == ID($bmux))
|
||||
else if (cell->type == TW($bmux))
|
||||
{
|
||||
if (!eval(sig_s, undef, cell))
|
||||
return false;
|
||||
|
|
@ -217,7 +217,7 @@ struct ConstEval
|
|||
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))
|
||||
return false;
|
||||
|
|
@ -229,7 +229,7 @@ struct ConstEval
|
|||
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_x = cell->getPort(TW::X);
|
||||
|
|
@ -258,7 +258,7 @@ struct ConstEval
|
|||
set(sig_y, val_y);
|
||||
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_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.from_cell(cell);
|
||||
|
|
@ -336,7 +336,7 @@ struct ConstEval
|
|||
{
|
||||
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))
|
||||
sig_c = cell->getPort(TW::C);
|
||||
if (cell->hasPort(TW::D))
|
||||
|
|
|
|||
|
|
@ -22,24 +22,24 @@ static unsigned int y_coef(TwineRef type)
|
|||
{
|
||||
if (
|
||||
// equality
|
||||
type.in(ID($bweqx), ID($nex), ID($eqx)) ||
|
||||
type.in(TW($bweqx), TW($nex), TW($eqx)) ||
|
||||
// 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
|
||||
type.in(ID($bwmux), ID($mux)) ||
|
||||
type.in(TW($bwmux), TW($mux)) ||
|
||||
// others
|
||||
type == ID($tribuf)) {
|
||||
type == TW($tribuf)) {
|
||||
return 1;
|
||||
} else if (type == ID($neg)) {
|
||||
} else if (type == TW($neg)) {
|
||||
return 4;
|
||||
} else if (type == ID($demux)) {
|
||||
} else if (type == TW($demux)) {
|
||||
return 2;
|
||||
} else if (type == ID($fa)) {
|
||||
} else if (type == TW($fa)) {
|
||||
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
|
||||
return 8;
|
||||
} else if (type.in(ID($shl), ID($sshl))) {
|
||||
} else if (type.in(TW($shl), TW($sshl))) {
|
||||
// left shift
|
||||
return 10;
|
||||
}
|
||||
|
|
@ -50,19 +50,19 @@ static unsigned int max_inp_coef(TwineRef type)
|
|||
{
|
||||
if (
|
||||
// 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
|
||||
type.in(ID($logic_not), ID($pmux), ID($bmux))) {
|
||||
type.in(TW($logic_not), TW($pmux), TW($bmux))) {
|
||||
return 1;
|
||||
} else if (
|
||||
// equality
|
||||
type.in(ID($eq), ID($ne)) ||
|
||||
type.in(TW($eq), TW($ne)) ||
|
||||
// logic
|
||||
type.in(ID($logic_and), ID($logic_or))) {
|
||||
type.in(TW($logic_and), TW($logic_or))) {
|
||||
return 2;
|
||||
} else if (type == ID($lcu)) {
|
||||
} else if (type == TW($lcu)) {
|
||||
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
|
||||
return 7;
|
||||
}
|
||||
|
|
@ -71,10 +71,10 @@ static unsigned int max_inp_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
|
||||
return 4;
|
||||
} else if (type.in(ID($shift), ID($shiftx))) {
|
||||
} else if (type.in(TW($shift), TW($shiftx))) {
|
||||
// shift
|
||||
return 8;
|
||||
}
|
||||
|
|
@ -83,23 +83,23 @@ static unsigned int sum_coef(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)
|
||||
{
|
||||
return (
|
||||
// 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
|
||||
type.in(ID($check), ID($equiv), ID($initstate), ID($assert), ID($assume), ID($live), ID($cover), ID($fair)) ||
|
||||
type.in(ID($allseq), ID($allconst), ID($anyseq), ID($anyconst), ID($anyinit)) ||
|
||||
type.in(TW($check), TW($equiv), TW($initstate), TW($assert), TW($assume), TW($live), TW($cover), TW($fair)) ||
|
||||
type.in(TW($allseq), TW($allconst), TW($anyseq), TW($anyconst), TW($anyinit)) ||
|
||||
// utilities
|
||||
type.in(ID($scopeinfo), ID($print)) ||
|
||||
type.in(TW($scopeinfo), TW($print)) ||
|
||||
// real but free
|
||||
type.in(ID($concat), ID($slice), ID($pos)) ||
|
||||
type.in(TW($concat), TW($slice), TW($pos)) ||
|
||||
// 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)
|
||||
|
|
@ -112,7 +112,7 @@ unsigned int max_inp_width(RTLIL::Cell *cell)
|
|||
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();
|
||||
|
||||
for (RTLIL::IdString param : input_width_params)
|
||||
|
|
@ -139,7 +139,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
{
|
||||
|
||||
// simple 1-bit cells
|
||||
if (cmos_gate_cost().count(cell->type))
|
||||
if (cmos_gate_cost().count(cell->type_impl))
|
||||
return 1;
|
||||
|
||||
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_debug("%s is ff\n", cell->name);
|
||||
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);
|
||||
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
|
||||
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;
|
||||
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();
|
||||
log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type));
|
||||
return width * y_coef(cell->type);
|
||||
} else if (sum_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.ref());
|
||||
} else if (sum_coef(cell->type.ref())) {
|
||||
// linear with sum of port widths
|
||||
unsigned int sum = port_width_sum(cell);
|
||||
log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type));
|
||||
return sum * sum_coef(cell->type);
|
||||
} else if (max_inp_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.ref());
|
||||
} else if (max_inp_coef(cell->type.ref())) {
|
||||
// linear with largest input width
|
||||
unsigned int max = max_inp_width(cell);
|
||||
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type));
|
||||
return max * max_inp_coef(cell->type);
|
||||
} else if (is_div_mod(cell->type) || cell->type == ID($mul)) {
|
||||
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type.ref()));
|
||||
return max * max_inp_coef(cell->type.ref());
|
||||
} else if (is_div_mod(cell->type.ref()) || cell->type == TW($mul)) {
|
||||
// quadratic with sum of port widths
|
||||
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);
|
||||
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
|
||||
unsigned int cost_sum = 0;
|
||||
Macc macc;
|
||||
|
|
@ -193,17 +193,17 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
cost_sum += 3 * sum * sum;
|
||||
}
|
||||
return cost_sum;
|
||||
} else if (cell->type == ID($lut)) {
|
||||
} else if (cell->type == TW($lut)) {
|
||||
int width = cell->getParam(ID::WIDTH).as_int();
|
||||
unsigned int cost = 1U << (unsigned int)width;
|
||||
log_debug("%s is 2**%d\n", cell->name, width);
|
||||
return cost;
|
||||
} else if (cell->type == ID($sop)) {
|
||||
} else if (cell->type == TW($sop)) {
|
||||
int width = cell->getParam(ID::WIDTH).as_int();
|
||||
int depth = cell->getParam(ID::DEPTH).as_int();
|
||||
log_debug("%s is (2*%d + 1)*%d\n", cell->name, width, 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);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,52 +34,52 @@ struct CellCosts
|
|||
public:
|
||||
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
|
||||
// used by abc and stat
|
||||
static const dict<RTLIL::IdString, int> db = {
|
||||
{ ID($_BUF_), 1 },
|
||||
{ ID($_NOT_), 2 },
|
||||
{ ID($_AND_), 4 },
|
||||
{ ID($_NAND_), 4 },
|
||||
{ ID($_OR_), 4 },
|
||||
{ ID($_NOR_), 4 },
|
||||
{ ID($_ANDNOT_), 4 },
|
||||
{ ID($_ORNOT_), 4 },
|
||||
{ ID($_XOR_), 5 },
|
||||
{ ID($_XNOR_), 5 },
|
||||
{ ID($_AOI3_), 6 },
|
||||
{ ID($_OAI3_), 6 },
|
||||
{ ID($_AOI4_), 7 },
|
||||
{ ID($_OAI4_), 7 },
|
||||
{ ID($_MUX_), 4 },
|
||||
{ ID($_NMUX_), 4 },
|
||||
static const dict<TwineRef, int> db = {
|
||||
{ TW($_BUF_), 1 },
|
||||
{ TW($_NOT_), 2 },
|
||||
{ TW($_AND_), 4 },
|
||||
{ TW($_NAND_), 4 },
|
||||
{ TW($_OR_), 4 },
|
||||
{ TW($_NOR_), 4 },
|
||||
{ TW($_ANDNOT_), 4 },
|
||||
{ TW($_ORNOT_), 4 },
|
||||
{ TW($_XOR_), 5 },
|
||||
{ TW($_XNOR_), 5 },
|
||||
{ TW($_AOI3_), 6 },
|
||||
{ TW($_OAI3_), 6 },
|
||||
{ TW($_AOI4_), 7 },
|
||||
{ TW($_OAI4_), 7 },
|
||||
{ TW($_MUX_), 4 },
|
||||
{ TW($_NMUX_), 4 },
|
||||
};
|
||||
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
|
||||
// used by stat and optionally by abc
|
||||
static const dict<RTLIL::IdString, int> db = {
|
||||
{ ID($_BUF_), 1 },
|
||||
{ ID($_NOT_), 2 },
|
||||
{ ID($_AND_), 6 },
|
||||
{ ID($_NAND_), 4 },
|
||||
{ ID($_OR_), 6 },
|
||||
{ ID($_NOR_), 4 },
|
||||
{ ID($_ANDNOT_), 6 },
|
||||
{ ID($_ORNOT_), 6 },
|
||||
{ ID($_XOR_), 12 },
|
||||
{ ID($_XNOR_), 12 },
|
||||
{ ID($_AOI3_), 6 },
|
||||
{ ID($_OAI3_), 6 },
|
||||
{ ID($_AOI4_), 8 },
|
||||
{ ID($_OAI4_), 8 },
|
||||
{ ID($_MUX_), 12 },
|
||||
{ ID($_NMUX_), 10 },
|
||||
{ ID($_DFF_P_), 16 },
|
||||
{ ID($_DFF_N_), 16 },
|
||||
static const dict<TwineRef, int> db = {
|
||||
{ TW($_BUF_), 1 },
|
||||
{ TW($_NOT_), 2 },
|
||||
{ TW($_AND_), 6 },
|
||||
{ TW($_NAND_), 4 },
|
||||
{ TW($_OR_), 6 },
|
||||
{ TW($_NOR_), 4 },
|
||||
{ TW($_ANDNOT_), 6 },
|
||||
{ TW($_ORNOT_), 6 },
|
||||
{ TW($_XOR_), 12 },
|
||||
{ TW($_XNOR_), 12 },
|
||||
{ TW($_AOI3_), 6 },
|
||||
{ TW($_OAI3_), 6 },
|
||||
{ TW($_AOI4_), 8 },
|
||||
{ TW($_OAI4_), 8 },
|
||||
{ TW($_MUX_), 12 },
|
||||
{ TW($_NMUX_), 10 },
|
||||
{ TW($_DFF_P_), 16 },
|
||||
{ TW($_DFF_N_), 16 },
|
||||
};
|
||||
return db;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -537,8 +537,8 @@ DriverMap::BitMode DriverMap::bit_mode(DriveBit const &bit)
|
|||
}
|
||||
case DriveType::PORT: {
|
||||
auto const &port = bit.port();
|
||||
bool driver = celltypes.cell_output(port.cell->type, port.port);
|
||||
bool driven = celltypes.cell_input(port.cell->type, port.port);
|
||||
bool driver = celltypes.cell_output(port.cell->type.ref(), port.port);
|
||||
bool driven = celltypes.cell_input(port.cell->type.ref(), port.port);
|
||||
if (driver && !driven)
|
||||
return BitMode::DRIVER;
|
||||
else if (driven && !driver)
|
||||
|
|
@ -866,7 +866,7 @@ DriveSpec DriverMap::operator()(DriveSpec spec)
|
|||
|
||||
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())
|
||||
return id;
|
||||
if (chunk.width == 1)
|
||||
|
|
|
|||
26
kernel/ff.cc
26
kernel/ff.cc
|
|
@ -54,19 +54,19 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
|
|||
|
||||
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(ID($anyinit), ID($ff))) {
|
||||
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(TW($anyinit), TW($ff))) {
|
||||
info.has_gclk = true;
|
||||
if constexpr (have_cell)
|
||||
info.sig_d = cell->getPort(TW::D);
|
||||
if (type == ID($anyinit)) {
|
||||
if (type == TW($anyinit)) {
|
||||
info.is_anyinit = true;
|
||||
if constexpr (have_cell)
|
||||
log_assert(info.val_init.is_fully_undef());
|
||||
}
|
||||
} else if (type == ID($sr)) {
|
||||
} else if (type == TW($sr)) {
|
||||
// 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;
|
||||
if constexpr (have_cell) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if constexpr (have_cell) {
|
||||
info.sig_ce = cell->getPort(TW::EN);
|
||||
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;
|
||||
if constexpr (have_cell) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
if (type.in(ID($aldff), ID($aldffe))) {
|
||||
if (type.in(TW($aldff), TW($aldffe))) {
|
||||
info.has_aload = true;
|
||||
if constexpr (have_cell) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (type.in(ID($adff), ID($adffe), ID($adlatch))) {
|
||||
if (type.in(TW($adff), TW($adffe), TW($adlatch))) {
|
||||
info.has_arst = true;
|
||||
if constexpr (have_cell) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (type.in(ID($sdff), ID($sdffe), ID($sdffce))) {
|
||||
if (type.in(TW($sdff), TW($sdffe), TW($sdffce))) {
|
||||
info.has_srst = true;
|
||||
if constexpr (have_cell) {
|
||||
info.sig_srst = cell->getPort(TW::SRST);
|
||||
info.pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool();
|
||||
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.has_gclk = true;
|
||||
if constexpr (have_cell)
|
||||
|
|
@ -815,7 +815,7 @@ void FfData::flip_bits(const pool<int> &bits) {
|
|||
Wire *new_q = module->addWire(NEW_TWINE, width);
|
||||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ const char *fn_to_string(Fn 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;
|
||||
for (const auto &[name, input] : _inputs)
|
||||
if(input.kind == kind)
|
||||
|
|
@ -75,7 +75,7 @@ vector<IRInput const*> IR::inputs(IdString kind) const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
vector<IROutput const*> IR::outputs(IdString kind) const {
|
||||
vector<IROutput const*> IR::outputs(TwineRef kind) const {
|
||||
vector<IROutput const*> ret;
|
||||
for (const auto &[name, output] : _outputs)
|
||||
if(output.kind == kind)
|
||||
|
|
@ -83,7 +83,7 @@ vector<IROutput const*> IR::outputs(IdString kind) const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
vector<IRState const*> IR::states(IdString kind) const {
|
||||
vector<IRState const*> IR::states(TwineRef kind) const {
|
||||
vector<IRState const*> ret;
|
||||
for (const auto &[name, state] : _states)
|
||||
if(state.kind == kind)
|
||||
|
|
@ -136,7 +136,7 @@ struct PrintVisitor : DefaultVisitor<std::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)
|
||||
|
|
@ -253,87 +253,87 @@ public:
|
|||
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 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;
|
||||
Node a = factory.extend(inputs.at(TW::A), 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);
|
||||
else if(cellType == ID($sub))
|
||||
else if(cellType == TW($sub))
|
||||
return factory.sub(a, b);
|
||||
else if(cellType == ID($mul))
|
||||
else if(cellType == TW($mul))
|
||||
return factory.mul(a, b);
|
||||
else if(cellType == ID($and))
|
||||
else if(cellType == TW($and))
|
||||
return factory.bitwise_and(a, b);
|
||||
else if(cellType == ID($or))
|
||||
else if(cellType == TW($or))
|
||||
return factory.bitwise_or(a, b);
|
||||
else if(cellType == ID($xor))
|
||||
else if(cellType == TW($xor))
|
||||
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));
|
||||
else
|
||||
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;
|
||||
int width = max(a_width, b_width);
|
||||
Node a = factory.extend(inputs.at(TW::A), 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
else
|
||||
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 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);
|
||||
}else if(cellType == ID($not)){
|
||||
}else if(cellType == TW($not)){
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
|
||||
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);
|
||||
}else if(cellType == ID($neg)){
|
||||
}else if(cellType == TW($neg)){
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
|
||||
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 y = factory.bitwise_not(a);
|
||||
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));
|
||||
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));
|
||||
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 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);
|
||||
}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 b = inputs.at(TW::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);
|
||||
Node a = factory.extend(inputs.at(TW::A), width, a_signed);
|
||||
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) :
|
||||
logical_shift_right(a, b);
|
||||
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);
|
||||
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 shr = logical_shift_right(a, b);
|
||||
if(b_signed) {
|
||||
|
|
@ -343,35 +343,35 @@ public:
|
|||
} else {
|
||||
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));
|
||||
}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));
|
||||
}else if(cellType == ID($concat)){
|
||||
}else if(cellType == TW($concat)){
|
||||
Node a = inputs.at(TW::A);
|
||||
Node b = inputs.at(TW::B);
|
||||
return factory.concat(a, b);
|
||||
}else if(cellType == ID($slice)){
|
||||
}else if(cellType == TW($slice)){
|
||||
int offset = parameters.at(ID(OFFSET)).as_int();
|
||||
Node a = inputs.at(TW::A);
|
||||
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);
|
||||
bool is_signed = a_signed && b_signed;
|
||||
Node a = factory.extend(inputs.at(TW::A), width, is_signed);
|
||||
Node b = factory.extend(inputs.at(TW::B), width, is_signed);
|
||||
if(is_signed) {
|
||||
if(cellType == ID($div)) {
|
||||
if(cellType == TW($div)) {
|
||||
// divide absolute values, then flip the sign if input signs differ
|
||||
// but extend the width first, to handle the case (most negative value) / (-1)
|
||||
Node abs_y = factory.unsigned_div(abs(a), abs(b));
|
||||
Node out_sign = factory.not_equal(sign(a), sign(b));
|
||||
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
|
||||
Node abs_y = factory.unsigned_mod(abs(a), abs(b));
|
||||
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
|
||||
Node b_sign = sign(b);
|
||||
Node a1 = neg_if(a, b_sign);
|
||||
|
|
@ -385,7 +385,7 @@ public:
|
|||
Node y1 = factory.unsigned_div(a2, b1);
|
||||
Node y2 = factory.extend(y1, y_width, false);
|
||||
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
|
||||
Node abs_b = abs(b);
|
||||
Node abs_y = factory.unsigned_mod(abs(a), abs_b);
|
||||
|
|
@ -397,34 +397,34 @@ public:
|
|||
} else
|
||||
log_error("unhandled cell in CellSimplifier %s\n", cellType);
|
||||
} 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);
|
||||
else
|
||||
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);
|
||||
} else if (cellType == ID($lut)) {
|
||||
} else if (cellType == TW($lut)) {
|
||||
int width = parameters.at(ID(WIDTH)).as_int();
|
||||
Const lut_table = parameters.at(ID(LUT));
|
||||
lut_table.extu(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 b = inputs.at(TW::B);
|
||||
Node s = inputs.at(TW::S);
|
||||
return factory.bitwise_or(
|
||||
factory.bitwise_and(a, factory.bitwise_not(s)),
|
||||
factory.bitwise_and(b, s));
|
||||
} else if (cellType == ID($bweqx)) {
|
||||
} else if (cellType == TW($bweqx)) {
|
||||
Node a = inputs.at(TW::A);
|
||||
Node b = inputs.at(TW::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 s_width = parameters.at(ID(S_WIDTH)).as_int();
|
||||
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 s_width = parameters.at(ID(S_WIDTH)).as_int();
|
||||
int y_width = width << s_width;
|
||||
|
|
@ -433,31 +433,31 @@ public:
|
|||
Node s = factory.extend(inputs.at(TW::S), b_width, false);
|
||||
Node b = factory.mul(s, factory.constant(Const(width, b_width)));
|
||||
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));
|
||||
} 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));
|
||||
} 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));
|
||||
} 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));
|
||||
auto &output = factory.add_output(cellName, cellType, Sort(1));
|
||||
output.set_value(a);
|
||||
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();
|
||||
auto &input = factory.add_input(cellName, cellType, Sort(width));
|
||||
return factory.value(input);
|
||||
} else if(cellType == ID($initstate)) {
|
||||
if(factory.ir().has_state(ID($initstate), ID($state)))
|
||||
return factory.value(factory.ir().state(ID($initstate)));
|
||||
} else if(cellType == TW($initstate)) {
|
||||
if(factory.ir().has_state(TW($initstate), TW($state)))
|
||||
return factory.value(factory.ir().state(TW($initstate)));
|
||||
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_next_value(factory.constant(RTLIL::Const(State::S0, 1)));
|
||||
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);
|
||||
} else {
|
||||
log_error("`%s' cells are not supported by the functional backend\n", cellType);
|
||||
|
|
@ -495,7 +495,7 @@ class FunctionalIRConstruction {
|
|||
queue.emplace_back(cell);
|
||||
std::optional<Node> rv;
|
||||
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());
|
||||
factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name));
|
||||
cell_outputs.emplace({cell, name}, node);
|
||||
|
|
@ -515,17 +515,17 @@ public:
|
|||
{
|
||||
driver_map.add(module);
|
||||
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);
|
||||
}
|
||||
// we are relying here on unsorted pools iterating last-in-first-out
|
||||
for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) {
|
||||
auto *wire = module->wire(*riter);
|
||||
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) {
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
// ascending index order the result will obey the priorty relation.
|
||||
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));
|
||||
Node node = factory.value(state);
|
||||
for (size_t i = 0; i < mem->wr_ports.size(); i++) {
|
||||
const auto &wr = mem->wr_ports[i];
|
||||
if (wr.clk_enable)
|
||||
log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
|
||||
"Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, mem->memid.unescape());
|
||||
"Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
|
||||
Node en = enqueue(driver_map(DriveSpec(wr.en)));
|
||||
Node addr = enqueue(driver_map(DriveSpec(wr.addr)));
|
||||
Node new_data = enqueue(driver_map(DriveSpec(wr.data)));
|
||||
|
|
@ -582,12 +582,12 @@ private:
|
|||
}
|
||||
if (mem->rd_ports.empty())
|
||||
log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. "
|
||||
"Call opt_clean to remove it.", mem->module, mem->memid.unescape());
|
||||
"Call opt_clean to remove it.", mem->module, design->twines.unescaped_str(mem->memid));
|
||||
for (size_t i = 0; i < mem->rd_ports.size(); i++) {
|
||||
const auto &rd = mem->rd_ports[i];
|
||||
if (rd.clk_enable)
|
||||
log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
|
||||
"Call memory_nordff to avoid this error.\n", i, mem->module, mem->memid.unescape());
|
||||
"Call memory_nordff to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
|
||||
Node addr = enqueue(driver_map(DriveSpec(rd.addr)));
|
||||
read_results.push_back(factory.memory_read(node, addr));
|
||||
}
|
||||
|
|
@ -609,8 +609,8 @@ private:
|
|||
FfData ff(&ff_initvals, cell);
|
||||
if (!ff.has_gclk)
|
||||
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);
|
||||
auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width));
|
||||
"Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescaped(), cell);
|
||||
auto &state = factory.add_state(ff.name, TW($state), Sort(ff.width));
|
||||
Node q_value = factory.value(state);
|
||||
factory.suggest_name(q_value, ff.name);
|
||||
factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value);
|
||||
|
|
@ -621,9 +621,9 @@ private:
|
|||
TwineRef output_name; // for the single output case
|
||||
int n_outputs = 0;
|
||||
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})) });
|
||||
if(driver_map.celltypes.cell_output(cell->type, name)) {
|
||||
if(driver_map.celltypes.cell_output(cell->type.ref(), name)) {
|
||||
output_name = name;
|
||||
n_outputs++;
|
||||
}
|
||||
|
|
@ -677,7 +677,7 @@ public:
|
|||
factory.update_pending(pending, node);
|
||||
} else {
|
||||
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);
|
||||
factory.suggest_name(node, wire_chunk.wire->name);
|
||||
factory.update_pending(pending, node);
|
||||
|
|
@ -690,7 +690,7 @@ public:
|
|||
} else if (chunk.is_port()) {
|
||||
DriveChunkPort port_chunk = chunk.port();
|
||||
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);
|
||||
factory.update_pending(pending, node);
|
||||
} else {
|
||||
|
|
@ -745,7 +745,7 @@ void IR::topological_sort() {
|
|||
log_warning("Combinational loop:\n");
|
||||
for (int *i = begin; i != end; ++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");
|
||||
scc = true;
|
||||
|
|
|
|||
1276
kernel/functional.h
1276
kernel/functional.h
File diff suppressed because it is too large
Load diff
|
|
@ -138,11 +138,11 @@ struct Macc
|
|||
|
||||
void from_cell(RTLIL::Cell *cell)
|
||||
{
|
||||
if (cell->type == ID($macc)) {
|
||||
if (cell->type == TW($macc)) {
|
||||
from_cell_v1(cell);
|
||||
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_b = cell->getPort(TW::B);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ void Mem::emit() {
|
|||
if (!cell) {
|
||||
if (memid.empty())
|
||||
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->attributes = attributes;
|
||||
|
|
@ -300,7 +300,7 @@ void Mem::emit() {
|
|||
mem->attributes = attributes;
|
||||
for (auto &port : rd_ports) {
|
||||
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->attributes = port.attributes;
|
||||
port.cell->parameters[ID::MEMID] = memid.str();
|
||||
|
|
@ -325,7 +325,7 @@ void Mem::emit() {
|
|||
int idx = 0;
|
||||
for (auto &port : wr_ports) {
|
||||
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->attributes = port.attributes;
|
||||
if (port.cell->parameters.count(ID::PRIORITY))
|
||||
|
|
@ -346,7 +346,7 @@ void Mem::emit() {
|
|||
for (auto &init : inits) {
|
||||
bool v2 = !init.en.is_fully_ones();
|
||||
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 {
|
||||
if (!v2)
|
||||
init.cell->unsetPort(TW::EN);
|
||||
|
|
@ -548,11 +548,11 @@ namespace {
|
|||
dict<IdString, pool<Cell *>> inits;
|
||||
MemIndex (Module *module) {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -568,7 +568,7 @@ namespace {
|
|||
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)))) {
|
||||
MemRd mrd;
|
||||
bool is_compat = cell->type == ID($memrd);
|
||||
bool is_compat = cell->type == TW($memrd);
|
||||
mrd.cell = cell;
|
||||
mrd.attributes = cell->attributes;
|
||||
mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
|
||||
|
|
@ -612,7 +612,7 @@ namespace {
|
|||
std::vector<std::pair<int, MemWr>> ports;
|
||||
for (auto cell : index.wr_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
|
||||
MemWr mwr;
|
||||
bool is_compat = cell->type == ID($memwr);
|
||||
bool is_compat = cell->type == TW($memwr);
|
||||
mwr.cell = cell;
|
||||
mwr.attributes = cell->attributes;
|
||||
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++) {
|
||||
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) {
|
||||
port.priority_mask.resize(GetSize(res.wr_ports));
|
||||
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);
|
||||
init.addr = addr.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);
|
||||
if (!en.is_fully_const())
|
||||
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++) {
|
||||
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) {
|
||||
port.transparency_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::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();
|
||||
res.packed = true;
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ struct ModIndex : public RTLIL::Monitor
|
|||
log(" PRIMARY OUTPUT\n");
|
||||
for (auto &port : it.second.ports)
|
||||
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)
|
||||
{
|
||||
if (ct.cell_known(cell->type)) {
|
||||
if (ct.cell_known(cell->type.ref())) {
|
||||
for (auto &conn : cell->connections())
|
||||
add_cell_port(cell, conn.first, sigmap(conn.second),
|
||||
ct.cell_output(cell->type, conn.first),
|
||||
ct.cell_input(cell->type, conn.first));
|
||||
ct.cell_output(cell->type.ref(), conn.first),
|
||||
ct.cell_input(cell->type.ref(), conn.first));
|
||||
} else {
|
||||
for (auto &conn : cell->connections())
|
||||
add_cell_port(cell, conn.first, sigmap(conn.second), true, true);
|
||||
|
|
@ -436,7 +436,7 @@ struct ModWalker
|
|||
for (auto &it : module->wires_)
|
||||
add_wire(it.second);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -555,13 +555,8 @@ struct NewCellType {
|
|||
};
|
||||
|
||||
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;
|
||||
std::unordered_map<TwineRef, NewCellType, IdStringHash> custom_cell_types {};
|
||||
dict<TwineRef, NewCellType> custom_cell_types {};
|
||||
|
||||
NewCellTypes() {
|
||||
static_cell_types = StaticCellTypes::categories.empty;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ struct PmuxBPortIterator {
|
|||
int port_idx;
|
||||
int port_count;
|
||||
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;
|
||||
b = mux->getPort(TW::B).to_sigbit_vector();
|
||||
|
||||
|
|
|
|||
|
|
@ -77,25 +77,25 @@ void QuickConeSat::prepare()
|
|||
|
||||
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;
|
||||
if (cell->type.in(ID($not), ID($and), ID($or), ID($xor), ID($xnor),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor),
|
||||
ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($logic_not), ID($logic_and), ID($logic_or),
|
||||
ID($eq), ID($ne), ID($eqx), ID($nex), ID($fa),
|
||||
ID($mux), ID($pmux), ID($bmux), ID($demux), ID($lut), ID($sop),
|
||||
ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
|
||||
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
|
||||
ID($_MUX_), ID($_NMUX_), ID($_MUX4_), ID($_MUX8_), ID($_MUX16_),
|
||||
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
|
||||
if (cell->type.in(TW($not), TW($and), TW($or), TW($xor), TW($xnor),
|
||||
TW($reduce_and), TW($reduce_or), TW($reduce_xor),
|
||||
TW($reduce_xnor), TW($reduce_bool),
|
||||
TW($logic_not), TW($logic_and), TW($logic_or),
|
||||
TW($eq), TW($ne), TW($eqx), TW($nex), TW($fa),
|
||||
TW($mux), TW($pmux), TW($bmux), TW($demux), TW($lut), TW($sop),
|
||||
TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
|
||||
TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
|
||||
TW($_MUX_), TW($_NMUX_), TW($_MUX4_), TW($_MUX8_), TW($_MUX16_),
|
||||
TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)))
|
||||
return 1;
|
||||
if (cell->type.in(ID($neg), ID($add), ID($sub), ID($alu), ID($lcu),
|
||||
ID($lt), ID($le), ID($gt), ID($ge)))
|
||||
if (cell->type.in(TW($neg), TW($add), TW($sub), TW($alu), TW($lcu),
|
||||
TW($lt), TW($le), TW($gt), TW($ge)))
|
||||
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;
|
||||
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;
|
||||
// Unknown cell.
|
||||
return 5;
|
||||
|
|
|
|||
|
|
@ -983,7 +983,7 @@ struct HelpPass : public Pass {
|
|||
for (auto it : StaticCellTypes::builder.cells) {
|
||||
if (!StaticCellTypes::categories.is_known(it.type))
|
||||
continue;
|
||||
auto name = it.type.str();
|
||||
auto name = TW::str(it.type);
|
||||
if (cell_help_messages.contains(name)) {
|
||||
auto cell_help = cell_help_messages.get(name);
|
||||
groups[cell_help.group].emplace_back(name);
|
||||
|
|
@ -1021,10 +1021,10 @@ struct HelpPass : public Pass {
|
|||
json.name("code"); json.value(ch.code);
|
||||
vector<string> inputs, outputs;
|
||||
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);
|
||||
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);
|
||||
vector<string> properties;
|
||||
// CellType properties
|
||||
|
|
|
|||
|
|
@ -1948,18 +1948,18 @@ bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
|
|||
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)
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
@ -3574,6 +3574,11 @@ TwineRef RTLIL::Module::uniquify(TwineRef name)
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (a->port_id && !b->port_id)
|
||||
|
|
@ -4524,10 +4534,14 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
|
|||
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,
|
||||
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::R, sig_clr);
|
||||
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)
|
||||
{
|
||||
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::D, sig_d);
|
||||
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)
|
||||
{
|
||||
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::E, sig_en);
|
||||
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,
|
||||
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::S, sig_set);
|
||||
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,
|
||||
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::S, sig_set);
|
||||
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,
|
||||
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::R, sig_arst);
|
||||
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,
|
||||
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::R, sig_arst);
|
||||
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,
|
||||
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::L, sig_aload);
|
||||
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,
|
||||
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::L, sig_aload);
|
||||
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,
|
||||
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::R, sig_srst);
|
||||
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,
|
||||
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::R, sig_srst);
|
||||
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,
|
||||
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::R, sig_srst);
|
||||
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)
|
||||
{
|
||||
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::D, sig_d);
|
||||
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,
|
||||
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::R, sig_arst);
|
||||
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,
|
||||
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::S, sig_set);
|
||||
cell->setPort(TW::R, sig_clr);
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ constexpr int lookup_well_known_id(std::string_view name)
|
|||
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
|
||||
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
|
||||
|
|
@ -3026,7 +3026,7 @@ public:
|
|||
Module();
|
||||
virtual ~Module();
|
||||
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail = false);
|
||||
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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> ¶meters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool mayfail = false);
|
||||
virtual size_t count_id(TwineRef id);
|
||||
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
|
||||
virtual bool reprocess_if_necessary(RTLIL::Design *design);
|
||||
|
|
@ -3158,7 +3158,9 @@ public:
|
|||
void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2);
|
||||
|
||||
TwineRef uniquify(TwineRef name);
|
||||
TwineRef uniquify(Twine&& name);
|
||||
TwineRef uniquify(TwineRef name, int &index);
|
||||
TwineRef uniquify(Twine&& name, int &index);
|
||||
|
||||
// Primary overloads: name already interned in design->twines.
|
||||
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, const RTLIL::Cell *other);
|
||||
// Convenience.
|
||||
RTLIL::Cell *addCell(Twine name, Twine type);
|
||||
RTLIL::Cell *addCell(Twine &&name, TwineRef type);
|
||||
RTLIL::Cell *addCell(TwineRef name, Twine &&type);
|
||||
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ struct RTLIL::SigNormIndex
|
|||
dict<Wire *, Cell *> input_port_cells;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type != ID($input_port))
|
||||
if (cell->type != TW($input_port))
|
||||
continue;
|
||||
|
||||
auto const &sig_y = cell->getPort(TW::Y);
|
||||
|
|
@ -98,7 +98,7 @@ struct RTLIL::SigNormIndex
|
|||
for (auto portname : module->ports) {
|
||||
Wire *wire = module->wire(portname);
|
||||
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->setPort(TW::Y, wire);
|
||||
input_port_cells.emplace(wire, cell);
|
||||
|
|
@ -195,7 +195,7 @@ struct RTLIL::SigNormIndex
|
|||
}
|
||||
|
||||
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);
|
||||
cell->setParam(ID::WIDTH, GetSize(connect_lhs));
|
||||
cell->setPort(TW::A, std::move(connect_lhs));
|
||||
|
|
@ -355,7 +355,7 @@ void RTLIL::Design::sigNormalize(bool enable)
|
|||
// TODO inefficient?
|
||||
std::vector<Cell*> cells_snapshot = module->cells();
|
||||
for (auto cell : cells_snapshot) {
|
||||
if (cell->type == ID($input_port))
|
||||
if (cell->type == TW($input_port))
|
||||
module->remove(cell);
|
||||
}
|
||||
}
|
||||
|
|
@ -560,12 +560,12 @@ void RTLIL::Module::bufNormalize()
|
|||
// Ensure that every enqueued input port is represented by a cell
|
||||
for (auto wire : buf_norm_wire_queue) {
|
||||
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->driverPort_ = Twine::Null;
|
||||
}
|
||||
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->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())
|
||||
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
|
||||
// side, bypass it using module level connections (skipping 'z
|
||||
// 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);
|
||||
buf_norm_wire_queue.clear();
|
||||
return;
|
||||
} else if (cell->type == ID($input_port)) {
|
||||
} else if (cell->type == TW($input_port)) {
|
||||
log_assert(port == TW::Y);
|
||||
if (sig.is_wire()) {
|
||||
Wire *w = sig.as_wire();
|
||||
|
|
@ -744,7 +744,7 @@ void RTLIL::Module::bufNormalize()
|
|||
break;
|
||||
while (!found->second.empty()) {
|
||||
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_b = connect_cell->getPort(TW::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
|
||||
// wires for cell output and inout 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(!pending_deleted_cells.count(cell));
|
||||
SigSpec const &sig = cell->getPort(port);
|
||||
|
|
@ -848,7 +848,7 @@ void RTLIL::Module::bufNormalize()
|
|||
auto const &[cell, port] = cellport;
|
||||
for (int i = 0; i != GetSize(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
|
||||
weakly_driven.insert(driver);
|
||||
} else {
|
||||
|
|
@ -947,7 +947,7 @@ void RTLIL::Module::bufNormalize()
|
|||
if (sig_a.empty())
|
||||
return;
|
||||
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->setPort(TW::A, sig_a);
|
||||
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 &chunk : sig.chunks()) {
|
||||
if (!chunk.wire)
|
||||
|
|
@ -1097,7 +1097,7 @@ void RTLIL::Cell::unsetPort(TwineRef portname)
|
|||
|
||||
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)
|
||||
|
|
@ -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()) {
|
||||
Wire *w = signal.as_wire();
|
||||
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->driverPort_ = portname;
|
||||
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);
|
||||
}
|
||||
|
||||
if (type == ID($connect)) {
|
||||
if (type == TW($connect)) {
|
||||
for (auto &[port, sig] : connections_) {
|
||||
for (auto &chunk : sig.chunks()) {
|
||||
if (!chunk.wire) continue;
|
||||
|
|
@ -1229,7 +1229,7 @@ void RTLIL::Cell::initIndex()
|
|||
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
|
||||
Wire *w = signal.as_wire();
|
||||
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->driverPort_ = portname;
|
||||
continue;
|
||||
|
|
|
|||
198
kernel/satgen.cc
198
kernel/satgen.cc
|
|
@ -26,9 +26,9 @@ USING_YOSYS_NAMESPACE
|
|||
bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||
{
|
||||
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_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_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);
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
|
||||
ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub)))
|
||||
if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
|
||||
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> 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;
|
||||
|
||||
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));
|
||||
if (cell->type == ID($_NAND_))
|
||||
if (cell->type == TW($_NAND_))
|
||||
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));
|
||||
if (cell->type == ID($_NOR_))
|
||||
if (cell->type == TW($_NOR_))
|
||||
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));
|
||||
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));
|
||||
if (cell->type == ID($_ANDNOT_))
|
||||
if (cell->type == TW($_ANDNOT_))
|
||||
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));
|
||||
if (cell->type == ID($add))
|
||||
if (cell->type == TW($add))
|
||||
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));
|
||||
|
||||
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);
|
||||
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> 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)));
|
||||
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> 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)));
|
||||
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);
|
||||
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> 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)));
|
||||
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> 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)));
|
||||
|
|
@ -139,10 +139,10 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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 three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_));
|
||||
bool aoi_mode = cell->type.in(TW($_AOI3_), TW($_AOI4_));
|
||||
bool three_mode = cell->type.in(TW($_AOI3_), TW($_OAI3_));
|
||||
|
||||
int a = importDefSigSpec(cell->getPort(TW::A), 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 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));
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
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> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
|
||||
|
|
@ -224,7 +224,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> b = importDefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -250,7 +250,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> 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> 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));
|
||||
else if (cell->type == ID($bwmux))
|
||||
else if (cell->type == TW($bwmux))
|
||||
ez->assume(ez->vec_eq(ez->vec_ite(s, b, a), yy));
|
||||
else
|
||||
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> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
|
||||
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));
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($bmux))
|
||||
if (cell->type == TW($bmux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), 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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($demux))
|
||||
if (cell->type == TW($demux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), 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;
|
||||
}
|
||||
|
||||
if (cell->type == ID($pmux))
|
||||
if (cell->type == TW($pmux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), 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;
|
||||
}
|
||||
|
||||
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> 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;
|
||||
|
||||
if (cell->type.in(ID($pos), ID($buf))) {
|
||||
if (cell->type.in(TW($pos), TW($buf))) {
|
||||
ez->assume(ez->vec_eq(a, yy));
|
||||
} else {
|
||||
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);
|
||||
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));
|
||||
} else {
|
||||
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
|
||||
|
|
@ -465,7 +465,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> b = importDefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -485,22 +485,22 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
|
||||
|
||||
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));
|
||||
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));
|
||||
if (cell->type == ID($reduce_xor))
|
||||
if (cell->type == TW($reduce_xor))
|
||||
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));
|
||||
if (cell->type == ID($logic_not))
|
||||
if (cell->type == TW($logic_not))
|
||||
ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0));
|
||||
for (size_t i = 1; i < y.size(); 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);
|
||||
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)));
|
||||
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)));
|
||||
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)));
|
||||
} else
|
||||
log_abort();
|
||||
|
|
@ -532,7 +532,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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_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;
|
||||
|
||||
if (cell->type == ID($logic_and))
|
||||
if (cell->type == TW($logic_and))
|
||||
ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0));
|
||||
else
|
||||
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 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));
|
||||
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));
|
||||
else
|
||||
log_abort();
|
||||
|
|
@ -578,7 +578,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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();
|
||||
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;
|
||||
|
||||
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_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
for (size_t i = 1; i < y.size(); 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_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
|
||||
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
|
||||
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));
|
||||
else
|
||||
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));
|
||||
}
|
||||
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_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -662,7 +662,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> 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> 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_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())
|
||||
extend_bit = undef_a.back();
|
||||
|
||||
|
|
@ -711,19 +711,19 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
while (undef_y.size() > undef_a.size())
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
|
||||
|
|
@ -734,7 +734,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> b = importDefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -761,7 +761,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> 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_c;
|
||||
|
||||
if (cell->type == ID($macc_v2))
|
||||
if (cell->type == TW($macc_v2))
|
||||
undef_c = importUndefSigSpec(cell->getPort(TW::C), timestep);
|
||||
|
||||
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
|
||||
|
|
@ -830,7 +830,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> 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;
|
||||
}
|
||||
|
||||
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())
|
||||
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
|
||||
else
|
||||
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));
|
||||
} 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())
|
||||
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(
|
||||
ez->XOR(a.back(), b.back()),
|
||||
|
|
@ -898,7 +898,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
)));
|
||||
else
|
||||
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))));
|
||||
}
|
||||
|
||||
|
|
@ -906,7 +906,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
ez->assume(ez->expression(ezSAT::OpOr, b));
|
||||
} else {
|
||||
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()) {
|
||||
std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
|
||||
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(), 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
|
||||
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);
|
||||
|
|
@ -936,7 +936,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
|
||||
|
|
@ -986,7 +986,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($sop))
|
||||
if (cell->type == TW($sop))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
|
||||
int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0);
|
||||
|
|
@ -1068,7 +1068,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> b = importDefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -1104,7 +1104,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> g = importDefSigSpec(cell->getPort(TW::G), timestep);
|
||||
|
|
@ -1136,7 +1136,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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> b = importDefSigSpec(cell->getPort(TW::B), timestep);
|
||||
|
|
@ -1202,7 +1202,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($slice))
|
||||
if (cell->type == TW($slice))
|
||||
{
|
||||
RTLIL::SigSpec a = cell->getPort(TW::A);
|
||||
RTLIL::SigSpec y = cell->getPort(TW::Y);
|
||||
|
|
@ -1210,7 +1210,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($concat))
|
||||
if (cell->type == TW($concat))
|
||||
{
|
||||
RTLIL::SigSpec a = cell->getPort(TW::A);
|
||||
RTLIL::SigSpec b = cell->getPort(TW::B);
|
||||
|
|
@ -1223,7 +1223,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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);
|
||||
|
||||
|
|
@ -1303,7 +1303,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($anyconst))
|
||||
if (cell->type == TW($anyconst))
|
||||
{
|
||||
if (timestep < 2) {
|
||||
if (model_undef && def_formal) {
|
||||
|
|
@ -1335,7 +1335,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($anyseq))
|
||||
if (cell->type == TW($anyseq))
|
||||
{
|
||||
if (model_undef && def_formal) {
|
||||
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;
|
||||
}
|
||||
|
||||
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> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
|
||||
|
|
@ -1364,7 +1364,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($initstate))
|
||||
if (cell->type == TW($initstate))
|
||||
{
|
||||
auto key = make_pair(prefix, timestep);
|
||||
if (initstates.count(key) == 0)
|
||||
|
|
@ -1383,7 +1383,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($assert))
|
||||
if (cell->type == TW($assert))
|
||||
{
|
||||
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
|
||||
asserts_a[pf].append((*sigmap)(cell->getPort(TW::A)));
|
||||
|
|
@ -1391,7 +1391,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($assume))
|
||||
if (cell->type == TW($assume))
|
||||
{
|
||||
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
|
||||
assumes_a[pf].append((*sigmap)(cell->getPort(TW::A)));
|
||||
|
|
@ -1399,7 +1399,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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;
|
||||
}
|
||||
|
|
@ -1415,9 +1415,9 @@ void report_missing_model(bool warn_only, RTLIL::Cell* cell)
|
|||
{
|
||||
std::string s;
|
||||
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
|
||||
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) {
|
||||
log_formatted_warning_noprefix(s);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ struct SatGen
|
|||
else
|
||||
vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE);
|
||||
} 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 +
|
||||
(bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset));
|
||||
vec.push_back(ez->frozen_literal(name));
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ void ModuleHdlnameIndex::index_cells()
|
|||
void ModuleHdlnameIndex::index_scopeinfo_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)
|
||||
|
|
@ -69,7 +69,7 @@ std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor)
|
|||
continue;
|
||||
}
|
||||
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("");
|
||||
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)
|
||||
{
|
||||
log_assert(scopeinfo->type == ID($scopeinfo));
|
||||
return scopeinfo->has_attribute(attr_prefix(attrs) + id.unescape());
|
||||
log_assert(scopeinfo->type == TW($scopeinfo));
|
||||
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)
|
||||
{
|
||||
log_assert(scopeinfo->type == ID($scopeinfo));
|
||||
auto found = scopeinfo->attributes.find(attr_prefix(attrs) + id.unescape());
|
||||
log_assert(scopeinfo->type == TW($scopeinfo));
|
||||
auto found = scopeinfo->attributes.find(attr_prefix(attrs) + design->twines.unescaped_str(id));
|
||||
if (found == scopeinfo->attributes.end())
|
||||
return RTLIL::Const();
|
||||
return found->second;
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@ struct TimingInfo
|
|||
{
|
||||
struct NameBit
|
||||
{
|
||||
RTLIL::IdString name;
|
||||
TwineRef name;
|
||||
int offset;
|
||||
NameBit() : offset(0) {}
|
||||
NameBit(const RTLIL::IdString name, int offset) : name(name), offset(offset) {}
|
||||
explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->name), offset(b.offset) {}
|
||||
NameBit(TwineRef name, int offset) : name(name), offset(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 !operator==(nb); }
|
||||
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))
|
||||
return {};
|
||||
auto &port = cell->getPort(port_name);
|
||||
|
|
@ -71,7 +71,7 @@ struct TimingInfo
|
|||
bool has_inputs;
|
||||
};
|
||||
|
||||
dict<RTLIL::IdString, ModuleTiming> data;
|
||||
dict<TwineRef, ModuleTiming> data;
|
||||
|
||||
TimingInfo()
|
||||
{
|
||||
|
|
@ -93,12 +93,12 @@ struct TimingInfo
|
|||
|
||||
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);
|
||||
auto &t = r.first->second;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == ID($specify2)) {
|
||||
if (cell->type == TW($specify2)) {
|
||||
auto en = cell->getPort(TW::EN);
|
||||
if (en.is_fully_const() && !en.as_bool())
|
||||
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 dst = cell->getPort(TW::DST);
|
||||
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();
|
||||
if (type != ID($setup) && type != ID($setuphold))
|
||||
if (type != TW($setup) && type != TW($setuphold))
|
||||
continue;
|
||||
auto src = cell->getPort(TW::SRC);
|
||||
auto dst = cell->getPort(TW::DST).as_bit();
|
||||
|
|
@ -198,10 +198,10 @@ struct TimingInfo
|
|||
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(); }
|
||||
int count(RTLIL::IdString module_name) const { return data.count(module_name); }
|
||||
const ModuleTiming& at(RTLIL::IdString module_name) const { return data.at(module_name); }
|
||||
int count(TwineRef module_name) const { return data.count(module_name); }
|
||||
const ModuleTiming& at(TwineRef module_name) const { return data.at(module_name); }
|
||||
};
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -91,6 +91,20 @@ struct TW {
|
|||
|
||||
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)
|
||||
|
|
@ -102,7 +116,6 @@ struct Twine {
|
|||
struct Suffix {
|
||||
TwineRef prefix;
|
||||
std::string tail;
|
||||
// TODO check
|
||||
auto operator<=>(const Suffix&) const = default;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -76,9 +76,9 @@ public:
|
|||
|
||||
RTLIL::Cell *addCell(TwineRef name, TwineRef type);
|
||||
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(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.
|
||||
// Returned refs are twine_staging-local and die at the next commit.
|
||||
|
|
|
|||
|
|
@ -964,7 +964,7 @@ static char *readline_obj_generator(const char *text, int state)
|
|||
RTLIL::Module *module = design->module(design->selected_active_module);
|
||||
|
||||
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()));
|
||||
|
||||
for (auto &it : module->memories) {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ OBJS += passes/cmds/xprop.o
|
|||
OBJS += passes/cmds/dft_tag.o
|
||||
OBJS += passes/cmds/future.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/wrapcell.o
|
||||
OBJS += passes/cmds/setenv.o
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ unsigned int abstract_state(Module* mod, EnableLogic enable, const std::vector<S
|
|||
std::vector<FfData> ffs;
|
||||
// Abstract flop inputs if they're driving a selected output rep
|
||||
for (auto cell : mod->cells()) {
|
||||
if (!ct.cell_types.count(cell->type))
|
||||
if (!ct.cell_types.count(cell->type_impl))
|
||||
continue;
|
||||
FfData ff(nullptr, cell);
|
||||
if (ff.has_sr)
|
||||
|
|
@ -265,7 +265,7 @@ unsigned int abstract_value(Module* mod, EnableLogic enable, const std::vector<S
|
|||
unsigned int changed = 0;
|
||||
std::vector<Cell*> cells_snapshot = mod->cells();
|
||||
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;
|
||||
for (auto conn : cell->connections())
|
||||
if (cell->output(conn.first)) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
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);
|
||||
if(enable_name == "") {
|
||||
formal_cell->setPort(TW::EN, State::S1);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ struct BoxDerivePass : Pass {
|
|||
continue;
|
||||
|
||||
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);
|
||||
log_assert(derived && "Failed to derive module\n");
|
||||
log("derived %s\n", derived_type);
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ int check_bufnorm_wire(RTLIL::Module *module, RTLIL::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_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_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
|
||||
// in port widths are those for us to check.
|
||||
if (!cell->type.in(
|
||||
ID($add), ID($sub),
|
||||
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
|
||||
ID($pmux), ID($bmux)))
|
||||
TW($add), TW($sub),
|
||||
TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx),
|
||||
TW($pmux), TW($bmux)))
|
||||
return false;
|
||||
|
||||
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
|
||||
in_widths = GetSize(cell->getPort(TW::S));
|
||||
out_widths = GetSize(cell->getPort(TW::Y));
|
||||
|
|
@ -358,17 +358,17 @@ struct CheckPass : public Pass {
|
|||
pool<Cell *> coarsened_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;
|
||||
|
||||
if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) {
|
||||
if (allow_tbuf && cell->type == ID($_TBUF_)) goto cell_allowed;
|
||||
log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", module, cell, cell->type.unescape());
|
||||
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.unescaped());
|
||||
counter++;
|
||||
cell_allowed:;
|
||||
}
|
||||
|
||||
if (cell->type == ID($connect)) {
|
||||
if (cell->type == TW($connect)) {
|
||||
// Inefficient, but rare case in sane design
|
||||
auto sig_a = cell->getPort(TW::A);
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -406,13 +406,13 @@ struct CheckPass : public Pass {
|
|||
wire_drivers_count[bit]++;
|
||||
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,
|
||||
cell, cell->type.unescape()));
|
||||
cell, cell->type.unescaped()));
|
||||
if (output)
|
||||
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()) {
|
||||
if (!edges_db.add_edges_from_cell(cell))
|
||||
coarsened_cells.insert(cell);
|
||||
|
|
@ -529,7 +529,7 @@ struct CheckPass : public Pass {
|
|||
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)) {
|
||||
MatchingEdgePrinter printer(message, sigmap, prev, bit);
|
||||
|
|
|
|||
|
|
@ -24,42 +24,42 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
static RTLIL::IdString formal_flavor(RTLIL::Cell *cell)
|
||||
static TwineRef formal_flavor(RTLIL::Cell *cell)
|
||||
{
|
||||
if (cell->type != ID($check))
|
||||
return cell->type;
|
||||
if (cell->type != TW($check))
|
||||
return cell->type_impl;
|
||||
|
||||
std::string flavor_param = cell->getParam(ID(FLAVOR)).decode_string();
|
||||
if (flavor_param == "assert")
|
||||
return ID($assert);
|
||||
return TW($assert);
|
||||
else if (flavor_param == "assume")
|
||||
return ID($assume);
|
||||
return TW($assume);
|
||||
else if (flavor_param == "cover")
|
||||
return ID($cover);
|
||||
return TW($cover);
|
||||
else if (flavor_param == "live")
|
||||
return ID($live);
|
||||
return TW($live);
|
||||
else if (flavor_param == "fair")
|
||||
return ID($fair);
|
||||
return TW($fair);
|
||||
else
|
||||
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)) {
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{flavor.str()});
|
||||
if (cell->type != TW($check)) {
|
||||
cell->type_impl = flavor;
|
||||
return;
|
||||
}
|
||||
|
||||
if (flavor == ID($assert))
|
||||
if (flavor == TW($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"));
|
||||
else if (flavor == ID($cover))
|
||||
else if (flavor == TW($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"));
|
||||
else if (flavor == ID($fair))
|
||||
else if (flavor == TW($fair))
|
||||
cell->setParam(ID(FLAVOR), std::string("fair"));
|
||||
else
|
||||
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)
|
||||
{
|
||||
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 {
|
||||
|
|
@ -136,7 +136,7 @@ struct ChformalPass : public Pass {
|
|||
bool live2fair = false;
|
||||
bool fair2live = false;
|
||||
|
||||
pool<IdString> constr_types;
|
||||
pool<TwineRef> constr_types;
|
||||
char mode = 0;
|
||||
int mode_arg = 0;
|
||||
|
||||
|
|
@ -144,23 +144,23 @@ struct ChformalPass : public Pass {
|
|||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-assert") {
|
||||
constr_types.insert(ID($assert));
|
||||
constr_types.insert(TW($assert));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-assume") {
|
||||
constr_types.insert(ID($assume));
|
||||
constr_types.insert(TW($assume));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-live") {
|
||||
constr_types.insert(ID($live));
|
||||
constr_types.insert(TW($live));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-fair") {
|
||||
constr_types.insert(ID($fair));
|
||||
constr_types.insert(TW($fair));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-cover") {
|
||||
constr_types.insert(ID($cover));
|
||||
constr_types.insert(TW($cover));
|
||||
continue;
|
||||
}
|
||||
if (mode == 0 && args[argidx] == "-remove") {
|
||||
|
|
@ -222,11 +222,11 @@ struct ChformalPass : public Pass {
|
|||
design->sigNormalize(false);
|
||||
|
||||
if (constr_types.empty()) {
|
||||
constr_types.insert(ID($assert));
|
||||
constr_types.insert(ID($assume));
|
||||
constr_types.insert(ID($live));
|
||||
constr_types.insert(ID($fair));
|
||||
constr_types.insert(ID($cover));
|
||||
constr_types.insert(TW($assert));
|
||||
constr_types.insert(TW($assume));
|
||||
constr_types.insert(TW($live));
|
||||
constr_types.insert(TW($fair));
|
||||
constr_types.insert(TW($cover));
|
||||
}
|
||||
|
||||
if (assert2assume && assert2cover) {
|
||||
|
|
@ -274,13 +274,13 @@ struct ChformalPass : public Pass {
|
|||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type == ID($ff)) {
|
||||
if (cell->type == TW($ff)) {
|
||||
SigSpec D = sigmap(cell->getPort(TW::D));
|
||||
SigSpec Q = sigmap(cell->getPort(TW::Q));
|
||||
for (int i = 0; i < GetSize(D); i++)
|
||||
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 Q = sigmap(cell->getPort(TW::Q));
|
||||
SigSpec C = sigmap(cell->getPort(TW::CLK));
|
||||
|
|
@ -301,7 +301,7 @@ struct ChformalPass : public Pass {
|
|||
cell->setParam(ID::TRG_POLARITY, false);
|
||||
}
|
||||
|
||||
IdString flavor = formal_flavor(cell);
|
||||
TwineRef flavor = formal_flavor(cell);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -312,8 +312,8 @@ struct ChformalPass : public Pass {
|
|||
break;
|
||||
|
||||
if (!init_zero.count(EN)) {
|
||||
if (flavor == ID($cover)) break;
|
||||
if (flavor.in(ID($assert), ID($assume)) && !init_one.count(A)) break;
|
||||
if (flavor == TW($cover)) break;
|
||||
if (flavor.in(TW($assert), TW($assume)) && !init_one.count(A)) break;
|
||||
}
|
||||
|
||||
const auto &A_map = ffmap.at(A);
|
||||
|
|
@ -372,8 +372,8 @@ struct ChformalPass : public Pass {
|
|||
{
|
||||
for (auto cell : constr_cells)
|
||||
{
|
||||
if (cell->type == ID($check)) {
|
||||
Cell *cover = module->addCell(NEW_TWINE_SUFFIX("coverenable"), ID($check));
|
||||
if (cell->type == TW($check)) {
|
||||
Cell *cover = module->addCell(NEW_TWINE_SUFFIX("coverenable"), TW::$check);
|
||||
cover->attributes = cell->attributes;
|
||||
if (cell->src_id() != Twine::Null && module->design)
|
||||
cover->set_src_id(cell->src_id());
|
||||
|
|
@ -395,24 +395,24 @@ struct ChformalPass : public Pass {
|
|||
if (mode == 'c')
|
||||
{
|
||||
for (auto cell : constr_cells) {
|
||||
IdString flavor = formal_flavor(cell);
|
||||
if (assert2assume && flavor == ID($assert))
|
||||
set_formal_flavor(cell, ID($assume));
|
||||
if (assert2cover && flavor == ID($assert))
|
||||
set_formal_flavor(cell, ID($cover));
|
||||
else if (assume2assert && flavor == ID($assume))
|
||||
set_formal_flavor(cell, ID($assert));
|
||||
else if (live2fair && flavor == ID($live))
|
||||
set_formal_flavor(cell, ID($fair));
|
||||
else if (fair2live && flavor == ID($fair))
|
||||
set_formal_flavor(cell, ID($live));
|
||||
TwineRef flavor = formal_flavor(cell);
|
||||
if (assert2assume && flavor == TW($assert))
|
||||
set_formal_flavor(cell, TW($assume));
|
||||
if (assert2cover && flavor == TW($assert))
|
||||
set_formal_flavor(cell, TW($cover));
|
||||
else if (assume2assert && flavor == TW($assume))
|
||||
set_formal_flavor(cell, TW($assert));
|
||||
else if (live2fair && flavor == TW($live))
|
||||
set_formal_flavor(cell, TW($fair));
|
||||
else if (fair2live && flavor == TW($fair))
|
||||
set_formal_flavor(cell, TW($live));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (mode == 'l')
|
||||
{
|
||||
for (auto cell : constr_cells) {
|
||||
if (cell->type != ID($check))
|
||||
if (cell->type != TW($check))
|
||||
continue;
|
||||
|
||||
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::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);
|
||||
|
||||
SigBit combined_en = module->And(NEW_TWINE, sig_a, sig_en);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ struct CleanZeroWidthPass : public Pass {
|
|||
{
|
||||
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.
|
||||
for (auto it: cell->connections()) {
|
||||
if (GetSize(it.second) == 0) {
|
||||
|
|
@ -80,7 +80,7 @@ struct CleanZeroWidthPass : public Pass {
|
|||
if (GetSize(cell->getPort(TW::Q)) == 0) {
|
||||
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
|
||||
// a connection if S_WIDTH is 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->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
|
||||
// connection to the other input.
|
||||
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->remove(cell);
|
||||
}
|
||||
} else if (cell->type == ID($fsm)) {
|
||||
} else if (cell->type == TW($fsm)) {
|
||||
// TODO: not supported
|
||||
} else if (cell->is_mem_cell()) {
|
||||
// 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.
|
||||
if (cell->getParam(ID::WIDTH).as_int() == 0) {
|
||||
module->connect(cell->getPort(TW::Y), cell->getParam(ID::LUT)[0]);
|
||||
module->remove(cell);
|
||||
}
|
||||
} else if (cell->type == ID($sop)) {
|
||||
} else if (cell->type == TW($sop)) {
|
||||
// Zero-width SOP is just a const driver.
|
||||
if (cell->getParam(ID::WIDTH).as_int() == 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.
|
||||
if (cell->getParam(ID::Y_WIDTH).as_int() == 0) {
|
||||
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.
|
||||
} else {
|
||||
if (cell->getParam(ID::A_WIDTH).as_int() == 0) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap &
|
|||
|
||||
for (auto cell : module->cells())
|
||||
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);
|
||||
|
||||
bool need_fixup = false;
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ struct DesignPass : public Pass {
|
|||
{
|
||||
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);
|
||||
|
||||
queue.insert(t);
|
||||
|
|
@ -297,7 +297,7 @@ struct DesignPass : public Pass {
|
|||
if (copy_to_design->module(trg_name) != nullptr)
|
||||
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);
|
||||
|
||||
queue.insert(t);
|
||||
|
|
@ -321,7 +321,7 @@ struct DesignPass : public Pass {
|
|||
if (copy_to_design->module(trg_name) != nullptr)
|
||||
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}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,10 +90,10 @@ struct DftTagWorker {
|
|||
bool design_changed = false;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == ID($overwrite_tag))
|
||||
if (cell->type == TW($overwrite_tag))
|
||||
overwrite_cells.push_back(cell);
|
||||
|
||||
if (cell->type == ID($original_tag))
|
||||
if (cell->type == TW($original_tag))
|
||||
original_cells.push_back(cell);
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ struct DftTagWorker {
|
|||
if (found == modwalker.signal_consumers.end())
|
||||
return;
|
||||
for (auto &consumer : found->second) {
|
||||
if (consumer.cell->type.in(ID($original_tag)))
|
||||
if (consumer.cell->type.in(TW($original_tag)))
|
||||
continue;
|
||||
if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit)
|
||||
continue;
|
||||
|
|
@ -249,7 +249,7 @@ struct DftTagWorker {
|
|||
void propagate_tags()
|
||||
{
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == ID($set_tag)) {
|
||||
if (cell->type == TW($set_tag)) {
|
||||
pending_cells.insert(cell);
|
||||
pending_cell_queue.push_back(cell);
|
||||
}
|
||||
|
|
@ -371,7 +371,7 @@ struct DftTagWorker {
|
|||
|
||||
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());
|
||||
if (all_tags.insert(tag).second) {
|
||||
auto group_sep = tag.str().find(':');
|
||||
|
|
@ -388,25 +388,25 @@ struct DftTagWorker {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == ID($get_tag)) {
|
||||
if (cell->type == TW($get_tag)) {
|
||||
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_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());
|
||||
}
|
||||
forward_tags(sig_y, sig_a);
|
||||
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_a = cell->getPort(TW::A);
|
||||
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_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool());
|
||||
}
|
||||
|
|
@ -415,13 +415,13 @@ struct DftTagWorker {
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
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));
|
||||
|
||||
forward_tags(sig_y, sig_a);
|
||||
|
|
@ -430,7 +430,7 @@ struct DftTagWorker {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
|
||||
if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
|
||||
FfData ff(&initvals, cell);
|
||||
|
||||
if (ff.has_clk || ff.has_gclk)
|
||||
|
|
@ -440,10 +440,10 @@ struct DftTagWorker {
|
|||
|
||||
// Single output but, sensitive to all inputs
|
||||
if (cell->type.in(
|
||||
ID($le), ID($lt), ID($ge), ID($gt),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor),
|
||||
ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and),
|
||||
ID($eq), ID($ne)
|
||||
TW($le), TW($lt), TW($ge), TW($gt),
|
||||
TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor),
|
||||
TW($reduce_bool), TW($logic_not), TW($logic_or), TW($logic_and),
|
||||
TW($eq), TW($ne)
|
||||
)) {
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
|
||||
|
|
@ -456,10 +456,10 @@ struct DftTagWorker {
|
|||
add_tags(cell, tags(cell));
|
||||
|
||||
if (cell->type.in(
|
||||
ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_),
|
||||
ID($_XOR_), ID($_XNOR_), ID($_NOT_), ID($_BUF_), ID($_MUX_),
|
||||
TW($_AND_), TW($_OR_), TW($_NAND_), TW($_NOR_), TW($_ANDNOT_), TW($_ORNOT_),
|
||||
TW($_XOR_), TW($_XNOR_), TW($_NOT_), TW($_BUF_), TW($_MUX_),
|
||||
|
||||
ID($assert), ID($assume)
|
||||
TW($assert), TW($assume)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ struct DftTagWorker {
|
|||
|
||||
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());
|
||||
|
||||
auto tag_sig_a = tag_signal(tag, cell->getPort(TW::A));
|
||||
|
|
@ -494,14 +494,14 @@ struct DftTagWorker {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == ID($get_tag)) {
|
||||
if (cell->type == TW($get_tag)) {
|
||||
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_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());
|
||||
}
|
||||
emit_tag_signal(tag, sig_y, tag_signal(tag, sig_a));
|
||||
|
|
@ -509,13 +509,13 @@ struct DftTagWorker {
|
|||
}
|
||||
|
||||
if (cell->type.in(
|
||||
ID($and), ID($or),
|
||||
ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_)
|
||||
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_a = cell->getPort(TW::A);
|
||||
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_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_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;
|
||||
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
|
||||
inv_b ^= true;
|
||||
|
||||
if (inv_a)
|
||||
|
|
@ -554,11 +554,11 @@ struct DftTagWorker {
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_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_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
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));
|
||||
|
||||
auto group_sig_a = tag_group_signal(tag, sig_a);
|
||||
|
|
@ -606,7 +606,7 @@ struct DftTagWorker {
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_a = cell->getPort(TW::A);
|
||||
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_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);
|
||||
|
||||
auto group_sig_a = tag_group_signal(tag, sig_a);
|
||||
|
|
@ -666,14 +666,14 @@ struct DftTagWorker {
|
|||
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_a = cell->getPort(TW::A);
|
||||
|
||||
auto group_sig_a = tag_group_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);
|
||||
|
||||
auto filled = autoOr(NEW_TWINE, sig_a, group_sig_a);
|
||||
|
|
@ -686,12 +686,12 @@ struct DftTagWorker {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
|
||||
if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
|
||||
FfData ff(&initvals, cell);
|
||||
// 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 && !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;
|
||||
|
||||
|
|
@ -709,7 +709,7 @@ struct DftTagWorker {
|
|||
emit_tag_signal(tag, sig_q, ff.sig_q);
|
||||
return;
|
||||
} 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
|
||||
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
|
||||
// generates tags itself in which case it could be arbitrary).
|
||||
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()
|
||||
|
|
@ -747,7 +747,7 @@ struct DftTagWorker {
|
|||
warned_cells.clear();
|
||||
std::vector<Cell *> get_tag_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);
|
||||
|
||||
for (auto cell : get_tag_cells) {
|
||||
|
|
@ -798,13 +798,13 @@ struct DftTagWorker {
|
|||
std::vector<Cell *> get_tag_cells;
|
||||
std::vector<Cell *> set_tag_cells;
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == ID($get_tag))
|
||||
if (cell->type == TW($get_tag))
|
||||
get_tag_cells.push_back(cell);
|
||||
|
||||
if (cell->type == ID($set_tag))
|
||||
if (cell->type == TW($set_tag))
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -92,12 +92,12 @@ struct EdgetypePass : public Pass {
|
|||
auto sink_bit_index = std::get<2>(sink);
|
||||
|
||||
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", source_cell_type.unescape(), module->design->twines.str(source_port_name).c_str());
|
||||
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", 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)) ?
|
||||
stringf("%s.%s[%d]", sink_cell_type.unescape(), 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[%d]", design->twines.unescaped_str(sink_cell_type), module->design->twines.str(sink_port_name).c_str(), sink_bit_index) :
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,13 +77,13 @@ struct ExampleDtPass : public Pass
|
|||
auto enqueue = [&](DriveSpec const &spec) {
|
||||
int index = queue(spec);
|
||||
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))
|
||||
return compute_graph[graph_nodes[index]];
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ struct ExampleDtPass : public Pass
|
|||
ExampleGraph::Ref node = compute_graph[i];
|
||||
|
||||
if (spec.chunks().size() > 1) {
|
||||
node.set_function(ID($$concat));
|
||||
node.set_function(TW($$concat));
|
||||
|
||||
for (auto const &chunk : spec.chunks()) {
|
||||
node.append_arg(enqueue(chunk));
|
||||
|
|
@ -111,39 +111,39 @@ struct ExampleDtPass : public Pass
|
|||
if (wire_chunk.is_whole()) {
|
||||
node.sparse_attr() = wire_chunk.wire->name;
|
||||
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 {
|
||||
DriveSpec driver = dm(DriveSpec(wire_chunk));
|
||||
node.set_function(ID($$buf));
|
||||
node.set_function(TW($$buf));
|
||||
|
||||
node.append_arg(enqueue(driver));
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
} else if (chunk.is_port()) {
|
||||
DriveChunkPort port_chunk = chunk.port();
|
||||
if (port_chunk.is_whole()) {
|
||||
if (dm.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) {
|
||||
if (port_chunk.cell->type.in(ID($dff), ID($ff)))
|
||||
if (dm.celltypes.cell_output(port_chunk.cell->type_impl, port_chunk.port)) {
|
||||
if (port_chunk.cell->type.in(TW($dff), TW($ff)))
|
||||
{
|
||||
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()) {
|
||||
if (!dm.celltypes.cell_input(cell->type, conn.first))
|
||||
if (!dm.celltypes.cell_input(cell->type_impl, conn.first))
|
||||
continue;
|
||||
enqueue(DriveChunkPort(cell, conn)).assign_key(cell->name);
|
||||
}
|
||||
}
|
||||
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)));
|
||||
}
|
||||
} else {
|
||||
node.set_function(ID($$buf));
|
||||
node.set_function(TW($$buf));
|
||||
|
||||
DriveSpec driver = dm(DriveSpec(port_chunk));
|
||||
node.append_arg(enqueue(driver));
|
||||
|
|
@ -151,14 +151,14 @@ struct ExampleDtPass : public Pass
|
|||
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
} 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()) {
|
||||
node.set_function(ID($$multi));
|
||||
node.set_function(TW($$multi));
|
||||
for (auto const &driver : chunk.multiple().multiple())
|
||||
node.append_arg(enqueue(driver));
|
||||
} else if (chunk.is_marker()) {
|
||||
|
|
@ -166,13 +166,13 @@ struct ExampleDtPass : public Pass
|
|||
|
||||
node.set_function(ExampleFn(cell->type, cell->parameters));
|
||||
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;
|
||||
|
||||
node.append_arg(enqueue(DriveChunkPort(cell, conn)));
|
||||
}
|
||||
} else if (chunk.is_none()) {
|
||||
node.set_function(ID($$undriven));
|
||||
node.set_function(TW($$undriven));
|
||||
|
||||
} else {
|
||||
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)
|
||||
{
|
||||
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()]);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ struct FutureWorker {
|
|||
|
||||
std::vector<Cell *> replaced_cells;
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type != ID($future_ff))
|
||||
if (cell->type != TW($future_ff))
|
||||
continue;
|
||||
|
||||
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)
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
//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_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());
|
||||
|
|
@ -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) {
|
||||
//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());
|
||||
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());
|
||||
|
|
@ -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) {
|
||||
//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());
|
||||
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());
|
||||
|
|
@ -150,13 +150,13 @@ private:
|
|||
auto select_width = metamux_select.as_wire()->width;
|
||||
|
||||
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};
|
||||
log_assert(select_width == 2 || select_width == 3);
|
||||
log_assert(opt_instrumentmore || select_width == 2);
|
||||
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};
|
||||
log_assert(select_width == 2);
|
||||
}
|
||||
|
|
@ -184,10 +184,10 @@ private:
|
|||
std::vector<RTLIL::SigSig> connections(module->connections());
|
||||
|
||||
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);
|
||||
}
|
||||
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 NUM_PORTS = 3;
|
||||
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);
|
||||
log_assert(exp2(select_width) == num_versions);
|
||||
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()));
|
||||
|
||||
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 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 NUM_PORTS = 3;
|
||||
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));
|
||||
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()));
|
||||
|
||||
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 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 NUM_PORTS = 4;
|
||||
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]);
|
||||
}
|
||||
else if (cell->type.in(ID($_NOT_))) {
|
||||
else if (cell->type.in(TW($_NOT_))) {
|
||||
const unsigned int A = 0, Y = 1;
|
||||
const unsigned int NUM_PORTS = 2;
|
||||
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)
|
||||
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]);
|
||||
}
|
||||
else log_cmd_error("This is a bug (3).\n");
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ struct LibertyStubber {
|
|||
}
|
||||
|
||||
f << "\tcell (\"" << derived_name << "\") {\n";
|
||||
auto& base_type = ct.cell_types[base_name];
|
||||
auto& base_type = ct.cell_types[base->name];
|
||||
i.indent = 3;
|
||||
auto sorted_ports = derived->ports;
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
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());
|
||||
return;
|
||||
}
|
||||
|
||||
if (StaticCellTypes::categories.is_ff(base_name))
|
||||
if (StaticCellTypes::categories.is_ff(base->name))
|
||||
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";
|
||||
for (auto x : derived->ports) {
|
||||
std::string port_name = derived->design->twines.str(x);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ struct CoveragePass : public Pass {
|
|||
{
|
||||
log_debug("Module %s:\n", module);
|
||||
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)) {
|
||||
auto filename = extract_src_filename(src);
|
||||
if (filename.empty()) continue;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ struct LtpWorker
|
|||
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 d : dst_bits) {
|
||||
bit2ff[s] = tuple<SigBit, Cell*>(d, cell);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static RTLIL::SigBit canonical_bit(RTLIL::SigBit bit)
|
|||
{
|
||||
RTLIL::Wire *w;
|
||||
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];
|
||||
}
|
||||
return bit;
|
||||
|
|
@ -125,10 +125,10 @@ struct PortarcsPass : Pass {
|
|||
|
||||
for (auto cell : m->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);
|
||||
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) {
|
||||
auto from = edge.first.get_connection(cell);
|
||||
auto to = edge.second.get_connection(cell);
|
||||
|
|
@ -292,7 +292,7 @@ struct PortarcsPass : Pass {
|
|||
int *p = annotations.at(canonical_bit(bit));
|
||||
for (auto i = 0; i < inputs.size(); i++) {
|
||||
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::DST_WIDTH, 1);
|
||||
spec->setParam(ID::T_FALL_MAX, p[i]);
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ struct PrintAttrsPass : public Pass {
|
|||
|
||||
static void log_const(RTLIL::IdString s, const RTLIL::Const &x, const unsigned int indent) {
|
||||
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)
|
||||
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
|
||||
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()) {
|
||||
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;
|
||||
log_src(design, wire, indent);
|
||||
for (auto &it : wire->attributes)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "kernel/rtlil.h"
|
||||
#include "kernel/log.h"
|
||||
#include "backends/verilog/verilog_backend.h"
|
||||
#include "kernel/twine.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
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;
|
||||
IdString QY;
|
||||
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;
|
||||
else
|
||||
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;
|
||||
if (cell->name.isPublic())
|
||||
continue;
|
||||
|
|
@ -386,6 +387,7 @@ struct RenamePass : public Pass {
|
|||
// TODO disable signorm due to rename I think?
|
||||
design->sigNormalize(false);
|
||||
|
||||
TwineSearch search(&design->twines);
|
||||
if (flag_src)
|
||||
{
|
||||
extra_args(args, argidx, design);
|
||||
|
|
@ -527,14 +529,14 @@ struct RenamePass : public Pass {
|
|||
if (argidx+1 != args.size())
|
||||
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();
|
||||
|
||||
if (module == nullptr)
|
||||
log_cmd_error("No top module found!\n");
|
||||
|
||||
log("Renaming module %s to %s.\n", log_id(module), new_name.unescape());
|
||||
design->rename(module, design->twines.add(Twine{new_name.str()}));
|
||||
log("Renaming module %s to %s.\n", log_id(module), design->twines.unescaped_str(new_name));
|
||||
design->rename(module, new_name);
|
||||
}
|
||||
else
|
||||
if (flag_scramble_name)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ struct ScatterPass : public Pass {
|
|||
for (auto conn : cell->connections())
|
||||
new_connections.emplace(conn.first, RTLIL::SigSig(conn.second, module->addWire(NEW_TWINE, GetSize(conn.second))));
|
||||
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));
|
||||
else
|
||||
module->connect(RTLIL::SigSig(it.second.second, it.second.first));
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ struct SccWorker
|
|||
for (auto mod : design->modules())
|
||||
if (mod->get_blackbox_attribute(false))
|
||||
for (auto cell : mod->cells())
|
||||
if (cell->type == ID($specify2))
|
||||
if (cell->type == TW($specify2))
|
||||
{
|
||||
specifyCells.setup_module(mod);
|
||||
break;
|
||||
|
|
@ -138,18 +138,18 @@ struct SccWorker
|
|||
if (!design->selected(module, cell))
|
||||
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;
|
||||
|
||||
workQueue.insert(cell);
|
||||
|
||||
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.
|
||||
for (auto subcell : design->module(cell->type)->cells())
|
||||
{
|
||||
if (subcell->type != ID($specify2))
|
||||
if (subcell->type != TW($specify2))
|
||||
continue;
|
||||
|
||||
for (auto bit : subcell->getPort(TW::SRC))
|
||||
|
|
@ -171,9 +171,9 @@ struct SccWorker
|
|||
{
|
||||
bool isInput = true, isOutput = true;
|
||||
|
||||
if (ct.cell_known(cell->type)) {
|
||||
isInput = ct.cell_input(cell->type, conn.first);
|
||||
isOutput = ct.cell_output(cell->type, conn.first);
|
||||
if (ct.cell_known(cell->type.ref())) {
|
||||
isInput = ct.cell_input(cell->type.ref(), conn.first);
|
||||
isOutput = ct.cell_output(cell->type.ref(), conn.first);
|
||||
}
|
||||
|
||||
RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "kernel/twine.h"
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
|
||||
#include "kernel/register.h"
|
||||
|
|
@ -97,7 +98,7 @@ struct SdcObjects {
|
|||
// constraint-side tracking
|
||||
FullConstraint,
|
||||
} collect_mode;
|
||||
using CellPin = std::pair<Cell*, IdString>;
|
||||
using CellPin = std::pair<Cell*, TwineRef>;
|
||||
Design* design;
|
||||
std::vector<std::pair<std::string, Wire*>> design_ports;
|
||||
std::vector<std::pair<std::string, Cell*>> design_cells;
|
||||
|
|
@ -149,8 +150,8 @@ struct SdcObjects {
|
|||
path += name;
|
||||
design_cells.push_back(std::make_pair(path, cell));
|
||||
for (auto pin : cell->connections()) {
|
||||
IdString pin_name = pin.first;
|
||||
std::string pin_name_sdc = path + "/" + pin.first.str().substr(1);
|
||||
TwineRef pin_name = pin.first;
|
||||
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)));
|
||||
}
|
||||
if (auto sub_mod = mod->design->module(cell->type)) {
|
||||
|
|
@ -168,9 +169,9 @@ struct SdcObjects {
|
|||
RTLIL::Wire *wire = top->wire(port);
|
||||
if (!wire) {
|
||||
// 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{};
|
||||
sniff_module(hierarchy, top);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/twine.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/newcelltypes.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);
|
||||
|
||||
std::vector<RTLIL::IdString> del_list;
|
||||
std::vector<TwineRef> del_list;
|
||||
|
||||
for (auto mod_name : lhs.selected_modules) {
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
std::vector<RTLIL::IdString> del_list2;
|
||||
std::vector<TwineRef> del_list2;
|
||||
for (auto &it2 : it.second)
|
||||
if (!rhs.selected_member(it.first, it2))
|
||||
del_list2.push_back(it2);
|
||||
|
|
@ -487,11 +489,11 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
|
|||
namespace {
|
||||
struct expand_rule_t {
|
||||
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 += ',';
|
||||
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];
|
||||
|
||||
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);
|
||||
|
||||
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 &conn : cell->connections())
|
||||
{
|
||||
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;
|
||||
for (auto &rule : rules) {
|
||||
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;
|
||||
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;
|
||||
if (rule.mode == '+')
|
||||
goto include_match;
|
||||
|
|
@ -558,16 +561,16 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
|
|||
if (last_mode == '+')
|
||||
goto exclude_match;
|
||||
include_match:
|
||||
is_input = mode == 'x' || ct.cell_input(cell->type, conn.first);
|
||||
is_output = mode == 'x' || ct.cell_output(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.ref(), conn.first);
|
||||
for (auto &chunk : conn.second.chunks())
|
||||
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))
|
||||
lhs.selected_members[mod->name].insert(cell->name), 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)
|
||||
lhs.selected_members[mod->meta_->name].insert(cell->name.ref()), sel_objects++, max_objects--;
|
||||
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))
|
||||
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:;
|
||||
}
|
||||
|
|
@ -634,7 +637,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
|
|||
if (design->selection_vars.count(str) > 0) {
|
||||
for (auto i1 : design->selection_vars.at(str).selected_members)
|
||||
for (auto i2 : i1.second)
|
||||
limits.insert(i2);
|
||||
limits.insert(RTLIL::IdString(design->twines.str(i2)));
|
||||
} else
|
||||
log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str));
|
||||
} 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)
|
||||
{
|
||||
if (design->selected_active_module.empty())
|
||||
if (!design->selected_active_module)
|
||||
return;
|
||||
|
||||
if (sel.full_selection) {
|
||||
|
|
@ -691,7 +694,7 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<RTLIL::IdString> del_list;
|
||||
std::vector<TwineRef> del_list;
|
||||
for (auto mod_name : sel.selected_modules)
|
||||
if (mod_name != design->selected_active_module)
|
||||
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;
|
||||
}
|
||||
|
||||
if (!design->selected_active_module.empty()) {
|
||||
arg_mod = design->selected_active_module;
|
||||
if (design->selected_active_module) {
|
||||
arg_mod = design->twines.str(design->selected_active_module);
|
||||
arg_memb = arg;
|
||||
if (!isprefixed(arg_memb))
|
||||
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;
|
||||
|
||||
if (arg_memb == "") {
|
||||
sel.selected_modules.insert(mod->name);
|
||||
sel.selected_modules.insert(mod->meta_->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg_memb.compare(0, 2, "w:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "i:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "o:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "x:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "s:") == 0) {
|
||||
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());
|
||||
for (auto wire : mod->wires())
|
||||
if (wire->width == width)
|
||||
sel.selected_members[mod->name].insert(wire->name);
|
||||
sel.selected_members[mod->meta_->name].insert(wire->name.ref());
|
||||
} else {
|
||||
std::string min_str = arg_memb.substr(2, delim);
|
||||
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());
|
||||
for (auto wire : mod->wires())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "m:") == 0) {
|
||||
for (auto &it : mod->memories)
|
||||
if (match_ids(it.first, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb.substr(2)))
|
||||
sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "c:") == 0) {
|
||||
for (auto cell : mod->cells())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "t:") == 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];
|
||||
for (auto cell : mod->cells())
|
||||
if (muster.selected_modules.count(cell->type))
|
||||
sel.selected_members[mod->name].insert(cell->name);
|
||||
if (muster.selected_modules.count(cell->type.ref()))
|
||||
sel.selected_members[mod->meta_->name].insert(cell->name.ref());
|
||||
} else {
|
||||
for (auto cell : mod->cells())
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "p:") == 0) {
|
||||
for (auto &it : mod->processes)
|
||||
if (match_ids(it.first, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb.substr(2)))
|
||||
sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "a:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
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)
|
||||
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())
|
||||
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)
|
||||
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
|
||||
if (arg_memb.compare(0, 2, "r:") == 0) {
|
||||
for (auto cell : mod->cells())
|
||||
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 {
|
||||
std::string orig_arg_memb = arg_memb;
|
||||
if (arg_memb.compare(0, 2, "n:") == 0)
|
||||
arg_memb = arg_memb.substr(2);
|
||||
for (auto wire : mod->wires())
|
||||
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;
|
||||
}
|
||||
for (auto &it : mod->memories)
|
||||
if (match_ids(it.first, arg_memb)) {
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb)) {
|
||||
sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
for (auto cell : mod->cells())
|
||||
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;
|
||||
}
|
||||
for (auto &it : mod->processes)
|
||||
if (match_ids(it.first, arg_memb)) {
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
if (match_ids(RTLIL::IdString(design->twines.str(it.first)), arg_memb)) {
|
||||
sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1365,6 +1368,7 @@ struct SelectPass : public Pass {
|
|||
|
||||
work_stack.clear();
|
||||
|
||||
TwineSearch search(&design->twines);
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
|
|
@ -1431,10 +1435,11 @@ struct SelectPass : public Pass {
|
|||
continue;
|
||||
}
|
||||
if (arg == "-module" && argidx+1 < args.size()) {
|
||||
RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]);
|
||||
if (design->module(mod_name) == nullptr)
|
||||
log_cmd_error("No such module: %s\n", mod_name.unescape());
|
||||
design->selected_active_module = mod_name.str();
|
||||
std::string mod_name = RTLIL::escape_id(args[++argidx]);
|
||||
TwineRef t = search.find(mod_name);
|
||||
if (t == Twine::Null || design->module(t) == nullptr)
|
||||
log_cmd_error("No such module: %s\n", RTLIL::unescape_id(mod_name));
|
||||
design->selected_active_module = t;
|
||||
got_module = true;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1475,7 +1480,7 @@ struct SelectPass : public Pass {
|
|||
}
|
||||
IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
|
||||
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);
|
||||
|
|
@ -1493,7 +1498,7 @@ struct SelectPass : public Pass {
|
|||
const char *common_flagset = "-add, -del, -assert-none, -assert-any, -assert-mod-count, -assert-count, -assert-max, or -assert-min";
|
||||
|
||||
if (common_flagset_tally > 1)
|
||||
log_cmd_error("Options %s can not be combined.\n", common_flagset);
|
||||
log_cmd_error("Options %s can not be combined.\n", common_flagset);
|
||||
|
||||
if ((list_mode || !write_file.empty() || count_mode) && common_flagset_tally)
|
||||
log_cmd_error("Options -list, -list-mod, -write and -count can not be combined with %s.\n", common_flagset);
|
||||
|
|
@ -1519,7 +1524,7 @@ struct SelectPass : public Pass {
|
|||
|
||||
if (clear_mode) {
|
||||
design->selection() = RTLIL::Selection::FullSelection(design);
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = TwineRef{};
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1545,11 +1550,11 @@ struct SelectPass : public Pass {
|
|||
sel->optimize(design);
|
||||
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);
|
||||
if (!list_mod_mode)
|
||||
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)
|
||||
{
|
||||
|
|
@ -1673,10 +1678,10 @@ struct SelectPass : public Pass {
|
|||
if (sel.full_selection)
|
||||
log("*\n");
|
||||
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 &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;
|
||||
}
|
||||
|
||||
|
|
@ -1728,17 +1733,17 @@ struct CdPass : public Pass {
|
|||
if (args.size() == 1 || args[1] == "/") {
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = TwineRef{};
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[1] == "..")
|
||||
{
|
||||
string modname = design->selected_active_module;
|
||||
string modname = design->twines.str(design->selected_active_module);
|
||||
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = TwineRef{};
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -1748,12 +1753,12 @@ struct CdPass : public Pass {
|
|||
break;
|
||||
|
||||
modname = modname.substr(0, pos);
|
||||
Module *mod = design->module(modname);
|
||||
Module *mod = design->module(RTLIL::IdString(modname));
|
||||
|
||||
if (mod == nullptr)
|
||||
continue;
|
||||
|
||||
design->selected_active_module = modname;
|
||||
design->selected_active_module = design->twines.add(Twine{modname});
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
select_filter_active_mod(design, design->selection());
|
||||
|
|
@ -1766,14 +1771,15 @@ struct CdPass : public Pass {
|
|||
|
||||
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);
|
||||
if (module != nullptr && module->cell(modname) != nullptr)
|
||||
modname = module->cell(modname)->type.str();
|
||||
TwineRef cell_ref = design->twines.lookup(modname);
|
||||
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) {
|
||||
design->selected_active_module = modname;
|
||||
if (design->module(RTLIL::IdString(modname)) != nullptr) {
|
||||
design->selected_active_module = design->twines.add(Twine{modname});
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
select_filter_active_mod(design, design->selection());
|
||||
|
|
@ -1788,17 +1794,20 @@ struct CdPass : public Pass {
|
|||
template<typename T>
|
||||
static void log_matches(const char *title, Module *module, const T &list)
|
||||
{
|
||||
std::vector<IdString> matches;
|
||||
std::vector<TwineRef> matches;
|
||||
|
||||
for (auto &it : list)
|
||||
if (module->selected(it.second))
|
||||
matches.push_back(RTLIL::IdString(it.second->name));
|
||||
matches.push_back(it.first);
|
||||
|
||||
if (!matches.empty()) {
|
||||
log("\n%d %s:\n", int(matches.size()), title);
|
||||
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
|
||||
for (auto id : matches)
|
||||
log(" %s\n", id.unescape());
|
||||
auto &twines = module->design->twines;
|
||||
std::sort(matches.begin(), matches.end(), [&](TwineRef a, TwineRef b) {
|
||||
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;
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (design->selected_active_module.empty())
|
||||
if (!design->selected_active_module)
|
||||
{
|
||||
std::vector<IdString> matches;
|
||||
|
||||
|
|
@ -1836,7 +1845,7 @@ struct LsPass : public Pass {
|
|||
log("\n%d %s:\n", int(matches.size()), "modules");
|
||||
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
|
||||
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
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width
|
|||
RTLIL::Wire *wire = NULL;
|
||||
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);
|
||||
name += "$";
|
||||
|
|
@ -47,7 +47,7 @@ static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width
|
|||
}
|
||||
else
|
||||
{
|
||||
wire = module->addWire(name, width);
|
||||
wire = module->addWire(t, width);
|
||||
wire->port_input = flag_input;
|
||||
wire->port_output = flag_output;
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ struct SetundefPass : public Pass {
|
|||
CellTypes ct(design);
|
||||
for (auto &it : module->cells_)
|
||||
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));
|
||||
|
||||
RTLIL::SigSpec sig = undriven_signals.export_all();
|
||||
|
|
@ -340,7 +340,7 @@ struct SetundefPass : public Pass {
|
|||
CellTypes ct(design);
|
||||
for (auto &it : module->cells_)
|
||||
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));
|
||||
|
||||
RTLIL::SigSpec sig = undriven_signals.export_all();
|
||||
|
|
|
|||
|
|
@ -148,14 +148,15 @@ struct ShowWorker
|
|||
|
||||
std::string findColor(IdString member_name)
|
||||
{
|
||||
TwineRef member_ref = design->twines.lookup(member_name.str());
|
||||
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);
|
||||
}
|
||||
|
||||
RTLIL::Const colorattr_value;
|
||||
RTLIL::Cell *cell = module->cell(member_name);
|
||||
RTLIL::Wire *wire = module->wire(member_name);
|
||||
RTLIL::Cell *cell = member_ref ? module->cell(member_ref) : nullptr;
|
||||
RTLIL::Wire *wire = member_ref ? module->wire(member_ref) : nullptr;
|
||||
|
||||
if (cell && cell->attributes.count(colorattr))
|
||||
colorattr_value = cell->attributes.at(colorattr);
|
||||
|
|
@ -174,8 +175,9 @@ struct ShowWorker
|
|||
|
||||
const char *findLabel(std::string member_name)
|
||||
{
|
||||
TwineRef member_ref = design->twines.lookup(member_name);
|
||||
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(member_name, true);
|
||||
}
|
||||
|
|
@ -240,7 +242,7 @@ struct ShowWorker
|
|||
|
||||
if (sig.is_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)
|
||||
return stringf("n%d", id2num(c.wire->name));
|
||||
} else {
|
||||
|
|
@ -472,10 +474,10 @@ struct ShowWorker
|
|||
std::vector<std::string> in_label_pieces, out_label_pieces;
|
||||
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (!ct.cell_output(cell->type, conn.first))
|
||||
in_ports.push_back(conn.first);
|
||||
if (!ct.cell_output(cell->type.ref(), conn.first))
|
||||
in_ports.push_back(RTLIL::IdString(design->twines.str(conn.first)));
|
||||
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());
|
||||
|
|
@ -501,8 +503,8 @@ struct ShowWorker
|
|||
|
||||
std::string code;
|
||||
for (auto &conn : cell->connections()) {
|
||||
code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(conn.first)),
|
||||
conn.second, ct.cell_output(cell->type, 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.ref(), conn.first));
|
||||
}
|
||||
|
||||
std::string src_href;
|
||||
|
|
@ -523,7 +525,7 @@ struct ShowWorker
|
|||
{
|
||||
RTLIL::Process *proc = it.second;
|
||||
|
||||
if (!design->selected_member(module->name, proc->name))
|
||||
if (!design->selected_member(module->meta_->name, it.first))
|
||||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
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())
|
||||
{
|
||||
bool found_lhs_wire = false;
|
||||
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;
|
||||
}
|
||||
bool found_rhs_wire = false;
|
||||
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;
|
||||
}
|
||||
if (!found_lhs_wire || !found_rhs_wire)
|
||||
|
|
@ -645,16 +648,16 @@ struct ShowWorker
|
|||
module = mod;
|
||||
if (design->selected_whole_module(module->name)) {
|
||||
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;
|
||||
} else
|
||||
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;
|
||||
} 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
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ struct SpliceWorker
|
|||
RTLIL::SigSpec new_sig = sig;
|
||||
|
||||
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::A_WIDTH] = sig_a.size();
|
||||
cell->parameters[ID::Y_WIDTH] = sig.size();
|
||||
|
|
@ -132,7 +132,7 @@ struct SpliceWorker
|
|||
RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
|
||||
for (size_t i = 1; i < chunks.size(); 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::B_WIDTH] = sig2.size();
|
||||
cell->setPort(TW::A, new_sig);
|
||||
|
|
@ -149,7 +149,7 @@ struct SpliceWorker
|
|||
|
||||
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);
|
||||
|
|
@ -165,7 +165,7 @@ struct SpliceWorker
|
|||
|
||||
for (auto cell : module->cells())
|
||||
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);
|
||||
driven_chunks.insert(sig);
|
||||
for (auto &bit : sig.to_sigbit_vector())
|
||||
|
|
@ -189,10 +189,10 @@ struct SpliceWorker
|
|||
if (!sel_by_wire && !design->selected(module, cell))
|
||||
continue;
|
||||
for (auto &conn : cell->connections_)
|
||||
if (ct.cell_input(cell->type, conn.first)) {
|
||||
if (ports.size() > 0 && !ports.count(conn.first))
|
||||
if (ct.cell_input(cell->type.ref(), conn.first)) {
|
||||
if (ports.size() > 0 && !ports.count(RTLIL::IdString(design->twines.str(conn.first))))
|
||||
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;
|
||||
RTLIL::SigSpec sig = sigmap(conn.second);
|
||||
if (!sel_by_cell) {
|
||||
|
|
@ -231,8 +231,8 @@ struct SpliceWorker
|
|||
|
||||
for (auto &it : rework_wires)
|
||||
{
|
||||
RTLIL::IdString orig_name = it.first->name;
|
||||
module->rename(it.first, NEW_ID);
|
||||
TwineRef orig_name = it.first->name.ref();
|
||||
module->rename(it.first, design->twines.add(NEW_TWINE));
|
||||
|
||||
RTLIL::Wire *new_port = module->addWire(orig_name, it.first);
|
||||
it.first->port_id = 0;
|
||||
|
|
|
|||
|
|
@ -181,9 +181,9 @@ struct SplitnetsPass : public Pass {
|
|||
for (auto c : module->cells())
|
||||
for (auto &p : c->connections())
|
||||
{
|
||||
if (!ct.cell_known(c->type))
|
||||
if (!ct.cell_known(c->type.ref()))
|
||||
continue;
|
||||
if (!ct.cell_output(c->type, p.first))
|
||||
if (!ct.cell_output(c->type.ref(), p.first))
|
||||
continue;
|
||||
|
||||
RTLIL::SigSpec sig = p.second;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ struct StaWorker
|
|||
|
||||
struct t_data {
|
||||
Cell* driver;
|
||||
IdString dst_port, src_port;
|
||||
vector<tuple<SigBit,int,IdString>> fanouts;
|
||||
TwineRef dst_port, src_port;
|
||||
vector<tuple<SigBit,int,TwineRef>> fanouts;
|
||||
SigBit backtrack;
|
||||
t_data() : driver(nullptr) {}
|
||||
};
|
||||
|
|
@ -44,7 +44,7 @@ struct StaWorker
|
|||
std::deque<SigBit> queue;
|
||||
struct t_endpoint {
|
||||
Cell *sink;
|
||||
IdString port;
|
||||
TwineRef port;
|
||||
int required;
|
||||
t_endpoint() : sink(nullptr), required(0) {}
|
||||
};
|
||||
|
|
@ -66,23 +66,23 @@ struct StaWorker
|
|||
Module *inst_module = design->module(cell->type);
|
||||
if (!inst_module) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
IdString derived_type = inst_module->derive(design, cell->parameters);
|
||||
TwineRef derived_type = inst_module->derive(design, cell->parameters);
|
||||
inst_module = design->module(derived_type);
|
||||
log_assert(inst_module);
|
||||
|
||||
if (!timing.count(derived_type)) {
|
||||
auto &t = timing.setup_module(inst_module);
|
||||
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);
|
||||
|
|
@ -206,7 +206,7 @@ struct StaWorker
|
|||
log("Latest arrival time in '%s' is %d:\n", module, maxarrival);
|
||||
auto it = endpoints.find(maxbit);
|
||||
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 {
|
||||
log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "<primary output>" : "<unknown>");
|
||||
if (!b.wire->port_output)
|
||||
|
|
@ -217,7 +217,7 @@ struct StaWorker
|
|||
int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset];
|
||||
if (jt->second.driver) {
|
||||
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)
|
||||
log(" %6d %s (%s)\n", arrival, log_signal(b), "<primary input>");
|
||||
|
|
|
|||
|
|
@ -59,18 +59,18 @@ struct statdata_t {
|
|||
double local_sequential_area = 0;
|
||||
double submodule_area = 0;
|
||||
int num_submodules = 0;
|
||||
std::map<RTLIL::IdString, 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, unsigned int, RTLIL::sort_by_id_str> num_submodules_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<RTLIL::IdString, 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, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type;
|
||||
std::map<TwineRef, double, RTLIL::sort_by_id_str> local_area_cells_by_type;
|
||||
std::map<TwineRef, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type;
|
||||
string tech;
|
||||
|
||||
std::map<RTLIL::IdString, 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<RTLIL::IdString, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
|
||||
std::set<RTLIL::IdString> unknown_cell_area;
|
||||
std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type;
|
||||
std::map<TwineRef, double, RTLIL::sort_by_id_str> area_cells_by_type;
|
||||
std::map<TwineRef, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
|
||||
std::set<TwineRef> unknown_cell_area;
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -183,35 +183,35 @@ struct statdata_t {
|
|||
local_num_memory_bits += it.second->width * it.second->size;
|
||||
}
|
||||
for (auto cell : mod->selected_cells()) {
|
||||
RTLIL::IdString cell_type = cell->type;
|
||||
TwineRef cell_type = cell->type_impl;
|
||||
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),
|
||||
ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($lut), ID($and), ID($or),
|
||||
ID($xor), ID($xnor), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), ID($lt),
|
||||
ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), ID($add), ID($sub), ID($mul),
|
||||
ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow), ID($alu))) {
|
||||
if (cell_type.in(TW($not), TW($pos), TW($neg), TW($logic_not), TW($logic_and), TW($logic_or), TW($reduce_and),
|
||||
TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($lut), TW($and), TW($or),
|
||||
TW($xor), TW($xnor), TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx), TW($lt),
|
||||
TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt), TW($add), TW($sub), TW($mul),
|
||||
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_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 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}));
|
||||
} else if (cell_type.in(ID($mux)))
|
||||
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y)));
|
||||
else if (cell_type.in(ID($bmux), ID($pmux)))
|
||||
cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, max<int>({width_a, width_b, width_y}))});
|
||||
} else if (cell_type.in(TW($mux)))
|
||||
cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y)))});
|
||||
else if (cell_type.in(TW($bmux), TW($pmux)))
|
||||
cell_type =
|
||||
stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S)));
|
||||
else if (cell_type == ID($demux))
|
||||
design->twines.add(Twine{stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S)))});
|
||||
else if (cell_type == TW($demux))
|
||||
cell_type =
|
||||
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),
|
||||
ID($sdff), ID($sdffe), ID($sdffce), ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch),
|
||||
ID($dlatchsr)))
|
||||
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q)));
|
||||
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(TW($sr), TW($ff), TW($dff), TW($dffe), TW($dffsr), TW($dffsre), TW($adff), TW($adffe),
|
||||
TW($sdff), TW($sdffe), TW($sdffce), TW($aldff), TW($aldffe), TW($dlatch), TW($adlatch),
|
||||
TW($dlatchsr)))
|
||||
cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q)))});
|
||||
}
|
||||
|
||||
if (!cell_area.empty()) {
|
||||
// check if cell_area provides a area calculator
|
||||
if (cell_area.count(cell->type)) {
|
||||
cell_area_t cell_data = cell_area.at(cell->type);
|
||||
if (cell_area.count(cell->type_impl)) {
|
||||
cell_area_t cell_data = cell_area.at(cell->type_impl);
|
||||
if (cell_data.single_parameter_area.size() > 0) {
|
||||
// assume that we just take the max of the A,B,Y ports
|
||||
|
||||
|
|
@ -337,18 +337,16 @@ struct statdata_t {
|
|||
num_processes++;
|
||||
local_num_processes++;
|
||||
}
|
||||
RTLIL::IdString cell_name = mod->name;
|
||||
auto s = cell_name.str();
|
||||
}
|
||||
|
||||
unsigned int estimate_xilinx_lc()
|
||||
{
|
||||
unsigned int lut6_cnt = num_cells_by_type[ID(LUT6)];
|
||||
unsigned int lut5_cnt = num_cells_by_type[ID(LUT5)];
|
||||
unsigned int lut4_cnt = num_cells_by_type[ID(LUT4)];
|
||||
unsigned int lut3_cnt = num_cells_by_type[ID(LUT3)];
|
||||
unsigned int lut2_cnt = num_cells_by_type[ID(LUT2)];
|
||||
unsigned int lut1_cnt = num_cells_by_type[ID(LUT1)];
|
||||
unsigned int lut6_cnt = num_cells_by_type[TW::LUT6];
|
||||
unsigned int lut5_cnt = num_cells_by_type[TW::LUT5];
|
||||
unsigned int lut4_cnt = num_cells_by_type[TW::LUT4];
|
||||
unsigned int lut3_cnt = num_cells_by_type[TW::LUT3];
|
||||
unsigned int lut2_cnt = num_cells_by_type[TW::LUT2];
|
||||
unsigned int lut1_cnt = num_cells_by_type[TW::LUT1];
|
||||
unsigned int lc_cnt = 0;
|
||||
|
||||
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);
|
||||
|
|
@ -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);
|
||||
for (auto &it : num_cells_by_type)
|
||||
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,
|
||||
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);
|
||||
|
|
@ -533,7 +531,7 @@ struct statdata_t {
|
|||
print_global_only);
|
||||
for (auto &it : num_submodules_by_type)
|
||||
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,
|
||||
print_area, print_hierarchical, print_global_only);
|
||||
}
|
||||
|
|
@ -582,7 +580,7 @@ struct statdata_t {
|
|||
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)
|
||||
log(",\n");
|
||||
|
|
@ -607,7 +605,7 @@ struct statdata_t {
|
|||
if (it.second) {
|
||||
if (!first_line)
|
||||
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,
|
||||
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))
|
||||
|
|
@ -621,7 +619,7 @@ struct statdata_t {
|
|||
if (it.second) {
|
||||
if (!first_line)
|
||||
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,
|
||||
submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0)
|
||||
.c_str());
|
||||
|
|
@ -662,14 +660,14 @@ struct statdata_t {
|
|||
if (it.second) {
|
||||
if (!first_line)
|
||||
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;
|
||||
}
|
||||
for (auto &it : num_submodules_by_type)
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
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;
|
||||
}
|
||||
log("\n");
|
||||
|
|
@ -697,14 +695,14 @@ struct statdata_t {
|
|||
if (it.second) {
|
||||
if (!first_line)
|
||||
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;
|
||||
}
|
||||
for (auto &it : num_submodules_by_type)
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
if (mod_stat.count(it.first) > 0) {
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
|
||||
bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
|
||||
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<TwineRef, statdata_t> &mod_stat,
|
||||
bool width_mode, dict<TwineRef, cell_area_t> &cell_area, string techname)
|
||||
{
|
||||
if (top_mod == nullptr)
|
||||
top_mod = design->top_module();
|
||||
statdata_t mod_data(design, top_mod, width_mode, cell_area, techname);
|
||||
for (auto cell : top_mod->selected_cells()) {
|
||||
if (cell_area.count(cell->type) == 0) {
|
||||
if (design->has(cell->type)) {
|
||||
if (cell_area.count(cell->type_impl) == 0) {
|
||||
if (design->has(cell->type_impl)) {
|
||||
if (!(design->module(cell->type)->attributes.count(ID::blackbox))) {
|
||||
// deal with modules
|
||||
mod_data.add(
|
||||
hierarchy_builder(design, design->module(cell->type), mod_stat, width_mode, cell_area, techname));
|
||||
mod_data.num_submodules_by_type[cell->type]++;
|
||||
mod_data.submodules_area_by_type[cell->type] += mod_stat.at(cell->type).area;
|
||||
mod_data.submodule_area += mod_stat.at(cell->type).area;
|
||||
mod_data.num_submodules_by_type[cell->type_impl]++;
|
||||
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_impl).area;
|
||||
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_by_type.count(cell->type) != 0) ? mod_data.num_cells_by_type.at(cell->type) : 0;
|
||||
mod_data.num_cells_by_type.erase(cell->type);
|
||||
mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0)
|
||||
? mod_data.local_num_cells_by_type.at(cell->type)
|
||||
(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_impl);
|
||||
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_impl)
|
||||
: 0;
|
||||
mod_data.local_num_cells_by_type.erase(cell->type);
|
||||
mod_data.local_area_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_impl);
|
||||
} else {
|
||||
// deal with blackbox cells
|
||||
if (design->module(cell->type)->attributes.count(ID::area) &&
|
||||
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.submodules_area_by_type[cell->type] +=
|
||||
double(design->module(cell->type)->attributes.at(ID::area).as_int());
|
||||
mod_data.area += double(design->module(cell->type)->attributes.at(ID::area).as_int());
|
||||
mod_data.unknown_cell_area.erase(cell->type);
|
||||
mod_data.submodules_area_by_type[cell->type_impl] +=
|
||||
double(design->module(cell->type_impl)->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_impl);
|
||||
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.erase(cell->type);
|
||||
mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0)
|
||||
? mod_data.local_num_cells_by_type.at(cell->type)
|
||||
(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_impl);
|
||||
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_impl)
|
||||
: 0;
|
||||
mod_data.local_num_cells_by_type.erase(cell->type);
|
||||
mod_data.local_area_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_impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -797,7 +795,7 @@ statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod
|
|||
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());
|
||||
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()) {
|
||||
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};
|
||||
}
|
||||
}
|
||||
|
|
@ -927,8 +926,8 @@ struct StatPass : public Pass {
|
|||
{
|
||||
bool width_mode = false, json_mode = false, hierarchy_mode = false;
|
||||
RTLIL::Module *top_mod = nullptr;
|
||||
std::map<RTLIL::IdString, statdata_t> mod_stat;
|
||||
dict<IdString, cell_area_t> cell_area;
|
||||
std::map<TwineRef, statdata_t> mod_stat;
|
||||
dict<TwineRef, cell_area_t> cell_area;
|
||||
string techname;
|
||||
|
||||
size_t argidx;
|
||||
|
|
@ -940,7 +939,7 @@ struct StatPass : public Pass {
|
|||
if (args[argidx] == "-liberty" && argidx + 1 < args.size()) {
|
||||
string liberty_file = args[++argidx];
|
||||
rewrite_filename(liberty_file);
|
||||
read_liberty_cellarea(cell_area, liberty_file);
|
||||
read_liberty_cellarea(design->twines, cell_area, liberty_file);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-tech" && argidx + 1 < args.size()) {
|
||||
|
|
@ -1005,13 +1004,13 @@ struct StatPass : public Pass {
|
|||
top_mod = mod;
|
||||
statdata_t data = mod_stat.at(mod->name);
|
||||
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;
|
||||
} else {
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
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) {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ struct TestPatchPass : public Pass {
|
|||
for (auto module : design->selected_modules()) {
|
||||
SigMap sigmap(module);
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type == ID($add)) {
|
||||
if (cell->type == TW($add)) {
|
||||
Cell* add = cell;
|
||||
log_assert(add->getPort(TW::B).is_wire());
|
||||
log_assert(add->getPort(TW::B).known_driver());
|
||||
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);
|
||||
int width = cell->getPort(TW::A).size();
|
||||
auto sub = patcher.addSub(NEW_TWINE,
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ struct EstimateSta {
|
|||
// and to account for the AIG model not being balanced
|
||||
int cell_type_factor(IdString type)
|
||||
{
|
||||
if (type.in(ID($gt), ID($ge), ID($lt), ID($le), ID($add), ID($sub),
|
||||
ID($logic_not), ID($reduce_and), ID($reduce_or), ID($eq)))
|
||||
if (type.in(TW($gt), TW($ge), TW($lt), TW($le), TW($add), TW($sub),
|
||||
TW($logic_not), TW($reduce_and), TW($reduce_or), TW($eq)))
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
|
|
@ -97,7 +97,7 @@ struct EstimateSta {
|
|||
FfData ff(nullptr, cell);
|
||||
if (!ff.has_clk) {
|
||||
log_warning("Ignoring unsupported storage element '%s' (%s)\n",
|
||||
cell, cell->type.unescape());
|
||||
cell, cell->type.unescaped());
|
||||
continue;
|
||||
}
|
||||
if (!clk || ff.sig_clk.as_bit() != *clk)
|
||||
|
|
@ -112,7 +112,7 @@ struct EstimateSta {
|
|||
} else if (cell->is_mem_cell()) {
|
||||
// memories handled separately
|
||||
continue;
|
||||
} else if (cell->type == ID($scopeinfo)) {
|
||||
} else if (cell->type == TW($scopeinfo)) {
|
||||
continue;
|
||||
} else {
|
||||
// find or build AIG model of combinational cell
|
||||
|
|
@ -121,7 +121,7 @@ struct EstimateSta {
|
|||
aigs.emplace(fingerprint, Aig(cell));
|
||||
if (aigs.at(fingerprint).name.empty()) {
|
||||
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();
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -83,13 +83,13 @@ struct TorderPass : public Pass {
|
|||
for (auto cell : module->selected_cells())
|
||||
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;
|
||||
|
||||
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))
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -309,12 +309,12 @@ struct Graph {
|
|||
{
|
||||
GraphNode *g = nullptr;
|
||||
|
||||
if (!grp.second.selected_module(module->name))
|
||||
if (!grp.second.selected_module(module->meta_->name))
|
||||
continue;
|
||||
|
||||
for (auto wire : module->wires()) {
|
||||
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)) {
|
||||
auto it = wire_nodes.find(bit);
|
||||
if (it == wire_nodes.end())
|
||||
|
|
@ -708,8 +708,8 @@ struct VizWorker
|
|||
c->attributes.erase(vg_id);
|
||||
for (auto g : graph.nodes) {
|
||||
for (auto name : g->names()) {
|
||||
auto w = module->wire(name);
|
||||
auto c = module->cell(name);
|
||||
auto w = module->wire(module->design->twines.lookup(name.str()));
|
||||
auto c = module->cell(module->design->twines.lookup(name.str()));
|
||||
if (w) w->attributes[vg_id] = g->index;
|
||||
if (c) c->attributes[vg_id] = g->index;
|
||||
}
|
||||
|
|
@ -718,7 +718,7 @@ struct VizWorker
|
|||
|
||||
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");
|
||||
|
||||
dict<GraphNode*, std::vector<std::vector<std::string>>> extra_lines;
|
||||
|
|
@ -782,7 +782,7 @@ struct VizWorker
|
|||
g->names().sort();
|
||||
std::string label; // = stringf("vg=%d\\n", g->index);
|
||||
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());
|
||||
} else {
|
||||
std::string label = stringf("vg=%d | %d cells", g->index, GetSize(g->names()));
|
||||
|
|
|
|||
|
|
@ -208,13 +208,13 @@ struct WrapcellPass : Pass {
|
|||
Module *subm;
|
||||
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",
|
||||
cell->type.unescape(), cell, module);
|
||||
cell->type.unescaped(), cell, module);
|
||||
|
||||
std::vector<std::pair<IdString, int>> unused_outputs, used_outputs;
|
||||
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++) {
|
||||
if (tracking_unused && unused.check(conn.second[i]))
|
||||
unused_outputs.emplace_back(conn.first, i);
|
||||
|
|
@ -227,7 +227,7 @@ struct WrapcellPass : Pass {
|
|||
if (!unused_outputs.empty()) {
|
||||
context.unused_outputs += "_unused";
|
||||
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);
|
||||
|
|
@ -242,7 +242,7 @@ struct WrapcellPass : Pass {
|
|||
subm = d->addModule(name);
|
||||
subcell = subm->addCell("$1", cell->type);
|
||||
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
|
||||
subcell->setPort(conn.first, SigSpec(RTLIL::Sm, conn.second.size()));
|
||||
} else {
|
||||
|
|
@ -286,7 +286,7 @@ struct WrapcellPass : Pass {
|
|||
dict<IdString, SigSpec> new_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;
|
||||
|
||||
for (auto chunk : collect_chunks(used_outputs))
|
||||
|
|
|
|||
|
|
@ -294,18 +294,18 @@ struct XpropWorker
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
if (cell->type.in(ID($pmux))) {
|
||||
if (cell->type.in(TW($pmux))) {
|
||||
mark_outputs_maybe_x(cell);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
|
||||
if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
|
||||
FfData ff(&initvals, cell);
|
||||
|
||||
if (cell->type != ID($anyinit))
|
||||
if (cell->type != TW($anyinit))
|
||||
for (int i = 0; i < ff.width; i++)
|
||||
if (ff.val_init[i] == State::Sx)
|
||||
mark_maybe_x(ff.sig_q[i]);
|
||||
|
|
@ -318,7 +318,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == ID($not)) {
|
||||
if (cell->type == TW($not)) {
|
||||
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());
|
||||
for (int i = 0; i < GetSize(sig_y); i++)
|
||||
|
|
@ -327,7 +327,7 @@ struct XpropWorker
|
|||
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_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());
|
||||
|
|
@ -337,7 +337,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($bwmux))) {
|
||||
if (cell->type.in(TW($bwmux))) {
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
auto &sig_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -348,7 +348,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -372,7 +372,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($demux))) {
|
||||
if (cell->type.in(TW($demux))) {
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
auto &sig_a = cell->getPort(TW::A);
|
||||
auto &sig_s = cell->getPort(TW::S);
|
||||
|
|
@ -387,7 +387,7 @@ struct XpropWorker
|
|||
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_y = cell->getPort(TW::Y);
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($shiftx))) {
|
||||
if (cell->type.in(TW($shiftx))) {
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
|
||||
|
|
@ -438,24 +438,24 @@ struct XpropWorker
|
|||
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))
|
||||
mark_outputs_maybe_x(cell);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(
|
||||
ID($le), ID($lt), ID($ge), ID($gt),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor),
|
||||
ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and),
|
||||
ID($eq), ID($ne),
|
||||
TW($le), TW($lt), TW($ge), TW($gt),
|
||||
TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor),
|
||||
TW($reduce_bool), TW($logic_not), TW($logic_or), TW($logic_and),
|
||||
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);
|
||||
if (inputs_maybe_x(cell))
|
||||
|
|
@ -463,11 +463,11 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($scopeinfo))) {
|
||||
if (cell->type.in(TW($scopeinfo))) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +481,7 @@ struct XpropWorker
|
|||
{
|
||||
if (!ports_maybe_x(cell)) {
|
||||
|
||||
if (cell->type == ID($bweq)) {
|
||||
if (cell->type == TW($bweq)) {
|
||||
auto sig_y = cell->getPort(TW::Y);
|
||||
auto sig_a = cell->getPort(TW::A);
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -492,7 +492,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -500,7 +500,7 @@ struct XpropWorker
|
|||
RTLIL::IdString name(cell->name);
|
||||
auto type = cell->type;
|
||||
module->remove(cell);
|
||||
if (type == ID($eqx))
|
||||
if (type == TW($eqx))
|
||||
module->addEq(name, sig_a, sig_b, sig_y);
|
||||
else
|
||||
module->addNe(name, sig_a, sig_b, sig_y);
|
||||
|
|
@ -510,10 +510,10 @@ struct XpropWorker
|
|||
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_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());
|
||||
|
||||
auto enc_a = encoded(sig_a);
|
||||
|
|
@ -527,11 +527,11 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_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_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();
|
||||
if (cell->type.in(ID($_NAND_), ID($_NOR_)))
|
||||
if (cell->type.in(TW($_NAND_), TW($_NOR_)))
|
||||
enc_y.invert();
|
||||
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
if (cell->type.in(TW($_ANDNOT_), TW($_ORNOT_)))
|
||||
enc_b.invert();
|
||||
|
||||
enc_y.connect_0(module->Or(NEW_TWINE, enc_a.is_0, enc_b.is_0));
|
||||
|
|
@ -554,7 +554,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
|
||||
|
|
@ -563,9 +563,9 @@ struct XpropWorker
|
|||
|
||||
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();
|
||||
if (cell->type == ID($logic_not))
|
||||
if (cell->type == TW($logic_not))
|
||||
enc_a.invert();
|
||||
|
||||
enc_y.connect_0(module->ReduceOr(NEW_TWINE, enc_a.is_0));
|
||||
|
|
@ -576,7 +576,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
|
||||
|
|
@ -584,7 +584,7 @@ struct XpropWorker
|
|||
auto enc_y = encoded(sig_y, true);
|
||||
|
||||
enc_y.connect_as_bool();
|
||||
if (cell->type == ID($reduce_xnor))
|
||||
if (cell->type == TW($reduce_xnor))
|
||||
enc_y.invert();
|
||||
|
||||
|
||||
|
|
@ -596,7 +596,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_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.connect_0(module->Or(NEW_TWINE, a_is_0, b_is_0));
|
||||
|
|
@ -622,11 +622,11 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_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_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.connect_x(module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x));
|
||||
|
|
@ -645,7 +645,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -658,7 +658,7 @@ struct XpropWorker
|
|||
auto enc_y = encoded(sig_y, true);
|
||||
enc_y.connect_as_bool();
|
||||
|
||||
if (cell->type == ID($ne))
|
||||
if (cell->type == TW($ne))
|
||||
enc_y.invert();
|
||||
|
||||
auto delta = module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1);
|
||||
|
|
@ -671,7 +671,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -687,7 +687,7 @@ struct XpropWorker
|
|||
|
||||
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);
|
||||
if (GetSize(sig_y) > 1)
|
||||
|
|
@ -696,7 +696,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($bweqx))) {
|
||||
if (cell->type.in(TW($bweqx))) {
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
auto &sig_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -711,13 +711,13 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
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));
|
||||
|
||||
auto enc_a = encoded(sig_a);
|
||||
|
|
@ -736,7 +736,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($pmux))) {
|
||||
if (cell->type.in(TW($pmux))) {
|
||||
auto &sig_y = cell->getPort(TW::Y);
|
||||
auto &sig_a = cell->getPort(TW::A);
|
||||
auto &sig_b = cell->getPort(TW::B);
|
||||
|
|
@ -771,7 +771,7 @@ struct XpropWorker
|
|||
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_a = cell->getPort(TW::A);
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
|
@ -813,7 +813,7 @@ struct XpropWorker
|
|||
|
||||
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);
|
||||
|
||||
enc_y.connect_0(module->And(NEW_TWINE, y_0, SigSpec(not_all_x, GetSize(sig_y))));
|
||||
|
|
@ -824,7 +824,7 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($ff))) {
|
||||
if (cell->type.in(TW($ff))) {
|
||||
auto &sig_d = cell->getPort(TW::D);
|
||||
auto &sig_q = cell->getPort(TW::Q);
|
||||
|
||||
|
|
@ -857,12 +857,12 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
|
||||
if (cell->is_builtin_ff() || cell->type == TW($anyinit)) {
|
||||
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 && 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 {
|
||||
auto init_q = ff.val_init;
|
||||
auto init_q_is_1 = init_q;
|
||||
|
|
@ -907,15 +907,15 @@ struct XpropWorker
|
|||
return;
|
||||
}
|
||||
} 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
|
||||
if (cell->type.in(
|
||||
ID($neg),
|
||||
ID($le), ID($lt), ID($ge), ID($gt),
|
||||
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)
|
||||
TW($neg),
|
||||
TW($le), TW($lt), TW($ge), TW($gt),
|
||||
TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor)
|
||||
)) {
|
||||
|
||||
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 invalid = module->LogicNot(NEW_TWINE, sig_b);
|
||||
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));
|
||||
|
||||
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()) {
|
||||
if (cell->output(conn.first)) {
|
||||
|
|
@ -958,15 +958,15 @@ struct XpropWorker
|
|||
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");
|
||||
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");
|
||||
|
||||
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
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ struct EquivInductWorker : public EquivWorker<>
|
|||
if (!satgen.importCell(cell, step)) {
|
||||
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_b = sigmap(cell->getPort(TW::B)).as_bit();
|
||||
if (bit_a != bit_b) {
|
||||
|
|
@ -88,14 +88,14 @@ struct EquivInductWorker : public EquivWorker<>
|
|||
|
||||
if (satgen.model_undef) {
|
||||
for (auto cell : cells)
|
||||
if (yosys_celltypes.cell_known(cell->type))
|
||||
if (yosys_celltypes.cell_known(cell->type_impl))
|
||||
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));
|
||||
for (auto cell : cells)
|
||||
if (yosys_celltypes.cell_known(cell->type))
|
||||
if (yosys_celltypes.cell_known(cell->type_impl))
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ struct EquivInductPass : public Pass {
|
|||
vector<Cell*> assume_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))
|
||||
unproven_equiv_cells.insert(cell);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ struct EquivMakeWorker
|
|||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
cell_names.insert(it->name);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ struct EquivMakeWorker
|
|||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
cell_names.insert(it->name);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ struct EquivMakeWorker
|
|||
|
||||
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 *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",
|
||||
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)
|
||||
{
|
||||
|
|
@ -310,7 +310,7 @@ struct EquivMakeWorker
|
|||
|
||||
for (auto c : cells_list)
|
||||
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 new_sig = rd_signal_map(old_sig);
|
||||
for (int i = 0; i < GetSize(old_sig); i++)
|
||||
|
|
@ -318,7 +318,7 @@ struct EquivMakeWorker
|
|||
new_sig[i] = old_sig[i];
|
||||
if (old_sig != new_sig) {
|
||||
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));
|
||||
c->setPort(conn.first, new_sig);
|
||||
}
|
||||
|
|
@ -339,7 +339,7 @@ struct EquivMakeWorker
|
|||
Cell *gold_cell = equiv_mod->cell(gold_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()))
|
||||
try_next_cell_name:
|
||||
continue;
|
||||
|
|
@ -349,14 +349,14 @@ struct EquivMakeWorker
|
|||
goto try_next_cell_name;
|
||||
|
||||
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())
|
||||
{
|
||||
SigSpec gold_sig = assign_map(gold_conn.second);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -403,7 +403,7 @@ struct EquivMakeWorker
|
|||
|
||||
for (auto cell : equiv_mod->cells()) {
|
||||
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))
|
||||
undriven_bits.erase(bit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ struct EquivMarkWorker
|
|||
{
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID($equiv))
|
||||
if (cell->type == TW($equiv))
|
||||
equiv_cells.insert(cell->meta_->name);
|
||||
|
||||
for (auto &port : cell->connections())
|
||||
|
|
@ -139,7 +139,7 @@ struct EquivMarkWorker
|
|||
|
||||
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;
|
||||
|
||||
SigSpec sig_a = sigmap(cell->getPort(TW::A));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue