34 std::map<RTLIL::SigBit, cell_int_t>
bit2mux;
43 for (
auto wire : module->
wires()) {
44 if (wire->port_output)
45 for (
auto bit :
sigmap(wire))
49 for (
auto cell : module->
cells()) {
50 if (cell->type ==
"$mux" || cell->type ==
"$pmux") {
52 for (
int i = 0; i <
GetSize(sig_y); i++)
55 if (cell->type ==
"$dff")
57 for (
auto conn : cell->connections()) {
60 for (
auto bit :
sigmap(conn.second))
82 int width =
GetSize(sig_a), index = mux_cell_int.second;
84 for (
int i = 0; i <
GetSize(sig_s); i++)
85 if (path.count(sig_s[i]) && path.at(sig_s[i]))
89 if (sig_b[i*width + index] == q) {
92 mux_cell_int.first->setPort(
"\\B", s);
100 for (
int i = 0; i <
GetSize(sig_s); i++)
102 if (path.count(sig_s[i]))
106 path_else[sig_s[i]] =
false;
107 path_this[sig_s[i]] =
true;
112 if (sig_b[i*width + index] == q) {
115 mux_cell_int.first->setPort(
"\\B", s);
122 if (sig_a[index] == q) {
125 mux_cell_int.first->setPort(
"\\A", s);
139 for (
auto pat : patterns) {
141 for (
auto it : pat) {
159 std::map<patterns_t, std::set<int>> grouped_patterns;
160 std::set<int> remaining_indices;
162 for (
int i = 0 ; i <
GetSize(sig_d); i++) {
164 if (!patterns.empty()) {
166 grouped_patterns[patterns].insert(i);
168 remaining_indices.insert(i);
171 for (
auto &it : grouped_patterns) {
173 for (
int i : it.second) {
174 new_sig_d.
append(sig_d[i]);
175 new_sig_q.
append(sig_q[i]);
178 new_sig_d, new_sig_q, dff_cell->
getParam(
"\\CLK_POLARITY").
as_bool(),
true);
182 if (remaining_indices.empty()) {
183 log(
" removing now obsolete cell %s.\n",
log_id(dff_cell));
186 log(
" removing %d now obsolete bits from cell %s.\n",
GetSize(sig_d) -
GetSize(remaining_indices),
log_id(dff_cell));
188 for (
int i : remaining_indices) {
189 new_sig_d.
append(sig_d[i]);
190 new_sig_q.
append(sig_q[i]);
192 dff_cell->
setPort(
"\\D", new_sig_d);
193 dff_cell->
setPort(
"\\Q", new_sig_q);
200 log(
"Transforming $dff to $dffe cells in module %s:\n",
log_id(
module));
212 log(
" dff2dffe [selection]\n");
214 log(
"This pass transforms $dff cells driven by a tree of multiplexers with one or\n");
215 log(
"more feedback paths to $dffe cells.\n");
220 log_header(
"Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n");
223 for (argidx = 1; argidx < args.size(); argidx++) {
233 if (!mod->has_processes_warn()) {
std::map< RTLIL::SigBit, int > bitusers
Dff2dffeWorker(RTLIL::Module *module)
RTLIL::SigSpec Ne(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed=false)
void log_header(const char *format,...)
void setParam(RTLIL::IdString paramname, RTLIL::Const value)
void simplify_patterns(patterns_t &)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
RTLIL::ObjRange< RTLIL::Wire * > wires()
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
std::map< RTLIL::SigBit, bool > pattern_t
std::set< pattern_t > patterns_t
Dff2dffePass Dff2dffePass
std::vector< RTLIL::Cell * > dff_cells
void handle_dff_cell(RTLIL::Cell *dff_cell)
#define PRIVATE_NAMESPACE_BEGIN
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
int GetSize(RTLIL::Wire *wire)
patterns_t find_muxtree_feedback_patterns(RTLIL::SigBit d, RTLIL::SigBit q, pattern_t path)
#define PRIVATE_NAMESPACE_END
std::map< RTLIL::SigBit, cell_int_t > bit2mux
#define USING_YOSYS_NAMESPACE
RTLIL::ObjRange< RTLIL::Cell * > cells()
void remove(const std::set< RTLIL::Wire * > &wires)
RTLIL::SigSpec ReduceOr(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed=false)
std::pair< RTLIL::Cell *, int > cell_int_t
void log(const char *format,...)
const RTLIL::Const & getParam(RTLIL::IdString paramname) const
void append(const RTLIL::SigSpec &signal)
std::vector< RTLIL::Module * > selected_modules() const
RTLIL::SigSpec make_patterns_logic(patterns_t patterns)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
RTLIL::Cell * addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity=true, bool en_polarity=true)
const char * log_id(RTLIL::IdString str)