yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
opt_rmdff.cc File Reference
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/log.h"
#include <stdlib.h>
#include <stdio.h>
+ Include dependency graph for opt_rmdff.cc:

Go to the source code of this file.

Data Structures

struct  OptRmdffPass
 

Functions

bool handle_dff (RTLIL::Module *mod, RTLIL::Cell *dff)
 

Variables

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN SigMap 
assign_map
 
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN SigMap 
dff_init_map
 
SigSet< RTLIL::Cell * > mux_drivers
 
OptRmdffPass OptRmdffPass
 

Function Documentation

bool handle_dff ( RTLIL::Module mod,
RTLIL::Cell dff 
)

Definition at line 32 of file opt_rmdff.cc.

33 {
34  RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r;
35  RTLIL::Const val_cp, val_rp, val_rv;
36 
37  if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") {
38  sig_d = dff->getPort("\\D");
39  sig_q = dff->getPort("\\Q");
40  sig_c = dff->getPort("\\C");
41  val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1);
42  }
43  else if (dff->type.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" &&
44  (dff->type[6] == 'N' || dff->type[6] == 'P') &&
45  (dff->type[7] == 'N' || dff->type[7] == 'P') &&
46  (dff->type[8] == '0' || dff->type[8] == '1')) {
47  sig_d = dff->getPort("\\D");
48  sig_q = dff->getPort("\\Q");
49  sig_c = dff->getPort("\\C");
50  sig_r = dff->getPort("\\R");
51  val_cp = RTLIL::Const(dff->type[6] == 'P', 1);
52  val_rp = RTLIL::Const(dff->type[7] == 'P', 1);
53  val_rv = RTLIL::Const(dff->type[8] == '1', 1);
54  }
55  else if (dff->type == "$dff") {
56  sig_d = dff->getPort("\\D");
57  sig_q = dff->getPort("\\Q");
58  sig_c = dff->getPort("\\CLK");
59  val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1);
60  }
61  else if (dff->type == "$adff") {
62  sig_d = dff->getPort("\\D");
63  sig_q = dff->getPort("\\Q");
64  sig_c = dff->getPort("\\CLK");
65  sig_r = dff->getPort("\\ARST");
66  val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1);
67  val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1);
68  val_rv = dff->parameters["\\ARST_VALUE"];
69  }
70  else
71  log_abort();
72 
73  assign_map.apply(sig_d);
74  assign_map.apply(sig_q);
75  assign_map.apply(sig_c);
76  assign_map.apply(sig_r);
77 
78  bool has_init = false;
79  RTLIL::Const val_init;
80  for (auto bit : dff_init_map(sig_q).to_sigbit_vector()) {
81  if (bit.wire == NULL)
82  has_init = true;
83  val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx);
84  }
85 
86  if (dff->type == "$dff" && mux_drivers.has(sig_d) && !has_init) {
87  std::set<RTLIL::Cell*> muxes;
88  mux_drivers.find(sig_d, muxes);
89  for (auto mux : muxes) {
90  RTLIL::SigSpec sig_a = assign_map(mux->getPort("\\A"));
91  RTLIL::SigSpec sig_b = assign_map(mux->getPort("\\B"));
92  if (sig_a == sig_q && sig_b.is_fully_const()) {
93  RTLIL::SigSig conn(sig_q, sig_b);
94  mod->connect(conn);
95  goto delete_dff;
96  }
97  if (sig_b == sig_q && sig_a.is_fully_const()) {
98  RTLIL::SigSig conn(sig_q, sig_a);
99  mod->connect(conn);
100  goto delete_dff;
101  }
102  }
103  }
104 
105  if (sig_c.is_fully_const() && (!sig_r.size() || !has_init)) {
106  if (val_rv.bits.size() == 0)
107  val_rv = val_init;
108  RTLIL::SigSig conn(sig_q, val_rv);
109  mod->connect(conn);
110  goto delete_dff;
111  }
112 
113  if (sig_d.is_fully_undef() && sig_r.size() && !has_init) {
114  RTLIL::SigSig conn(sig_q, val_rv);
115  mod->connect(conn);
116  goto delete_dff;
117  }
118 
119  if (sig_d.is_fully_undef() && !sig_r.size() && has_init) {
120  RTLIL::SigSig conn(sig_q, val_init);
121  mod->connect(conn);
122  goto delete_dff;
123  }
124 
125  if (sig_d.is_fully_const() && !sig_r.size() && !has_init) {
126  RTLIL::SigSig conn(sig_q, sig_d);
127  mod->connect(conn);
128  goto delete_dff;
129  }
130 
131  if (sig_d == sig_q && !(sig_r.size() && has_init)) {
132  if (sig_r.size()) {
133  RTLIL::SigSig conn(sig_q, val_rv);
134  mod->connect(conn);
135  }
136  if (has_init) {
137  RTLIL::SigSig conn(sig_q, val_init);
138  mod->connect(conn);
139  }
140  goto delete_dff;
141  }
142 
143  return false;
144 
145 delete_dff:
146  log("Removing %s (%s) from module %s.\n", dff->name.c_str(), dff->type.c_str(), mod->name.c_str());
147  mod->remove(dff);
148  return true;
149 }
const char * c_str() const
Definition: rtlil.h:178
bool is_fully_undef() const
Definition: rtlil.cc:2789
bool has(RTLIL::SigSpec sig)
Definition: sigtools.h:203
RTLIL::IdString name
Definition: rtlil.h:853
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
int size() const
Definition: rtlil.h:1019
#define log_abort()
Definition: log.h:84
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
bool is_fully_const() const
Definition: rtlil.cc:2763
RTLIL::IdString name
Definition: rtlil.h:599
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN SigMap dff_init_map
Definition: opt_rmdff.cc:29
std::string substr(size_t pos=0, size_t len=std::string::npos) const
Definition: rtlil.h:208
#define NULL
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
SigSet< RTLIL::Cell * > mux_drivers
Definition: opt_rmdff.cc:30
void log(const char *format,...)
Definition: log.cc:180
std::vector< RTLIL::State > bits
Definition: rtlil.h:438
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
void find(RTLIL::SigSpec sig, std::set< T > &result)
Definition: sigtools.h:187
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN SigMap assign_map
Definition: opt_rmdff.cc:29

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

Definition at line 29 of file opt_rmdff.cc.

Definition at line 29 of file opt_rmdff.cc.

SigSet<RTLIL::Cell*> mux_drivers

Definition at line 30 of file opt_rmdff.cc.