mirror of https://github.com/YosysHQ/yosys.git
Fixed handling of driver-driver conflicts in wreduce
This commit is contained in:
parent
4cec1c058d
commit
2a0f577f83
|
@ -226,7 +226,7 @@ struct ModIndex : public RTLIL::Monitor
|
||||||
auto_reload_module = true;
|
auto_reload_module = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModIndex(RTLIL::Module *_m) : module(_m)
|
ModIndex(RTLIL::Module *_m) : sigmap(_m), module(_m)
|
||||||
{
|
{
|
||||||
auto_reload_counter = 0;
|
auto_reload_counter = 0;
|
||||||
auto_reload_module = true;
|
auto_reload_module = true;
|
||||||
|
@ -274,6 +274,27 @@ struct ModIndex : public RTLIL::Monitor
|
||||||
return empty_result_set;
|
return empty_result_set;
|
||||||
return info->ports;
|
return info->ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump_db()
|
||||||
|
{
|
||||||
|
log("--- ModIndex Dump ---\n");
|
||||||
|
|
||||||
|
if (auto_reload_module) {
|
||||||
|
log("AUTO-RELOAD\n");
|
||||||
|
reload_module();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : database) {
|
||||||
|
log("BIT %s:\n", log_signal(it.first));
|
||||||
|
if (it.second.is_input)
|
||||||
|
log(" PRIMARY INPUT\n");
|
||||||
|
if (it.second.is_output)
|
||||||
|
log(" PRIMARY OUTPUT\n");
|
||||||
|
for (auto &port : it.second.ports)
|
||||||
|
log(" PORT: %s.%s[%d] (%s)\n", log_id(port.cell),
|
||||||
|
log_id(port.port), port.offset, log_id(port.cell->type));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModWalker
|
struct ModWalker
|
||||||
|
|
|
@ -1448,6 +1448,10 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
|
||||||
for (auto mon : design->monitors)
|
for (auto mon : design->monitors)
|
||||||
mon->notify_connect(this, conn);
|
mon->notify_connect(this, conn);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
log_assert(!conn.first.has_const());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (yosys_xtrace) {
|
if (yosys_xtrace) {
|
||||||
log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
|
log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
|
||||||
log_backtrace("-X- ", yosys_xtrace-1);
|
log_backtrace("-X- ", yosys_xtrace-1);
|
||||||
|
|
|
@ -66,6 +66,9 @@ struct WreduceWorker
|
||||||
SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
|
SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
|
||||||
std::vector<SigBit> bits_removed;
|
std::vector<SigBit> bits_removed;
|
||||||
|
|
||||||
|
if (sig_y.has_const())
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = GetSize(sig_y)-1; i >= 0; i--)
|
for (int i = GetSize(sig_y)-1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto info = mi.query(sig_y[i]);
|
auto info = mi.query(sig_y[i]);
|
||||||
|
@ -173,6 +176,11 @@ struct WreduceWorker
|
||||||
if (cell->type.in("$mux", "$pmux"))
|
if (cell->type.in("$mux", "$pmux"))
|
||||||
return run_cell_mux(cell);
|
return run_cell_mux(cell);
|
||||||
|
|
||||||
|
SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
|
||||||
|
|
||||||
|
if (sig.has_const())
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
// Reduce size of ports A and B based on constant input bits and size of output port
|
// Reduce size of ports A and B based on constant input bits and size of output port
|
||||||
|
|
||||||
|
@ -180,8 +188,8 @@ struct WreduceWorker
|
||||||
int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1;
|
int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1;
|
||||||
|
|
||||||
if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) {
|
if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) {
|
||||||
max_port_a_size = std::min(max_port_a_size, GetSize(cell->getPort("\\Y")));
|
max_port_a_size = std::min(max_port_a_size, GetSize(sig));
|
||||||
max_port_b_size = std::min(max_port_b_size, GetSize(cell->getPort("\\Y")));
|
max_port_b_size = std::min(max_port_b_size, GetSize(sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool port_a_signed = false;
|
bool port_a_signed = false;
|
||||||
|
@ -196,8 +204,6 @@ struct WreduceWorker
|
||||||
|
|
||||||
// Reduce size of port Y based on sizes for A and B and unused bits in Y
|
// Reduce size of port Y based on sizes for A and B and unused bits in Y
|
||||||
|
|
||||||
SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
|
|
||||||
|
|
||||||
int bits_removed = 0;
|
int bits_removed = 0;
|
||||||
if (port_a_signed && cell->type == "$shr") {
|
if (port_a_signed && cell->type == "$shr") {
|
||||||
// do not reduce size of output on $shr cells with signed A inputs
|
// do not reduce size of output on $shr cells with signed A inputs
|
||||||
|
@ -358,10 +364,12 @@ struct WreducePass : public Pass {
|
||||||
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
|
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
|
||||||
"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
|
"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
|
||||||
SigSpec sig = c->getPort("\\Y");
|
SigSpec sig = c->getPort("\\Y");
|
||||||
c->setPort("\\Y", sig[0]);
|
if (!sig.has_const()) {
|
||||||
c->setParam("\\Y_WIDTH", 1);
|
c->setPort("\\Y", sig[0]);
|
||||||
sig.remove(0);
|
c->setParam("\\Y_WIDTH", 1);
|
||||||
module->connect(sig, Const(0, GetSize(sig)));
|
sig.remove(0);
|
||||||
|
module->connect(sig, Const(0, GetSize(sig)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WreduceWorker worker(&config, module);
|
WreduceWorker worker(&config, module);
|
||||||
|
|
Loading…
Reference in New Issue