274 std::string mapmsg_prefix = in_recursion ?
"Recursively mapping" :
"Mapping";
279 bool log_continue =
false;
285 std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
286 std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
288 for (
auto cell : module->
cells())
290 if (!design->
selected(module, cell) || handled_cells.count(cell) > 0)
293 std::string cell_type = cell->type.str();
294 if (in_recursion && cell_type.substr(0, 2) ==
"\\$")
295 cell_type = cell_type.substr(1);
297 if (celltypeMap.count(cell_type) == 0) {
299 log_error(
"(ASSERT MODE) No matching template cell for type %s found.\n",
log_id(cell_type));
303 for (
auto &conn : cell->connections())
311 for (
auto &tpl_name : celltypeMap.at(cell_type)) {
315 cell_to_inbit[cell].insert(sig.
begin(), sig.
end());
317 for (
auto &bit : sig)
318 outbit_to_cell[bit].insert(cell);
325 for (
auto &it_right : cell_to_inbit)
326 for (
auto &it_sigbit : it_right.second)
327 for (
auto &it_left : outbit_to_cell[it_sigbit])
328 cells.
edge(it_left, it_right.first);
332 for (
auto cell : cells.
sorted)
336 bool mapped_cell =
false;
338 std::string cell_type = cell->type.str();
339 if (in_recursion && cell_type.substr(0, 2) ==
"\\$")
340 cell_type = cell_type.substr(1);
342 for (
auto &tpl_name : celltypeMap.at(cell_type))
346 std::map<RTLIL::IdString, RTLIL::Const> parameters = cell->parameters;
348 if (tpl->get_bool_attribute(
"\\blackbox"))
353 std::string extmapper_name;
355 if (tpl->get_bool_attribute(
"\\techmap_simplemap"))
356 extmapper_name =
"simplemap";
358 if (tpl->get_bool_attribute(
"\\techmap_maccmap"))
359 extmapper_name =
"maccmap";
361 if (tpl->attributes.count(
"\\techmap_wrap"))
362 extmapper_name =
"wrap";
364 if (!extmapper_name.empty())
366 cell->type = cell_type;
368 if ((
extern_mode && !in_recursion) || extmapper_name ==
"wrap")
370 std::string m_name =
stringf(
"$extern:%s:%s", extmapper_name.c_str(),
log_id(cell->type));
372 for (
auto &c : cell->parameters)
375 if (extmapper_name ==
"wrap")
376 m_name +=
":" +
sha1(tpl->attributes.at(
"\\techmap_wrap").decode_string());
379 RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
381 if (extmapper_module ==
nullptr)
383 extmapper_module = extmapper_design->addModule(m_name);
389 if (w->
name ==
"\\Y" || w->
name ==
"\\Q")
398 extmapper_module->
check();
400 if (extmapper_name ==
"simplemap") {
401 log(
"Creating %s with simplemap.\n",
log_id(extmapper_module));
405 extmapper_module->
remove(extmapper_cell);
408 if (extmapper_name ==
"maccmap") {
409 log(
"Creating %s with maccmap.\n",
log_id(extmapper_module));
410 if (extmapper_cell->
type !=
"$macc")
411 log_error(
"The maccmap mapper can only map $macc (not %s) cells!\n",
log_id(extmapper_cell->
type));
412 maccmap(extmapper_module, extmapper_cell);
413 extmapper_module->
remove(extmapper_cell);
416 if (extmapper_name ==
"wrap") {
417 std::string cmd_string = tpl->attributes.at(
"\\techmap_wrap").decode_string();
418 log(
"Running \"%s\" on wrapper %s.\n", cmd_string.c_str(),
log_id(extmapper_module));
424 cell->type = extmapper_module->
name;
425 cell->parameters.
clear();
428 tpl = extmapper_module;
429 goto use_wrapper_tpl;
436 log(
"%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(),
log_id(module),
log_id(cell),
log_id(cell->type), extmapper_name.c_str());
438 if (extmapper_name ==
"simplemap") {
444 if (extmapper_name ==
"maccmap") {
445 if (cell->type !=
"$macc")
446 log_error(
"The maccmap mapper can only map $macc (not %s) cells!\n",
log_id(cell->type));
454 did_something =
true;
459 for (
auto conn : cell->connections()) {
460 if (conn.first.substr(0, 1) ==
"$")
462 if (tpl->
wires_.count(conn.first) > 0 && tpl->
wires_.at(conn.first)->port_id > 0)
464 if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->
avail_parameters.count(conn.first) == 0)
466 parameters[conn.first] = conn.second.as_const();
477 for (
auto conn : cell->connections()) {
479 std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
485 std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
487 if (bit.wire !=
NULL)
493 int unique_bit_id_counter = 0;
494 std::map<RTLIL::SigBit, int> unique_bit_id;
500 for (
auto conn : cell->connections())
502 for (
auto &bit : sigmap(conn.second).to_sigbit_vector())
503 if (unique_bit_id.count(bit) == 0)
504 unique_bit_id[bit] = unique_bit_id_counter++;
508 for (
int i = 0; i < 32; i++)
509 if (((unique_bit_id_counter-1) & (1 << i)) != 0)
512 parameters[
"\\_TECHMAP_BITS_CONNMAP_"] = bits;
514 for (
auto conn : cell->connections())
517 for (
auto &bit : sigmap(conn.second).to_sigbit_vector()) {
519 value.
bits.insert(value.
bits.end(), chunk.bits.begin(), chunk.bits.end());
529 std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>> key(tpl_name, parameters);
533 if (cell->parameters.size() != 0) {
534 derived_name = tpl->
derive(map, parameters);
535 tpl = map->
module(derived_name);
546 if (constmapped_tpl !=
nullptr)
547 tpl = constmapped_tpl;
552 bool keep_running =
true;
555 std::set<std::string> techmap_wire_names;
560 keep_running =
false;
563 techmap_wire_names.insert(it.first);
565 for (
auto &it : twd[
"_TECHMAP_FAIL_"]) {
568 log(
"Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n",
579 if (it.first.substr(0, 12) !=
"_TECHMAP_DO_" || it.second.empty())
582 auto &data = it.second.front();
584 if (!data.value.is_fully_const())
587 techmap_wire_names.erase(it.first);
589 const char *p = data.wire->name.c_str();
590 const char *q = strrchr(p+1,
'.');
593 std::string cmd_string = data.value.as_const().decode_string();
595 restart_eval_cmd_string:
596 if (cmd_string.rfind(
"CONSTMAP; ", 0) == 0)
598 cmd_string = cmd_string.substr(strlen(
"CONSTMAP; "));
600 log(
"Analyzing pattern of constant bits for this cell:\n");
602 log(
"Creating constmapped module `%s'.\n",
log_id(new_tpl_name));
612 std::map<RTLIL::SigBit, RTLIL::SigBit> port_new2old_map;
613 std::map<RTLIL::SigBit, RTLIL::SigBit> port_connmap;
614 std::map<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits;
616 for (
auto wire : tpl->wires().to_vector())
618 if (!wire->port_input || wire->port_output)
622 tpl->rename(wire,
NEW_ID);
624 RTLIL::Wire *new_wire = tpl->addWire(port_name, wire);
628 for (
int i = 0; i < wire->width; i++) {
634 for (
auto conn : cell->connections())
635 for (
int i = 0; i <
GetSize(conn.second); i++)
640 if (bit.
wire ==
nullptr)
643 port_connmap.at(oldbit) = bit;
645 else if (cellbits_to_tplbits.count(bit))
648 port_connmap.at(oldbit) = cellbits_to_tplbits[bit];
651 cellbits_to_tplbits[bit] = tplbit;
655 for (
auto &it : port_connmap) {
656 port_conn.first.append_bit(it.first);
657 port_conn.second.append_bit(it.second);
659 tpl->connect(port_conn);
662 goto restart_eval_cmd_string;
665 if (cmd_string.rfind(
"RECURSION; ", 0) == 0)
667 cmd_string = cmd_string.substr(strlen(
"RECURSION; "));
668 while (
techmap_module(map, tpl, map, handled_cells, celltypeMap,
true)) { }
669 goto restart_eval_cmd_string;
675 std::string new_name = data.wire->name.substr(0, q-p) +
"_TECHMAP_DONE_" + data.wire->name.substr(q-p+12);
676 while (tpl->wires_.count(new_name))
678 tpl->rename(data.wire->name, new_name);
686 for (
auto &it : twd) {
687 if (it.first !=
"_TECHMAP_FAIL_" && it.first.substr(0, 12) !=
"_TECHMAP_DO_" && it.first.substr(0, 14) !=
"_TECHMAP_DONE_")
688 log_error(
"Techmap yielded unknown config wire %s.\n", it.first.c_str());
690 for (
auto &it2 : it.second)
691 if (!it2.value.is_fully_const())
693 techmap_wire_names.erase(it.first);
696 for (
auto &it : techmap_wire_names)
702 log_continue =
false;
704 while (
techmap_module(map, tpl, map, handled_cells, celltypeMap,
true)) { }
713 log_continue =
false;
720 if (!design->
module(m_name))
725 for (
auto cell : m->
cells()) {
726 if (cell->type.substr(0, 2) ==
"\\$")
727 cell->type = cell->type.substr(1);
733 log(
"%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(),
log_id(module),
log_id(cell),
log_id(m_name));
735 cell->parameters.clear();
743 did_something =
true;
751 handled_cells.insert(cell);
756 log_continue =
false;
const char * c_str() const
bool selected(T1 *module) const
void cloneInto(RTLIL::Module *new_mod) const
RTLIL::Wire * wire(RTLIL::IdString id)
std::set< RTLIL::Module *, RTLIL::IdString::compare_ptr_by_name< RTLIL::Module > > module_queue
std::string stringf(const char *fmt,...)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void log_header(const char *format,...)
RTLIL::Const as_const() const
std::map< RTLIL::Module *, bool > techmap_do_cache
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
std::map< std::pair< RTLIL::IdString, std::map< RTLIL::IdString, RTLIL::Const > >, RTLIL::Module * > techmap_cache
std::map< RTLIL::IdString, void(*)(RTLIL::Module *, RTLIL::Cell *)> simplemap_mappers
void log_error(const char *format,...)
std::set< RTLIL::IdString > avail_parameters
virtual RTLIL::IdString derive(RTLIL::Design *design, std::map< RTLIL::IdString, RTLIL::Const > parameters)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
std::map< std::string, std::vector< TechmapWireData > > TechmapWires
bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set< RTLIL::Cell * > &handled_cells, const std::map< RTLIL::IdString, std::set< RTLIL::IdString, RTLIL::sort_by_id_str >> &celltypeMap, bool in_recursion)
void edge(T left, T right)
int GetSize(RTLIL::Wire *wire)
RTLIL::SigSpecIterator begin()
#define log_assert(_assert_expr_)
bool is_fully_const() const
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
static const char * id2cstr(const RTLIL::IdString &str)
RTLIL::Module * addModule(RTLIL::IdString name)
RTLIL::Module * module(RTLIL::IdString name)
RTLIL::ObjRange< RTLIL::Cell * > cells()
std::map< RTLIL::IdString, RTLIL::Module * > modules_
RTLIL::Cell * cell(RTLIL::IdString id)
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
void remove(const std::set< RTLIL::Wire * > &wires)
void log(const char *format,...)
std::string sha1(const std::string &string)
std::vector< RTLIL::State > bits
void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap=false)
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
std::pair< SigSpec, SigSpec > SigSig
void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl)
const char * log_id(RTLIL::IdString str)
RTLIL::SigSpecIterator end()
TechmapWires techmap_find_special_wires(RTLIL::Module *module)