mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
f592f2f3af
commit
8e522b08c0
206 changed files with 3081 additions and 2782 deletions
|
|
@ -776,7 +776,7 @@ struct AigerWriter
|
|||
if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_), ID($anyinit), ID($anyconst), ID($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)) ? ID::Y : ID::Q);
|
||||
auto sig_qy = cell->getPort(cell->type.in(ID($anyconst), ID($anyseq)) ? TW::Y : TW::Q);
|
||||
SigSpec sig = sigmap(sig_qy);
|
||||
|
||||
if (cell->get_bool_attribute(ID(clk2fflogic)))
|
||||
|
|
|
|||
|
|
@ -248,14 +248,16 @@ struct XAigerWriter
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!timing.count(inst_module->name))
|
||||
auto inst_name_id = RTLIL::IdString(design->twines.str(inst_module->meta_->name));
|
||||
if (!timing.count(inst_name_id))
|
||||
timing.setup_module(inst_module);
|
||||
|
||||
for (auto &i : timing.at(inst_module->name).arrival) {
|
||||
if (!cell->hasPort(i.first.name))
|
||||
for (auto &i : timing.at(inst_name_id).arrival) {
|
||||
auto port_name_ref = design->twines.add(Twine{i.first.name.str()});
|
||||
if (!cell->hasPort(port_name_ref))
|
||||
continue;
|
||||
|
||||
auto port_wire = inst_module->wire(i.first.name);
|
||||
auto port_wire = inst_module->wire(port_name_ref);
|
||||
log_assert(port_wire->port_output);
|
||||
|
||||
auto d = i.second.first;
|
||||
|
|
@ -263,14 +265,14 @@ struct XAigerWriter
|
|||
continue;
|
||||
auto offset = i.first.offset;
|
||||
|
||||
auto rhs = cell->getPort(i.first.name);
|
||||
auto rhs = cell->getPort(port_name_ref);
|
||||
if (offset >= rhs.size())
|
||||
continue;
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (ys_debug(1)) {
|
||||
static pool<std::pair<IdString,TimingInfo::NameBit>> seen;
|
||||
if (seen.emplace(inst_module->name, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n",
|
||||
if (seen.emplace(inst_name_id, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n",
|
||||
cell->type.unescape(), i.first.name.unescape(), offset, d);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -288,7 +290,7 @@ struct XAigerWriter
|
|||
auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first);
|
||||
auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first);
|
||||
if (!is_input && !is_output)
|
||||
log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", c.first.unescape(), cell, cell->type.unescape());
|
||||
log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", RTLIL::IdString(design->twines.str(c.first)).unescape(), cell, cell->type.unescape());
|
||||
|
||||
if (is_input)
|
||||
for (auto b : c.second) {
|
||||
|
|
@ -309,7 +311,7 @@ struct XAigerWriter
|
|||
//log_warning("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell);
|
||||
}
|
||||
|
||||
dict<IdString, std::vector<IdString>> box_ports;
|
||||
dict<IdString, std::vector<TwineRef>> box_ports;
|
||||
for (auto cell : box_list) {
|
||||
log_assert(cell);
|
||||
|
||||
|
|
@ -321,18 +323,18 @@ struct XAigerWriter
|
|||
if (r.second) {
|
||||
// Make carry in the last PI, and carry out the last PO
|
||||
// since ABC requires it this way
|
||||
IdString carry_in, carry_out;
|
||||
TwineRef carry_in = Twine::Null, carry_out = Twine::Null;
|
||||
for (const auto &port_name : box_module->ports) {
|
||||
auto w = box_module->wire(port_name);
|
||||
log_assert(w);
|
||||
if (w->get_bool_attribute(ID::abc9_carry)) {
|
||||
if (w->port_input) {
|
||||
if (carry_in != IdString())
|
||||
if (carry_in != Twine::Null)
|
||||
log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", box_module);
|
||||
carry_in = port_name;
|
||||
}
|
||||
if (w->port_output) {
|
||||
if (carry_out != IdString())
|
||||
if (carry_out != Twine::Null)
|
||||
log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", box_module);
|
||||
carry_out = port_name;
|
||||
}
|
||||
|
|
@ -341,11 +343,11 @@ struct XAigerWriter
|
|||
r.first->second.push_back(port_name);
|
||||
}
|
||||
|
||||
if (carry_in != IdString() && carry_out == IdString())
|
||||
if (carry_in != Twine::Null && carry_out == Twine::Null)
|
||||
log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", box_module);
|
||||
if (carry_in == IdString() && carry_out != IdString())
|
||||
if (carry_in == Twine::Null && carry_out != Twine::Null)
|
||||
log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", box_module);
|
||||
if (carry_in != IdString()) {
|
||||
if (carry_in != Twine::Null) {
|
||||
r.first->second.push_back(carry_in);
|
||||
r.first->second.push_back(carry_out);
|
||||
}
|
||||
|
|
@ -646,7 +648,7 @@ struct XAigerWriter
|
|||
holes_design = it->second;
|
||||
else
|
||||
holes_design = nullptr;
|
||||
RTLIL::Module *holes_module = holes_design ? holes_design->module(module->name) : nullptr;
|
||||
RTLIL::Module *holes_module = holes_design ? holes_design->module(module->meta_->name) : nullptr;
|
||||
if (holes_module) {
|
||||
std::stringstream a_buffer;
|
||||
XAigerWriter writer(holes_module, false /* dff_mode */);
|
||||
|
|
@ -712,7 +714,7 @@ struct XAigerWriter
|
|||
|
||||
int box_count = 0;
|
||||
for (auto cell : box_list)
|
||||
f << stringf("box %d %d %s\n", box_count++, 0, cell->name.unescape());
|
||||
f << stringf("box %d %d %s\n", box_count++, 0, cell->module->design->twines.str(cell->meta_->name));
|
||||
|
||||
output_lines.sort();
|
||||
for (auto &it : output_lines)
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ struct Index {
|
|||
return lits.front();
|
||||
}
|
||||
|
||||
Lit impl_op(HierCursor &cursor, Cell *cell, IdString oport, int obit)
|
||||
Lit impl_op(HierCursor &cursor, Cell *cell, TwineRef oport, int obit)
|
||||
{
|
||||
if (cell->type.in(REDUCE_OPS, LOGIC_OPS, CMP_OPS) && obit != 0) {
|
||||
return CFALSE;
|
||||
|
|
@ -418,9 +418,9 @@ struct Index {
|
|||
} else if (cell->type.in(ID($fa))) {
|
||||
Lit c = visit(cursor, cell->getPort(TW::C)[obit]);
|
||||
Lit ab = XOR(a, b);
|
||||
if (oport == ID::Y) {
|
||||
if (oport == TW::Y) {
|
||||
return XOR(ab, c);
|
||||
} else /* oport == ID::X */ {
|
||||
} else /* oport == TW::X */ {
|
||||
Lit a_and_b = AND(a, b);
|
||||
Lit c_and_ab = AND(c, ab);
|
||||
return OR(a_and_b, c_and_ab);
|
||||
|
|
@ -556,13 +556,14 @@ struct Index {
|
|||
{
|
||||
std::string ret;
|
||||
bool first = true;
|
||||
Design *design = levels[0].first.module ? levels[0].first.module->design : nullptr;
|
||||
for (auto [minfo, cell] : levels) {
|
||||
if (!first)
|
||||
ret += ".";
|
||||
if (!cell)
|
||||
ret += minfo.module->name.unescape();
|
||||
ret += design->twines.str(minfo.module->meta_->name);
|
||||
else
|
||||
ret += cell->name.unescape();
|
||||
ret += design->twines.str(cell->meta_->name);
|
||||
first = false;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -636,10 +637,10 @@ struct Index {
|
|||
Wire *w = def->wire(portname);
|
||||
if (!w)
|
||||
log_error("Output port %s on instance %s of %s doesn't exist\n",
|
||||
portname.unescape(), driver, def);
|
||||
design->twines.str(portname).c_str(), driver, def);
|
||||
if (bit.offset >= w->width)
|
||||
log_error("Bit position %d of output port %s on instance %s of %s is out of range (port has width %d)\n",
|
||||
bit.offset, portname.unescape(), driver, def, w->width);
|
||||
bit.offset, design->twines.str(portname).c_str(), driver, def, w->width);
|
||||
ret = visit(cursor, SigBit(w, bit.offset));
|
||||
}
|
||||
cursor.exit(*this);
|
||||
|
|
@ -652,14 +653,14 @@ struct Index {
|
|||
// step into the upper module
|
||||
Cell *instance = cursor.exit(*this);
|
||||
{
|
||||
TwineRef portname = bit.wire->name;
|
||||
TwineRef portname = bit.wire->meta_->name;
|
||||
if (!instance->hasPort(portname))
|
||||
log_error("Input port %s on instance %s of %s unconnected\n",
|
||||
portname.unescape(), instance, instance->type);
|
||||
design->twines.str(portname).c_str(), instance, instance->type);
|
||||
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, portname.unescape(), instance, instance->type.unescape());
|
||||
bit.offset, design->twines.str(portname).c_str(), instance, instance->type.unescape());
|
||||
ret = visit(cursor, port[bit.offset]);
|
||||
}
|
||||
cursor.enter(*this, instance);
|
||||
|
|
@ -905,7 +906,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
int max = 1;
|
||||
for (auto wire : mod->wires()) {
|
||||
if (wire->port_input && !wire->port_output) {
|
||||
SigSpec port = driver->getPort(wire->name);
|
||||
SigSpec port = driver->getPort(wire->meta_->name);
|
||||
for (int i = 0; i < std::min(wire->width, port.size()); i++) {
|
||||
int ilevel = visit(cursor, port[i]);
|
||||
max = std::max(max, ilevel + 1);
|
||||
|
|
@ -999,7 +1000,7 @@ struct XAigerWriter : AigerWriter {
|
|||
log_assert(cursor.is_top()); // TODO
|
||||
driven_by_opaque_box.insert(bit);
|
||||
map_file << "pi " << pis.size() - 1 << " " << bit.offset
|
||||
<< " " << bit.wire->name.c_str() << "\n";
|
||||
<< " " << design->twines.str(bit.wire->meta_->name).c_str() << "\n";
|
||||
}
|
||||
} else {
|
||||
log_assert(!box_port);
|
||||
|
|
@ -1034,8 +1035,8 @@ struct XAigerWriter : AigerWriter {
|
|||
if (map_file.is_open()) {
|
||||
log_assert(cursor.is_top());
|
||||
map_file << "pseudopo " << proper_pos_counter << " " << bitp
|
||||
<< " " << box->name.c_str()
|
||||
<< " " << conn.first.c_str() << "\n";
|
||||
<< " " << design->twines.str(box->meta_->name).c_str()
|
||||
<< " " << design->twines.str(conn.first).c_str() << "\n";
|
||||
}
|
||||
proper_pos_counter++;
|
||||
pos.push_back(std::make_pair(bit, cursor));
|
||||
|
|
@ -1048,7 +1049,7 @@ struct XAigerWriter : AigerWriter {
|
|||
} else if (!is_input && !inputs) {
|
||||
for (auto &bit : conn.second) {
|
||||
if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output))
|
||||
log_error("Bad connection %s/%s ~ %s\n", box, conn.first.unescape(), log_signal(conn.second));
|
||||
log_error("Bad connection %s/%s ~ %s\n", box, design->twines.str(conn.first).c_str(), log_signal(conn.second));
|
||||
|
||||
|
||||
ensure_pi(bit, cursor);
|
||||
|
|
@ -1116,7 +1117,7 @@ struct XAigerWriter : AigerWriter {
|
|||
for (auto [cursor, box, def] : opaque_boxes)
|
||||
append_opaque_box_ports(box, cursor, false);
|
||||
|
||||
holes_module = design->addModule(NEW_ID);
|
||||
holes_module = design->addModule(design->twines.add(NEW_TWINE));
|
||||
std::vector<RTLIL::Wire *> holes_pis;
|
||||
int boxes_ci_num = 0, boxes_co_num = 0;
|
||||
|
||||
|
|
@ -1133,13 +1134,13 @@ struct XAigerWriter : AigerWriter {
|
|||
}
|
||||
|
||||
for (auto [cursor, box, def] : nonopaque_boxes) {
|
||||
// use `def->name` not `box->type` as we want the derived type
|
||||
Cell *holes_wb = holes_module->addCell(NEW_TWINE, def->name);
|
||||
// use `def->meta_->name` not `box->type` as we want the derived type
|
||||
Cell *holes_wb = holes_module->addCell(NEW_TWINE, IdString(design->twines.str(def->meta_->name)));
|
||||
int holes_pi_idx = 0;
|
||||
|
||||
if (map_file.is_open()) {
|
||||
log_assert(cursor.is_top());
|
||||
map_file << "box " << box_seq << " " << box->name.c_str() << "\n";
|
||||
map_file << "box " << box_seq << " " << design->twines.str(box->meta_->name).c_str() << "\n";
|
||||
}
|
||||
box_seq++;
|
||||
|
||||
|
|
@ -1158,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",
|
||||
port_id.unescape(), i, box, box->type.unescape());
|
||||
design->twines.str(port_id).c_str(), i, box, box->type.unescape());
|
||||
bit = RTLIL::Sx;
|
||||
}
|
||||
|
||||
|
|
@ -1177,7 +1178,7 @@ struct XAigerWriter : AigerWriter {
|
|||
while (holes_pi_idx >= (int) holes_pis.size()) {
|
||||
Wire *w = holes_module->addWire(NEW_TWINE, 1);
|
||||
w->port_input = true;
|
||||
holes_module->ports.push_back(w->name);
|
||||
holes_module->ports.push_back(w->meta_->name);
|
||||
holes_pis.push_back(w);
|
||||
}
|
||||
in_conn.append(holes_pis[holes_pi_idx]);
|
||||
|
|
@ -1193,7 +1194,7 @@ struct XAigerWriter : AigerWriter {
|
|||
} else {
|
||||
// FIXME: hierarchical path
|
||||
log_warning("connection on port %s[%d] of instance %s (type %s) missing\n",
|
||||
port_id.unescape(), i, box, box->type.unescape());
|
||||
design->twines.str(port_id).c_str(), i, box, box->type.unescape());
|
||||
pad_pi();
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1206,11 +1207,11 @@ struct XAigerWriter : AigerWriter {
|
|||
// holes
|
||||
Wire *w = holes_module->addWire(NEW_TWINE, port->width);
|
||||
w->port_output = true;
|
||||
holes_module->ports.push_back(w->name);
|
||||
holes_module->ports.push_back(w->meta_->name);
|
||||
holes_wb->setPort(port_id, w);
|
||||
} else {
|
||||
log_error("Ambiguous port direction on %s/%s\n",
|
||||
box->type.unescape(), port_id.unescape());
|
||||
box->type.unescape(), design->twines.str(port_id).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ struct BlifDumper
|
|||
void dump()
|
||||
{
|
||||
f << stringf("\n");
|
||||
f << stringf(".model %s\n", str(module->name));
|
||||
f << stringf(".model %s\n", design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
std::map<int, RTLIL::Wire*> inputs, outputs;
|
||||
|
||||
|
|
@ -237,8 +237,10 @@ struct BlifDumper
|
|||
|
||||
if (config->unbuf_types.count(cell->type)) {
|
||||
auto portnames = config->unbuf_types.at(cell->type);
|
||||
TwineRef port_in = design->twines.lookup(portnames.first.str());
|
||||
TwineRef port_out = design->twines.lookup(portnames.second.str());
|
||||
f << stringf(".names %s %s\n1 1\n",
|
||||
str(cell->getPort(portnames.first)).c_str(), str(cell->getPort(portnames.second)).c_str());
|
||||
str(cell->getPort(port_in)).c_str(), str(cell->getPort(port_out)).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -420,7 +422,7 @@ struct BlifDumper
|
|||
for (auto &conn : cell->connections())
|
||||
{
|
||||
if (conn.second.size() == 1) {
|
||||
f << stringf(" %s=%s", str(conn.first), str(conn.second[0]));
|
||||
f << stringf(" %s=%s", design->twines.str(conn.first).c_str(), str(conn.second[0]));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -429,11 +431,11 @@ struct BlifDumper
|
|||
|
||||
if (w == nullptr) {
|
||||
for (int i = 0; i < GetSize(conn.second); i++)
|
||||
f << stringf(" %s[%d]=%s", str(conn.first), i, str(conn.second[i]));
|
||||
f << stringf(" %s[%d]=%s", design->twines.str(conn.first).c_str(), i, str(conn.second[i]));
|
||||
} else {
|
||||
for (int i = 0; i < std::min(GetSize(conn.second), GetSize(w)); i++) {
|
||||
SigBit sig(w, i);
|
||||
f << stringf(" %s[%d]=%s", str(conn.first), sig.wire->upto ?
|
||||
f << stringf(" %s[%d]=%s", design->twines.str(conn.first).c_str(), sig.wire->upto ?
|
||||
sig.wire->start_offset+sig.wire->width-sig.offset-1 :
|
||||
sig.wire->start_offset+sig.offset, str(conn.second[i]).c_str());
|
||||
}
|
||||
|
|
@ -665,7 +667,7 @@ struct BlifBackend : public Backend {
|
|||
if (top_module_name.empty())
|
||||
for (auto module : design->modules())
|
||||
if (module->get_bool_attribute(ID::top))
|
||||
top_module_name = module->name.str();
|
||||
top_module_name = design->twines.str(module->meta_->name);
|
||||
|
||||
*f << stringf("# Generated by %s\n", yosys_maybe_version());
|
||||
|
||||
|
|
@ -678,11 +680,11 @@ struct BlifBackend : public Backend {
|
|||
continue;
|
||||
|
||||
if (module->processes.size() != 0)
|
||||
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", module->name.unescape());
|
||||
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", design->twines.str(module->meta_->name).c_str());
|
||||
if (module->memories.size() != 0)
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", module->name.unescape());
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
if (module->name == RTLIL::escape_id(top_module_name)) {
|
||||
if (design->twines.str(module->meta_->name) == top_module_name) {
|
||||
BlifDumper::dump(*f, module, design, config);
|
||||
top_module_name.clear();
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -122,14 +122,43 @@ struct BtorWorker
|
|||
string infostr = obj->name.unescape();
|
||||
if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
|
||||
if (obj->has_attribute(ID::src)) {
|
||||
string raw_src = module && module->design ? module->design->get_src_attribute(obj) : std::string();
|
||||
string src = module && module->design ? module->design->resolve_src(raw_src) : raw_src;
|
||||
string src = module && module->design ? module->design->get_src_attribute(obj) : std::string();
|
||||
if (srcsym && infostr[0] == '$') {
|
||||
std::replace(src.begin(), src.end(), ' ', '_');
|
||||
if (srcsymbols.count(src) || module->count_id("\\" + src)) {
|
||||
TwineRef src_ref = module->design->twines.lookup(src);
|
||||
if (srcsymbols.count(src) || src_ref != Twine::Null) {
|
||||
for (int i = 1;; i++) {
|
||||
string s = stringf("%s-%d", src, i);
|
||||
if (!srcsymbols.count(s) && !module->count_id("\\" + s)) {
|
||||
TwineRef s_ref = module->design->twines.lookup(s);
|
||||
if (!srcsymbols.count(s) && s_ref == Twine::Null) {
|
||||
src = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
srcsymbols.insert(src);
|
||||
infostr = src;
|
||||
} else {
|
||||
infostr += " ; " + src;
|
||||
}
|
||||
}
|
||||
return " " + infostr;
|
||||
}
|
||||
|
||||
string getinfo(Mem *mem, bool srcsym = false)
|
||||
{
|
||||
string infostr = mem->memid.unescape();
|
||||
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();
|
||||
if (srcsym && infostr[0] == '$') {
|
||||
std::replace(src.begin(), src.end(), ' ', '_');
|
||||
TwineRef src_ref = module->design->twines.lookup(src);
|
||||
if (srcsymbols.count(src) || src_ref != Twine::Null) {
|
||||
for (int i = 1;; i++) {
|
||||
string s = stringf("%s-%d", src, i);
|
||||
TwineRef s_ref = module->design->twines.lookup(s);
|
||||
if (!srcsymbols.count(s) && s_ref == Twine::Null) {
|
||||
src = s;
|
||||
break;
|
||||
}
|
||||
|
|
@ -249,7 +278,7 @@ struct BtorWorker
|
|||
}
|
||||
|
||||
cell_recursion_guard.insert(cell);
|
||||
btorf_push(cell->name.unescape());
|
||||
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_)))
|
||||
|
|
@ -681,7 +710,7 @@ struct BtorWorker
|
|||
|
||||
if ((!info_filename.empty() || ywmap_json.active()) && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)))
|
||||
{
|
||||
SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? ID::CLK : ID::C));
|
||||
SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? TW::CLK : TW::C));
|
||||
int nid = get_sig_nid(sig_c);
|
||||
bool negedge = false;
|
||||
|
||||
|
|
@ -962,7 +991,7 @@ struct BtorWorker
|
|||
log_error("Unsupported cell type %s for cell %s.%s.\n",
|
||||
cell->type.unescape(), module, cell);
|
||||
okay:
|
||||
btorf_pop(cell->name.unescape());
|
||||
btorf_pop(cell->module->design->twines.str(cell->meta_->name));
|
||||
cell_recursion_guard.erase(cell);
|
||||
}
|
||||
|
||||
|
|
@ -1269,7 +1298,7 @@ struct BtorWorker
|
|||
{
|
||||
if (cell->type == ID($assume))
|
||||
{
|
||||
btorf_push(cell->name.unescape());
|
||||
btorf_push(cell->module->design->twines.str(cell->meta_->name));
|
||||
|
||||
int sid = get_bv_sid(1);
|
||||
int nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -1284,12 +1313,12 @@ struct BtorWorker
|
|||
|
||||
if (ywmap_json.active()) ywmap_assumes.emplace_back(cell);
|
||||
|
||||
btorf_pop(cell->name.unescape());
|
||||
btorf_pop(cell->module->design->twines.str(cell->meta_->name));
|
||||
}
|
||||
|
||||
if (cell->type == ID($assert))
|
||||
{
|
||||
btorf_push(cell->name.unescape());
|
||||
btorf_push(cell->module->design->twines.str(cell->meta_->name));
|
||||
|
||||
int sid = get_bv_sid(1);
|
||||
int nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -1313,12 +1342,12 @@ struct BtorWorker
|
|||
}
|
||||
}
|
||||
|
||||
btorf_pop(cell->name.unescape());
|
||||
btorf_pop(cell->module->design->twines.str(cell->meta_->name));
|
||||
}
|
||||
|
||||
if (cell->type == ID($cover) && cover_mode)
|
||||
{
|
||||
btorf_push(cell->name.unescape());
|
||||
btorf_push(cell->module->design->twines.str(cell->meta_->name));
|
||||
|
||||
int sid = get_bv_sid(1);
|
||||
int nid_a = get_sig_nid(cell->getPort(TW::A));
|
||||
|
|
@ -1334,7 +1363,7 @@ struct BtorWorker
|
|||
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true));
|
||||
}
|
||||
|
||||
btorf_pop(cell->name.unescape());
|
||||
btorf_pop(cell->module->design->twines.str(cell->meta_->name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1434,7 +1463,7 @@ struct BtorWorker
|
|||
}
|
||||
|
||||
int nid2 = next_nid++;
|
||||
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)));
|
||||
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, getinfo(mem));
|
||||
|
||||
btorf_pop(stringf("next %s", mem->memid.unescape()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,8 +642,18 @@ std::string get_hdl_name(T *object)
|
|||
{
|
||||
if (object->has_attribute(ID::hdlname))
|
||||
return object->get_string_attribute(ID::hdlname);
|
||||
else
|
||||
return object->name.str().substr(1);
|
||||
else {
|
||||
// For Wire/Cell with ->name, Module/Memory with ->meta_->name
|
||||
std::string name;
|
||||
if constexpr (std::is_same_v<T, RTLIL::Wire> || std::is_same_v<T, RTLIL::Cell>) {
|
||||
name = object->name.str();
|
||||
} else if constexpr (std::is_same_v<T, RTLIL::Module>) {
|
||||
name = object->design->twines.str(object->meta_->name);
|
||||
} else if constexpr (std::is_same_v<T, RTLIL::Memory>) {
|
||||
name = object->module->design->twines.str(object->meta_->name);
|
||||
}
|
||||
return name.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
struct WireType {
|
||||
|
|
@ -812,9 +822,15 @@ struct CxxrtlWorker {
|
|||
return mangle_name(name);
|
||||
}
|
||||
|
||||
std::string mangle_wire_name(TwineRef name, const RTLIL::Design *design)
|
||||
{
|
||||
// Class member namespace.
|
||||
return mangle_name(RTLIL::IdString(design->twines.str(name)));
|
||||
}
|
||||
|
||||
std::string mangle(const RTLIL::Module *module)
|
||||
{
|
||||
return mangle_module_name(module->name, /*is_blackbox=*/module->get_bool_attribute(ID(cxxrtl_blackbox)));
|
||||
return mangle_module_name(RTLIL::IdString(module->design->twines.str(module->meta_->name)), /*is_blackbox=*/module->get_bool_attribute(ID(cxxrtl_blackbox)));
|
||||
}
|
||||
|
||||
std::string mangle(const Mem *mem)
|
||||
|
|
@ -824,7 +840,7 @@ struct CxxrtlWorker {
|
|||
|
||||
std::string mangle(const RTLIL::Memory *memory)
|
||||
{
|
||||
return mangle_memory_name(memory->name);
|
||||
return mangle_memory_name(RTLIL::IdString(memory->module->design->twines.str(memory->meta_->name)));
|
||||
}
|
||||
|
||||
std::string mangle(const RTLIL::Cell *cell)
|
||||
|
|
@ -1127,7 +1143,7 @@ struct CxxrtlWorker {
|
|||
if (is_cxxrtl_sync_port(cell, conn.first) && !conn.second.empty()) {
|
||||
f << indent;
|
||||
dump_sigspec_lhs(conn.second, for_debug);
|
||||
f << " = " << mangle(cell) << access << mangle_wire_name(conn.first) << ".curr;\n";
|
||||
f << " = " << mangle(cell) << access << mangle_wire_name(conn.first, cell->module->design) << ".curr;\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1307,7 +1323,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(arg.second);
|
||||
f << ";\n";
|
||||
}
|
||||
if (cell->hasPort(ID::A)) {
|
||||
if (cell->hasPort(TW::A)) {
|
||||
f << indent << "bool condition = (bool)";
|
||||
dump_sigspec_rhs(cell->getPort(TW::A));
|
||||
f << ";\n";
|
||||
|
|
@ -1406,7 +1422,7 @@ struct CxxrtlWorker {
|
|||
} else if (is_ff_cell(cell->type)) {
|
||||
log_assert(!for_debug);
|
||||
// Clocks might be slices of larger signals but should only ever be single bit
|
||||
if (cell->hasPort(ID::CLK) && is_valid_clock(cell->getPort(TW::CLK))) {
|
||||
if (cell->hasPort(TW::CLK) && is_valid_clock(cell->getPort(TW::CLK))) {
|
||||
// Edge-sensitive logic
|
||||
RTLIL::SigBit clk_bit = cell->getPort(TW::CLK)[0];
|
||||
clk_bit = sigmaps[clk_bit.wire->module](clk_bit);
|
||||
|
|
@ -1417,7 +1433,7 @@ struct CxxrtlWorker {
|
|||
f << indent << "if (false) {\n";
|
||||
}
|
||||
inc_indent();
|
||||
if (cell->hasPort(ID::EN)) {
|
||||
if (cell->hasPort(TW::EN)) {
|
||||
f << indent << "if (";
|
||||
dump_sigspec_rhs(cell->getPort(TW::EN));
|
||||
f << " == value<1> {" << cell->getParam(ID::EN_POLARITY).as_bool() << "u}) {\n";
|
||||
|
|
@ -1428,11 +1444,11 @@ struct CxxrtlWorker {
|
|||
f << " = ";
|
||||
dump_sigspec_rhs(cell->getPort(TW::D));
|
||||
f << ";\n";
|
||||
if (cell->hasPort(ID::EN) && cell->type != ID($sdffce)) {
|
||||
if (cell->hasPort(TW::EN) && cell->type != ID($sdffce)) {
|
||||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(ID::SRST)) {
|
||||
if (cell->hasPort(TW::SRST)) {
|
||||
f << indent << "if (";
|
||||
dump_sigspec_rhs(cell->getPort(TW::SRST));
|
||||
f << " == value<1> {" << cell->getParam(ID::SRST_POLARITY).as_bool() << "u}) {\n";
|
||||
|
|
@ -1445,13 +1461,13 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(ID::EN) && cell->type == ID($sdffce)) {
|
||||
if (cell->hasPort(TW::EN) && cell->type == ID($sdffce)) {
|
||||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
} else if (cell->hasPort(ID::EN)) {
|
||||
} else if (cell->hasPort(TW::EN)) {
|
||||
// Level-sensitive logic
|
||||
f << indent << "if (";
|
||||
dump_sigspec_rhs(cell->getPort(TW::EN));
|
||||
|
|
@ -1465,7 +1481,7 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(ID::ARST)) {
|
||||
if (cell->hasPort(TW::ARST)) {
|
||||
// Asynchronous reset (entire coarse cell at once)
|
||||
f << indent << "if (";
|
||||
dump_sigspec_rhs(cell->getPort(TW::ARST));
|
||||
|
|
@ -1479,7 +1495,7 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(ID::ALOAD)) {
|
||||
if (cell->hasPort(TW::ALOAD)) {
|
||||
// Asynchronous load
|
||||
f << indent << "if (";
|
||||
dump_sigspec_rhs(cell->getPort(TW::ALOAD));
|
||||
|
|
@ -1493,7 +1509,7 @@ struct CxxrtlWorker {
|
|||
dec_indent();
|
||||
f << indent << "}\n";
|
||||
}
|
||||
if (cell->hasPort(ID::SET)) {
|
||||
if (cell->hasPort(TW::SET)) {
|
||||
// Asynchronous set (for individual bits)
|
||||
f << indent;
|
||||
dump_sigspec_lhs(cell->getPort(TW::Q));
|
||||
|
|
@ -1505,7 +1521,7 @@ struct CxxrtlWorker {
|
|||
dump_sigspec_rhs(cell->getPort(TW::SET));
|
||||
f << (cell->getParam(ID::SET_POLARITY).as_bool() ? "" : ".bit_not()") << ");\n";
|
||||
}
|
||||
if (cell->hasPort(ID::CLR)) {
|
||||
if (cell->hasPort(TW::CLR)) {
|
||||
// Asynchronous clear (for individual bits; priority over set)
|
||||
f << indent;
|
||||
dump_sigspec_lhs(cell->getPort(TW::Q));
|
||||
|
|
@ -1533,7 +1549,7 @@ struct CxxrtlWorker {
|
|||
RTLIL::Module *cell_module = cell->module->design->module(cell->type);
|
||||
log_assert(cell_module != nullptr && cell_module->wire(conn.first));
|
||||
RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first);
|
||||
f << indent << mangle(cell) << access << mangle_wire_name(conn.first);
|
||||
f << indent << mangle(cell) << access << mangle_wire_name(conn.first, cell->module->design);
|
||||
if (!is_cxxrtl_blackbox_cell(cell) && wire_types[cell_module_wire].is_buffered()) {
|
||||
buffered_inputs = true;
|
||||
f << ".next";
|
||||
|
|
@ -1565,7 +1581,7 @@ struct CxxrtlWorker {
|
|||
continue; // fully sync ports are handled in CELL_SYNC nodes
|
||||
f << indent;
|
||||
dump_sigspec_lhs(conn.second);
|
||||
f << " = " << mangle(cell) << access << mangle_wire_name(conn.first);
|
||||
f << " = " << mangle(cell) << access << mangle_wire_name(conn.first, cell->module->design);
|
||||
// Similarly to how there is no purpose to buffering cell inputs, there is also no purpose to buffering
|
||||
// combinatorial cell outputs in case the cell converges within one cycle. (To convince yourself that
|
||||
// this optimization is valid, consider that, since the cell converged within one cycle, it would not
|
||||
|
|
@ -1699,7 +1715,7 @@ struct CxxrtlWorker {
|
|||
void dump_process_case(const RTLIL::Process *proc, bool for_debug = false)
|
||||
{
|
||||
dump_attrs(proc);
|
||||
f << indent << "// process " << proc->name.str() << " case\n";
|
||||
f << indent << "// process " << proc->module->design->twines.str(proc->meta_->name) << " case\n";
|
||||
// The case attributes (for root case) are always empty.
|
||||
log_assert(proc->root_case.attributes.empty());
|
||||
dump_case_rule(&proc->root_case, for_debug);
|
||||
|
|
@ -1708,7 +1724,7 @@ struct CxxrtlWorker {
|
|||
void dump_process_syncs(const RTLIL::Process *proc, bool for_debug = false)
|
||||
{
|
||||
dump_attrs(proc);
|
||||
f << indent << "// process " << proc->name.str() << " syncs\n";
|
||||
f << indent << "// process " << proc->module->design->twines.str(proc->meta_->name) << " syncs\n";
|
||||
for (auto sync : proc->syncs) {
|
||||
log_assert(!for_debug || sync->type == RTLIL::STa);
|
||||
|
||||
|
|
@ -1760,7 +1776,9 @@ struct CxxrtlWorker {
|
|||
for (auto &action : sync->actions)
|
||||
dump_assign(action, for_debug);
|
||||
for (auto &memwr : sync->mem_write_actions) {
|
||||
RTLIL::Memory *memory = proc->module->memories.at(memwr.memid);
|
||||
TwineRef memid_ref = proc->module->design->twines.lookup(memwr.memid.str());
|
||||
log_assert(memid_ref != Twine::Null);
|
||||
RTLIL::Memory *memory = proc->module->memories[memid_ref];
|
||||
std::string valid_index_temp = fresh_temporary();
|
||||
f << indent << "auto " << valid_index_temp << " = memory_index(";
|
||||
dump_sigspec_rhs(memwr.address);
|
||||
|
|
@ -2448,7 +2466,7 @@ struct CxxrtlWorker {
|
|||
else
|
||||
has_driven_comb = true;
|
||||
} else if (wire->port_output) {
|
||||
switch (cxxrtl_port_type(module, wire->name)) {
|
||||
switch (cxxrtl_port_type(module, wire->meta_->name)) {
|
||||
case CxxrtlPortType::SYNC:
|
||||
has_driven_sync = true;
|
||||
break;
|
||||
|
|
@ -2777,8 +2795,19 @@ struct CxxrtlWorker {
|
|||
{
|
||||
RTLIL::Module *top_module = nullptr;
|
||||
std::vector<RTLIL::Module*> modules;
|
||||
using Order = IdString::compare_ptr_by_name<RTLIL::NamedObject>;
|
||||
TopoSort<RTLIL::Module*, Order> topo_design;
|
||||
|
||||
// Custom comparator for Module* that uses new meta_->name field
|
||||
struct CompareModuleByName {
|
||||
bool operator()(const RTLIL::Module *a, const RTLIL::Module *b) const {
|
||||
if (a == nullptr || b == nullptr)
|
||||
return a < b;
|
||||
auto name_a = a->design->twines.str(a->meta_->name);
|
||||
auto name_b = b->design->twines.str(b->meta_->name);
|
||||
return name_a < name_b;
|
||||
}
|
||||
};
|
||||
|
||||
TopoSort<RTLIL::Module*, CompareModuleByName> topo_design;
|
||||
for (auto module : design->modules()) {
|
||||
if (!design->selected_module(module))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ struct EdifBackend : public Backend {
|
|||
bool port_rename = false;
|
||||
bool attr_properties = false;
|
||||
bool lsbidx = false;
|
||||
std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports;
|
||||
std::map<RTLIL::IdString, std::map<TwineRef, int>> lib_cell_ports;
|
||||
bool nogndvcc = false, gndvccy = false, keepmode = false;
|
||||
NewCellTypes ct(design);
|
||||
EdifNames edif_names;
|
||||
|
|
@ -190,28 +190,29 @@ struct EdifBackend : public Backend {
|
|||
if (top_module_name.empty())
|
||||
for (auto module : design->modules())
|
||||
if (module->get_bool_attribute(ID::top))
|
||||
top_module_name = module->name.str();
|
||||
top_module_name = design->twines.str(module->meta_->name);
|
||||
|
||||
for (auto module : design->modules())
|
||||
{
|
||||
lib_cell_ports[module->name];
|
||||
IdString module_type = IdString(design->twines.str(module->meta_->name));
|
||||
lib_cell_ports[module_type];
|
||||
|
||||
for (auto port : module->ports)
|
||||
{
|
||||
Wire *wire = module->wire(port);
|
||||
lib_cell_ports[module->name][port] = std::max(lib_cell_ports[module->name][port], GetSize(wire));
|
||||
lib_cell_ports[module_type][port] = std::max(lib_cell_ports[module_type][port], GetSize(wire));
|
||||
}
|
||||
|
||||
if (module->get_blackbox_attribute())
|
||||
continue;
|
||||
|
||||
if (top_module_name.empty())
|
||||
top_module_name = module->name.str();
|
||||
top_module_name = design->twines.str(module->meta_->name);
|
||||
|
||||
if (module->processes.size() != 0)
|
||||
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", module->name.unescape());
|
||||
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", design->twines.str(module->meta_->name));
|
||||
if (module->memories.size() != 0)
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", module->name.unescape());
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", design->twines.str(module->meta_->name));
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
|
|
@ -285,13 +286,14 @@ struct EdifBackend : public Backend {
|
|||
upto = w->upto;
|
||||
}
|
||||
}
|
||||
std::string port_str = design->twines.str(port_it.first);
|
||||
if (width == 1)
|
||||
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir);
|
||||
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF_STR(port_str), dir);
|
||||
else {
|
||||
int b[2];
|
||||
b[upto ? 0 : 1] = start;
|
||||
b[upto ? 1 : 0] = start+width-1;
|
||||
*f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), width, dir);
|
||||
*f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(IdString(port_str), port_rename, b[0], b[1]), width, dir);
|
||||
}
|
||||
}
|
||||
*f << stringf(" )\n");
|
||||
|
|
@ -324,7 +326,7 @@ struct EdifBackend : public Backend {
|
|||
not_ready_yet:;
|
||||
}
|
||||
if (sorted_modules_idx == sorted_modules.size())
|
||||
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape());
|
||||
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", design->twines.str(module_deps.begin()->first->meta_->name));
|
||||
while (sorted_modules_idx < sorted_modules.size())
|
||||
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
|
||||
}
|
||||
|
|
@ -361,7 +363,8 @@ struct EdifBackend : public Backend {
|
|||
SigMap sigmap(module);
|
||||
std::map<RTLIL::SigSpec, std::set<std::pair<std::string, bool>>> net_join_db;
|
||||
|
||||
*f << stringf(" (cell %s\n", EDIF_DEF(module->name));
|
||||
std::string module_name_str = design->twines.str(module->meta_->name);
|
||||
*f << stringf(" (cell %s\n", EDIF_DEF_STR(module_name_str));
|
||||
*f << stringf(" (cellType GENERIC)\n");
|
||||
*f << stringf(" (view VIEW_NETLIST\n");
|
||||
*f << stringf(" (viewType NETLIST)\n");
|
||||
|
|
@ -485,10 +488,12 @@ struct EdifBackend : public Backend {
|
|||
*f << stringf(")\n");
|
||||
for (auto &p : cell->connections()) {
|
||||
RTLIL::SigSpec sig = sigmap(p.second);
|
||||
std::string port_name_str = design->twines.str(p.first);
|
||||
std::string cell_name_str = cell->name.str();
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
|
||||
log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
|
||||
i, module, cell, p.first.unescape(), log_signal(sig[i]));
|
||||
i, module, cell, port_name_str, log_signal(sig[i]));
|
||||
else {
|
||||
int member_idx = lsbidx ? i : GetSize(sig)-i-1;
|
||||
auto m = design->module(cell->type);
|
||||
|
|
@ -501,10 +506,10 @@ struct EdifBackend : public Backend {
|
|||
}
|
||||
}
|
||||
if (width == 1)
|
||||
net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
|
||||
net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF_STR(port_name_str), EDIF_REF(cell->name)), cell->output(p.first)));
|
||||
else {
|
||||
net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
|
||||
EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
|
||||
EDIF_REF_STR(port_name_str), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ std::string getFileinfo(const RTLIL::AttrObject *design_entity, const RTLIL::Des
|
|||
}
|
||||
|
||||
// Get a port direction with respect to a specific module.
|
||||
FDirection getPortFDirection(IdString id, Module *module)
|
||||
FDirection getPortFDirection(TwineRef ref, Module *module)
|
||||
{
|
||||
Wire *wire = module->wire(id);
|
||||
Wire *wire = module->wire(ref);
|
||||
FDirection direction = FD_NODIRECTION;
|
||||
if (wire && wire->port_id)
|
||||
{
|
||||
|
|
@ -229,7 +229,7 @@ std::string extmodule_name(RTLIL::Cell *cell, RTLIL::Module *mod_instance)
|
|||
// this blackbox, we need to create a custom name for it. We just use the
|
||||
// name of the blackbox itself followed by the name of the cell.
|
||||
const std::string cell_name = std::string(make_id(cell->name));
|
||||
const std::string blackbox_name = std::string(make_id(mod_instance->name));
|
||||
const std::string blackbox_name = std::string(make_id(IdString(mod_instance->design->twines.str(mod_instance->meta_->name))));
|
||||
const std::string extmodule_name = blackbox_name + "_" + cell_name;
|
||||
return extmodule_name;
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
|
|||
{
|
||||
const std::string indent = " ";
|
||||
|
||||
const std::string blackbox_name = std::string(make_id(mod_instance->name));
|
||||
const std::string blackbox_name = std::string(make_id(IdString(mod_instance->design->twines.str(mod_instance->meta_->name))));
|
||||
const std::string exported_name = extmodule_name(cell, mod_instance);
|
||||
|
||||
// We use the cell's fileinfo for this extmodule as its parameters come from
|
||||
|
|
@ -482,7 +482,7 @@ struct FirrtlWorker
|
|||
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
||||
if (it->second.size() > 0) {
|
||||
const SigSpec &secondSig = it->second;
|
||||
const std::string firstName = cell_name + "." + make_id(it->first);
|
||||
const std::string firstName = cell_name + "." + make_id(IdString(design->twines.str(it->first)));
|
||||
const std::string secondExpr = make_expr(secondSig);
|
||||
// Find the direction for this port.
|
||||
FDirection dir = getPortFDirection(it->first, instModule);
|
||||
|
|
@ -543,7 +543,7 @@ struct FirrtlWorker
|
|||
void emit_module()
|
||||
{
|
||||
std::string moduleFileinfo = getFileinfo(module);
|
||||
f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo);
|
||||
f << stringf(" module %s: %s\n", make_id(IdString(module->design->twines.str(module->meta_->name))), moduleFileinfo);
|
||||
vector<string> port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs;
|
||||
|
||||
std::vector<Mem> memories = Mem::get_all_memories(module);
|
||||
|
|
@ -1232,7 +1232,7 @@ struct FirrtlBackend : public Backend {
|
|||
Module *last = nullptr;
|
||||
// Generate module and wire names.
|
||||
for (auto module : design->modules()) {
|
||||
make_id(module->name);
|
||||
make_id(IdString(module->design->twines.str(module->meta_->name)));
|
||||
last = module;
|
||||
if (top == nullptr && module->get_bool_attribute(ID::top)) {
|
||||
top = module;
|
||||
|
|
@ -1249,7 +1249,7 @@ struct FirrtlBackend : public Backend {
|
|||
log_cmd_error("There is no top module in this design!\n");
|
||||
|
||||
std::string circuitFileinfo = getFileinfo(top);
|
||||
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo);
|
||||
*f << stringf("circuit %s: %s\n", make_id(IdString(top->design->twines.str(top->meta_->name))), circuitFileinfo);
|
||||
|
||||
emit_elaborated_extmodules(design, *f);
|
||||
|
||||
|
|
|
|||
|
|
@ -131,20 +131,20 @@ struct IntersynthBackend : public Backend {
|
|||
if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0)
|
||||
continue;
|
||||
|
||||
if (selected && !design->selected_whole_module(module->name)) {
|
||||
if (design->selected_module(module->name))
|
||||
log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape());
|
||||
if (selected && !design->selected_whole_module(module->meta_->name)) {
|
||||
if (design->selected_module(module->meta_->name))
|
||||
log_cmd_error("Can't handle partially selected module %s!\n", design->twines.str(module->meta_->name).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
log("Generating netlist %s.\n", module->name.unescape());
|
||||
log("Generating netlist %s.\n", design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
if (module->memories.size() != 0 || module->processes.size() != 0)
|
||||
log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
|
||||
|
||||
std::set<std::string> constcells_code;
|
||||
netlists_code += stringf("# Netlist of module %s\n", module->name.unescape());
|
||||
netlists_code += stringf("netlist %s\n", module->name.unescape());
|
||||
netlists_code += stringf("# Netlist of module %s\n", design->twines.str(module->meta_->name).c_str());
|
||||
netlists_code += stringf("netlist %s\n", design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
// Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports
|
||||
for (auto wire : module->wires()) {
|
||||
|
|
@ -166,13 +166,14 @@ struct IntersynthBackend : public Backend {
|
|||
log_error("Found unknown cell type %s in module!\n", cell->type.unescape());
|
||||
|
||||
celltype_code = stringf("celltype %s", cell->type.unescape());
|
||||
node_code = stringf("node %s %s", cell->name.unescape(), cell->type.unescape());
|
||||
node_code = stringf("node %s %s", cell->module->design->twines.str(cell->meta_->name), cell->type.unescape());
|
||||
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()));
|
||||
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", port.first.unescape());
|
||||
node_code += stringf(" %s %s", port.first.unescape(), netname(conntypes_code, celltypes_code, constcells_code, sig));
|
||||
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());
|
||||
node_code += stringf(" %s %s", port_name.c_str(), netname(conntypes_code, celltypes_code, constcells_code, sig));
|
||||
}
|
||||
}
|
||||
for (auto ¶m : cell->parameters) {
|
||||
|
|
|
|||
|
|
@ -211,10 +211,11 @@ struct JnyWriter
|
|||
f << _indent << " }";
|
||||
}
|
||||
|
||||
void write_cell_conn(const std::pair<RTLIL::IdString, RTLIL::SigSpec>& sig, uint16_t indent_level = 0) {
|
||||
void write_cell_conn(Design* design, const std::pair<TwineRef, RTLIL::SigSpec>& sig, uint16_t indent_level = 0) {
|
||||
const auto _indent = gen_indent(indent_level);
|
||||
std::string port_name = design->twines.str(sig.first);
|
||||
f << _indent << " {\n";
|
||||
f << _indent << " \"name\": \"" << escape_string(sig.first.unescape()) << "\",\n";
|
||||
f << _indent << " \"name\": \"" << escape_string(port_name) << "\",\n";
|
||||
f << _indent << " \"signals\": [\n";
|
||||
|
||||
write_sigspec(sig.second, indent_level + 2);
|
||||
|
|
@ -232,7 +233,7 @@ struct JnyWriter
|
|||
const auto _indent = gen_indent(indent_level);
|
||||
|
||||
f << _indent << "{\n";
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(mod->name.unescape()));
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(mod->design->twines.str(mod->meta_->name)));
|
||||
f << _indent << " \"cell_sorts\": [\n";
|
||||
|
||||
bool first_sort{true};
|
||||
|
|
@ -279,8 +280,9 @@ struct JnyWriter
|
|||
if (!first_port)
|
||||
f << ",\n";
|
||||
|
||||
std::string port_name = port_cell->module->design->twines.str(con.first);
|
||||
f << _indent << " {\n";
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(con.first.unescape()));
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(port_name));
|
||||
f << _indent << " \"direction\": \"";
|
||||
if (port_cell->input(con.first))
|
||||
f << "i";
|
||||
|
|
@ -366,7 +368,7 @@ struct JnyWriter
|
|||
log_assert(cell != nullptr);
|
||||
|
||||
f << _indent << " {\n";
|
||||
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(cell->name.unescape()));
|
||||
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(cell->module->design->twines.str(cell->meta_->name)));
|
||||
|
||||
if (_include_connections) {
|
||||
f << ",\n" << _indent << " \"connections\": [\n";
|
||||
|
|
@ -376,7 +378,7 @@ struct JnyWriter
|
|||
if (!first_conn)
|
||||
f << ",\n";
|
||||
|
||||
write_cell_conn(conn, indent_level + 2);
|
||||
write_cell_conn(cell->module->design, conn, indent_level + 2);
|
||||
|
||||
first_conn = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,11 @@ struct JsonWriter
|
|||
return get_string(name.unescape());
|
||||
}
|
||||
|
||||
string get_name(TwineRef name)
|
||||
{
|
||||
return get_string(design->twines.str(name));
|
||||
}
|
||||
|
||||
string get_bits(SigSpec sig)
|
||||
{
|
||||
bool first = true;
|
||||
|
|
@ -162,7 +167,7 @@ struct JsonWriter
|
|||
log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", module);
|
||||
}
|
||||
|
||||
f << stringf(" %s: {\n", get_name(module->name));
|
||||
f << stringf(" %s: {\n", get_name(module->meta_->name));
|
||||
|
||||
f << stringf(" \"attributes\": {");
|
||||
write_parameters(module->attributes, /*for_module=*/true, module);
|
||||
|
|
@ -252,8 +257,8 @@ struct JsonWriter
|
|||
if (use_selection && !module->selected(it.second))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(it.second->name));
|
||||
f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0");
|
||||
f << stringf(" %s: {\n", get_name(it.second->meta_->name));
|
||||
f << stringf(" \"hide_name\": %s,\n", design->twines.str(it.second->meta_->name)[0] == '$' ? "1" : "0");
|
||||
f << stringf(" \"attributes\": {");
|
||||
write_parameters(it.second->attributes, false, it.second);
|
||||
f << stringf("\n },\n");
|
||||
|
|
@ -323,13 +328,13 @@ struct JsonWriter
|
|||
f << stringf(" /* %3d */ [ ", node_idx);
|
||||
if (node.portbit >= 0)
|
||||
f << stringf("\"%sport\", \"%s\", %d", node.inverter ? "n" : "",
|
||||
node.portname.unescape(), node.portbit);
|
||||
design->twines.str(node.portname), node.portbit);
|
||||
else if (node.left_parent < 0 && node.right_parent < 0)
|
||||
f << stringf("\"%s\"", node.inverter ? "true" : "false");
|
||||
else
|
||||
f << stringf("\"%s\", %d, %d", node.inverter ? "nand" : "and", node.left_parent, node.right_parent);
|
||||
for (auto &op : node.outports)
|
||||
f << stringf(", \"%s\", %d", op.first.unescape(), op.second);
|
||||
f << stringf(", \"%s\", %d", design->twines.str(op.first), op.second);
|
||||
f << stringf(" ]");
|
||||
node_idx++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const R
|
|||
TwineRef id = design->obj_src_id(obj);
|
||||
f << stringf("%s" "attribute \\src ", indent);
|
||||
if (resolve_src) {
|
||||
dump_const(f, RTLIL::Const(design->twines.flatten(id)));
|
||||
dump_const(f, RTLIL::Const(design->twines.str(id)));
|
||||
} else {
|
||||
dump_const(f, RTLIL::Const(design->twines.format_ref(id)));
|
||||
dump_const(f, RTLIL::Const(stringf("@%zu", id)));
|
||||
}
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
|
@ -59,22 +59,23 @@ void RTLIL_BACKEND::dump_twines(std::ostream &f, const RTLIL::Design *design)
|
|||
if (!design || design->twines.size() == 0)
|
||||
return;
|
||||
f << stringf("twines\n");
|
||||
design->twines.for_each_live([&](TwineRef id, const Twine &n) {
|
||||
for (TwineRef id = 0; id < STATIC_TWINE_END; id++) {
|
||||
const Twine &n = design->twines[id];
|
||||
if (n.is_leaf()) {
|
||||
f << stringf(" leaf %u ", id);
|
||||
f << stringf(" leaf %zu ", id);
|
||||
dump_const(f, RTLIL::Const(n.leaf()));
|
||||
f << stringf("\n");
|
||||
} else if (n.is_suffix()) {
|
||||
f << stringf(" suffix %u %u ", id, n.suffix().parent);
|
||||
f << stringf(" suffix %zu %zu ", id, n.suffix().prefix);
|
||||
dump_const(f, RTLIL::Const(n.suffix().tail));
|
||||
f << stringf("\n");
|
||||
} else {
|
||||
f << stringf(" concat %u", id);
|
||||
} else if (n.is_concat()) {
|
||||
f << stringf(" concat %zu", id);
|
||||
for (TwineRef c : n.children())
|
||||
f << stringf(" %u", c);
|
||||
f << stringf(" %zu", c);
|
||||
f << stringf("\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
f << stringf("end\n");
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL
|
|||
f << stringf("size %d ", memory->size);
|
||||
if (memory->start_offset != 0)
|
||||
f << stringf("offset %d ", memory->start_offset);
|
||||
f << stringf("%s\n", memory->name);
|
||||
f << stringf("%s\n", design->twines.str(memory->meta_->name).c_str());
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell, const RTLIL::Design *design, bool resolve_src)
|
||||
|
|
@ -309,7 +310,7 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
|
|||
void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc, const RTLIL::Design *design, bool resolve_src)
|
||||
{
|
||||
dump_attributes(f, indent, proc, design, resolve_src);
|
||||
f << stringf("%s" "process %s\n", indent, proc->name);
|
||||
f << stringf("%s" "process %s\n", indent, design->twines.str(proc->meta_->name).c_str());
|
||||
dump_proc_case_body(f, indent + " ", &proc->root_case, design, resolve_src);
|
||||
for (auto* sync : proc->syncs)
|
||||
dump_proc_sync(f, indent + " ", sync, design, resolve_src);
|
||||
|
|
@ -334,7 +335,7 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
{
|
||||
dump_attributes(f, indent, module, design, resolve_src);
|
||||
|
||||
f << stringf("%s" "module %s\n", indent, module->name);
|
||||
f << stringf("%s" "module %s\n", indent, design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
if (!module->avail_parameters.empty()) {
|
||||
if (only_selected)
|
||||
|
|
@ -384,7 +385,7 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
|
||||
bool first_conn_line = true;
|
||||
for (const auto& [lhs, rhs] : module->connections()) {
|
||||
bool show_conn = !only_selected || design->selected_whole_module(module->name);
|
||||
bool show_conn = !only_selected || design->selected_whole_module(module->meta_->name);
|
||||
if (!show_conn) {
|
||||
RTLIL::SigSpec sigs = lhs;
|
||||
sigs.append(rhs);
|
||||
|
|
@ -414,9 +415,9 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
if (!flag_m) {
|
||||
int count_selected_mods = 0;
|
||||
for (auto* module : design->modules()) {
|
||||
if (design->selected_whole_module(module->name))
|
||||
if (design->selected_whole_module(module->meta_->name))
|
||||
flag_m = true;
|
||||
if (design->selected(module))
|
||||
if (design->selected_module(module->meta_->name))
|
||||
count_selected_mods++;
|
||||
}
|
||||
if (count_selected_mods > 1)
|
||||
|
|
@ -432,7 +433,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
}
|
||||
|
||||
for (const auto& [_, module] : reversed(design->modules_)) {
|
||||
if (!only_selected || design->selected(module)) {
|
||||
if (!only_selected || design->selected_module(module->meta_->name)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_module(f, "", module, design, only_selected, flag_m, flag_n, resolve_src);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ struct HierDirtyFlags
|
|||
for (Cell *cell : module->cells()) {
|
||||
Module *mod = module->design->module(cell->type);
|
||||
if (mod) children[cell->name] = new HierDirtyFlags(mod, cell->name, this,
|
||||
prefix + cid(cell->name) + ".", log_prefix + "." + prefix + cell->name.unescape());
|
||||
prefix + cid(cell->name) + ".", log_prefix + "." + prefix + cell->module->design->twines.str(cell->meta_->name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ struct SimplecWorker
|
|||
|
||||
vector<string> funct_declarations;
|
||||
|
||||
dict<Module*, dict<SigBit, pool<tuple<Cell*, IdString, int>>>> bit2cell;
|
||||
dict<Module*, dict<SigBit, pool<tuple<Cell*, TwineRef, int>>>> bit2cell;
|
||||
dict<Module*, dict<SigBit, pool<SigBit>>> bit2output;
|
||||
dict<Module*, pool<SigBit>> driven_bits;
|
||||
|
||||
|
|
@ -284,10 +284,10 @@ struct SimplecWorker
|
|||
|
||||
void create_module_struct(Module *mod)
|
||||
{
|
||||
if (generated_structs.count(mod->name))
|
||||
if (generated_structs.count(design->twines.str(mod->meta_->name)))
|
||||
return;
|
||||
|
||||
generated_structs.insert(mod->name);
|
||||
generated_structs.insert(design->twines.str(mod->meta_->name));
|
||||
sigmaps[mod].set(mod);
|
||||
|
||||
for (Wire *w : mod->wires())
|
||||
|
|
@ -309,7 +309,7 @@ struct SimplecWorker
|
|||
|
||||
int idx = 0;
|
||||
for (auto bit : sigmaps.at(mod)(conn.second))
|
||||
bit2cell[mod][bit].insert(tuple<Cell*, IdString, int>(c, conn.first, idx++));
|
||||
bit2cell[mod][bit].insert(tuple<Cell*, TwineRef, int>(c, conn.first, idx++));
|
||||
}
|
||||
|
||||
if (design->module(c->type))
|
||||
|
|
@ -337,9 +337,9 @@ struct SimplecWorker
|
|||
topo.sort();
|
||||
|
||||
for (int i = 0; i < GetSize(topo.sorted); i++)
|
||||
topoidx[mod->cell(topo.sorted[i])] = i;
|
||||
topoidx[mod->cell(design->twines.lookup(topo.sorted[i].str()))] = i;
|
||||
|
||||
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name));
|
||||
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(RTLIL::IdString(design->twines.str(mod->meta_->name))));
|
||||
|
||||
for (int i = 0; i < GetSize(ifdef_name); i++)
|
||||
if ('a' <= ifdef_name[i] && ifdef_name[i] <= 'z')
|
||||
|
|
@ -348,7 +348,7 @@ struct SimplecWorker
|
|||
struct_declarations.push_back("");
|
||||
struct_declarations.push_back(stringf("#ifndef %s", ifdef_name));
|
||||
struct_declarations.push_back(stringf("#define %s", ifdef_name));
|
||||
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name)));
|
||||
struct_declarations.push_back(stringf("struct %s_state_t", cid(RTLIL::IdString(design->twines.str(mod->meta_->name)))));
|
||||
struct_declarations.push_back("{");
|
||||
|
||||
struct_declarations.push_back(" // Input Ports");
|
||||
|
|
@ -527,9 +527,9 @@ struct SimplecWorker
|
|||
for (auto outbit : bit2output[work->module][bit])
|
||||
{
|
||||
Module *parent_mod = work->parent->module;
|
||||
Cell *parent_cell = parent_mod->cell(work->hiername);
|
||||
Cell *parent_cell = parent_mod->cell(parent_mod->design->twines.lookup(work->hiername.str()));
|
||||
|
||||
IdString port_name = outbit.wire->name;
|
||||
TwineRef port_name = outbit.wire->meta_->name;
|
||||
int port_offset = outbit.offset;
|
||||
SigBit parent_bit = sigmaps.at(parent_mod)(parent_cell->getPort(port_name)[port_offset]);
|
||||
|
||||
|
|
@ -576,7 +576,7 @@ struct SimplecWorker
|
|||
if (cell == nullptr || topoidx.at(cell) < topoidx.at(c))
|
||||
cell = c;
|
||||
|
||||
string hiername = work->log_prefix + "." + cell->name.unescape();
|
||||
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));
|
||||
|
|
@ -636,7 +636,7 @@ struct SimplecWorker
|
|||
reactivated_cells.clear();
|
||||
|
||||
funct_declarations.push_back("");
|
||||
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name, cid(work->module->name)));
|
||||
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name, cid(RTLIL::IdString(work->module->design->twines.str(work->module->meta_->name)))));
|
||||
funct_declarations.push_back("{");
|
||||
for (auto &line : preamble)
|
||||
funct_declarations.push_back(line);
|
||||
|
|
@ -690,7 +690,7 @@ struct SimplecWorker
|
|||
{
|
||||
vector<string> preamble;
|
||||
eval_init(work, preamble);
|
||||
make_func(work, cid(work->module->name) + "_init", preamble);
|
||||
make_func(work, cid(RTLIL::IdString(work->module->design->twines.str(work->module->meta_->name))) + "_init", preamble);
|
||||
}
|
||||
|
||||
void make_eval_func(HierDirtyFlags *work)
|
||||
|
|
@ -704,7 +704,7 @@ struct SimplecWorker
|
|||
work->set_dirty(bit);
|
||||
}
|
||||
|
||||
make_func(work, cid(work->module->name) + "_eval", preamble);
|
||||
make_func(work, cid(RTLIL::IdString(work->module->design->twines.str(work->module->meta_->name))) + "_eval", preamble);
|
||||
}
|
||||
|
||||
void make_tick_func(HierDirtyFlags* /* work */)
|
||||
|
|
@ -716,7 +716,7 @@ struct SimplecWorker
|
|||
{
|
||||
create_module_struct(mod);
|
||||
|
||||
HierDirtyFlags work(mod, IdString(), nullptr, "state->", mod->name.unescape());
|
||||
HierDirtyFlags work(mod, IdString(), nullptr, "state->", mod->design->twines.str(mod->meta_->name));
|
||||
|
||||
make_init_func(&work);
|
||||
make_eval_func(&work);
|
||||
|
|
|
|||
|
|
@ -207,9 +207,9 @@ struct Smt2Worker
|
|||
}
|
||||
else if (is_output || !is_input)
|
||||
log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n",
|
||||
conn.first.unescape(), module, cell, cell->type.unescape());
|
||||
module->design->twines.str(conn.first).c_str(), module, cell, cell->type.unescape());
|
||||
|
||||
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C))
|
||||
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_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());
|
||||
for (auto bit : sigmap(conn.second)) {
|
||||
|
|
@ -220,19 +220,22 @@ struct Smt2Worker
|
|||
}
|
||||
}
|
||||
else
|
||||
if (mod_clk_cache.count(cell->type) && mod_clk_cache.at(cell->type).count(conn.first))
|
||||
{
|
||||
for (auto bit : sigmap(conn.second)) {
|
||||
if (mod_clk_cache.at(cell->type).at(conn.first).first)
|
||||
clock_posedge.insert(bit);
|
||||
if (mod_clk_cache.at(cell->type).at(conn.first).second)
|
||||
clock_negedge.insert(bit);
|
||||
IdString port_name = IdString(module->design->twines.str(conn.first));
|
||||
if (mod_clk_cache.count(cell->type) && mod_clk_cache.at(cell->type).count(port_name))
|
||||
{
|
||||
for (auto bit : sigmap(conn.second)) {
|
||||
if (mod_clk_cache.at(cell->type).at(port_name).first)
|
||||
clock_posedge.insert(bit);
|
||||
if (mod_clk_cache.at(cell->type).at(port_name).second)
|
||||
clock_negedge.insert(bit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto bit : sigmap(conn.second))
|
||||
noclock.insert(bit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto bit : sigmap(conn.second))
|
||||
noclock.insert(bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,10 +260,11 @@ struct Smt2Worker
|
|||
if (!wire->port_input || GetSize(wire) != 1)
|
||||
continue;
|
||||
SigBit bit = sigmap(wire);
|
||||
IdString module_name = IdString(module->design->twines.str(module->meta_->name));
|
||||
if (clock_posedge.count(bit))
|
||||
mod_clk_cache[module->name][wire->name].first = true;
|
||||
mod_clk_cache[module_name][wire->name].first = true;
|
||||
if (clock_negedge.count(bit))
|
||||
mod_clk_cache[module->name][wire->name].second = true;
|
||||
mod_clk_cache[module_name][wire->name].second = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,7 +277,7 @@ struct Smt2Worker
|
|||
|
||||
const char *get_id(Module *m)
|
||||
{
|
||||
return get_id(m->name);
|
||||
return get_id(IdString(m->design->twines.str(m->meta_->name)));
|
||||
}
|
||||
|
||||
const char *get_id(Cell *c)
|
||||
|
|
@ -468,16 +472,16 @@ struct Smt2Worker
|
|||
width = GetSize(cell->getPort(TW::A));
|
||||
else
|
||||
width = max(width, GetSize(cell->getPort(TW::A)));
|
||||
if (cell->hasPort(ID::B))
|
||||
if (cell->hasPort(TW::B))
|
||||
width = max(width, GetSize(cell->getPort(TW::B)));
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::A)) {
|
||||
if (cell->hasPort(TW::A)) {
|
||||
sig_a = cell->getPort(TW::A);
|
||||
sig_a.extend_u0(width, is_signed);
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::B)) {
|
||||
if (cell->hasPort(TW::B)) {
|
||||
sig_b = cell->getPort(TW::B);
|
||||
sig_b.extend_u0(width, (type == 'S') || (is_signed && !(type == 's')));
|
||||
}
|
||||
|
|
@ -520,7 +524,8 @@ struct Smt2Worker
|
|||
|
||||
for (char ch : expr)
|
||||
if (ch == 'A' || ch == 'B') {
|
||||
RTLIL::SigSpec sig = sigmap(cell->getPort(stringf("\\%c", ch)));
|
||||
TwineRef port = (ch == 'A') ? TW::A : TW::B;
|
||||
RTLIL::SigSpec sig = sigmap(cell->getPort(port));
|
||||
for (auto bit : sig)
|
||||
processed_expr += " " + get_bool(bit);
|
||||
if (GetSize(sig) == 1)
|
||||
|
|
@ -612,12 +617,11 @@ struct Smt2Worker
|
|||
|
||||
if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq)))
|
||||
{
|
||||
auto QY = cell->type == ID($anyinit) ? ID::Q : ID::Y;
|
||||
auto QY = cell->type == ID($anyinit) ? TW::Q : TW::Y;
|
||||
registers.insert(cell);
|
||||
string infostr;
|
||||
if (cell->has_attribute(ID::src)) {
|
||||
string raw_src = cell->get_src_attribute();
|
||||
infostr = module && module->design ? module->design->resolve_src(raw_src) : raw_src;
|
||||
infostr = cell->get_src_attribute();
|
||||
} else {
|
||||
infostr = get_id(cell);
|
||||
}
|
||||
|
|
@ -636,7 +640,7 @@ struct Smt2Worker
|
|||
bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst));
|
||||
bool clk2fflogic = cell->type == ID($anyinit) && cell->get_bool_attribute(ID(clk2fflogic));
|
||||
int smtoffset = 0;
|
||||
for (auto chunk : cell->getPort(clk2fflogic ? ID::D : QY).chunks()) {
|
||||
for (auto chunk : cell->getPort(clk2fflogic ? TW::D : QY).chunks()) {
|
||||
if (chunk.is_wire())
|
||||
decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, smtoffset));
|
||||
smtoffset += chunk.width;
|
||||
|
|
@ -1138,8 +1142,7 @@ struct Smt2Worker
|
|||
|
||||
if (private_name && cell->has_attribute(ID::src)) {
|
||||
string raw_src = cell->get_src_attribute();
|
||||
string resolved_src = module && module->design ? module->design->resolve_src(raw_src) : raw_src;
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), resolved_src.c_str()));
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), raw_src.c_str()));
|
||||
}
|
||||
else
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
|
||||
|
|
@ -1478,7 +1481,8 @@ struct Smt2Worker
|
|||
|
||||
if (statebv) {
|
||||
f << stringf("(define-sort |%s_s| () (_ BitVec %d))\n", get_id(module), statebv_width);
|
||||
mod_stbv_width[module->name] = statebv_width;
|
||||
IdString module_name = IdString(module->design->twines.str(module->meta_->name));
|
||||
mod_stbv_width[module_name] = statebv_width;
|
||||
} else
|
||||
if (statedt) {
|
||||
f << stringf("(declare-datatype |%s_s| ((|%s_mk|\n", get_id(module), get_id(module));
|
||||
|
|
@ -1863,9 +1867,11 @@ struct Smt2Backend : public Backend {
|
|||
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
|
||||
for (auto mod : design->modules()) {
|
||||
module_deps[mod] = std::set<RTLIL::Module*>();
|
||||
for (auto cell : mod->cells())
|
||||
if (design->has(cell->type))
|
||||
module_deps[mod].insert(design->module(cell->type));
|
||||
for (auto cell : mod->cells()) {
|
||||
TwineRef cell_type_ref = design->twines.lookup(cell->type.str());
|
||||
if (cell_type_ref != Twine::Null && design->has(cell_type_ref))
|
||||
module_deps[mod].insert(design->module(cell_type_ref));
|
||||
}
|
||||
}
|
||||
|
||||
// simple good-enough topological sort
|
||||
|
|
@ -1881,7 +1887,7 @@ struct Smt2Backend : public Backend {
|
|||
not_ready_yet:;
|
||||
}
|
||||
if (sorted_modules_idx == sorted_modules.size())
|
||||
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape());
|
||||
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->design->twines.str(module_deps.begin()->first->meta_->name).c_str());
|
||||
while (sorted_modules_idx < sorted_modules.size())
|
||||
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct SmvWorker
|
|||
ct(module->design), sigmap(module), module(module), f(f), verbose(verbose), idcounter(0)
|
||||
{
|
||||
for (auto mod : module->design->modules())
|
||||
cid(mod->name, true);
|
||||
cid(IdString(module->design->twines.str(mod->meta_->name)), true);
|
||||
|
||||
for (auto wire : module->wires())
|
||||
cid(wire->name, true);
|
||||
|
|
@ -100,7 +100,7 @@ struct SmvWorker
|
|||
cid(cell->name, true);
|
||||
cid(cell->type, true);
|
||||
for (auto &conn : cell->connections())
|
||||
cid(conn.first, true);
|
||||
cid(IdString(module->design->twines.str(conn.first)), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ struct SmvWorker
|
|||
|
||||
void run()
|
||||
{
|
||||
f << stringf("MODULE %s\n", cid(module->name));
|
||||
f << stringf("MODULE %s\n", cid(IdString(module->design->twines.str(module->meta_->name))));
|
||||
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
|
|
@ -597,9 +597,9 @@ struct SmvWorker
|
|||
|
||||
for (auto &conn : cell->connections())
|
||||
if (cell->output(conn.first))
|
||||
definitions.push_back(stringf("%s := %s.%s;", lvalue(conn.second), cid(cell->name), cid(conn.first)));
|
||||
definitions.push_back(stringf("%s := %s.%s;", lvalue(conn.second), cid(cell->name), cid(IdString(module->design->twines.str(conn.first)))));
|
||||
else
|
||||
definitions.push_back(stringf("%s.%s := %s;", cid(cell->name), cid(conn.first), rvalue(conn.second)));
|
||||
definitions.push_back(stringf("%s.%s := %s;", cid(cell->name), cid(IdString(module->design->twines.str(conn.first))), rvalue(conn.second)));
|
||||
}
|
||||
|
||||
for (Wire *wire : partial_assignment_wires)
|
||||
|
|
|
|||
|
|
@ -104,8 +104,9 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
|
|||
for (RTLIL::Wire *wire : ports) {
|
||||
log_assert(wire != NULL);
|
||||
RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width);
|
||||
if (cell->hasPort(wire->name)) {
|
||||
sig = sigmap(cell->getPort(wire->name));
|
||||
TwineRef wire_name_ref = design->twines.lookup(wire->name.str());
|
||||
if (cell->hasPort(wire_name_ref)) {
|
||||
sig = sigmap(cell->getPort(wire_name_ref));
|
||||
sig.extend_u0(wire->width, false);
|
||||
}
|
||||
port_sigs.push_back(sig);
|
||||
|
|
@ -213,7 +214,7 @@ struct SpiceBackend : public Backend {
|
|||
if (top_module_name.empty())
|
||||
for (auto module : design->modules())
|
||||
if (module->get_bool_attribute(ID::top))
|
||||
top_module_name = module->name.str();
|
||||
top_module_name = design->twines.str(module->meta_->name);
|
||||
|
||||
*f << stringf("* SPICE netlist generated by %s\n", yosys_maybe_version());
|
||||
*f << stringf("\n");
|
||||
|
|
@ -228,7 +229,7 @@ struct SpiceBackend : public Backend {
|
|||
if (module->memories.size() != 0)
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in SPICE backend!\n", module);
|
||||
|
||||
if (module->name == RTLIL::escape_id(top_module_name)) {
|
||||
if (design->twines.str(module->meta_->name) == RTLIL::escape_id(top_module_name)) {
|
||||
top_module = module;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -242,7 +243,7 @@ struct SpiceBackend : public Backend {
|
|||
ports.at(wire->port_id-1) = wire;
|
||||
}
|
||||
|
||||
*f << stringf(".SUBCKT %s", spice_id2str(module->name));
|
||||
*f << stringf(".SUBCKT %s", spice_id2str(IdString(design->twines.str(module->meta_->name))));
|
||||
for (RTLIL::Wire *wire : ports) {
|
||||
log_assert(wire != NULL);
|
||||
if (wire->width > 1) {
|
||||
|
|
@ -253,7 +254,7 @@ struct SpiceBackend : public Backend {
|
|||
}
|
||||
*f << stringf("\n");
|
||||
print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
|
||||
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name));
|
||||
*f << stringf(".ENDS %s\n\n", spice_id2str(IdString(design->twines.str(module->meta_->name))));
|
||||
}
|
||||
|
||||
if (!top_module_name.empty()) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ struct TableBackend : public Backend {
|
|||
if (wire->port_id == 0)
|
||||
continue;
|
||||
|
||||
*f << module->name.unescape() << "\t";
|
||||
*f << design->twines.str(module->meta_->name) << "\t";
|
||||
*f << wire->name.unescape() << "\t";
|
||||
*f << "-" << "\t";
|
||||
*f << "-" << "\t";
|
||||
|
|
@ -97,10 +97,10 @@ struct TableBackend : public Backend {
|
|||
for (auto cell : module->cells())
|
||||
for (auto conn : cell->connections())
|
||||
{
|
||||
*f << module->name.unescape() << "\t";
|
||||
*f << cell->name.unescape() << "\t";
|
||||
*f << design->twines.str(module->meta_->name) << "\t";
|
||||
*f << cell->module->design->twines.str(cell->meta_->name) << "\t";
|
||||
*f << cell->type.unescape() << "\t";
|
||||
*f << conn.first.unescape() << "\t";
|
||||
*f << design->twines.str(conn.first) << "\t";
|
||||
|
||||
if (cell->input(conn.first) && cell->output(conn.first))
|
||||
*f << "inout" << "\t";
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ void reset_auto_counter(RTLIL::Module *module)
|
|||
auto_name_counter = 0;
|
||||
auto_name_offset = 0;
|
||||
|
||||
reset_auto_counter_id(module->name, false);
|
||||
reset_auto_counter_id(RTLIL::IdString(module->design->twines.flat_string(module->meta_->name)), false);
|
||||
|
||||
for (auto w : module->wires())
|
||||
reset_auto_counter_id(w->name, true);
|
||||
|
|
@ -154,7 +154,7 @@ void reset_auto_counter(RTLIL::Module *module)
|
|||
}
|
||||
|
||||
for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
|
||||
reset_auto_counter_id(it->second->name, false);
|
||||
reset_auto_counter_id(RTLIL::IdString(module->design->twines.flat_string(it->first)), false);
|
||||
|
||||
auto_name_digits = 1;
|
||||
for (size_t i = 10; i < auto_name_offset + auto_name_map.size(); i = i*10)
|
||||
|
|
@ -417,7 +417,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
|
|||
else if (modattr && (it->second == State::S1 || it->second == Const(1)))
|
||||
f << stringf(" 1 ");
|
||||
else if (it->first == ID::src && (it->second.flags & RTLIL::CONST_FLAG_STRING) && active_module && active_module->design)
|
||||
dump_const(f, RTLIL::Const(active_module->design->resolve_src(it->second.decode_string())), -1, 0, false, as_comment);
|
||||
dump_const(f, RTLIL::Const(it->second.decode_string()), -1, 0, false, as_comment);
|
||||
else
|
||||
dump_const(f, it->second, -1, 0, false, as_comment);
|
||||
f << stringf(" %s%s", as_comment ? "*/" : "*)", term);
|
||||
|
|
@ -981,15 +981,18 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
|
|||
{
|
||||
if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) {
|
||||
f << stringf("$signed(");
|
||||
dump_sigspec(f, cell->getPort("\\" + port));
|
||||
TwineRef port_ref = cell->module->design->twines.lookup("\\" + port);
|
||||
dump_sigspec(f, cell->getPort(port_ref != Twine::Null ? port_ref : cell->module->design->twines.add(Twine{"\\" + port})));
|
||||
f << stringf(")");
|
||||
} else
|
||||
dump_sigspec(f, cell->getPort("\\" + port));
|
||||
} else {
|
||||
TwineRef port_ref = cell->module->design->twines.lookup("\\" + port);
|
||||
dump_sigspec(f, cell->getPort(port_ref != Twine::Null ? port_ref : cell->module->design->twines.add(Twine{"\\" + port})));
|
||||
}
|
||||
}
|
||||
|
||||
std::string cellname(RTLIL::Cell *cell)
|
||||
{
|
||||
if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_)))
|
||||
if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(ID($ff), ID($_FF_)))
|
||||
{
|
||||
RTLIL::SigSpec sig = cell->getPort(TW::Q);
|
||||
if (GetSize(sig) != 1 || sig.is_fully_const())
|
||||
|
|
@ -1011,7 +1014,7 @@ std::string cellname(RTLIL::Cell *cell)
|
|||
if (wire->width != 1)
|
||||
cell_name += stringf("[%d]", wire->start_offset + sig[0].offset);
|
||||
|
||||
if (active_module && active_module->count_id(cell_name) > 0)
|
||||
if (active_module && active_module->count_id(active_module->design->twines.lookup(cell_name)) > 0)
|
||||
goto no_special_reg_name;
|
||||
|
||||
return id(cell_name);
|
||||
|
|
@ -2006,12 +2009,15 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
f << stringf(" %s (", cell_name);
|
||||
|
||||
bool first_arg = true;
|
||||
std::set<RTLIL::IdString> numbered_ports;
|
||||
std::set<TwineRef> numbered_ports;
|
||||
for (int i = 1; true; i++) {
|
||||
char str[16];
|
||||
snprintf(str, 16, "$%d", i);
|
||||
std::string port_str(str);
|
||||
TwineRef port_ref = cell->module->design->twines.lookup(port_str);
|
||||
bool found_port = false;
|
||||
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
||||
if (it->first != str)
|
||||
if (port_ref == Twine::Null || it->first != port_ref)
|
||||
continue;
|
||||
if (!first_arg)
|
||||
f << stringf(",");
|
||||
|
|
@ -2019,10 +2025,11 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
f << stringf("\n%s ", indent);
|
||||
dump_sigspec(f, it->second);
|
||||
numbered_ports.insert(it->first);
|
||||
goto found_numbered_port;
|
||||
found_port = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
found_numbered_port:;
|
||||
if (!found_port)
|
||||
break;
|
||||
}
|
||||
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
||||
if (numbered_ports.count(it->first))
|
||||
|
|
@ -2030,7 +2037,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
if (!first_arg)
|
||||
f << stringf(",");
|
||||
first_arg = false;
|
||||
f << stringf("\n%s .%s(", indent, id(it->first));
|
||||
f << stringf("\n%s .%s(", indent, id(cell->module->design->twines.str(it->first)).c_str());
|
||||
if (it->second.size() > 0)
|
||||
dump_sigspec(f, it->second);
|
||||
f << stringf(")");
|
||||
|
|
@ -2045,7 +2052,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
}
|
||||
}
|
||||
|
||||
if (siminit && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) {
|
||||
if (siminit && cell->is_builtin_ff() && cell->hasPort(TW::Q) && !cell->type.in(ID($ff), ID($_FF_))) {
|
||||
std::stringstream ss;
|
||||
dump_reg_init(ss, cell->getPort(TW::Q));
|
||||
if (!ss.str().empty()) {
|
||||
|
|
@ -2406,7 +2413,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!cell->is_builtin_ff() || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_)))
|
||||
if (!cell->is_builtin_ff() || !cell->hasPort(TW::Q) || cell->type.in(ID($ff), ID($_FF_)))
|
||||
continue;
|
||||
|
||||
RTLIL::SigSpec sig = cell->getPort(TW::Q);
|
||||
|
|
@ -2430,7 +2437,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
|
|||
}
|
||||
|
||||
dump_attributes(f, indent, module->attributes, "\n", /*modattr=*/true);
|
||||
f << stringf("%s" "module %s(", indent, id(module->name, false));
|
||||
f << stringf("%s" "module %s(", indent, id(RTLIL::IdString(module->design->twines.str(module->meta_->name)), false));
|
||||
int cnt = 0;
|
||||
for (auto port : module->ports) {
|
||||
Wire *wire = module->wire(port);
|
||||
|
|
@ -2714,12 +2721,12 @@ struct VerilogBackend : public Backend {
|
|||
for (auto module : design->modules()) {
|
||||
if (module->get_blackbox_attribute() != blackboxes)
|
||||
continue;
|
||||
if (selected && !design->selected_whole_module(module->name)) {
|
||||
if (design->selected_module(module->name))
|
||||
log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape());
|
||||
if (selected && !design->selected_whole_module(module->meta_->name)) {
|
||||
if (design->selected_module(module->meta_->name))
|
||||
log_cmd_error("Can't handle partially selected module %s!\n", design->twines.str(module->meta_->name).c_str());
|
||||
continue;
|
||||
}
|
||||
log("Dumping module `%s'.\n", module->name);
|
||||
log("Dumping module `%s'.\n", design->twines.str(module->meta_->name).c_str());
|
||||
module->sort();
|
||||
dump_module(*f, "", module);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ struct Test1Pass : public Pass {
|
|||
y->port_id = 2;
|
||||
|
||||
RTLIL::Wire *a_inv = module->addWire(NEW_TWINE, 4);
|
||||
module->addNeg(NEW_ID, a, a_inv, true);
|
||||
module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 3), y);
|
||||
module->addNeg(NEW_TWINE, a, a_inv, true);
|
||||
module->addMux(NEW_TWINE, a, a_inv, RTLIL::SigSpec(a, 3), y);
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,9 +223,9 @@ AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString
|
|||
{
|
||||
module = new RTLIL::Module;
|
||||
module->design = design;
|
||||
module->name = module_name;
|
||||
if (design->module(module->name))
|
||||
log_error("Duplicate definition of module %s!\n", module->name.unescape());
|
||||
module->meta_->name = design->twines.add(Twine{module_name.str()});
|
||||
if (design->module(design->twines.str(module->meta_->name)))
|
||||
log_error("Duplicate definition of module %s!\n", design->twines.str(module->meta_->name).c_str());
|
||||
}
|
||||
|
||||
void AigerReader::parse_aiger()
|
||||
|
|
@ -269,7 +269,7 @@ end_of_header:
|
|||
else
|
||||
log_abort();
|
||||
|
||||
RTLIL::Wire* n0 = module->wire(stringf("$aiger%d$0", aiger_autoidx));
|
||||
RTLIL::Wire* n0 = module->wire(design->twines.lookup(stringf("$aiger%d$0", aiger_autoidx)));
|
||||
if (n0)
|
||||
module->connect(n0, State::S0);
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ end_of_header:
|
|||
log_assert(l1 < latches.size());
|
||||
wire = latches[l1];
|
||||
} else if (c == 'o') {
|
||||
wire = module->wire(escaped_s);
|
||||
wire = module->wire(design->twines.lookup(escaped_s.str()));
|
||||
log_assert(l1 < outputs.size());
|
||||
if (wire) {
|
||||
// Could have been renamed by a latch
|
||||
|
|
@ -307,7 +307,7 @@ end_of_header:
|
|||
wire = bad_properties[l1];
|
||||
} else log_abort();
|
||||
|
||||
module->rename(wire, escaped_s);
|
||||
module->rename(wire, design->twines.add(Twine{escaped_s.str()}));
|
||||
}
|
||||
else if (c == 'j' || c == 'f') {
|
||||
// TODO
|
||||
|
|
@ -347,25 +347,25 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned
|
|||
const unsigned variable = literal >> 1;
|
||||
const bool invert = literal & 1;
|
||||
RTLIL::IdString wire_name(stringf("$aiger%d$%d%s", aiger_autoidx, variable, invert ? "b" : ""));
|
||||
RTLIL::Wire *wire = module->wire(wire_name);
|
||||
RTLIL::Wire *wire = module->wire(design->twines.lookup(wire_name.str()));
|
||||
if (wire) return wire;
|
||||
log_debug2("Creating %s\n", wire_name.c_str());
|
||||
wire = module->addWire(wire_name);
|
||||
wire = module->addWire(Twine{wire_name.str()});
|
||||
wire->port_input = wire->port_output = false;
|
||||
if (!invert) return wire;
|
||||
RTLIL::IdString wire_inv_name(stringf("$aiger%d$%d", aiger_autoidx, variable));
|
||||
RTLIL::Wire *wire_inv = module->wire(wire_inv_name);
|
||||
RTLIL::Wire *wire_inv = module->wire(design->twines.lookup(wire_inv_name.str()));
|
||||
if (wire_inv) {
|
||||
if (module->cell(wire_inv_name)) return wire;
|
||||
if (module->cell(design->twines.lookup(wire_inv_name.str()))) return wire;
|
||||
}
|
||||
else {
|
||||
log_debug2("Creating %s\n", wire_inv_name.c_str());
|
||||
wire_inv = module->addWire(wire_inv_name);
|
||||
wire_inv = module->addWire(Twine{wire_inv_name.str()});
|
||||
wire_inv->port_input = wire_inv->port_output = false;
|
||||
}
|
||||
|
||||
log_debug2("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
|
||||
module->addNotGate(stringf("$not$aiger%d$%d", aiger_autoidx, variable), wire_inv, wire);
|
||||
module->addNotGate(Twine{stringf("$not$aiger%d$%d", aiger_autoidx, variable)}, wire_inv, wire);
|
||||
|
||||
return wire;
|
||||
}
|
||||
|
|
@ -402,7 +402,7 @@ void AigerReader::parse_xaiger()
|
|||
else
|
||||
log_abort();
|
||||
|
||||
RTLIL::Wire* n0 = module->wire(stringf("$aiger%d$0", aiger_autoidx));
|
||||
RTLIL::Wire* n0 = module->wire(design->twines.lookup(stringf("$aiger%d$0", aiger_autoidx)));
|
||||
if (n0)
|
||||
module->connect(n0, State::S0);
|
||||
|
||||
|
|
@ -426,7 +426,7 @@ void AigerReader::parse_xaiger()
|
|||
uint32_t rootNodeID = parse_xaiger_literal(f);
|
||||
uint32_t cutLeavesM = parse_xaiger_literal(f);
|
||||
log_debug2("rootNodeID=%d cutLeavesM=%d\n", rootNodeID, cutLeavesM);
|
||||
RTLIL::Wire *output_sig = module->wire(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID));
|
||||
RTLIL::Wire *output_sig = module->wire(design->twines.lookup(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
log_assert(output_sig);
|
||||
uint32_t nodeID;
|
||||
RTLIL::SigSpec input_sig;
|
||||
|
|
@ -437,7 +437,7 @@ void AigerReader::parse_xaiger()
|
|||
log_debug("\tLUT '$lut$aiger%d$%d' input %d is constant!\n", aiger_autoidx, rootNodeID, cutLeavesM);
|
||||
continue;
|
||||
}
|
||||
RTLIL::Wire *wire = module->wire(stringf("$aiger%d$%d", aiger_autoidx, nodeID));
|
||||
RTLIL::Wire *wire = module->wire(design->twines.lookup(stringf("$aiger%d$%d", aiger_autoidx, nodeID)));
|
||||
log_assert(wire);
|
||||
input_sig.append(wire);
|
||||
}
|
||||
|
|
@ -456,10 +456,10 @@ void AigerReader::parse_xaiger()
|
|||
log_assert(o.wire == nullptr);
|
||||
lut_mask.set(gray, o.data);
|
||||
}
|
||||
RTLIL::Cell *output_cell = module->cell(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID));
|
||||
RTLIL::Cell *output_cell = module->cell(design->twines.lookup(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
log_assert(output_cell);
|
||||
module->remove(output_cell);
|
||||
module->addLut(stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID), input_sig, output_sig, std::move(lut_mask));
|
||||
module->addLut(Twine{stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID)}, input_sig, output_sig, std::move(lut_mask));
|
||||
}
|
||||
}
|
||||
else if (c == 'r') {
|
||||
|
|
@ -504,9 +504,9 @@ 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(stringf("$box%u", oldBoxNum), stringf("$__boxid%u", boxUniqueId));
|
||||
cell->setPort(ID(i), SigSpec(State::S0, boxInputs));
|
||||
cell->setPort(ID(o), SigSpec(State::S0, boxOutputs));
|
||||
RTLIL::Cell* cell = module->addCell(Twine{stringf("$box%u", oldBoxNum)}, ID(stringf("$__boxid%u", boxUniqueId)));
|
||||
cell->setPort(TW::I, SigSpec(State::S0, boxInputs));
|
||||
cell->setPort(TW::O, SigSpec(State::S0, boxOutputs));
|
||||
cell->attributes[ID::abc9_box_seq] = oldBoxNum;
|
||||
boxes.emplace_back(cell);
|
||||
}
|
||||
|
|
@ -538,7 +538,7 @@ void AigerReader::parse_aiger_ascii()
|
|||
log_error("Line %u cannot be interpreted as an input!\n", line_count);
|
||||
log_debug2("%d is an input\n", l1);
|
||||
log_assert(!(l1 & 1)); // Inputs can't be inverted
|
||||
RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, l1 >> 1));
|
||||
RTLIL::Wire *wire = module->addWire(Twine{stringf("$i%0*d", digits, l1 >> 1)});
|
||||
wire->port_input = true;
|
||||
module->connect(createWireIfNotExists(module, l1), wire);
|
||||
inputs.push_back(wire);
|
||||
|
|
@ -547,10 +547,10 @@ void AigerReader::parse_aiger_ascii()
|
|||
// Parse latches
|
||||
RTLIL::Wire *clk_wire = nullptr;
|
||||
if (L > 0 && !clk_name.empty()) {
|
||||
clk_wire = module->wire(clk_name);
|
||||
clk_wire = module->wire(design->twines.lookup(clk_name.str()));
|
||||
log_assert(!clk_wire);
|
||||
log_debug2("Creating %s\n", clk_name.c_str());
|
||||
clk_wire = module->addWire(clk_name);
|
||||
clk_wire = module->addWire(Twine{clk_name.str()});
|
||||
clk_wire->port_input = true;
|
||||
clk_wire->port_output = false;
|
||||
}
|
||||
|
|
@ -560,14 +560,14 @@ void AigerReader::parse_aiger_ascii()
|
|||
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
||||
log_debug2("%d %d is a latch\n", l1, l2);
|
||||
log_assert(!(l1 & 1));
|
||||
RTLIL::Wire *q_wire = module->addWire(stringf("$l%0*d", digits, l1 >> 1));
|
||||
RTLIL::Wire *q_wire = module->addWire(Twine{stringf("$l%0*d", digits, l1 >> 1)});
|
||||
module->connect(createWireIfNotExists(module, l1), q_wire);
|
||||
RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
|
||||
|
||||
if (clk_wire)
|
||||
module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
|
||||
module->addDffGate(NEW_TWINE, clk_wire, d_wire, q_wire);
|
||||
else
|
||||
module->addFfGate(NEW_ID, d_wire, q_wire);
|
||||
module->addFfGate(NEW_TWINE, d_wire, q_wire);
|
||||
|
||||
// Reset logic is optional in AIGER 1.9
|
||||
if (f.peek() == ' ') {
|
||||
|
|
@ -599,7 +599,7 @@ void AigerReader::parse_aiger_ascii()
|
|||
std::getline(f, line); // Ignore up to start of next line
|
||||
|
||||
log_debug2("%d is an output\n", l1);
|
||||
RTLIL::Wire *wire = module->addWire(stringf("$o%0*d", digits, i));
|
||||
RTLIL::Wire *wire = module->addWire(Twine{stringf("$o%0*d", digits, i)});
|
||||
wire->port_output = true;
|
||||
module->connect(wire, createWireIfNotExists(module, l1));
|
||||
outputs.push_back(wire);
|
||||
|
|
@ -640,7 +640,7 @@ void AigerReader::parse_aiger_ascii()
|
|||
RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
|
||||
RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
|
||||
RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
|
||||
module->addAndGate("$and" + o_wire->name.str(), i1_wire, i2_wire, o_wire);
|
||||
module->addAndGate(Twine{stringf("$and%s", design->twines.str(o_wire->meta_->name).c_str())}, i1_wire, i2_wire, o_wire);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -665,7 +665,7 @@ void AigerReader::parse_aiger_binary()
|
|||
int digits = decimal_digits(I);
|
||||
for (unsigned i = 1; i <= I; ++i) {
|
||||
log_debug2("%d is an input\n", i);
|
||||
RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i));
|
||||
RTLIL::Wire *wire = module->addWire(Twine{stringf("$i%0*d", digits, i)});
|
||||
wire->port_input = true;
|
||||
module->connect(createWireIfNotExists(module, i << 1), wire);
|
||||
inputs.push_back(wire);
|
||||
|
|
@ -674,10 +674,10 @@ void AigerReader::parse_aiger_binary()
|
|||
// Parse latches
|
||||
RTLIL::Wire *clk_wire = nullptr;
|
||||
if (L > 0 && !clk_name.empty()) {
|
||||
clk_wire = module->wire(clk_name);
|
||||
clk_wire = module->wire(design->twines.lookup(clk_name.str()));
|
||||
log_assert(!clk_wire);
|
||||
log_debug2("Creating %s\n", clk_name.c_str());
|
||||
clk_wire = module->addWire(clk_name);
|
||||
clk_wire = module->addWire(Twine{clk_name.str()});
|
||||
clk_wire->port_input = true;
|
||||
clk_wire->port_output = false;
|
||||
}
|
||||
|
|
@ -687,14 +687,14 @@ void AigerReader::parse_aiger_binary()
|
|||
if (!(f >> l2))
|
||||
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
||||
log_debug("%d %d is a latch\n", l1, l2);
|
||||
RTLIL::Wire *q_wire = module->addWire(stringf("$l%0*d", digits, l1 >> 1));
|
||||
RTLIL::Wire *q_wire = module->addWire(Twine{stringf("$l%0*d", digits, l1 >> 1)});
|
||||
module->connect(createWireIfNotExists(module, l1), q_wire);
|
||||
RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
|
||||
|
||||
if (clk_wire)
|
||||
module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
|
||||
module->addDff(NEW_TWINE, clk_wire, d_wire, q_wire);
|
||||
else
|
||||
module->addFf(NEW_ID, d_wire, q_wire);
|
||||
module->addFf(NEW_TWINE, d_wire, q_wire);
|
||||
|
||||
// Reset logic is optional in AIGER 1.9
|
||||
if (f.peek() == ' ') {
|
||||
|
|
@ -726,7 +726,7 @@ void AigerReader::parse_aiger_binary()
|
|||
std::getline(f, line); // Ignore up to start of next line
|
||||
|
||||
log_debug2("%d is an output\n", l1);
|
||||
RTLIL::Wire *wire = module->addWire(stringf("$o%0*d", digits, i));
|
||||
RTLIL::Wire *wire = module->addWire(Twine{stringf("$o%0*d", digits, i)});
|
||||
wire->port_output = true;
|
||||
module->connect(wire, createWireIfNotExists(module, l1));
|
||||
outputs.push_back(wire);
|
||||
|
|
@ -767,7 +767,7 @@ void AigerReader::parse_aiger_binary()
|
|||
RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
|
||||
RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
|
||||
RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
|
||||
module->addAndGate("$and" + o_wire->name.str(), i1_wire, i2_wire, o_wire);
|
||||
module->addAndGate(Twine{stringf("$and%s", design->twines.str(o_wire->meta_->name).c_str())}, i1_wire, i2_wire, o_wire);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -775,7 +775,7 @@ void AigerReader::post_process()
|
|||
{
|
||||
unsigned ci_count = 0, co_count = 0;
|
||||
for (auto cell : boxes) {
|
||||
for (auto &bit : cell->connections_.at(ID(i))) {
|
||||
for (auto &bit : cell->connections_.at(TW::I)) {
|
||||
log_assert(bit == State::S0);
|
||||
log_assert(co_count < outputs.size());
|
||||
bit = outputs[co_count++];
|
||||
|
|
@ -783,7 +783,7 @@ void AigerReader::post_process()
|
|||
log_assert(bit.wire->port_output);
|
||||
bit.wire->port_output = false;
|
||||
}
|
||||
for (auto &bit : cell->connections_.at(ID(o))) {
|
||||
for (auto &bit : cell->connections_.at(TW::O)) {
|
||||
log_assert(bit == State::S0);
|
||||
log_assert((piNum + ci_count) < inputs.size());
|
||||
bit = inputs[piNum + ci_count++];
|
||||
|
|
@ -804,7 +804,7 @@ void AigerReader::post_process()
|
|||
log_assert(q->port_input);
|
||||
q->port_input = false;
|
||||
|
||||
Cell* ff = module->addFfGate(NEW_ID, d, q);
|
||||
Cell* ff = module->addFfGate(NEW_TWINE, d, q);
|
||||
ff->attributes[ID::abc9_mergeability] = mergeability[i];
|
||||
q->attributes[ID::init] = initial_state[i];
|
||||
}
|
||||
|
|
@ -829,9 +829,9 @@ void AigerReader::post_process()
|
|||
// Cope with the fact that a CI might be identical
|
||||
// to a PI (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = module->wire(escaped_s);
|
||||
existing = module->wire(design->twines.lookup(escaped_s.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, escaped_s);
|
||||
module->rename(wire, design->twines.add(Twine{escaped_s.str()}));
|
||||
else {
|
||||
wire->port_input = false;
|
||||
module->connect(wire, existing);
|
||||
|
|
@ -840,9 +840,9 @@ void AigerReader::post_process()
|
|||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = module->wire(indexed_name);
|
||||
existing = module->wire(design->twines.lookup(indexed_name.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, indexed_name);
|
||||
module->rename(wire, design->twines.add(Twine{indexed_name.str()}));
|
||||
else {
|
||||
module->connect(wire, existing);
|
||||
wire->port_input = false;
|
||||
|
|
@ -874,9 +874,9 @@ void AigerReader::post_process()
|
|||
// Cope with the fact that a CO might be identical
|
||||
// to a PO (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = module->wire(escaped_s);
|
||||
existing = module->wire(design->twines.lookup(escaped_s.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, escaped_s);
|
||||
module->rename(wire, design->twines.add(Twine{escaped_s.str()}));
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
|
|
@ -887,9 +887,9 @@ void AigerReader::post_process()
|
|||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = module->wire(indexed_name);
|
||||
existing = module->wire(design->twines.lookup(indexed_name.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, indexed_name);
|
||||
module->rename(wire, design->twines.add(Twine{indexed_name.str()}));
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
|
|
@ -911,11 +911,11 @@ void AigerReader::post_process()
|
|||
}
|
||||
}
|
||||
else if (type == "box") {
|
||||
RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
|
||||
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());
|
||||
else
|
||||
module->rename(cell, escaped_s);
|
||||
module->rename(cell, design->twines.add(Twine{escaped_s.str()}));
|
||||
}
|
||||
else
|
||||
log_error("Symbol type '%s' not recognised.\n", type);
|
||||
|
|
@ -929,30 +929,30 @@ void AigerReader::post_process()
|
|||
if (min == 0 && max == 0)
|
||||
continue;
|
||||
|
||||
RTLIL::Wire *wire = module->wire(name);
|
||||
RTLIL::Wire *wire = module->wire(design->twines.lookup(name.str()));
|
||||
if (wire)
|
||||
module->rename(wire, RTLIL::escape_id(stringf("%s[%d]", name, 0)));
|
||||
module->rename(wire, design->twines.add(Twine{RTLIL::escape_id(stringf("%s[%d]", name.str(), 0))}));
|
||||
|
||||
// Do not make ports with a mix of input/output into
|
||||
// wide ports
|
||||
bool port_input = false, port_output = false;
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
|
||||
RTLIL::Wire *other_wire = module->wire(other_name);
|
||||
RTLIL::Wire *other_wire = module->wire(design->twines.lookup(other_name.str()));
|
||||
if (other_wire) {
|
||||
port_input = port_input || other_wire->port_input;
|
||||
port_output = port_output || other_wire->port_output;
|
||||
}
|
||||
}
|
||||
|
||||
wire = module->addWire(name, max-min+1);
|
||||
wire = module->addWire(Twine{name.str()}, max-min+1);
|
||||
wire->start_offset = min;
|
||||
wire->port_input = port_input;
|
||||
wire->port_output = port_output;
|
||||
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = stringf("%s[%d]", name, i);
|
||||
RTLIL::Wire *other_wire = module->wire(other_name);
|
||||
RTLIL::Wire *other_wire = module->wire(design->twines.lookup(other_name.str()));
|
||||
if (other_wire) {
|
||||
other_wire->port_input = false;
|
||||
other_wire->port_output = false;
|
||||
|
|
@ -971,7 +971,7 @@ void AigerReader::post_process()
|
|||
RTLIL::Design *mapped_design = new RTLIL::Design;
|
||||
mapped_design->add(module);
|
||||
Pass::call(mapped_design, "clean");
|
||||
mapped_design->modules_.erase(module->name);
|
||||
mapped_design->modules_.erase(module->meta_->name);
|
||||
delete mapped_design;
|
||||
|
||||
design->add(module);
|
||||
|
|
@ -980,9 +980,9 @@ void AigerReader::post_process()
|
|||
if (cell->type != ID($lut)) continue;
|
||||
auto y_port = cell->getPort(TW::Y).as_bit();
|
||||
if (y_port.wire->width == 1)
|
||||
module->rename(cell, stringf("$lut%s", y_port.wire->name));
|
||||
module->rename(cell, design->twines.add(Twine{stringf("$lut%s", design->twines.str(y_port.wire->meta_->name).c_str())}));
|
||||
else
|
||||
module->rename(cell, stringf("$lut%s[%d]", y_port.wire->name, y_port.offset));
|
||||
module->rename(cell, design->twines.add(Twine{stringf("$lut%s[%d]", design->twines.str(y_port.wire->meta_->name).c_str(), y_port.offset)}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,17 +215,18 @@ struct Xaiger2Frontend : public Frontend {
|
|||
for (auto port_id : def->ports) {
|
||||
Wire *port = def->wire(port_id);
|
||||
if (port->port_output) {
|
||||
if (!cell->hasPort(search.find(port_id)) || cell->getPort(port_id).size() != port->width)
|
||||
if (!cell->hasPort(port_id) || cell->getPort(port_id).size() != port->width)
|
||||
log_error("Malformed design (1)\n");
|
||||
|
||||
SigSpec &conn = cell->connections_[port_id];
|
||||
std::string port_id_str = design->twines.str(port_id);
|
||||
for (int j = 0; j < port->width; j++) {
|
||||
if (conn[j].wire && conn[j].wire->port_output)
|
||||
conn[j] = module->addWire(module->uniquify(
|
||||
stringf("$box$%s$%s$%d",
|
||||
cell->name.isPublic() ? cell->name.c_str() + 1 : cell->name.c_str(),
|
||||
port_id.isPublic() ? port_id.c_str() + 1 : port_id.c_str(),
|
||||
j)));
|
||||
if (conn[j].wire && conn[j].wire->port_output) {
|
||||
std::string cell_name_str = cell->name.isPublic() ? cell->name.c_str() + 1 : cell->name.c_str();
|
||||
const char *port_id_str_part = RTLIL::IdString(port_id_str).isPublic() ? port_id_str.c_str() + 1 : port_id_str.c_str();
|
||||
auto new_wire_name = module->uniquify(design->twines.add(Twine{stringf("$box$%s$%s$%d", cell_name_str.c_str(), port_id_str_part, j)}));
|
||||
conn[j] = module->addWire(new_wire_name);
|
||||
}
|
||||
|
||||
bits[2*(pi_num + ci_counter + box_ci_idx++) + 2] = conn[j];
|
||||
}
|
||||
|
|
@ -291,15 +292,15 @@ struct Xaiger2Frontend : public Frontend {
|
|||
log_assert(bits[out_lit] == RTLIL::Sm);
|
||||
log_assert(cell_id < cells.size());
|
||||
auto &cell = cells[cell_id];
|
||||
Cell *instance = module->addCell(module->uniquify(stringf("$sc%d", out_lit)), cell.type);
|
||||
auto out_w = module->addWire(module->uniquify(stringf("$lit%d", out_lit)));
|
||||
instance->setPort(cell.out, out_w);
|
||||
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);
|
||||
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(in, bits[in_lit]);
|
||||
instance->setPort(design->twines.add(Twine{in.str()}), bits[in_lit]);
|
||||
}
|
||||
}
|
||||
} else if (c == '\n') {
|
||||
|
|
@ -413,7 +414,7 @@ struct Xaiger2Frontend : public Frontend {
|
|||
log_error("Bad map file: primary output literal out of range\n");
|
||||
if (bits[lit] == RTLIL::Sm)
|
||||
log_error("Bad map file: primary output literal is a marker\n");
|
||||
Wire *w = module->wire(name);
|
||||
Wire *w = module->wire(design->twines.lookup(name));
|
||||
if (!w || woffset < 0 || woffset >= w->width)
|
||||
log_error("Map file references non-existent signal bit %s[%d]\n",
|
||||
name.c_str(), woffset);
|
||||
|
|
@ -433,11 +434,12 @@ struct Xaiger2Frontend : public Frontend {
|
|||
log_error("Bad map file: pseudo primary output literal out of range\n");
|
||||
if (bits[lit] == RTLIL::Sm)
|
||||
log_error("Bad map file: pseudo primary output literal is a marker\n");
|
||||
Cell *cell = module->cell(box_name);
|
||||
if (!cell || !cell->hasPort(box_port))
|
||||
Cell *cell = module->cell(design->twines.lookup(box_name));
|
||||
auto box_port_ref = design->twines.lookup(box_port);
|
||||
if (!cell || !cell->hasPort(box_port_ref))
|
||||
log_error("Map file references non-existent box port %s/%s\n",
|
||||
box_name.c_str(), box_port.c_str());
|
||||
SigSpec &port = cell->connections_[box_port];
|
||||
SigSpec &port = cell->connections_[box_port_ref];
|
||||
if (poffset < 0 || poffset >= port.size())
|
||||
log_error("Map file references non-existent box port bit %s/%s[%d]\n",
|
||||
box_name.c_str(), box_port.c_str(), poffset);
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,7 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast)
|
|||
return;
|
||||
const auto &loc = ast->location;
|
||||
if (!loc.begin.filename || loc.begin.filename->empty()) {
|
||||
current_module->design->set_src_attribute(obj, ast->loc_string());
|
||||
current_module->design->set_src_attribute(obj, current_module->design->twines.add(Twine{ast->loc_string()}));
|
||||
return;
|
||||
}
|
||||
// Split filename and per-location tail so the filename interns once
|
||||
|
|
@ -1123,14 +1123,12 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast)
|
|||
// thousands of objects in one file this collapses N copies of a long
|
||||
// path into 1 Leaf + N short Suffix tails.
|
||||
TwinePool *pool = ¤t_module->design->twines;
|
||||
TwineRef file_id = pool->intern(*loc.begin.filename);
|
||||
TwineRef file_id = pool->add(Twine{*loc.begin.filename});
|
||||
std::string tail = stringf(":%d.%d-%d.%d",
|
||||
loc.begin.line, loc.begin.column,
|
||||
loc.end.line, loc.end.column);
|
||||
TwineRef suffix_id = pool->intern_suffix(file_id, tail);
|
||||
pool->release(file_id); // suffix internally holds a ref now
|
||||
TwineRef suffix_id = pool->add(Twine{Twine::Suffix{file_id, tail}});
|
||||
current_module->design->obj_set_src_id(obj, suffix_id);
|
||||
pool->release(suffix_id); // obj_set_src_id retained on obj's behalf
|
||||
}
|
||||
|
||||
static bool param_has_no_default(const AstNode* param) {
|
||||
|
|
@ -1162,7 +1160,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
|
|||
module->design = design;
|
||||
|
||||
module->ast = nullptr;
|
||||
module->name = ast->str;
|
||||
module->meta_->name = design->twines.add(Twine{ast->str});
|
||||
set_src_attr(module, ast);
|
||||
module->set_bool_attribute(ID::cells_not_processed);
|
||||
|
||||
|
|
@ -1373,12 +1371,12 @@ AST_INTERNAL::process_and_replace_module(RTLIL::Design *design,
|
|||
// a static counter to make sure we get a unique name.
|
||||
static unsigned counter;
|
||||
std::ostringstream new_name;
|
||||
new_name << old_module->name.str()
|
||||
new_name << design->twines.str(old_module->meta_->name)
|
||||
<< "_before_process_and_replace_module_"
|
||||
<< counter;
|
||||
++counter;
|
||||
|
||||
design->rename(old_module, new_name.str());
|
||||
design->rename(old_module, design->twines.add(Twine{new_name.str()}));
|
||||
old_module->set_bool_attribute(ID::to_delete);
|
||||
|
||||
// Check if the module was the top module. If it was, we need to remove
|
||||
|
|
@ -1486,8 +1484,9 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump
|
|||
if (defer_local)
|
||||
child->str = "$abstract" + child->str;
|
||||
|
||||
if (design->has(child->str)) {
|
||||
RTLIL::Module *existing_mod = design->module(child->str);
|
||||
TwineRef mod_name = design->twines.lookup(child->str);
|
||||
if (design->has(mod_name)) {
|
||||
RTLIL::Module *existing_mod = design->module(mod_name);
|
||||
if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
|
||||
log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str);
|
||||
} else if (nooverwrite) {
|
||||
|
|
@ -1612,9 +1611,11 @@ bool AstModule::reprocess_if_necessary(RTLIL::Design *design)
|
|||
std::string modname = cell->get_string_attribute(ID::reprocess_after);
|
||||
if (modname.empty())
|
||||
continue;
|
||||
if (design->module(modname) || design->module("$abstract" + modname)) {
|
||||
TwineRef mod_ref = design->twines.lookup(modname);
|
||||
TwineRef abstract_ref = design->twines.lookup("$abstract" + modname);
|
||||
if (design->module(mod_ref) || design->module(abstract_ref)) {
|
||||
log("Reprocessing module %s because instantiated module %s has become available.\n",
|
||||
name.unescape(), RTLIL::unescape_id(modname));
|
||||
design->twines.str(meta_->name).c_str(), RTLIL::unescape_id(modname));
|
||||
loadconfig();
|
||||
process_and_replace_module(design, this, ast.get(), NULL);
|
||||
return true;
|
||||
|
|
@ -1709,7 +1710,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
|
|||
|
||||
bool has_interfaces = false;
|
||||
for(auto &intf : interfaces) {
|
||||
interf_info += intf.second->name.unescape();
|
||||
interf_info += design->twines.str(intf.second->meta_->name);
|
||||
has_interfaces = true;
|
||||
}
|
||||
|
||||
|
|
@ -1717,10 +1718,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
|
|||
if (has_interfaces)
|
||||
new_modname += "$interfaces$" + interf_info;
|
||||
|
||||
|
||||
if (!design->has(new_modname)) {
|
||||
TwineRef new_modname_ref = design->twines.lookup(new_modname);
|
||||
if (!design->has(new_modname_ref)) {
|
||||
if (!new_ast) {
|
||||
auto mod = dynamic_cast<AstModule*>(design->module(modname));
|
||||
TwineRef modname_ref = design->twines.lookup(modname);
|
||||
auto mod = dynamic_cast<AstModule*>(design->module(modname_ref));
|
||||
new_ast = mod->ast->clone();
|
||||
}
|
||||
modname = new_modname;
|
||||
|
|
@ -1749,19 +1751,20 @@ 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) {
|
||||
if(mod->wire(intf.first) != nullptr) {
|
||||
TwineRef intf_name = design->twines.lookup(intf.first.str());
|
||||
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
|
||||
// that a cell with the same name cannot be created (below)...
|
||||
// Since we won't expect many interfaces to exist in a module,
|
||||
// we can let this slide...
|
||||
pool<RTLIL::Wire*> to_remove;
|
||||
to_remove.insert(mod->wire(intf.first));
|
||||
to_remove.insert(mod->wire(intf_name));
|
||||
mod->remove(to_remove);
|
||||
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(intf.first, intf.second->name);
|
||||
RTLIL::Cell *new_subcell = mod->addCell(Twine{intf.first.str()}, RTLIL::IdString(design->twines.str(intf.second->meta_->name)));
|
||||
new_subcell->set_bool_attribute(ID::is_interface);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1790,10 +1793,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
|
|||
std::unique_ptr<AstNode> new_ast = NULL;
|
||||
std::string modname = derive_common(design, parameters, &new_ast, quiet);
|
||||
|
||||
if (!design->has(modname) && new_ast) {
|
||||
TwineRef modname_ref = design->twines.lookup(modname);
|
||||
if (!design->has(modname_ref) && new_ast) {
|
||||
new_ast->str = modname;
|
||||
process_module(design, new_ast.get(), false, NULL, quiet);
|
||||
design->module(modname)->check();
|
||||
design->module(modname_ref)->check();
|
||||
} else if (!quiet) {
|
||||
log("Found cached RTLIL representation for module `%s'.\n", modname);
|
||||
}
|
||||
|
|
@ -1832,7 +1836,7 @@ std::string AST::derived_module_name(std::string stripped_name, const std::vecto
|
|||
// create a new parametric module (when needed) and return the name of the generated module
|
||||
std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, std::unique_ptr<AstNode>* new_ast_out, bool quiet)
|
||||
{
|
||||
std::string stripped_name = name.str();
|
||||
std::string stripped_name = design->twines.str(meta_->name);
|
||||
(*new_ast_out) = nullptr;
|
||||
|
||||
if (stripped_name.compare(0, 9, "$abstract") == 0)
|
||||
|
|
@ -1864,7 +1868,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id
|
|||
if (parameters.size()) // not named_parameters to cover hierarchical defparams
|
||||
modname = derived_module_name(stripped_name, named_parameters);
|
||||
|
||||
if (design->has(modname))
|
||||
if (design->has(design->twines.lookup(modname)))
|
||||
return modname;
|
||||
|
||||
if (!quiet)
|
||||
|
|
@ -1932,7 +1936,7 @@ RTLIL::Module *AstModule::clone() const
|
|||
{
|
||||
AstModule *new_mod = new AstModule;
|
||||
new_mod->design = design;
|
||||
new_mod->name = name;
|
||||
new_mod->meta_->name = meta_->name;
|
||||
cloneInto(new_mod);
|
||||
|
||||
new_mod->ast = ast->clone();
|
||||
|
|
@ -1955,7 +1959,7 @@ RTLIL::Module *AstModule::clone(RTLIL::Design *dst, bool src_id_verbatim) const
|
|||
{
|
||||
AstModule *new_mod = new AstModule;
|
||||
new_mod->design = dst;
|
||||
new_mod->name = name;
|
||||
new_mod->meta_->name = dst->twines.copy_from(design->twines, meta_->name);
|
||||
cloneInto(new_mod, src_id_verbatim);
|
||||
dst->add(new_mod);
|
||||
|
||||
|
|
@ -1979,7 +1983,7 @@ RTLIL::Module *AstModule::clone(RTLIL::Design *dst, RTLIL::IdString target_name,
|
|||
{
|
||||
AstModule *new_mod = new AstModule;
|
||||
new_mod->design = dst;
|
||||
new_mod->name = target_name;
|
||||
new_mod->meta_->name = dst->twines.add(Twine{target_name.str()});
|
||||
cloneInto(new_mod, src_id_verbatim);
|
||||
dst->add(new_mod);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ using namespace AST_INTERNAL;
|
|||
static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString 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(name, type);
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
|
||||
set_src_attr(cell, that);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, result_width);
|
||||
set_src_attr(wire, that);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
|
|
@ -78,10 +78,10 @@ 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(name, ID($pos));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, ID($pos));
|
||||
set_src_attr(cell, that);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, width);
|
||||
set_src_attr(wire, that);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
|
|
@ -105,10 +105,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
|
|||
static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString 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(name, type);
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type);
|
||||
set_src_attr(cell, that);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, result_width);
|
||||
set_src_attr(wire, that);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
|
|
@ -140,10 +140,10 @@ 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(sstr.str(), ID($mux));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($mux));
|
||||
set_src_attr(cell, that);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, left.size());
|
||||
set_src_attr(wire, that);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
|
|
@ -177,14 +177,15 @@ static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
|||
to_add_kind, id.c_str(), existing_kind, location_str.c_str());
|
||||
};
|
||||
|
||||
if (const RTLIL::Wire *wire = module->wire(id))
|
||||
TwineRef id_tw = module->design->twines.lookup(id.str());
|
||||
if (const RTLIL::Wire *wire = module->wire(id_tw))
|
||||
already_exists(wire, "signal");
|
||||
if (const RTLIL::Cell *cell = module->cell(id))
|
||||
if (const RTLIL::Cell *cell = module->cell(id_tw))
|
||||
already_exists(cell, "cell");
|
||||
if (module->processes.count(id))
|
||||
already_exists(module->processes.at(id), "process");
|
||||
if (module->memories.count(id))
|
||||
already_exists(module->memories.at(id), "memory");
|
||||
if (module->processes.count(id_tw))
|
||||
already_exists(module->processes.at(id_tw), "process");
|
||||
if (module->memories.count(id_tw))
|
||||
already_exists(module->memories.at(id_tw), "memory");
|
||||
}
|
||||
|
||||
// helper class for rewriting simple lookahead references in AST always blocks
|
||||
|
|
@ -353,7 +354,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
LookaheadRewriter la_rewriter(always.get());
|
||||
|
||||
// generate process and simple root case
|
||||
proc = current_module->addProcess(stringf("$proc$%s:%d$%d", RTLIL::encode_filename(*always->location.begin.filename), always->location.begin.line, autoidx++));
|
||||
proc = current_module->addProcess(Twine{stringf("$proc$%s:%d$%d", RTLIL::encode_filename(*always->location.begin.filename), always->location.begin.line, autoidx++)});
|
||||
set_src_attr(proc, always.get());
|
||||
for (auto &attr : always->attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
|
|
@ -503,9 +504,9 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);;
|
||||
if (chunk.wire->name.str().find('$') != std::string::npos)
|
||||
wire_name += stringf("$%d", autoidx++);
|
||||
} while (current_module->wire(RTLIL::IdString(wire_name)) != nullptr);
|
||||
} while (current_module->wire(current_module->design->twines.lookup(wire_name)) != nullptr);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{wire_name}, chunk.width);
|
||||
set_src_attr(wire, always.get());
|
||||
|
||||
chunk.wire = wire;
|
||||
|
|
@ -818,7 +819,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
std::stringstream sstr;
|
||||
sstr << ast->str << "$" << ast->location.begin.filename << ":" << ast->location.begin.line << "$" << (autoidx++);
|
||||
|
||||
Wire *en = current_module->addWire(sstr.str() + "_EN", 1);
|
||||
Wire *en = current_module->addWire(Twine{sstr.str() + "_EN"}, 1);
|
||||
set_src_attr(en, ast);
|
||||
proc->root_case.actions.push_back(SigSig(en, false));
|
||||
current_case->actions.push_back(SigSig(en, true));
|
||||
|
|
@ -836,7 +837,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
}
|
||||
RTLIL::Const polarity = polarity_builder.build();
|
||||
|
||||
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($print));
|
||||
set_src_attr(cell, ast);
|
||||
cell->setParam(ID::TRG_WIDTH, triggers.size());
|
||||
cell->setParam(ID::TRG_ENABLE, (always->type == AST_INITIAL) || !triggers.empty());
|
||||
|
|
@ -882,7 +883,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
}
|
||||
|
||||
Fmt fmt;
|
||||
fmt.parse_verilog(args, /*sformat_like=*/false, default_base, /*task_name=*/ast->str, current_module->name);
|
||||
fmt.parse_verilog(args, /*sformat_like=*/false, default_base, /*task_name=*/ast->str, RTLIL::IdString(current_module->design->twines.str(current_module->meta_->name)));
|
||||
if (ast->str.substr(0, 8) == "$display")
|
||||
fmt.append_literal("\n");
|
||||
fmt.emit_rtlil(cell);
|
||||
|
|
@ -914,9 +915,9 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
|
||||
RTLIL::SigSpec check = ast->children[0]->genWidthRTLIL(-1, false, &subst_rvalue_map.stdmap());
|
||||
if (GetSize(check) != 1)
|
||||
check = current_module->ReduceBool(NEW_ID, check);
|
||||
check = current_module->ReduceBool(NEW_TWINE, check);
|
||||
|
||||
Wire *en = current_module->addWire(cellname.str() + "_EN", 1);
|
||||
Wire *en = current_module->addWire(Twine{cellname.str() + "_EN"}, 1);
|
||||
set_src_attr(en, ast);
|
||||
proc->root_case.actions.push_back(SigSig(en, false));
|
||||
current_case->actions.push_back(SigSig(en, true));
|
||||
|
|
@ -934,7 +935,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
}
|
||||
RTLIL::Const polarity = polarity_builder.build();
|
||||
|
||||
RTLIL::Cell *cell = current_module->addCell(cellname, ID($check));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, ID($check));
|
||||
set_src_attr(cell, ast);
|
||||
cell->set_bool_attribute(ID(keep));
|
||||
for (auto &attr : ast->attributes) {
|
||||
|
|
@ -982,7 +983,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
set_src_attr(&action, child.get());
|
||||
action.memid = memid;
|
||||
action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap());
|
||||
action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid]->width, true, &subst_rvalue_map.stdmap());
|
||||
action.data = child->children[1]->genWidthRTLIL(current_module->memories[current_module->design->twines.lookup(memid)]->width, true, &subst_rvalue_map.stdmap());
|
||||
action.enable = child->children[2]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap());
|
||||
RTLIL::Const orig_priority_mask = child->children[4]->bitsAsConst();
|
||||
RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx);
|
||||
|
|
@ -1475,7 +1476,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
// signals.
|
||||
RTLIL::IdString id = str;
|
||||
check_unique_id(current_module, id, this, "interface port");
|
||||
RTLIL::Wire *wire = current_module->addWire(id, 1);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, 1);
|
||||
set_src_attr(wire, this);
|
||||
wire->start_offset = 0;
|
||||
wire->port_id = port_id;
|
||||
|
|
@ -1515,7 +1516,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
RTLIL::Const val = children[0]->bitsAsConst();
|
||||
RTLIL::IdString id = str;
|
||||
check_unique_id(current_module, id, this, "pwire");
|
||||
RTLIL::Wire *wire = current_module->addWire(id, GetSize(val));
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, GetSize(val));
|
||||
current_module->connect(wire, val);
|
||||
wire->is_signed = children[0]->is_signed;
|
||||
|
||||
|
|
@ -1540,7 +1541,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
RTLIL::IdString id = str;
|
||||
check_unique_id(current_module, id, this, "signal");
|
||||
RTLIL::Wire *wire = current_module->addWire(id, range_left - range_right + 1);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, range_left - range_right + 1);
|
||||
set_src_attr(wire, this);
|
||||
wire->start_offset = range_right;
|
||||
wire->port_id = port_id;
|
||||
|
|
@ -1570,10 +1571,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
if (!children[0]->range_valid || !children[1]->range_valid)
|
||||
input_error("Memory `%s' with non-constant width or size!\n", str);
|
||||
|
||||
RTLIL::Memory *memory = new RTLIL::Memory;
|
||||
memory->module = current_module;
|
||||
check_unique_id(current_module, RTLIL::IdString(str), this, "memory");
|
||||
RTLIL::Memory *memory = current_module->addMemory(Twine{str});
|
||||
set_src_attr(memory, this);
|
||||
memory->name = str;
|
||||
memory->width = children[0]->range_left - children[0]->range_right + 1;
|
||||
if (children[1]->range_right < children[1]->range_left) {
|
||||
memory->start_offset = children[1]->range_right;
|
||||
|
|
@ -1582,8 +1582,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
memory->start_offset = children[1]->range_left;
|
||||
memory->size = children[1]->range_right - children[1]->range_left + 1;
|
||||
}
|
||||
check_unique_id(current_module, memory->name, this, "memory");
|
||||
current_module->memories[memory->name] = memory;
|
||||
|
||||
for (auto &attr : attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
|
|
@ -1629,8 +1627,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
log_assert(id2ast != nullptr);
|
||||
|
||||
if (id2ast->type == AST_AUTOWIRE && current_module->wire(RTLIL::IdString(str)) == nullptr) {
|
||||
RTLIL::Wire *wire = current_module->addWire(str);
|
||||
if (id2ast->type == AST_AUTOWIRE && current_module->wire(current_module->design->twines.lookup(str)) == nullptr) {
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{str});
|
||||
set_src_attr(wire, this);
|
||||
|
||||
// If we are currently processing a bind directive which wires up
|
||||
|
|
@ -1651,8 +1649,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
chunk = RTLIL::Const(id2ast->children[0]->bits);
|
||||
goto use_const_chunk;
|
||||
}
|
||||
else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wire(RTLIL::IdString(str)) != nullptr) {
|
||||
RTLIL::Wire *current_wire = current_module->wire(str);
|
||||
else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wire(current_module->design->twines.lookup(str)) != nullptr) {
|
||||
RTLIL::Wire *current_wire = current_module->wire(current_module->design->twines.lookup(str));
|
||||
if (current_wire->get_bool_attribute(ID::is_interface))
|
||||
is_interface = true;
|
||||
// Ignore
|
||||
|
|
@ -1673,15 +1671,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
// with the individual signals:
|
||||
if (is_interface) {
|
||||
IdString dummy_wire_name = stringf("$dummywireforinterface%s", str);
|
||||
RTLIL::Wire *dummy_wire = current_module->wire(dummy_wire_name);
|
||||
RTLIL::Wire *dummy_wire = current_module->wire(current_module->design->twines.lookup(dummy_wire_name.str()));
|
||||
if (!dummy_wire) {
|
||||
dummy_wire = current_module->addWire(dummy_wire_name);
|
||||
dummy_wire = current_module->addWire(Twine{dummy_wire_name.str()});
|
||||
dummy_wire->set_bool_attribute(ID::is_interface);
|
||||
}
|
||||
return dummy_wire;
|
||||
}
|
||||
|
||||
wire = current_module->wire(RTLIL::IdString(str));
|
||||
wire = current_module->wire(current_module->design->twines.lookup(str));
|
||||
chunk.wire = wire;
|
||||
chunk.width = wire->width;
|
||||
chunk.offset = 0;
|
||||
|
|
@ -1728,11 +1726,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(fake_ast_width, fake_ast_sign);
|
||||
|
||||
if (source_offset != 0) {
|
||||
shift_val = current_module->Sub(NEW_ID, shift_val, source_offset, fake_ast_sign);
|
||||
shift_val = current_module->Sub(NEW_TWINE, shift_val, source_offset, fake_ast_sign);
|
||||
fake_ast->children[1]->is_signed = true;
|
||||
}
|
||||
if (id2ast->range_swapped) {
|
||||
shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast_sign);
|
||||
shift_val = current_module->Sub(NEW_TWINE, RTLIL::SigSpec(source_width - width), shift_val, fake_ast_sign);
|
||||
fake_ast->children[1]->is_signed = true;
|
||||
}
|
||||
if (GetSize(shift_val) >= 32)
|
||||
|
|
@ -2045,10 +2043,10 @@ 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(sstr.str(), ID($memrd));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($memrd));
|
||||
set_src_attr(cell, this);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_DATA"}, current_module->memories[current_module->design->twines.lookup(str)]->width);
|
||||
set_src_attr(wire, this);
|
||||
|
||||
int mem_width, mem_size, addr_bits;
|
||||
|
|
@ -2085,7 +2083,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
SigSpec en_sig = children[2]->genRTLIL();
|
||||
|
||||
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($meminit_v2));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, ID($meminit_v2));
|
||||
set_src_attr(cell, this);
|
||||
|
||||
int mem_width, mem_size, addr_bits;
|
||||
|
|
@ -2099,12 +2097,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
SigSpec addr_sig = children[0]->genRTLIL();
|
||||
|
||||
cell->setPort(TW::ADDR, addr_sig);
|
||||
cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words, true));
|
||||
cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[current_module->design->twines.lookup(str)]->width * num_words, true));
|
||||
cell->setPort(TW::EN, en_sig);
|
||||
|
||||
cell->parameters[ID::MEMID] = RTLIL::Const(str);
|
||||
cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
|
||||
cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[str]->width);
|
||||
cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[current_module->design->twines.lookup(str)]->width);
|
||||
|
||||
cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
|
||||
}
|
||||
|
|
@ -2133,9 +2131,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
RTLIL::SigSpec check = children[0]->genRTLIL();
|
||||
if (GetSize(check) != 1)
|
||||
check = current_module->ReduceBool(NEW_ID, check);
|
||||
check = current_module->ReduceBool(NEW_TWINE, check);
|
||||
|
||||
RTLIL::Cell *cell = current_module->addCell(cellname, ID($check));
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, ID($check));
|
||||
set_src_attr(cell, this);
|
||||
for (auto &attr : attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
|
|
@ -2187,7 +2185,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(id, "");
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{id.str()}, "");
|
||||
set_src_attr(cell, this);
|
||||
|
||||
for (auto it = children.begin(); it != children.end(); it++) {
|
||||
|
|
@ -2234,7 +2232,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
// non-trivial signed nodes are indirected through
|
||||
// signed wires to enable sign extension
|
||||
RTLIL::IdString wire_name = NEW_ID;
|
||||
RTLIL::Wire *wire = current_module->addWire(wire_name, GetSize(sig));
|
||||
RTLIL::Wire *wire = current_module->addWire(Twine{wire_name.str()}, GetSize(sig));
|
||||
wire->is_signed = true;
|
||||
current_module->connect(wire, sig);
|
||||
sig = wire;
|
||||
|
|
@ -2243,9 +2241,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
if (child->str.size() == 0) {
|
||||
char buf[100];
|
||||
snprintf(buf, 100, "$%d", ++port_counter);
|
||||
cell->setPort(buf, sig);
|
||||
cell->setPort(current_module->design->twines.add(Twine{std::string(buf)}), sig);
|
||||
} else {
|
||||
cell->setPort(child->str, sig);
|
||||
cell->setPort(current_module->design->twines.add(Twine{child->str}), sig);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2357,7 +2355,7 @@ 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(myid, str.substr(1));
|
||||
Cell *cell = current_module->addCell(Twine{myid}, str.substr(1));
|
||||
set_src_attr(cell, this);
|
||||
cell->parameters[ID::WIDTH] = width;
|
||||
|
||||
|
|
@ -2368,7 +2366,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
cell->attributes[ID::reg] = attr->asAttrConst();
|
||||
}
|
||||
|
||||
Wire *wire = current_module->addWire(myid + "_wire", width);
|
||||
Wire *wire = current_module->addWire(Twine{myid + "_wire"}, width);
|
||||
set_src_attr(wire, this);
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_
|
|||
}
|
||||
|
||||
Fmt fmt;
|
||||
fmt.parse_verilog(args, sformat_like, default_base, /*task_name=*/str, current_module->name);
|
||||
fmt.parse_verilog(args, sformat_like, default_base, /*task_name=*/str, RTLIL::IdString(current_module->design->twines.str(current_module->meta_->name)));
|
||||
return fmt;
|
||||
}
|
||||
|
||||
|
|
@ -1481,7 +1481,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
// determine the full name of port this argument is connected to
|
||||
TwineRef port_name;
|
||||
if (child->str.size())
|
||||
port_name = child->str;
|
||||
port_name = module->design->twines.lookup(child->str);
|
||||
else {
|
||||
if (port_counter >= module->ports.size())
|
||||
input_error("Cell instance has more ports than the module!\n");
|
||||
|
|
@ -1492,7 +1492,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
const RTLIL::Wire *ref = module->wire(port_name);
|
||||
if (ref == nullptr)
|
||||
input_error("Cell instance refers to port %s which does not exist in module %s!.\n",
|
||||
port_name.unescape(), module->name.unescape());
|
||||
module->design->twines.str(port_name).c_str(), module->design->twines.str(module->meta_->name).c_str());
|
||||
|
||||
// select the argument, if present
|
||||
log_assert(child->children.size() <= 1);
|
||||
|
|
|
|||
|
|
@ -115,11 +115,12 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
}
|
||||
}
|
||||
|
||||
IdString wire_id = RTLIL::escape_id(wire_name);
|
||||
Wire *wire = module->wire(wire_id);
|
||||
std::string escaped_name = RTLIL::escape_id(wire_name);
|
||||
TwineRef wire_ref = design->twines.lookup(escaped_name);
|
||||
Wire *wire = module->wire(wire_ref);
|
||||
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(wire_id);
|
||||
wire = module->addWire(Twine{escaped_name});
|
||||
|
||||
return wire;
|
||||
};
|
||||
|
|
@ -127,7 +128,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
dict<RTLIL::IdString, RTLIL::Const> *obj_attributes = nullptr;
|
||||
dict<RTLIL::IdString, RTLIL::Const> *obj_parameters = nullptr;
|
||||
|
||||
dict<RTLIL::IdString, std::pair<int, bool>> wideports_cache;
|
||||
dict<TwineRef, std::pair<int, bool>> wideports_cache;
|
||||
|
||||
size_t buffer_size = 4096;
|
||||
char *buffer = (char*)malloc(buffer_size);
|
||||
|
|
@ -172,11 +173,12 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
char *name = strtok(NULL, " \t\r\n");
|
||||
if (name == nullptr)
|
||||
goto error;
|
||||
module->name = RTLIL::escape_id(name);
|
||||
std::string escaped_name = RTLIL::escape_id(name);
|
||||
module->meta_->name = design->twines.add(Twine{escaped_name});
|
||||
obj_attributes = &module->attributes;
|
||||
obj_parameters = nullptr;
|
||||
if (design->module(module->name))
|
||||
log_error("Duplicate definition of module %s in line %d!\n", module->name.unescape(), line_count);
|
||||
if (design->module(design->twines.lookup(escaped_name)))
|
||||
log_error("Duplicate definition of module %s in line %d!\n", escaped_name.c_str(), line_count);
|
||||
design->add(module);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -198,13 +200,14 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
int width = wp.second.first;
|
||||
bool isinput = wp.second.second;
|
||||
|
||||
RTLIL::Wire *wire = module->addWire(name, width);
|
||||
RTLIL::Wire *wire = module->addWire(Twine{design->twines.str(name)}, width);
|
||||
wire->port_input = isinput;
|
||||
wire->port_output = !isinput;
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
|
||||
RTLIL::Wire *other_wire = module->wire(other_name);
|
||||
std::string other_name = design->twines.str(name) + stringf("[%d]", i);
|
||||
TwineRef other_ref = design->twines.lookup(other_name);
|
||||
RTLIL::Wire *other_wire = module->wire(other_ref);
|
||||
if (other_wire) {
|
||||
other_wire->port_input = false;
|
||||
other_wire->port_output = false;
|
||||
|
|
@ -233,18 +236,18 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
for (auto cell : remove_cells)
|
||||
module->remove(cell);
|
||||
|
||||
Wire *true_wire = module->wire(ID($true));
|
||||
Wire *false_wire = module->wire(ID($false));
|
||||
Wire *undef_wire = module->wire(ID($undef));
|
||||
Wire *true_wire = module->wire(design->twines.lookup("$true"));
|
||||
Wire *false_wire = module->wire(design->twines.lookup("$false"));
|
||||
Wire *undef_wire = module->wire(design->twines.lookup("$undef"));
|
||||
|
||||
if (true_wire != nullptr)
|
||||
module->rename(true_wire, stringf("$true$%d", ++blif_maxnum));
|
||||
module->rename(true_wire, design->twines.add(Twine{stringf("$true$%d", ++blif_maxnum)}));
|
||||
|
||||
if (false_wire != nullptr)
|
||||
module->rename(false_wire, stringf("$false$%d", ++blif_maxnum));
|
||||
module->rename(false_wire, design->twines.add(Twine{stringf("$false$%d", ++blif_maxnum)}));
|
||||
|
||||
if (undef_wire != nullptr)
|
||||
module->rename(undef_wire, stringf("$undef$%d", ++blif_maxnum));
|
||||
module->rename(undef_wire, design->twines.add(Twine{stringf("$undef$%d", ++blif_maxnum)}));
|
||||
|
||||
autoidx.ensure_at_least(blif_maxnum+1);
|
||||
blif_maxnum = 0;
|
||||
|
|
@ -272,10 +275,11 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
char *p;
|
||||
while ((p = strtok(NULL, " \t\r\n")) != NULL)
|
||||
{
|
||||
RTLIL::IdString wire_name(stringf("\\%s", p));
|
||||
RTLIL::Wire *wire = module->wire(wire_name);
|
||||
std::string wire_name_str = stringf("\\%s", p);
|
||||
TwineRef wire_ref = design->twines.lookup(wire_name_str);
|
||||
RTLIL::Wire *wire = module->wire(wire_ref);
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(wire_name);
|
||||
wire = module->addWire(Twine{wire_name_str});
|
||||
if (!strcmp(cmd, ".inputs"))
|
||||
wire->port_input = true;
|
||||
else
|
||||
|
|
@ -284,8 +288,9 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
if (wideports) {
|
||||
std::pair<RTLIL::IdString, int> wp = wideports_split(p);
|
||||
if (!wp.first.empty() && wp.second >= 0) {
|
||||
wideports_cache[wp.first].first = std::max(wideports_cache[wp.first].first, wp.second + 1);
|
||||
wideports_cache[wp.first].second = !strcmp(cmd, ".inputs");
|
||||
TwineRef wp_ref = design->twines.lookup(wp.first.str());
|
||||
wideports_cache[wp_ref].first = std::max(wideports_cache[wp_ref].first, wp.second + 1);
|
||||
wideports_cache[wp_ref].second = !strcmp(cmd, ".inputs");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,7 +311,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
goto error_with_reason;
|
||||
}
|
||||
|
||||
module->rename(lastcell, RTLIL::escape_id(p));
|
||||
module->rename(lastcell, design->twines.add(Twine{RTLIL::escape_id(p)}));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -364,17 +369,17 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
goto no_latch_clock;
|
||||
|
||||
if (!strcmp(edge, "re"))
|
||||
cell = module->addDffGate(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q));
|
||||
cell = module->addDffGate(NEW_TWINE, blif_wire(clock), blif_wire(d), blif_wire(q));
|
||||
else if (!strcmp(edge, "fe"))
|
||||
cell = module->addDffGate(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q), false);
|
||||
cell = module->addDffGate(NEW_TWINE, blif_wire(clock), blif_wire(d), blif_wire(q), false);
|
||||
else if (!strcmp(edge, "ah"))
|
||||
cell = module->addDlatchGate(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q));
|
||||
cell = module->addDlatchGate(NEW_TWINE, blif_wire(clock), blif_wire(d), blif_wire(q));
|
||||
else if (!strcmp(edge, "al"))
|
||||
cell = module->addDlatchGate(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q), false);
|
||||
cell = module->addDlatchGate(NEW_TWINE, blif_wire(clock), blif_wire(d), blif_wire(q), false);
|
||||
else {
|
||||
no_latch_clock:
|
||||
if (dff_name.empty()) {
|
||||
cell = module->addFfGate(NEW_ID, blif_wire(d), blif_wire(q));
|
||||
cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q));
|
||||
} else {
|
||||
cell = module->addCell(NEW_TWINE, dff_name);
|
||||
cell->setPort(TW::D, blif_wire(d));
|
||||
|
|
@ -398,7 +403,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
RTLIL::Cell *cell = module->addCell(NEW_TWINE, celltype);
|
||||
RTLIL::Module *cell_mod = design->module(celltype);
|
||||
|
||||
dict<RTLIL::IdString, dict<int, SigBit>> cell_wideports_cache;
|
||||
dict<TwineRef, dict<int, SigBit>> cell_wideports_cache;
|
||||
|
||||
while ((p = strtok(NULL, " \t\r\n")) != NULL)
|
||||
{
|
||||
|
|
@ -409,12 +414,18 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
|
||||
if (wideports) {
|
||||
std::pair<RTLIL::IdString, int> wp = wideports_split(p);
|
||||
if (wp.first.empty())
|
||||
cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec());
|
||||
else
|
||||
cell_wideports_cache[wp.first][wp.second] = blif_wire(q);
|
||||
if (wp.first.empty()) {
|
||||
std::string port_name_str = RTLIL::escape_id(p);
|
||||
TwineRef port_ref = design->twines.lookup(port_name_str);
|
||||
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
|
||||
} else {
|
||||
TwineRef wp_ref = design->twines.lookup(wp.first.str());
|
||||
cell_wideports_cache[wp_ref][wp.second] = blif_wire(q);
|
||||
}
|
||||
} else {
|
||||
cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec());
|
||||
std::string port_name_str = RTLIL::escape_id(p);
|
||||
TwineRef port_ref = design->twines.lookup(port_name_str);
|
||||
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -609,7 +620,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
if (!sopmode) {
|
||||
SigSpec outnet = sopcell->getPort(TW::Y);
|
||||
SigSpec tempnet = module->addWire(NEW_TWINE);
|
||||
module->addNotGate(NEW_ID, tempnet, outnet);
|
||||
module->addNotGate(NEW_TWINE, tempnet, outnet);
|
||||
sopcell->setPort(TW::Y, tempnet);
|
||||
}
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ void json_parse_attributes(RTLIL::Design *design, RTLIL::AttrObject *obj, JsonNo
|
|||
IdString key = RTLIL::escape_id(it.first.c_str());
|
||||
Const value = json_parse_attr_param_value(it.second);
|
||||
if (key == ID::src && (value.flags & RTLIL::CONST_FLAG_STRING))
|
||||
design->set_src_attribute(obj, value.decode_string());
|
||||
design->set_src_attribute(obj, design->twines.add(Twine{value.decode_string()}));
|
||||
else
|
||||
obj->attributes[key] = value;
|
||||
}
|
||||
|
|
@ -312,10 +312,10 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
|
||||
Module *module = new RTLIL::Module;
|
||||
module->design = design;
|
||||
module->name = RTLIL::escape_id(modname.c_str());
|
||||
module->meta_->name = design->twines.add(Twine{RTLIL::escape_id(modname)});
|
||||
|
||||
if (design->module(module->name))
|
||||
log_error("Re-definition of module %s.\n", module->name.unescape());
|
||||
if (design->module(module->meta_->name))
|
||||
log_error("Re-definition of module %s.\n", design->twines.str(module->meta_->name));
|
||||
|
||||
design->add(module);
|
||||
|
||||
|
|
@ -357,10 +357,10 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
if (port_bits_node->type != 'A')
|
||||
log_error("JSON port node '%s' has non-array bits attribute.\n", port_name.unescape());
|
||||
|
||||
Wire *port_wire = module->wire(port_name);
|
||||
Wire *port_wire = module->wire(design->twines.lookup(port_name.str()));
|
||||
|
||||
if (port_wire == nullptr)
|
||||
port_wire = module->addWire(port_name, GetSize(port_bits_node->data_array));
|
||||
port_wire = module->addWire(Twine{port_name.str()}, GetSize(port_bits_node->data_array));
|
||||
|
||||
if (port_node->data_dict.count("upto") != 0) {
|
||||
JsonNode *val = port_node->data_dict.at("upto");
|
||||
|
|
@ -455,10 +455,10 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
if (bits_node->type != 'A')
|
||||
log_error("JSON netname node '%s' has non-array bits attribute.\n", net_name.unescape());
|
||||
|
||||
Wire *wire = module->wire(net_name);
|
||||
Wire *wire = module->wire(design->twines.lookup(net_name.str()));
|
||||
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(net_name, GetSize(bits_node->data_array));
|
||||
wire = module->addWire(Twine{net_name.str()}, GetSize(bits_node->data_array));
|
||||
|
||||
if (net_node->data_dict.count("upto") != 0) {
|
||||
JsonNode *val = net_node->data_dict.at("upto");
|
||||
|
|
@ -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(cell_name, cell_type);
|
||||
Cell *cell = module->addCell(Twine{cell_name.str()}, cell_type);
|
||||
|
||||
if (cell_node->data_dict.count("connections") == 0)
|
||||
log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape());
|
||||
|
|
@ -580,7 +580,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
|
||||
}
|
||||
|
||||
cell->setPort(conn_name, sig);
|
||||
cell->setPort(design->twines.add(Twine{conn_name.str()}), sig);
|
||||
}
|
||||
|
||||
if (cell_node->data_dict.count("attributes"))
|
||||
|
|
@ -604,7 +604,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
JsonNode *memory_node = memory_node_it.second;
|
||||
|
||||
RTLIL::Memory *mem = new RTLIL::Memory;
|
||||
mem->name = memory_name;
|
||||
mem->meta_->name = design->twines.add(Twine{memory_name.str()});
|
||||
mem->module = module;
|
||||
|
||||
if (memory_node->type != 'D')
|
||||
|
|
@ -634,7 +634,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
|||
if (memory_node->data_dict.count("attributes"))
|
||||
json_parse_attributes(design, mem, memory_node->data_dict.at("attributes"));
|
||||
|
||||
module->memories[mem->name] = mem;
|
||||
module->memories[mem->meta_->name] = mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
|
|||
return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1;
|
||||
|
||||
std::string id = RTLIL::escape_id(std::string(expr, id_len));
|
||||
RTLIL::Wire *w = module->wire(RTLIL::IdString(id));
|
||||
TwineRef wire_ref = module->design->twines.lookup(id);
|
||||
RTLIL::Wire *w = module->wire(wire_ref);
|
||||
if (!w)
|
||||
log_error("Can't resolve wire name %s in %s.\n", RTLIL::unescape_id(id), module);
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
int top = int(stack.size())-1;
|
||||
|
||||
if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') {
|
||||
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top].sig));
|
||||
token_t t = token_t(0, module->NotGate(NEW_TWINE, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -68,7 +69,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) {
|
||||
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top-1].sig));
|
||||
token_t t = token_t(0, module->NotGate(NEW_TWINE, stack[top-1].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -83,7 +84,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) {
|
||||
token_t t = token_t(1, module->XorGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(1, module->XorGate(NEW_TWINE, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -99,7 +100,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) {
|
||||
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-1].sig, stack[top].sig));
|
||||
token_t t = token_t(2, module->AndGate(NEW_TWINE, stack[top-1].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -107,7 +108,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) {
|
||||
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(2, module->AndGate(NEW_TWINE, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -123,7 +124,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) {
|
||||
token_t t = token_t(3, module->OrGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(3, module->OrGate(NEW_TWINE, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -188,21 +189,23 @@ static RTLIL::SigSpec create_tristate(RTLIL::Module *module, RTLIL::SigSpec func
|
|||
RTLIL::Cell *cell = module->addCell(NEW_TWINE, ID($tribuf));
|
||||
cell->setParam(ID::WIDTH, GetSize(func));
|
||||
cell->setPort(TW::A, func);
|
||||
cell->setPort(TW::EN, module->NotGate(NEW_ID, three_state));
|
||||
cell->setPort(TW::EN, module->NotGate(NEW_TWINE, three_state));
|
||||
cell->setPort(TW::Y, module->addWire(NEW_TWINE));
|
||||
return cell->getPort(TW::Y);
|
||||
}
|
||||
|
||||
static void create_latch_ff_wires(RTLIL::Module *module, const LibertyAst *node)
|
||||
{
|
||||
module->addWire(RTLIL::escape_id(node->args.at(0)));
|
||||
module->addWire(RTLIL::escape_id(node->args.at(1)));
|
||||
module->addWire(Twine{RTLIL::escape_id(node->args.at(0))});
|
||||
module->addWire(Twine{RTLIL::escape_id(node->args.at(1))});
|
||||
}
|
||||
|
||||
static std::pair<RTLIL::SigSpec, RTLIL::SigSpec> find_latch_ff_wires(RTLIL::Module *module, const LibertyAst *node)
|
||||
{
|
||||
auto* iq_wire = module->wire(RTLIL::escape_id(node->args.at(0)));
|
||||
auto* iqn_wire = module->wire(RTLIL::escape_id(node->args.at(1)));
|
||||
TwineRef iq_ref = module->design->twines.lookup(RTLIL::escape_id(node->args.at(0)));
|
||||
TwineRef iqn_ref = module->design->twines.lookup(RTLIL::escape_id(node->args.at(1)));
|
||||
auto* iq_wire = module->wire(iq_ref);
|
||||
auto* iqn_wire = module->wire(iqn_ref);
|
||||
log_assert(iq_wire && iqn_wire);
|
||||
return std::make_pair(iq_wire, iqn_wire);
|
||||
}
|
||||
|
|
@ -212,7 +215,7 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
|||
auto [iq_sig, iqn_sig] = find_latch_ff_wires(module, node);
|
||||
RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig;
|
||||
bool clk_polarity = true, clear_polarity = true, preset_polarity = true;
|
||||
const std::string name = module->name.unescape();
|
||||
const std::string name = module->design->twines.str(module->meta_->name);
|
||||
|
||||
std::optional<char> clear_preset_var1;
|
||||
std::optional<char> clear_preset_var2;
|
||||
|
|
@ -265,7 +268,7 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
|||
SigSpec q_sig = out_sig;
|
||||
if (neg) {
|
||||
q_sig = module->addWire(NEW_TWINE, out_sig.as_wire());
|
||||
module->addNotGate(NEW_ID, q_sig, out_sig);
|
||||
module->addNotGate(NEW_TWINE, q_sig, out_sig);
|
||||
}
|
||||
|
||||
RTLIL::Cell* cell = module->addCell(NEW_TWINE, "");
|
||||
|
|
@ -305,9 +308,9 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
|||
log_debug("cell %s variable %d cp_var %c set dominates? %d\n", name, (int)neg + 1, *cp_var, set_dominates);
|
||||
// S&R priority is well-defined now
|
||||
if (set_dominates) {
|
||||
r_sig = module->AndnotGate(NEW_ID, r_sig, s_sig);
|
||||
r_sig = module->AndnotGate(NEW_TWINE, r_sig, s_sig);
|
||||
} else {
|
||||
s_sig = module->AndnotGate(NEW_ID, s_sig, r_sig);
|
||||
s_sig = module->AndnotGate(NEW_TWINE, s_sig, r_sig);
|
||||
}
|
||||
} else {
|
||||
log_debug("cell %s variable %d undef c&p behavior\n", name, (int)neg + 1);
|
||||
|
|
@ -609,7 +612,8 @@ struct LibertyFrontend : public Frontend {
|
|||
RTLIL::Module *module = new RTLIL::Module;
|
||||
module->design = design;
|
||||
std::string cell_name = RTLIL::escape_id(cell->args.at(0));
|
||||
module->name = cell_name;
|
||||
TwineRef cell_name_ref = design->twines.lookup(cell_name);
|
||||
module->meta_->name = design->twines.add(Twine{cell_name});
|
||||
|
||||
if (flag_lib)
|
||||
module->set_bool_attribute(ID::blackbox);
|
||||
|
|
@ -642,7 +646,7 @@ struct LibertyFrontend : public Frontend {
|
|||
}
|
||||
}
|
||||
if (!flag_lib || dir->value != "internal")
|
||||
module->addWire(RTLIL::escape_id(node->args.at(0)));
|
||||
module->addWire(Twine{RTLIL::escape_id(node->args.at(0))});
|
||||
}
|
||||
|
||||
if (node->id == "bus" && node->args.size() == 1)
|
||||
|
|
@ -682,7 +686,7 @@ struct LibertyFrontend : public Frontend {
|
|||
int bus_type_offset = std::get<1>(type_map.at(bus_type_node->value));
|
||||
bool bus_type_upto = std::get<2>(type_map.at(bus_type_node->value));
|
||||
|
||||
Wire *wire = module->addWire(RTLIL::escape_id(node->args.at(0)), bus_type_width);
|
||||
Wire *wire = module->addWire(Twine{RTLIL::escape_id(node->args.at(0))}, bus_type_width);
|
||||
wire->start_offset = bus_type_offset;
|
||||
wire->upto = bus_type_upto;
|
||||
|
||||
|
|
@ -729,7 +733,8 @@ struct LibertyFrontend : public Frontend {
|
|||
if (flag_lib && dir->value == "internal")
|
||||
continue;
|
||||
|
||||
RTLIL::Wire *wire = module->wire(RTLIL::IdString(RTLIL::escape_id(node->args.at(0))));
|
||||
TwineRef wire_ref = module->design->twines.lookup(RTLIL::escape_id(node->args.at(0)));
|
||||
RTLIL::Wire *wire = module->wire(wire_ref);
|
||||
log_assert(wire);
|
||||
|
||||
const LibertyAst *capacitance = node->find("capacitance");
|
||||
|
|
@ -813,8 +818,8 @@ struct LibertyFrontend : public Frontend {
|
|||
}
|
||||
}
|
||||
|
||||
if (design->has(cell_name)) {
|
||||
Module *existing_mod = design->module(cell_name);
|
||||
if (design->has(cell_name_ref)) {
|
||||
Module *existing_mod = design->module(cell_name_ref);
|
||||
if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
|
||||
log_error("Re-definition of cell/module %s!\n", RTLIL::unescape_id(cell_name));
|
||||
} else if (flag_nooverwrite) {
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ 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 {
|
||||
std::string stripped_name = name.str();
|
||||
std::string stripped_name = design->twines.str(meta_->name);
|
||||
if (stripped_name.compare(0, 9, "$abstract") == 0)
|
||||
stripped_name = stripped_name.substr(9);
|
||||
log_assert(stripped_name[0] == '\\');
|
||||
|
|
@ -179,7 +179,7 @@ struct RpcModule : RTLIL::Module {
|
|||
else
|
||||
derived_name = "$paramod" + stripped_name + parameter_info;
|
||||
|
||||
if (design->has(derived_name)) {
|
||||
if (design->has(design->twines.lookup(derived_name))) {
|
||||
log("Found cached RTLIL representation for module `%s'.\n", derived_name);
|
||||
} else {
|
||||
std::string command, input;
|
||||
|
|
@ -193,12 +193,12 @@ struct RpcModule : RTLIL::Module {
|
|||
dict<std::string, std::string> name_mangling;
|
||||
bool found_derived_top = false;
|
||||
for (auto module : derived_design->modules()) {
|
||||
std::string original_name = module->name.str();
|
||||
std::string original_name = derived_design->twines.str(module->meta_->name);
|
||||
if (original_name == stripped_name) {
|
||||
found_derived_top = true;
|
||||
name_mangling[original_name] = derived_name;
|
||||
} else {
|
||||
name_mangling[original_name] = derived_name + module->name.str();
|
||||
name_mangling[original_name] = derived_name + derived_design->twines.str(module->meta_->name);
|
||||
}
|
||||
}
|
||||
if (!found_derived_top)
|
||||
|
|
@ -210,11 +210,11 @@ struct RpcModule : RTLIL::Module {
|
|||
cell->type = name_mangling[cell->type.str()];
|
||||
|
||||
for (auto module : derived_design->modules_) {
|
||||
std::string mangled_name = name_mangling[module.first.str()];
|
||||
std::string mangled_name = name_mangling[derived_design->twines.str(module.first)];
|
||||
|
||||
log("Importing `%s' as `%s'.\n", module.first.unescape(), mangled_name);
|
||||
log("Importing `%s' as `%s'.\n", derived_design->twines.str(module.first), mangled_name);
|
||||
|
||||
RTLIL::IdString original_name = module.first;
|
||||
RTLIL::IdString original_name = RTLIL::IdString(derived_design->twines.str(module.first));
|
||||
RTLIL::Module *t = module.second->clone(design, RTLIL::IdString(mangled_name));
|
||||
t->attributes.erase(ID::top);
|
||||
if (!t->has_attribute(ID::hdlname))
|
||||
|
|
@ -587,7 +587,7 @@ cleanup_path:
|
|||
log("Linking module `%s'.\n", module_name);
|
||||
RpcModule *module = new RpcModule;
|
||||
module->design = design;
|
||||
module->name = "$abstract\\" + module_name;
|
||||
module->meta_->name = design->twines.add(Twine{"$abstract\\" + module_name});
|
||||
module->server = server;
|
||||
design->add(module);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ struct RTLILFrontendWorker {
|
|||
// We don't need to addref/release in this case.
|
||||
std::optional<RTLIL::IdString> id = try_parse_id();
|
||||
if (id.has_value()) {
|
||||
RTLIL::Wire *wire = current_module->wire(*id);
|
||||
RTLIL::Wire *wire = current_module->wire(design->twines.lookup(id->str()));
|
||||
if (wire == nullptr) {
|
||||
if (flag_legalize)
|
||||
wire = legalize_wire(*id);
|
||||
|
|
@ -515,17 +515,7 @@ struct RTLILFrontendWorker {
|
|||
// is wrong and silently interning it would hide that.
|
||||
if (id == RTLIL::ID::src && (c.flags & RTLIL::CONST_FLAG_STRING)) {
|
||||
std::string raw = c.decode_string();
|
||||
// TODO error handling
|
||||
auto file_id = design->twines.parse_ref(raw);
|
||||
if (file_id) {
|
||||
// Translate the file-local twine id to the destination
|
||||
// design's pool id via twine_remap. If the file had no
|
||||
// `twines` block (legacy) the remap is empty — accept the
|
||||
// ref verbatim and let downstream code intern it.
|
||||
auto it = twine_remap.find(*file_id);
|
||||
if (it != twine_remap.end())
|
||||
c = RTLIL::Const(design->twines.format_ref(it->second));
|
||||
} else if (raw.find('|') != std::string::npos) {
|
||||
if (raw.find('|') != std::string::npos) {
|
||||
log_warning("line %d: src attribute %s contains '|' separators. "
|
||||
"That convention is Yosys-internal; the producing tool "
|
||||
"should emit a single path:line.col per attribute and "
|
||||
|
|
@ -541,12 +531,10 @@ struct RTLILFrontendWorker {
|
|||
// cell/wire src "@N" references (which use file-local ids) translate
|
||||
// to ids in design->twines. The destination pool may already be
|
||||
// non-empty (multi-file load) — interned/concated nodes are dedup'd
|
||||
// against the existing pool by the pool itself. Each parser-side
|
||||
// retain is tracked in twine_parser_holds and released at end-of-parse
|
||||
// so only cell/wire references survive.
|
||||
// against the existing pool by the pool itself.
|
||||
void parse_twines()
|
||||
{
|
||||
TwinePoolExtender extender(design->twines, design->twines.size());
|
||||
dict<size_t, Twine> file_twines;
|
||||
expect_eol();
|
||||
while (true) {
|
||||
if (try_parse_keyword("end"))
|
||||
|
|
@ -555,7 +543,7 @@ struct RTLILFrontendWorker {
|
|||
size_t file_id = parse_integer();
|
||||
std::string text = parse_string();
|
||||
expect_eol();
|
||||
extender.extend_leaf(text, file_id);
|
||||
file_twines[file_id] = Twine{text};
|
||||
continue;
|
||||
}
|
||||
if (try_parse_keyword("suffix")) {
|
||||
|
|
@ -563,23 +551,30 @@ struct RTLILFrontendWorker {
|
|||
size_t file_parent = parse_integer();
|
||||
std::string tail = parse_string();
|
||||
expect_eol();
|
||||
extender.extend_suffix(file_parent, tail, file_id);
|
||||
if (twine_remap.count(file_parent) == 0)
|
||||
error("Unknown parent twine @%zu for suffix at line %d", file_parent, line_num);
|
||||
file_twines[file_id] = Twine{Twine::Suffix{twine_remap[file_parent], tail}};
|
||||
continue;
|
||||
}
|
||||
if (try_parse_keyword("concat")) {
|
||||
size_t file_id = parse_integer();
|
||||
std::vector<size_t> children;
|
||||
std::vector<TwineRef> children;
|
||||
while (!try_parse_eol()) {
|
||||
children.push_back(parse_integer());
|
||||
size_t child_id = parse_integer();
|
||||
if (twine_remap.count(child_id) == 0)
|
||||
error("Unknown child twine @%zu for concat at line %d", child_id, line_num);
|
||||
children.push_back(twine_remap[child_id]);
|
||||
}
|
||||
extender.extend_concat(children, file_id);
|
||||
file_twines[file_id] = Twine{children};
|
||||
continue;
|
||||
}
|
||||
error("Expected `leaf`, `suffix` or `concat` inside twines block, got `%s'.",
|
||||
error_token());
|
||||
}
|
||||
expect_eol();
|
||||
extender.finish();
|
||||
for (auto &p : file_twines) {
|
||||
twine_remap[p.first] = design->twines.add(std::move(p.second));
|
||||
}
|
||||
}
|
||||
|
||||
// Release the per-file parser refs gathered during parse_twines. Call
|
||||
|
|
@ -587,8 +582,6 @@ struct RTLILFrontendWorker {
|
|||
// referred to a file_id has already adopted the corresponding local_id.
|
||||
void release_twine_parser_holds()
|
||||
{
|
||||
for (TwineRef id : twine_parser_holds)
|
||||
design->twines.release(id);
|
||||
twine_parser_holds.clear();
|
||||
twine_remap.clear();
|
||||
}
|
||||
|
|
@ -619,15 +612,18 @@ struct RTLILFrontendWorker {
|
|||
{
|
||||
std::optional<RTLIL::IdString> id = try_parse_id();
|
||||
if (id.has_value()) {
|
||||
if (current_module->wire(*id) != nullptr) {
|
||||
TwineRef wire_name = design->twines.lookup(id->str());
|
||||
if (wire_name == Twine::Null)
|
||||
wire_name = design->twines.add(Twine{id->str()});
|
||||
if (current_module->wire(wire_name) != nullptr) {
|
||||
if (flag_legalize) {
|
||||
log("Legalizing redefinition of wire %s.\n", *id);
|
||||
pool<RTLIL::Wire*> wires = {current_module->wire(*id)};
|
||||
pool<RTLIL::Wire*> wires = {current_module->wire(wire_name)};
|
||||
current_module->remove(wires);
|
||||
} else
|
||||
error("RTLIL error: redefinition of wire %s.", *id);
|
||||
}
|
||||
wire = current_module->addWire(std::move(*id));
|
||||
wire = current_module->addWire(Twine{id->str()});
|
||||
break;
|
||||
}
|
||||
if (try_parse_keyword("width"))
|
||||
|
|
@ -674,18 +670,22 @@ struct RTLILFrontendWorker {
|
|||
int width = 1;
|
||||
int start_offset = 0;
|
||||
int size = 0;
|
||||
TwineRef mem_name = Twine::Null;
|
||||
while (true)
|
||||
{
|
||||
std::optional<RTLIL::IdString> id = try_parse_id();
|
||||
if (id.has_value()) {
|
||||
if (current_module->memories.count(*id) != 0) {
|
||||
mem_name = design->twines.lookup(id->str());
|
||||
if (mem_name == Twine::Null)
|
||||
mem_name = design->twines.add(Twine{id->str()});
|
||||
if (current_module->memories.count(mem_name) != 0) {
|
||||
if (flag_legalize) {
|
||||
log("Legalizing redefinition of memory %s.\n", *id);
|
||||
current_module->remove(current_module->memories.at(*id));
|
||||
current_module->remove(current_module->memories.at(mem_name));
|
||||
} else
|
||||
error("RTLIL error: redefinition of memory %s.", *id);
|
||||
}
|
||||
memory->name = std::move(*id);
|
||||
memory->meta_->name = mem_name;
|
||||
break;
|
||||
}
|
||||
if (try_parse_keyword("width"))
|
||||
|
|
@ -702,41 +702,53 @@ struct RTLILFrontendWorker {
|
|||
memory->width = width;
|
||||
memory->start_offset = start_offset;
|
||||
memory->size = size;
|
||||
current_module->memories.insert({memory->name, memory});
|
||||
current_module->memories.insert({mem_name, memory});
|
||||
expect_eol();
|
||||
}
|
||||
|
||||
void legalize_width_parameter(RTLIL::Cell *cell, TwineRef port_name)
|
||||
{
|
||||
std::string width_param_name = port_name.str() + "_WIDTH";
|
||||
if (cell->parameters.count(width_param_name) == 0)
|
||||
std::string width_param_name = design->twines.str(port_name) + "_WIDTH";
|
||||
if (cell->parameters.count(RTLIL::IdString(width_param_name)) == 0)
|
||||
return;
|
||||
RTLIL::Const ¶m = cell->parameters.at(width_param_name);
|
||||
RTLIL::Const ¶m = cell->parameters.at(RTLIL::IdString(width_param_name));
|
||||
if (param.as_int() != 0)
|
||||
return;
|
||||
cell->parameters[width_param_name] = RTLIL::Const(cell->getPort(port_name).size());
|
||||
cell->parameters[RTLIL::IdString(width_param_name)] = RTLIL::Const(cell->getPort(port_name).size());
|
||||
}
|
||||
|
||||
void parse_cell()
|
||||
{
|
||||
RTLIL::IdString cell_type = parse_id();
|
||||
RTLIL::IdString cell_name = parse_id();
|
||||
std::string cell_name_str = parse_id();
|
||||
expect_eol();
|
||||
|
||||
if (current_module->cell(cell_name) != nullptr) {
|
||||
TwineRef cell_name_ref = design->twines.lookup(cell_name_str);
|
||||
if (cell_name_ref == Twine::Null)
|
||||
cell_name_ref = design->twines.add(Twine{cell_name_str});
|
||||
|
||||
if (current_module->cell(cell_name_ref) != nullptr) {
|
||||
if (flag_legalize) {
|
||||
RTLIL::IdString new_name;
|
||||
std::string new_name_str;
|
||||
int suffix = 1;
|
||||
do {
|
||||
new_name = RTLIL::IdString(cell_name.str() + "_" + std::to_string(suffix));
|
||||
new_name_str = cell_name_str + "_" + std::to_string(suffix);
|
||||
TwineRef test_ref = design->twines.lookup(new_name_str);
|
||||
if (test_ref == Twine::Null)
|
||||
test_ref = design->twines.add(Twine{new_name_str});
|
||||
++suffix;
|
||||
} while (current_module->cell(new_name) != nullptr);
|
||||
log("Legalizing redefinition of cell %s by renaming to %s.\n", cell_name, new_name);
|
||||
cell_name = new_name;
|
||||
if (current_module->cell(test_ref) == nullptr)
|
||||
break;
|
||||
} while (true);
|
||||
log("Legalizing redefinition of cell %s by renaming to %s.\n", cell_name_str, new_name_str);
|
||||
cell_name_str = new_name_str;
|
||||
cell_name_ref = design->twines.lookup(cell_name_str);
|
||||
if (cell_name_ref == Twine::Null)
|
||||
cell_name_ref = design->twines.add(Twine{cell_name_str});
|
||||
} else
|
||||
error("RTLIL error: redefinition of cell %s.", cell_name);
|
||||
error("RTLIL error: redefinition of cell %s.", cell_name_str);
|
||||
}
|
||||
RTLIL::Cell *cell = current_module->addCell(cell_name, cell_type);
|
||||
RTLIL::Cell *cell = current_module->addCell(Twine{cell_name_str}, cell_type);
|
||||
cell->absorb_attrs(std::move(attrbuf));
|
||||
|
||||
while (true)
|
||||
|
|
@ -763,14 +775,17 @@ struct RTLILFrontendWorker {
|
|||
cell->parameters.insert({std::move(param_name), std::move(val)});
|
||||
expect_eol();
|
||||
} else if (try_parse_keyword("connect")) {
|
||||
TwineRef port_name = parse_id();
|
||||
std::string port_name_str = parse_id();
|
||||
TwineRef port_name = design->twines.lookup(port_name_str);
|
||||
if (port_name == Twine::Null)
|
||||
port_name = design->twines.add(Twine{port_name_str});
|
||||
if (cell->hasPort(port_name)) {
|
||||
if (flag_legalize)
|
||||
log("Legalizing redefinition of cell port %s.", port_name);
|
||||
log("Legalizing redefinition of cell port %s.", port_name_str);
|
||||
else
|
||||
error("RTLIL error: redefinition of cell port %s.", port_name);
|
||||
error("RTLIL error: redefinition of cell port %s.", port_name_str);
|
||||
}
|
||||
cell->setPort(std::move(port_name), parse_sigspec());
|
||||
cell->setPort(port_name, parse_sigspec());
|
||||
if (flag_legalize)
|
||||
legalize_width_parameter(cell, port_name);
|
||||
expect_eol();
|
||||
|
|
@ -869,17 +884,21 @@ struct RTLILFrontendWorker {
|
|||
|
||||
void parse_process()
|
||||
{
|
||||
RTLIL::IdString proc_name = parse_id();
|
||||
std::string proc_name_str = parse_id();
|
||||
expect_eol();
|
||||
|
||||
TwineRef proc_name = design->twines.lookup(proc_name_str);
|
||||
if (proc_name == Twine::Null)
|
||||
proc_name = design->twines.add(Twine{proc_name_str});
|
||||
|
||||
if (current_module->processes.count(proc_name) != 0) {
|
||||
if (flag_legalize) {
|
||||
log("Legalizing redefinition of process %s.\n", proc_name);
|
||||
log("Legalizing redefinition of process %s.\n", proc_name_str);
|
||||
current_module->remove(current_module->processes.at(proc_name));
|
||||
} else
|
||||
error("RTLIL error: redefinition of process %s.", proc_name);
|
||||
error("RTLIL error: redefinition of process %s.", proc_name_str);
|
||||
}
|
||||
RTLIL::Process *proc = current_module->addProcess(std::move(proc_name));
|
||||
RTLIL::Process *proc = current_module->addProcess(Twine{proc_name_str});
|
||||
proc->absorb_attrs(std::move(attrbuf));
|
||||
|
||||
switch_stack.clear();
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ struct AigMaker
|
|||
int inport(TwineRef portname, int portbit = 0, bool inverter = false)
|
||||
{
|
||||
if (portbit >= GetSize(cell->getPort(portname))) {
|
||||
if (cell->parameters.count(portname.str() + "_SIGNED") && cell->getParam(portname.str() + "_SIGNED").as_bool())
|
||||
if (cell->parameters.count(cell->module->design->twines.str(portname) + "_SIGNED") && cell->getParam(cell->module->design->twines.str(portname) + "_SIGNED").as_bool())
|
||||
return inport(portname, GetSize(cell->getPort(portname))-1, inverter);
|
||||
return bool_node(inverter);
|
||||
}
|
||||
|
|
@ -247,7 +247,7 @@ struct AigMaker
|
|||
void outport(int node, TwineRef portname, int portbit = 0)
|
||||
{
|
||||
if (portbit < GetSize(cell->getPort(portname)))
|
||||
aig->nodes.at(node).outports.push_back(pair<IdString, int>(portname, portbit));
|
||||
aig->nodes.at(node).outports.push_back(pair<TwineRef, int>(portname, portbit));
|
||||
}
|
||||
|
||||
void outport_bool(int node, TwineRef portname)
|
||||
|
|
@ -305,9 +305,9 @@ Aig::Aig(Cell *cell)
|
|||
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_)))
|
||||
{
|
||||
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
|
||||
int A = mk.inport(ID::A, i);
|
||||
int A = mk.inport(TW::A, i);
|
||||
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
|
||||
mk.outport(Y, ID::Y, i);
|
||||
mk.outport(Y, TW::Y, i);
|
||||
}
|
||||
goto optimize;
|
||||
}
|
||||
|
|
@ -315,8 +315,8 @@ Aig::Aig(Cell *cell)
|
|||
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_)))
|
||||
{
|
||||
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
|
||||
int A = mk.inport(ID::A, i);
|
||||
int B = mk.inport(ID::B, 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) :
|
||||
|
|
@ -325,30 +325,30 @@ Aig::Aig(Cell *cell)
|
|||
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;
|
||||
mk.outport(Y, ID::Y, i);
|
||||
mk.outport(Y, TW::Y, i);
|
||||
}
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_)))
|
||||
{
|
||||
int S = mk.inport(ID::S);
|
||||
int S = mk.inport(TW::S);
|
||||
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
|
||||
int A = mk.inport(ID::A, i);
|
||||
int B = mk.inport(ID::B, 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_))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport(Y, ID::Y, i);
|
||||
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)))
|
||||
{
|
||||
int Y = mk.inport(ID::A, 0);
|
||||
int Y = mk.inport(TW::A, 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++) {
|
||||
int A = mk.inport(ID::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);
|
||||
|
|
@ -357,35 +357,35 @@ Aig::Aig(Cell *cell)
|
|||
}
|
||||
if (cell->type == ID($reduce_xnor))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport(Y, ID::Y, 0);
|
||||
mk.outport(Y, TW::Y, 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
|
||||
mk.outport(mk.bool_node(false), ID::Y, i);
|
||||
mk.outport(mk.bool_node(false), TW::Y, i);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
|
||||
{
|
||||
int A = mk.inport(ID::A, 0), Y = -1;
|
||||
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(ID::A, i), A);
|
||||
A = mk.or_gate(mk.inport(TW::A, i), A);
|
||||
if (cell->type.in(ID($logic_and), ID($logic_or))) {
|
||||
int B = mk.inport(ID::B, 0);
|
||||
int B = mk.inport(TW::B, 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++)
|
||||
B = mk.or_gate(mk.inport(ID::B, i), B);
|
||||
B = mk.or_gate(mk.inport(TW::B, i), B);
|
||||
if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B);
|
||||
if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B);
|
||||
} else {
|
||||
if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
|
||||
}
|
||||
mk.outport_bool(Y, ID::Y);
|
||||
mk.outport_bool(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($add), ID($sub)))
|
||||
{
|
||||
int width = GetSize(cell->getPort(TW::Y));
|
||||
vector<int> A = mk.inport_vec(ID::A, width);
|
||||
vector<int> B = mk.inport_vec(ID::B, width);
|
||||
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)) {
|
||||
for (auto &n : B)
|
||||
|
|
@ -393,7 +393,7 @@ Aig::Aig(Cell *cell)
|
|||
carry = mk.not_gate(carry);
|
||||
}
|
||||
vector<int> Y = mk.adder(A, B, carry);
|
||||
mk.outport_vec(Y, ID::Y);
|
||||
mk.outport_vec(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
|
|
@ -401,8 +401,8 @@ Aig::Aig(Cell *cell)
|
|||
{
|
||||
int width = std::max(GetSize(cell->getPort(TW::A)),
|
||||
GetSize(cell->getPort(TW::B))) + 1;
|
||||
vector<int> A = mk.inport_vec(ID::A, width);
|
||||
vector<int> B = mk.inport_vec(ID::B, width);
|
||||
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)))
|
||||
std::swap(A, B);
|
||||
|
|
@ -411,86 +411,86 @@ Aig::Aig(Cell *cell)
|
|||
for (auto &n : B)
|
||||
n = mk.not_gate(n);
|
||||
vector<int> Y = mk.adder(A, B, carry);
|
||||
mk.outport(Y.back(), ID::Y);
|
||||
mk.outport(Y.back(), TW::Y);
|
||||
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
|
||||
mk.outport(mk.bool_node(false), ID::Y, i);
|
||||
mk.outport(mk.bool_node(false), TW::Y, i);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($alu))
|
||||
{
|
||||
int width = GetSize(cell->getPort(TW::Y));
|
||||
vector<int> A = mk.inport_vec(ID::A, width);
|
||||
vector<int> B = mk.inport_vec(ID::B, width);
|
||||
int carry = mk.inport(ID::CI);
|
||||
int binv = mk.inport(ID::BI);
|
||||
vector<int> A = mk.inport_vec(TW::A, width);
|
||||
vector<int> B = mk.inport_vec(TW::B, width);
|
||||
int carry = mk.inport(TW::CI);
|
||||
int binv = mk.inport(TW::BI);
|
||||
for (auto &n : B)
|
||||
n = mk.xor_gate(n, binv);
|
||||
vector<int> X(width), CO(width);
|
||||
vector<int> Y = mk.adder(A, B, carry, &X, &CO);
|
||||
for (int i = 0; i < width; i++)
|
||||
X[i] = mk.xor_gate(A[i], B[i]);
|
||||
mk.outport_vec(Y, ID::Y);
|
||||
mk.outport_vec(X, ID::X);
|
||||
mk.outport_vec(CO, ID::CO);
|
||||
mk.outport_vec(Y, TW::Y);
|
||||
mk.outport_vec(X, TW::X);
|
||||
mk.outport_vec(CO, TW::CO);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($eq), ID($ne)))
|
||||
{
|
||||
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
|
||||
vector<int> A = mk.inport_vec(ID::A, width);
|
||||
vector<int> B = mk.inport_vec(ID::B, width);
|
||||
vector<int> A = mk.inport_vec(TW::A, width);
|
||||
vector<int> B = mk.inport_vec(TW::B, width);
|
||||
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))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport_bool(Y, ID::Y);
|
||||
mk.outport_bool(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI3_))
|
||||
{
|
||||
int A = mk.inport(ID::A);
|
||||
int B = mk.inport(ID::B);
|
||||
int C = mk.inport(ID::C);
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
int C = mk.inport(TW::C);
|
||||
int Y = mk.nor_gate(mk.and_gate(A, B), C);
|
||||
mk.outport(Y, ID::Y);
|
||||
mk.outport(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_OAI3_))
|
||||
{
|
||||
int A = mk.inport(ID::A);
|
||||
int B = mk.inport(ID::B);
|
||||
int C = mk.inport(ID::C);
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
int C = mk.inport(TW::C);
|
||||
int Y = mk.nand_gate(mk.or_gate(A, B), C);
|
||||
mk.outport(Y, ID::Y);
|
||||
mk.outport(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI4_))
|
||||
{
|
||||
int A = mk.inport(ID::A);
|
||||
int B = mk.inport(ID::B);
|
||||
int C = mk.inport(ID::C);
|
||||
int D = mk.inport(ID::D);
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
int C = mk.inport(TW::C);
|
||||
int D = mk.inport(TW::D);
|
||||
int a_and_b = mk.and_gate(A, B);
|
||||
int Y = mk.nor_gate(a_and_b, mk.and_gate(C, D));
|
||||
mk.outport(Y, ID::Y);
|
||||
mk.outport(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($_OAI4_))
|
||||
{
|
||||
int A = mk.inport(ID::A);
|
||||
int B = mk.inport(ID::B);
|
||||
int C = mk.inport(ID::C);
|
||||
int D = mk.inport(ID::D);
|
||||
int A = mk.inport(TW::A);
|
||||
int B = mk.inport(TW::B);
|
||||
int C = mk.inport(TW::C);
|
||||
int D = mk.inport(TW::D);
|
||||
int a_or_b = mk.or_gate(A, B);
|
||||
int Y = mk.nand_gate(a_or_b, mk.or_gate(C, D));
|
||||
mk.outport(Y, ID::Y);
|
||||
mk.outport(Y, TW::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ struct AigNode
|
|||
int portbit;
|
||||
bool inverter;
|
||||
int left_parent, right_parent;
|
||||
vector<pair<IdString, int>> outports;
|
||||
vector<pair<TwineRef, int>> outports;
|
||||
|
||||
AigNode();
|
||||
bool operator==(const AigNode &other) const;
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int i = 0; i < y_width; i++)
|
||||
{
|
||||
if (i < a_width)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
else if (is_signed && a_width > 0)
|
||||
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, a_width-1, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,14 +54,14 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int i = 0; i < y_width; i++)
|
||||
{
|
||||
if (i < a_width)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
else if (is_signed && a_width > 0)
|
||||
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, a_width-1, TW::Y, i, -1);
|
||||
|
||||
if (i < b_width)
|
||||
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
|
||||
else if (is_signed && b_width > 0)
|
||||
db->add_edge(cell, ID::B, b_width-1, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, b_width-1, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
for (int i = 0; i < y_width; i++)
|
||||
for (int k = 0; k <= i && k < a_width; k++)
|
||||
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
|
||||
}
|
||||
|
||||
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -96,10 +96,10 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int k = 0; k <= i; k++)
|
||||
{
|
||||
if (k < a_width)
|
||||
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
|
||||
|
||||
if (k < b_width)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int a_width = GetSize(cell->getPort(TW::A));
|
||||
|
||||
for (int i = 0; i < a_width; i++)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
|
||||
}
|
||||
|
||||
void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -118,9 +118,9 @@ void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int b_width = GetSize(cell->getPort(TW::B));
|
||||
|
||||
for (int i = 0; i < a_width; i++)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
|
||||
for (int i = 0; i < b_width; i++)
|
||||
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, 0, -1);
|
||||
}
|
||||
|
||||
void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -129,9 +129,9 @@ void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int b_width = GetSize(cell->getPort(TW::B));
|
||||
|
||||
for (int i = 0; i < a_width; i++)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
for (int i = 0; i < b_width; i++)
|
||||
db->add_edge(cell, ID::B, i, ID::Y, a_width + i, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, a_width + i, -1);
|
||||
}
|
||||
|
||||
void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -143,7 +143,7 @@ void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int i = 0; i < y_width; i++) {
|
||||
int a_bit = offset + i;
|
||||
if (a_bit >= 0 && a_bit < a_width)
|
||||
db->add_edge(cell, ID::A, a_bit, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, a_bit, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,10 +153,10 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int b_width = GetSize(cell->getPort(TW::B));
|
||||
|
||||
for (int i = 0; i < a_width; i++)
|
||||
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
|
||||
|
||||
for (int i = 0; i < b_width; i++)
|
||||
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, 0, -1);
|
||||
}
|
||||
|
||||
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -167,13 +167,13 @@ void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
for (int i = 0; i < a_width; i++)
|
||||
{
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
|
||||
for (int k = i; k < b_width; k += a_width)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
|
||||
for (int k = 0; k < s_width; k++)
|
||||
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,10 +186,10 @@ void bmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
for (int k = i; k < a_width; k += width)
|
||||
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
|
||||
|
||||
for (int k = 0; k < s_width; k++)
|
||||
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,9 +201,9 @@ void demux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
db->add_edge(cell, ID::A, i % a_width, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i % a_width, TW::Y, i, -1);
|
||||
for (int k = 0; k < s_width; k++)
|
||||
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -275,11 +275,11 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
if (i < b_range_upper) {
|
||||
for (int k = a_range_lower; k < a_range_upper; k++)
|
||||
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
|
||||
} else {
|
||||
// only influence is through sign extension
|
||||
if (is_signed)
|
||||
db->add_edge(cell, ID::A, a_width - 1, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, a_width - 1, TW::Y, i, -1);
|
||||
}
|
||||
|
||||
for (int k = 0; k < b_width_capped; k++) {
|
||||
|
|
@ -289,13 +289,13 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int skip = 1 << (k + 1);
|
||||
int base = skip -1;
|
||||
if (i % skip != base && i - a_width + 2 < 1 << b_width_capped)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
} else if (is_signed) {
|
||||
if (i - a_width + 2 < 1 << b_width_capped)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
} else {
|
||||
if (i - a_width + 1 < 1 << b_width_capped)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
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)) {
|
||||
|
|
@ -306,10 +306,10 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
&& (((y_width - i) & ~(1 << k)) < (1 << b_width_capped)));
|
||||
|
||||
if (shift_in_bulk || (cell->type.in(ID($shr), ID($shift), ID($shiftx)) && zpad_jump))
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
} else {
|
||||
if (i < a_width)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
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) {
|
||||
|
|
@ -326,14 +326,14 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
l = l && (~(i - a_width) & ((1 << (k + 1)) - 1)) != 0;
|
||||
}
|
||||
if (r_shift_in_bulk || r_zpad_jump || l)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
} else {
|
||||
if (y_width - i <= b_high || a_width - 2 - i >= b_low)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
}
|
||||
} else {
|
||||
if (a_width - 1 - i >= b_low)
|
||||
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
|
||||
}
|
||||
} else {
|
||||
log_assert(false && "unreachable");
|
||||
|
|
@ -353,14 +353,14 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
for (int i = 0; i < n_rd_ports; i++) {
|
||||
if (rd_clk_enable[i] != State::S0) {
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::RD_ARST, i, ID::RD_DATA, i * width + k, -1);
|
||||
db->add_edge(cell, TW::RD_ARST, i, TW::RD_DATA, i * width + k, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < abits; j++)
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::RD_ADDR, i * abits + j,
|
||||
ID::RD_DATA, i * width + k, -1);
|
||||
db->add_edge(cell, TW::RD_ADDR, i * abits + j,
|
||||
TW::RD_DATA, i * width + k, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -373,14 +373,14 @@ void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
|
||||
if (cell->type == ID($memrd_v2)) {
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::ARST, 0, ID::DATA, k, -1);
|
||||
db->add_edge(cell, TW::ARST, 0, TW::DATA, k, -1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = 0; j < abits; j++)
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1);
|
||||
db->add_edge(cell, TW::ADDR, j, TW::DATA, k, -1);
|
||||
}
|
||||
|
||||
void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
|
|
@ -401,32 +401,32 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) {
|
||||
for (int k = 0; k < width; k++) {
|
||||
db->add_edge(cell, ID::D, k, ID::Q, k, -1);
|
||||
db->add_edge(cell, ID::EN, 0, ID::Q, k, -1);
|
||||
db->add_edge(cell, TW::D, k, TW::Q, k, -1);
|
||||
db->add_edge(cell, TW::EN, 0, TW::Q, k, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::CLR))
|
||||
if (cell->hasPort(TW::CLR))
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::CLR, 0, ID::Q, k, -1);
|
||||
if (cell->hasPort(ID::SET))
|
||||
db->add_edge(cell, TW::CLR, 0, TW::Q, k, -1);
|
||||
if (cell->hasPort(TW::SET))
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::SET, 0, ID::Q, k, -1);
|
||||
if (cell->hasPort(ID::ALOAD))
|
||||
db->add_edge(cell, TW::SET, 0, TW::Q, k, -1);
|
||||
if (cell->hasPort(TW::ALOAD))
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::ALOAD, 0, ID::Q, k, -1);
|
||||
if (cell->hasPort(ID::AD))
|
||||
db->add_edge(cell, TW::ALOAD, 0, TW::Q, k, -1);
|
||||
if (cell->hasPort(TW::AD))
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::AD, k, ID::Q, k, -1);
|
||||
if (cell->hasPort(ID::ARST))
|
||||
db->add_edge(cell, TW::AD, k, TW::Q, k, -1);
|
||||
if (cell->hasPort(TW::ARST))
|
||||
for (int k = 0; k < width; k++)
|
||||
db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1);
|
||||
db->add_edge(cell, TW::ARST, 0, TW::Q, k, -1);
|
||||
}
|
||||
|
||||
void full_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
std::vector<RTLIL::IdString> input_ports;
|
||||
std::vector<RTLIL::IdString> output_ports;
|
||||
std::vector<TwineRef> input_ports;
|
||||
std::vector<TwineRef> output_ports;
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
|
|
@ -461,8 +461,8 @@ void bweqx_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int max_width = std::min(width, std::min(a_width, b_width));
|
||||
|
||||
for (int i = 0; i < max_width; i++) {
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,9 +475,9 @@ void bwmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
int max_width = std::min(width, std::min(a_width, std::min(b_width, s_width)));
|
||||
|
||||
for (int i = 0; i < max_width; i++) {
|
||||
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, ID::S, i, ID::Y, i, -1);
|
||||
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
|
||||
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
|
||||
db->add_edge(cell, TW::S, i, TW::Y, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ YOSYS_NAMESPACE_BEGIN
|
|||
struct AbstractCellEdgesDatabase
|
||||
{
|
||||
virtual ~AbstractCellEdgesDatabase() { }
|
||||
virtual void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int delay) = 0;
|
||||
virtual void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int delay) = 0;
|
||||
bool add_edges_from_cell(RTLIL::Cell *cell);
|
||||
};
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ struct FwdCellEdgesDatabase : AbstractCellEdgesDatabase
|
|||
dict<SigBit, pool<SigBit>> db;
|
||||
FwdCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
|
||||
|
||||
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
|
||||
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int) override {
|
||||
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
|
||||
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
|
||||
db[from_sigbit].insert(to_sigbit);
|
||||
|
|
@ -51,7 +51,7 @@ struct RevCellEdgesDatabase : AbstractCellEdgesDatabase
|
|||
dict<SigBit, pool<SigBit>> db;
|
||||
RevCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
|
||||
|
||||
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
|
||||
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int) override {
|
||||
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
|
||||
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
|
||||
db[to_sigbit].insert(from_sigbit);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ struct CellTypes
|
|||
if (wire->port_output)
|
||||
outputs.insert(wire->meta_->name);
|
||||
}
|
||||
setup_type(module->name, inputs, outputs);
|
||||
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
|
||||
}
|
||||
|
||||
void setup_design(RTLIL::Design *design)
|
||||
|
|
|
|||
|
|
@ -132,19 +132,19 @@ struct ConstEval
|
|||
|
||||
RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y;
|
||||
|
||||
log_assert(cell->hasPort(ID::Y));
|
||||
log_assert(cell->hasPort(TW::Y));
|
||||
sig_y = values_map(assign_map(cell->getPort(TW::Y)));
|
||||
if (sig_y.is_fully_const())
|
||||
return true;
|
||||
|
||||
if (cell->hasPort(ID::S)) {
|
||||
if (cell->hasPort(TW::S)) {
|
||||
sig_s = cell->getPort(TW::S);
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::A))
|
||||
if (cell->hasPort(TW::A))
|
||||
sig_a = cell->getPort(TW::A);
|
||||
|
||||
if (cell->hasPort(ID::B))
|
||||
if (cell->hasPort(TW::B))
|
||||
sig_b = cell->getPort(TW::B);
|
||||
|
||||
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
|
||||
|
|
@ -337,9 +337,9 @@ struct ConstEval
|
|||
RTLIL::SigSpec sig_c, sig_d;
|
||||
|
||||
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
|
||||
if (cell->hasPort(ID::C))
|
||||
if (cell->hasPort(TW::C))
|
||||
sig_c = cell->getPort(TW::C);
|
||||
if (cell->hasPort(ID::D))
|
||||
if (cell->hasPort(TW::D))
|
||||
sig_d = cell->getPort(TW::D);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ USING_YOSYS_NAMESPACE
|
|||
|
||||
unsigned int CellCosts::get(RTLIL::Module *mod)
|
||||
{
|
||||
if (mod_cost_cache_.count(mod->name))
|
||||
return mod_cost_cache_.at(mod->name);
|
||||
if (mod_cost_cache_.count(mod->meta_->name))
|
||||
return mod_cost_cache_.at(mod->meta_->name);
|
||||
|
||||
unsigned int module_cost = 1;
|
||||
for (auto c : mod->cells()) {
|
||||
|
|
@ -14,7 +14,7 @@ unsigned int CellCosts::get(RTLIL::Module *mod)
|
|||
module_cost = new_cost >= module_cost ? new_cost : INT_MAX;
|
||||
}
|
||||
|
||||
mod_cost_cache_[mod->name] = module_cost;
|
||||
mod_cost_cache_[mod->meta_->name] = module_cost;
|
||||
return module_cost;
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ unsigned int max_inp_width(RTLIL::Cell *cell)
|
|||
unsigned int port_width_sum(RTLIL::Cell *cell)
|
||||
{
|
||||
unsigned int sum = 0;
|
||||
TwineRef port_width_params[] = {
|
||||
IdString port_width_params[] = {
|
||||
ID::WIDTH, ID::A_WIDTH, ID::B_WIDTH, ID::S_WIDTH, ID::Y_WIDTH,
|
||||
};
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
log_debug("%s is a module, recurse\n", cell->name);
|
||||
return get(design_->module(cell->type));
|
||||
} else if (cell->is_builtin_ff()) {
|
||||
log_assert(cell->hasPort(ID::Q) && "Weird flip flop");
|
||||
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))) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ struct CellCosts
|
|||
{
|
||||
|
||||
private:
|
||||
dict<RTLIL::IdString, int> mod_cost_cache_;
|
||||
dict<TwineRef, int> mod_cost_cache_;
|
||||
Design *design_ = nullptr;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ void DriverMap::add(SigSpec const &a, SigSpec const &b)
|
|||
}
|
||||
}
|
||||
|
||||
void DriverMap::add_port(Cell *cell, IdString const &port, SigSpec const &b)
|
||||
void DriverMap::add_port(Cell *cell, TwineRef port, SigSpec const &b)
|
||||
{
|
||||
int offset = 0;
|
||||
for (auto const &chunk : b.chunks()) {
|
||||
|
|
@ -877,8 +877,8 @@ std::string log_signal(DriveChunkWire const &chunk)
|
|||
|
||||
std::string log_signal(DriveChunkPort const &chunk)
|
||||
{
|
||||
std::string cell_id = chunk.cell->name.unescape();
|
||||
std::string port_id = chunk.port.unescape();
|
||||
std::string cell_id = chunk.cell->module->design->twines.str(cell->meta_->name);
|
||||
std::string port_id = chunk.cell->module->design->twines.str(chunk.port);
|
||||
if (chunk.is_whole())
|
||||
return stringf("%s <%s>", cell_id, port_id);
|
||||
if (chunk.width == 1)
|
||||
|
|
|
|||
|
|
@ -87,10 +87,10 @@ struct DriveBitWire
|
|||
struct DriveBitPort
|
||||
{
|
||||
Cell *cell;
|
||||
IdString port;
|
||||
TwineRef port;
|
||||
int offset;
|
||||
|
||||
DriveBitPort(Cell *cell, IdString port, int offset) : cell(cell), port(port), offset(offset) {}
|
||||
DriveBitPort(Cell *cell, TwineRef port, int offset) : cell(cell), port(port), offset(offset) {}
|
||||
|
||||
bool operator==(const DriveBitPort &other) const
|
||||
{
|
||||
|
|
@ -485,15 +485,15 @@ struct DriveChunkWire
|
|||
struct DriveChunkPort
|
||||
{
|
||||
Cell *cell;
|
||||
IdString port;
|
||||
TwineRef port;
|
||||
int offset;
|
||||
int width;
|
||||
|
||||
DriveChunkPort(Cell *cell, IdString port, int offset, int width) :
|
||||
DriveChunkPort(Cell *cell, TwineRef port, int offset, int width) :
|
||||
cell(cell), port(port), offset(offset), width(width) { }
|
||||
DriveChunkPort(Cell *cell, IdString port) :
|
||||
DriveChunkPort(Cell *cell, TwineRef port) :
|
||||
cell(cell), port(port), offset(0), width(GetSize(cell->connections().at(port))) { }
|
||||
DriveChunkPort(Cell *cell, std::pair<IdString, SigSpec> const &conn) :
|
||||
DriveChunkPort(Cell *cell, std::pair<TwineRef, SigSpec> const &conn) :
|
||||
cell(cell), port(conn.first), offset(0), width(GetSize(conn.second)) { }
|
||||
DriveChunkPort(DriveBitPort const &bit) :
|
||||
cell(bit.cell), port(bit.port), offset(bit.offset), width(1) { }
|
||||
|
|
@ -1141,7 +1141,7 @@ private:
|
|||
|
||||
// Maps cell ports to a the first DriveBitId of the consecutive range used
|
||||
// for that cell port.
|
||||
dict<pair<Cell *, IdString>, DriveBitId> port_offsets;
|
||||
dict<pair<Cell *, TwineRef>, DriveBitId> port_offsets;
|
||||
|
||||
// For the inverse map that maps DriveBitIds back to DriveBits we use a
|
||||
// sorted map containing only the first DriveBit for each wire and cell
|
||||
|
|
@ -1237,7 +1237,7 @@ public:
|
|||
void add(SigSpec const &a, SigSpec const &b);
|
||||
|
||||
private:
|
||||
void add_port(Cell *cell, IdString const &port, SigSpec const &b);
|
||||
void add_port(Cell *cell, TwineRef port, SigSpec const &b);
|
||||
|
||||
// Only used a local variables in `orient_undirected`, always cleared, only
|
||||
// stored to reduce allocations.
|
||||
|
|
|
|||
181
kernel/ff.cc
181
kernel/ff.cc
|
|
@ -498,21 +498,21 @@ void FfData::aload_to_sr() {
|
|||
pol_clr = false;
|
||||
pol_set = true;
|
||||
if (pol_aload) {
|
||||
sig_clr = patcher.Mux(NEW_ID, Const(State::S1, width), sig_ad, sig_aload);
|
||||
sig_set = patcher.Mux(NEW_ID, Const(State::S0, width), sig_ad, sig_aload);
|
||||
sig_clr = patcher.Mux(NEW_TWINE, Const(State::S1, width), sig_ad, sig_aload);
|
||||
sig_set = patcher.Mux(NEW_TWINE, Const(State::S0, width), sig_ad, sig_aload);
|
||||
} else {
|
||||
sig_clr = patcher.Mux(NEW_ID, sig_ad, Const(State::S1, width), sig_aload);
|
||||
sig_set = patcher.Mux(NEW_ID, sig_ad, Const(State::S0, width), sig_aload);
|
||||
sig_clr = patcher.Mux(NEW_TWINE, sig_ad, Const(State::S1, width), sig_aload);
|
||||
sig_set = patcher.Mux(NEW_TWINE, sig_ad, Const(State::S0, width), sig_aload);
|
||||
}
|
||||
} else {
|
||||
pol_clr = pol_aload;
|
||||
pol_set = pol_aload;
|
||||
if (pol_aload) {
|
||||
sig_clr = patcher.AndnotGate(NEW_ID, sig_aload, sig_ad);
|
||||
sig_set = patcher.AndGate(NEW_ID, sig_aload, sig_ad);
|
||||
sig_clr = patcher.AndnotGate(NEW_TWINE, sig_aload, sig_ad);
|
||||
sig_set = patcher.AndGate(NEW_TWINE, sig_aload, sig_ad);
|
||||
} else {
|
||||
sig_clr = patcher.OrGate(NEW_ID, sig_aload, sig_ad);
|
||||
sig_set = patcher.OrnotGate(NEW_ID, sig_aload, sig_ad);
|
||||
sig_clr = patcher.OrGate(NEW_TWINE, sig_aload, sig_ad);
|
||||
sig_set = patcher.OrnotGate(NEW_TWINE, sig_aload, sig_ad);
|
||||
}
|
||||
}
|
||||
patcher.commit_inheriting_src(cell);
|
||||
|
|
@ -527,31 +527,31 @@ void FfData::convert_ce_over_srst(bool val) {
|
|||
if (!is_fine) {
|
||||
if (pol_ce) {
|
||||
if (pol_srst) {
|
||||
sig_ce = patcher.Or(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.Or(NEW_TWINE, sig_ce, sig_srst);
|
||||
} else {
|
||||
SigSpec tmp = patcher.Not(NEW_ID, sig_srst);
|
||||
sig_ce = patcher.Or(NEW_ID, sig_ce, tmp);
|
||||
SigSpec tmp = patcher.Not(NEW_TWINE, sig_srst);
|
||||
sig_ce = patcher.Or(NEW_TWINE, sig_ce, tmp);
|
||||
}
|
||||
} else {
|
||||
if (pol_srst) {
|
||||
SigSpec tmp = patcher.Not(NEW_ID, sig_srst);
|
||||
sig_ce = patcher.And(NEW_ID, sig_ce, tmp);
|
||||
SigSpec tmp = patcher.Not(NEW_TWINE, sig_srst);
|
||||
sig_ce = patcher.And(NEW_TWINE, sig_ce, tmp);
|
||||
} else {
|
||||
sig_ce = patcher.And(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.And(NEW_TWINE, sig_ce, sig_srst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pol_ce) {
|
||||
if (pol_srst) {
|
||||
sig_ce = patcher.OrGate(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.OrGate(NEW_TWINE, sig_ce, sig_srst);
|
||||
} else {
|
||||
sig_ce = patcher.OrnotGate(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.OrnotGate(NEW_TWINE, sig_ce, sig_srst);
|
||||
}
|
||||
} else {
|
||||
if (pol_srst) {
|
||||
sig_ce = patcher.AndnotGate(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.AndnotGate(NEW_TWINE, sig_ce, sig_srst);
|
||||
} else {
|
||||
sig_ce = patcher.AndGate(NEW_ID, sig_ce, sig_srst);
|
||||
sig_ce = patcher.AndGate(NEW_TWINE, sig_ce, sig_srst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -560,31 +560,31 @@ void FfData::convert_ce_over_srst(bool val) {
|
|||
if (!is_fine) {
|
||||
if (pol_srst) {
|
||||
if (pol_ce) {
|
||||
sig_srst = patcher.And(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.And(NEW_TWINE, sig_srst, sig_ce);
|
||||
} else {
|
||||
SigSpec tmp = patcher.Not(NEW_ID, sig_ce);
|
||||
sig_srst = patcher.And(NEW_ID, sig_srst, tmp);
|
||||
SigSpec tmp = patcher.Not(NEW_TWINE, sig_ce);
|
||||
sig_srst = patcher.And(NEW_TWINE, sig_srst, tmp);
|
||||
}
|
||||
} else {
|
||||
if (pol_ce) {
|
||||
SigSpec tmp = patcher.Not(NEW_ID, sig_ce);
|
||||
sig_srst = patcher.Or(NEW_ID, sig_srst, tmp);
|
||||
SigSpec tmp = patcher.Not(NEW_TWINE, sig_ce);
|
||||
sig_srst = patcher.Or(NEW_TWINE, sig_srst, tmp);
|
||||
} else {
|
||||
sig_srst = patcher.Or(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.Or(NEW_TWINE, sig_srst, sig_ce);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pol_srst) {
|
||||
if (pol_ce) {
|
||||
sig_srst = patcher.AndGate(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.AndGate(NEW_TWINE, sig_srst, sig_ce);
|
||||
} else {
|
||||
sig_srst = patcher.AndnotGate(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.AndnotGate(NEW_TWINE, sig_srst, sig_ce);
|
||||
}
|
||||
} else {
|
||||
if (pol_ce) {
|
||||
sig_srst = patcher.OrnotGate(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.OrnotGate(NEW_TWINE, sig_srst, sig_ce);
|
||||
} else {
|
||||
sig_srst = patcher.OrGate(NEW_ID, sig_srst, sig_ce);
|
||||
sig_srst = patcher.OrGate(NEW_TWINE, sig_srst, sig_ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -603,14 +603,14 @@ void FfData::unmap_ce() {
|
|||
RTLIL::Patch patcher(module);
|
||||
if (!is_fine) {
|
||||
if (pol_ce)
|
||||
sig_d = patcher.Mux(NEW_ID, sig_q, sig_d, sig_ce);
|
||||
sig_d = patcher.Mux(NEW_TWINE, sig_q, sig_d, sig_ce);
|
||||
else
|
||||
sig_d = patcher.Mux(NEW_ID, sig_d, sig_q, sig_ce);
|
||||
sig_d = patcher.Mux(NEW_TWINE, sig_d, sig_q, sig_ce);
|
||||
} else {
|
||||
if (pol_ce)
|
||||
sig_d = patcher.MuxGate(NEW_ID, sig_q, sig_d, sig_ce);
|
||||
sig_d = patcher.MuxGate(NEW_TWINE, sig_q, sig_d, sig_ce);
|
||||
else
|
||||
sig_d = patcher.MuxGate(NEW_ID, sig_d, sig_q, sig_ce);
|
||||
sig_d = patcher.MuxGate(NEW_TWINE, sig_d, sig_q, sig_ce);
|
||||
}
|
||||
patcher.commit_inheriting_src(cell);
|
||||
has_ce = false;
|
||||
|
|
@ -625,14 +625,14 @@ void FfData::unmap_srst() {
|
|||
RTLIL::Patch patcher(module);
|
||||
if (!is_fine) {
|
||||
if (pol_srst)
|
||||
sig_d = patcher.Mux(NEW_ID, sig_d, val_srst, sig_srst);
|
||||
sig_d = patcher.Mux(NEW_TWINE, sig_d, val_srst, sig_srst);
|
||||
else
|
||||
sig_d = patcher.Mux(NEW_ID, val_srst, sig_d, sig_srst);
|
||||
sig_d = patcher.Mux(NEW_TWINE, val_srst, sig_d, sig_srst);
|
||||
} else {
|
||||
if (pol_srst)
|
||||
sig_d = patcher.MuxGate(NEW_ID, sig_d, val_srst[0], sig_srst);
|
||||
sig_d = patcher.MuxGate(NEW_TWINE, sig_d, val_srst[0], sig_srst);
|
||||
else
|
||||
sig_d = patcher.MuxGate(NEW_ID, val_srst[0], sig_d, sig_srst);
|
||||
sig_d = patcher.MuxGate(NEW_TWINE, val_srst[0], sig_d, sig_srst);
|
||||
}
|
||||
patcher.commit_inheriting_src(cell);
|
||||
has_srst = false;
|
||||
|
|
@ -664,48 +664,48 @@ Cell *FfData::emit() {
|
|||
cell = module->addAnyinit(name, sig_d, sig_q);
|
||||
log_assert(val_init.is_fully_undef());
|
||||
} else {
|
||||
cell = module->addFf(name, sig_d, sig_q);
|
||||
cell = module->addFf(Twine{name.str()}, sig_d, sig_q);
|
||||
}
|
||||
} else if (!has_aload && !has_clk) {
|
||||
log_assert(has_sr);
|
||||
cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr);
|
||||
cell = module->addSr(Twine{name.str()}, sig_set, sig_clr, sig_q, pol_set, pol_clr);
|
||||
} else if (!has_clk) {
|
||||
log_assert(!has_srst);
|
||||
if (has_sr)
|
||||
cell = module->addDlatchsr(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
|
||||
cell = module->addDlatchsr(Twine{name.str()}, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
|
||||
else if (has_arst)
|
||||
cell = module->addAdlatch(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst);
|
||||
cell = module->addAdlatch(Twine{name.str()}, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst);
|
||||
else
|
||||
cell = module->addDlatch(name, sig_aload, sig_ad, sig_q, pol_aload);
|
||||
cell = module->addDlatch(Twine{name.str()}, sig_aload, sig_ad, sig_q, pol_aload);
|
||||
} else {
|
||||
if (has_sr) {
|
||||
if (has_ce)
|
||||
cell = module->addDffsre(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
|
||||
cell = module->addDffsre(Twine{name.str()}, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
|
||||
else
|
||||
cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
|
||||
cell = module->addDffsr(Twine{name.str()}, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
|
||||
} else if (has_arst) {
|
||||
if (has_ce)
|
||||
cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst);
|
||||
cell = module->addAdffe(Twine{name.str()}, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst);
|
||||
else
|
||||
cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst);
|
||||
cell = module->addAdff(Twine{name.str()}, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst);
|
||||
} else if (has_aload) {
|
||||
if (has_ce)
|
||||
cell = module->addAldffe(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
|
||||
cell = module->addAldffe(Twine{name.str()}, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
|
||||
else
|
||||
cell = module->addAldff(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
|
||||
cell = module->addAldff(Twine{name.str()}, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
|
||||
} else if (has_srst) {
|
||||
if (has_ce)
|
||||
if (ce_over_srst)
|
||||
cell = module->addSdffce(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
|
||||
cell = module->addSdffce(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
|
||||
else
|
||||
cell = module->addSdffe(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
|
||||
cell = module->addSdffe(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
|
||||
else
|
||||
cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst);
|
||||
cell = module->addSdff(Twine{name.str()}, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst);
|
||||
} else {
|
||||
if (has_ce)
|
||||
cell = module->addDffe(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
|
||||
cell = module->addDffe(Twine{name.str()}, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
|
||||
else
|
||||
cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk);
|
||||
cell = module->addDff(Twine{name.str()}, sig_clk, sig_d, sig_q, pol_clk);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -717,47 +717,47 @@ Cell *FfData::emit() {
|
|||
log_assert(!has_srst);
|
||||
log_assert(!has_sr);
|
||||
log_assert(!is_anyinit);
|
||||
cell = module->addFfGate(name, sig_d, sig_q);
|
||||
cell = module->addFfGate(Twine{name.str()}, sig_d, sig_q);
|
||||
} else if (!has_aload && !has_clk) {
|
||||
log_assert(has_sr);
|
||||
cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr);
|
||||
cell = module->addSrGate(Twine{name.str()}, sig_set, sig_clr, sig_q, pol_set, pol_clr);
|
||||
} else if (!has_clk) {
|
||||
log_assert(!has_srst);
|
||||
if (has_sr)
|
||||
cell = module->addDlatchsrGate(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
|
||||
cell = module->addDlatchsrGate(Twine{name.str()}, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
|
||||
else if (has_arst)
|
||||
cell = module->addAdlatchGate(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst);
|
||||
cell = module->addAdlatchGate(Twine{name.str()}, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst);
|
||||
else
|
||||
cell = module->addDlatchGate(name, sig_aload, sig_ad, sig_q, pol_aload);
|
||||
cell = module->addDlatchGate(Twine{name.str()}, sig_aload, sig_ad, sig_q, pol_aload);
|
||||
} else {
|
||||
if (has_sr) {
|
||||
if (has_ce)
|
||||
cell = module->addDffsreGate(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
|
||||
cell = module->addDffsreGate(Twine{name.str()}, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
|
||||
else
|
||||
cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
|
||||
cell = module->addDffsrGate(Twine{name.str()}, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
|
||||
} else if (has_arst) {
|
||||
if (has_ce)
|
||||
cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst);
|
||||
cell = module->addAdffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst);
|
||||
else
|
||||
cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst);
|
||||
cell = module->addAdffGate(Twine{name.str()}, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst);
|
||||
} else if (has_aload) {
|
||||
if (has_ce)
|
||||
cell = module->addAldffeGate(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
|
||||
cell = module->addAldffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
|
||||
else
|
||||
cell = module->addAldffGate(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
|
||||
cell = module->addAldffGate(Twine{name.str()}, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
|
||||
} else if (has_srst) {
|
||||
if (has_ce)
|
||||
if (ce_over_srst)
|
||||
cell = module->addSdffceGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
|
||||
cell = module->addSdffceGate(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
|
||||
else
|
||||
cell = module->addSdffeGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
|
||||
cell = module->addSdffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
|
||||
else
|
||||
cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst);
|
||||
cell = module->addSdffGate(Twine{name.str()}, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst);
|
||||
} else {
|
||||
if (has_ce)
|
||||
cell = module->addDffeGate(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
|
||||
cell = module->addDffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
|
||||
else
|
||||
cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk);
|
||||
cell = module->addDffGate(Twine{name.str()}, sig_clk, sig_d, sig_q, pol_clk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -766,19 +766,8 @@ Cell *FfData::emit() {
|
|||
// pool, no flatten. The OwnedTwine still holds its own ref until
|
||||
// FfData is destroyed; set_src_id retains on the cell's behalf.
|
||||
cell->attributes = attributes;
|
||||
if (!src_twine.empty() && cell->module && cell->module->design) {
|
||||
TwinePool *dst_pool = &cell->module->design->twines;
|
||||
if (src_twine.pool() == dst_pool) {
|
||||
cell->set_src_id(src_twine.id());
|
||||
} else {
|
||||
// Cross-pool (unusual — FfData migrated between
|
||||
// designs). Rebuild the twine structure into the
|
||||
// destination pool, then adopt that fresh id.
|
||||
TwineRef migrated = dst_pool->copy_from(*src_twine.pool(), src_twine.id());
|
||||
cell->set_src_id(migrated);
|
||||
dst_pool->release(migrated);
|
||||
}
|
||||
}
|
||||
if (src_twine != Twine::Null && cell->module && cell->module->design)
|
||||
cell->set_src_id(src_twine);
|
||||
if (initvals && !is_anyinit)
|
||||
initvals->set_init(cell->getPort(TW::Q), val_init);
|
||||
return cell;
|
||||
|
|
@ -826,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->name.unescape(), cell->name.unescape(), 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->module->design->twines.str(cell->meta_->name), cell->type.unescape());
|
||||
}
|
||||
|
||||
if (is_fine) {
|
||||
|
|
@ -835,15 +824,15 @@ void FfData::flip_bits(const pool<int> &bits) {
|
|||
SigSpec new_sig_clr;
|
||||
if (pol_set) {
|
||||
if (pol_clr) {
|
||||
new_sig_clr = module->AndnotGate(NEW_ID, sig_set, sig_clr);
|
||||
new_sig_clr = module->AndnotGate(NEW_TWINE, sig_set, sig_clr);
|
||||
} else {
|
||||
new_sig_clr = module->AndGate(NEW_ID, sig_set, sig_clr);
|
||||
new_sig_clr = module->AndGate(NEW_TWINE, sig_set, sig_clr);
|
||||
}
|
||||
} else {
|
||||
if (pol_clr) {
|
||||
new_sig_clr = module->OrGate(NEW_ID, sig_set, sig_clr);
|
||||
new_sig_clr = module->OrGate(NEW_TWINE, sig_set, sig_clr);
|
||||
} else {
|
||||
new_sig_clr = module->OrnotGate(NEW_ID, sig_set, sig_clr);
|
||||
new_sig_clr = module->OrnotGate(NEW_TWINE, sig_set, sig_clr);
|
||||
}
|
||||
}
|
||||
pol_set = pol_clr;
|
||||
|
|
@ -852,10 +841,10 @@ void FfData::flip_bits(const pool<int> &bits) {
|
|||
sig_clr = new_sig_clr;
|
||||
}
|
||||
if (has_clk || has_gclk)
|
||||
sig_d = module->NotGate(NEW_ID, sig_d);
|
||||
sig_d = module->NotGate(NEW_TWINE, sig_d);
|
||||
if (has_aload)
|
||||
sig_ad = module->NotGate(NEW_ID, sig_ad);
|
||||
module->addNotGate(NEW_ID, new_q, sig_q);
|
||||
sig_ad = module->NotGate(NEW_TWINE, sig_ad);
|
||||
module->addNotGate(NEW_TWINE, new_q, sig_q);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -863,17 +852,17 @@ void FfData::flip_bits(const pool<int> &bits) {
|
|||
SigSpec not_clr;
|
||||
if (!pol_clr) {
|
||||
not_clr = sig_clr;
|
||||
sig_clr = module->Not(NEW_ID, sig_clr);
|
||||
sig_clr = module->Not(NEW_TWINE, sig_clr);
|
||||
pol_clr = true;
|
||||
} else {
|
||||
not_clr = module->Not(NEW_ID, sig_clr);
|
||||
not_clr = module->Not(NEW_TWINE, sig_clr);
|
||||
}
|
||||
if (!pol_set) {
|
||||
sig_set = module->Not(NEW_ID, sig_set);
|
||||
sig_set = module->Not(NEW_TWINE, sig_set);
|
||||
pol_set = true;
|
||||
}
|
||||
|
||||
SigSpec masked_set = module->And(NEW_ID, sig_set, not_clr);
|
||||
SigSpec masked_set = module->And(NEW_TWINE, sig_set, not_clr);
|
||||
for (auto bit: bits) {
|
||||
sig_set[bit] = sig_clr[bit];
|
||||
sig_clr[bit] = masked_set[bit];
|
||||
|
|
@ -885,10 +874,10 @@ void FfData::flip_bits(const pool<int> &bits) {
|
|||
mask.set(bit, State::S1);
|
||||
|
||||
if (has_clk || has_gclk)
|
||||
sig_d = module->Xor(NEW_ID, sig_d, mask);
|
||||
sig_d = module->Xor(NEW_TWINE, sig_d, mask);
|
||||
if (has_aload)
|
||||
sig_ad = module->Xor(NEW_ID, sig_ad, mask);
|
||||
module->addXor(NEW_ID, new_q, mask, sig_q);
|
||||
sig_ad = module->Xor(NEW_TWINE, sig_ad, mask);
|
||||
module->addXor(NEW_TWINE, new_q, mask, sig_q);
|
||||
}
|
||||
|
||||
sig_q = new_q;
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ void FfMergeHelper::remove_output_ff(const pool<std::pair<Cell *, int>> &bits) {
|
|||
SigSpec q = cell->getPort(TW::Q);
|
||||
initvals->remove_init(q[idx]);
|
||||
dff_driver.erase((*sigmap)(q[idx]));
|
||||
q[idx] = module->addWire(stringf("$ffmerge_disconnected$%d", autoidx++));
|
||||
q[idx] = module->addWire(Twine{stringf("$ffmerge_disconnected$%d", autoidx++)});
|
||||
cell->setPort(TW::Q, q);
|
||||
initvals->set_init(cell->getPort(TW::Q), (*initvals)(q));
|
||||
}
|
||||
|
|
@ -311,7 +311,7 @@ void FfMergeHelper::mark_input_ff(const pool<std::pair<Cell *, int>> &bits) {
|
|||
for (auto &it : bits) {
|
||||
Cell *cell = it.first;
|
||||
int idx = it.second;
|
||||
if (cell->hasPort(ID::D)) {
|
||||
if (cell->hasPort(TW::D)) {
|
||||
SigSpec d = cell->getPort(TW::D);
|
||||
// The user count was already at least 1
|
||||
// (for the D port). Bump it as it is now connected
|
||||
|
|
@ -337,7 +337,7 @@ void FfMergeHelper::set(FfInitVals *initvals_, RTLIL::Module *module_)
|
|||
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->is_builtin_ff()) {
|
||||
if (cell->hasPort(ID::D)) {
|
||||
if (cell->hasPort(TW::D)) {
|
||||
SigSpec d = (*sigmap)(cell->getPort(TW::D));
|
||||
for (int i = 0; i < GetSize(d); i++)
|
||||
dff_sink[d[i]].insert(std::make_pair(cell, i));
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ void Fmt::append_literal(const std::string &str) {
|
|||
|
||||
void Fmt::parse_rtlil(const RTLIL::Cell *cell) {
|
||||
std::string fmt = cell->getParam(ID(FORMAT)).decode_string();
|
||||
RTLIL::SigSpec args = cell->getPort(ID(ARGS));
|
||||
RTLIL::SigSpec args = cell->getPort(TW::ARGS);
|
||||
parts.clear();
|
||||
|
||||
FmtPart part;
|
||||
|
|
@ -261,7 +261,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
|
|||
|
||||
cell->setParam(ID(FORMAT), fmt);
|
||||
cell->setParam(ID(ARGS_WIDTH), args.size());
|
||||
cell->setPort(ID(ARGS), args);
|
||||
cell->setPort(TW::ARGS, args);
|
||||
}
|
||||
|
||||
static size_t compute_required_decimal_places(size_t size, bool signed_)
|
||||
|
|
|
|||
|
|
@ -218,15 +218,15 @@ private:
|
|||
y = factory.mux(y, factory.slice(b, a.width() * i, a.width()), factory.slice(s, i, 1));
|
||||
return y;
|
||||
}
|
||||
dict<IdString, Node> handle_fa(Node a, Node b, Node c) {
|
||||
dict<TwineRef, Node> handle_fa(Node a, Node b, Node c) {
|
||||
Node t1 = factory.bitwise_xor(a, b);
|
||||
Node t2 = factory.bitwise_and(a, b);
|
||||
Node t3 = factory.bitwise_and(c, t1);
|
||||
Node y = factory.bitwise_xor(c, t1);
|
||||
Node x = factory.bitwise_or(t2, t3);
|
||||
return {{ID(X), x}, {ID(Y), y}};
|
||||
return {{TW::X, x}, {TW::Y, y}};
|
||||
}
|
||||
dict<IdString, Node> handle_alu(Node a_in, Node b_in, int y_width, bool is_signed, Node ci, Node bi) {
|
||||
dict<TwineRef, Node> handle_alu(Node a_in, Node b_in, int y_width, bool is_signed, Node ci, Node bi) {
|
||||
Node a = factory.extend(a_in, y_width, is_signed);
|
||||
Node b_uninverted = factory.extend(b_in, y_width, is_signed);
|
||||
Node b = factory.mux(b_uninverted, factory.bitwise_not(b_uninverted), bi);
|
||||
|
|
@ -240,13 +240,13 @@ private:
|
|||
Node y = factory.slice(y_extra, 0, y_width);
|
||||
Node carries = factory.bitwise_xor(y_extra, factory.bitwise_xor(a_extra, b_extra));
|
||||
Node co = factory.slice(carries, 1, y_width);
|
||||
return {{ID(X), x}, {ID(Y), y}, {ID(CO), co}};
|
||||
return {{TW::X, x}, {TW::Y, y}, {TW::CO, co}};
|
||||
}
|
||||
Node handle_lcu(Node p, Node g, Node ci) {
|
||||
return handle_alu(g, factory.bitwise_or(p, g), g.width(), false, ci, factory.constant(Const(State::S0, 1))).at(ID(CO));
|
||||
return handle_alu(g, factory.bitwise_or(p, g), g.width(), false, ci, factory.constant(Const(State::S0, 1))).at(TW::CO);
|
||||
}
|
||||
public:
|
||||
std::variant<dict<IdString, Node>, Node> handle(IdString cellName, IdString cellType, dict<IdString, Const> parameters, dict<IdString, Node> inputs)
|
||||
std::variant<dict<TwineRef, Node>, Node> handle(IdString cellName, IdString cellType, dict<IdString, Const> parameters, dict<TwineRef, Node> inputs)
|
||||
{
|
||||
int a_width = parameters.at(ID(A_WIDTH), Const(-1)).as_int();
|
||||
int b_width = parameters.at(ID(B_WIDTH), Const(-1)).as_int();
|
||||
|
|
@ -255,8 +255,8 @@ public:
|
|||
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))){
|
||||
bool is_signed = a_signed && b_signed;
|
||||
Node a = factory.extend(inputs.at(ID(A)), y_width, is_signed);
|
||||
Node b = factory.extend(inputs.at(ID(B)), y_width, is_signed);
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, is_signed);
|
||||
Node b = factory.extend(inputs.at(TW::B), y_width, is_signed);
|
||||
if(cellType == ID($add))
|
||||
return factory.add(a, b);
|
||||
else if(cellType == ID($sub))
|
||||
|
|
@ -276,8 +276,8 @@ public:
|
|||
}else if(cellType.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($le), ID($lt), ID($ge), ID($gt))){
|
||||
bool is_signed = a_signed && b_signed;
|
||||
int width = max(a_width, b_width);
|
||||
Node a = factory.extend(inputs.at(ID(A)), width, is_signed);
|
||||
Node b = factory.extend(inputs.at(ID(B)), width, is_signed);
|
||||
Node a = factory.extend(inputs.at(TW::A), width, is_signed);
|
||||
Node b = factory.extend(inputs.at(TW::B), width, is_signed);
|
||||
if(cellType.in(ID($eq), ID($eqx)))
|
||||
return factory.extend(factory.equal(a, b), y_width, false);
|
||||
else if(cellType.in(ID($ne), ID($nex)))
|
||||
|
|
@ -293,48 +293,48 @@ public:
|
|||
else
|
||||
log_abort();
|
||||
}else if(cellType.in(ID($logic_or), ID($logic_and))){
|
||||
Node a = factory.reduce_or(inputs.at(ID(A)));
|
||||
Node b = factory.reduce_or(inputs.at(ID(B)));
|
||||
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);
|
||||
return factory.extend(y, y_width, false);
|
||||
}else if(cellType == ID($not)){
|
||||
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
|
||||
return factory.bitwise_not(a);
|
||||
}else if(cellType == ID($pos)){
|
||||
return factory.extend(inputs.at(ID(A)), y_width, a_signed);
|
||||
return factory.extend(inputs.at(TW::A), y_width, a_signed);
|
||||
}else if(cellType == ID($neg)){
|
||||
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
|
||||
return factory.unary_minus(a);
|
||||
}else if(cellType == ID($logic_not)){
|
||||
Node a = factory.reduce_or(inputs.at(ID(A)));
|
||||
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))){
|
||||
Node a = factory.reduce_or(inputs.at(ID(A)));
|
||||
Node a = factory.reduce_or(inputs.at(TW::A));
|
||||
return factory.extend(a, y_width, false);
|
||||
}else if(cellType == ID($reduce_and)){
|
||||
Node a = factory.reduce_and(inputs.at(ID(A)));
|
||||
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))){
|
||||
Node a = factory.reduce_xor(inputs.at(ID(A)));
|
||||
Node a = factory.reduce_xor(inputs.at(TW::A));
|
||||
Node y = cellType == ID($reduce_xnor) ? factory.bitwise_not(a) : a;
|
||||
return factory.extend(y, y_width, false);
|
||||
}else if(cellType == ID($shl) || cellType == ID($sshl)){
|
||||
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
|
||||
Node b = inputs.at(ID(B));
|
||||
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)){
|
||||
int width = max(a_width, y_width);
|
||||
Node a = factory.extend(inputs.at(ID(A)), width, a_signed);
|
||||
Node b = inputs.at(ID(B));
|
||||
Node a = factory.extend(inputs.at(TW::A), width, a_signed);
|
||||
Node b = inputs.at(TW::B);
|
||||
Node y = a_signed && cellType == ID($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)){
|
||||
int width = max(a_width, y_width);
|
||||
Node a = factory.extend(inputs.at(ID(A)), width, cellType == ID($shift) && a_signed);
|
||||
Node b = inputs.at(ID(B));
|
||||
Node a = factory.extend(inputs.at(TW::A), width, cellType == ID($shift) && a_signed);
|
||||
Node b = inputs.at(TW::B);
|
||||
Node shr = logical_shift_right(a, b);
|
||||
if(b_signed) {
|
||||
Node shl = logical_shift_left(a, factory.unary_minus(b));
|
||||
|
|
@ -344,22 +344,22 @@ public:
|
|||
return factory.extend(shr, y_width, false);
|
||||
}
|
||||
}else if(cellType == ID($mux)){
|
||||
return factory.mux(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(S)));
|
||||
return factory.mux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
|
||||
}else if(cellType == ID($pmux)){
|
||||
return handle_pmux(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(S)));
|
||||
return handle_pmux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
|
||||
}else if(cellType == ID($concat)){
|
||||
Node a = inputs.at(ID(A));
|
||||
Node b = inputs.at(ID(B));
|
||||
Node a = inputs.at(TW::A);
|
||||
Node b = inputs.at(TW::B);
|
||||
return factory.concat(a, b);
|
||||
}else if(cellType == ID($slice)){
|
||||
int offset = parameters.at(ID(OFFSET)).as_int();
|
||||
Node a = inputs.at(ID(A));
|
||||
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))) {
|
||||
int width = max(a_width, b_width);
|
||||
bool is_signed = a_signed && b_signed;
|
||||
Node a = factory.extend(inputs.at(ID(A)), width, is_signed);
|
||||
Node b = factory.extend(inputs.at(ID(B)), width, is_signed);
|
||||
Node a = factory.extend(inputs.at(TW::A), width, is_signed);
|
||||
Node b = factory.extend(inputs.at(TW::B), width, is_signed);
|
||||
if(is_signed) {
|
||||
if(cellType == ID($div)) {
|
||||
// divide absolute values, then flip the sign if input signs differ
|
||||
|
|
@ -403,44 +403,44 @@ public:
|
|||
return factory.extend(factory.unsigned_div(a, b), y_width, false);
|
||||
}
|
||||
} else if(cellType == ID($pow)) {
|
||||
return handle_pow(inputs.at(ID(A)), inputs.at(ID(B)), y_width, a_signed && b_signed);
|
||||
return handle_pow(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed);
|
||||
} else if (cellType == ID($lut)) {
|
||||
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(ID(A)), 0, 1, width);
|
||||
return handle_bmux(factory.constant(lut_table), inputs.at(TW::A), 0, 1, width);
|
||||
} else if (cellType == ID($bwmux)) {
|
||||
Node a = inputs.at(ID(A));
|
||||
Node b = inputs.at(ID(B));
|
||||
Node s = inputs.at(ID(S));
|
||||
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)) {
|
||||
Node a = inputs.at(ID(A));
|
||||
Node b = inputs.at(ID(B));
|
||||
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)) {
|
||||
int width = parameters.at(ID(WIDTH)).as_int();
|
||||
int s_width = parameters.at(ID(S_WIDTH)).as_int();
|
||||
return handle_bmux(inputs.at(ID(A)), inputs.at(ID(S)), 0, width, s_width);
|
||||
return handle_bmux(inputs.at(TW::A), inputs.at(TW::S), 0, width, s_width);
|
||||
} else if(cellType == ID($demux)) {
|
||||
int width = parameters.at(ID(WIDTH)).as_int();
|
||||
int s_width = parameters.at(ID(S_WIDTH)).as_int();
|
||||
int y_width = width << s_width;
|
||||
int b_width = ceil_log2(y_width);
|
||||
Node a = factory.extend(inputs.at(ID(A)), y_width, false);
|
||||
Node s = factory.extend(inputs.at(ID(S)), b_width, false);
|
||||
Node a = factory.extend(inputs.at(TW::A), y_width, false);
|
||||
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)) {
|
||||
return handle_fa(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(C)));
|
||||
return handle_fa(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::C));
|
||||
} else if(cellType == ID($lcu)) {
|
||||
return handle_lcu(inputs.at(ID(P)), inputs.at(ID(G)), inputs.at(ID(CI)));
|
||||
return handle_lcu(inputs.at(TW::P), inputs.at(TW::G), inputs.at(TW::CI));
|
||||
} else if(cellType == ID($alu)) {
|
||||
return handle_alu(inputs.at(ID(A)), inputs.at(ID(B)), y_width, a_signed && b_signed, inputs.at(ID(CI)), inputs.at(ID(BI)));
|
||||
return handle_alu(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed, inputs.at(TW::CI), inputs.at(TW::BI));
|
||||
} else if(cellType.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
|
||||
Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(ID(A)), inputs.at(ID(EN)));
|
||||
Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(TW::A), inputs.at(TW::EN));
|
||||
auto &output = factory.add_output(cellName, cellType, Sort(1));
|
||||
output.set_value(a);
|
||||
return {};
|
||||
|
|
@ -468,7 +468,7 @@ public:
|
|||
class FunctionalIRConstruction {
|
||||
std::deque<std::variant<DriveSpec, Cell *>> queue;
|
||||
dict<DriveSpec, Node> graph_nodes;
|
||||
dict<std::pair<Cell *, IdString>, Node> cell_outputs;
|
||||
dict<std::pair<Cell *, TwineRef>, Node> cell_outputs;
|
||||
DriverMap driver_map;
|
||||
Factory& factory;
|
||||
CellSimplifier simplifier;
|
||||
|
|
@ -488,7 +488,7 @@ class FunctionalIRConstruction {
|
|||
}else
|
||||
return it->second;
|
||||
}
|
||||
Node enqueue_cell(Cell *cell, IdString port_name)
|
||||
Node enqueue_cell(Cell *cell, TwineRef port_name)
|
||||
{
|
||||
auto it = cell_outputs.find({cell, port_name});
|
||||
if(it == cell_outputs.end()) {
|
||||
|
|
@ -497,7 +497,7 @@ class FunctionalIRConstruction {
|
|||
for(auto const &[name, sigspec] : cell->connections())
|
||||
if(driver_map.celltypes.cell_output(cell->type, name)) {
|
||||
auto node = factory.create_pending(sigspec.size());
|
||||
factory.suggest_name(node, cell->name.str() + "$" + name.str());
|
||||
factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name));
|
||||
cell_outputs.emplace({cell, name}, node);
|
||||
if(name == port_name)
|
||||
rv = node;
|
||||
|
|
@ -539,7 +539,7 @@ private:
|
|||
Node concatenate_read_results(Mem *mem, vector<Node> results)
|
||||
{
|
||||
// sanity check: all read ports concatenated should equal to the RD_DATA port
|
||||
const SigSpec &rd_data = mem->cell->connections().at(ID(RD_DATA));
|
||||
const SigSpec &rd_data = mem->cell->connections().at(TW::RD_DATA);
|
||||
int current = 0;
|
||||
for(size_t i = 0; i < mem->rd_ports.size(); i++) {
|
||||
int width = mem->width << mem->rd_ports[i].wide_log2;
|
||||
|
|
@ -604,7 +604,7 @@ private:
|
|||
"Call memory_collect to avoid this error.\n", log_const(cell->parameters.at(ID(MEMID))));
|
||||
}
|
||||
Node node = handle_memory(mem);
|
||||
factory.update_pending(cell_outputs.at({cell, ID(RD_DATA)}), node);
|
||||
factory.update_pending(cell_outputs.at({cell, TW::RD_DATA}), node);
|
||||
} else if (cell->is_builtin_ff()) {
|
||||
FfData ff(&ff_initvals, cell);
|
||||
if (!ff.has_gclk)
|
||||
|
|
@ -613,12 +613,12 @@ private:
|
|||
auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width));
|
||||
Node q_value = factory.value(state);
|
||||
factory.suggest_name(q_value, ff.name);
|
||||
factory.update_pending(cell_outputs.at({cell, ID(Q)}), q_value);
|
||||
factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value);
|
||||
state.set_next_value(enqueue(ff.sig_d));
|
||||
state.set_initial_value(ff.val_init);
|
||||
} else {
|
||||
dict<IdString, Node> connections;
|
||||
IdString output_name; // for the single output case
|
||||
dict<TwineRef, Node> connections;
|
||||
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)
|
||||
|
|
@ -628,12 +628,12 @@ private:
|
|||
n_outputs++;
|
||||
}
|
||||
}
|
||||
std::variant<dict<IdString, Node>, Node> outputs = simplifier.handle(cell->name, cell->type, cell->parameters, connections);
|
||||
std::variant<dict<TwineRef, Node>, Node> outputs = simplifier.handle(cell->name, cell->type, cell->parameters, connections);
|
||||
if(auto *nodep = std::get_if<Node>(&outputs); nodep != nullptr) {
|
||||
log_assert(n_outputs == 1);
|
||||
factory.update_pending(cell_outputs.at({cell, output_name}), *nodep);
|
||||
} else {
|
||||
for(auto [name, node] : std::get<dict<IdString, Node>>(outputs))
|
||||
for(auto [name, node] : std::get<dict<TwineRef, Node>>(outputs))
|
||||
factory.update_pending(cell_outputs.at({cell, name}), node);
|
||||
}
|
||||
}
|
||||
|
|
@ -695,7 +695,8 @@ public:
|
|||
factory.update_pending(pending, node);
|
||||
} else {
|
||||
DriveSpec driver = driver_map(DriveSpec(port_chunk));
|
||||
check_undriven(driver, port_chunk.cell->name.unescape() + " port " + port_chunk.port.unescape());
|
||||
auto& twines = port_chunk.cell->module->design->twines;
|
||||
check_undriven(driver, twines.str(port_chunk.cell->meta_->name) + " port " + twines.str(port_chunk.port));
|
||||
factory.update_pending(pending, enqueue(driver));
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -619,6 +619,39 @@ const char *log_id(const RTLIL::IdString &str)
|
|||
return log_id_cache.back();
|
||||
}
|
||||
|
||||
static const char *log_id_twine(const RTLIL::Design *design, TwineRef name)
|
||||
{
|
||||
std::string unescaped = RTLIL::unescape_id(design->twines.str(name));
|
||||
log_id_cache.push_back(strdup(unescaped.c_str()));
|
||||
return log_id_cache.back();
|
||||
}
|
||||
|
||||
const char *log_id(const RTLIL::Module *obj, const char *nullstr)
|
||||
{
|
||||
if (nullstr && obj == nullptr) return nullstr;
|
||||
return log_id_twine(obj->design, obj->meta_->name);
|
||||
}
|
||||
const char *log_id(const RTLIL::Cell *obj, const char *nullstr)
|
||||
{
|
||||
if (nullstr && obj == nullptr) return nullstr;
|
||||
return log_id_twine(obj->module->design, obj->meta_->name);
|
||||
}
|
||||
const char *log_id(const RTLIL::Wire *obj, const char *nullstr)
|
||||
{
|
||||
if (nullstr && obj == nullptr) return nullstr;
|
||||
return log_id_twine(obj->module->design, obj->meta_->name);
|
||||
}
|
||||
const char *log_id(const RTLIL::Memory *obj, const char *nullstr)
|
||||
{
|
||||
if (nullstr && obj == nullptr) return nullstr;
|
||||
return log_id_twine(obj->module->design, obj->meta_->name);
|
||||
}
|
||||
const char *log_id(const RTLIL::Process *obj, const char *nullstr)
|
||||
{
|
||||
if (nullstr && obj == nullptr) return nullstr;
|
||||
return log_id_twine(obj->module->design, obj->meta_->name);
|
||||
}
|
||||
|
||||
void log_module(RTLIL::Module *module, std::string indent)
|
||||
{
|
||||
std::stringstream buf;
|
||||
|
|
|
|||
10
kernel/log.h
10
kernel/log.h
|
|
@ -259,11 +259,11 @@ std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
|
|||
std::string log_const(const RTLIL::Const &value, bool autoint = true);
|
||||
const char *log_id(const RTLIL::IdString &id);
|
||||
|
||||
template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {
|
||||
if (nullstr && obj == nullptr)
|
||||
return nullstr;
|
||||
return log_id(obj->name);
|
||||
}
|
||||
const char *log_id(const RTLIL::Module *obj, const char *nullstr = nullptr);
|
||||
const char *log_id(const RTLIL::Cell *obj, const char *nullstr = nullptr);
|
||||
const char *log_id(const RTLIL::Wire *obj, const char *nullstr = nullptr);
|
||||
const char *log_id(const RTLIL::Memory *obj, const char *nullstr = nullptr);
|
||||
const char *log_id(const RTLIL::Process *obj, const char *nullstr = nullptr);
|
||||
|
||||
void log_module(RTLIL::Module *module, std::string indent = "");
|
||||
void log_cell(RTLIL::Cell *cell, std::string indent = "");
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ void Mem::remove() {
|
|||
cell = nullptr;
|
||||
}
|
||||
if (mem) {
|
||||
module->memories.erase(mem->name);
|
||||
module->memories.erase(mem->meta_->name);
|
||||
delete mem;
|
||||
mem = nullptr;
|
||||
}
|
||||
|
|
@ -116,14 +116,14 @@ void Mem::emit() {
|
|||
|
||||
if (packed) {
|
||||
if (mem) {
|
||||
module->memories.erase(mem->name);
|
||||
module->memories.erase(mem->meta_->name);
|
||||
delete mem;
|
||||
mem = nullptr;
|
||||
}
|
||||
if (!cell) {
|
||||
if (memid.empty())
|
||||
memid = NEW_ID;
|
||||
cell = module->addCell(memid, ID($mem_v2));
|
||||
cell = module->addCell(Twine{memid.str()}, ID($mem_v2));
|
||||
}
|
||||
cell->type = ID($mem_v2);
|
||||
cell->attributes = attributes;
|
||||
|
|
@ -292,10 +292,7 @@ void Mem::emit() {
|
|||
if (!mem) {
|
||||
if (memid.empty())
|
||||
memid = NEW_ID;
|
||||
mem = new RTLIL::Memory;
|
||||
mem->name = memid;
|
||||
mem->module = module;
|
||||
module->memories[memid] = mem;
|
||||
mem = module->addMemory(Twine{memid.str()});
|
||||
}
|
||||
mem->width = width;
|
||||
mem->start_offset = start_offset;
|
||||
|
|
@ -562,14 +559,14 @@ namespace {
|
|||
};
|
||||
|
||||
Mem mem_from_memory(Module *module, RTLIL::Memory *mem, const MemIndex &index) {
|
||||
Mem res(module, mem->name, mem->width, mem->start_offset, mem->size);
|
||||
Mem res(module, RTLIL::IdString(module->design->twines.str(mem->meta_->name)), mem->width, mem->start_offset, mem->size);
|
||||
res.packed = false;
|
||||
res.mem = mem;
|
||||
res.attributes = mem->attributes;
|
||||
std::vector<bool> rd_transparent;
|
||||
std::vector<int> wr_portid;
|
||||
if (index.rd_ports.count(mem->name)) {
|
||||
for (auto cell : index.rd_ports.at(mem->name)) {
|
||||
if (index.rd_ports.count(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);
|
||||
mrd.cell = cell;
|
||||
|
|
@ -611,9 +608,9 @@ namespace {
|
|||
rd_transparent.push_back(transparent);
|
||||
}
|
||||
}
|
||||
if (index.wr_ports.count(mem->name)) {
|
||||
if (index.wr_ports.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
|
||||
std::vector<std::pair<int, MemWr>> ports;
|
||||
for (auto cell : index.wr_ports.at(mem->name)) {
|
||||
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);
|
||||
mwr.cell = cell;
|
||||
|
|
@ -656,9 +653,9 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (index.inits.count(mem->name)) {
|
||||
if (index.inits.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
|
||||
std::vector<std::pair<int, MemInit>> inits;
|
||||
for (auto cell : index.inits.at(mem->name)) {
|
||||
for (auto cell : index.inits.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
|
||||
MemInit init;
|
||||
init.cell = cell;
|
||||
init.attributes = cell->attributes;
|
||||
|
|
@ -933,7 +930,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
|
||||
if (width)
|
||||
{
|
||||
SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid, idx), width);
|
||||
SigSpec sig_q = module->addWire(Twine{stringf("$%s$rdreg[%d]$q", memid, idx)}, width);
|
||||
SigSpec sig_d;
|
||||
|
||||
int pos = 0;
|
||||
|
|
@ -943,7 +940,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
port.addr[i] = sig_q[pos++];
|
||||
}
|
||||
|
||||
c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity, mem_src);
|
||||
c = module->addDff(Twine{stringf("$%s$rdreg[%d]", memid, idx)}, port.clk, sig_d, sig_q, port.clk_polarity, mem_src);
|
||||
} else {
|
||||
c = nullptr;
|
||||
}
|
||||
|
|
@ -952,7 +949,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
{
|
||||
log_assert(port.arst == State::S0 || port.srst == State::S0);
|
||||
|
||||
SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid, idx), GetSize(port.data));
|
||||
SigSpec async_d = module->addWire(Twine{stringf("$%s$rdreg[%d]$d", memid, idx)}, GetSize(port.data));
|
||||
SigSpec sig_d = async_d;
|
||||
|
||||
for (int i = 0; i < GetSize(wr_ports); i++) {
|
||||
|
|
@ -975,7 +972,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
raddr = port.sub_addr(sub);
|
||||
SigSpec addr_eq;
|
||||
if (raddr != waddr)
|
||||
addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr, false, mem_src);
|
||||
addr_eq = module->Eq(Twine{stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub)}, raddr, waddr, false, mem_src);
|
||||
int pos = 0;
|
||||
int ewidth = width << min_wide_log2;
|
||||
int wsub = wide_write ? sub : 0;
|
||||
|
|
@ -988,10 +985,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos);
|
||||
SigSpec cond;
|
||||
if (raddr != waddr)
|
||||
cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq, false, mem_src);
|
||||
cond = module->And(Twine{stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos)}, wport.en[pos + wsub * width], addr_eq, false, mem_src);
|
||||
else
|
||||
cond = wport.en[pos + wsub * width];
|
||||
SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond, mem_src);
|
||||
SigSpec merged = module->Mux(Twine{stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos)}, cur, other, cond, mem_src);
|
||||
sig_d.replace(pos + rsub * width, merged);
|
||||
pos = epos;
|
||||
}
|
||||
|
|
@ -1140,7 +1137,7 @@ void Mem::emulate_priority(int idx1, int idx2, FfInitVals *initvals)
|
|||
addr1 = port1.sub_addr(sub);
|
||||
else
|
||||
addr2 = port2.sub_addr(sub);
|
||||
SigSpec addr_eq = module->Eq(NEW_ID, addr1, addr2);
|
||||
SigSpec addr_eq = module->Eq(NEW_TWINE, addr1, addr2);
|
||||
int ewidth = width << min_wide_log2;
|
||||
int sub1 = wide1 ? sub : 0;
|
||||
int sub2 = wide1 ? 0 : sub;
|
||||
|
|
@ -1152,9 +1149,9 @@ void Mem::emulate_priority(int idx1, int idx2, FfInitVals *initvals)
|
|||
if (cache.count(key)) {
|
||||
en1 = cache[key];
|
||||
} else {
|
||||
SigBit active2 = module->And(NEW_ID, addr_eq, en2);
|
||||
SigBit nactive2 = module->Not(NEW_ID, active2);
|
||||
en1 = cache[key] = module->And(NEW_ID, en1, nactive2);
|
||||
SigBit active2 = module->And(NEW_TWINE, addr_eq, en2);
|
||||
SigBit nactive2 = module->Not(NEW_TWINE, active2);
|
||||
en1 = cache[key] = module->And(NEW_TWINE, en1, nactive2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1179,7 +1176,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
|
|||
// the mux whenever this would be relevant. It does, however, need to have the same
|
||||
// clock enable signal as the read port.
|
||||
SigSpec wdata_q = module->addWire(NEW_TWINE, GetSize(wport.data));
|
||||
module->addDffe(NEW_ID, rport.clk, rport.en, wport.data, wdata_q, rport.clk_polarity, true);
|
||||
module->addDffe(NEW_TWINE, rport.clk, rport.en, wport.data, wdata_q, rport.clk_polarity, true);
|
||||
for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) {
|
||||
SigSpec raddr = rport.addr;
|
||||
SigSpec waddr = wport.addr;
|
||||
|
|
@ -1190,7 +1187,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
|
|||
raddr = rport.sub_addr(sub);
|
||||
SigSpec addr_eq;
|
||||
if (raddr != waddr)
|
||||
addr_eq = module->Eq(NEW_ID, raddr, waddr);
|
||||
addr_eq = module->Eq(NEW_TWINE, raddr, waddr);
|
||||
int pos = 0;
|
||||
int ewidth = width << min_wide_log2;
|
||||
int wsub = wide_write ? sub : 0;
|
||||
|
|
@ -1202,7 +1199,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
|
|||
epos++;
|
||||
SigSpec cond;
|
||||
if (raddr != waddr)
|
||||
cond = module->And(NEW_ID, wport.en[pos + wsub * width], addr_eq);
|
||||
cond = module->And(NEW_TWINE, wport.en[pos + wsub * width], addr_eq);
|
||||
else
|
||||
cond = wport.en[pos + wsub * width];
|
||||
SigSpec cond_q = module->addWire(NEW_TWINE);
|
||||
|
|
@ -1243,7 +1240,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
|
|||
SigSpec cur = rdata_a.extract(pos, epos-pos);
|
||||
SigSpec other = wdata_q.extract(pos + wsub * width, epos-pos);
|
||||
SigSpec dest = rport.data.extract(pos + rsub * width, epos-pos);
|
||||
module->addMux(NEW_ID, cur, other, cond_q, dest);
|
||||
module->addMux(NEW_TWINE, cur, other, cond_q, dest);
|
||||
pos = epos;
|
||||
}
|
||||
rport.data.replace(rsub * width, rdata_a);
|
||||
|
|
@ -1389,8 +1386,8 @@ void Mem::widen_wr_port(int idx, int wide_log2) {
|
|||
} else {
|
||||
// May or may not write to this subword.
|
||||
new_data.append(port.data);
|
||||
SigSpec addr_eq = module->Eq(NEW_ID, addr_lo, cur_addr_lo);
|
||||
SigSpec en = module->Mux(NEW_ID, Const(State::S0, GetSize(port.data)), port.en, addr_eq);
|
||||
SigSpec addr_eq = module->Eq(NEW_TWINE, addr_lo, cur_addr_lo);
|
||||
SigSpec en = module->Mux(NEW_TWINE, Const(State::S0, GetSize(port.data)), port.en, addr_eq);
|
||||
new_en.append(en);
|
||||
}
|
||||
}
|
||||
|
|
@ -1457,7 +1454,7 @@ void Mem::emulate_rden(int idx, FfInitVals *initvals) {
|
|||
}
|
||||
ff_sel.emit();
|
||||
ff_data.emit();
|
||||
module->addMux(NEW_ID, prev_data, new_data, sel, port.data);
|
||||
module->addMux(NEW_TWINE, prev_data, new_data, sel, port.data);
|
||||
port.data = new_data;
|
||||
port.en = State::S1;
|
||||
}
|
||||
|
|
@ -1506,7 +1503,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
|
|||
}
|
||||
}
|
||||
ff_sel.emit();
|
||||
module->addMux(NEW_ID, port.init_value, new_data, sel, port.data);
|
||||
module->addMux(NEW_TWINE, port.init_value, new_data, sel, port.data);
|
||||
port.data = new_data;
|
||||
port.init_value = Const(State::Sx, GetSize(port.data));
|
||||
}
|
||||
|
|
@ -1546,7 +1543,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
|
|||
}
|
||||
}
|
||||
ff_sel.emit();
|
||||
module->addMux(NEW_ID, port.arst_value, new_data, sel, port.data);
|
||||
module->addMux(NEW_TWINE, port.arst_value, new_data, sel, port.data);
|
||||
port.data = new_data;
|
||||
port.arst = State::S0;
|
||||
}
|
||||
|
|
@ -1581,7 +1578,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
|
|||
ff_sel.val_arst = State::S1;
|
||||
}
|
||||
ff_sel.emit();
|
||||
module->addMux(NEW_ID, port.srst_value, new_data, sel, port.data);
|
||||
module->addMux(NEW_TWINE, port.srst_value, new_data, sel, port.data);
|
||||
port.data = new_data;
|
||||
port.srst = State::S0;
|
||||
}
|
||||
|
|
@ -1595,7 +1592,7 @@ void Mem::emulate_rd_ce_over_srst(int idx) {
|
|||
return;
|
||||
}
|
||||
port.ce_over_srst = false;
|
||||
port.srst = module->And(NEW_ID, port.en, port.srst);
|
||||
port.srst = module->And(NEW_TWINE, port.en, port.srst);
|
||||
}
|
||||
|
||||
void Mem::emulate_rd_srst_over_ce(int idx) {
|
||||
|
|
@ -1606,7 +1603,7 @@ void Mem::emulate_rd_srst_over_ce(int idx) {
|
|||
return;
|
||||
}
|
||||
port.ce_over_srst = true;
|
||||
port.en = module->Or(NEW_ID, port.en, port.srst);
|
||||
port.en = module->Or(NEW_TWINE, port.en, port.srst);
|
||||
}
|
||||
|
||||
bool Mem::emulate_read_first_ok() {
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ struct NewCellTypes {
|
|||
if (wire->port_output)
|
||||
outputs.insert(wire->meta_->name);
|
||||
}
|
||||
setup_type(module->name, inputs, outputs);
|
||||
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
|
||||
}
|
||||
|
||||
void setup_type(RTLIL::IdString type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) {
|
||||
|
|
|
|||
|
|
@ -305,8 +305,8 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
|
|||
|
||||
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
|
||||
{
|
||||
std::string backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module.clear();
|
||||
TwineRef backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = Twine::Null;
|
||||
design->push_selection(selection);
|
||||
|
||||
Pass::call(design, command);
|
||||
|
|
@ -317,8 +317,8 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele
|
|||
|
||||
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::vector<std::string> args)
|
||||
{
|
||||
std::string backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module.clear();
|
||||
TwineRef backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = Twine::Null;
|
||||
design->push_selection(selection);
|
||||
|
||||
Pass::call(design, args);
|
||||
|
|
@ -329,8 +329,8 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele
|
|||
|
||||
void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
|
||||
{
|
||||
std::string backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = module->name.str();
|
||||
TwineRef backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = module->meta_->name;
|
||||
design->push_empty_selection();
|
||||
design->select(module);
|
||||
|
||||
|
|
@ -342,8 +342,8 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str
|
|||
|
||||
void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector<std::string> args)
|
||||
{
|
||||
std::string backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = module->name.str();
|
||||
TwineRef backup_selected_active_module = design->selected_active_module;
|
||||
design->selected_active_module = module->meta_->name;
|
||||
design->push_empty_selection();
|
||||
design->select(module);
|
||||
|
||||
|
|
@ -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(input.str());
|
||||
inputs.push_back(RTLIL::IdString((RTLIL::StaticId)input).str());
|
||||
json.name("inputs"); json.value(inputs);
|
||||
for (auto &output : ct.outputs)
|
||||
outputs.push_back(output.str());
|
||||
outputs.push_back(RTLIL::IdString((RTLIL::StaticId)output).str());
|
||||
json.name("outputs"); json.value(outputs);
|
||||
vector<string> properties;
|
||||
// CellType properties
|
||||
|
|
|
|||
124
kernel/rtlil.cc
124
kernel/rtlil.cc
|
|
@ -196,9 +196,10 @@ struct IdStringCollector {
|
|||
trace(selection_var.selected_modules);
|
||||
trace(selection_var.selected_members);
|
||||
}
|
||||
void trace_named(const RTLIL::NamedObject &named) {
|
||||
void trace_named(const RTLIL::AttrObject &named) {
|
||||
trace_keys(named.attributes);
|
||||
trace(named.name);
|
||||
if (named.meta_)
|
||||
trace(named.meta_->name);
|
||||
}
|
||||
void trace(const RTLIL::Wire &wire) {
|
||||
trace_named(wire);
|
||||
|
|
@ -1548,6 +1549,7 @@ RTLIL::Module *RTLIL::Design::addModule(TwineRef name)
|
|||
RTLIL::Module *module = new RTLIL::Module;
|
||||
modules_[name] = module;
|
||||
module->design = this;
|
||||
module->meta_ = alloc_obj_meta();
|
||||
module->meta_->name = name;
|
||||
|
||||
for (auto mon : monitors)
|
||||
|
|
@ -1938,7 +1940,7 @@ void RTLIL::Module::makeblackbox()
|
|||
|
||||
void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
|
||||
{
|
||||
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", name.unescape());
|
||||
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", design->twines.str(meta_->name).c_str());
|
||||
}
|
||||
|
||||
bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
|
||||
|
|
@ -1950,7 +1952,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
|
|||
{
|
||||
if (mayfail)
|
||||
return IdString();
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1958,13 +1960,12 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
|
|||
{
|
||||
if (mayfail)
|
||||
return IdString();
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
|
||||
}
|
||||
|
||||
size_t RTLIL::Module::count_id(TwineRef id)
|
||||
{
|
||||
IdString sid(design->twines.str(id));
|
||||
return wires_.count(id) + cells_.count(id) + memories.count(sid) + processes.count(sid);
|
||||
return wires_.count(id) + cells_.count(id) + memories.count(id) + processes.count(id);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -1983,9 +1984,11 @@ namespace {
|
|||
std::stringstream buf;
|
||||
RTLIL_BACKEND::dump_cell(buf, " ", cell);
|
||||
|
||||
std::string mod_name = module ? module->design->twines.str(module->meta_->name) : std::string();
|
||||
std::string cell_name = cell->module->design->twines.str(cell->meta_->name);
|
||||
log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
|
||||
module ? module->name.c_str() : "", module ? "." : "",
|
||||
cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
|
||||
mod_name.c_str(), module ? "." : "",
|
||||
cell_name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
|
||||
}
|
||||
|
||||
int param(IdString name)
|
||||
|
|
@ -2951,8 +2954,8 @@ void RTLIL::Module::sort()
|
|||
wires_.sort(sort_twine_by_str);
|
||||
cells_.sort(sort_twine_by_str);
|
||||
parameter_default_values.sort(sort_by_id_str());
|
||||
memories.sort(sort_by_id_str());
|
||||
processes.sort(sort_by_id_str());
|
||||
memories.sort(sort_twine_by_str);
|
||||
processes.sort(sort_twine_by_str);
|
||||
for (auto &it : cells_)
|
||||
it.second->sort();
|
||||
for (auto &it : wires_)
|
||||
|
|
@ -2969,13 +2972,13 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool
|
|||
|
||||
pool<std::string> memory_strings;
|
||||
for (auto &it : module->memories) {
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->meta_ && it.first == it.second->meta_->name);
|
||||
log_assert(it.first != Twine::Null);
|
||||
log_assert(it.second->width >= 0);
|
||||
log_assert(it.second->size >= 0);
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
memory_strings.insert(it.second->name.str());
|
||||
memory_strings.insert(module->design->twines.str(it.second->meta_->name));
|
||||
}
|
||||
|
||||
std::vector<MonotonicFlag> ports_declared(GetSize(module->ports));
|
||||
|
|
@ -3047,8 +3050,8 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool
|
|||
log_assert(memids_pool.insert(memid).second);
|
||||
|
||||
for (auto &it : module->processes) {
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->meta_ && it.first == it.second->meta_->name);
|
||||
log_assert(it.first != Twine::Null);
|
||||
log_assert(it.second->root_case.compare.empty());
|
||||
std::vector<RTLIL::CaseRule*> all_cases = {&it.second->root_case};
|
||||
for (size_t i = 0; i < all_cases.size(); i++) {
|
||||
|
|
@ -3172,7 +3175,8 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
}
|
||||
for (auto it = memories.rbegin(); it != memories.rend(); ++it) {
|
||||
const RTLIL::Memory *o = it->second;
|
||||
RTLIL::Memory *m = new_mod->addMemory(it->first);
|
||||
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
RTLIL::Memory *m = new_mod->addMemory(dst_name);
|
||||
m->width = o->width;
|
||||
m->start_offset = o->start_offset;
|
||||
m->size = o->size;
|
||||
|
|
@ -3190,8 +3194,11 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
}
|
||||
for (auto it = processes.rbegin(); it != processes.rend(); ++it) {
|
||||
const RTLIL::Process *o = it->second;
|
||||
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
RTLIL::Process *p = o->clone();
|
||||
p->name = it->first;
|
||||
if (!p->meta_)
|
||||
p->meta_ = new_mod->design->alloc_obj_meta();
|
||||
p->meta_->name = dst_name;
|
||||
new_mod->add(p);
|
||||
copy_meta(o, p);
|
||||
std::vector<std::pair<const RTLIL::CaseRule*, RTLIL::CaseRule*>> case_stack;
|
||||
|
|
@ -3236,16 +3243,20 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
new_mod->addWire(dst_id, it->second);
|
||||
}
|
||||
|
||||
for (auto it = memories.rbegin(); it != memories.rend(); ++it)
|
||||
new_mod->addMemory(it->first, it->second);
|
||||
for (auto it = memories.rbegin(); it != memories.rend(); ++it) {
|
||||
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
new_mod->addMemory(dst_id, it->second);
|
||||
}
|
||||
|
||||
for (auto it = cells_.rbegin(); it != cells_.rend(); ++it) {
|
||||
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
new_mod->addCell(dst_id, it->second);
|
||||
}
|
||||
|
||||
for (auto it = processes.rbegin(); it != processes.rend(); ++it)
|
||||
new_mod->addProcess(it->first, it->second);
|
||||
for (auto it = processes.rbegin(); it != processes.rend(); ++it) {
|
||||
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
new_mod->addProcess(dst_id, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
struct RewriteSigSpecWorker
|
||||
|
|
@ -3272,7 +3283,8 @@ RTLIL::Module *RTLIL::Module::clone() const
|
|||
{
|
||||
RTLIL::Module *new_mod = new RTLIL::Module;
|
||||
new_mod->design = design;
|
||||
new_mod->name = name;
|
||||
new_mod->meta_ = design->alloc_obj_meta();
|
||||
new_mod->meta_->name = meta_->name;
|
||||
cloneInto(new_mod);
|
||||
return new_mod;
|
||||
}
|
||||
|
|
@ -3281,7 +3293,8 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, bool src_id_verbatim) co
|
|||
{
|
||||
RTLIL::Module *new_mod = new RTLIL::Module;
|
||||
new_mod->design = dst;
|
||||
new_mod->name = name;
|
||||
new_mod->meta_ = dst->alloc_obj_meta();
|
||||
new_mod->meta_->name = dst->twines.copy_from(design->twines, meta_->name);
|
||||
cloneInto(new_mod, src_id_verbatim);
|
||||
dst->add(new_mod);
|
||||
return new_mod;
|
||||
|
|
@ -3291,7 +3304,8 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, RTLIL::IdString target_n
|
|||
{
|
||||
RTLIL::Module *new_mod = new RTLIL::Module;
|
||||
new_mod->design = dst;
|
||||
new_mod->name = target_name;
|
||||
new_mod->meta_ = dst->alloc_obj_meta();
|
||||
new_mod->meta_->name = dst->twines.add(Twine{target_name.str()});
|
||||
cloneInto(new_mod, src_id_verbatim);
|
||||
dst->add(new_mod);
|
||||
return new_mod;
|
||||
|
|
@ -3371,9 +3385,9 @@ std::vector<RTLIL::Process*> RTLIL::Module::selected_processes() const
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<RTLIL::NamedObject*> RTLIL::Module::selected_members() const
|
||||
std::vector<RTLIL::AttrObject*> RTLIL::Module::selected_members() const
|
||||
{
|
||||
std::vector<RTLIL::NamedObject*> result;
|
||||
std::vector<RTLIL::AttrObject*> result;
|
||||
auto cells = selected_cells();
|
||||
auto memories = selected_memories();
|
||||
auto wires = selected_wires();
|
||||
|
|
@ -3407,9 +3421,9 @@ void RTLIL::Module::add(RTLIL::Cell *cell)
|
|||
|
||||
void RTLIL::Module::add(RTLIL::Process *process)
|
||||
{
|
||||
log_assert(!process->name.empty());
|
||||
log_assert(count_id(design->twines.lookup(process->name.str())) == 0);
|
||||
processes[process->name] = process;
|
||||
log_assert(process->meta_ && process->meta_->name != Twine::Null);
|
||||
log_assert(count_id(process->meta_->name) == 0);
|
||||
processes[process->meta_->name] = process;
|
||||
process->module = this;
|
||||
// Propagate module back-pointer to every CaseRule/SwitchRule in the
|
||||
// root case tree and every MemWriteAction in the sync rules — so the
|
||||
|
|
@ -3476,15 +3490,15 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
|
|||
|
||||
void RTLIL::Module::remove(RTLIL::Memory *memory)
|
||||
{
|
||||
log_assert(memories.count(memory->name) != 0);
|
||||
memories.erase(memory->name);
|
||||
log_assert(memory->meta_ && memories.count(memory->meta_->name) != 0);
|
||||
memories.erase(memory->meta_->name);
|
||||
delete memory;
|
||||
}
|
||||
|
||||
void RTLIL::Module::remove(RTLIL::Process *process)
|
||||
{
|
||||
log_assert(processes.count(process->name) != 0);
|
||||
processes.erase(process->name);
|
||||
log_assert(process->meta_ && processes.count(process->meta_->name) != 0);
|
||||
processes.erase(process->meta_->name);
|
||||
delete process;
|
||||
}
|
||||
|
||||
|
|
@ -3729,20 +3743,30 @@ RTLIL::Cell *RTLIL::Module::addCell(Twine &&name, const RTLIL::Cell *other)
|
|||
return addCell(design->twines.add(std::move(name)), other);
|
||||
}
|
||||
|
||||
RTLIL::Memory *RTLIL::Module::addMemory(IdString name)
|
||||
RTLIL::Memory *RTLIL::Module::addMemory(TwineRef name)
|
||||
{
|
||||
log_assert(design);
|
||||
RTLIL::Memory *mem = new RTLIL::Memory;
|
||||
mem->name = std::move(name);
|
||||
mem->module = this;
|
||||
memories[mem->name] = mem;
|
||||
mem->meta_ = design->alloc_obj_meta();
|
||||
mem->meta_->name = name;
|
||||
memories[name] = mem;
|
||||
return mem;
|
||||
}
|
||||
|
||||
RTLIL::Memory *RTLIL::Module::addMemory(IdString name, const RTLIL::Memory *other)
|
||||
RTLIL::Memory *RTLIL::Module::addMemory(Twine &&name)
|
||||
{
|
||||
log_assert(design);
|
||||
return addMemory(design->twines.add(std::move(name)));
|
||||
}
|
||||
|
||||
RTLIL::Memory *RTLIL::Module::addMemory(TwineRef name, const RTLIL::Memory *other)
|
||||
{
|
||||
log_assert(design);
|
||||
RTLIL::Memory *mem = new RTLIL::Memory;
|
||||
mem->name = std::move(name);
|
||||
mem->module = this;
|
||||
mem->meta_ = design->alloc_obj_meta();
|
||||
mem->meta_->name = name;
|
||||
mem->width = other->width;
|
||||
mem->start_offset = other->start_offset;
|
||||
mem->size = other->size;
|
||||
|
|
@ -3753,18 +3777,26 @@ RTLIL::Memory *RTLIL::Module::addMemory(IdString name, const RTLIL::Memory *othe
|
|||
// common case.
|
||||
(void)other;
|
||||
}
|
||||
memories[mem->name] = mem;
|
||||
memories[name] = mem;
|
||||
return mem;
|
||||
}
|
||||
|
||||
RTLIL::Process *RTLIL::Module::addProcess(IdString name)
|
||||
RTLIL::Process *RTLIL::Module::addProcess(TwineRef name)
|
||||
{
|
||||
log_assert(design);
|
||||
RTLIL::Process *proc = new RTLIL::Process;
|
||||
proc->name = std::move(name);
|
||||
proc->meta_ = design->alloc_obj_meta();
|
||||
proc->meta_->name = name;
|
||||
add(proc);
|
||||
return proc;
|
||||
}
|
||||
|
||||
RTLIL::Process *RTLIL::Module::addProcess(Twine &&name)
|
||||
{
|
||||
log_assert(design);
|
||||
return addProcess(design->twines.add(std::move(name)));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Walk two process trees in parallel and transfer src across the
|
||||
// design boundary for every AttrObject (CaseRule, SwitchRule,
|
||||
|
|
@ -3806,10 +3838,13 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
RTLIL::Process *RTLIL::Module::addProcess(IdString name, const RTLIL::Process *other)
|
||||
RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *other)
|
||||
{
|
||||
log_assert(design);
|
||||
RTLIL::Process *proc = other->clone();
|
||||
proc->name = std::move(name);
|
||||
if (!proc->meta_)
|
||||
proc->meta_ = design->alloc_obj_meta();
|
||||
proc->meta_->name = name;
|
||||
add(proc);
|
||||
// Migrate src across the design boundary for the inner-process tree.
|
||||
// Process::clone drops src on CaseRule/SwitchRule/MemWriteAction since
|
||||
|
|
@ -6747,7 +6782,6 @@ RTLIL::Process *RTLIL::Process::clone() const
|
|||
{
|
||||
RTLIL::Process *new_proc = new RTLIL::Process;
|
||||
|
||||
new_proc->name = name;
|
||||
new_proc->attributes = attributes;
|
||||
// clone() drops src across the whole tree; the caller is responsible
|
||||
// for migrating src via context after the clone has a module.
|
||||
|
|
|
|||
|
|
@ -1951,8 +1951,8 @@ struct RTLIL::Selection
|
|||
|
||||
// add member of module to this selection
|
||||
template<typename T1, typename T2> void select(T1 *module, T2 *member) {
|
||||
if (!selects_all() && selected_modules.count(module->name) == 0) {
|
||||
selected_members[module->name].insert(member->name);
|
||||
if (!selects_all() && selected_modules.count(module->meta_->name) == 0) {
|
||||
selected_members[module->meta_->name].insert(member->meta_->name);
|
||||
if (module->get_blackbox_attribute())
|
||||
selects_boxes = true;
|
||||
}
|
||||
|
|
@ -2921,13 +2921,13 @@ struct RTLIL::ModuleNameMasq {
|
|||
bool operator!=(const ModuleNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); }
|
||||
};
|
||||
|
||||
struct RTLIL::Module : public RTLIL::NamedObject, public CellAdderMixin<RTLIL::Module>
|
||||
struct RTLIL::Module : public RTLIL::AttrObject, public CellAdderMixin<RTLIL::Module>
|
||||
{
|
||||
friend struct RTLIL::SigNormIndex;
|
||||
friend struct RTLIL::Cell;
|
||||
friend struct RTLIL::Design;
|
||||
|
||||
// [[no_unique_address]] RTLIL::ModuleNameMasq name;
|
||||
[[no_unique_address]] RTLIL::ModuleNameMasq name;
|
||||
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
|
@ -2952,8 +2952,8 @@ public:
|
|||
|
||||
idict<RTLIL::IdString> avail_parameters;
|
||||
dict<RTLIL::IdString, RTLIL::Const> parameter_default_values;
|
||||
dict<RTLIL::IdString, RTLIL::Memory*> memories;
|
||||
dict<RTLIL::IdString, RTLIL::Process*> processes;
|
||||
dict<TwineRef, RTLIL::Memory*> memories;
|
||||
dict<TwineRef, RTLIL::Process*> processes;
|
||||
|
||||
// Context-aware src helpers. Resolve Design via this->design and
|
||||
// route to the per-Design meta vector; assert the module is attached.
|
||||
|
|
@ -3053,7 +3053,7 @@ public:
|
|||
std::vector<RTLIL::Cell*> selected_cells() const;
|
||||
std::vector<RTLIL::Memory*> selected_memories() const;
|
||||
std::vector<RTLIL::Process*> selected_processes() const;
|
||||
std::vector<RTLIL::NamedObject*> selected_members() const;
|
||||
std::vector<RTLIL::AttrObject*> selected_members() const;
|
||||
|
||||
template<typename T> bool selected(T *member) const {
|
||||
return design->selected_member(meta_->name, member->meta_->name);
|
||||
|
|
@ -3122,11 +3122,13 @@ public:
|
|||
return design->twines.add(Twine{Twine::Suffix{pref, std::to_string(autoidx++)}});
|
||||
}
|
||||
|
||||
RTLIL::Memory *addMemory(RTLIL::IdString name);
|
||||
RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other);
|
||||
RTLIL::Memory *addMemory(TwineRef name);
|
||||
RTLIL::Memory *addMemory(Twine &&name);
|
||||
RTLIL::Memory *addMemory(TwineRef name, const RTLIL::Memory *other);
|
||||
|
||||
RTLIL::Process *addProcess(RTLIL::IdString name);
|
||||
RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other);
|
||||
RTLIL::Process *addProcess(TwineRef name);
|
||||
RTLIL::Process *addProcess(Twine &&name);
|
||||
RTLIL::Process *addProcess(TwineRef name, const RTLIL::Process *other);
|
||||
|
||||
// The add* methods create a cell and return the created cell. All signals must exist in advance.
|
||||
|
||||
|
|
@ -3298,18 +3300,6 @@ inline RTLIL::CellNameMasq::operator RTLIL::IdString() const {
|
|||
return RTLIL::IdString(c->module->design->twines.flat_string(id));
|
||||
}
|
||||
|
||||
inline RTLIL::ModuleNameMasq::operator RTLIL::IdString() const {
|
||||
const RTLIL::Module *m = reinterpret_cast<const RTLIL::Module*>(
|
||||
reinterpret_cast<const char*>(this) - offsetof(RTLIL::Module, name));
|
||||
return m->design ? m->design->obj_name(m) : std::string();
|
||||
}
|
||||
|
||||
inline RTLIL::ModuleNameMasq::operator TwineRef() const {
|
||||
const RTLIL::Module *m = reinterpret_cast<const RTLIL::Module*>(
|
||||
reinterpret_cast<const char*>(this) - offsetof(RTLIL::Module, name));
|
||||
return m->design ? m->design->obj_src_id(m) : Twine::Null;
|
||||
}
|
||||
|
||||
// inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) {
|
||||
// RTLIL::Module *m = reinterpret_cast<RTLIL::Module*>(
|
||||
// reinterpret_cast<char*>(this) - offsetof(RTLIL::Module, name));
|
||||
|
|
|
|||
|
|
@ -1283,7 +1283,7 @@ void RTLIL::Cell::setPort(TwineRef portname, RTLIL::SigSpec signal)
|
|||
}
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# Connect %s.%s.%s = %s (%d)\n", module ? module->name.unescape() : "PATCH", this, module->design->twines.str(portname), log_signal(signal), GetSize(signal));
|
||||
log("#X# Connect %s.%s.%s = %s (%d)\n", module ? log_id(module) : "PATCH", this, module->design->twines.str(portname).c_str(), log_signal(signal), GetSize(signal));
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -270,11 +270,11 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
|||
auto obj_twine = search.find(obj_id);
|
||||
obj = mod->wire(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->memories.at(obj_id, nullptr);
|
||||
obj = mod->memories.at(obj_twine, nullptr);
|
||||
if (!obj)
|
||||
obj = mod->cell(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->processes.at(obj_id, nullptr);
|
||||
obj = mod->processes.at(obj_twine, nullptr);
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
|
|
@ -335,11 +335,11 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
|||
auto obj_twine = search.find(obj_id);
|
||||
obj = mod->wire(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->memories.at(obj_id, nullptr);
|
||||
obj = mod->memories.at(obj_twine, nullptr);
|
||||
if (!obj)
|
||||
obj = mod->cell(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->processes.at(obj_id, nullptr);
|
||||
obj = mod->processes.at(obj_twine, nullptr);
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
|
|
@ -390,11 +390,11 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
|
|||
auto obj_twine = search.find(obj_id);
|
||||
obj = mod->wire(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->memories.at(obj_id, nullptr);
|
||||
obj = mod->memories.at(obj_twine, nullptr);
|
||||
if (!obj)
|
||||
obj = mod->cell(obj_twine);
|
||||
if (!obj)
|
||||
obj = mod->processes.at(obj_id, nullptr);
|
||||
obj = mod->processes.at(obj_twine, nullptr);
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
|
|
|
|||
|
|
@ -37,9 +37,10 @@ struct TimingInfo
|
|||
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) {
|
||||
if (!cell->hasPort(name))
|
||||
TwineRef port_name = cell->module->design->twines.lookup(name.str());
|
||||
if (!cell->hasPort(port_name))
|
||||
return {};
|
||||
auto &port = cell->getPort(name);
|
||||
auto &port = cell->getPort(port_name);
|
||||
if (offset >= port.size())
|
||||
return {};
|
||||
return port[offset];
|
||||
|
|
@ -92,7 +93,7 @@ struct TimingInfo
|
|||
|
||||
const ModuleTiming& setup_module(RTLIL::Module *module)
|
||||
{
|
||||
auto r = data.insert(module->name);
|
||||
auto r = data.insert(RTLIL::IdString(module->design->twines.str(module->meta_->name)));
|
||||
log_assert(r.second);
|
||||
auto &t = r.first->second;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ inline std::pair<SigSpec, SigSpec> emit_fa(Module *module, SigSpec a, SigSpec b,
|
|||
SigSpec sum = module->addWire(NEW_TWINE, width);
|
||||
SigSpec cout = module->addWire(NEW_TWINE, width);
|
||||
|
||||
module->addFa(NEW_ID, a, b, c, cout, sum);
|
||||
module->addFa(NEW_TWINE, a, b, c, cout, sum);
|
||||
|
||||
SigSpec carry;
|
||||
carry.append(State::S0);
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ void yosys_setup()
|
|||
already_shutdown = false;
|
||||
|
||||
IdString::ensure_prepopulated();
|
||||
Twine::ensure_prepopulated();
|
||||
twine_prepopulate();
|
||||
|
||||
#ifdef YOSYS_ENABLE_PYTHON
|
||||
// Starting Python 3.12, calling PyImport_AppendInittab on an already
|
||||
|
|
@ -364,13 +364,13 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter)
|
|||
if (recursion_counter > 1)
|
||||
str += stringf("(%d) ", recursion_counter);
|
||||
str += "yosys";
|
||||
if (!design->selected_active_module.empty())
|
||||
str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module));
|
||||
if (design->selected_active_module != Twine::Null)
|
||||
str += stringf(" [%s]", RTLIL::unescape_id(design->twines.str(design->selected_active_module)).c_str());
|
||||
if (!design->full_selection()) {
|
||||
if (design->selected_active_module.empty())
|
||||
if (design->selected_active_module == Twine::Null)
|
||||
str += "*";
|
||||
else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 ||
|
||||
design->selection().selected_modules.count(design->twines.intern(design->selected_active_module)) == 0)
|
||||
design->selection().selected_modules.count(design->selected_active_module) == 0)
|
||||
str += "*";
|
||||
}
|
||||
snprintf(buffer, 100, "%s> ", str.c_str());
|
||||
|
|
@ -951,11 +951,13 @@ static char *readline_obj_generator(const char *text, int state)
|
|||
RTLIL::Design *design = yosys_get_design();
|
||||
int len = strlen(text);
|
||||
|
||||
if (design->selected_active_module.empty())
|
||||
if (design->selected_active_module == Twine::Null)
|
||||
{
|
||||
for (auto mod : design->modules())
|
||||
if (mod->name.unescape().compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(mod->name.unescape().c_str()));
|
||||
for (auto mod : design->modules()) {
|
||||
std::string mod_name = design->twines.str(mod->meta_->name);
|
||||
if (mod_name.compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(mod_name.c_str()));
|
||||
}
|
||||
}
|
||||
else if (design->module(design->selected_active_module) != nullptr)
|
||||
{
|
||||
|
|
@ -965,17 +967,21 @@ static char *readline_obj_generator(const char *text, int state)
|
|||
if (w->name.unescape().compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(w->name.unescape().c_str()));
|
||||
|
||||
for (auto &it : module->memories)
|
||||
if (it.first.unescape().compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(it.first.unescape().c_str()));
|
||||
for (auto &it : module->memories) {
|
||||
std::string mem_name = design->twines.str(it.first);
|
||||
if (mem_name.compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(mem_name.c_str()));
|
||||
}
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (cell->name.unescape().compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(cell->name.unescape().c_str()));
|
||||
if (cell->module->design->twines.str(cell->meta_->name).compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(cell->module->design->twines.str(cell->meta_->name).c_str()));
|
||||
|
||||
for (auto &it : module->processes)
|
||||
if (it.first.unescape().compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(it.first.unescape().c_str()));
|
||||
for (auto &it : module->processes) {
|
||||
std::string proc_name = design->twines.str(it.first);
|
||||
if (proc_name.compare(0, len, text) == 0)
|
||||
obj_names.push_back(strdup(proc_name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(obj_names.begin(), obj_names.end());
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ OBJS += passes/cmds/tee.o
|
|||
OBJS += passes/cmds/write_file.o
|
||||
OBJS += passes/cmds/connwrappers.o
|
||||
OBJS += passes/cmds/trace.o
|
||||
OBJS += passes/cmds/dump_twines.o
|
||||
OBJS += passes/cmds/plugin.o
|
||||
OBJS += passes/cmds/check.o
|
||||
OBJS += passes/cmds/edgetypes.o
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ struct Slice {
|
|||
};
|
||||
|
||||
void emit_mux_anyseq(Module* mod, const SigSpec& mux_input, const SigSpec& mux_output, EnableLogic enable) {
|
||||
auto anyseq = mod->Anyseq(NEW_ID, mux_input.size());
|
||||
auto anyseq = mod->Anyseq(mod->design->twines.add(NEW_TWINE), mux_input.size());
|
||||
if (enable.bit == (enable.pol ? State::S1 : State::S0)) {
|
||||
mod->connect(mux_output, anyseq);
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ void emit_mux_anyseq(Module* mod, const SigSpec& mux_input, const SigSpec& mux_o
|
|||
mux_a = anyseq;
|
||||
mux_b = mux_input;
|
||||
}
|
||||
(void)mod->addMux(NEW_ID,
|
||||
(void)mod->addMux(NEW_TWINE,
|
||||
mux_a,
|
||||
mux_b,
|
||||
enable.bit,
|
||||
|
|
@ -212,7 +212,7 @@ unsigned int abstract_state(Module* mod, EnableLogic enable, const std::vector<S
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool abstract_value_cell_port(Module* mod, Cell* cell, std::set<int> offsets, IdString port_name, EnableLogic enable) {
|
||||
bool abstract_value_cell_port(Module* mod, Cell* cell, std::set<int> offsets, TwineRef port_name, EnableLogic enable) {
|
||||
Wire* to_abstract = mod->addWire(NEW_TWINE, offsets.size());
|
||||
SigSpec mux_input;
|
||||
SigSpec mux_output;
|
||||
|
|
@ -273,7 +273,7 @@ unsigned int abstract_value(Module* mod, EnableLogic enable, const std::vector<S
|
|||
for (int i = 0; i < conn.second.size(); i++) {
|
||||
if (selected_reps.count(sigmap(conn.second[i]))) {
|
||||
log_debug("Abstracting value for %s.%s[%i] in module %s due to selections:\n",
|
||||
cell, conn.first.unescape(), i, mod);
|
||||
cell, cell->module->design->twines.str(conn.first).c_str(), i, mod);
|
||||
explain_selections(selected_reps.at(sigmap(conn.second[i])));
|
||||
offsets_to_abstract.insert(i);
|
||||
}
|
||||
|
|
@ -496,19 +496,19 @@ struct AbstractPass : public Pass {
|
|||
} break;
|
||||
case Enable::ActiveLow:
|
||||
case Enable::ActiveHigh: {
|
||||
Wire *enable_wire = mod->wire("\\" + enable_name);
|
||||
Wire *enable_wire = mod->wire(mod->design->twines.lookup("\\" + enable_name));
|
||||
if (!enable_wire)
|
||||
log_cmd_error("Enable wire %s not found in module %s\n", enable_name, mod->name);
|
||||
log_cmd_error("Enable wire %s not found in module %s\n", enable_name, log_id(mod));
|
||||
if (GetSize(enable_wire) != 1)
|
||||
log_cmd_error("Enable wire %s must have width 1 but has width %d in module %s\n",
|
||||
enable_name.c_str(), GetSize(enable_wire), mod->name.c_str());
|
||||
enable_name.c_str(), GetSize(enable_wire), log_id(mod));
|
||||
enable_logic = { enable_wire, enable == Enable::ActiveHigh };
|
||||
} break;
|
||||
case Enable::Initstates: {
|
||||
SigBit in_init_states = mod->Initstate(NEW_ID);
|
||||
SigBit in_init_states = mod->Initstate(mod->design->twines.add(NEW_TWINE));
|
||||
for (int i = 1; i < initstates; i++) {
|
||||
Wire *in_init_states_q = mod->addWire(NEW_TWINE);
|
||||
mod->addFf(NEW_ID, in_init_states, in_init_states_q);
|
||||
mod->addFf(NEW_TWINE, in_init_states, in_init_states_q);
|
||||
in_init_states_q->attributes[ID::init] = State::S1;
|
||||
in_init_states = in_init_states_q;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
|
|||
{
|
||||
std::string escaped_name = RTLIL::escape_id(name);
|
||||
std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : "";
|
||||
RTLIL::Wire *wire = module->wire(escaped_name);
|
||||
RTLIL::Design *design = module->design;
|
||||
RTLIL::Wire *wire = module->wire(design->twines.lookup(escaped_name));
|
||||
log_assert(is_formal_celltype(celltype));
|
||||
|
||||
if (wire == nullptr) {
|
||||
|
|
@ -45,15 +46,15 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
|
|||
formal_cell->setPort(TW::A, wire);
|
||||
if(enable_name == "") {
|
||||
formal_cell->setPort(TW::EN, State::S1);
|
||||
log("Added $%s cell for wire \"%s.%s\"\n", celltype, module->name.str(), name);
|
||||
log("Added $%s cell for wire \"%s.%s\"\n", celltype, log_id(module), name);
|
||||
}
|
||||
else {
|
||||
RTLIL::Wire *enable_wire = module->wire(escaped_enable_name);
|
||||
RTLIL::Wire *enable_wire = module->wire(design->twines.lookup(escaped_enable_name));
|
||||
if(enable_wire == nullptr)
|
||||
log_error("Could not find enable wire with name \"%s\".\n", enable_name);
|
||||
|
||||
formal_cell->setPort(TW::EN, enable_wire);
|
||||
log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype, module->name.str(), name, module->name.str(), enable_name);
|
||||
log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype, log_id(module), name, log_id(module), enable_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -62,10 +63,11 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
|||
{
|
||||
RTLIL::Wire *wire = nullptr;
|
||||
name = RTLIL::escape_id(name);
|
||||
TwineRef name_ref = design->twines.lookup(name);
|
||||
|
||||
if (module->count_id(name) != 0)
|
||||
if (name_ref != Twine::Null)
|
||||
{
|
||||
wire = module->wire(name);
|
||||
wire = module->wire(name_ref);
|
||||
|
||||
if (wire != nullptr && wire->width != width)
|
||||
wire = nullptr;
|
||||
|
|
@ -77,13 +79,13 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
|||
wire = nullptr;
|
||||
|
||||
if (wire == nullptr)
|
||||
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name);
|
||||
log_cmd_error("Found incompatible object with same name in module %s!\n", log_id(module));
|
||||
|
||||
log("Module %s already has such an object.\n", module->name);
|
||||
log("Module %s already has such an object.\n", log_id(module));
|
||||
}
|
||||
else
|
||||
{
|
||||
wire = module->addWire(name, width);
|
||||
wire = module->addWire(Twine{name}, width);
|
||||
wire->port_input = flag_input;
|
||||
wire->port_output = flag_output;
|
||||
|
||||
|
|
@ -91,7 +93,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
|||
module->fixup_ports();
|
||||
}
|
||||
|
||||
log("Added wire %s to module %s.\n", name, module->name);
|
||||
log("Added wire %s to module %s.\n", name, log_id(module));
|
||||
}
|
||||
|
||||
if (!flag_global)
|
||||
|
|
@ -106,11 +108,11 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
|||
continue;
|
||||
if (mod->get_blackbox_attribute())
|
||||
continue;
|
||||
if (cell->hasPort(name))
|
||||
if (cell->hasPort(design->twines.add(Twine{name})))
|
||||
continue;
|
||||
|
||||
cell->setPort(name, wire);
|
||||
log("Added connection %s to cell %s.%s (%s).\n", name, module->name, cell->name, cell->type);
|
||||
cell->setPort(design->twines.add(Twine{name}), wire);
|
||||
log("Added connection %s to cell %s.%s (%s).\n", name, log_id(module), log_id(cell), cell->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,7 +202,7 @@ struct AddPass : public Pass {
|
|||
|
||||
if (mod_mode) {
|
||||
for (; argidx < args.size(); argidx++)
|
||||
design->addModule(RTLIL::escape_id(args[argidx]));
|
||||
design->addModule(design->twines.add(Twine{RTLIL::escape_id(args[argidx])}));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +212,7 @@ struct AddPass : public Pass {
|
|||
for (auto module : design->modules())
|
||||
{
|
||||
log_assert(module != nullptr);
|
||||
if (!design->selected_whole_module(module->name))
|
||||
if (!design->selected_whole_module(module->meta_->name))
|
||||
continue;
|
||||
if (module->get_bool_attribute(ID::blackbox))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ int autoname_worker(Module *module, const dict<Wire*, unsigned int>& wire_score)
|
|||
for (auto bit : conn.second)
|
||||
if (bit.wire != nullptr && bit.wire->name[0] != '$') {
|
||||
if (suffix.empty())
|
||||
suffix = stringf("_%s_%s", cell->type.unescape(), conn.first.unescape());
|
||||
suffix = stringf("_%s_%s", cell->type.unescape(), module->design->twines.str(conn.first).c_str());
|
||||
name_proposal proposed_name(
|
||||
bit.wire->name.str() + suffix,
|
||||
cell->output(conn.first) ? 0 : wire_score.at(bit.wire)
|
||||
|
|
@ -66,7 +66,7 @@ int autoname_worker(Module *module, const dict<Wire*, unsigned int>& wire_score)
|
|||
for (auto bit : conn.second)
|
||||
if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) {
|
||||
if (suffix.empty())
|
||||
suffix = stringf("_%s", conn.first.unescape());
|
||||
suffix = stringf("_%s", module->design->twines.str(conn.first).c_str());
|
||||
name_proposal proposed_name(
|
||||
cell->name.str() + suffix,
|
||||
cell->output(conn.first) ? 0 : wire_score.at(bit.wire)
|
||||
|
|
@ -89,8 +89,8 @@ int autoname_worker(Module *module, const dict<Wire*, unsigned int>& wire_score)
|
|||
for (auto &it : proposed_cell_names) {
|
||||
if (best_name < it.second)
|
||||
continue;
|
||||
IdString n = module->uniquify(IdString(it.second.name));
|
||||
log_debug("Rename cell %s in %s to %s.\n", it.first, module, n.unescape());
|
||||
TwineRef n = module->uniquify(module->design->twines.add(Twine{it.second.name}));
|
||||
log_debug("Rename cell %s in %s to %s.\n", it.first, module, module->design->twines.str(n).c_str());
|
||||
module->rename(it.first, n);
|
||||
count++;
|
||||
}
|
||||
|
|
@ -98,8 +98,8 @@ int autoname_worker(Module *module, const dict<Wire*, unsigned int>& wire_score)
|
|||
for (auto &it : proposed_wire_names) {
|
||||
if (best_name < it.second)
|
||||
continue;
|
||||
IdString n = module->uniquify(IdString(it.second.name));
|
||||
log_debug("Rename wire %s in %s to %s.\n", it.first, module, n.unescape());
|
||||
TwineRef n = module->uniquify(module->design->twines.add(Twine{it.second.name}));
|
||||
log_debug("Rename wire %s in %s to %s.\n", it.first, module, module->design->twines.str(n).c_str());
|
||||
module->rename(it.first, n);
|
||||
count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ struct BoxDerivePass : Pass {
|
|||
if (base_override)
|
||||
base = base_override;
|
||||
|
||||
auto index = std::make_pair(RTLIL::IdString(base->name), cell->parameters);
|
||||
auto index = std::make_pair(RTLIL::IdString(base->design->twines.str(base->meta_->name)), cell->parameters);
|
||||
|
||||
if (cell->parameters.empty())
|
||||
continue;
|
||||
|
|
@ -111,14 +111,14 @@ struct BoxDerivePass : Pass {
|
|||
log_error("Derived module %s cannot be renamed to private name %s.\n",
|
||||
derived, new_name.unescape());
|
||||
derived->attributes.erase(naming_attr);
|
||||
d->rename(derived, new_name);
|
||||
d->rename(derived, d->twines.add(Twine{new_name.str()}));
|
||||
}
|
||||
|
||||
done[index] = derived;
|
||||
}
|
||||
|
||||
if (apply_mode)
|
||||
cell->type = done[index]->name;
|
||||
cell->type = RTLIL::IdString(done[index]->design->twines.str(done[index]->meta_->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ struct BugpointPass : public Pass {
|
|||
|
||||
if (index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to remove cell port %s.%s.%s.\n", mod, cell, it.first.unescape());
|
||||
log_header(design, "Trying to remove cell port %s.%s.%s.\n", mod, cell, design->twines.str(it.first).c_str());
|
||||
RTLIL::SigSpec port_x(State::Sx, port.size());
|
||||
cell->unsetPort(it.first);
|
||||
cell->setPort(it.first, port_x);
|
||||
|
|
@ -305,7 +305,7 @@ struct BugpointPass : public Pass {
|
|||
|
||||
if (!stage2 && (cell->input(it.first) || cell->output(it.first)) && index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", mod, cell, it.first.unescape());
|
||||
log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", mod, cell, design->twines.str(it.first).c_str());
|
||||
RTLIL::Wire *wire = mod->addWire(NEW_TWINE, port.size());
|
||||
wire->set_bool_attribute(ID($bugpoint));
|
||||
wire->port_input = cell->input(it.first);
|
||||
|
|
@ -334,7 +334,7 @@ struct BugpointPass : public Pass {
|
|||
|
||||
if (index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to remove process %s.%s.\n", mod, process.first.unescape());
|
||||
log_header(design, "Trying to remove process %s.%s.\n", mod, design->twines.str(process.first).c_str());
|
||||
removed_process = process.second;
|
||||
break;
|
||||
}
|
||||
|
|
@ -363,7 +363,7 @@ struct BugpointPass : public Pass {
|
|||
{
|
||||
if (index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), mod, pr.first.unescape());
|
||||
log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), mod, design->twines.str(pr.first).c_str());
|
||||
cs->actions.erase(it);
|
||||
return design_copy;
|
||||
}
|
||||
|
|
@ -389,7 +389,7 @@ struct BugpointPass : public Pass {
|
|||
{
|
||||
if (index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), mod, pr.first.unescape());
|
||||
log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), mod, design->twines.str(pr.first).c_str());
|
||||
sy->actions.erase(it);
|
||||
return design_copy;
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ struct BugpointPass : public Pass {
|
|||
{
|
||||
if (index++ == seed)
|
||||
{
|
||||
log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), it->memid.unescape(), log_signal(it->address), log_signal(it->data), log_signal(it->enable), mod, pr.first.unescape());
|
||||
log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), it->memid.unescape(), log_signal(it->address), log_signal(it->data), log_signal(it->enable), mod, design->twines.str(pr.first).c_str());
|
||||
sy->mem_write_actions.erase(it);
|
||||
// Remove the bit for removed action from other actions' priority masks.
|
||||
for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) {
|
||||
|
|
|
|||
|
|
@ -42,25 +42,25 @@ int check_bufnorm_cell(RTLIL::Module *module, RTLIL::Cell *cell)
|
|||
for (auto bit : conn.second) {
|
||||
if (bit.is_wire() && !module->fanout(bit).count(RTLIL::PortBit(cell, conn.first, i)))
|
||||
log_warning("sigNorm: fanout index missing entry for cell %s.%s port %s bit %d\n",
|
||||
log_id(module), log_id(cell), log_id(conn.first), i), counter++;
|
||||
log_id(module), log_id(cell), module->design->twines.str(conn.first).c_str(), i), counter++;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
} else if (!conn.second.empty()) {
|
||||
if (!conn.second.is_wire()) {
|
||||
log_warning("bufNorm: cell %s.%s port %s output is not a full wire: %s\n",
|
||||
log_id(module), log_id(cell), log_id(conn.first), log_signal(conn.second));
|
||||
log_id(module), log_id(cell), module->design->twines.str(conn.first).c_str(), log_signal(conn.second));
|
||||
counter++;
|
||||
} else {
|
||||
Wire *w = conn.second.as_wire();
|
||||
if (!w->known_driver())
|
||||
log_warning("bufNorm: cell %s.%s port %s drives wire %s but wire has no driverCell_ set\n",
|
||||
log_id(module), log_id(cell), log_id(conn.first), log_id(w)), counter++;
|
||||
log_id(module), log_id(cell), module->design->twines.str(conn.first).c_str(), log_id(w)), counter++;
|
||||
else if (w->driverCell() != cell || w->driverPort() != conn.first)
|
||||
log_warning("bufNorm: wire %s.%s driverCell_/driverPort_ mismatch: recorded driver is cell %s port %s, but cell %s port %s also drives it\n",
|
||||
log_id(module), log_id(w),
|
||||
log_id(w->driverCell()), log_id(w->driverPort()),
|
||||
log_id(cell), log_id(conn.first)), counter++;
|
||||
log_id(w->driverCell()), module->design->twines.str(w->driverPort()).c_str(),
|
||||
log_id(cell), module->design->twines.str(conn.first).c_str()), counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -77,16 +77,16 @@ int check_bufnorm_wire(RTLIL::Module *module, RTLIL::Wire *wire)
|
|||
int counter = 0;
|
||||
if (wire->known_driver()) {
|
||||
Cell *driver = wire->driverCell();
|
||||
IdString dport = wire->driverPort();
|
||||
TwineRef dport = wire->driverPort();
|
||||
if (!driver->hasPort(dport)) {
|
||||
log_warning("bufNorm: wire %s.%s driverPort_ %s does not exist on driverCell_ %s\n",
|
||||
log_id(module), log_id(wire), log_id(dport), log_id(driver));
|
||||
log_id(module), log_id(wire), module->design->twines.str(dport).c_str(), log_id(driver));
|
||||
counter++;
|
||||
} else {
|
||||
const SigSpec &dsig = driver->getPort(dport);
|
||||
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), log_id(dport)), counter++;
|
||||
log_id(module), log_id(wire), log_id(driver), module->design->twines.str(dport).c_str()), counter++;
|
||||
if (wire->port_input && !wire->port_output && driver->type != ID($input_port))
|
||||
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++;
|
||||
|
|
@ -109,20 +109,20 @@ int check_signorm_fanout(RTLIL::Module *module)
|
|||
for (auto &pb : portbits) {
|
||||
if (!pb.cell->hasPort(pb.port)) {
|
||||
log_warning("sigNorm: fanout entry for %s points to non-existent port %s on cell %s.%s\n",
|
||||
log_signal(bit), log_id(pb.port), log_id(module), log_id(pb.cell));
|
||||
log_signal(bit), module->design->twines.str(pb.port).c_str(), log_id(module), log_id(pb.cell));
|
||||
counter++;
|
||||
continue;
|
||||
}
|
||||
const SigSpec &fsig = pb.cell->getPort(pb.port);
|
||||
if (pb.offset < 0 || pb.offset >= fsig.size()) {
|
||||
log_warning("sigNorm: fanout entry for %s has out-of-bounds offset %d for cell %s.%s port %s (width %d)\n",
|
||||
log_signal(bit), pb.offset, log_id(module), log_id(pb.cell), log_id(pb.port), fsig.size());
|
||||
log_signal(bit), pb.offset, log_id(module), log_id(pb.cell), module->design->twines.str(pb.port).c_str(), fsig.size());
|
||||
counter++;
|
||||
continue;
|
||||
}
|
||||
if (fsig[pb.offset] != bit)
|
||||
log_warning("sigNorm: fanout entry mismatch: expected %s at offset %d of cell %s.%s port %s, found %s\n",
|
||||
log_signal(bit), pb.offset, log_id(module), log_id(pb.cell), log_id(pb.port), log_signal(fsig[pb.offset])), counter++;
|
||||
log_signal(bit), pb.offset, log_id(module), log_id(pb.cell), module->design->twines.str(pb.port).c_str(), log_signal(fsig[pb.offset])), counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
|
|
@ -234,7 +234,7 @@ struct CheckPass : public Pass {
|
|||
for (auto bit : sigmap(action.first))
|
||||
wire_drivers[bit].push_back(
|
||||
stringf("action %s <= %s (case rule) in process %s",
|
||||
log_signal(action.first), log_signal(action.second), proc_it.first.unescape()));
|
||||
log_signal(action.first), log_signal(action.second), module->design->twines.str(proc_it.first).c_str()));
|
||||
|
||||
for (auto bit : sigmap(action.second))
|
||||
if (bit.wire) used_wires.insert(bit);
|
||||
|
|
@ -255,7 +255,7 @@ struct CheckPass : public Pass {
|
|||
for (auto bit : sigmap(action.first))
|
||||
wire_drivers[bit].push_back(
|
||||
stringf("action %s <= %s (sync rule) in process %s",
|
||||
log_signal(action.first), log_signal(action.second), proc_it.first.unescape()));
|
||||
log_signal(action.first), log_signal(action.second), module->design->twines.str(proc_it.first).c_str()));
|
||||
for (auto bit : sigmap(action.second))
|
||||
if (bit.wire) used_wires.insert(bit);
|
||||
}
|
||||
|
|
@ -278,8 +278,8 @@ struct CheckPass : public Pass {
|
|||
CircuitEdgesDatabase(TopoSort<std::pair<RTLIL::IdString, int>> &topo, SigMap &sigmap, bool force_detail)
|
||||
: topo(topo), sigmap(sigmap), force_detail(force_detail) {}
|
||||
|
||||
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit,
|
||||
RTLIL::IdString to_port, int to_bit, int) override {
|
||||
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit,
|
||||
TwineRef to_port, int to_bit, int) override {
|
||||
SigSpec from_portsig = cell->getPort(from_port);
|
||||
SigSpec to_portsig = cell->getPort(to_port);
|
||||
log_assert(from_bit >= 0 && from_bit < from_portsig.size());
|
||||
|
|
@ -405,7 +405,7 @@ struct CheckPass : public Pass {
|
|||
if (output && !input && bit.wire)
|
||||
wire_drivers_count[bit]++;
|
||||
if (output && (bit.wire || !input))
|
||||
wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", conn.first.unescape(), i,
|
||||
wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", cell->module->design->twines.str(conn.first).c_str(), i,
|
||||
cell, cell->type.unescape()));
|
||||
if (output)
|
||||
driver_cells[bit] = cell;
|
||||
|
|
@ -485,7 +485,7 @@ struct CheckPass : public Pass {
|
|||
SigBit prev;
|
||||
for (auto it = loop.rbegin(); it != loop.rend(); it++)
|
||||
if (it->second != -1) { // skip the fallback helper nodes
|
||||
prev = SigBit(module->wire(it->first), it->second);
|
||||
prev = SigBit(module->wire(module->design->twines.lookup(it->first.str())), it->second);
|
||||
break;
|
||||
}
|
||||
log_assert(prev != SigBit());
|
||||
|
|
@ -504,22 +504,22 @@ struct CheckPass : public Pass {
|
|||
MatchingEdgePrinter(std::string &message, SigMap &sigmap, SigBit from, SigBit to)
|
||||
: message(message), sigmap(sigmap), from(from), to(to), nhits(0) {}
|
||||
|
||||
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit,
|
||||
RTLIL::IdString to_port, int to_bit, int) override {
|
||||
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit,
|
||||
TwineRef to_port, int to_bit, int) override {
|
||||
SigBit edge_from = sigmap(cell->getPort(from_port))[from_bit];
|
||||
SigBit edge_to = sigmap(cell->getPort(to_port))[to_bit];
|
||||
|
||||
if (edge_from == from && edge_to == to && nhits++ < HITS_LIMIT)
|
||||
message += stringf(" %s[%d] --> %s[%d]\n", from_port.unescape(), from_bit,
|
||||
to_port.unescape(), to_bit);
|
||||
message += stringf(" %s[%d] --> %s[%d]\n", cell->module->design->twines.str(from_port).c_str(), from_bit,
|
||||
cell->module->design->twines.str(to_port).c_str(), to_bit);
|
||||
if (nhits == HITS_LIMIT)
|
||||
message += " ...\n";
|
||||
}
|
||||
};
|
||||
|
||||
Wire *wire = module->wire(pair.first);
|
||||
Wire *wire = module->wire(module->design->twines.lookup(pair.first.str()));
|
||||
log_assert(wire);
|
||||
SigBit bit(module->wire(pair.first), pair.second);
|
||||
SigBit bit(module->wire(module->design->twines.lookup(pair.first.str())), pair.second);
|
||||
log_assert(driver_cells.count(bit));
|
||||
Cell *driver = driver_cells.at(bit);
|
||||
|
||||
|
|
|
|||
|
|
@ -344,8 +344,8 @@ struct ChformalPass : public Pass {
|
|||
Wire *new_en = module->addWire(NEW_TWINE);
|
||||
new_en->attributes[ID::init] = State::S0;
|
||||
|
||||
module->addFf(NEW_ID, orig_a, new_a);
|
||||
module->addFf(NEW_ID, orig_en, new_en);
|
||||
module->addFf(NEW_TWINE, orig_a, new_a);
|
||||
module->addFf(NEW_TWINE, orig_en, new_en);
|
||||
|
||||
cell->setPort(TW::A, new_a);
|
||||
cell->setPort(TW::EN, new_en);
|
||||
|
|
@ -360,12 +360,12 @@ struct ChformalPass : public Pass {
|
|||
for (int i = 0; i < mode_arg; i++) {
|
||||
Wire *w = module->addWire(NEW_TWINE);
|
||||
w->attributes[ID::init] = State::S0;
|
||||
module->addFf(NEW_ID, en, w);
|
||||
module->addFf(NEW_TWINE, en, w);
|
||||
en = w;
|
||||
}
|
||||
|
||||
for (auto cell : constr_cells)
|
||||
cell->setPort(TW::EN, module->LogicAnd(NEW_ID, en, cell->getPort(TW::EN)));
|
||||
cell->setPort(TW::EN, module->LogicAnd(NEW_TWINE, en, cell->getPort(TW::EN)));
|
||||
}
|
||||
else
|
||||
if (mode =='p')
|
||||
|
|
@ -381,13 +381,13 @@ struct ChformalPass : public Pass {
|
|||
cover->setParam(ID(FLAVOR), Const("cover"));
|
||||
|
||||
for (auto const &conn : cell->connections())
|
||||
if (!conn.first.in(ID::A, ID::EN))
|
||||
if (conn.first != TW::A && conn.first != TW::EN)
|
||||
cover->setPort(conn.first, conn.second);
|
||||
cover->setPort(TW::A, cell->getPort(TW::EN));
|
||||
cover->setPort(TW::EN, State::S1);
|
||||
} else {
|
||||
module->addCover(NEW_ID_SUFFIX("coverenable"),
|
||||
cell->getPort(TW::EN), State::S1, cell->get_src_attribute());
|
||||
module->addCover(NEW_TWINE_SUFFIX("coverenable"),
|
||||
cell->getPort(TW::EN), State::S1, module->design->twines.add(Twine{cell->get_src_attribute()}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -432,9 +432,9 @@ struct ChformalPass : public Pass {
|
|||
plain_cell->setPort(TW::EN, sig_en);
|
||||
|
||||
if (plain_cell->type.in(ID($assert), ID($assume)))
|
||||
sig_a = module->Not(NEW_ID, sig_a);
|
||||
sig_a = module->Not(NEW_TWINE, sig_a);
|
||||
|
||||
SigBit combined_en = module->And(NEW_ID, sig_a, sig_en);
|
||||
SigBit combined_en = module->And(NEW_TWINE, sig_a, sig_en);
|
||||
|
||||
module->swap_names(cell, plain_cell);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,10 +34,9 @@ static void publish_design(RTLIL::Design* design) {
|
|||
auto saved_modules = design->modules_;
|
||||
design->modules_.clear();
|
||||
for (auto& [name, mod] : saved_modules) {
|
||||
RTLIL::IdString new_name = mod->name;
|
||||
RTLIL::IdString new_name = RTLIL::IdString(design->twines.str(mod->meta_->name));
|
||||
publish(new_name);
|
||||
mod->name = new_name;
|
||||
design->modules_[mod->name] = mod;
|
||||
design->modules_[mod->meta_->name] = mod;
|
||||
for (auto* cell : mod->cells()) {
|
||||
publish(cell->type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ struct ConnectPass : public Pass {
|
|||
RTLIL::Module *module = nullptr;
|
||||
for (auto mod : design->selected_modules()) {
|
||||
if (module != nullptr)
|
||||
log_cmd_error("Multiple modules selected: %s, %s\n", module->name.unescape(), mod->name.unescape());
|
||||
log_cmd_error("Multiple modules selected: %s, %s\n", module->design->twines.str(module->meta_->name).c_str(), module->design->twines.str(mod->meta_->name).c_str());
|
||||
module = mod;
|
||||
}
|
||||
if (module == nullptr)
|
||||
|
|
@ -198,7 +198,7 @@ struct ConnectPass : public Pass {
|
|||
if (flag_nounset)
|
||||
log_cmd_error("Can't use -port together with -nounset.\n");
|
||||
|
||||
if (module->cell(RTLIL::escape_id(port_cell)) == nullptr)
|
||||
if (module->cell(module->design->twines.lookup(RTLIL::escape_id(port_cell))) == nullptr)
|
||||
log_cmd_error("Can't find cell %s.\n", port_cell);
|
||||
|
||||
RTLIL::SigSpec sig;
|
||||
|
|
@ -206,9 +206,9 @@ struct ConnectPass : public Pass {
|
|||
log_cmd_error("Failed to parse port expression `%s'.\n", port_expr);
|
||||
|
||||
if (!flag_assert) {
|
||||
module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));
|
||||
module->cell(module->design->twines.lookup(RTLIL::escape_id(port_cell)))->setPort(module->design->twines.lookup(RTLIL::escape_id(port_port)), sigmap(sig));
|
||||
} else {
|
||||
SigSpec cur = module->cell(RTLIL::escape_id(port_cell))->getPort(RTLIL::escape_id(port_port));
|
||||
SigSpec cur = module->cell(module->design->twines.lookup(RTLIL::escape_id(port_cell)))->getPort(module->design->twines.lookup(RTLIL::escape_id(port_port)));
|
||||
if (sigmap(sig) != sigmap(cur)) {
|
||||
log_cmd_error("Expected connection not present: expected %s, found %s.\n", log_signal(sig), log_signal(cur));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ struct ConnwrappersWorker
|
|||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
std::pair<RTLIL::IdString, RTLIL::IdString> key(cell->type, conn.first);
|
||||
std::pair<RTLIL::IdString, RTLIL::IdString> key(cell->type, RTLIL::IdString(cell->module->design->twines.str(conn.first)));
|
||||
|
||||
if (!decls.count(key))
|
||||
continue;
|
||||
|
|
@ -134,8 +134,8 @@ struct ConnwrappersWorker
|
|||
}
|
||||
|
||||
if (old_sig.size())
|
||||
log("Connected extended bits of %s.%s:%s: %s -> %s\n", module->name.unescape(), cell->name.unescape(),
|
||||
conn.first.unescape(), log_signal(old_sig), log_signal(conn.second));
|
||||
log("Connected extended bits of %s.%s:%s: %s -> %s\n", module->design->twines.str(module->meta_->name).c_str(), cell->module->design->twines.str(cell->meta_->name),
|
||||
module->design->twines.str(conn.first).c_str(), log_signal(old_sig), log_signal(conn.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ struct CopyPass : public Pass {
|
|||
log_cmd_error("Target module name %s already exists.\n", trg_name);
|
||||
|
||||
RTLIL::Module *new_mod = design->module(src_name)->clone();
|
||||
new_mod->name = trg_name;
|
||||
design->rename(new_mod, design->twines.add(Twine{trg_name}));
|
||||
design->add(new_mod);
|
||||
}
|
||||
} CopyPass;
|
||||
|
|
|
|||
|
|
@ -68,12 +68,12 @@ struct DeletePass : public Pass {
|
|||
std::vector<RTLIL::Module *> delete_mods;
|
||||
for (auto module : design->modules())
|
||||
{
|
||||
if (design->selected_whole_module(module->name) && !flag_input && !flag_output) {
|
||||
if (design->selected_whole_module(module->meta_->name) && !flag_input && !flag_output) {
|
||||
delete_mods.push_back(module);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!design->selected_module(module->name))
|
||||
if (!design->selected_module(module->meta_->name))
|
||||
continue;
|
||||
|
||||
if (flag_input || flag_output) {
|
||||
|
|
@ -91,7 +91,7 @@ struct DeletePass : public Pass {
|
|||
pool<RTLIL::Wire*> delete_wires;
|
||||
pool<RTLIL::Cell*> delete_cells;
|
||||
pool<RTLIL::Process*> delete_procs;
|
||||
pool<RTLIL::IdString> delete_mems;
|
||||
pool<TwineRef> delete_mems;
|
||||
|
||||
for (auto wire : module->selected_wires())
|
||||
delete_wires.insert(wire);
|
||||
|
|
@ -104,7 +104,7 @@ struct DeletePass : public Pass {
|
|||
if (design->selected(module, cell))
|
||||
delete_cells.insert(cell);
|
||||
if (cell->has_memid() &&
|
||||
delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0)
|
||||
delete_mems.count(design->twines.lookup(cell->parameters.at(ID::MEMID).decode_string())) != 0)
|
||||
delete_cells.insert(cell);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ struct DesignPass : public Pass {
|
|||
t->attributes.erase(ID::top);
|
||||
|
||||
queue.insert(t);
|
||||
done[mod->name] = prefix;
|
||||
done[RTLIL::escape_id(copy_from_design->twines.str(mod->meta_->name))] = prefix;
|
||||
}
|
||||
|
||||
while (!queue.empty() && copy_from_design)
|
||||
|
|
@ -316,7 +316,7 @@ struct DesignPass : public Pass {
|
|||
|
||||
for (auto mod : copy_src_modules)
|
||||
{
|
||||
std::string trg_name = as_name.empty() ? mod->name.str() : RTLIL::escape_id(as_name);
|
||||
std::string trg_name = as_name.empty() ? copy_from_design->twines.str(mod->meta_->name) : RTLIL::escape_id(as_name);
|
||||
|
||||
if (copy_to_design->module(trg_name) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(trg_name));
|
||||
|
|
@ -358,7 +358,7 @@ struct DesignPass : public Pass {
|
|||
|
||||
design->selection_stack.clear();
|
||||
design->selection_vars.clear();
|
||||
design->selected_active_module.clear();
|
||||
design->selected_active_module = Twine::Null;
|
||||
|
||||
design->push_full_selection();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ public:
|
|||
[[noreturn]]
|
||||
void formatted_error(std::string err)
|
||||
{
|
||||
log("Module A: %s\n", mod_a->name.unescape());
|
||||
log("Module A: %s\n", log_id(mod_a));
|
||||
log_module(mod_a, " ");
|
||||
log("Module B: %s\n", mod_b->name.unescape());
|
||||
log("Module B: %s\n", log_id(mod_b));
|
||||
log_module(mod_b, " ");
|
||||
log_cmd_error("Designs are different: %s\n", err);
|
||||
}
|
||||
|
|
@ -104,24 +104,22 @@ public:
|
|||
void check_wires()
|
||||
{
|
||||
for (const auto &it : mod_a->wires_) {
|
||||
RTLIL::IdString wname(it.second->name);
|
||||
RTLIL::Wire *wb = mod_b->wire(wname);
|
||||
RTLIL::Wire *wb = mod_b->wire(it.first);
|
||||
if (!wb)
|
||||
error("Module %s missing wire %s in second design.\n", mod_a->name.unescape(), wname.unescape());
|
||||
error("Module %s missing wire %s in second design.\n", log_id(mod_a), log_id(it.second));
|
||||
else if (std::string mismatch = compare_wires(it.second, wb); !mismatch.empty())
|
||||
error("Module %s wire %s %s.\n", mod_a->name.unescape(), wname.unescape(), mismatch);
|
||||
error("Module %s wire %s %s.\n", log_id(mod_a), log_id(it.second), mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->wires_) {
|
||||
RTLIL::IdString wname(it.second->name);
|
||||
if (!mod_a->wire(wname))
|
||||
error("Module %s missing wire %s in first design.\n", mod_b->name.unescape(), wname.unescape());
|
||||
if (!mod_a->wire(it.first))
|
||||
error("Module %s missing wire %s in first design.\n", log_id(mod_b), log_id(it.second));
|
||||
}
|
||||
}
|
||||
|
||||
std::string compare_memories(const RTLIL::Memory *a, const RTLIL::Memory *b)
|
||||
{
|
||||
if (a->name != b->name)
|
||||
return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (a->meta_->name != b->meta_->name)
|
||||
return "name mismatch: " + std::string(a->module->design->twines.str(a->meta_->name)) + " != " + b->module->design->twines.str(b->meta_->name);
|
||||
if (a->width != b->width)
|
||||
return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width);
|
||||
if (a->start_offset != b->start_offset)
|
||||
|
|
@ -154,13 +152,13 @@ public:
|
|||
|
||||
for (const auto &it : a->connections()) {
|
||||
if (b->connections().count(it.first) == 0)
|
||||
return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in second design";
|
||||
return "connection mismatch: missing connection " + a->module->design->twines.str(it.first) + " in second design";
|
||||
if (!compare_sigspec(it.second, b->connections().at(it.first)))
|
||||
return "connection " + std::string(it.first.unescape()) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first));
|
||||
return "connection " + a->module->design->twines.str(it.first) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first));
|
||||
}
|
||||
for (const auto &it : b->connections())
|
||||
if (a->connections().count(it.first) == 0)
|
||||
return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in first design";
|
||||
return "connection mismatch: missing connection " + a->module->design->twines.str(it.first) + " in first design";
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
@ -168,17 +166,15 @@ public:
|
|||
void check_cells()
|
||||
{
|
||||
for (const auto &it : mod_a->cells_) {
|
||||
RTLIL::IdString cname(it.second->name);
|
||||
RTLIL::Cell *cb = mod_b->cell(cname);
|
||||
RTLIL::Cell *cb = mod_b->cell(it.first);
|
||||
if (!cb)
|
||||
error("Module %s missing cell %s in second design.\n", mod_a->name.unescape(), cname.unescape());
|
||||
error("Module %s missing cell %s in second design.\n", log_id(mod_a), log_id(it.second));
|
||||
else if (std::string mismatch = compare_cells(it.second, cb); !mismatch.empty())
|
||||
error("Module %s cell %s %s.\n", mod_a->name.unescape(), cname.unescape(), mismatch);
|
||||
error("Module %s cell %s %s.\n", log_id(mod_a), log_id(it.second), mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->cells_) {
|
||||
RTLIL::IdString cname(it.second->name);
|
||||
if (!mod_a->cell(cname))
|
||||
error("Module %s missing cell %s in first design.\n", mod_b->name.unescape(), cname.unescape());
|
||||
if (!mod_a->cell(it.first))
|
||||
error("Module %s missing cell %s in first design.\n", log_id(mod_b), log_id(it.second));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,13 +182,13 @@ public:
|
|||
{
|
||||
for (const auto &it : mod_a->memories) {
|
||||
if (mod_b->memories.count(it.first) == 0)
|
||||
error("Module %s missing memory %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
error("Module %s missing memory %s in second design.\n", log_id(mod_a), log_id(it.second));
|
||||
if (std::string mismatch = compare_memories(it.second, mod_b->memories.at(it.first)); !mismatch.empty())
|
||||
error("Module %s memory %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch);
|
||||
error("Module %s memory %s %s.\n", log_id(mod_a), log_id(it.second), mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->memories)
|
||||
if (mod_a->memories.count(it.first) == 0)
|
||||
error("Module %s missing memory %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
error("Module %s missing memory %s in first design.\n", log_id(mod_b), log_id(it.second));
|
||||
}
|
||||
|
||||
std::string compare_case_rules(const RTLIL::CaseRule *a, const RTLIL::CaseRule *b)
|
||||
|
|
@ -276,7 +272,7 @@ public:
|
|||
|
||||
std::string compare_processes(const RTLIL::Process *a, const RTLIL::Process *b)
|
||||
{
|
||||
if (a->name != b->name) return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (a->meta_->name != b->meta_->name) return "name mismatch: " + std::string(a->module->design->twines.str(a->meta_->name)) + " != " + b->module->design->twines.str(b->meta_->name);
|
||||
if (std::string mismatch = compare_attributes(a, b); !mismatch.empty())
|
||||
return mismatch;
|
||||
if (std::string mismatch = compare_case_rules(&a->root_case, &b->root_case); !mismatch.empty())
|
||||
|
|
@ -293,13 +289,13 @@ public:
|
|||
{
|
||||
for (auto &it : mod_a->processes) {
|
||||
if (mod_b->processes.count(it.first) == 0)
|
||||
error("Module %s missing process %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
error("Module %s missing process %s in second design.\n", log_id(mod_a), log_id(it.second));
|
||||
if (std::string mismatch = compare_processes(it.second, mod_b->processes.at(it.first)); !mismatch.empty())
|
||||
error("Module %s process %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch.c_str());
|
||||
error("Module %s process %s %s.\n", log_id(mod_a), log_id(it.second), mismatch.c_str());
|
||||
}
|
||||
for (auto &it : mod_b->processes)
|
||||
if (mod_a->processes.count(it.first) == 0)
|
||||
error("Module %s missing process %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
error("Module %s missing process %s in first design.\n", log_id(mod_b), log_id(it.second));
|
||||
}
|
||||
|
||||
void check_connections()
|
||||
|
|
@ -307,23 +303,23 @@ public:
|
|||
const auto &conns_a = mod_a->connections();
|
||||
const auto &conns_b = mod_b->connections();
|
||||
if (conns_a.size() != conns_b.size()) {
|
||||
error("Module %s connection count differs: %zu != %zu\n", mod_a->name.unescape(), conns_a.size(), conns_b.size());
|
||||
error("Module %s connection count differs: %zu != %zu\n", log_id(mod_a), conns_a.size(), conns_b.size());
|
||||
} else {
|
||||
for (size_t i = 0; i < conns_a.size(); i++) {
|
||||
if (!compare_sigspec(conns_a[i].first, conns_b[i].first))
|
||||
error("Module %s connection %zu LHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first));
|
||||
error("Module %s connection %zu LHS %s != %s.\n", log_id(mod_a), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first));
|
||||
if (!compare_sigspec(conns_a[i].second, conns_b[i].second))
|
||||
error("Module %s connection %zu RHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second));
|
||||
error("Module %s connection %zu RHS %s != %s.\n", log_id(mod_a), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
if (mod_a->name != mod_b->name)
|
||||
error("Modules have different names: %s != %s\n", mod_a->name.unescape(), mod_b->name.unescape());
|
||||
if (mod_a->meta_->name != mod_b->meta_->name)
|
||||
error("Modules have different names: %s != %s\n", log_id(mod_a), log_id(mod_b));
|
||||
if (std::string mismatch = compare_attributes(mod_a, mod_b); !mismatch.empty())
|
||||
error("Module %s %s.\n", mod_a->name.unescape(), mismatch);
|
||||
error("Module %s %s.\n", log_id(mod_a), mismatch);
|
||||
check_wires();
|
||||
check_cells();
|
||||
check_memories();
|
||||
|
|
@ -356,16 +352,16 @@ struct DesignEqualPass : public Pass {
|
|||
|
||||
for (auto &it : design->modules_) {
|
||||
RTLIL::Module *mod = it.second;
|
||||
if (!other->has(mod->name))
|
||||
log_error("Second design missing module %s.\n", mod->name.unescape());
|
||||
if (!other->has(it.first))
|
||||
log_error("Second design missing module %s.\n", log_id(mod));
|
||||
|
||||
ModuleComparator cmp(mod, other->module(mod->name));
|
||||
ModuleComparator cmp(mod, other->module(it.first));
|
||||
cmp.check();
|
||||
}
|
||||
for (auto &it : other->modules_) {
|
||||
RTLIL::Module *mod = it.second;
|
||||
if (!design->has(mod->name))
|
||||
log_error("First design missing module %s.\n", mod->name.unescape());
|
||||
if (!design->has(it.first))
|
||||
log_error("First design missing module %s.\n", log_id(mod));
|
||||
}
|
||||
|
||||
log("Designs are identical.\n");
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ struct DftTagWorker {
|
|||
}
|
||||
|
||||
for (auto cell : overwrite_cells) {
|
||||
log_debug("Applying $overwrite_tag %s for signal %s\n", cell->name.unescape(), log_signal(cell->getPort(TW::A)));
|
||||
log_debug("Applying $overwrite_tag %s for signal %s\n", cell->module->design->twines.str(cell->meta_->name), log_signal(cell->getPort(TW::A)));
|
||||
SigSpec orig_signal = cell->getPort(TW::A);
|
||||
SigSpec interposed_signal = divert_users(orig_signal);
|
||||
auto *set_tag_cell = module->addSetTag(NEW_ID, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
|
||||
auto *set_tag_cell = module->addSetTag(module->design->twines.add(NEW_TWINE), cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
|
||||
modwalker.add_cell(set_tag_cell); // Make sure the next $overwrite_tag sees the new connections
|
||||
design_changed = true;
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ struct DftTagWorker {
|
|||
|
||||
void divert_users(SigBit driver_bit, SigBit interposed_bit)
|
||||
{
|
||||
dict<std::pair<Cell *, IdString>, SigSpec> updated_ports;
|
||||
dict<std::pair<Cell *, TwineRef>, SigSpec> updated_ports;
|
||||
// TODO also check module outputs
|
||||
auto found = modwalker.signal_consumers.find(driver_bit);
|
||||
if (found == modwalker.signal_consumers.end())
|
||||
|
|
@ -141,7 +141,7 @@ struct DftTagWorker {
|
|||
continue;
|
||||
if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit)
|
||||
continue;
|
||||
std::pair<Cell *, IdString> key = {consumer.cell, consumer.port};
|
||||
std::pair<Cell *, TwineRef> key = {consumer.cell, consumer.port};
|
||||
auto found_port = updated_ports.find(key);
|
||||
if (found_port == updated_ports.end()) {
|
||||
updated_ports.emplace(key, consumer.cell->getPort(consumer.port));
|
||||
|
|
@ -318,7 +318,7 @@ struct DftTagWorker {
|
|||
if (!GetSize(combined))
|
||||
combined = tag_sig;
|
||||
else
|
||||
combined = autoOr(NEW_ID, combined, tag_sig);
|
||||
combined = autoOr(NEW_TWINE, combined, tag_sig);
|
||||
}
|
||||
|
||||
if (!GetSize(combined))
|
||||
|
|
@ -486,8 +486,8 @@ struct DftTagWorker {
|
|||
if (cell_tag == tag) {
|
||||
auto &sig_set = cell->getPort(TW::SET);
|
||||
auto &sig_clr = cell->getPort(TW::CLR);
|
||||
tag_sig_a = autoAnd(NEW_ID, tag_sig_a, autoNot(NEW_ID, sig_clr));
|
||||
tag_sig_a = autoOr(NEW_ID, tag_sig_a, sig_set);
|
||||
tag_sig_a = autoAnd(NEW_TWINE, tag_sig_a, autoNot(NEW_TWINE, sig_clr));
|
||||
tag_sig_a = autoOr(NEW_TWINE, tag_sig_a, sig_set);
|
||||
}
|
||||
|
||||
emit_tag_signal(tag, sig_y, tag_sig_a);
|
||||
|
|
@ -529,9 +529,9 @@ struct DftTagWorker {
|
|||
inv_b ^= true;
|
||||
|
||||
if (inv_a)
|
||||
sig_a = autoNot(NEW_ID, sig_a);
|
||||
sig_a = autoNot(NEW_TWINE, sig_a);
|
||||
if (inv_b)
|
||||
sig_b = autoNot(NEW_ID, sig_b);
|
||||
sig_b = autoNot(NEW_TWINE, sig_b);
|
||||
|
||||
auto group_sig_a = tag_group_signal(tag, sig_a);
|
||||
auto group_sig_b = tag_group_signal(tag, sig_b);
|
||||
|
|
@ -541,15 +541,15 @@ struct DftTagWorker {
|
|||
|
||||
|
||||
// Does this input allow propagating (doesn't fix output or same tag group)
|
||||
sig_a = autoOr(NEW_ID, sig_a, group_sig_a);
|
||||
sig_b = autoOr(NEW_ID, sig_b, group_sig_b);
|
||||
sig_a = autoOr(NEW_TWINE, sig_a, group_sig_a);
|
||||
sig_b = autoOr(NEW_TWINE, sig_b, group_sig_b);
|
||||
|
||||
// Mask input tags by whether the other side allows propagation
|
||||
tag_sig_a = autoAnd(NEW_ID, tag_sig_a, sig_b);
|
||||
tag_sig_b = autoAnd(NEW_ID, tag_sig_b, sig_a);
|
||||
tag_sig_a = autoAnd(NEW_TWINE, tag_sig_a, sig_b);
|
||||
tag_sig_b = autoAnd(NEW_TWINE, tag_sig_b, sig_a);
|
||||
|
||||
|
||||
auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b);
|
||||
auto tag_sig = autoOr(NEW_TWINE, tag_sig_a, tag_sig_b);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
}
|
||||
|
|
@ -566,7 +566,7 @@ struct DftTagWorker {
|
|||
auto tag_sig_a = tag_signal(tag, sig_a);
|
||||
auto tag_sig_b = tag_signal(tag, sig_b);
|
||||
|
||||
auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b);
|
||||
auto tag_sig = autoOr(NEW_TWINE, tag_sig_a, tag_sig_b);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
}
|
||||
|
|
@ -585,23 +585,23 @@ struct DftTagWorker {
|
|||
auto group_sig_b = tag_group_signal(tag, sig_b);
|
||||
auto group_sig_s = tag_group_signal(tag, sig_s);
|
||||
|
||||
auto prop_s = autoOr(NEW_ID,
|
||||
autoXor(NEW_ID, sig_a, sig_b),
|
||||
autoOr(NEW_ID, group_sig_a, group_sig_b));
|
||||
auto prop_s = autoOr(NEW_TWINE,
|
||||
autoXor(NEW_TWINE, sig_a, sig_b),
|
||||
autoOr(NEW_TWINE, group_sig_a, group_sig_b));
|
||||
|
||||
auto prop_a = autoOr(NEW_ID, autoNot(NEW_ID, sig_s), group_sig_s);
|
||||
auto prop_b = autoOr(NEW_ID, sig_s, group_sig_s);
|
||||
auto prop_a = autoOr(NEW_TWINE, autoNot(NEW_TWINE, sig_s), group_sig_s);
|
||||
auto prop_b = autoOr(NEW_TWINE, sig_s, group_sig_s);
|
||||
|
||||
auto tag_sig_a = tag_signal(tag, sig_a);
|
||||
auto tag_sig_b = tag_signal(tag, sig_b);
|
||||
auto tag_sig_s = tag_signal(tag, sig_s);
|
||||
|
||||
tag_sig_a = autoAnd(NEW_ID, tag_sig_a, prop_a);
|
||||
tag_sig_b = autoAnd(NEW_ID, tag_sig_b, prop_b);
|
||||
tag_sig_s = autoAnd(NEW_ID, tag_sig_s, prop_s);
|
||||
tag_sig_a = autoAnd(NEW_TWINE, tag_sig_a, prop_a);
|
||||
tag_sig_b = autoAnd(NEW_TWINE, tag_sig_b, prop_b);
|
||||
tag_sig_s = autoAnd(NEW_TWINE, tag_sig_s, prop_s);
|
||||
|
||||
auto tag_sig = autoOr(NEW_ID, tag_sig_s,
|
||||
autoOr(NEW_ID, tag_sig_a, tag_sig_b));
|
||||
auto tag_sig = autoOr(NEW_TWINE, tag_sig_s,
|
||||
autoOr(NEW_TWINE, tag_sig_a, tag_sig_b));
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
}
|
||||
|
|
@ -620,15 +620,15 @@ struct DftTagWorker {
|
|||
auto tag_sig_a = tag_signal(tag, sig_a);
|
||||
auto tag_sig_b = tag_signal(tag, sig_b);
|
||||
|
||||
auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b);
|
||||
auto group_sig = autoOr(NEW_TWINE, group_sig_a, group_sig_b);
|
||||
// The output can only be affected by the tagged inputs if all group-untagged bits are equal
|
||||
|
||||
auto masked_a = autoOr(NEW_ID, sig_a, group_sig);
|
||||
auto masked_b = autoOr(NEW_ID, sig_b, group_sig);
|
||||
auto masked_a = autoOr(NEW_TWINE, sig_a, group_sig);
|
||||
auto masked_b = autoOr(NEW_TWINE, sig_b, group_sig);
|
||||
|
||||
auto prop = autoEq(NEW_ID, masked_a, masked_b);
|
||||
auto prop = autoEq(NEW_TWINE, masked_a, masked_b);
|
||||
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b}));
|
||||
auto tag_sig = autoAnd(NEW_TWINE, prop, autoReduceOr(NEW_TWINE, {tag_sig_a, tag_sig_b}));
|
||||
tag_sig.extend_u0(GetSize(sig_y), false);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
|
|
@ -652,15 +652,15 @@ struct DftTagWorker {
|
|||
auto tag_sig_a = tag_signal(tag, sig_a);
|
||||
auto tag_sig_b = tag_signal(tag, sig_b);
|
||||
|
||||
auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b);
|
||||
auto group_sig = autoOr(NEW_TWINE, group_sig_a, group_sig_b);
|
||||
// The output can only be affected by the tagged inputs if the greatest possible sig_a is
|
||||
// greater or equal to the least possible sig_b
|
||||
auto masked_a = autoOr(NEW_ID, sig_a, group_sig);
|
||||
auto masked_b = autoAnd(NEW_ID, sig_b, autoNot(NEW_ID, group_sig));
|
||||
auto masked_a = autoOr(NEW_TWINE, sig_a, group_sig);
|
||||
auto masked_b = autoAnd(NEW_TWINE, sig_b, autoNot(NEW_TWINE, group_sig));
|
||||
|
||||
auto prop = autoGe(NEW_ID, masked_a, masked_b);
|
||||
auto prop = autoGe(NEW_TWINE, masked_a, masked_b);
|
||||
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b}));
|
||||
auto tag_sig = autoAnd(NEW_TWINE, prop, autoReduceOr(NEW_TWINE, {tag_sig_a, tag_sig_b}));
|
||||
tag_sig.extend_u0(GetSize(sig_y), false);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
|
|
@ -674,13 +674,13 @@ struct DftTagWorker {
|
|||
auto tag_sig_a = tag_signal(tag, sig_a);
|
||||
|
||||
if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not)))
|
||||
sig_a = autoNot(NEW_ID, sig_a);
|
||||
sig_a = autoNot(NEW_TWINE, sig_a);
|
||||
|
||||
auto filled = autoOr(NEW_ID, sig_a, group_sig_a);
|
||||
auto filled = autoOr(NEW_TWINE, sig_a, group_sig_a);
|
||||
|
||||
auto prop = autoReduceAnd(NEW_ID, filled);
|
||||
auto tagged = autoReduceOr(NEW_ID, tag_sig_a);
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, tagged);
|
||||
auto prop = autoReduceAnd(NEW_TWINE, filled);
|
||||
auto tagged = autoReduceOr(NEW_TWINE, tag_sig_a);
|
||||
auto tag_sig = autoAnd(NEW_TWINE, prop, tagged);
|
||||
tag_sig.extend_u0(GetSize(sig_y), false);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
|
|
@ -727,7 +727,7 @@ struct DftTagWorker {
|
|||
}
|
||||
}
|
||||
|
||||
SigBit any_tagged = autoReduceOr(NEW_ID, tag_input);
|
||||
SigBit any_tagged = autoReduceOr(NEW_TWINE, tag_input);
|
||||
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (cell->output(conn.first)) {
|
||||
|
|
@ -772,7 +772,7 @@ struct DftTagWorker {
|
|||
continue;
|
||||
|
||||
int index = 0;
|
||||
auto name = module->uniquify(stringf("%s:%s", wire->name, tag.c_str() + 1), index);
|
||||
auto name = module->uniquify(module->design->twines.add(Twine{stringf("%s:%s", wire->name, tag.c_str() + 1)}), index);
|
||||
auto hdlname = wire->get_hdlname_attribute();
|
||||
|
||||
if (!hdlname.empty())
|
||||
|
|
@ -826,7 +826,7 @@ struct DftTagWorker {
|
|||
}
|
||||
|
||||
|
||||
SigSpec autoAnd(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoAnd(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a.is_fully_zero() || sig_b.is_fully_ones() || sig_a == sig_b)
|
||||
|
|
@ -834,10 +834,10 @@ struct DftTagWorker {
|
|||
if (sig_a.is_fully_ones() || sig_b.is_fully_zero())
|
||||
return sig_b;
|
||||
|
||||
return module->And(name, sig_a, sig_b);
|
||||
return module->And(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoOr(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoOr(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a.is_fully_ones() || sig_b.is_fully_zero() || sig_a == sig_b)
|
||||
|
|
@ -845,10 +845,10 @@ struct DftTagWorker {
|
|||
if (sig_a.is_fully_zero() || sig_b.is_fully_ones())
|
||||
return sig_b;
|
||||
|
||||
return module->Or(name, sig_a, sig_b);
|
||||
return module->Or(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoXor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoXor(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
|
|
@ -858,13 +858,13 @@ struct DftTagWorker {
|
|||
if (sig_b.is_fully_zero())
|
||||
return sig_a;
|
||||
if (sig_a.is_fully_ones())
|
||||
return autoNot(name, sig_b);
|
||||
return autoNot(std::move(name), sig_b);
|
||||
if (sig_b.is_fully_ones())
|
||||
return autoNot(name, sig_a);
|
||||
return module->Xor(name, sig_a, sig_b);
|
||||
return autoNot(std::move(name), sig_a);
|
||||
return module->Xor(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoXnor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoXnor(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
|
|
@ -874,13 +874,13 @@ struct DftTagWorker {
|
|||
if (sig_b.is_fully_ones())
|
||||
return sig_a;
|
||||
if (sig_a.is_fully_zero())
|
||||
return autoNot(name, sig_b);
|
||||
return autoNot(std::move(name), sig_b);
|
||||
if (sig_b.is_fully_zero())
|
||||
return autoNot(name, sig_a);
|
||||
return module->Xnor(name, sig_a, sig_b);
|
||||
return autoNot(std::move(name), sig_a);
|
||||
return module->Xnor(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoNot(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoNot(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (sig_a.is_fully_const()) {
|
||||
auto const_val = sig_a.as_const();
|
||||
|
|
@ -890,10 +890,10 @@ struct DftTagWorker {
|
|||
}
|
||||
return const_val;
|
||||
}
|
||||
return module->Not(name, sig_a);
|
||||
return module->Not(std::move(name), sig_a);
|
||||
}
|
||||
|
||||
SigSpec autoEq(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoEq(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
|
|
@ -908,10 +908,10 @@ struct DftTagWorker {
|
|||
return State::S0;
|
||||
}
|
||||
|
||||
return module->Eq(name, sig_a, sig_b);
|
||||
return module->Eq(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoGe(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoGe(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b || sig_a.is_fully_ones())
|
||||
|
|
@ -919,10 +919,10 @@ struct DftTagWorker {
|
|||
if (sig_b.is_fully_zero())
|
||||
return State::S1;
|
||||
|
||||
return module->Ge(name, sig_a, sig_b);
|
||||
return module->Ge(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoReduceAnd(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoReduceAnd(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (GetSize(sig_a) == 0)
|
||||
return State::S1;
|
||||
|
|
@ -934,10 +934,10 @@ struct DftTagWorker {
|
|||
return State::S0;
|
||||
if (sig_a.is_fully_ones())
|
||||
return State::S1;
|
||||
return module->ReduceAnd(name, sig_a);
|
||||
return module->ReduceAnd(std::move(name), sig_a);
|
||||
}
|
||||
|
||||
SigSpec autoReduceOr(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoReduceOr(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (GetSize(sig_a) == 0)
|
||||
return State::S0;
|
||||
|
|
@ -949,7 +949,7 @@ struct DftTagWorker {
|
|||
return State::S1;
|
||||
if (sig_a.is_fully_zero())
|
||||
return State::S0;
|
||||
return module->ReduceOr(name, sig_a);
|
||||
return module->ReduceOr(std::move(name), sig_a);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58,24 +58,24 @@ struct EdgetypePass : public Pass {
|
|||
for (auto module : design->selected_modules())
|
||||
{
|
||||
SigMap sigmap(module);
|
||||
dict<SigBit, pool<tuple<IdString, IdString, int>>> bit_sources, bit_sinks;
|
||||
pool<std::pair<IdString, IdString>> multibit_ports;
|
||||
dict<SigBit, pool<tuple<IdString, TwineRef, int>>> bit_sources, bit_sinks;
|
||||
pool<std::pair<IdString, TwineRef>> multibit_ports;
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
for (auto conn : cell->connections())
|
||||
{
|
||||
IdString cell_type = cell->type;
|
||||
IdString port_name = conn.first;
|
||||
TwineRef port_name = conn.first;
|
||||
SigSpec sig = sigmap(conn.second);
|
||||
|
||||
if (GetSize(sig) > 1)
|
||||
multibit_ports.insert(std::pair<IdString, IdString>(cell_type, port_name));
|
||||
multibit_ports.insert(std::pair<IdString, TwineRef>(cell_type, port_name));
|
||||
|
||||
for (int i = 0; i < GetSize(sig); i++) {
|
||||
if (cell->output(port_name))
|
||||
bit_sources[sig[i]].insert(tuple<IdString, IdString, int>(cell_type, port_name, i));
|
||||
bit_sources[sig[i]].insert(tuple<IdString, TwineRef, int>(cell_type, port_name, i));
|
||||
if (cell->input(port_name))
|
||||
bit_sinks[sig[i]].insert(tuple<IdString, IdString, int>(cell_type, port_name, i));
|
||||
bit_sinks[sig[i]].insert(tuple<IdString, TwineRef, int>(cell_type, port_name, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,13 +91,13 @@ struct EdgetypePass : public Pass {
|
|||
auto sink_port_name = std::get<1>(sink);
|
||||
auto sink_bit_index = std::get<2>(sink);
|
||||
|
||||
string source_str = multibit_ports.count(std::pair<IdString, IdString>(source_cell_type, source_port_name)) ?
|
||||
stringf("%s.%s[%d]", source_cell_type.unescape(), source_port_name.unescape(), source_bit_index) :
|
||||
stringf("%s.%s", source_cell_type.unescape(), source_port_name.unescape());
|
||||
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());
|
||||
|
||||
string sink_str = multibit_ports.count(std::pair<IdString, IdString>(sink_cell_type, sink_port_name)) ?
|
||||
stringf("%s.%s[%d]", sink_cell_type.unescape(), sink_port_name.unescape(), sink_bit_index) :
|
||||
stringf("%s.%s", sink_cell_type.unescape(), sink_port_name.unescape());
|
||||
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());
|
||||
|
||||
edge_cache.insert(source_str + " " + sink_str);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ struct ExampleDtPass : public Pass
|
|||
}
|
||||
else
|
||||
{
|
||||
node.set_function(ExampleFn(ID($$cell_output), {{port_chunk.port, {}}}));
|
||||
node.set_function(ExampleFn(ID($$cell_output), {{RTLIL::escape_id(module->design->twines.str(port_chunk.port)), {}}}));
|
||||
node.append_arg(enqueue(DriveBitMarker(cells(port_chunk.cell), 0)));
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ private:
|
|||
|
||||
//Get a SigSpec for the corresponding taint signal for the cell port, creating one if necessary:
|
||||
if (sig.is_wire()) {
|
||||
RTLIL::Wire *w = module->wire(sig.as_wire()->name.str() + "_t");
|
||||
if (w == nullptr) w = module->addWire(sig.as_wire()->name.str() + "_t", 1);
|
||||
TwineRef taint_name_ref = module->design->twines.add(Twine{sig.as_wire()->name.str() + "_t"});
|
||||
RTLIL::Wire *w = module->wire(taint_name_ref);
|
||||
if (w == nullptr) w = module->addWire(Twine{sig.as_wire()->name.str() + "_t"}, 1);
|
||||
ret = w;
|
||||
}
|
||||
else if (sig.is_fully_const() && opt_taintconstants)
|
||||
|
|
@ -70,34 +71,34 @@ 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_));
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(cell->name.str() + "_t_1_3", is_and? port_a : n_port_a, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr2 = module->And(cell->name.str() + "_t_1_4", is_and? port_b : n_port_b, port_a_taint, false, cell->src_ref());
|
||||
auto subexpr3 = module->And(cell->name.str() + "_t_1_5", port_a_taint, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr4 = module->Or(cell->name.str() + "_t_1_6", subexpr1, subexpr2, false, cell->src_ref());
|
||||
module->addOr(cell->name.str() + "_t_1_7", subexpr4, subexpr3, port_y_taint, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_1_1"}, port_a, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_1_2"}, port_b, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_1_3"}, is_and? port_a : n_port_a, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr2 = module->And(Twine{cell->name.str() + "_t_1_4"}, is_and? port_b : n_port_b, port_a_taint, false, cell->src_ref());
|
||||
auto subexpr3 = module->And(Twine{cell->name.str() + "_t_1_5"}, port_a_taint, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr4 = module->Or(Twine{cell->name.str() + "_t_1_6"}, subexpr1, subexpr2, false, cell->src_ref());
|
||||
module->addOr(Twine{cell->name.str() + "_t_1_7"}, subexpr4, subexpr3, port_y_taint, false, cell->src_ref());
|
||||
}
|
||||
|
||||
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_));
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(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(cell->name.str() + "_t_2_3", is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_2_1"}, port_a, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_2_2"}, is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->src_ref());
|
||||
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());
|
||||
}
|
||||
|
||||
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_));
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(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(cell->name.str() + "_t_3_3", is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_3_1"}, port_b, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_3_2"}, is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->src_ref());
|
||||
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());
|
||||
}
|
||||
|
||||
void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) {
|
||||
//AKA AN2_SH5 or OR2_SH5 or XR2_SH2
|
||||
module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->src_ref());
|
||||
module->addOr(Twine{cell->name.str() + "_t_4_1"}, port_a_taint, port_b_taint, port_y_taint, false, cell->src_ref());
|
||||
}
|
||||
|
||||
void add_imprecise_GLIFT_logic_4(RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_y_taint) {
|
||||
|
|
@ -118,22 +119,22 @@ private:
|
|||
|
||||
void add_precise_GLIFT_mux(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_s, RTLIL::SigSpec &port_s_taint, RTLIL::SigSpec &port_y_taint) {
|
||||
//S&At | ~S&Bt | ~A&B&St | A&~B&St | At&St | Bt&St
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_4_1", port_a, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_4_2", port_b, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_s = module->LogicNot(cell->name.str() + "_t_4_3", port_s, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(cell->name.str() + "_t_4_4", port_s, port_a_taint, false, cell->src_ref());
|
||||
auto subexpr2 = module->And(cell->name.str() + "_t_4_5", n_port_s, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr3 = module->And(cell->name.str() + "_t_4_6", n_port_a, port_b, false, cell->src_ref());
|
||||
auto subexpr4 = module->And(cell->name.str() + "_t_4_7", subexpr3, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr5 = module->And(cell->name.str() + "_t_4_8", port_a, n_port_b, false, cell->src_ref());
|
||||
auto subexpr6 = module->And(cell->name.str() + "_t_4_9", subexpr5, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr7 = module->And(cell->name.str() + "_t_4_10", port_a_taint, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr8 = module->And(cell->name.str() + "_t_4_11", port_b_taint, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr9 = module->Or(cell->name.str() + "_t_4_12", subexpr1, subexpr2, false, cell->src_ref());
|
||||
auto subexpr10 = module->Or(cell->name.str() + "_t_4_13", subexpr4, subexpr6, false, cell->src_ref());
|
||||
auto subexpr11 = module->Or(cell->name.str() + "_t_4_14", subexpr7, subexpr8, false, cell->src_ref());
|
||||
auto subexpr12 = module->Or(cell->name.str() + "_t_4_15", subexpr9, subexpr10, false, cell->src_ref());
|
||||
module->addOr(cell->name.str() + "_t_4_16", subexpr11, subexpr12, port_y_taint, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_a = module->LogicNot(Twine{cell->name.str() + "_t_4_1"}, port_a, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_b = module->LogicNot(Twine{cell->name.str() + "_t_4_2"}, port_b, false, cell->src_ref());
|
||||
RTLIL::SigSpec n_port_s = module->LogicNot(Twine{cell->name.str() + "_t_4_3"}, port_s, false, cell->src_ref());
|
||||
auto subexpr1 = module->And(Twine{cell->name.str() + "_t_4_4"}, port_s, port_a_taint, false, cell->src_ref());
|
||||
auto subexpr2 = module->And(Twine{cell->name.str() + "_t_4_5"}, n_port_s, port_b_taint, false, cell->src_ref());
|
||||
auto subexpr3 = module->And(Twine{cell->name.str() + "_t_4_6"}, n_port_a, port_b, false, cell->src_ref());
|
||||
auto subexpr4 = module->And(Twine{cell->name.str() + "_t_4_7"}, subexpr3, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr5 = module->And(Twine{cell->name.str() + "_t_4_8"}, port_a, n_port_b, false, cell->src_ref());
|
||||
auto subexpr6 = module->And(Twine{cell->name.str() + "_t_4_9"}, subexpr5, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr7 = module->And(Twine{cell->name.str() + "_t_4_10"}, port_a_taint, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr8 = module->And(Twine{cell->name.str() + "_t_4_11"}, port_b_taint, port_s_taint, false, cell->src_ref());
|
||||
auto subexpr9 = module->Or(Twine{cell->name.str() + "_t_4_12"}, subexpr1, subexpr2, false, cell->src_ref());
|
||||
auto subexpr10 = module->Or(Twine{cell->name.str() + "_t_4_13"}, subexpr4, subexpr6, false, cell->src_ref());
|
||||
auto subexpr11 = module->Or(Twine{cell->name.str() + "_t_4_14"}, subexpr7, subexpr8, false, cell->src_ref());
|
||||
auto subexpr12 = module->Or(Twine{cell->name.str() + "_t_4_15"}, subexpr9, subexpr10, false, cell->src_ref());
|
||||
module->addOr(Twine{cell->name.str() + "_t_4_16"}, subexpr11, subexpr12, port_y_taint, false, cell->src_ref());
|
||||
}
|
||||
|
||||
RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select, const RTLIL::IdString celltype) {
|
||||
|
|
@ -143,8 +144,8 @@ private:
|
|||
//The complex model is an area model, so a lower score should mean smaller.
|
||||
//In this case, a nonzero hole metamux select value means less logic.
|
||||
//Thus we should invert the ReduceOr over the metamux_select signal.
|
||||
RTLIL::SigSpec pmux_select = module->ReduceOr(metamux_select.as_wire()->name.str() + "_nonzero", metamux_select);
|
||||
return module->Pmux(NEW_ID, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->src_ref());
|
||||
RTLIL::SigSpec pmux_select = module->ReduceOr(Twine{metamux_select.as_wire()->name.str() + "_nonzero"}, metamux_select);
|
||||
return module->Pmux(NEW_TWINE, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->src_ref());
|
||||
} else {
|
||||
auto select_width = metamux_select.as_wire()->width;
|
||||
|
||||
|
|
@ -163,7 +164,7 @@ private:
|
|||
std::vector<RTLIL::SigSpec> next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + exp2(select_width));
|
||||
for (auto i = 0; pmux_y_ports.size() > 1; ++i) {
|
||||
for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) {
|
||||
next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name, i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->src_ref()));
|
||||
next_pmux_y_ports.emplace_back(module->Pmux(Twine{stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j)}, pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->src_ref()));
|
||||
}
|
||||
if (GetSize(pmux_y_ports) % 2 == 1)
|
||||
next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]);
|
||||
|
|
@ -206,7 +207,7 @@ private:
|
|||
int num_versions = opt_instrumentmore? 8 : 4;
|
||||
|
||||
for (auto i = 1; i <= num_versions; ++i)
|
||||
taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name, i), 1)));
|
||||
taint_version.emplace_back(RTLIL::SigSpec(module->addWire(Twine{stringf("%s_y%d", cell->name.c_str(), i)}, 1)));
|
||||
|
||||
for (auto i = 0; i < num_versions; ++i) {
|
||||
switch(i) {
|
||||
|
|
@ -232,14 +233,14 @@ private:
|
|||
|
||||
auto select_width = log2(num_versions);
|
||||
log_assert(exp2(select_width) == num_versions);
|
||||
RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width));
|
||||
RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width));
|
||||
meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type));
|
||||
module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->src_ref()));
|
||||
module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref()));
|
||||
|
||||
std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version);
|
||||
for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) {
|
||||
for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) {
|
||||
next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name, i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i]));
|
||||
next_meta_mux_y_ports.emplace_back(module->Mux(Twine{stringf("%s_mux_%d_%d", cell->name.c_str(), i, j)}, meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i]));
|
||||
}
|
||||
if (GetSize(meta_mux_y_ports) % 2 == 1)
|
||||
next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]);
|
||||
|
|
@ -271,7 +272,7 @@ private:
|
|||
log_assert(exp2(select_width) == num_versions);
|
||||
|
||||
for (auto i = 1; i <= num_versions; ++i)
|
||||
taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name, i), 1)));
|
||||
taint_version.emplace_back(RTLIL::SigSpec(module->addWire(Twine{stringf("%s_y%d", cell->name.c_str(), i)}, 1)));
|
||||
|
||||
for (auto i = 0; i < num_versions; ++i) {
|
||||
switch(i) {
|
||||
|
|
@ -287,14 +288,14 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width));
|
||||
RTLIL::SigSpec meta_mux_select(module->addWire(Twine{cell->name.str() + "_sel"}, select_width));
|
||||
meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type));
|
||||
module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->src_ref()));
|
||||
module->connect(meta_mux_select, module->Anyconst(module->design->twines.add(Twine{cell->name.str() + "_hole"}), select_width, cell->src_ref()));
|
||||
|
||||
std::vector<RTLIL::SigSpec> next_meta_mux_y_ports, meta_mux_y_ports(taint_version);
|
||||
for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) {
|
||||
for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) {
|
||||
next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name, i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i]));
|
||||
next_meta_mux_y_ports.emplace_back(module->Mux(Twine{stringf("%s_mux_%d_%d", cell->name.c_str(), i, j)}, meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i]));
|
||||
}
|
||||
if (GetSize(meta_mux_y_ports) % 2 == 1)
|
||||
next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]);
|
||||
|
|
@ -342,15 +343,15 @@ private:
|
|||
//recurse to GLIFT model the child module. However, we need to augment the ports list
|
||||
//with taint signals and connect the new ports to the corresponding taint signals.
|
||||
RTLIL::Module *cell_module_def = module->design->module(cell->type);
|
||||
dict<RTLIL::IdString, RTLIL::SigSpec> orig_ports = cell->connections();
|
||||
log("Adding cell %s\n", cell_module_def->name);
|
||||
auto orig_ports = cell->connections();
|
||||
log("Adding cell %s\n", module->design->twines.str(cell_module_def->meta_->name).c_str());
|
||||
for (auto &it : orig_ports) {
|
||||
RTLIL::SigSpec port = it.second;
|
||||
RTLIL::SigSpec port_taint = get_corresponding_taint_signal(port);
|
||||
|
||||
log_assert(port_taint.is_wire());
|
||||
log_assert(std::find(cell_module_def->ports.begin(), cell_module_def->ports.end(), port_taint.as_wire()->name) != cell_module_def->ports.end());
|
||||
cell->setPort(port_taint.as_wire()->name, port_taint);
|
||||
log_assert(std::find(cell_module_def->ports.begin(), cell_module_def->ports.end(), port_taint.as_wire()->meta_->name) != cell_module_def->ports.end());
|
||||
cell->setPort(module->design->twines.add(Twine{module->design->twines.str(port_taint.as_wire()->meta_->name) + "_t"}), port_taint);
|
||||
}
|
||||
}
|
||||
else log_cmd_error("This is a bug (4).\n");
|
||||
|
|
@ -378,7 +379,7 @@ private:
|
|||
for (unsigned int i = 0; meta_mux_select_sums.size() > 1; ) {
|
||||
meta_mux_select_sums_buf.clear();
|
||||
for (i = 0; i + 1 < meta_mux_select_sums.size(); i += 2) {
|
||||
meta_mux_select_sums_buf.push_back(module->Add(meta_mux_select_sums[i].as_wire()->name.str() + "_add", meta_mux_select_sums[i], meta_mux_select_sums[i+1], false));
|
||||
meta_mux_select_sums_buf.push_back(module->Add(Twine{module->design->twines.str(meta_mux_select_sums[i].as_wire()->meta_->name) + "_add"}, meta_mux_select_sums[i], meta_mux_select_sums[i+1], false));
|
||||
}
|
||||
if (meta_mux_select_sums.size() % 2 == 1)
|
||||
meta_mux_select_sums_buf.push_back(meta_mux_select_sums[meta_mux_select_sums.size()-1]);
|
||||
|
|
@ -387,7 +388,7 @@ private:
|
|||
if (meta_mux_select_sums.size() > 0) {
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\minimize");
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\keep");
|
||||
module->rename(meta_mux_select_sums[0].as_wire(), cost_model_wire_name);
|
||||
module->rename(meta_mux_select_sums[0].as_wire(), module->design->twines.add(Twine{cost_model_wire_name.str()}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +577,13 @@ struct GliftPass : public Pass {
|
|||
if (GetSize(design->selected_modules()) == 0)
|
||||
log_cmd_error("Can't operate on an empty selection!\n");
|
||||
|
||||
TopoSort<RTLIL::Module*, IdString::compare_ptr_by_name<RTLIL::Module>> topo_modules; //cribbed from passes/techmap/flatten.cc
|
||||
struct ModuleNameCmp {
|
||||
bool operator()(const RTLIL::Module *a, const RTLIL::Module *b) const {
|
||||
if (a == nullptr || b == nullptr) return a < b;
|
||||
return a->design->twines.str(a->meta_->name) < b->design->twines.str(b->meta_->name);
|
||||
}
|
||||
};
|
||||
TopoSort<RTLIL::Module*, ModuleNameCmp> topo_modules; //cribbed from passes/techmap/flatten.cc
|
||||
auto worklist = design->selected_modules();
|
||||
pool<RTLIL::IdString> non_top_modules;
|
||||
while (!worklist.empty()) {
|
||||
|
|
@ -600,7 +607,7 @@ struct GliftPass : public Pass {
|
|||
|
||||
for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) {
|
||||
RTLIL::Module *module = topo_modules.sorted[i];
|
||||
GliftWorker(module, !non_top_modules[module->name], opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore);
|
||||
GliftWorker(module, !non_top_modules[ID(module->design->twines.str(module->meta_->name))], opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore);
|
||||
}
|
||||
}
|
||||
} GliftPass;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ struct LibertyStubber {
|
|||
};
|
||||
void liberty_flop(Module* base, Module* derived, std::ostream& f)
|
||||
{
|
||||
auto base_name = base->name.str().substr(1);
|
||||
auto derived_name = derived->name.str().substr(1);
|
||||
auto base_name = base->design->twines.str(base->meta_->name).substr(1);
|
||||
auto derived_name = derived->design->twines.str(derived->meta_->name).substr(1);
|
||||
|
||||
FfTypeData ffType(base_name);
|
||||
LibertyItemizer i(f);
|
||||
|
|
@ -67,14 +67,14 @@ struct LibertyStubber {
|
|||
i.indent = 3;
|
||||
auto sorted_ports = derived->ports;
|
||||
// Hack for CLK and C coming before Q does
|
||||
auto cmp = [](IdString l, IdString r) { return l.str() < r.str(); };
|
||||
auto cmp = [derived](TwineRef l, TwineRef r) { return derived->design->twines.str(l) < derived->design->twines.str(r); };
|
||||
std::sort(sorted_ports.begin(), sorted_ports.end(), cmp);
|
||||
std::string clock_pin_name = "";
|
||||
for (auto x : sorted_ports) {
|
||||
std::string port_name = x.unescape();
|
||||
std::string port_name = derived->design->twines.str(x);
|
||||
bool is_input = base_type.inputs.count(x);
|
||||
bool is_output = base_type.outputs.count(x);
|
||||
f << "\t\tpin (" << x.unescape() << ") {\n";
|
||||
f << "\t\tpin (" << port_name << ") {\n";
|
||||
if (is_input && !is_output) {
|
||||
i.item("direction", "input");
|
||||
} else if (!is_input && is_output) {
|
||||
|
|
@ -117,8 +117,8 @@ struct LibertyStubber {
|
|||
}
|
||||
void liberty_cell(Module* base, Module* derived, std::ostream& f)
|
||||
{
|
||||
auto base_name = base->name.str().substr(1);
|
||||
auto derived_name = derived->name.str().substr(1);
|
||||
auto base_name = base->design->twines.str(base->meta_->name).substr(1);
|
||||
auto derived_name = derived->design->twines.str(derived->meta_->name).substr(1);
|
||||
if (!ct.cell_types.count(base_name)) {
|
||||
log_debug("skip skeleton for %s\n", base_name.c_str());
|
||||
return;
|
||||
|
|
@ -130,9 +130,10 @@ struct LibertyStubber {
|
|||
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);
|
||||
bool is_input = base_type.inputs.count(x);
|
||||
bool is_output = base_type.outputs.count(x);
|
||||
f << "\t\tpin (" << x.unescape() << ") {\n";
|
||||
f << "\t\tpin (" << port_name << ") {\n";
|
||||
if (is_input && !is_output) {
|
||||
f << "\t\t\tdirection : input;\n";
|
||||
} else if (!is_input && is_output) {
|
||||
|
|
@ -193,9 +194,10 @@ struct IcellLiberty : Pass {
|
|||
if (!inst_module || !inst_module->get_blackbox_attribute())
|
||||
continue;
|
||||
Module *base = inst_module;
|
||||
if (!done.count(base->name)) {
|
||||
auto base_name_id = ID(base->design->twines.str(base->meta_->name));
|
||||
if (!done.count(base_name_id)) {
|
||||
stubber.liberty_cell(base, base, *liberty_file);
|
||||
done.insert(base->name);
|
||||
done.insert(base_name_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ struct CoveragePass : public Pass {
|
|||
}
|
||||
}
|
||||
for (auto cell: module->cells()) {
|
||||
log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute(), cell->name.unescape());
|
||||
log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute(), cell->module->design->twines.str(cell->meta_->name));
|
||||
for (auto src: design->src_leaves(cell)) {
|
||||
auto filename = extract_src_filename(src);
|
||||
if (filename.empty()) continue;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ struct PrintAttrsPass : public Pass {
|
|||
for (auto mod : design->selected_modules())
|
||||
{
|
||||
if (design->selected_whole_module(mod)) {
|
||||
log("%s%s\n", get_indent_str(indent), mod->name.unescape());
|
||||
log("%s%s\n", get_indent_str(indent), log_id(mod));
|
||||
indent += 2;
|
||||
log_src(design, mod, indent);
|
||||
for (auto &it : mod->attributes)
|
||||
|
|
@ -79,7 +79,7 @@ struct PrintAttrsPass : public Pass {
|
|||
}
|
||||
|
||||
for (auto cell : mod->selected_cells()) {
|
||||
log("%s%s\n", get_indent_str(indent), cell->name.unescape());
|
||||
log("%s%s\n", get_indent_str(indent), cell->module->design->twines.str(cell->meta_->name));
|
||||
indent += 2;
|
||||
log_src(design, cell, indent);
|
||||
for (auto &it : cell->attributes)
|
||||
|
|
|
|||
|
|
@ -30,15 +30,17 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
|
|||
from_name = RTLIL::escape_id(from_name);
|
||||
to_name = RTLIL::escape_id(to_name);
|
||||
|
||||
if (module->count_id(to_name))
|
||||
log_cmd_error("There is already an object `%s' in module `%s'.\n", RTLIL::unescape_id(to_name), module->name);
|
||||
TwineRef to_ref = module->design->twines.lookup(to_name);
|
||||
if (module->count_id(to_ref))
|
||||
log_cmd_error("There is already an object `%s' in module `%s'.\n", RTLIL::unescape_id(to_name), log_id(module));
|
||||
|
||||
RTLIL::Wire *wire_to_rename = module->wire(from_name);
|
||||
RTLIL::Cell *cell_to_rename = module->cell(from_name);
|
||||
TwineRef from_ref = module->design->twines.lookup(from_name);
|
||||
RTLIL::Wire *wire_to_rename = module->wire(from_ref);
|
||||
RTLIL::Cell *cell_to_rename = module->cell(from_ref);
|
||||
|
||||
if (wire_to_rename != nullptr) {
|
||||
log("Renaming wire %s to %s in module %s.\n", wire_to_rename, RTLIL::unescape_id(to_name), module);
|
||||
module->rename(wire_to_rename, to_name);
|
||||
log("Renaming wire %s to %s in module %s.\n", log_id(wire_to_rename), RTLIL::unescape_id(to_name), log_id(module));
|
||||
module->rename(wire_to_rename, module->design->twines.add(Twine{to_name}));
|
||||
if (wire_to_rename->port_id || flag_output) {
|
||||
if (flag_output)
|
||||
wire_to_rename->port_output = true;
|
||||
|
|
@ -50,8 +52,8 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
|
|||
if (cell_to_rename != nullptr) {
|
||||
if (flag_output)
|
||||
log_cmd_error("Called with -output but the specified object is a cell.\n");
|
||||
log("Renaming cell %s to %s in module %s.\n", cell_to_rename, RTLIL::unescape_id(to_name), module);
|
||||
module->rename(cell_to_rename, to_name);
|
||||
log("Renaming cell %s to %s in module %s.\n", log_id(cell_to_rename), RTLIL::unescape_id(to_name), log_id(module));
|
||||
module->rename(cell_to_rename, module->design->twines.add(Twine{to_name}));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -105,8 +107,11 @@ static IdString derive_name_from_cell_output_wire(const RTLIL::Cell *cell, strin
|
|||
|
||||
RTLIL::Wire *wire;
|
||||
|
||||
if (move_to_cell && (!(wire = cell->module->wire(name)) || !(wire->port_input || wire->port_output)))
|
||||
return name;
|
||||
if (move_to_cell) {
|
||||
TwineRef name_ref = cell->module->design->twines.lookup(name);
|
||||
if (name_ref == Twine::Null || (!(wire = cell->module->wire(name_ref)) || !(wire->port_input || wire->port_output)))
|
||||
return name;
|
||||
}
|
||||
|
||||
if (suffix.empty()) {
|
||||
suffix = cell->type.str();
|
||||
|
|
@ -138,7 +143,7 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
|||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
auto new_id = ID(module->design->twines.str(module->uniquify(module->design->twines.add(Twine{"\\_witness_." + name}))));
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
renames.emplace_back(cell, new_id);
|
||||
}
|
||||
|
|
@ -152,7 +157,7 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
|||
QY = (clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic))) ? ID::D : ID::Q;
|
||||
else
|
||||
QY = ID::Y;
|
||||
auto sig_out = cell->getPort(QY);
|
||||
auto sig_out = cell->getPort(QY == ID::D ? TW::D : (QY == ID::Q ? TW::Q : TW::Y));
|
||||
|
||||
for (auto chunk : sig_out.chunks()) {
|
||||
if (chunk.is_wire() && !chunk.wire->name.isPublic()) {
|
||||
|
|
@ -160,14 +165,14 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
|||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
auto new_wire = module->addWire(new_id, GetSize(sig_out));
|
||||
auto new_id = ID(module->design->twines.str(module->uniquify(module->design->twines.add(Twine{"\\_witness_." + name}))));
|
||||
auto new_wire = module->addWire(Twine{new_id.str()}, GetSize(sig_out));
|
||||
new_wire->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
if (clk2fflogic)
|
||||
module->connect({new_wire, sig_out});
|
||||
else
|
||||
module->connect({sig_out, new_wire});
|
||||
cell->setPort(QY, new_wire);
|
||||
cell->setPort(QY == ID::D ? TW::D : (QY == ID::Q ? TW::Q : TW::Y), new_wire);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -182,20 +187,20 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
|||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
auto new_id = ID(module->design->twines.str(module->uniquify(module->design->twines.add(Twine{"\\_witness_." + name}))));
|
||||
renames.emplace_back(cell, new_id);
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
}
|
||||
}
|
||||
for (auto rename : renames) {
|
||||
module->rename(rename.first, rename.second);
|
||||
module->rename(rename.first, module->design->twines.add(Twine{rename.second.str()}));
|
||||
}
|
||||
|
||||
cache[module] = has_witness_signals;
|
||||
return has_witness_signals;
|
||||
}
|
||||
|
||||
static std::string renamed_unescaped(const std::string& str)
|
||||
[[maybe_unused]] static std::string renamed_unescaped(const std::string& str)
|
||||
{
|
||||
std::string new_str = "";
|
||||
|
||||
|
|
@ -400,10 +405,10 @@ struct RenamePass : public Pass {
|
|||
new_cell_names.emplace(cell, derive_name_from_src(cell->get_src_attribute(), counter++));
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
for (auto &it : new_cell_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -418,22 +423,23 @@ struct RenamePass : public Pass {
|
|||
new_cell_names[cell] = derive_name_from_cell_output_wire(cell, cell_suffix, flag_move_to_cell);
|
||||
for (auto &[cell, new_name] : new_cell_names) {
|
||||
if (flag_move_to_cell) {
|
||||
RTLIL::Wire *found_wire = module->wire(new_name);
|
||||
TwineRef new_name_ref = module->design->twines.lookup(new_name.str());
|
||||
RTLIL::Wire *found_wire = new_name_ref != Twine::Null ? module->wire(new_name_ref) : nullptr;
|
||||
if (found_wire) {
|
||||
std::string wire_suffix = cell_suffix;
|
||||
if (wire_suffix.empty()) {
|
||||
for (auto const &[port, _] : cell->connections()) {
|
||||
if (cell->output(port)) {
|
||||
wire_suffix += stringf("%s.%s", cell->type, port.c_str() + 1);
|
||||
wire_suffix += stringf("%s.%s", cell->type, module->design->twines.str(port).c_str() + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
IdString new_wire_name = found_wire->name.str() + wire_suffix;
|
||||
module->rename(found_wire, new_wire_name);
|
||||
IdString new_wire_name_id = ID(found_wire->name.str() + wire_suffix);
|
||||
module->rename(found_wire, module->design->twines.add(Twine{new_wire_name_id.str()}));
|
||||
}
|
||||
}
|
||||
module->rename(cell, new_name);
|
||||
module->rename(cell, module->design->twines.add(Twine{new_name.str()}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -451,24 +457,30 @@ struct RenamePass : public Pass {
|
|||
for (auto wire : module->selected_wires())
|
||||
if (wire->name[0] == '$') {
|
||||
RTLIL::IdString buf;
|
||||
do buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
while (module->wire(buf) != nullptr);
|
||||
TwineRef buf_ref;
|
||||
do {
|
||||
buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
buf_ref = module->design->twines.lookup(buf.str());
|
||||
} while (buf_ref != Twine::Null && module->wire(buf_ref) != nullptr);
|
||||
new_wire_names[wire] = buf;
|
||||
}
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->name[0] == '$') {
|
||||
RTLIL::IdString buf;
|
||||
do buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
while (module->cell(buf) != nullptr);
|
||||
TwineRef buf_ref;
|
||||
do {
|
||||
buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
buf_ref = module->design->twines.lookup(buf.str());
|
||||
} while (buf_ref != Twine::Null && module->cell(buf_ref) != nullptr);
|
||||
new_cell_names[cell] = buf;
|
||||
}
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
for (auto &it : new_cell_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -503,10 +515,10 @@ struct RenamePass : public Pass {
|
|||
new_cell_names[cell] = NEW_ID;
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
for (auto &it : new_cell_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -521,8 +533,8 @@ struct RenamePass : public Pass {
|
|||
if (module == nullptr)
|
||||
log_cmd_error("No top module found!\n");
|
||||
|
||||
log("Renaming module %s to %s.\n", module, new_name.unescape());
|
||||
design->rename(module, new_name);
|
||||
log("Renaming module %s to %s.\n", log_id(module), new_name.unescape());
|
||||
design->rename(module, design->twines.add(Twine{new_name.str()}));
|
||||
}
|
||||
else
|
||||
if (flag_scramble_name)
|
||||
|
|
@ -554,10 +566,10 @@ struct RenamePass : public Pass {
|
|||
}
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
for (auto &it : new_cell_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
}
|
||||
}
|
||||
else if (flag_unescape)
|
||||
|
|
@ -576,7 +588,7 @@ struct RenamePass : public Pass {
|
|||
name = name.substr(1);
|
||||
if (!VERILOG_BACKEND::id_is_verilog_escaped(name))
|
||||
continue;
|
||||
new_wire_names[wire] = module->uniquify("\\" + renamed_unescaped(name));
|
||||
new_wire_names[wire] = ID(module->design->twines.str(module->uniquify(module->design->twines.add(Twine{"\\" + renamed_unescaped(name)}))));
|
||||
auto new_name = new_wire_names[wire].str().substr(1);
|
||||
if (VERILOG_BACKEND::id_is_verilog_escaped(new_name))
|
||||
log_error("Failed to rename wire %s -> %s\n", name, new_name);
|
||||
|
|
@ -589,17 +601,17 @@ struct RenamePass : public Pass {
|
|||
name = name.substr(1);
|
||||
if (!VERILOG_BACKEND::id_is_verilog_escaped(name))
|
||||
continue;
|
||||
new_cell_names[cell] = module->uniquify("\\" + renamed_unescaped(name));
|
||||
new_cell_names[cell] = ID(module->design->twines.str(module->uniquify(module->design->twines.add(Twine{"\\" + renamed_unescaped(name)}))));
|
||||
auto new_name = new_cell_names[cell].str().substr(1);
|
||||
if (VERILOG_BACKEND::id_is_verilog_escaped(new_name))
|
||||
log_error("Failed to rename cell %s -> %s\n", name, new_name);
|
||||
}
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
for (auto &it : new_cell_names)
|
||||
module->rename(it.first, it.second);
|
||||
module->rename(it.first, module->design->twines.add(Twine{it.second.str()}));
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
|
|
@ -612,7 +624,7 @@ struct RenamePass : public Pass {
|
|||
std::string from_name = args[argidx++];
|
||||
std::string to_name = args[argidx++];
|
||||
|
||||
if (!design->selected_active_module.empty())
|
||||
if (design->selected_active_module != Twine::Null)
|
||||
{
|
||||
if (design->module(design->selected_active_module) != nullptr)
|
||||
rename_in_module(design->module(design->selected_active_module), from_name, to_name, flag_output);
|
||||
|
|
@ -623,16 +635,18 @@ struct RenamePass : public Pass {
|
|||
log_cmd_error("Mode -output requires that there is an active module selected.\n");
|
||||
|
||||
RTLIL::Module *module_to_rename = nullptr;
|
||||
for (auto module : design->modules())
|
||||
if (module->name == from_name || module->name.unescape() == from_name) {
|
||||
for (auto module : design->modules()) {
|
||||
std::string module_name_str = module->design->twines.str(module->meta_->name);
|
||||
if (module_name_str == from_name || RTLIL::unescape_id(module_name_str) == from_name) {
|
||||
module_to_rename = module;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (module_to_rename != nullptr) {
|
||||
to_name = RTLIL::escape_id(to_name);
|
||||
log("Renaming module %s to %s.\n", module_to_rename->name, to_name);
|
||||
design->rename(module_to_rename, to_name);
|
||||
log("Renaming module %s to %s.\n", log_id(module_to_rename), to_name);
|
||||
design->rename(module_to_rename, design->twines.add(Twine{to_name}));
|
||||
} else
|
||||
log_cmd_error("Object `%s' not found!\n", from_name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct ScatterPass : public Pass {
|
|||
for (auto module : design->selected_modules())
|
||||
{
|
||||
for (auto cell : module->cells()) {
|
||||
dict<RTLIL::IdString, RTLIL::SigSig> new_connections;
|
||||
dict<TwineRef, RTLIL::SigSig> new_connections;
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ struct SccWorker
|
|||
design(design), module(module), sigmap(module)
|
||||
{
|
||||
if (module->processes.size() > 0) {
|
||||
log("Skipping module %s as it contains processes (run 'proc' pass first).\n", module->name);
|
||||
log("Skipping module %s as it contains processes (run 'proc' pass first).\n", log_id(module));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -154,16 +154,16 @@ struct SccWorker
|
|||
|
||||
for (auto bit : subcell->getPort(TW::SRC))
|
||||
{
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->name))
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->meta_->name))
|
||||
continue;
|
||||
inputSignals.append(sigmap(cell->getPort(bit.wire->name)));
|
||||
inputSignals.append(sigmap(cell->getPort(bit.wire->meta_->name)));
|
||||
}
|
||||
|
||||
for (auto bit : subcell->getPort(TW::DST))
|
||||
{
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->name))
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->meta_->name))
|
||||
continue;
|
||||
outputSignals.append(sigmap(cell->getPort(bit.wire->name)));
|
||||
outputSignals.append(sigmap(cell->getPort(bit.wire->meta_->name)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -221,7 +221,7 @@ struct SccWorker
|
|||
run(cell, 0, maxDepth);
|
||||
}
|
||||
|
||||
log("Found %d SCCs in module %s.\n", int(sccList.size()), module);
|
||||
log("Found %d SCCs in module %s.\n", int(sccList.size()), log_id(module));
|
||||
}
|
||||
|
||||
void select(RTLIL::Selection &sel)
|
||||
|
|
@ -232,7 +232,7 @@ struct SccWorker
|
|||
RTLIL::SigSpec prevsig, nextsig, sig;
|
||||
|
||||
for (auto cell : cells) {
|
||||
sel.selected_members[module->name].insert(cell->name);
|
||||
sel.selected_members[module->meta_->name].insert(cell->meta_->name);
|
||||
prevsig.append(cellToPrevSig[cell]);
|
||||
nextsig.append(cellToNextSig[cell]);
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ struct SccWorker
|
|||
|
||||
for (auto &chunk : sig.chunks())
|
||||
if (chunk.wire != NULL)
|
||||
sel.selected_members[module->name].insert(chunk.wire->name);
|
||||
sel.selected_members[module->meta_->name].insert(chunk.wire->meta_->name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs)
|
|||
for (auto mod : design->modules()) {
|
||||
if (!lhs.selects_boxes && mod->get_blackbox_attribute())
|
||||
continue;
|
||||
lhs.selected_modules.insert(mod->name);
|
||||
lhs.selected_modules.insert(mod->meta_->name);
|
||||
}
|
||||
lhs.full_selection = false;
|
||||
lhs.complete_selection = false;
|
||||
|
|
@ -195,25 +195,25 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
|
|||
{
|
||||
if (!lhs.selects_boxes && mod->get_blackbox_attribute())
|
||||
continue;
|
||||
if (lhs.selected_whole_module(mod->name))
|
||||
if (lhs.selected_whole_module(mod->meta_->name))
|
||||
continue;
|
||||
if (!lhs.selected_module(mod->name)) {
|
||||
new_sel.selected_modules.insert(mod->name);
|
||||
if (!lhs.selected_module(mod->meta_->name)) {
|
||||
new_sel.selected_modules.insert(mod->meta_->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto wire : mod->wires())
|
||||
if (!lhs.selected_member(mod->name, wire->name))
|
||||
new_sel.selected_members[mod->name].insert(wire->name);
|
||||
if (!lhs.selected_member(mod->meta_->name, wire->meta_->name))
|
||||
new_sel.selected_members[mod->meta_->name].insert(wire->meta_->name);
|
||||
for (auto &it : mod->memories)
|
||||
if (!lhs.selected_member(mod->name, it.first))
|
||||
new_sel.selected_members[mod->name].insert(it.first);
|
||||
if (!lhs.selected_member(mod->meta_->name, it.first))
|
||||
new_sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
for (auto cell : mod->cells())
|
||||
if (!lhs.selected_member(mod->name, cell->name))
|
||||
new_sel.selected_members[mod->name].insert(cell->name);
|
||||
if (!lhs.selected_member(mod->meta_->name, cell->meta_->name))
|
||||
new_sel.selected_members[mod->meta_->name].insert(cell->meta_->name);
|
||||
for (auto &it : mod->processes)
|
||||
if (!lhs.selected_member(mod->name, it.first))
|
||||
new_sel.selected_members[mod->name].insert(it.first);
|
||||
if (!lhs.selected_member(mod->meta_->name, it.first))
|
||||
new_sel.selected_members[mod->meta_->name].insert(it.first);
|
||||
}
|
||||
|
||||
lhs.selected_modules.swap(new_sel.selected_modules);
|
||||
|
|
@ -230,21 +230,21 @@ static int my_xorshift32_rng() {
|
|||
|
||||
static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int count)
|
||||
{
|
||||
vector<pair<IdString, IdString>> objects;
|
||||
vector<pair<TwineRef, TwineRef>> objects;
|
||||
|
||||
for (auto mod : design->modules())
|
||||
{
|
||||
if (!lhs.selected_module(mod->name))
|
||||
if (!lhs.selected_module(mod->meta_->name))
|
||||
continue;
|
||||
|
||||
for (auto cell : mod->cells()) {
|
||||
if (lhs.selected_member(mod->name, cell->name))
|
||||
objects.push_back(make_pair(RTLIL::IdString(mod->name), RTLIL::IdString(cell->name)));
|
||||
if (lhs.selected_member(mod->meta_->name, cell->meta_->name))
|
||||
objects.push_back(make_pair(mod->meta_->name, cell->meta_->name));
|
||||
}
|
||||
|
||||
for (auto wire : mod->wires()) {
|
||||
if (lhs.selected_member(mod->name, wire->name))
|
||||
objects.push_back(make_pair(RTLIL::IdString(mod->name), RTLIL::IdString(wire->name)));
|
||||
if (lhs.selected_member(mod->meta_->name, wire->meta_->name))
|
||||
objects.push_back(make_pair(mod->meta_->name, wire->meta_->name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,13 +265,13 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
|
|||
{
|
||||
for (auto mod : design->modules())
|
||||
{
|
||||
if (lhs.selected_whole_module(mod->name))
|
||||
if (lhs.selected_whole_module(mod->meta_->name))
|
||||
{
|
||||
for (auto cell : mod->cells())
|
||||
{
|
||||
if (design->module(cell->type) == nullptr)
|
||||
continue;
|
||||
lhs.selected_modules.insert(cell->type);
|
||||
lhs.selected_modules.insert(design->twines.add(Twine{cell->type.str()}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -281,10 +281,10 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &
|
|||
{
|
||||
RTLIL::Selection new_sel(false, lhs.selects_boxes, design);
|
||||
for (auto mod : design->modules())
|
||||
if (lhs.selected_module(mod->name))
|
||||
if (lhs.selected_module(mod->meta_->name))
|
||||
for (auto cell : mod->cells())
|
||||
if (lhs.selected_member(mod->name, cell->name) && (design->module(cell->type) != nullptr))
|
||||
new_sel.selected_modules.insert(cell->type);
|
||||
if (lhs.selected_member(mod->meta_->name, cell->meta_->name) && (design->module(cell->type) != nullptr))
|
||||
new_sel.selected_modules.insert(design->twines.add(Twine{cell->type.str()}));
|
||||
lhs = new_sel;
|
||||
}
|
||||
|
||||
|
|
@ -293,8 +293,8 @@ static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &l
|
|||
RTLIL::Selection new_sel(false, lhs.selects_boxes, design);
|
||||
for (auto mod : design->modules())
|
||||
for (auto cell : mod->cells())
|
||||
if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type))
|
||||
new_sel.selected_members[mod->name].insert(cell->name);
|
||||
if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(design->twines.add(Twine{cell->type.str()})))
|
||||
new_sel.selected_members[mod->meta_->name].insert(cell->meta_->name);
|
||||
lhs = new_sel;
|
||||
}
|
||||
|
||||
|
|
@ -312,21 +312,21 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs)
|
|||
{
|
||||
if (!lhs.selects_boxes && mod->get_blackbox_attribute())
|
||||
continue;
|
||||
if (lhs.selected_whole_module(mod->name))
|
||||
if (lhs.selected_whole_module(mod->meta_->name))
|
||||
continue;
|
||||
if (!lhs.selected_module(mod->name))
|
||||
if (!lhs.selected_module(mod->meta_->name))
|
||||
continue;
|
||||
|
||||
SigMap sigmap(mod);
|
||||
SigPool selected_bits;
|
||||
|
||||
for (auto wire : mod->wires())
|
||||
if (lhs.selected_member(mod->name, wire->name))
|
||||
if (lhs.selected_member(mod->meta_->name, wire->meta_->name))
|
||||
selected_bits.add(sigmap(wire));
|
||||
|
||||
for (auto wire : mod->wires())
|
||||
if (!lhs.selected_member(mod->name, wire->name) && selected_bits.check_any(sigmap(wire)))
|
||||
lhs.selected_members[mod->name].insert(wire->name);
|
||||
if (!lhs.selected_member(mod->meta_->name, wire->meta_->name) && selected_bits.check_any(sigmap(wire)))
|
||||
lhs.selected_members[mod->meta_->name].insert(wire->meta_->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -411,24 +411,24 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R
|
|||
|
||||
RTLIL::Module *mod = design->module(it.first);
|
||||
|
||||
if (lhs.selected_modules.count(mod->name) > 0)
|
||||
if (lhs.selected_modules.count(mod->meta_->name) > 0)
|
||||
{
|
||||
for (auto wire : mod->wires())
|
||||
lhs.selected_members[mod->name].insert(wire->name);
|
||||
lhs.selected_members[mod->meta_->name].insert(wire->meta_->name);
|
||||
for (auto &it : mod->memories)
|
||||
lhs.selected_members[mod->name].insert(it.first);
|
||||
lhs.selected_members[mod->meta_->name].insert(it.first);
|
||||
for (auto cell : mod->cells())
|
||||
lhs.selected_members[mod->name].insert(cell->name);
|
||||
lhs.selected_members[mod->meta_->name].insert(cell->meta_->name);
|
||||
for (auto &it : mod->processes)
|
||||
lhs.selected_members[mod->name].insert(it.first);
|
||||
lhs.selected_modules.erase(mod->name);
|
||||
lhs.selected_members[mod->meta_->name].insert(it.first);
|
||||
lhs.selected_modules.erase(mod->meta_->name);
|
||||
}
|
||||
|
||||
if (lhs.selected_members.count(mod->name) == 0)
|
||||
if (lhs.selected_members.count(mod->meta_->name) == 0)
|
||||
continue;
|
||||
|
||||
for (auto &it2 : it.second)
|
||||
lhs.selected_members[mod->name].erase(it2);
|
||||
lhs.selected_members[mod->meta_->name].erase(it2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -513,14 +513,14 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
|
|||
bool is_input, is_output;
|
||||
for (auto mod : design->modules())
|
||||
{
|
||||
if (lhs.selected_whole_module(mod->name) || !lhs.selected_module(mod->name))
|
||||
if (lhs.selected_whole_module(mod->meta_->name) || !lhs.selected_module(mod->meta_->name))
|
||||
continue;
|
||||
|
||||
std::set<RTLIL::Wire*> selected_wires;
|
||||
auto selected_members = lhs.selected_members[mod->name];
|
||||
auto selected_members = lhs.selected_members[mod->meta_->name];
|
||||
|
||||
for (auto wire : mod->wires())
|
||||
if (lhs.selected_member(mod->name, wire->name) && limits.count(wire->name) == 0)
|
||||
if (lhs.selected_member(mod->meta_->name, wire->meta_->name) && limits.count(wire->meta_->name) == 0)
|
||||
selected_wires.insert(wire);
|
||||
|
||||
for (auto &conn : mod->connections())
|
||||
|
|
@ -531,10 +531,10 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
|
|||
for (size_t i = 0; i < conn_lhs.size(); i++) {
|
||||
if (conn_lhs[i].wire == nullptr || conn_rhs[i].wire == nullptr)
|
||||
continue;
|
||||
if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0)
|
||||
lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--;
|
||||
if (mode != 'o' && selected_wires.count(conn_lhs[i].wire) && selected_members.count(conn_rhs[i].wire->name) == 0)
|
||||
lhs.selected_members[mod->name].insert(conn_rhs[i].wire->name), sel_objects++, max_objects--;
|
||||
if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->meta_->name) == 0)
|
||||
lhs.selected_members[mod->meta_->name].insert(conn_lhs[i].wire->meta_->name), sel_objects++, max_objects--;
|
||||
if (mode != 'o' && selected_wires.count(conn_lhs[i].wire) && selected_members.count(conn_rhs[i].wire->meta_->name) == 0)
|
||||
lhs.selected_members[mod->meta_->name].insert(conn_rhs[i].wire->meta_->name), sel_objects++, max_objects--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -253,10 +253,10 @@ struct ChparamPass : public Pass {
|
|||
return;
|
||||
}
|
||||
|
||||
pool<IdString> modnames, old_modnames;
|
||||
pool<TwineRef> modnames, old_modnames;
|
||||
for (auto module : design->selected_whole_modules_warn()) {
|
||||
modnames.insert(module->name);
|
||||
old_modnames.insert(module->name);
|
||||
modnames.insert(module->meta_->name);
|
||||
old_modnames.insert(module->meta_->name);
|
||||
}
|
||||
modnames.sort();
|
||||
|
||||
|
|
@ -265,11 +265,11 @@ struct ChparamPass : public Pass {
|
|||
Module *new_module = design->module(module->derive(design, new_parameters));
|
||||
if (module != new_module) {
|
||||
Module *m = new_module->clone();
|
||||
m->name = module->name;
|
||||
m->meta_->name = module->meta_->name;
|
||||
design->remove(module);
|
||||
design->add(m);
|
||||
}
|
||||
if (old_modnames.count(new_module->name) == 0)
|
||||
if (old_modnames.count(new_module->meta_->name) == 0)
|
||||
design->remove(new_module);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,9 +347,9 @@ struct SetundefPass : public Pass {
|
|||
for (auto &c : sig.chunks()) {
|
||||
RTLIL::SigSpec bits;
|
||||
if (worker.next_bit_mode == MODE_ANYSEQ)
|
||||
bits = module->Anyseq(NEW_ID, c.width);
|
||||
bits = module->Anyseq(NEW_TWINE, c.width);
|
||||
else if (worker.next_bit_mode == MODE_ANYCONST)
|
||||
bits = module->Anyconst(NEW_ID, c.width);
|
||||
bits = module->Anyconst(NEW_TWINE, c.width);
|
||||
else
|
||||
for (int i = 0; i < c.width; i++)
|
||||
bits.append(worker.next_bit());
|
||||
|
|
@ -547,9 +547,9 @@ struct SetundefPass : public Pass {
|
|||
|
||||
if (width > 0) {
|
||||
if (worker.next_bit_mode == MODE_ANYSEQ)
|
||||
sig.replace(cursor, module->Anyseq(NEW_ID, width));
|
||||
sig.replace(cursor, module->Anyseq(NEW_TWINE, width));
|
||||
else
|
||||
sig.replace(cursor, module->Anyconst(NEW_ID, width));
|
||||
sig.replace(cursor, module->Anyconst(NEW_TWINE, width));
|
||||
cursor += width;
|
||||
} else {
|
||||
cursor++;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ struct SplitcellsWorker
|
|||
{
|
||||
Module *module;
|
||||
SigMap sigmap;
|
||||
dict<SigBit, tuple<IdString,IdString,int>> bit_drivers_db;
|
||||
dict<SigBit, pool<tuple<IdString,IdString,int>>> bit_users_db;
|
||||
dict<SigBit, tuple<TwineRef,TwineRef,int>> bit_drivers_db;
|
||||
dict<SigBit, pool<tuple<TwineRef,TwineRef,int>>> bit_users_db;
|
||||
|
||||
SplitcellsWorker(Module *module) : module(module), sigmap(module)
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ struct SplitcellsWorker
|
|||
if (!cell->output(conn.first)) continue;
|
||||
for (int i = 0; i < GetSize(conn.second); i++) {
|
||||
SigBit bit(sigmap(conn.second[i]));
|
||||
bit_drivers_db[bit] = tuple<IdString,IdString,int>(cell->name, conn.first, i);
|
||||
bit_drivers_db[bit] = tuple<TwineRef,TwineRef,int>(cell->meta_->name, conn.first, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ struct SplitcellsWorker
|
|||
for (int i = 0; i < GetSize(conn.second); i++) {
|
||||
SigBit bit(sigmap(conn.second[i]));
|
||||
if (!bit_drivers_db.count(bit)) continue;
|
||||
bit_users_db[bit].insert(tuple<IdString,IdString,int>(cell->name,
|
||||
bit_users_db[bit].insert(tuple<TwineRef,TwineRef,int>(cell->meta_->name,
|
||||
conn.first, i-std::get<2>(bit_drivers_db[bit])));
|
||||
}
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ struct SplitcellsWorker
|
|||
for (int i = 0; i < GetSize(sig); i++) {
|
||||
SigBit bit(sig[i]);
|
||||
if (!bit_drivers_db.count(bit)) continue;
|
||||
bit_users_db[bit].insert(tuple<IdString,IdString,int>(wire->name,
|
||||
IdString(), i-std::get<2>(bit_drivers_db[bit])));
|
||||
bit_users_db[bit].insert(tuple<TwineRef,TwineRef,int>(wire->meta_->name,
|
||||
Twine::Null, i-std::get<2>(bit_drivers_db[bit])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ struct SplitcellsWorker
|
|||
|
||||
int width = GetSize(outsig);
|
||||
width = std::min(width, GetSize(cell->getPort(TW::A)));
|
||||
if (cell->hasPort(ID::B))
|
||||
if (cell->hasPort(TW::B))
|
||||
width = std::min(width, GetSize(cell->getPort(TW::B)));
|
||||
|
||||
for (int i = 1; i < width; i++) {
|
||||
|
|
@ -95,9 +95,10 @@ struct SplitcellsWorker
|
|||
int slice_msb = slices[i]-1;
|
||||
int slice_lsb = slices[i-1];
|
||||
|
||||
IdString slice_name = module->uniquify(cell->name.str() + (slice_msb == slice_lsb ?
|
||||
std::string s = cell->name.str() + (slice_msb == slice_lsb ?
|
||||
stringf("%c%d%c", format[0], slice_lsb, format[1]) :
|
||||
stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
|
||||
stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1]));
|
||||
TwineRef slice_name = module->uniquify(module->design->twines.add(Twine{s}));
|
||||
|
||||
Cell *slice = module->addCell(slice_name, cell);
|
||||
|
||||
|
|
@ -114,7 +115,7 @@ struct SplitcellsWorker
|
|||
if (slice->hasParam(ID::A_WIDTH))
|
||||
slice->setParam(ID::A_WIDTH, GetSize(slice->getPort(TW::A)));
|
||||
|
||||
if (slice->hasPort(ID::B)) {
|
||||
if (slice->hasPort(TW::B)) {
|
||||
slice->setPort(TW::B, slice_signal(slice->getPort(TW::B)));
|
||||
if (slice->hasParam(ID::B_WIDTH))
|
||||
slice->setParam(ID::B_WIDTH, GetSize(slice->getPort(TW::B)));
|
||||
|
|
@ -136,7 +137,7 @@ struct SplitcellsWorker
|
|||
if (cell->type.in("$ff", "$dff", "$dffe", "$dffsr", "$dffsre", "$adff", "$adffe", "$aldff", "$aldffe",
|
||||
"$sdff", "$sdffce", "$sdffe", "$dlatch", "$dlatchsr", "$adlatch"))
|
||||
{
|
||||
auto splitports = {ID::D, ID::Q, ID::AD, ID::SET, ID::CLR};
|
||||
auto splitports = {TW::D, TW::Q, TW::AD, TW::SET, TW::CLR};
|
||||
auto splitparams = {ID::ARST_VALUE, ID::SRST_VALUE};
|
||||
|
||||
SigSpec outsig = sigmap(cell->getPort(TW::Q));
|
||||
|
|
@ -161,9 +162,11 @@ struct SplitcellsWorker
|
|||
int slice_msb = slices[i]-1;
|
||||
int slice_lsb = slices[i-1];
|
||||
|
||||
IdString slice_name = module->uniquify(cell->name.str() + (slice_msb == slice_lsb ?
|
||||
TwinePool twines = module->design->twines;
|
||||
std::string s = cell->name.str() + (slice_msb == slice_lsb ?
|
||||
stringf("%c%d%c", format[0], slice_lsb, format[1]) :
|
||||
stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
|
||||
stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1]));
|
||||
TwineRef slice_name = module->uniquify(twines.add(Twine{s}));
|
||||
|
||||
Cell *slice = module->addCell(slice_name, cell);
|
||||
|
||||
|
|
@ -185,7 +188,7 @@ struct SplitcellsWorker
|
|||
|
||||
slice->setParam(ID::WIDTH, GetSize(slice->getPort(TW::Q)));
|
||||
|
||||
log(" slice %d: %s => %s\n", i, slice_name.unescape(), log_signal(slice->getPort(TW::Q)));
|
||||
log(" slice %d: %s => %s\n", i, twines.str(slice_name), log_signal(slice->getPort(TW::Q)));
|
||||
}
|
||||
|
||||
module->remove(cell);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct SplitnetsWorker
|
|||
if (format.size() > 1)
|
||||
new_wire_name += format.substr(1, 1);
|
||||
|
||||
RTLIL::Wire *new_wire = module->addWire(module->uniquify(new_wire_name), width);
|
||||
RTLIL::Wire *new_wire = module->addWire(module->uniquify(module->design->twines.add(Twine{new_wire_name})), width);
|
||||
new_wire->port_id = wire->port_id ? wire->port_id + offset : 0;
|
||||
new_wire->port_input = wire->port_input;
|
||||
new_wire->port_output = wire->port_output;
|
||||
|
|
@ -149,7 +149,7 @@ struct SplitnetsPass : public Pass {
|
|||
design->sigNormalize(false);
|
||||
|
||||
// module_ports_db[module_name][old_port_name] = new_port_name_list
|
||||
dict<IdString, dict<IdString, vector<IdString>>> module_ports_db;
|
||||
dict<IdString, dict<TwineRef, vector<TwineRef>>> module_ports_db;
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
|
|
@ -239,10 +239,10 @@ struct SplitnetsPass : public Pass {
|
|||
if (sig == wire)
|
||||
continue;
|
||||
|
||||
vector<IdString> &new_ports = module_ports_db[module->name][wire->name];
|
||||
vector<TwineRef> &new_ports = module_ports_db[module->design->twines.str(module->meta_->name)][wire->meta_->name];
|
||||
|
||||
for (SigSpec c : sig.chunks())
|
||||
new_ports.push_back(c.as_wire()->name);
|
||||
new_ports.push_back(c.as_wire()->meta_->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ struct SplitnetsPass : public Pass {
|
|||
|
||||
for (auto &it : module_ports_db.at(cell->type))
|
||||
{
|
||||
IdString port_id = it.first;
|
||||
TwineRef port_id = it.first;
|
||||
const auto &new_port_ids = it.second;
|
||||
|
||||
if (!cell->hasPort(port_id))
|
||||
|
|
|
|||
|
|
@ -190,9 +190,9 @@ struct statdata_t {
|
|||
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))) {
|
||||
int width_a = cell->hasPort(ID::A) ? GetSize(cell->getPort(TW::A)) : 0;
|
||||
int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(TW::B)) : 0;
|
||||
int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(TW::Y)) : 0;
|
||||
int width_a = cell->hasPort(TW::A) ? GetSize(cell->getPort(TW::A)) : 0;
|
||||
int width_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 0;
|
||||
int width_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)));
|
||||
|
|
@ -215,10 +215,10 @@ struct statdata_t {
|
|||
if (cell_data.single_parameter_area.size() > 0) {
|
||||
// assume that we just take the max of the A,B,Y ports
|
||||
|
||||
int width_a = cell->hasPort(ID::A) ? GetSize(cell->getPort(TW::A)) : 0;
|
||||
int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(TW::B)) : 0;
|
||||
int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(TW::Y)) : 0;
|
||||
int width_q = cell->hasPort(ID::Q) ? GetSize(cell->getPort(TW::Q)) : 0;
|
||||
int width_a = cell->hasPort(TW::A) ? GetSize(cell->getPort(TW::A)) : 0;
|
||||
int width_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 0;
|
||||
int width_y = cell->hasPort(TW::Y) ? GetSize(cell->getPort(TW::Y)) : 0;
|
||||
int width_q = cell->hasPort(TW::Q) ? GetSize(cell->getPort(TW::Q)) : 0;
|
||||
int max_width = max<int>({width_a, width_b, width_y, width_q});
|
||||
if (!cell_area.count(cell_type)) {
|
||||
cell_area[cell_type] = cell_data;
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ struct TestPatchPass : public Pass {
|
|||
log_assert(neg->type == ID($not));
|
||||
RTLIL::Patch patcher(module, nullptr);
|
||||
int width = cell->getPort(TW::A).size();
|
||||
auto sub = patcher.addSub(NEW_ID,
|
||||
auto sub = patcher.addSub(NEW_TWINE,
|
||||
neg->getPort(TW::A),
|
||||
add->getPort(TW::A),
|
||||
patcher.addWire(NEW_TWINE, width));
|
||||
auto new_out_wire = patcher.addWire(NEW_TWINE, width);
|
||||
auto new_cell = patcher.addNeg(NEW_ID, sub->getPort(TW::Y), new_out_wire);
|
||||
auto new_cell = patcher.addNeg(NEW_TWINE, sub->getPort(TW::Y), new_out_wire);
|
||||
log_cell(new_cell);
|
||||
patcher.patch(add, ID::Y, new_out_wire);
|
||||
patcher.patch(add, TW::Y, new_out_wire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "kernel/rtlil.h"
|
||||
#include "kernel/yosys.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
|
@ -139,16 +140,16 @@ struct TestSelectPass : public Pass {
|
|||
|
||||
// get sub selection and store the results
|
||||
auto sub_sel = design->selected_modules(partials, (RTLIL::SelectBoxes)boxes);
|
||||
pool<RTLIL::IdString> selected_modules;
|
||||
dict<RTLIL::IdString, pool<RTLIL::NamedObject*>> selected_members;
|
||||
pool<TwineRef> selected_modules;
|
||||
dict<TwineRef, pool<RTLIL::AttrObject*>> selected_members;
|
||||
|
||||
for (auto *mod : sub_sel) {
|
||||
if (mod->is_selected_whole()) {
|
||||
log_debug(" Adding %s.\n", mod);
|
||||
selected_modules.insert(mod->name);
|
||||
selected_modules.insert(mod->meta_->name);
|
||||
} else for (auto *memb : mod->selected_members()) {
|
||||
log_debug(" Adding %s.%s.\n", mod, memb);
|
||||
selected_members[mod->name].insert(memb);
|
||||
selected_members[mod->meta_->name].insert(memb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,18 +55,18 @@ struct XpropWorker
|
|||
Module *module;
|
||||
|
||||
void invert() { std::swap(is_0, is_1); }
|
||||
void auto_0() { connect_0(module->Not(NEW_ID, module->Or(NEW_ID, is_1, is_x))); }
|
||||
void auto_1() { connect_1(module->Not(NEW_ID, module->Or(NEW_ID, is_0, is_x))); }
|
||||
void auto_x() { connect_x(module->Not(NEW_ID, module->Or(NEW_ID, is_0, is_1))); }
|
||||
void auto_0() { connect_0(module->Not(NEW_ID, module->Or(NEW_TWINE, is_1, is_x))); }
|
||||
void auto_1() { connect_1(module->Not(NEW_ID, module->Or(NEW_TWINE, is_0, is_x))); }
|
||||
void auto_x() { connect_x(module->Not(NEW_ID, module->Or(NEW_TWINE, is_0, is_1))); }
|
||||
|
||||
void connect_0(SigSpec sig) { module->connect(is_0, sig); }
|
||||
void connect_1(SigSpec sig) { module->connect(is_1, sig); }
|
||||
void connect_x(SigSpec sig) { module->connect(is_x, sig); }
|
||||
|
||||
void connect_1_under_x(SigSpec sig) { connect_1(module->And(NEW_ID, sig, module->Not(NEW_ID, is_x))); }
|
||||
void connect_0_under_x(SigSpec sig) { connect_0(module->And(NEW_ID, sig, module->Not(NEW_ID, is_x))); }
|
||||
void connect_1_under_x(SigSpec sig) { connect_1(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_x))); }
|
||||
void connect_0_under_x(SigSpec sig) { connect_0(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_x))); }
|
||||
|
||||
void connect_x_under_0(SigSpec sig) { connect_x(module->And(NEW_ID, sig, module->Not(NEW_ID, is_0))); }
|
||||
void connect_x_under_0(SigSpec sig) { connect_x(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_0))); }
|
||||
|
||||
void connect_as_bool() {
|
||||
int width = GetSize(is_0);
|
||||
|
|
@ -198,7 +198,7 @@ struct XpropWorker
|
|||
}
|
||||
|
||||
if (!invert.empty() && !driving)
|
||||
invert = module->Not(NEW_ID, invert);
|
||||
invert = module->Not(NEW_TWINE, invert);
|
||||
|
||||
EncodedSig new_sigs;
|
||||
if (new_bits > 0) {
|
||||
|
|
@ -253,7 +253,7 @@ struct XpropWorker
|
|||
}
|
||||
|
||||
if (!driven_orig.empty()) {
|
||||
auto decoder = module->addBwmux(NEW_ID, driven_enc.is_1, Const(State::Sx, GetSize(driven_orig)), driven_enc.is_x, driven_orig);
|
||||
auto decoder = module->addBwmux(NEW_TWINE, driven_enc.is_1, Const(State::Sx, GetSize(driven_orig)), driven_enc.is_x, driven_orig);
|
||||
decoder->set_bool_attribute(ID::xprop_decoder);
|
||||
}
|
||||
if (!driven_never_x.first.empty()) {
|
||||
|
|
@ -261,21 +261,21 @@ struct XpropWorker
|
|||
}
|
||||
|
||||
if (driving && (options.assert_encoding || options.assume_encoding)) {
|
||||
auto not_0 = module->Not(NEW_ID, result.is_0);
|
||||
auto not_1 = module->Not(NEW_ID, result.is_1);
|
||||
auto not_x = module->Not(NEW_ID, result.is_x);
|
||||
auto valid = module->ReduceAnd(NEW_ID, {
|
||||
module->Eq(NEW_ID, result.is_0, module->And(NEW_ID, not_1, not_x)),
|
||||
module->Eq(NEW_ID, result.is_1, module->And(NEW_ID, not_0, not_x)),
|
||||
module->Eq(NEW_ID, result.is_x, module->And(NEW_ID, not_0, not_1)),
|
||||
auto not_0 = module->Not(NEW_TWINE, result.is_0);
|
||||
auto not_1 = module->Not(NEW_TWINE, result.is_1);
|
||||
auto not_x = module->Not(NEW_TWINE, result.is_x);
|
||||
auto valid = module->ReduceAnd(NEW_TWINE, {
|
||||
module->Eq(NEW_ID, result.is_0, module->And(NEW_TWINE, not_1, not_x)),
|
||||
module->Eq(NEW_ID, result.is_1, module->And(NEW_TWINE, not_0, not_x)),
|
||||
module->Eq(NEW_ID, result.is_x, module->And(NEW_TWINE, not_0, not_1)),
|
||||
});
|
||||
if (options.assert_encoding)
|
||||
module->addAssert(NEW_ID_SUFFIX("xprop_enc"), valid, State::S1);
|
||||
module->addAssert(NEW_TWINE_SUFFIX("xprop_enc"), valid, State::S1);
|
||||
else
|
||||
module->addAssume(NEW_ID_SUFFIX("xprop_enc"), valid, State::S1);
|
||||
module->addAssume(NEW_TWINE_SUFFIX("xprop_enc"), valid, State::S1);
|
||||
if (options.debug_asserts) {
|
||||
auto bad_bits = module->Bweqx(NEW_ID, {result.is_0, result.is_1, result.is_x}, Const(State::Sx, GetSize(result) * 3));
|
||||
module->addAssert(NEW_ID_SUFFIX("xprop_debug"), module->LogicNot(NEW_ID, bad_bits), State::S1);
|
||||
auto bad_bits = module->Bweqx(NEW_TWINE, {result.is_0, result.is_1, result.is_x}, Const(State::Sx, GetSize(result) * 3));
|
||||
module->addAssert(NEW_TWINE_SUFFIX("xprop_debug"), module->LogicNot(NEW_TWINE, bad_bits), State::S1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,8 +547,8 @@ struct XpropWorker
|
|||
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
enc_b.invert();
|
||||
|
||||
enc_y.connect_0(module->Or(NEW_ID, enc_a.is_0, enc_b.is_0));
|
||||
enc_y.connect_1(module->And(NEW_ID, enc_a.is_1, enc_b.is_1));
|
||||
enc_y.connect_0(module->Or(NEW_TWINE, enc_a.is_0, enc_b.is_0));
|
||||
enc_y.connect_1(module->And(NEW_TWINE, enc_a.is_1, enc_b.is_1));
|
||||
enc_y.auto_x();
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -568,8 +568,8 @@ struct XpropWorker
|
|||
if (cell->type == ID($logic_not))
|
||||
enc_a.invert();
|
||||
|
||||
enc_y.connect_0(module->ReduceOr(NEW_ID, enc_a.is_0));
|
||||
enc_y.connect_1(module->ReduceAnd(NEW_ID, enc_a.is_1));
|
||||
enc_y.connect_0(module->ReduceOr(NEW_TWINE, enc_a.is_0));
|
||||
enc_y.connect_1(module->ReduceAnd(NEW_TWINE, enc_a.is_1));
|
||||
enc_y.auto_x();
|
||||
module->remove(cell);
|
||||
|
||||
|
|
@ -588,8 +588,8 @@ struct XpropWorker
|
|||
enc_y.invert();
|
||||
|
||||
|
||||
enc_y.connect_x(module->ReduceOr(NEW_ID, enc_a.is_x));
|
||||
enc_y.connect_1_under_x(module->ReduceXor(NEW_ID, enc_a.is_1));
|
||||
enc_y.connect_x(module->ReduceOr(NEW_TWINE, enc_a.is_x));
|
||||
enc_y.connect_1_under_x(module->ReduceXor(NEW_TWINE, enc_a.is_1));
|
||||
enc_y.auto_0();
|
||||
module->remove(cell);
|
||||
|
||||
|
|
@ -607,16 +607,16 @@ struct XpropWorker
|
|||
|
||||
enc_y.connect_as_bool();
|
||||
|
||||
auto a_is_1 = module->ReduceOr(NEW_ID, enc_a.is_1);
|
||||
auto a_is_0 = module->ReduceAnd(NEW_ID, enc_a.is_0);
|
||||
auto b_is_1 = module->ReduceOr(NEW_ID, enc_b.is_1);
|
||||
auto b_is_0 = module->ReduceAnd(NEW_ID, enc_b.is_0);
|
||||
auto a_is_1 = module->ReduceOr(NEW_TWINE, enc_a.is_1);
|
||||
auto a_is_0 = module->ReduceAnd(NEW_TWINE, enc_a.is_0);
|
||||
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))
|
||||
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_ID, a_is_0, b_is_0));
|
||||
enc_y.connect_1(module->And(NEW_ID, a_is_1, b_is_1));
|
||||
enc_y.connect_0(module->Or(NEW_TWINE, a_is_0, b_is_0));
|
||||
enc_y.connect_1(module->And(NEW_TWINE, a_is_1, b_is_1));
|
||||
enc_y.auto_x();
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -638,8 +638,8 @@ struct XpropWorker
|
|||
if (cell->type.in(ID($xnor), ID($_XNOR_)))
|
||||
enc_y.invert();
|
||||
|
||||
enc_y.connect_x(module->Or(NEW_ID, enc_a.is_x, enc_b.is_x));
|
||||
enc_y.connect_1_under_x(module->Xor(NEW_ID, enc_a.is_1, enc_b.is_1));
|
||||
enc_y.connect_x(module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x));
|
||||
enc_y.connect_1_under_x(module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1));
|
||||
enc_y.auto_0();
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -661,11 +661,11 @@ struct XpropWorker
|
|||
if (cell->type == ID($ne))
|
||||
enc_y.invert();
|
||||
|
||||
auto delta = module->Xor(NEW_ID, enc_a.is_1, enc_b.is_1);
|
||||
auto xpos = module->Or(NEW_ID, enc_a.is_x, enc_b.is_x);
|
||||
auto delta = module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1);
|
||||
auto xpos = module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x);
|
||||
|
||||
enc_y.connect_0(module->ReduceOr(NEW_ID, module->And(NEW_ID, delta, module->Not(NEW_ID, xpos))));
|
||||
enc_y.connect_x_under_0(module->ReduceOr(NEW_ID, xpos));
|
||||
enc_y.connect_0(module->ReduceOr(NEW_ID, module->And(NEW_ID, delta, module->Not(NEW_TWINE, xpos))));
|
||||
enc_y.connect_x_under_0(module->ReduceOr(NEW_TWINE, xpos));
|
||||
enc_y.auto_1();
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -682,12 +682,12 @@ struct XpropWorker
|
|||
auto enc_a = encoded(sig_a);
|
||||
auto enc_b = encoded(sig_b);
|
||||
|
||||
auto delta_0 = module->Xnor(NEW_ID, enc_a.is_0, enc_b.is_0);
|
||||
auto delta_1 = module->Xnor(NEW_ID, enc_a.is_1, enc_b.is_1);
|
||||
auto delta_0 = module->Xnor(NEW_TWINE, enc_a.is_0, enc_b.is_0);
|
||||
auto delta_1 = module->Xnor(NEW_TWINE, enc_a.is_1, enc_b.is_1);
|
||||
|
||||
auto eq = module->ReduceAnd(NEW_ID, {delta_0, delta_1});
|
||||
auto eq = module->ReduceAnd(NEW_TWINE, {delta_0, delta_1});
|
||||
|
||||
auto res = cell->type == ID($nex) ? module->Not(NEW_ID, eq) : eq;
|
||||
auto res = cell->type == ID($nex) ? module->Not(NEW_TWINE, eq) : eq;
|
||||
|
||||
module->connect(sig_y[0], res);
|
||||
if (GetSize(sig_y) > 1)
|
||||
|
|
@ -704,9 +704,9 @@ struct XpropWorker
|
|||
auto enc_a = encoded(sig_a);
|
||||
auto enc_b = encoded(sig_b);
|
||||
|
||||
auto delta_0 = module->Xnor(NEW_ID, enc_a.is_0, enc_b.is_0);
|
||||
auto delta_1 = module->Xnor(NEW_ID, enc_a.is_1, enc_b.is_1);
|
||||
module->addAnd(NEW_ID, delta_0, delta_1, sig_y);
|
||||
auto delta_0 = module->Xnor(NEW_TWINE, enc_a.is_0, enc_b.is_0);
|
||||
auto delta_1 = module->Xnor(NEW_TWINE, enc_a.is_1, enc_b.is_1);
|
||||
module->addAnd(NEW_TWINE, delta_0, delta_1, sig_y);
|
||||
module->remove(cell);
|
||||
return;
|
||||
}
|
||||
|
|
@ -725,12 +725,12 @@ struct XpropWorker
|
|||
auto enc_s = encoded(sig_s);
|
||||
auto enc_y = encoded(sig_y, true);
|
||||
|
||||
enc_y.connect_1(module->And(NEW_ID,
|
||||
module->Or(NEW_ID, enc_a.is_1, enc_s.is_1),
|
||||
module->Or(NEW_ID, enc_b.is_1, enc_s.is_0)));
|
||||
enc_y.connect_0(module->And(NEW_ID,
|
||||
module->Or(NEW_ID, enc_a.is_0, enc_s.is_1),
|
||||
module->Or(NEW_ID, enc_b.is_0, enc_s.is_0)));
|
||||
enc_y.connect_1(module->And(NEW_TWINE,
|
||||
module->Or(NEW_TWINE, enc_a.is_1, enc_s.is_1),
|
||||
module->Or(NEW_TWINE, enc_b.is_1, enc_s.is_0)));
|
||||
enc_y.connect_0(module->And(NEW_TWINE,
|
||||
module->Or(NEW_TWINE, enc_a.is_0, enc_s.is_1),
|
||||
module->Or(NEW_TWINE, enc_b.is_0, enc_s.is_0)));
|
||||
enc_y.auto_x();
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -749,23 +749,23 @@ struct XpropWorker
|
|||
|
||||
int width = GetSize(enc_y);
|
||||
|
||||
auto all_x = module->ReduceOr(NEW_ID, {
|
||||
auto all_x = module->ReduceOr(NEW_TWINE, {
|
||||
enc_s.is_x,
|
||||
module->And(NEW_ID, enc_s.is_1, module->Sub(NEW_ID, enc_s.is_1, Const(1, width)))
|
||||
module->And(NEW_ID, enc_s.is_1, module->Sub(NEW_TWINE, enc_s.is_1, Const(1, width)))
|
||||
});
|
||||
|
||||
auto selected = enc_a;
|
||||
|
||||
for (int i = 0; i < GetSize(enc_s); i++) {
|
||||
auto sel_bit = enc_s.is_1[i];
|
||||
selected.is_0 = module->Mux(NEW_ID, selected.is_0, enc_b.is_0.extract(i * width, width), sel_bit);
|
||||
selected.is_1 = module->Mux(NEW_ID, selected.is_1, enc_b.is_1.extract(i * width, width), sel_bit);
|
||||
selected.is_x = module->Mux(NEW_ID, selected.is_x, enc_b.is_x.extract(i * width, width), sel_bit);
|
||||
selected.is_0 = module->Mux(NEW_TWINE, selected.is_0, enc_b.is_0.extract(i * width, width), sel_bit);
|
||||
selected.is_1 = module->Mux(NEW_TWINE, selected.is_1, enc_b.is_1.extract(i * width, width), sel_bit);
|
||||
selected.is_x = module->Mux(NEW_TWINE, selected.is_x, enc_b.is_x.extract(i * width, width), sel_bit);
|
||||
}
|
||||
|
||||
enc_y.connect_0(module->Mux(NEW_ID, selected.is_0, Const(State::S0, width), all_x));
|
||||
enc_y.connect_1(module->Mux(NEW_ID, selected.is_1, Const(State::S0, width), all_x));
|
||||
enc_y.connect_x(module->Mux(NEW_ID, selected.is_x, Const(State::S1, width), all_x));
|
||||
enc_y.connect_0(module->Mux(NEW_TWINE, selected.is_0, Const(State::S0, width), all_x));
|
||||
enc_y.connect_1(module->Mux(NEW_TWINE, selected.is_1, Const(State::S0, width), all_x));
|
||||
enc_y.connect_x(module->Mux(NEW_TWINE, selected.is_x, Const(State::S1, width), all_x));
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -780,8 +780,8 @@ struct XpropWorker
|
|||
auto enc_b = encoded(sig_b);
|
||||
auto enc_y = encoded(sig_y, true);
|
||||
|
||||
auto all_x = module->ReduceOr(NEW_ID, enc_b.is_x)[0];
|
||||
auto not_all_x = module->Not(NEW_ID, all_x)[0];
|
||||
auto all_x = module->ReduceOr(NEW_TWINE, enc_b.is_x)[0];
|
||||
auto not_all_x = module->Not(NEW_TWINE, all_x)[0];
|
||||
|
||||
SigSpec y_not_0 = module->addWire(NEW_TWINE, GetSize(sig_y));
|
||||
SigSpec y_1 = module->addWire(NEW_TWINE, GetSize(sig_y));
|
||||
|
|
@ -795,7 +795,7 @@ struct XpropWorker
|
|||
|
||||
auto shift_0 = module->addCell(NEW_TWINE, encoded_type);
|
||||
shift_0->parameters = cell->parameters;
|
||||
shift_0->setPort(TW::A, module->Not(NEW_ID, enc_a.is_0));
|
||||
shift_0->setPort(TW::A, module->Not(NEW_TWINE, enc_a.is_0));
|
||||
shift_0->setPort(TW::B, enc_b.is_1);
|
||||
shift_0->setPort(TW::Y, y_not_0);
|
||||
|
||||
|
|
@ -811,14 +811,14 @@ struct XpropWorker
|
|||
shift_x->setPort(TW::B, enc_b.is_1);
|
||||
shift_x->setPort(TW::Y, y_x);
|
||||
|
||||
SigSpec y_0 = module->Not(NEW_ID, y_not_0);
|
||||
SigSpec y_0 = module->Not(NEW_TWINE, y_not_0);
|
||||
|
||||
if (cell->type == ID($shiftx))
|
||||
std::swap(y_0, y_x);
|
||||
|
||||
enc_y.connect_0(module->And(NEW_ID, y_0, SigSpec(not_all_x, GetSize(sig_y))));
|
||||
enc_y.connect_1(module->And(NEW_ID, y_1, SigSpec(not_all_x, GetSize(sig_y))));
|
||||
enc_y.connect_x(module->Or(NEW_ID, y_x, SigSpec(all_x, GetSize(sig_y))));
|
||||
enc_y.connect_0(module->And(NEW_TWINE, y_0, SigSpec(not_all_x, GetSize(sig_y))));
|
||||
enc_y.connect_1(module->And(NEW_TWINE, y_1, SigSpec(not_all_x, GetSize(sig_y))));
|
||||
enc_y.connect_x(module->Or(NEW_TWINE, y_x, SigSpec(all_x, GetSize(sig_y))));
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
|
|
@ -844,8 +844,8 @@ struct XpropWorker
|
|||
|
||||
auto data_q = module->addWire(NEW_TWINE, GetSize(sig_q));
|
||||
|
||||
module->addFf(NEW_ID, enc_d.is_1, data_q);
|
||||
module->addFf(NEW_ID, enc_d.is_x, enc_q.is_x);
|
||||
module->addFf(NEW_TWINE, enc_d.is_1, data_q);
|
||||
module->addFf(NEW_TWINE, enc_d.is_x, enc_q.is_x);
|
||||
|
||||
initvals.set_init(data_q, init_q_is_1);
|
||||
initvals.set_init(enc_q.is_x, init_q_is_x);
|
||||
|
|
@ -929,13 +929,13 @@ struct XpropWorker
|
|||
|
||||
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) {
|
||||
auto sig_b = cell->getPort(TW::B);
|
||||
auto invalid = module->LogicNot(NEW_ID, sig_b);
|
||||
auto invalid = module->LogicNot(NEW_TWINE, sig_b);
|
||||
inbits_x.append(invalid);
|
||||
sig_b[0] = module->Or(NEW_ID, sig_b[0], invalid);
|
||||
sig_b[0] = module->Or(NEW_TWINE, sig_b[0], invalid);
|
||||
cell->setPort(TW::B, sig_b);
|
||||
}
|
||||
|
||||
SigBit outbits_x = (GetSize(inbits_x) == 1 ? inbits_x : module->ReduceOr(NEW_ID, inbits_x));
|
||||
SigBit outbits_x = (GetSize(inbits_x) == 1 ? inbits_x : module->ReduceOr(NEW_TWINE, inbits_x));
|
||||
|
||||
bool bool_out = cell->type.in(ID($le), ID($lt), ID($ge), ID($gt));
|
||||
|
||||
|
|
@ -1096,9 +1096,9 @@ struct XpropWorker
|
|||
it->second.driven = true;
|
||||
}
|
||||
|
||||
module->addBweqx(NEW_ID, orig, Const(State::S0, GetSize(orig)), enc.is_0);
|
||||
module->addBweqx(NEW_ID, orig, Const(State::S1, GetSize(orig)), enc.is_1);
|
||||
module->addBweqx(NEW_ID, orig, Const(State::Sx, GetSize(orig)), enc.is_x);
|
||||
module->addBweqx(NEW_TWINE, orig, Const(State::S0, GetSize(orig)), enc.is_0);
|
||||
module->addBweqx(NEW_TWINE, orig, Const(State::S1, GetSize(orig)), enc.is_1);
|
||||
module->addBweqx(NEW_TWINE, orig, Const(State::Sx, GetSize(orig)), enc.is_x);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1234,7 +1234,7 @@ struct XpropPass : public Pass {
|
|||
continue;
|
||||
|
||||
if (wire->port_input) {
|
||||
module->addAssume(NEW_ID, module->Not(NEW_ID, module->ReduceOr(NEW_ID, module->Bweqx(NEW_ID, wire, Const(State::Sx, GetSize(wire))))), State::S1);
|
||||
module->addAssume(NEW_ID, module->Not(NEW_TWINE, module->ReduceOr(NEW_TWINE, module->Bweqx(NEW_TWINE, wire, Const(State::Sx, GetSize(wire))))), State::S1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct EquivAddPass : public Pass {
|
|||
{
|
||||
bool try_mode = false;
|
||||
|
||||
if (design->selected_active_module.empty())
|
||||
if (design->selected_active_module == Twine::Null)
|
||||
log_cmd_error("This command must be executed in module context!\n");
|
||||
|
||||
Module *module = design->module(design->selected_active_module);
|
||||
|
|
@ -56,8 +56,8 @@ struct EquivAddPass : public Pass {
|
|||
|
||||
if (GetSize(args) == 4 && args[1] == "-cell")
|
||||
{
|
||||
Cell *gold_cell = module->cell(RTLIL::escape_id(args[2]));
|
||||
Cell *gate_cell = module->cell(RTLIL::escape_id(args[3]));
|
||||
Cell *gold_cell = module->cell(design->twines.lookup(RTLIL::escape_id(args[2])));
|
||||
Cell *gate_cell = module->cell(design->twines.lookup(RTLIL::escape_id(args[3])));
|
||||
|
||||
if (gold_cell == nullptr) {
|
||||
if (try_mode) {
|
||||
|
|
@ -87,7 +87,7 @@ struct EquivAddPass : public Pass {
|
|||
SigSpec combined_sig = module->addWire(NEW_TWINE, width);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
module->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], combined_sig[i]);
|
||||
module->addEquiv(NEW_TWINE, gold_sig[i], gate_sig[i], combined_sig[i]);
|
||||
gold_sig[i] = gate_sig[i] = combined_sig[i];
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ struct EquivAddPass : public Pass {
|
|||
SigSig gg_conn;
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
module->addEquiv(NEW_ID, new_gold_wire[i], new_gold_wire[i], gold_sig[i]);
|
||||
module->addEquiv(NEW_TWINE, new_gold_wire[i], new_gold_wire[i], gold_sig[i]);
|
||||
gg_conn.first.append(gate_sig[i]);
|
||||
gg_conn.second.append(gold_sig[i]);
|
||||
gold_sig[i] = new_gold_wire[i];
|
||||
|
|
@ -151,7 +151,7 @@ struct EquivAddPass : public Pass {
|
|||
pool<Cell*> added_equiv_cells;
|
||||
|
||||
for (int i = 0; i < GetSize(gold_signal); i++) {
|
||||
Cell *equiv_cell = module->addEquiv(NEW_ID, gold_signal[i], gate_signal[i], equiv_signal[i]);
|
||||
Cell *equiv_cell = module->addEquiv(NEW_TWINE, gold_signal[i], gate_signal[i], equiv_signal[i]);
|
||||
equiv_cell->set_bool_attribute(ID::keep);
|
||||
to_equiv_bits[gold_signal[i]] = equiv_signal[i];
|
||||
to_equiv_bits[gate_signal[i]] = equiv_signal[i];
|
||||
|
|
|
|||
|
|
@ -108,13 +108,13 @@ struct EquivMakeWorker
|
|||
for (auto it : gold_clone->wires().to_vector()) {
|
||||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
wire_names.insert(it->name);
|
||||
gold_clone->rename(it, it->name.str() + "_gold");
|
||||
gold_clone->rename(it, gold_clone->design->twines.add(Twine{it->name.str() + "_gold"}));
|
||||
}
|
||||
|
||||
for (auto it : gold_clone->cells().to_vector()) {
|
||||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
cell_names.insert(it->name);
|
||||
gold_clone->rename(it, it->name.str() + "_gold");
|
||||
gold_clone->rename(it, gold_clone->design->twines.add(Twine{it->name.str() + "_gold"}));
|
||||
if (it->type.in(ID($input_port), ID($output_port), ID($public)))
|
||||
gold_clone->remove(it);
|
||||
}
|
||||
|
|
@ -122,13 +122,13 @@ struct EquivMakeWorker
|
|||
for (auto it : gate_clone->wires().to_vector()) {
|
||||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
wire_names.insert(it->name);
|
||||
gate_clone->rename(it, it->name.str() + "_gate");
|
||||
gate_clone->rename(it, gate_clone->design->twines.add(Twine{it->name.str() + "_gate"}));
|
||||
}
|
||||
|
||||
for (auto it : gate_clone->cells().to_vector()) {
|
||||
if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0)
|
||||
cell_names.insert(it->name);
|
||||
gate_clone->rename(it, it->name.str() + "_gate");
|
||||
gate_clone->rename(it, gate_clone->design->twines.add(Twine{it->name.str() + "_gate"}));
|
||||
if (it->type.in(ID($input_port), ID($output_port), ID($public)))
|
||||
gate_clone->remove(it);
|
||||
}
|
||||
|
|
@ -141,8 +141,8 @@ struct EquivMakeWorker
|
|||
|
||||
void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig)
|
||||
{
|
||||
auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig);
|
||||
equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1);
|
||||
auto eq_wire = equiv_mod->Eqx(NEW_TWINE, gold_sig, gate_sig);
|
||||
equiv_mod->addAssert(NEW_TWINE_SUFFIX("assert"), eq_wire, State::S1);
|
||||
}
|
||||
|
||||
void find_same_wires()
|
||||
|
|
@ -156,8 +156,8 @@ struct EquivMakeWorker
|
|||
|
||||
for (auto id : wire_names)
|
||||
{
|
||||
IdString gold_id = id.str() + "_gold";
|
||||
IdString gate_id = id.str() + "_gate";
|
||||
TwineRef gold_id = equiv_mod->design->twines.lookup(id.str() + "_gold");
|
||||
TwineRef gate_id = equiv_mod->design->twines.lookup(id.str() + "_gate");
|
||||
|
||||
Wire *gold_wire = equiv_mod->wire(gold_id);
|
||||
Wire *gate_wire = equiv_mod->wire(gate_id);
|
||||
|
|
@ -166,8 +166,8 @@ struct EquivMakeWorker
|
|||
{
|
||||
log("Creating encoder/decoder for signal %s.\n", id.unescape());
|
||||
|
||||
Wire *dec_wire = equiv_mod->addWire(id.str() + "_decoded", gold_wire->width);
|
||||
Wire *enc_wire = equiv_mod->addWire(id.str() + "_encoded", gate_wire->width);
|
||||
Wire *dec_wire = equiv_mod->addWire(Twine{id.str() + "_decoded"}, gold_wire->width);
|
||||
Wire *enc_wire = equiv_mod->addWire(Twine{id.str() + "_encoded"}, gate_wire->width);
|
||||
|
||||
SigSpec dec_a, dec_b, dec_s;
|
||||
SigSpec enc_a, enc_b, enc_s;
|
||||
|
|
@ -213,8 +213,8 @@ struct EquivMakeWorker
|
|||
SigSpec dec_eq = equiv_mod->addWire(NEW_TWINE);
|
||||
SigSpec enc_eq = equiv_mod->addWire(NEW_TWINE);
|
||||
|
||||
equiv_mod->addEq(NEW_ID, reduced_dec_sig, reduced_dec_pat, dec_eq);
|
||||
cells_list.push_back(equiv_mod->addEq(NEW_ID, reduced_enc_sig, reduced_enc_pat, enc_eq));
|
||||
equiv_mod->addEq(NEW_TWINE, reduced_dec_sig, reduced_dec_pat, dec_eq);
|
||||
cells_list.push_back(equiv_mod->addEq(NEW_TWINE, reduced_enc_sig, reduced_enc_pat, enc_eq));
|
||||
|
||||
dec_s.append(dec_eq);
|
||||
enc_s.append(enc_eq);
|
||||
|
|
@ -222,8 +222,8 @@ struct EquivMakeWorker
|
|||
enc_b.append(enc_result);
|
||||
}
|
||||
|
||||
equiv_mod->addPmux(NEW_ID, dec_a, dec_b, dec_s, dec_wire);
|
||||
equiv_mod->addPmux(NEW_ID, enc_a, enc_b, enc_s, enc_wire);
|
||||
equiv_mod->addPmux(NEW_TWINE, dec_a, dec_b, dec_s, dec_wire);
|
||||
equiv_mod->addPmux(NEW_TWINE, enc_a, enc_b, enc_s, enc_wire);
|
||||
|
||||
rd_signal_map.add(assign_map(gate_wire), enc_wire);
|
||||
gate_wire = dec_wire;
|
||||
|
|
@ -248,7 +248,7 @@ struct EquivMakeWorker
|
|||
gold_wire->port_output = false;
|
||||
gate_wire->port_output = false;
|
||||
|
||||
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
|
||||
Wire *wire = equiv_mod->addWire(Twine{id.str()}, gold_wire->width);
|
||||
wire->port_output = true;
|
||||
|
||||
if (make_assert)
|
||||
|
|
@ -259,7 +259,7 @@ struct EquivMakeWorker
|
|||
else
|
||||
{
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
|
||||
equiv_mod->addEquiv(NEW_TWINE, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
|
||||
}
|
||||
|
||||
rd_signal_map.add(assign_map(gold_wire), wire);
|
||||
|
|
@ -268,7 +268,7 @@ struct EquivMakeWorker
|
|||
else
|
||||
if (gold_wire->port_input || gate_wire->port_input)
|
||||
{
|
||||
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
|
||||
Wire *wire = equiv_mod->addWire(Twine{id.str()}, gold_wire->width);
|
||||
wire->port_input = true;
|
||||
gold_wire->port_input = false;
|
||||
gate_wire->port_input = false;
|
||||
|
|
@ -284,7 +284,7 @@ struct EquivMakeWorker
|
|||
add_eq_assertion(gold_wire, gate_wire);
|
||||
|
||||
else {
|
||||
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
|
||||
Wire *wire = equiv_mod->addWire(Twine{id.str()}, gold_wire->width);
|
||||
SigSpec rdmap_gold, rdmap_gate, rdmap_equiv;
|
||||
|
||||
for (int i = 0; i < wire->width; i++) {
|
||||
|
|
@ -296,7 +296,7 @@ struct EquivMakeWorker
|
|||
log(" Skipping signal bit %s [%d]: undriven on gate side.\n", gate_wire, i);
|
||||
continue;
|
||||
}
|
||||
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
|
||||
equiv_mod->addEquiv(NEW_TWINE, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
|
||||
rdmap_gold.append(SigBit(gold_wire, i));
|
||||
rdmap_gate.append(SigBit(gate_wire, i));
|
||||
rdmap_equiv.append(SigBit(wire, 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",
|
||||
conn.first.unescape(), c, c->type.unescape(),
|
||||
equiv_mod->design->twines.str(conn.first).c_str(), c, c->type.unescape(),
|
||||
log_signal(old_sig), log_signal(new_sig));
|
||||
c->setPort(conn.first, new_sig);
|
||||
}
|
||||
|
|
@ -333,8 +333,8 @@ struct EquivMakeWorker
|
|||
|
||||
for (auto id : cell_names)
|
||||
{
|
||||
IdString gold_id = id.str() + "_gold";
|
||||
IdString gate_id = id.str() + "_gate";
|
||||
TwineRef gold_id = equiv_mod->design->twines.lookup(id.str() + "_gold");
|
||||
TwineRef gate_id = equiv_mod->design->twines.lookup(id.str() + "_gate");
|
||||
|
||||
Cell *gold_cell = equiv_mod->cell(gold_id);
|
||||
Cell *gate_cell = equiv_mod->cell(gate_id);
|
||||
|
|
@ -371,7 +371,7 @@ struct EquivMakeWorker
|
|||
for (int i = 0; i < GetSize(gold_sig); i++)
|
||||
if (gold_sig[i] != gate_sig[i]) {
|
||||
Wire *w = equiv_mod->addWire(NEW_TWINE);
|
||||
equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w);
|
||||
equiv_mod->addEquiv(NEW_TWINE, gold_sig[i], gate_sig[i], w);
|
||||
gold_sig[i] = w;
|
||||
}
|
||||
}
|
||||
|
|
@ -380,7 +380,7 @@ struct EquivMakeWorker
|
|||
}
|
||||
|
||||
equiv_mod->remove(gate_cell);
|
||||
equiv_mod->rename(gold_cell, id);
|
||||
equiv_mod->rename(gold_cell, equiv_mod->design->twines.lookup(id.str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,9 +492,9 @@ struct EquivMakePass : public Pass {
|
|||
if (argidx+3 != args.size())
|
||||
log_cmd_error("Invalid number of arguments.\n");
|
||||
|
||||
worker.gold_mod = design->module(RTLIL::escape_id(args[argidx]));
|
||||
worker.gate_mod = design->module(RTLIL::escape_id(args[argidx+1]));
|
||||
worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2]));
|
||||
worker.gold_mod = design->module(design->twines.lookup(RTLIL::escape_id(args[argidx])));
|
||||
worker.gate_mod = design->module(design->twines.lookup(RTLIL::escape_id(args[argidx+1])));
|
||||
worker.equiv_mod = design->module(design->twines.lookup(RTLIL::escape_id(args[argidx+2])));
|
||||
|
||||
if (worker.gold_mod == nullptr)
|
||||
log_cmd_error("Can't find gold module %s.\n", args[argidx]);
|
||||
|
|
@ -516,7 +516,7 @@ struct EquivMakePass : public Pass {
|
|||
|
||||
log_header(design, "Executing EQUIV_MAKE pass (creating equiv checking module).\n");
|
||||
|
||||
worker.equiv_mod = design->addModule(RTLIL::escape_id(args[argidx+2]));
|
||||
worker.equiv_mod = design->addModule(design->twines.add(Twine{RTLIL::escape_id(args[argidx+2])}));
|
||||
worker.run();
|
||||
Pass::call(design, "dump");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@ struct EquivMarkWorker
|
|||
SigMap sigmap;
|
||||
|
||||
// cache for traversing signal flow graph
|
||||
dict<SigBit, pool<IdString>> up_bit2cells;
|
||||
dict<IdString, pool<SigBit>> up_cell2bits;
|
||||
pool<IdString> edge_cells, equiv_cells;
|
||||
dict<SigBit, pool<TwineRef>> up_bit2cells;
|
||||
dict<TwineRef, pool<SigBit>> up_cell2bits;
|
||||
pool<TwineRef> edge_cells, equiv_cells;
|
||||
|
||||
// graph traversal state
|
||||
pool<SigBit> queue, visited;
|
||||
|
||||
// assigned regions
|
||||
dict<IdString, int> cell_regions;
|
||||
dict<TwineRef, int> cell_regions;
|
||||
dict<SigBit, int> bit_regions;
|
||||
int next_region;
|
||||
|
||||
|
|
@ -49,17 +49,17 @@ struct EquivMarkWorker
|
|||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID($equiv))
|
||||
equiv_cells.insert(cell->name);
|
||||
equiv_cells.insert(cell->meta_->name);
|
||||
|
||||
for (auto &port : cell->connections())
|
||||
{
|
||||
if (cell->input(port.first))
|
||||
for (auto bit : sigmap(port.second))
|
||||
up_cell2bits[cell->name].insert(bit);
|
||||
up_cell2bits[cell->meta_->name].insert(bit);
|
||||
|
||||
if (cell->output(port.first))
|
||||
for (auto bit : sigmap(port.second))
|
||||
up_bit2cells[bit].insert(cell->name);
|
||||
up_bit2cells[bit].insert(cell->meta_->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ struct EquivMarkWorker
|
|||
{
|
||||
while (!queue.empty())
|
||||
{
|
||||
pool<IdString> cells;
|
||||
pool<TwineRef> cells;
|
||||
|
||||
for (auto &bit : queue)
|
||||
{
|
||||
|
|
@ -139,7 +139,7 @@ struct EquivMarkWorker
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell_regions.count(cell->name) || cell->type != ID($equiv))
|
||||
if (cell_regions.count(cell->meta_->name) || cell->type != ID($equiv))
|
||||
continue;
|
||||
|
||||
SigSpec sig_a = sigmap(cell->getPort(TW::A));
|
||||
|
|
@ -153,7 +153,7 @@ struct EquivMarkWorker
|
|||
for (auto bit : sig_b)
|
||||
queue.insert(bit);
|
||||
|
||||
cell_regions[cell->name] = next_region;
|
||||
cell_regions[cell->meta_->name] = next_region;
|
||||
mark();
|
||||
}
|
||||
|
||||
|
|
@ -174,8 +174,8 @@ struct EquivMarkWorker
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell_regions.count(cell->name)) {
|
||||
int r = final_region_map.at(cell_regions.at(cell->name));
|
||||
if (cell_regions.count(cell->meta_->name)) {
|
||||
int r = final_region_map.at(cell_regions.at(cell->meta_->name));
|
||||
cell->attributes[ID::equiv_region] = Const(r);
|
||||
region_cell_count[r]++;
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct EquivMiterWorker
|
|||
for (auto &conn : c->connections()) {
|
||||
if (!ct.cell_input(c->type, conn.first))
|
||||
continue;
|
||||
if (c->type == ID($equiv) && (conn.first == ID::A) != gold_mode)
|
||||
if (c->type == ID($equiv) && (conn.first == TW::A) != gold_mode)
|
||||
continue;
|
||||
for (auto bit : sigmap(conn.second))
|
||||
if (bit_to_driver.count(bit))
|
||||
|
|
@ -141,11 +141,11 @@ struct EquivMiterWorker
|
|||
// copy wires and cells
|
||||
|
||||
for (auto w : miter_wires)
|
||||
miter_module->addWire(w->name, w->width);
|
||||
miter_module->addWire(Twine{w->name.str()}, w->width);
|
||||
for (auto c : miter_cells) {
|
||||
if (c->type.in(ID($input_port), ID($output_port), ID($public)))
|
||||
continue;
|
||||
auto mc = miter_module->addCell(c->name, c);
|
||||
auto mc = miter_module->addCell(Twine{c->name.str()}, c);
|
||||
for (auto &conn : mc->connections())
|
||||
mc->setPort(conn.first, sigmap(conn.second));
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ struct EquivMiterWorker
|
|||
vector<SigChunk> chunks = sig.chunks();
|
||||
for (auto &c : chunks)
|
||||
if (c.wire != NULL)
|
||||
c.wire = mod->wire(RTLIL::IdString(c.wire->name));
|
||||
c.wire = mod->wire(mod->design->twines.lookup(c.wire->name.str()));
|
||||
sig = chunks;
|
||||
}
|
||||
};
|
||||
|
|
@ -220,9 +220,9 @@ struct EquivMiterWorker
|
|||
for (auto c : equiv_cells)
|
||||
{
|
||||
SigSpec cmp = mode_undef ?
|
||||
miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort(TW::A), State::Sx),
|
||||
miter_module->Eqx(NEW_ID, c->getPort(TW::A), c->getPort(TW::B))) :
|
||||
miter_module->Eq(NEW_ID, c->getPort(TW::A), c->getPort(TW::B));
|
||||
miter_module->LogicOr(NEW_TWINE, miter_module->Eqx(NEW_TWINE, c->getPort(TW::A), State::Sx),
|
||||
miter_module->Eqx(NEW_TWINE, c->getPort(TW::A), c->getPort(TW::B))) :
|
||||
miter_module->Eq(NEW_TWINE, c->getPort(TW::A), c->getPort(TW::B));
|
||||
|
||||
if (mode_cmp) {
|
||||
string cmp_name = stringf("\\cmp%s", log_signal(c->getPort(TW::Y)));
|
||||
|
|
@ -231,21 +231,21 @@ struct EquivMiterWorker
|
|||
cmp_name[i] = '_';
|
||||
else if (cmp_name[i] == ' ')
|
||||
cmp_name = cmp_name.substr(0, i) + cmp_name.substr(i+1);
|
||||
auto w = miter_module->addWire(cmp_name);
|
||||
auto w = miter_module->addWire(Twine{cmp_name});
|
||||
w->port_output = true;
|
||||
miter_module->connect(w, cmp);
|
||||
}
|
||||
|
||||
if (mode_assert)
|
||||
miter_module->addAssert(NEW_ID, cmp, State::S1);
|
||||
miter_module->addAssert(NEW_TWINE, cmp, State::S1);
|
||||
|
||||
trigger_signals.append(miter_module->Not(NEW_ID, cmp));
|
||||
trigger_signals.append(miter_module->Not(NEW_TWINE, cmp));
|
||||
}
|
||||
|
||||
if (mode_trigger) {
|
||||
auto w = miter_module->addWire(ID(trigger));
|
||||
auto w = miter_module->addWire(Twine{"trigger"});
|
||||
w->port_output = true;
|
||||
miter_module->addReduceOr(NEW_ID, trigger_signals, w);
|
||||
miter_module->addReduceOr(NEW_TWINE, trigger_signals, w);
|
||||
}
|
||||
|
||||
miter_module->fixup_ports();
|
||||
|
|
@ -323,7 +323,7 @@ struct EquivMiterPass : public Pass {
|
|||
// TODO disable signorm due to rewrite_sigspecs assert
|
||||
design->sigNormalize(false);
|
||||
|
||||
if (design->module(worker.miter_name))
|
||||
if (design->module(design->twines.lookup(worker.miter_name.str())))
|
||||
log_cmd_error("Miter module %s already exists.\n", worker.miter_name.unescape());
|
||||
|
||||
worker.source_module = nullptr;
|
||||
|
|
@ -339,7 +339,7 @@ struct EquivMiterPass : public Pass {
|
|||
|
||||
log_header(design, "Executing EQUIV_MITER pass.\n");
|
||||
|
||||
worker.miter_module = design->addModule(worker.miter_name);
|
||||
worker.miter_module = design->addModule(design->twines.add(Twine{worker.miter_name.str()}));
|
||||
worker.run();
|
||||
}
|
||||
} EquivMiterPass;
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ struct EquivPurgeWorker
|
|||
|
||||
while (1)
|
||||
{
|
||||
IdString name = stringf("\\equiv_%d", name_cnt++);
|
||||
if (module->count_id(name))
|
||||
std::string name = stringf("\\equiv_%d", name_cnt++);
|
||||
if (module->count_id(module->design->twines.lookup(name)))
|
||||
continue;
|
||||
|
||||
Wire *wire = module->addWire(name, GetSize(sig));
|
||||
Wire *wire = module->addWire(Twine{name}, GetSize(sig));
|
||||
wire->port_output = true;
|
||||
module->connect(wire, sig);
|
||||
log(" Module output: %s (%s)\n", log_signal(wire), cellname.unescape());
|
||||
|
|
@ -73,11 +73,11 @@ struct EquivPurgeWorker
|
|||
|
||||
while (1)
|
||||
{
|
||||
IdString name = stringf("\\equiv_%d", name_cnt++);
|
||||
if (module->count_id(name))
|
||||
std::string name = stringf("\\equiv_%d", name_cnt++);
|
||||
if (module->count_id(module->design->twines.lookup(name)))
|
||||
continue;
|
||||
|
||||
Wire *wire = module->addWire(name, GetSize(sig));
|
||||
Wire *wire = module->addWire(Twine{name}, GetSize(sig));
|
||||
wire->port_input = true;
|
||||
module->connect(sig, wire);
|
||||
log(" Module input: %s (%s)\n", log_signal(wire), log_signal(sig));
|
||||
|
|
@ -97,8 +97,8 @@ struct EquivPurgeWorker
|
|||
pool<SigBit> queue, visited;
|
||||
|
||||
// cache for traversing signal flow graph
|
||||
dict<SigBit, pool<IdString>> up_bit2cells;
|
||||
dict<IdString, pool<SigBit>> up_cell2bits;
|
||||
dict<SigBit, pool<TwineRef>> up_bit2cells;
|
||||
dict<TwineRef, pool<SigBit>> up_cell2bits;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
|
|
@ -106,10 +106,10 @@ struct EquivPurgeWorker
|
|||
for (auto &port : cell->connections()) {
|
||||
if (cell->input(port.first))
|
||||
for (auto bit : sigmap(port.second))
|
||||
up_cell2bits[cell->name].insert(bit);
|
||||
up_cell2bits[cell->meta_->name].insert(bit);
|
||||
if (cell->output(port.first))
|
||||
for (auto bit : sigmap(port.second))
|
||||
up_bit2cells[bit].insert(cell->name);
|
||||
up_bit2cells[bit].insert(cell->meta_->name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ struct EquivSimpleWorker : public EquivWorker<EquivSimpleConfig>
|
|||
if (yosys_celltypes.cell_input(cell->type, conn.first))
|
||||
for (auto bit : model.sigmap(conn.second)) {
|
||||
if (cell->is_builtin_ff()) {
|
||||
if (!conn.first.in(ID::CLK, ID::C))
|
||||
if (conn.first != TW::CLK && conn.first != TW::C)
|
||||
next_seed.insert(bit);
|
||||
} else
|
||||
find_input_cone(bit);
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ struct EquivStructWorker
|
|||
{
|
||||
IdString type;
|
||||
vector<pair<IdString, Const>> parameters;
|
||||
vector<pair<IdString, int>> port_sizes;
|
||||
vector<tuple<IdString, int, SigBit>> connections;
|
||||
vector<pair<TwineRef, int>> port_sizes;
|
||||
vector<tuple<TwineRef, int, SigBit>> connections;
|
||||
|
||||
bool operator==(const merge_key_t &other) const {
|
||||
return type == other.type && connections == other.connections &&
|
||||
|
|
@ -55,7 +55,7 @@ struct EquivStructWorker
|
|||
}
|
||||
};
|
||||
|
||||
dict<merge_key_t, pool<IdString>> merge_cache;
|
||||
dict<merge_key_t, pool<TwineRef>> merge_cache;
|
||||
pool<merge_key_t> fwd_merge_cache, bwd_merge_cache;
|
||||
|
||||
void merge_cell_pair(Cell *cell_a, Cell *cell_b)
|
||||
|
|
@ -78,8 +78,8 @@ struct EquivStructWorker
|
|||
if (bits_a[i] != bits_b[i]) {
|
||||
inputs_a.append(bits_a[i]);
|
||||
inputs_b.append(bits_b[i]);
|
||||
input_names.push_back(GetSize(bits_a) == 1 ? port_a.first.str() :
|
||||
stringf("%s[%d]", port_a.first.unescape(), i));
|
||||
input_names.push_back(GetSize(bits_a) == 1 ? module->design->twines.str(port_a.first) :
|
||||
stringf("%s[%d]", module->design->twines.str(port_a.first).c_str(), i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,12 +88,12 @@ struct EquivStructWorker
|
|||
SigBit bit_y = module->addWire(NEW_TWINE);
|
||||
log(" New $equiv for input %s: A: %s, B: %s, Y: %s\n",
|
||||
input_names[i].c_str(), log_signal(bit_a), log_signal(bit_b), log_signal(bit_y));
|
||||
module->addEquiv(NEW_ID, bit_a, bit_b, bit_y);
|
||||
module->addEquiv(NEW_TWINE, bit_a, bit_b, bit_y);
|
||||
merged_map.add(bit_a, bit_y);
|
||||
merged_map.add(bit_b, bit_y);
|
||||
}
|
||||
|
||||
std::vector<IdString> outport_names, inport_names;
|
||||
std::vector<TwineRef> outport_names, inport_names;
|
||||
|
||||
for (auto &port_a : cell_a->connections())
|
||||
if (cell_a->output(port_a.first))
|
||||
|
|
@ -110,9 +110,7 @@ struct EquivStructWorker
|
|||
module->connect(sig_b, sig_a);
|
||||
}
|
||||
|
||||
auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged);
|
||||
merged_attr.insert(cell_b->name.unescape());
|
||||
cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr);
|
||||
cell_a->set_bool_attribute(ID::equiv_merged);
|
||||
module->remove(cell_b);
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +121,7 @@ struct EquivStructWorker
|
|||
log(" Starting iteration %d.\n", iter_num);
|
||||
|
||||
pool<SigBit> equiv_inputs;
|
||||
pool<IdString> cells;
|
||||
pool<TwineRef> cells;
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->type == ID($equiv)) {
|
||||
|
|
@ -132,10 +130,10 @@ struct EquivStructWorker
|
|||
equiv_bits.add(sig_b, sig_a);
|
||||
equiv_inputs.insert(sig_a);
|
||||
equiv_inputs.insert(sig_b);
|
||||
cells.insert(cell->name);
|
||||
cells.insert(cell->meta_->name);
|
||||
} else {
|
||||
if (mode_icells || module->design->module(cell->type))
|
||||
cells.insert(cell->name);
|
||||
cells.insert(cell->meta_->name);
|
||||
}
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
|
|
@ -157,7 +155,7 @@ struct EquivStructWorker
|
|||
for (auto cell_name : cells)
|
||||
{
|
||||
merge_key_t key;
|
||||
vector<tuple<IdString, int, SigBit>> fwd_connections;
|
||||
vector<tuple<TwineRef, int, SigBit>> fwd_connections;
|
||||
|
||||
Cell *cell = module->cell(cell_name);
|
||||
key.type = cell->type;
|
||||
|
|
@ -175,14 +173,14 @@ struct EquivStructWorker
|
|||
if (cell->input(conn.first)) {
|
||||
SigSpec sig = sigmap(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
fwd_connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
fwd_connections.push_back(std::make_tuple(conn.first, i, sig[i]));
|
||||
}
|
||||
|
||||
if (cell->output(conn.first)) {
|
||||
SigSpec sig = equiv_bits(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++) {
|
||||
key.connections.clear();
|
||||
key.connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
key.connections.push_back(std::make_tuple(conn.first, i, sig[i]));
|
||||
|
||||
if (merge_cache.count(key))
|
||||
bwd_merge_cache.insert(key);
|
||||
|
|
@ -213,7 +211,7 @@ struct EquivStructWorker
|
|||
for (auto cell_name : merge_cache[key]) {
|
||||
Cell *c = module->cell(cell_name);
|
||||
if (c != nullptr) {
|
||||
string n = cell_name.str();
|
||||
string n = module->design->twines.str(cell_name);
|
||||
cells_type = c->type;
|
||||
if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gold") == 0)
|
||||
gold_cells.push_back(c);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
|
||||
static RTLIL::Module *module;
|
||||
static SigMap assign_map;
|
||||
typedef std::pair<RTLIL::Cell*, RTLIL::IdString> sig2driver_entry_t;
|
||||
typedef std::pair<RTLIL::Cell*, TwineRef> sig2driver_entry_t;
|
||||
static SigSet<sig2driver_entry_t> sig2driver, sig2user;
|
||||
static std::set<RTLIL::Cell*> muxtree_cells;
|
||||
static SigPool sig_at_port;
|
||||
|
|
@ -55,7 +55,7 @@ ret_false:
|
|||
sig2driver.find(sig, cellport_list);
|
||||
for (auto &cellport : cellport_list)
|
||||
{
|
||||
if ((cellport.first->type != ID($mux) && cellport.first->type != ID($pmux)) || cellport.second != ID::Y) {
|
||||
if ((cellport.first->type != ID($mux) && cellport.first->type != ID($pmux)) || cellport.second != TW::Y) {
|
||||
goto ret_false;
|
||||
}
|
||||
|
||||
|
|
@ -103,12 +103,12 @@ static bool check_state_users(RTLIL::SigSpec sig)
|
|||
continue;
|
||||
if (cell->type == ID($logic_not) && assign_map(cell->getPort(TW::A)) == sig)
|
||||
continue;
|
||||
if (cellport.second != ID::A && cellport.second != ID::B)
|
||||
if (cellport.second != TW::A && cellport.second != TW::B)
|
||||
return false;
|
||||
if (!cell->hasPort(ID::A) || !cell->hasPort(ID::B) || !cell->hasPort(ID::Y))
|
||||
if (!cell->hasPort(TW::A) || !cell->hasPort(TW::B) || !cell->hasPort(TW::Y))
|
||||
return false;
|
||||
for (auto &port_it : cell->connections())
|
||||
if (port_it.first != ID::A && port_it.first != ID::B && port_it.first != ID::Y)
|
||||
if (port_it.first != TW::A && port_it.first != TW::B && port_it.first != TW::Y)
|
||||
return false;
|
||||
if (assign_map(cell->getPort(TW::A)) == sig && cell->getPort(TW::B).is_fully_const())
|
||||
continue;
|
||||
|
|
@ -145,7 +145,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false)
|
|||
|
||||
for (auto &cellport : cellport_list)
|
||||
{
|
||||
if ((cellport.first->type != ID($dff) && cellport.first->type != ID($adff)) || cellport.second != ID::Q)
|
||||
if ((cellport.first->type != ID($dff) && cellport.first->type != ID($adff)) || cellport.second != TW::Q)
|
||||
continue;
|
||||
|
||||
muxtree_cells.clear();
|
||||
|
|
|
|||
|
|
@ -57,17 +57,17 @@ struct FsmExpand
|
|||
int in_bits = 0;
|
||||
RTLIL::SigSpec new_signals;
|
||||
|
||||
if (cell->hasPort(ID::A)) {
|
||||
if (cell->hasPort(TW::A)) {
|
||||
in_bits += GetSize(cell->getPort(TW::A));
|
||||
new_signals.append(assign_map(cell->getPort(TW::A)));
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::B)) {
|
||||
if (cell->hasPort(TW::B)) {
|
||||
in_bits += GetSize(cell->getPort(TW::B));
|
||||
new_signals.append(assign_map(cell->getPort(TW::B)));
|
||||
}
|
||||
|
||||
if (cell->hasPort(ID::S)) {
|
||||
if (cell->hasPort(TW::S)) {
|
||||
in_bits += GetSize(cell->getPort(TW::S));
|
||||
new_signals.append(assign_map(cell->getPort(TW::S)));
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ struct FsmExpand
|
|||
if (in_bits > 8)
|
||||
return false;
|
||||
|
||||
if (cell->hasPort(ID::Y))
|
||||
if (cell->hasPort(TW::Y))
|
||||
new_signals.append(assign_map(cell->getPort(TW::Y)));
|
||||
|
||||
new_signals.sort_and_unify();
|
||||
|
|
@ -106,7 +106,7 @@ struct FsmExpand
|
|||
if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0)
|
||||
continue;
|
||||
for (auto &p : c->connections()) {
|
||||
if (p.first != ID::A && p.first != ID::B && p.first != ID::S && p.first != ID::Y)
|
||||
if (p.first != TW::A && p.first != TW::B && p.first != TW::S && p.first != TW::Y)
|
||||
goto next_cell;
|
||||
}
|
||||
if (!is_cell_merge_candidate(c)) {
|
||||
|
|
@ -159,11 +159,11 @@ struct FsmExpand
|
|||
for (int i = 0; i < (1 << input_sig.size()); i++) {
|
||||
RTLIL::Const in_val(i, input_sig.size());
|
||||
RTLIL::SigSpec A, B, S;
|
||||
if (cell->hasPort(ID::A))
|
||||
if (cell->hasPort(TW::A))
|
||||
A = assign_map(cell->getPort(TW::A));
|
||||
if (cell->hasPort(ID::B))
|
||||
if (cell->hasPort(TW::B))
|
||||
B = assign_map(cell->getPort(TW::B));
|
||||
if (cell->hasPort(ID::S))
|
||||
if (cell->hasPort(TW::S))
|
||||
S = assign_map(cell->getPort(TW::S));
|
||||
A.replace(input_sig, RTLIL::SigSpec(in_val));
|
||||
B.replace(input_sig, RTLIL::SigSpec(in_val));
|
||||
|
|
@ -243,7 +243,7 @@ struct FsmExpand
|
|||
void execute()
|
||||
{
|
||||
log("\n");
|
||||
log("Expanding FSM `%s' from module `%s':\n", fsm_cell->name, module->name);
|
||||
log("Expanding FSM `%s' from module `%s':\n", log_id(fsm_cell), log_id(module));
|
||||
|
||||
already_optimized = false;
|
||||
limit_transitions = 16 * fsm_cell->parameters[ID::TRANS_NUM].as_int();
|
||||
|
|
|
|||
|
|
@ -64,13 +64,13 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st
|
|||
kiss_name.assign(attr_it->second.decode_string());
|
||||
}
|
||||
else {
|
||||
kiss_name.assign(module->name.unescape() + std::string("-") + cell->name.unescape() + ".kiss2");
|
||||
kiss_name.assign(module->design->twines.str(module->meta_->name) + std::string("-") + module->design->twines.str(cell->meta_->name) + ".kiss2");
|
||||
}
|
||||
|
||||
log("\n");
|
||||
log("Exporting FSM `%s' from module `%s' to file `%s'.\n",
|
||||
cell->name.c_str(),
|
||||
module->name.c_str(),
|
||||
log_id(cell),
|
||||
log_id(module),
|
||||
kiss_name.c_str());
|
||||
|
||||
kiss_file.open(kiss_name, std::ios::out | std::ios::trunc);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
|
||||
static RTLIL::Module *module;
|
||||
static SigMap assign_map;
|
||||
typedef std::pair<RTLIL::IdString, RTLIL::IdString> sig2driver_entry_t;
|
||||
typedef std::pair<TwineRef, TwineRef> sig2driver_entry_t;
|
||||
static SigSet<sig2driver_entry_t> sig2driver, sig2trigger;
|
||||
static std::map<RTLIL::SigBit, std::set<RTLIL::SigBit>> exclusive_ctrls;
|
||||
|
||||
|
|
@ -70,8 +70,8 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL
|
|||
for (auto &cellport : cellport_list)
|
||||
{
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) {
|
||||
log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type, cell->name);
|
||||
if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != TW::Y) {
|
||||
log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type, log_id(cell));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ undef_bit_in_next_state:
|
|||
|
||||
static void extract_fsm(RTLIL::Wire *wire)
|
||||
{
|
||||
log("Extracting FSM `%s' from module `%s'.\n", wire->name, module->name);
|
||||
log("Extracting FSM `%s' from module `%s'.\n", log_id(wire), log_id(module));
|
||||
|
||||
// get input and output signals for state ff
|
||||
|
||||
|
|
@ -272,9 +272,9 @@ static void extract_fsm(RTLIL::Wire *wire)
|
|||
sig2driver.find(dff_out, cellport_list);
|
||||
for (auto &cellport : cellport_list) {
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q)
|
||||
if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != TW::Q)
|
||||
continue;
|
||||
log(" found %s cell for state register: %s\n", cell->type, cell->name);
|
||||
log(" found %s cell for state register: %s\n", cell->type, log_id(cell));
|
||||
RTLIL::SigSpec sig_q = assign_map(cell->getPort(TW::Q));
|
||||
RTLIL::SigSpec sig_d = assign_map(cell->getPort(TW::D));
|
||||
clk = cell->getPort(TW::CLK);
|
||||
|
|
@ -322,12 +322,12 @@ static void extract_fsm(RTLIL::Wire *wire)
|
|||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort(TW::A));
|
||||
RTLIL::SigSpec sig_b;
|
||||
if (cell->hasPort(ID::B))
|
||||
if (cell->hasPort(TW::B))
|
||||
sig_b = assign_map(cell->getPort(TW::B));
|
||||
RTLIL::SigSpec sig_y = assign_map(cell->getPort(TW::Y));
|
||||
if (cellport.second == ID::A && !sig_b.is_fully_const())
|
||||
if (cellport.second == TW::A && !sig_b.is_fully_const())
|
||||
continue;
|
||||
if (cellport.second == ID::B && !sig_a.is_fully_const())
|
||||
if (cellport.second == TW::B && !sig_a.is_fully_const())
|
||||
continue;
|
||||
log(" found ctrl output: %s\n", log_signal(sig_y));
|
||||
ctrl_out.append(sig_y);
|
||||
|
|
@ -368,7 +368,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
|||
|
||||
// create fsm cell
|
||||
|
||||
RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name, autoidx++), ID($fsm));
|
||||
RTLIL::Cell *fsm_cell = module->addCell(Twine{stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++)}, ID($fsm));
|
||||
fsm_cell->setPort(TW::CLK, clk);
|
||||
fsm_cell->setPort(TW::ARST, arst);
|
||||
fsm_cell->parameters[ID::CLK_POLARITY] = clk_polarity ? State::S1 : State::S0;
|
||||
|
|
@ -389,7 +389,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
|||
// rename original state wire
|
||||
|
||||
wire->attributes.erase(ID::fsm_encoding);
|
||||
module->rename(wire, stringf("$fsm$oldstate%s", wire->name.c_str()));
|
||||
module->rename(wire, module->design->twines.add(Twine{stringf("$fsm$oldstate%s", wire->name.c_str())}));
|
||||
if(wire->attributes.count(ID::hdlname)) {
|
||||
auto hdlname = wire->get_hdlname_attribute();
|
||||
hdlname.pop_back();
|
||||
|
|
@ -406,7 +406,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
|||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
RTLIL::SigSpec port_sig = assign_map(cell->getPort(cellport.second));
|
||||
RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out);
|
||||
RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%d", autoidx++), unconn_sig.size());
|
||||
RTLIL::Wire *unconn_wire = module->addWire(Twine{stringf("$fsm_unconnect$%d", autoidx++)}, unconn_sig.size());
|
||||
port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]);
|
||||
}
|
||||
}
|
||||
|
|
@ -449,13 +449,13 @@ struct FsmExtractPass : public Pass {
|
|||
if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
|
||||
RTLIL::SigSpec sig = conn_it.second;
|
||||
assign_map.apply(sig);
|
||||
sig2driver.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
|
||||
sig2driver.insert(sig, sig2driver_entry_t(cell->meta_->name, conn_it.first));
|
||||
}
|
||||
if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort(ID::Y) &&
|
||||
cell->getPort(TW::Y).size() == 1 && (conn_it.first == ID::A || conn_it.first == ID::B)) {
|
||||
if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort(TW::Y) &&
|
||||
cell->getPort(TW::Y).size() == 1 && (conn_it.first == TW::A || conn_it.first == TW::B)) {
|
||||
RTLIL::SigSpec sig = conn_it.second;
|
||||
assign_map.apply(sig);
|
||||
sig2trigger.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
|
||||
sig2trigger.insert(sig, sig2driver_entry_t(cell->meta_->name, conn_it.first));
|
||||
}
|
||||
}
|
||||
if (cell->type == ID($pmux)) {
|
||||
|
|
|
|||
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