From: Clifford Wolf Date: Sat, 24 Oct 2015 11:44:35 +0000 (+0200) Subject: Fixed handling of driver-driver conflicts in wreduce X-Git-Tag: yosys-0.6~93 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2a0f577f839bc43a5045ddf5a2b580bba8cabeab;p=yosys.git Fixed handling of driver-driver conflicts in wreduce --- diff --git a/kernel/modtools.h b/kernel/modtools.h index 44c1bde12..1480ec71f 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -226,7 +226,7 @@ struct ModIndex : public RTLIL::Monitor auto_reload_module = true; } - ModIndex(RTLIL::Module *_m) : module(_m) + ModIndex(RTLIL::Module *_m) : sigmap(_m), module(_m) { auto_reload_counter = 0; auto_reload_module = true; @@ -274,6 +274,27 @@ struct ModIndex : public RTLIL::Monitor return empty_result_set; 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 diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7090fe913..8332219ae 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1448,6 +1448,10 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn) for (auto mon : design->monitors) mon->notify_connect(this, conn); +#ifndef NDEBUG + log_assert(!conn.first.has_const()); +#endif + 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_backtrace("-X- ", yosys_xtrace-1); diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index c194d428d..e2d9a2c4f 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -66,6 +66,9 @@ struct WreduceWorker SigSpec sig_y = mi.sigmap(cell->getPort("\\Y")); std::vector bits_removed; + if (sig_y.has_const()) + return; + for (int i = GetSize(sig_y)-1; i >= 0; i--) { auto info = mi.query(sig_y[i]); @@ -173,6 +176,11 @@ struct WreduceWorker if (cell->type.in("$mux", "$pmux")) 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 @@ -180,8 +188,8 @@ struct WreduceWorker 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")) { - max_port_a_size = std::min(max_port_a_size, GetSize(cell->getPort("\\Y"))); - max_port_b_size = std::min(max_port_b_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(sig)); } 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 - SigSpec sig = mi.sigmap(cell->getPort("\\Y")); - int bits_removed = 0; if (port_a_signed && cell->type == "$shr") { // 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", "$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) { SigSpec sig = c->getPort("\\Y"); - c->setPort("\\Y", sig[0]); - c->setParam("\\Y_WIDTH", 1); - sig.remove(0); - module->connect(sig, Const(0, GetSize(sig))); + if (!sig.has_const()) { + c->setPort("\\Y", sig[0]); + c->setParam("\\Y_WIDTH", 1); + sig.remove(0); + module->connect(sig, Const(0, GetSize(sig))); + } } WreduceWorker worker(&config, module);