258 bool flag_shared =
false;
259 bool flag_evert =
false;
260 bool flag_dff =
false;
261 bool flag_cut =
false;
262 bool flag_evert_dff =
false;
263 std::string sep =
".";
265 log_header(
"Executing EXPOSE pass (exposing internal signals as outputs).\n");
268 for (argidx = 1; argidx <
args.size(); argidx++)
270 if (
args[argidx] ==
"-shared") {
274 if (
args[argidx] ==
"-evert") {
278 if (
args[argidx] ==
"-dff") {
282 if (
args[argidx] ==
"-cut") {
286 if (
args[argidx] ==
"-evert-dff") {
287 flag_evert_dff =
true;
290 if (
args[argidx] ==
"-sep" && argidx+1 <
args.size()) {
291 sep =
args[++argidx];
300 std::map<RTLIL::Module*, std::map<RTLIL::IdString, dff_map_info_t>> dff_dq_maps;
301 std::map<RTLIL::Module*, std::set<RTLIL::IdString>> dff_cells;
306 std::set<RTLIL::IdString> shared_dff_wires;
308 for (
auto &mod_it : design->
modules_)
310 if (!design->
selected(mod_it.second))
318 if (first_module ==
NULL) {
319 for (
auto &it : dff_dq_maps[mod_it.second])
320 shared_dff_wires.insert(it.first);
321 first_module = mod_it.second;
323 std::set<RTLIL::IdString> new_shared_dff_wires;
324 for (
auto &it : shared_dff_wires) {
325 if (!dff_dq_maps[mod_it.second].count(it))
329 new_shared_dff_wires.insert(it);
331 shared_dff_wires.swap(new_shared_dff_wires);
336 for (
auto &map_it : dff_dq_maps)
338 std::map<RTLIL::IdString, dff_map_info_t> new_map;
339 for (
auto &it : map_it.second)
340 if (shared_dff_wires.count(it.first))
341 new_map[it.first] = it.second;
342 map_it.second.swap(new_map);
345 for (
auto &it1 : dff_dq_maps)
346 for (
auto &it2 : it1.second)
347 for (
auto &it3 : it2.second.cells)
348 dff_cells[it1.first].insert(it3);
351 std::set<RTLIL::IdString> shared_wires, shared_cells;
352 std::set<RTLIL::IdString> used_names;
358 for (
auto &mod_it : design->
modules_)
365 std::set<RTLIL::IdString> dff_wires;
369 if (first_module ==
NULL)
371 for (
auto &it : module->
wires_)
373 if (!flag_dff || dff_wires.count(it.first))
374 shared_wires.insert(it.first);
377 for (
auto &it : module->
cells_)
379 shared_cells.insert(it.first);
385 std::vector<RTLIL::IdString> delete_shared_wires, delete_shared_cells;
387 for (
auto &it : shared_wires)
391 if (module->
wires_.count(it) == 0)
392 goto delete_shared_wire;
394 wire = module->
wires_.at(it);
396 if (!design->
selected(module, wire))
397 goto delete_shared_wire;
399 goto delete_shared_wire;
401 goto delete_shared_wire;
402 if (flag_dff && !dff_wires.count(it))
403 goto delete_shared_wire;
407 delete_shared_wires.push_back(it);
411 for (
auto &it : shared_cells)
415 if (module->cells_.count(it) == 0)
416 goto delete_shared_cell;
418 cell = module->cells_.at(it);
420 if (!design->
selected(module, cell))
421 goto delete_shared_cell;
423 goto delete_shared_cell;
425 goto delete_shared_cell;
429 delete_shared_cells.push_back(it);
432 for (
auto &it : delete_shared_wires)
433 shared_wires.erase(it);
434 for (
auto &it : delete_shared_cells)
435 shared_cells.erase(it);
440 for (
auto &mod_it : design->
modules_)
447 std::set<RTLIL::IdString> dff_wires;
448 if (flag_dff && !flag_shared)
455 for (
auto &it : module->
wires_)
458 if (shared_wires.count(it.first) == 0)
463 if (flag_dff && !dff_wires.count(it.first))
467 if (!it.second->port_output) {
468 it.second->port_output =
true;
475 out_to_in_map.
add(sigmap(it.second), in_wire);
481 for (
auto &it : module->
cells_) {
484 for (
auto &conn : it.second->connections_)
486 conn.second = out_to_in_map(sigmap(conn.second));
490 conn.second = out_to_in_map(sigmap(conn.second));
493 std::set<RTLIL::SigBit> set_q_bits;
495 for (
auto &dq : dff_dq_maps[module])
497 if (!module->wires_.count(dq.first))
501 std::set<RTLIL::SigBit> wire_bits_set = sigmap(wire).to_sigbit_set();
502 std::vector<RTLIL::SigBit> wire_bits_vec = sigmap(wire).to_sigbit_vector();
508 for (
auto &cell_name : info.
cells) {
510 std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->
getPort(
"\\Q")).to_sigbit_vector();
511 for (
auto &bit : cell_q_bits)
512 if (wire_bits_set.count(bit))
514 cell->
setPort(
"\\Q", cell_q_bits);
522 for (
size_t i = 0; i < wire_bits_vec.size(); i++) {
523 if (set_q_bits.count(wire_bits_vec[i]))
525 connect_q.first.append(wire_bits_vec[i]);
527 set_q_bits.insert(wire_bits_vec[i]);
529 module->connect(connect_q);
575 std::vector<RTLIL::Cell*> delete_cells;
577 for (
auto &it : module->cells_)
580 if (shared_cells.count(it.first) == 0)
593 for (
auto &it : mod->
wires_)
636 delete_cells.push_back(cell);
639 for (
auto cell : delete_cells) {
641 module->remove(cell);
645 module->fixup_ports();
bool selected(T1 *module) const
RTLIL::Wire * add_new_wire(RTLIL::Module *module, RTLIL::IdString name, int width=1)
void find_dff_wires(std::set< RTLIL::IdString > &dff_wires, RTLIL::Module *module)
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
std::map< RTLIL::IdString, RTLIL::Const > parameters
bool consider_wire(RTLIL::Wire *wire, std::map< RTLIL::IdString, dff_map_info_t > &dff_dq_map)
bool compare_wires(RTLIL::Wire *wire1, RTLIL::Wire *wire2)
std::vector< RTLIL::SigSig > connections_
bool cell_known(RTLIL::IdString type)
RTLIL_ATTRIBUTE_MEMBERS bool hasPort(RTLIL::IdString portname) const
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
bool consider_cell(RTLIL::Design *design, std::set< RTLIL::IdString > &dff_cells, RTLIL::Cell *cell)
static const char * id2cstr(const RTLIL::IdString &str)
std::map< RTLIL::IdString, RTLIL::Module * > modules_
void create_dff_dq_map(std::map< RTLIL::IdString, dff_map_info_t > &map, RTLIL::Design *design, RTLIL::Module *module)
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
std::vector< RTLIL::IdString > cells
void log(const char *format,...)
void extend(int width, bool is_signed=false)
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
bool compare_cells(RTLIL::Cell *cell1, RTLIL::Cell *cell2)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::pair< SigSpec, SigSpec > SigSig
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
const char * log_id(RTLIL::IdString str)