mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-05 15:06:11 +00:00
opt_muxtree: inhibit opt on reconvergence
This commit is contained in:
parent
4605811222
commit
ffd8683907
1 changed files with 22 additions and 14 deletions
|
|
@ -34,7 +34,7 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
* A multiplexer tree (mux tree) is a tree composed exclusively of muxes.
|
* A multiplexer tree (mux tree) is a tree composed exclusively of muxes.
|
||||||
* By mux, I mean $mux or $pmux. By port, I usually mean input port.
|
* By mux, I mean $mux or $pmux. By port, I usually mean input port.
|
||||||
* The children of a node are all the muxes driving its input ports (A, B).
|
* The children of a node are all the muxes driving its input ports (A, B).
|
||||||
* It must be rooted in a "root mux", a mux which has multiple mux users
|
* It must be rooted in a "root mux", a mux which has multiple mux port users
|
||||||
* or any number of non-mux users. Only the root and leaf nodes can be
|
* or any number of non-mux users. Only the root and leaf nodes can be
|
||||||
* root muxes, not the internal nodes. Leaf nodes that are root muxes
|
* root muxes, not the internal nodes. Leaf nodes that are root muxes
|
||||||
* are roots of "input trees".
|
* are roots of "input trees".
|
||||||
|
|
@ -64,10 +64,17 @@ struct OptMuxtreeWorker
|
||||||
int removed_count;
|
int removed_count;
|
||||||
int glob_evals_left = 10'000'000;
|
int glob_evals_left = 10'000'000;
|
||||||
|
|
||||||
|
struct MuxPort {
|
||||||
|
int mux;
|
||||||
|
// Hacky: -1 is port A, if positive then indexes B port slices (of which $mux has only one)
|
||||||
|
int port;
|
||||||
|
inline Hasher hash_into(Hasher h) const { h.eat(mux); h.eat(port); return h; }
|
||||||
|
bool operator==(const MuxPort &other) const { return mux == other.mux && port == other.port; }
|
||||||
|
};
|
||||||
struct bitinfo_t {
|
struct bitinfo_t {
|
||||||
// Is bit directly used by non-mux cells or ports?
|
// Is bit directly used by non-mux cells or ports?
|
||||||
bool seen_non_mux;
|
bool seen_non_mux;
|
||||||
pool<int> mux_users;
|
pool<struct MuxPort> mux_users;
|
||||||
pool<int> mux_drivers;
|
pool<int> mux_drivers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -94,10 +101,10 @@ struct OptMuxtreeWorker
|
||||||
vector<bool> root_enable_muxes;
|
vector<bool> root_enable_muxes;
|
||||||
pool<int> root_mux_rerun;
|
pool<int> root_mux_rerun;
|
||||||
|
|
||||||
portinfo_t used_port_bit(RTLIL::SigSpec& sig, int mux_idx) {
|
portinfo_t used_port_bit(RTLIL::SigSpec& sig, int mux_idx, int port_idx) {
|
||||||
portinfo_t portinfo = {};
|
portinfo_t portinfo = {};
|
||||||
for (int bit_idx : sig2bits(sig)) {
|
for (int bit_idx : sig2bits(sig)) {
|
||||||
bit2info[bit_idx].mux_users.insert(mux_idx);
|
bit2info[bit_idx].mux_users.insert({mux_idx, port_idx});
|
||||||
portinfo.input_sigs.insert(bit_idx);
|
portinfo.input_sigs.insert(bit_idx);
|
||||||
}
|
}
|
||||||
return portinfo;
|
return portinfo;
|
||||||
|
|
@ -127,7 +134,7 @@ struct OptMuxtreeWorker
|
||||||
for (int i = 0; i < GetSize(sig_s); i++) {
|
for (int i = 0; i < GetSize(sig_s); i++) {
|
||||||
RTLIL::SigSpec sig = sig_b.extract(i*GetSize(sig_a), GetSize(sig_a));
|
RTLIL::SigSpec sig = sig_b.extract(i*GetSize(sig_a), GetSize(sig_a));
|
||||||
RTLIL::SigSpec ctrl_sig = assign_map(SigSpec{sig_s[i]});
|
RTLIL::SigSpec ctrl_sig = assign_map(SigSpec{sig_s[i]});
|
||||||
portinfo_t portinfo = used_port_bit(sig, this_mux_idx);
|
portinfo_t portinfo = used_port_bit(sig, this_mux_idx, i);
|
||||||
portinfo.ctrl_sig = sig2bits(ctrl_sig, false).front();
|
portinfo.ctrl_sig = sig2bits(ctrl_sig, false).front();
|
||||||
portinfo.const_activated = ctrl_sig.is_fully_const() && ctrl_sig.as_bool();
|
portinfo.const_activated = ctrl_sig.is_fully_const() && ctrl_sig.as_bool();
|
||||||
portinfo.const_deactivated = ctrl_sig.is_fully_const() && !ctrl_sig.as_bool();
|
portinfo.const_deactivated = ctrl_sig.is_fully_const() && !ctrl_sig.as_bool();
|
||||||
|
|
@ -135,7 +142,7 @@ struct OptMuxtreeWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analyze port A
|
// Analyze port A
|
||||||
muxinfo.ports.push_back(used_port_bit(sig_a, this_mux_idx));
|
muxinfo.ports.push_back(used_port_bit(sig_a, this_mux_idx, -1));
|
||||||
|
|
||||||
for (int idx : sig2bits(sig_y))
|
for (int idx : sig2bits(sig_y))
|
||||||
bit2info[idx].mux_drivers.insert(this_mux_idx);
|
bit2info[idx].mux_drivers.insert(this_mux_idx);
|
||||||
|
|
@ -167,17 +174,18 @@ struct OptMuxtreeWorker
|
||||||
// bit2info knows the mux users and mux drivers of bits
|
// bit2info knows the mux users and mux drivers of bits
|
||||||
// use this to tell mux2info ports about what muxes are driven by it
|
// use this to tell mux2info ports about what muxes are driven by it
|
||||||
for (int i = 0; i < GetSize(bit2info); i++)
|
for (int i = 0; i < GetSize(bit2info); i++)
|
||||||
for (int j : bit2info[i].mux_users)
|
for (auto muxport : bit2info[i].mux_users) {
|
||||||
for (auto &p : mux2info[j].ports) {
|
for (auto &p : mux2info[muxport.mux].ports) {
|
||||||
if (p.input_sigs.count(i))
|
if (p.input_sigs.count(i))
|
||||||
for (int k : bit2info[i].mux_drivers)
|
for (int k : bit2info[i].mux_drivers)
|
||||||
p.input_muxes.insert(k);
|
p.input_muxes.insert(k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate_roots() {
|
void populate_roots() {
|
||||||
// mux_to_users[i] means "set of muxes using output of mux i"
|
// mux_to_users[i] means "set of muxes using output of mux i"
|
||||||
dict<int, pool<int>> mux_to_users;
|
dict<int, pool<struct MuxPort>> mux_to_users;
|
||||||
// Pure root muxes (outputs seen by non-muxes)
|
// Pure root muxes (outputs seen by non-muxes)
|
||||||
root_enable_muxes.resize(GetSize(mux2info));
|
root_enable_muxes.resize(GetSize(mux2info));
|
||||||
// All root muxes (outputs seen by non-muxes or multiple muxes)
|
// All root muxes (outputs seen by non-muxes or multiple muxes)
|
||||||
|
|
@ -185,8 +193,8 @@ struct OptMuxtreeWorker
|
||||||
|
|
||||||
for (auto &bi : bit2info) {
|
for (auto &bi : bit2info) {
|
||||||
for (int i : bi.mux_drivers)
|
for (int i : bi.mux_drivers)
|
||||||
for (int j : bi.mux_users)
|
for (auto muxport : bi.mux_users)
|
||||||
mux_to_users[i].insert(j);
|
mux_to_users[i].insert(muxport);
|
||||||
if (!bi.seen_non_mux)
|
if (!bi.seen_non_mux)
|
||||||
continue;
|
continue;
|
||||||
for (int mux_idx : bi.mux_drivers) {
|
for (int mux_idx : bi.mux_drivers) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue