3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-12 16:25:07 +02:00
parent c3ffbf6fae
commit d22805bd47
65 changed files with 739 additions and 718 deletions

View file

@ -55,31 +55,31 @@ static void logmap(IdString dff)
static void logmap_all()
{
logmap(TW($_DFF_N_));
logmap(TW($_DFF_P_));
logmap(ID($_DFF_N_));
logmap(ID($_DFF_P_));
logmap(TW($_DFF_NN0_));
logmap(TW($_DFF_NN1_));
logmap(TW($_DFF_NP0_));
logmap(TW($_DFF_NP1_));
logmap(TW($_DFF_PN0_));
logmap(TW($_DFF_PN1_));
logmap(TW($_DFF_PP0_));
logmap(TW($_DFF_PP1_));
logmap(ID($_DFF_NN0_));
logmap(ID($_DFF_NN1_));
logmap(ID($_DFF_NP0_));
logmap(ID($_DFF_NP1_));
logmap(ID($_DFF_PN0_));
logmap(ID($_DFF_PN1_));
logmap(ID($_DFF_PP0_));
logmap(ID($_DFF_PP1_));
logmap(TW($_DFFE_NN_));
logmap(TW($_DFFE_NP_));
logmap(TW($_DFFE_PN_));
logmap(TW($_DFFE_PP_));
logmap(ID($_DFFE_NN_));
logmap(ID($_DFFE_NP_));
logmap(ID($_DFFE_PN_));
logmap(ID($_DFFE_PP_));
logmap(TW($_DFFSR_NNN_));
logmap(TW($_DFFSR_NNP_));
logmap(TW($_DFFSR_NPN_));
logmap(TW($_DFFSR_NPP_));
logmap(TW($_DFFSR_PNN_));
logmap(TW($_DFFSR_PNP_));
logmap(TW($_DFFSR_PPN_));
logmap(TW($_DFFSR_PPP_));
logmap(ID($_DFFSR_NNN_));
logmap(ID($_DFFSR_NNP_));
logmap(ID($_DFFSR_NPN_));
logmap(ID($_DFFSR_NPP_));
logmap(ID($_DFFSR_PNN_));
logmap(ID($_DFFSR_PNP_));
logmap(ID($_DFFSR_PPN_));
logmap(ID($_DFFSR_PPP_));
}
static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std::string &data_name, bool &data_not_inverted, std::string &enable_name, bool &enable_not_inverted)
@ -504,14 +504,17 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
for (auto cell : module->cells()) {
if (design->selected(module, cell) && cell_mappings.count(cell->type) > 0)
cell_list.push_back(cell);
if (cell->type == TW($_NOT_))
if (cell->type.in(TwineRef{TW($_NOT_)}))
notmap[sigmap(cell->getPort(TW::A))].insert(cell);
}
auto &twines = module->design->twines;
auto conn_key = [&](char c) { return twines.add(Twine{std::string("\\") + c}); };
std::map<std::string, int> stats;
for (auto cell : cell_list)
{
auto cell_type = cell->type;
IdString cell_type = cell->type;
RTLIL::IdString cell_name(cell->name);
auto cell_connections = cell->connections();
std::string src = cell->get_src_attribute();
@ -519,7 +522,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
module->remove(cell);
cell_mapping &cm = cell_mappings[cell_type];
RTLIL::Cell *new_cell = module->addCell(cell_name, cm.cell_name);
RTLIL::Cell *new_cell = module->addCell(Twine{cell_name.str()}, twines.add(Twine{cm.cell_name.str()}));
new_cell->set_src_attribute(src);
@ -532,10 +535,10 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
for (auto &port : cm.ports) {
RTLIL::SigSpec sig;
if ('A' <= port.second && port.second <= 'Z') {
sig = cell_connections[std::string("\\") + port.second];
sig = cell_connections[conn_key(port.second)];
} else
if (port.second == 'q') {
RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
RTLIL::SigSpec old_sig = cell_connections[conn_key(char(port.second - ('a' - 'A')))];
sig = module->addWire(NEW_TWINE, GetSize(old_sig));
if (has_q && has_qn) {
for (auto &it : notmap[sigmap(old_sig)]) {
@ -547,7 +550,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
}
} else
if ('a' <= port.second && port.second <= 'z') {
sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
sig = cell_connections[conn_key(char(port.second - ('a' - 'A')))];
sig = module->NotGate(NEW_TWINE, sig);
} else
if (port.second == '0' || port.second == '1') {
@ -557,10 +560,10 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
sig = module->addWire(NEW_TWINE);
} else
log_abort();
new_cell->setPort("\\" + port.first, sig);
new_cell->setPort(twines.add(Twine{"\\" + port.first}), sig);
}
stats[stringf("%s cells to %s cells", cell_type, new_cell->type)]++;
stats[stringf("%s cells to %s cells", cell_type.c_str(), new_cell->type.unescape())]++;
}
for (auto &stat: stats)
@ -660,31 +663,31 @@ struct DfflibmapPass : public Pass {
delete f;
}
find_cell(merged.cells, TW($_DFF_N_), false, false, false, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_P_), true, false, false, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_N_), false, false, false, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_P_), true, false, false, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_NN0_), false, true, false, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_NN1_), false, true, false, true, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_NP0_), false, true, true, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_NP1_), false, true, true, true, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_PN0_), true, true, false, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_PN1_), true, true, false, true, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_PP0_), true, true, true, false, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFF_PP1_), true, true, true, true, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_NN0_), false, true, false, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_NN1_), false, true, false, true, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_NP0_), false, true, true, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_NP1_), false, true, true, true, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_PN0_), true, true, false, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_PN1_), true, true, false, true, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_PP0_), true, true, true, false, false, false, dont_use_cells);
find_cell(merged.cells, ID($_DFF_PP1_), true, true, true, true, false, false, dont_use_cells);
find_cell(merged.cells, TW($_DFFE_NN_), false, false, false, false, true, false, dont_use_cells);
find_cell(merged.cells, TW($_DFFE_NP_), false, false, false, false, true, true, dont_use_cells);
find_cell(merged.cells, TW($_DFFE_PN_), true, false, false, false, true, false, dont_use_cells);
find_cell(merged.cells, TW($_DFFE_PP_), true, false, false, false, true, true, dont_use_cells);
find_cell(merged.cells, ID($_DFFE_NN_), false, false, false, false, true, false, dont_use_cells);
find_cell(merged.cells, ID($_DFFE_NP_), false, false, false, false, true, true, dont_use_cells);
find_cell(merged.cells, ID($_DFFE_PN_), true, false, false, false, true, false, dont_use_cells);
find_cell(merged.cells, ID($_DFFE_PP_), true, false, false, false, true, true, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_NNN_), false, false, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_NNP_), false, false, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_NPN_), false, true, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_NPP_), false, true, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_PNN_), true, false, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_PNP_), true, false, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_PPN_), true, true, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, TW($_DFFSR_PPP_), true, true, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_NNN_), false, false, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_NNP_), false, false, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_NPN_), false, true, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_NPP_), false, true, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_PNN_), true, false, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_PNP_), true, false, true, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_PPN_), true, true, false, false, false, dont_use_cells);
find_cell_sr(merged.cells, ID($_DFFSR_PPP_), true, true, true, false, false, dont_use_cells);
log(" final dff cell mappings:\n");
logmap_all();

View file

@ -86,18 +86,18 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_b = cell->getPort(TW::B);
RTLIL::SigSpec sig_y = cell->getPort(TW::Y);
if (cell->type != TW($bweqx)) {
if (!cell->type.in(TwineRef{TW($bweqx)})) {
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool());
}
IdString gate_type;
if (cell->type == TW($and)) gate_type = TW($_AND_);
if (cell->type == TW($or)) gate_type = TW($_OR_);
if (cell->type == TW($xor)) gate_type = TW($_XOR_);
if (cell->type == TW($xnor)) gate_type = TW($_XNOR_);
if (cell->type == TW($bweqx)) gate_type = TW($_XNOR_);
log_assert(!gate_type.empty());
TwineRef gate_type;
if (cell->type.in(TwineRef{TW($and)})) gate_type = TwineRef{TW($_AND_)};
if (cell->type.in(TwineRef{TW($or)})) gate_type = TwineRef{TW($_OR_)};
if (cell->type.in(TwineRef{TW($xor)})) gate_type = TwineRef{TW($_XOR_)};
if (cell->type.in(TwineRef{TW($xnor)})) gate_type = TwineRef{TW($_XNOR_)};
if (cell->type.in(TwineRef{TW($bweqx)})) gate_type = TwineRef{TW($_XNOR_)};
log_assert(gate_type != TwineRef{});
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_TWINE, gate_type);
@ -117,11 +117,11 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
return;
if (sig_a.size() == 0) {
if (cell->type == TW($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == TW($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == TW($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == TW($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == TW($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type.in(TwineRef{TW($reduce_and)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type.in(TwineRef{TW($reduce_or)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type.in(TwineRef{TW($reduce_xor)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type.in(TwineRef{TW($reduce_xnor)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type.in(TwineRef{TW($reduce_bool)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
return;
}
@ -130,13 +130,13 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
sig_y = sig_y.extract(0, 1);
}
IdString gate_type;
if (cell->type == TW($reduce_and)) gate_type = TW($_AND_);
if (cell->type == TW($reduce_or)) gate_type = TW($_OR_);
if (cell->type == TW($reduce_xor)) gate_type = TW($_XOR_);
if (cell->type == TW($reduce_xnor)) gate_type = TW($_XOR_);
if (cell->type == TW($reduce_bool)) gate_type = TW($_OR_);
log_assert(!gate_type.empty());
TwineRef gate_type;
if (cell->type.in(TwineRef{TW($reduce_and)})) gate_type = TwineRef{TW($_AND_)};
if (cell->type.in(TwineRef{TW($reduce_or)})) gate_type = TwineRef{TW($_OR_)};
if (cell->type.in(TwineRef{TW($reduce_xor)})) gate_type = TwineRef{TW($_XOR_)};
if (cell->type.in(TwineRef{TW($reduce_xnor)})) gate_type = TwineRef{TW($_XOR_)};
if (cell->type.in(TwineRef{TW($reduce_bool)})) gate_type = TwineRef{TW($_OR_)};
log_assert(gate_type != TwineRef{});
RTLIL::Cell *last_output_cell = NULL;
@ -162,7 +162,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
sig_a = sig_t;
}
if (cell->type == TW($reduce_xnor)) {
if (cell->type.in(TwineRef{TW($reduce_xnor)})) {
RTLIL::SigSpec sig_t = module->addWire(NEW_TWINE);
RTLIL::Cell *gate = module->addCell(NEW_TWINE, TW($_NOT_));
transfer_src(gate, cell);
@ -245,10 +245,10 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
sig_y = sig_y.extract(0, 1);
}
IdString gate_type;
if (cell->type == TW($logic_and)) gate_type = TW($_AND_);
if (cell->type == TW($logic_or)) gate_type = TW($_OR_);
log_assert(!gate_type.empty());
TwineRef gate_type;
if (cell->type.in(TwineRef{TW($logic_and)})) gate_type = TwineRef{TW($_AND_)};
if (cell->type.in(TwineRef{TW($logic_or)})) gate_type = TwineRef{TW($_OR_)};
log_assert(gate_type != TwineRef{});
RTLIL::Cell *gate = module->addCell(NEW_TWINE, gate_type);
transfer_src(gate, cell);
@ -263,7 +263,7 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_b = cell->getPort(TW::B);
RTLIL::SigSpec sig_y = cell->getPort(TW::Y);
bool is_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
bool is_ne = cell->type.in(TW($ne), TW($nex));
bool is_ne = cell->type.in(TwineRef{TW($ne)}, TwineRef{TW($nex)});
RTLIL::SigSpec xor_out = module->addWire(NEW_TWINE, max(GetSize(sig_a), GetSize(sig_b)));
RTLIL::Cell *xor_cell = module->addXor(NEW_TWINE, sig_a, sig_b, xor_out, is_signed);
@ -479,51 +479,51 @@ void simplemap_pmux(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers)
{
mappers[TW($not)] = simplemap_not;
mappers[TW($pos)] = simplemap_pos;
mappers[TW($buf)] = simplemap_buf;
mappers[TW($and)] = simplemap_bitop;
mappers[TW($or)] = simplemap_bitop;
mappers[TW($xor)] = simplemap_bitop;
mappers[TW($xnor)] = simplemap_bitop;
mappers[TW($bweqx)] = simplemap_bitop;
mappers[TW($reduce_and)] = simplemap_reduce;
mappers[TW($reduce_or)] = simplemap_reduce;
mappers[TW($reduce_xor)] = simplemap_reduce;
mappers[TW($reduce_xnor)] = simplemap_reduce;
mappers[TW($reduce_bool)] = simplemap_reduce;
mappers[TW($logic_not)] = simplemap_lognot;
mappers[TW($logic_and)] = simplemap_logbin;
mappers[TW($logic_or)] = simplemap_logbin;
mappers[TW($eq)] = simplemap_eqne;
mappers[TW($eqx)] = simplemap_eqne;
mappers[TW($ne)] = simplemap_eqne;
mappers[TW($nex)] = simplemap_eqne;
mappers[TW($mux)] = simplemap_mux;
mappers[TW($pmux)] = simplemap_pmux;
mappers[TW($bwmux)] = simplemap_bwmux;
mappers[TW($tribuf)] = simplemap_tribuf;
mappers[TW($bmux)] = simplemap_bmux;
mappers[TW($lut)] = simplemap_lut;
mappers[TW($sop)] = simplemap_sop;
mappers[TW($slice)] = simplemap_slice;
mappers[TW($concat)] = simplemap_concat;
mappers[TW($sr)] = simplemap_ff;
mappers[TW($ff)] = simplemap_ff;
mappers[TW($dff)] = simplemap_ff;
mappers[TW($dffe)] = simplemap_ff;
mappers[TW($dffsr)] = simplemap_ff;
mappers[TW($dffsre)] = simplemap_ff;
mappers[TW($adff)] = simplemap_ff;
mappers[TW($sdff)] = simplemap_ff;
mappers[TW($adffe)] = simplemap_ff;
mappers[TW($sdffe)] = simplemap_ff;
mappers[TW($sdffce)] = simplemap_ff;
mappers[TW($aldff)] = simplemap_ff;
mappers[TW($aldffe)] = simplemap_ff;
mappers[TW($dlatch)] = simplemap_ff;
mappers[TW($adlatch)] = simplemap_ff;
mappers[TW($dlatchsr)] = simplemap_ff;
mappers[ID($not)] = simplemap_not;
mappers[ID($pos)] = simplemap_pos;
mappers[ID($buf)] = simplemap_buf;
mappers[ID($and)] = simplemap_bitop;
mappers[ID($or)] = simplemap_bitop;
mappers[ID($xor)] = simplemap_bitop;
mappers[ID($xnor)] = simplemap_bitop;
mappers[ID($bweqx)] = simplemap_bitop;
mappers[ID($reduce_and)] = simplemap_reduce;
mappers[ID($reduce_or)] = simplemap_reduce;
mappers[ID($reduce_xor)] = simplemap_reduce;
mappers[ID($reduce_xnor)] = simplemap_reduce;
mappers[ID($reduce_bool)] = simplemap_reduce;
mappers[ID($logic_not)] = simplemap_lognot;
mappers[ID($logic_and)] = simplemap_logbin;
mappers[ID($logic_or)] = simplemap_logbin;
mappers[ID($eq)] = simplemap_eqne;
mappers[ID($eqx)] = simplemap_eqne;
mappers[ID($ne)] = simplemap_eqne;
mappers[ID($nex)] = simplemap_eqne;
mappers[ID($mux)] = simplemap_mux;
mappers[ID($pmux)] = simplemap_pmux;
mappers[ID($bwmux)] = simplemap_bwmux;
mappers[ID($tribuf)] = simplemap_tribuf;
mappers[ID($bmux)] = simplemap_bmux;
mappers[ID($lut)] = simplemap_lut;
mappers[ID($sop)] = simplemap_sop;
mappers[ID($slice)] = simplemap_slice;
mappers[ID($concat)] = simplemap_concat;
mappers[ID($sr)] = simplemap_ff;
mappers[ID($ff)] = simplemap_ff;
mappers[ID($dff)] = simplemap_ff;
mappers[ID($dffe)] = simplemap_ff;
mappers[ID($dffsr)] = simplemap_ff;
mappers[ID($dffsre)] = simplemap_ff;
mappers[ID($adff)] = simplemap_ff;
mappers[ID($sdff)] = simplemap_ff;
mappers[ID($adffe)] = simplemap_ff;
mappers[ID($sdffe)] = simplemap_ff;
mappers[ID($sdffce)] = simplemap_ff;
mappers[ID($aldff)] = simplemap_ff;
mappers[ID($aldffe)] = simplemap_ff;
mappers[ID($dlatch)] = simplemap_ff;
mappers[ID($adlatch)] = simplemap_ff;
mappers[ID($dlatchsr)] = simplemap_ff;
}
void simplemap(RTLIL::Module *module, RTLIL::Cell *cell)

View file

@ -54,8 +54,9 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
if (chunk.wire != nullptr) {
IdString wire_name = chunk.wire->name;
apply_prefix(prefix, wire_name);
log_assert(module->wire(wire_name) != nullptr);
chunk.wire = module->wire(wire_name);
TwineRef wire_ref = module->design->twines.add(Twine{wire_name.str()});
log_assert(module->wire(wire_ref) != nullptr);
chunk.wire = module->wire(wire_ref);
}
sig = chunks;
}
@ -86,28 +87,29 @@ struct TechmapWorker
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
{
std::string constmap_info;
dict<RTLIL::SigBit, std::pair<IdString, int>> connbits_map;
auto &twines = cell->module->design->twines;
dict<RTLIL::SigBit, std::pair<TwineRef, int>> connbits_map;
for (auto &conn : cell->connections())
for (int i = 0; i < GetSize(conn.second); i++) {
RTLIL::SigBit bit = sigmap(conn.second[i]);
if (bit.wire == nullptr) {
if (verbose)
log(" Constant input on bit %d of port %s: %s\n", i, design->twines.unescaped_str(conn.first), log_signal(bit));
constmap_info += stringf("|%s %d %d", design->twines.unescaped_str(conn.first), i, bit.data);
log(" Constant input on bit %d of port %s: %s\n", i, twines.unescaped_str(conn.first).data(), log_signal(bit));
constmap_info += stringf("|%s %d %d", twines.unescaped_str(conn.first).data(), i, bit.data);
} else if (connbits_map.count(bit)) {
if (verbose)
log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, design->twines.unescaped_str(conn.first),
connbits_map.at(bit).second, design->twines.unescaped_str(connbits_map.at(bit).first));
constmap_info += stringf("|%s %d %s %d", design->twines.unescaped_str(conn.first), i,
connbits_map.at(bit).first.unescape(), connbits_map.at(bit).second);
log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, twines.unescaped_str(conn.first).data(),
connbits_map.at(bit).second, twines.unescaped_str(connbits_map.at(bit).first).data());
constmap_info += stringf("|%s %d %s %d", twines.unescaped_str(conn.first).data(), i,
twines.unescaped_str(connbits_map.at(bit).first).data(), connbits_map.at(bit).second);
} else {
connbits_map.emplace(bit, std::make_pair(conn.first, i));
constmap_info += stringf("|%s %d", design->twines.unescaped_str(conn.first), i);
constmap_info += stringf("|%s %d", twines.unescaped_str(conn.first).data(), i);
}
}
return stringf("$paramod$constmap:%s%s", sha1(constmap_info), tpl->name);
return stringf("$paramod$constmap:%s%s", sha1(constmap_info), log_id(tpl->name));
}
TechmapWires techmap_find_special_wires(RTLIL::Module *module)
@ -146,7 +148,7 @@ struct TechmapWorker
if (tpl->processes.size() != 0) {
log("Technology map yielded processes:");
for (auto &it : tpl->processes)
log(" design->twines.unescaped_str(%s",it.first));
log(" %s", tpl->design->twines.unescaped_str(it.first).data());
log("\n");
if (autoproc_mode) {
Pass::call_on_module(tpl->design, tpl, "proc");
@ -166,36 +168,38 @@ struct TechmapWorker
orig_cell_name = cell->name.str();
for (auto tpl_cell : tpl->cells())
if (tpl_cell->name.ends_with("_TECHMAP_REPLACE_")) {
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
module->rename(cell, module->design->twines.add(Twine{stringf("$techmap%d", autoidx++) + cell->name.str()}));
break;
}
dict<IdString, IdString> memory_renames;
for (auto &it : tpl->memories) {
IdString m_name = it.first;
apply_prefix(cell->name, m_name);
RTLIL::Memory *m = module->addMemory(m_name, it.second);
IdString old_m_id(std::string(tpl->design->twines.str(it.first)));
IdString m_name_id = old_m_id;
apply_prefix(cell->name, m_name_id);
TwineRef m_ref = module->design->twines.add(Twine{m_name_id.str()});
RTLIL::Memory *m = module->addMemory(m_ref, it.second);
if (m->has_attribute(ID::src))
design->merge_src(m, src_cell);
memory_renames[it.first] = m->name;
memory_renames[old_m_id] = m_name_id;
design->select(module, m);
}
dict<IdString, IdString> positional_ports;
dict<Wire*, IdString> temp_renamed_wires;
dict<TwineRef, TwineRef> positional_ports;
dict<Wire*, TwineRef> temp_renamed_wires;
pool<SigBit> autopurge_tpl_bits;
for (auto tpl_w : tpl->wires())
{
if (tpl_w->port_id > 0)
{
IdString posportname = stringf("$%d", tpl_w->port_id);
positional_ports.emplace(posportname, tpl_w->name);
TwineRef posportref = module->design->twines.add(Twine{stringf("$%d", tpl_w->port_id)});
positional_ports.emplace(posportref, tpl_w->name.ref());
if (tpl_w->get_bool_attribute(ID::techmap_autopurge) &&
(!cell->hasPort(tpl_w->name) || !GetSize(cell->getPort(tpl_w->name))) &&
(!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname))))
(!cell->hasPort(tpl_w->name.ref()) || !GetSize(cell->getPort(tpl_w->name.ref()))) &&
(!cell->hasPort(posportref) || !GetSize(cell->getPort(posportref))))
{
if (sigmaps.count(tpl) == 0)
sigmaps[tpl].set(tpl);
@ -207,14 +211,15 @@ struct TechmapWorker
}
IdString w_name = tpl_w->name;
apply_prefix(cell->name, w_name);
RTLIL::Wire *w = module->wire(w_name);
TwineRef w_ref = module->design->twines.add(Twine{w_name.str()});
RTLIL::Wire *w = module->wire(w_ref);
if (w != nullptr) {
temp_renamed_wires[w] = w->name;
module->rename(w, NEW_ID);
temp_renamed_wires[w] = w->name.ref();
module->rename(w, module->design->twines.add(NEW_TWINE));
w = nullptr;
}
if (w == nullptr) {
w = module->addWire(w_name, tpl_w);
w = module->addWire(Twine{w_name.str()}, tpl_w);
w->port_input = false;
w->port_output = false;
w->port_id = 0;
@ -227,8 +232,7 @@ struct TechmapWorker
design->select(module, w);
if (const char *p = strstr(tpl_w->name.c_str(), "_TECHMAP_REPLACE_.")) {
IdString replace_name = stringf("%s%s", orig_cell_name, p + strlen("_TECHMAP_REPLACE_"));
Wire *replace_w = module->addWire(replace_name, tpl_w);
Wire *replace_w = module->addWire(Twine{std::string(orig_cell_name) + (p + strlen("_TECHMAP_REPLACE_"))}, tpl_w);
module->connect(replace_w, w);
}
}
@ -251,8 +255,8 @@ struct TechmapWorker
if (positional_ports.count(portname) > 0)
portname = positional_ports.at(portname);
if (tpl->wire(portname) == nullptr || tpl->wire(portname)->port_id == 0) {
if (portname.begins_with("$"))
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname, cell->name, tpl->name);
if (design->twines.str(portname).starts_with("$"))
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", design->twines.unescaped_str(portname).data(), log_id(cell->name), log_id(tpl->name));
continue;
}
@ -336,15 +340,15 @@ struct TechmapWorker
else
apply_prefix(cell->name, c_name);
RTLIL::Cell *c = module->addCell(c_name, tpl_cell);
RTLIL::Cell *c = module->addCell(module->design->twines.add(Twine{c_name.str()}), tpl_cell);
design->select(module, c);
if (c->type == ID::_TECHMAP_PLACEHOLDER_ && tpl_cell->has_attribute(ID::techmap_chtype)) {
c->type = RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype));
if (c->type.in(TwineRef{TW(_TECHMAP_PLACEHOLDER_)}) && tpl_cell->has_attribute(ID::techmap_chtype)) {
c->type_impl = module->design->twines.add(Twine{RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype))});
c->attributes.erase(ID::techmap_chtype);
}
vector<IdString> autopurge_ports;
vector<TwineRef> autopurge_ports;
for (auto &conn : c->connections())
{
@ -406,8 +410,8 @@ struct TechmapWorker
for (auto &it : temp_renamed_wires)
{
Wire *w = it.first;
IdString name = it.second;
IdString altname = module->uniquify(name);
TwineRef name = it.second;
TwineRef altname = module->uniquify(name);
Wire *other_w = module->wire(name);
module->rename(other_w, altname);
module->rename(w, name);
@ -476,12 +480,12 @@ struct TechmapWorker
for (auto cell : cells.sorted)
{
log_assert(handled_cells.count(cell) == 0);
log_assert(cell == module->cell(cell->name));
log_assert(cell == module->cell(cell->name.ref()));
bool mapped_cell = false;
for (auto &tpl_name : celltypeMap.at(cell->type))
{
IdString derived_name = tpl_name;
TwineRef derived_name = map->twines.add(Twine{tpl_name.str()});
RTLIL::Module *tpl = map->module(tpl_name);
dict<IdString, RTLIL::Const> parameters(cell->parameters);
@ -506,18 +510,18 @@ struct TechmapWorker
std::string m_name = stringf("$extern:%s:%s", extmapper_name, cell->type.unescaped());
for (auto &c : cell->parameters)
m_name += stringf(":%s=%s", design->twines.unescaped_str(c.first), log_signal(c.second));
m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
if (extmapper_name == "wrap")
m_name += ":" + sha1(tpl->attributes.at(ID::techmap_wrap).decode_string());
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
RTLIL::Module *extmapper_module = extmapper_design->module(IdString(m_name));
if (extmapper_module == nullptr)
{
extmapper_module = extmapper_design->addModule(m_name);
RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell);
extmapper_module = extmapper_design->addModule(extmapper_design->twines.add(Twine{m_name}));
RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type.ref(), cell);
// addCell(name, cell) already migrated src across
// designs via copy_src_into — no need for an
// explicit set_src_attribute round-trip here.
@ -525,7 +529,7 @@ struct TechmapWorker
int port_counter = 1;
for (auto &c : extmapper_cell->connections_) {
RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
if (w->name.in(ID::Y, ID::Q))
if (w->name.in(TwineRef{TW(Y)}, TwineRef{TW(Q)}))
w->port_output = true;
else
w->port_input = true;
@ -537,24 +541,24 @@ struct TechmapWorker
extmapper_module->check();
if (extmapper_name == "simplemap") {
log("Creating %s with simplemap.\n", extmapper_module);
log("Creating %s with simplemap.\n", log_id(extmapper_module->name));
if (simplemap_mappers.count(extmapper_cell->type) == 0)
log_error("No simplemap mapper for cell type %s found!\n", design->twines.unescaped_str(extmapper_cell->type));
log_error("No simplemap mapper for cell type %s found!\n", extmapper_cell->type.unescape());
simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell);
extmapper_module->remove(extmapper_cell);
}
if (extmapper_name == "maccmap") {
log("Creating %s with maccmap.\n", extmapper_module);
if (!extmapper_cell->type.in(TW($macc), TW($macc_v2)))
log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", design->twines.unescaped_str(extmapper_cell->type));
log("Creating %s with maccmap.\n", log_id(extmapper_module->name));
if (!extmapper_cell->type.in(TwineRef{TW($macc)}, TwineRef{TW($macc_v2)}))
log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", extmapper_cell->type.unescape());
maccmap(extmapper_module, extmapper_cell);
extmapper_module->remove(extmapper_cell);
}
if (extmapper_name == "wrap") {
std::string cmd_string = tpl->attributes.at(ID::techmap_wrap).decode_string();
log("Running \"%s\" on wrapper %s.\n", cmd_string, extmapper_module);
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module->name));
mkdebug.on();
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
extmapper_design->sigNormalize(false);
@ -608,13 +612,14 @@ struct TechmapWorker
}
for (auto &conn : cell->connections()) {
if (conn.first.begins_with("$"))
if (design->twines.str(conn.first).starts_with("$"))
continue;
if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0)
continue;
if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0)
IdString conn_id(std::string(design->twines.str(conn.first)));
if (!conn.second.is_fully_const() || parameters.count(conn_id) > 0 || tpl->avail_parameters.count(conn_id) == 0)
goto next_tpl;
parameters[conn.first] = conn.second.as_const();
parameters[conn_id] = conn.second.as_const();
}
if (0) {
@ -731,7 +736,7 @@ struct TechmapWorker
RTLIL::SigSpec value = elem.value;
if (value.is_fully_const() && value.as_bool()) {
log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n",
derived_name.c_str(), design->twines.unescaped_str(elem.wire->name), log_signal(value));
design->twines.unescaped_str(derived_name).data(), design->twines.unescaped_str(elem.wire->name.ref()).data(), log_signal(value));
techmap_do_cache[tpl] = false;
}
}
@ -748,7 +753,7 @@ struct TechmapWorker
auto &data = it.second.front();
if (!data.value.is_fully_const())
log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(data.wire->name), log_signal(data.value));
log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(data.wire->name.ref()).data(), log_signal(data.value));
techmap_wire_names.erase(it.first);
@ -765,10 +770,10 @@ struct TechmapWorker
log("Analyzing pattern of constant bits for this cell:\n");
IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true);
log("Creating constmapped module `%s'.\n", design->twines.unescaped_str(new_tpl_name));
log("Creating constmapped module `%s'.\n", log_id(new_tpl_name));
log_assert(map->module(new_tpl_name) == nullptr);
RTLIL::Module *new_tpl = map->addModule(new_tpl_name);
RTLIL::Module *new_tpl = map->addModule(map->twines.add(Twine{new_tpl_name.str()}));
tpl->cloneInto(new_tpl);
techmap_do_cache.erase(tpl);
@ -785,9 +790,9 @@ struct TechmapWorker
continue;
IdString port_name = wire->name;
tpl->rename(wire, NEW_ID);
tpl->rename(wire, tpl->design->twines.add(NEW_TWINE));
RTLIL::Wire *new_wire = tpl->addWire(port_name, wire);
RTLIL::Wire *new_wire = tpl->addWire(Twine{port_name.str()}, wire);
wire->port_input = false;
wire->port_id = 0;
@ -861,9 +866,9 @@ struct TechmapWorker
log_assert(!strncmp(q, "_TECHMAP_DO_", 12));
std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12);
while (tpl->wire(new_name) != nullptr)
while (tpl->wire(tpl->design->twines.add(Twine{new_name})) != nullptr)
new_name += "_";
tpl->rename(data.wire->name, new_name);
tpl->rename(data.wire->name.ref(), tpl->design->twines.add(Twine{new_name}));
keep_running = true;
break;
@ -873,16 +878,16 @@ struct TechmapWorker
TechmapWires twd = techmap_find_special_wires(tpl);
for (auto &it : twd) {
if (!it.first.ends_with("_TECHMAP_FAIL_") && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.contains("_TECHMAP_DO_") && !it.first.contains("_TECHMAP_DONE_"))
log_error("Techmap yielded unknown config wire %s.\n", design->twines.unescaped_str(it.first));
log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first));
if (techmap_do_cache[tpl])
for (auto &it2 : it.second)
if (!it2.value.is_fully_const())
log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(it2.wire->name), log_signal(it2.value));
log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(it2.wire->name), log_signal(it2.value));
techmap_wire_names.erase(it.first);
}
for (auto &it : techmap_wire_names)
log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", design->twines.unescaped_str(it));
log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", log_id(it));
if (recursive_mode) {
if (log_continue) {
@ -909,7 +914,8 @@ struct TechmapWorker
for (auto &it2 : it.second) {
auto val = it2.value.as_const();
auto wirename = RTLIL::escape_id(it.first.substr(21, it.first.size() - 21 - 1));
auto it = cell->connections().find(wirename);
TwineRef wirename_ref = cell->module->design->twines.add(Twine{wirename});
auto it = cell->connections().find(wirename_ref);
if (it != cell->connections().end()) {
auto sig = sigmap(it->second);
for (int i = 0; i < sig.size(); i++)
@ -922,28 +928,28 @@ struct TechmapWorker
if (extern_mode && !in_recursion)
{
std::string m_name = stringf("$extern:%s", tpl);
std::string m_name = stringf("$extern:%s", log_id(tpl->name));
if (!design->module(m_name))
if (!design->module(RTLIL::IdString(m_name)))
{
RTLIL::Module *m = design->addModule(m_name);
RTLIL::Module *m = design->addModule(design->twines.add(Twine{m_name}));
tpl->cloneInto(m);
module_queue.insert(m);
}
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name);
cell->type_impl = cell->module->design->twines.add(Twine{m_name.str()});
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module->name), log_id(cell->name), m_name.c_str());
cell->type_impl = cell->module->design->twines.add(Twine{m_name});
cell->parameters.clear();
}
else
{
auto msg = stringf("Using template %s for cells of type %s.", tpl, cell->type.unescaped());
auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl->name), cell->type.unescape());
if (!log_msg_cache.count(msg)) {
log_msg_cache.insert(msg);
log("%s\n", msg);
}
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix, module, cell, cell->type.unescaped(), tpl);
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module->name), log_id(cell->name), cell->type.unescape(), log_id(tpl->name));
techmap_module_worker(design, module, cell, tpl);
cell = nullptr;
}
@ -1224,7 +1230,7 @@ struct TechmapPass : public Pass {
log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1);
}
for (auto mod : saved_designs.at(fn.substr(1))->modules())
if (!map->module(mod->name))
if (!map->module(IdString(mod->name)))
mod->clone(map);
} else {
Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend));
@ -1274,9 +1280,9 @@ struct TechmapPass : public Pass {
for (auto &i : celltypeMap) {
i.second.sort(RTLIL::sort_by_id_str());
std::string maps = "";
for (auto &map : i.second)
maps += stringf(" %s", design->twines.unescaped_str(map));
log_debug(" %s:%s\n", design->twines.unescaped_str(i.first), maps);
for (auto &m : i.second)
maps += stringf(" %s", log_id(m));
log_debug(" %s:%s\n", log_id(i.first), maps.c_str());
}
log_debug("\n");