33 std::vector<RTLIL::IdString>
cells;
45 if (wire->
name[0] ==
'$' || dff_dq_map.count(wire->
name))
54 if (cell->
name[0] ==
'$' || dff_cells.count(cell->
name))
88 for (
auto &it : module->
cells_) {
89 if (ct.
cell_known(it.second->type) && it.second->hasPort(
"\\Q"))
90 dffsignals.
add(sigmap(it.second->getPort(
"\\Q")));
93 for (
auto &it : module->
wires_) {
95 dff_wires.insert(it.first);
101 std::map<RTLIL::SigBit, dff_map_bit_info_t> bit_info;
104 for (
auto &it : module->
cells_)
106 if (!design->
selected(module, it.second))
116 info.
cell = it.second;
121 std::vector<RTLIL::SigBit> sig_d = sigmap(info.
cell->
getPort(
"\\D")).to_sigbit_vector();
122 std::vector<RTLIL::SigBit> sig_q = sigmap(info.
cell->
getPort(
"\\Q")).to_sigbit_vector();
123 for (
size_t i = 0; i < sig_d.size(); i++) {
124 info.
bit_d = sig_d.at(i);
125 bit_info[sig_q.at(i)] = info;
135 std::vector<RTLIL::SigBit> sig_d = sigmap(info.
cell->
getPort(
"\\D")).to_sigbit_vector();
136 std::vector<RTLIL::SigBit> sig_q = sigmap(info.
cell->
getPort(
"\\Q")).to_sigbit_vector();
137 std::vector<RTLIL::State> arst_value = info.
cell->
parameters.at(
"\\ARST_VALUE").bits;
138 for (
size_t i = 0; i < sig_d.size(); i++) {
139 info.
bit_d = sig_d.at(i);
141 bit_info[sig_q.at(i)] = info;
150 bit_info[sigmap(info.
cell->
getPort(
"\\Q")).to_single_sigbit()] = info;
161 bit_info[sigmap(info.
cell->
getPort(
"\\Q")).to_single_sigbit()] = info;
166 std::map<RTLIL::IdString, dff_map_info_t> empty_dq_map;
167 for (
auto &it : module->
wires_)
172 std::vector<RTLIL::SigBit> bits_q = sigmap(it.second).to_sigbit_vector();
173 std::vector<RTLIL::SigBit> bits_d;
174 std::vector<RTLIL::State> arst_value;
175 std::set<RTLIL::Cell*> cells;
177 if (bits_q.empty() || !bit_info.count(bits_q.front()))
181 for (
auto &bit : bits_q) {
182 if (!bit_info.count(bit))
193 bits_d.push_back(info.
bit_d);
195 cells.insert(info.
cell);
198 if (bits_d.size() != bits_q.size())
208 for (
auto it : cells)
209 info.
cells.push_back(it->name);
210 map[it.first] = info;
217 log_error(
"Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n",
log_id(name));
218 return module->
addWire(name, width);
227 log(
" expose [options] [selection]\n");
229 log(
"This command exposes all selected internal signals of a module as additional\n");
233 log(
" only consider wires that are directly driven by register cell.\n");
236 log(
" when exposing a wire, create an input/output pair and cut the internal\n");
237 log(
" signal path at that wire.\n");
240 log(
" only expose those signals that are shared ammong the selected modules.\n");
241 log(
" this is useful for preparing modules for equivialence checking.\n");
244 log(
" also turn connections to instances of other modules to additional\n");
245 log(
" inputs and outputs and remove the module instances.\n");
247 log(
" -evert-dff\n");
248 log(
" turn flip-flops to sets of inputs and outputs.\n");
250 log(
" -sep <separator>\n");
251 log(
" when creating new wire/port names, the original object name is suffixed\n");
252 log(
" with this separator (default: '.') and the port name or a type\n");
253 log(
" designator for the exposed signal.\n");
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_)
485 if (ct.
cell_input(it.second->type, conn.first))
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 setup_internals_mem()
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)
void log_error(const char *format,...)
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)
bool check_any(RTLIL::SigSpec sig)
#define PRIVATE_NAMESPACE_BEGIN
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
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
#define PRIVATE_NAMESPACE_END
bool consider_cell(RTLIL::Design *design, std::set< RTLIL::IdString > &dff_cells, RTLIL::Cell *cell)
static const char * id2cstr(const RTLIL::IdString &str)
void add(RTLIL::SigSpec sig)
std::string substr(size_t pos=0, size_t len=std::string::npos) const
#define USING_YOSYS_NAMESPACE
virtual size_t count_id(RTLIL::IdString id)
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 setup_stdcells_mem()
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)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)