diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/setundef.cc | 22 | ||||
-rw-r--r-- | passes/opt/opt_expr.cc | 129 | ||||
-rw-r--r-- | passes/techmap/abc9_exe.cc | 4 | ||||
-rw-r--r-- | passes/techmap/abc9_ops.cc | 3 | ||||
-rw-r--r-- | passes/techmap/dffinit.cc | 8 | ||||
-rw-r--r-- | passes/techmap/techmap.cc | 2 |
6 files changed, 133 insertions, 35 deletions
diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 2556d188a..8d973869e 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -149,7 +149,7 @@ struct SetundefPass : public Pass { } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { - bool got_value = false; + int got_value = 0; bool undriven_mode = false; bool expose_mode = false; bool init_mode = false; @@ -170,31 +170,31 @@ struct SetundefPass : public Pass { continue; } if (args[argidx] == "-zero") { - got_value = true; + got_value++; worker.next_bit_mode = MODE_ZERO; worker.next_bit_state = 0; continue; } if (args[argidx] == "-one") { - got_value = true; + got_value++; worker.next_bit_mode = MODE_ONE; worker.next_bit_state = 0; continue; } if (args[argidx] == "-anyseq") { - got_value = true; + got_value++; worker.next_bit_mode = MODE_ANYSEQ; worker.next_bit_state = 0; continue; } if (args[argidx] == "-anyconst") { - got_value = true; + got_value++; worker.next_bit_mode = MODE_ANYCONST; worker.next_bit_state = 0; continue; } if (args[argidx] == "-undef") { - got_value = true; + got_value++; worker.next_bit_mode = MODE_UNDEF; worker.next_bit_state = 0; continue; @@ -207,8 +207,8 @@ struct SetundefPass : public Pass { params_mode = true; continue; } - if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) { - got_value = true; + if (args[argidx] == "-random" && argidx+1 < args.size()) { + got_value++; worker.next_bit_mode = MODE_RANDOM; worker.next_bit_state = atoi(args[++argidx].c_str()) + 1; for (int i = 0; i < 10; i++) @@ -221,7 +221,7 @@ struct SetundefPass : public Pass { if (!got_value && expose_mode) { log("Using default as -undef with -expose.\n"); - got_value = true; + got_value++; worker.next_bit_mode = MODE_UNDEF; worker.next_bit_state = 0; } @@ -229,7 +229,9 @@ struct SetundefPass : public Pass { if (expose_mode && !undriven_mode) log_cmd_error("Option -expose must be used with option -undriven.\n"); if (!got_value) - log_cmd_error("One of the options -zero, -one, -anyseq, -anyconst, or -random <seed> must be specified.\n"); + log_cmd_error("One of the options -zero, -one, -anyseq, -anyconst, -random <seed>, or -expose must be specified.\n"); + else if (got_value > 1) + log_cmd_error("Only one of the options -zero, -one, -anyseq, -anyconst, or -random <seed> can be specified.\n"); if (init_mode && (worker.next_bit_mode == MODE_ANYSEQ || worker.next_bit_mode == MODE_ANYCONST)) log_cmd_error("The options -init and -anyseq / -anyconst are exclusive.\n"); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 0222df38a..3229dd1b2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -717,31 +717,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons RTLIL::SigSpec sig_y = cell->getPort(ID::Y); RTLIL::SigSpec sig_co = cell->getPort(ID::CO); - bool sub = (sig_ci == State::S1 && sig_bi == State::S1); + if (sig_bi != State::S0 && sig_bi != State::S1) + goto skip_fine_alu; + if (sig_ci != State::S0 && sig_ci != State::S1) + goto skip_fine_alu; - // If not a subtraction, yet there is a carry or B is inverted - // then no optimisation is possible as carry will not be constant - if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) - goto next_cell; + bool bi = sig_bi == State::S1; + bool ci = sig_ci == State::S1; int i; for (i = 0; i < GetSize(sig_y); i++) { RTLIL::SigBit b = sig_b.at(i, State::Sx); RTLIL::SigBit a = sig_a.at(i, State::Sx); - if (b == State::S0 && a != State::Sx) { - module->connect(sig_y[i], sig_a[i]); - module->connect(sig_x[i], sub ? module->Not(NEW_ID, a).as_bit() : a); - module->connect(sig_co[i], sub ? State::S1 : State::S0); - } - else if (sub && b == State::S1 && a == State::S1) { - module->connect(sig_y[i], State::S0); - module->connect(sig_x[i], module->Not(NEW_ID, a)); - module->connect(sig_co[i], State::S0); + if (b == ((bi ^ ci) ? State::S1 : State::S0) && a != State::Sx) { + module->connect(sig_y[i], a); + module->connect(sig_x[i], ci ? module->Not(NEW_ID, a).as_bit() : a); + module->connect(sig_co[i], ci ? State::S1 : State::S0); } - else if (!sub && a == State::S0 && b != State::Sx) { - module->connect(sig_y[i], b); - module->connect(sig_x[i], b); - module->connect(sig_co[i], State::S0); + else if (a == (ci ? State::S1 : State::S0) && b != State::Sx) { + module->connect(sig_y[i], bi ? module->Not(NEW_ID, b).as_bit() : b); + module->connect(sig_x[i], (bi ^ ci) ? module->Not(NEW_ID, b).as_bit() : b); + module->connect(sig_co[i], ci ? State::S1 : State::S0); } else break; @@ -758,6 +754,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } } +skip_fine_alu: if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) @@ -1089,7 +1086,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons // If not a subtraction, yet there is a carry or B is inverted // then no optimisation is possible as carry will not be constant if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) - goto next_cell; + goto skip_identity; } if (!sub && a.is_fully_const() && a.as_bool() == false) @@ -1163,6 +1160,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } } +skip_identity: if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) { @@ -1530,6 +1528,99 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + // Find places in $alu cell where the carry is constant, and split it at these points. + if (do_fine && !keepdc && cell->type == ID($alu)) + { + bool a_signed = cell->parameters[ID::A_SIGNED].as_bool(); + bool b_signed = cell->parameters[ID::B_SIGNED].as_bool(); + bool is_signed = a_signed && b_signed; + + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y)); + RTLIL::SigSpec sig_bi = assign_map(cell->getPort(ID::BI)); + if (GetSize(sig_a) == 0) + sig_a = State::S0; + if (GetSize(sig_b) == 0) + sig_b = State::S0; + sig_a.extend_u0(GetSize(sig_y), is_signed); + sig_b.extend_u0(GetSize(sig_y), is_signed); + + if (sig_bi != State::S0 && sig_bi != State::S1) + goto skip_alu_split; + + std::vector<std::pair<int, State>> split_points; + + for (int i = 0; i < GetSize(sig_y); i++) { + SigBit bit_a = sig_a[i]; + SigBit bit_b = sig_b[i]; + if (bit_a != State::S0 && bit_a != State::S1) + continue; + if (bit_b != State::S0 && bit_b != State::S1) + continue; + if (sig_bi == State::S1) { + if (bit_b == State::S0) + bit_b = State::S1; + else + bit_b = State::S0; + } + if (bit_a != bit_b) + continue; + split_points.push_back(std::make_pair(i + 1, bit_a.data)); + } + + if (split_points.empty() || split_points[0].first == GetSize(sig_y)) + goto skip_alu_split; + + for (auto &p : split_points) + log_debug("Splitting $alu cell `%s' in module `%s' at const-carry point %d.\n", + cell->name.c_str(), module->name.c_str(), p.first); + + if (split_points.back().first != GetSize(sig_y)) + split_points.push_back(std::make_pair(GetSize(sig_y), State::Sx)); + + RTLIL::SigSpec sig_ci = assign_map(cell->getPort(ID::CI)); + int prev = 0; + RTLIL::SigSpec sig_x = assign_map(cell->getPort(ID::X)); + RTLIL::SigSpec sig_co = assign_map(cell->getPort(ID::CO)); + + for (auto &p : split_points) { + int cur = p.first; + int sz = cur - prev; + bool last = cur == GetSize(sig_y); + + RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); + c->setPort(ID::A, sig_a.extract(prev, sz)); + c->setPort(ID::B, sig_b.extract(prev, sz)); + c->setPort(ID::BI, sig_bi); + c->setPort(ID::CI, sig_ci); + c->setPort(ID::Y, sig_y.extract(prev, sz)); + c->setPort(ID::X, sig_x.extract(prev, sz)); + RTLIL::SigSpec new_co = sig_co.extract(prev, sz); + if (p.second != State::Sx) { + module->connect(new_co[sz-1], p.second); + RTLIL::Wire *dummy = module->addWire(NEW_ID); + new_co[sz-1] = dummy; + } + c->setPort(ID::CO, new_co); + c->parameters[ID::A_WIDTH] = sz; + c->parameters[ID::B_WIDTH] = sz; + c->parameters[ID::Y_WIDTH] = sz; + c->parameters[ID::A_SIGNED] = last ? a_signed : false; + c->parameters[ID::B_SIGNED] = last ? b_signed : false; + + prev = p.first; + sig_ci = p.second; + } + + cover("opt.opt_expr.alu_split"); + module->remove(cell); + + did_something = true; + goto next_cell; + } +skip_alu_split: + // remove redundant pairs of bits in ==, ===, !=, and !== // replace cell with const driver if inputs can't be equal if (do_fine && cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 303b04402..18618ff91 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -222,9 +222,9 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe abc9_script += stringf("; &ps -l; &write -n %s/output.aig", tempdir_name.c_str()); if (design->scratchpad_get_bool("abc9.verify")) { if (dff_mode) - abc9_script += "; verify -s"; + abc9_script += "; &verify -s"; else - abc9_script += "; verify"; + abc9_script += "; &verify"; } abc9_script += "; time"; abc9_script = add_echos_to_abc9_cmd(abc9_script); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 00af36615..8ae1b51ff 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -434,6 +434,9 @@ void prep_delays(RTLIL::Design *design, bool dff_mode) auto &t = timing.at(derived_type).required; for (auto &conn : cell->connections_) { auto port_wire = inst_module->wire(conn.first); + if (!port_wire) + log_error("Port %s in cell %s (type %s) of module %s does not actually exist", + log_id(conn.first), log_id(cell->name), log_id(cell->type), log_id(module->name)); if (!port_wire->port_input) continue; diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 0424ce434..35645582b 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -154,9 +154,11 @@ struct DffinitPass : public Pass { value = Const(low_string); } - log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second), - log_id(it.first), log_signal(sig), log_signal(value)); - cell->setParam(it.second, value); + if (value.size() != 0) { + log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second), + log_id(it.first), log_signal(sig), log_signal(value)); + cell->setParam(it.second, value); + } } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 518afa1a7..a554be257 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -1282,7 +1282,7 @@ struct TechmapPass : public Pass { if (fn.compare(0, 1, "%") == 0) { if (!saved_designs.count(fn.substr(1))) { delete map; - log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1); + log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1); } for (auto mod : saved_designs.at(fn.substr(1))->modules()) if (!map->has(mod->name)) |