diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ac970e2f1..134082585 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3106,7 +3106,7 @@ void RTLIL::Module::fixup_ports() RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) { - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = new RTLIL::Wire(Wire::ConstructToken{}); wire->name = std::move(name); wire->width = width; add(wire); @@ -3181,850 +3181,850 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return proc; } -#define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::A_SIGNED] = is_signed; \ - cell->parameters[ID::A_WIDTH] = sig_a.size(); \ - cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ - add ## _func(name, sig_a, sig_y, is_signed, src); \ - return sig_y; \ + #define DEF_METHOD(_func, _y_size, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::A_SIGNED] = is_signed; \ + cell->parameters[ID::A_WIDTH] = sig_a.size(); \ + cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ + add ## _func(name, sig_a, sig_y, is_signed, src); \ + return sig_y; \ + } + DEF_METHOD(Not, sig_a.size(), ID($not)) + DEF_METHOD(Pos, sig_a.size(), ID($pos)) + DEF_METHOD(Neg, sig_a.size(), ID($neg)) + DEF_METHOD(ReduceAnd, 1, ID($reduce_and)) + DEF_METHOD(ReduceOr, 1, ID($reduce_or)) + DEF_METHOD(ReduceXor, 1, ID($reduce_xor)) + DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor)) + DEF_METHOD(ReduceBool, 1, ID($reduce_bool)) + DEF_METHOD(LogicNot, 1, ID($logic_not)) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _y_size, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool /* is_signed */, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::WIDTH] = sig_a.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ + add ## _func(name, sig_a, sig_y, is_signed, src); \ + return sig_y; \ + } + DEF_METHOD(Buf, sig_a.size(), ID($buf)) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _y_size, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::A_SIGNED] = is_signed; \ + cell->parameters[ID::B_SIGNED] = is_signed; \ + cell->parameters[ID::A_WIDTH] = sig_a.size(); \ + cell->parameters[ID::B_WIDTH] = sig_b.size(); \ + cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ + add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ + return sig_y; \ + } + DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and)) + DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or)) + DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor)) + DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor)) + DEF_METHOD(Shift, sig_a.size(), ID($shift)) + DEF_METHOD(Lt, 1, ID($lt)) + DEF_METHOD(Le, 1, ID($le)) + DEF_METHOD(Eq, 1, ID($eq)) + DEF_METHOD(Ne, 1, ID($ne)) + DEF_METHOD(Eqx, 1, ID($eqx)) + DEF_METHOD(Nex, 1, ID($nex)) + DEF_METHOD(Ge, 1, ID($ge)) + DEF_METHOD(Gt, 1, ID($gt)) + DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), ID($add)) + DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub)) + DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul)) + DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div)) + DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod)) + DEF_METHOD(DivFloor, max(sig_a.size(), sig_b.size()), ID($divfloor)) + DEF_METHOD(ModFloor, max(sig_a.size(), sig_b.size()), ID($modfloor)) + DEF_METHOD(LogicAnd, 1, ID($logic_and)) + DEF_METHOD(LogicOr, 1, ID($logic_or)) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _y_size, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::A_SIGNED] = is_signed; \ + cell->parameters[ID::B_SIGNED] = false; \ + cell->parameters[ID::A_WIDTH] = sig_a.size(); \ + cell->parameters[ID::B_WIDTH] = sig_b.size(); \ + cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ + add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ + return sig_y; \ + } + DEF_METHOD(Shl, sig_a.size(), ID($shl)) + DEF_METHOD(Shr, sig_a.size(), ID($shr)) + DEF_METHOD(Sshl, sig_a.size(), ID($sshl)) + DEF_METHOD(Sshr, sig_a.size(), ID($sshr)) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _y_size, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::A_SIGNED] = false; \ + cell->parameters[ID::B_SIGNED] = is_signed; \ + cell->parameters[ID::A_WIDTH] = sig_a.size(); \ + cell->parameters[ID::B_WIDTH] = sig_b.size(); \ + cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ + add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ + return sig_y; \ + } + DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx)) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _type, _pmux) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::WIDTH] = sig_a.size(); \ + if (_pmux) cell->parameters[ID::S_WIDTH] = sig_s.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::S, sig_s); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, sig_a.size()); \ + add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \ + return sig_y; \ + } + DEF_METHOD(Mux, ID($mux), 0) + DEF_METHOD(Bwmux, ID($bwmux), 0) + DEF_METHOD(Pmux, ID($pmux), 1) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _type, _demux) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::WIDTH] = _demux ? sig_a.size() : sig_y.size(); \ + cell->parameters[ID::S_WIDTH] = sig_s.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::S, sig_s); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _demux ? sig_a.size() << sig_s.size() : sig_a.size() >> sig_s.size()); \ + add ## _func(name, sig_a, sig_s, sig_y, src); \ + return sig_y; \ + } + DEF_METHOD(Bmux, ID($bmux), 0) + DEF_METHOD(Demux, ID($demux), 1) + #undef DEF_METHOD + + #define DEF_METHOD(_func, _type) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->parameters[ID::WIDTH] = sig_a.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src) { \ + RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, sig_a.size()); \ + add ## _func(name, sig_a, sig_s, sig_y, src); \ + return sig_y; \ + } + DEF_METHOD(Bweqx, ID($bweqx)) + #undef DEF_METHOD + + #define DEF_METHOD_2(_func, _type, _P1, _P2) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const std::string &src) { \ + RTLIL::SigBit sig2 = static_cast(this)->addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, src); \ + return sig2; \ + } + #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ + RTLIL::SigBit sig3 = static_cast(this)->addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, src); \ + return sig3; \ + } + #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->setPort("\\" #_P4, sig4); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ + RTLIL::SigBit sig4 = static_cast(this)->addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, sig4, src); \ + return sig4; \ + } + #define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \ + template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const std::string &src) { \ + RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->setPort("\\" #_P4, sig4); \ + cell->setPort("\\" #_P5, sig5); \ + cell->set_src_attribute(src); \ + return cell; \ + } \ + template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ + RTLIL::SigBit sig5 = static_cast(this)->addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \ + return sig5; \ + } + DEF_METHOD_2(BufGate, ID($_BUF_), A, Y) + DEF_METHOD_2(NotGate, ID($_NOT_), A, Y) + DEF_METHOD_3(AndGate, ID($_AND_), A, B, Y) + DEF_METHOD_3(NandGate, ID($_NAND_), A, B, Y) + DEF_METHOD_3(OrGate, ID($_OR_), A, B, Y) + DEF_METHOD_3(NorGate, ID($_NOR_), A, B, Y) + DEF_METHOD_3(XorGate, ID($_XOR_), A, B, Y) + DEF_METHOD_3(XnorGate, ID($_XNOR_), A, B, Y) + DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y) + DEF_METHOD_3(OrnotGate, ID($_ORNOT_), A, B, Y) + DEF_METHOD_4(MuxGate, ID($_MUX_), A, B, S, Y) + DEF_METHOD_4(NmuxGate, ID($_NMUX_), A, B, S, Y) + DEF_METHOD_4(Aoi3Gate, ID($_AOI3_), A, B, C, Y) + DEF_METHOD_4(Oai3Gate, ID($_OAI3_), A, B, C, Y) + DEF_METHOD_5(Aoi4Gate, ID($_AOI4_), A, B, C, D, Y) + DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y) + #undef DEF_METHOD_2 + #undef DEF_METHOD_3 + #undef DEF_METHOD_4 + #undef DEF_METHOD_5 + + template RTLIL::Cell* CellAdderMixin::addPow(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($pow)); + cell->parameters[ID::A_SIGNED] = a_signed; + cell->parameters[ID::B_SIGNED] = b_signed; + cell->parameters[ID::A_WIDTH] = sig_a.size(); + cell->parameters[ID::B_WIDTH] = sig_b.size(); + cell->parameters[ID::Y_WIDTH] = sig_y.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Not, sig_a.size(), ID($not)) -DEF_METHOD(Pos, sig_a.size(), ID($pos)) -DEF_METHOD(Neg, sig_a.size(), ID($neg)) -DEF_METHOD(ReduceAnd, 1, ID($reduce_and)) -DEF_METHOD(ReduceOr, 1, ID($reduce_or)) -DEF_METHOD(ReduceXor, 1, ID($reduce_xor)) -DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor)) -DEF_METHOD(ReduceBool, 1, ID($reduce_bool)) -DEF_METHOD(LogicNot, 1, ID($logic_not)) -#undef DEF_METHOD -#define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool /* is_signed */, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::WIDTH] = sig_a.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ - add ## _func(name, sig_a, sig_y, is_signed, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addFa(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($fa)); + cell->parameters[ID::WIDTH] = sig_a.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::X, sig_x); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Buf, sig_a.size(), ID($buf)) -#undef DEF_METHOD -#define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::A_SIGNED] = is_signed; \ - cell->parameters[ID::B_SIGNED] = is_signed; \ - cell->parameters[ID::A_WIDTH] = sig_a.size(); \ - cell->parameters[ID::B_WIDTH] = sig_b.size(); \ - cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::B, sig_b); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ - add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addSlice(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($slice)); + cell->parameters[ID::A_WIDTH] = sig_a.size(); + cell->parameters[ID::Y_WIDTH] = sig_y.size(); + cell->parameters[ID::OFFSET] = offset; + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and)) -DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or)) -DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor)) -DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor)) -DEF_METHOD(Shift, sig_a.size(), ID($shift)) -DEF_METHOD(Lt, 1, ID($lt)) -DEF_METHOD(Le, 1, ID($le)) -DEF_METHOD(Eq, 1, ID($eq)) -DEF_METHOD(Ne, 1, ID($ne)) -DEF_METHOD(Eqx, 1, ID($eqx)) -DEF_METHOD(Nex, 1, ID($nex)) -DEF_METHOD(Ge, 1, ID($ge)) -DEF_METHOD(Gt, 1, ID($gt)) -DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), ID($add)) -DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub)) -DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul)) -DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div)) -DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod)) -DEF_METHOD(DivFloor, max(sig_a.size(), sig_b.size()), ID($divfloor)) -DEF_METHOD(ModFloor, max(sig_a.size(), sig_b.size()), ID($modfloor)) -DEF_METHOD(LogicAnd, 1, ID($logic_and)) -DEF_METHOD(LogicOr, 1, ID($logic_or)) -#undef DEF_METHOD -#define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::A_SIGNED] = is_signed; \ - cell->parameters[ID::B_SIGNED] = false; \ - cell->parameters[ID::A_WIDTH] = sig_a.size(); \ - cell->parameters[ID::B_WIDTH] = sig_b.size(); \ - cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::B, sig_b); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ - add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addConcat(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($concat)); + cell->parameters[ID::A_WIDTH] = sig_a.size(); + cell->parameters[ID::B_WIDTH] = sig_b.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Shl, sig_a.size(), ID($shl)) -DEF_METHOD(Shr, sig_a.size(), ID($shr)) -DEF_METHOD(Sshl, sig_a.size(), ID($sshl)) -DEF_METHOD(Sshr, sig_a.size(), ID($sshr)) -#undef DEF_METHOD -#define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::A_SIGNED] = false; \ - cell->parameters[ID::B_SIGNED] = is_signed; \ - cell->parameters[ID::A_WIDTH] = sig_a.size(); \ - cell->parameters[ID::B_WIDTH] = sig_b.size(); \ - cell->parameters[ID::Y_WIDTH] = sig_y.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::B, sig_b); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ - add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addLut(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($lut)); + cell->parameters[ID::LUT] = lut; + cell->parameters[ID::WIDTH] = sig_a.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx)) -#undef DEF_METHOD -#define DEF_METHOD(_func, _type, _pmux) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::WIDTH] = sig_a.size(); \ - if (_pmux) cell->parameters[ID::S_WIDTH] = sig_s.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::B, sig_b); \ - cell->setPort(ID::S, sig_s); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \ - add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addTribuf(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($tribuf)); + cell->parameters[ID::WIDTH] = sig_a.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Mux, ID($mux), 0) -DEF_METHOD(Bwmux, ID($bwmux), 0) -DEF_METHOD(Pmux, ID($pmux), 1) -#undef DEF_METHOD -#define DEF_METHOD(_func, _type, _demux) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::WIDTH] = _demux ? sig_a.size() : sig_y.size(); \ - cell->parameters[ID::S_WIDTH] = sig_s.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::S, sig_s); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, _demux ? sig_a.size() << sig_s.size() : sig_a.size() >> sig_s.size()); \ - add ## _func(name, sig_a, sig_s, sig_y, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addAssert(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($assert)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Bmux, ID($bmux), 0) -DEF_METHOD(Demux, ID($demux), 1) -#undef DEF_METHOD -#define DEF_METHOD(_func, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters[ID::WIDTH] = sig_a.size(); \ - cell->setPort(ID::A, sig_a); \ - cell->setPort(ID::B, sig_b); \ - cell->setPort(ID::Y, sig_y); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \ - add ## _func(name, sig_a, sig_s, sig_y, src); \ - return sig_y; \ + template RTLIL::Cell* CellAdderMixin::addAssume(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($assume)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD(Bweqx, ID($bweqx)) -#undef DEF_METHOD -#define DEF_METHOD_2(_func, _type, _P1, _P2) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const std::string &src) { \ - RTLIL::SigBit sig2 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, src); \ - return sig2; \ + template RTLIL::Cell* CellAdderMixin::addLive(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($live)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->set_src_attribute(src); + return cell; } -#define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->setPort("\\" #_P3, sig3); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ - RTLIL::SigBit sig3 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, sig3, src); \ - return sig3; \ + + template RTLIL::Cell* CellAdderMixin::addFair(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($fair)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->set_src_attribute(src); + return cell; } -#define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->setPort("\\" #_P3, sig3); \ - cell->setPort("\\" #_P4, sig4); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ - RTLIL::SigBit sig4 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, sig3, sig4, src); \ - return sig4; \ + + template RTLIL::Cell* CellAdderMixin::addCover(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($cover)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::EN, sig_en); + cell->set_src_attribute(src); + return cell; } -#define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const std::string &src) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->setPort("\\" #_P3, sig3); \ - cell->setPort("\\" #_P4, sig4); \ - cell->setPort("\\" #_P5, sig5); \ - cell->set_src_attribute(src); \ - return cell; \ - } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ - RTLIL::SigBit sig5 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \ - return sig5; \ + + template RTLIL::Cell* CellAdderMixin::addEquiv(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($equiv)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; } -DEF_METHOD_2(BufGate, ID($_BUF_), A, Y) -DEF_METHOD_2(NotGate, ID($_NOT_), A, Y) -DEF_METHOD_3(AndGate, ID($_AND_), A, B, Y) -DEF_METHOD_3(NandGate, ID($_NAND_), A, B, Y) -DEF_METHOD_3(OrGate, ID($_OR_), A, B, Y) -DEF_METHOD_3(NorGate, ID($_NOR_), A, B, Y) -DEF_METHOD_3(XorGate, ID($_XOR_), A, B, Y) -DEF_METHOD_3(XnorGate, ID($_XNOR_), A, B, Y) -DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y) -DEF_METHOD_3(OrnotGate, ID($_ORNOT_), A, B, Y) -DEF_METHOD_4(MuxGate, ID($_MUX_), A, B, S, Y) -DEF_METHOD_4(NmuxGate, ID($_NMUX_), A, B, S, Y) -DEF_METHOD_4(Aoi3Gate, ID($_AOI3_), A, B, C, Y) -DEF_METHOD_4(Oai3Gate, ID($_OAI3_), A, B, C, Y) -DEF_METHOD_5(Aoi4Gate, ID($_AOI4_), A, B, C, D, Y) -DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y) -#undef DEF_METHOD_2 -#undef DEF_METHOD_3 -#undef DEF_METHOD_4 -#undef DEF_METHOD_5 -RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($pow)); - cell->parameters[ID::A_SIGNED] = a_signed; - cell->parameters[ID::B_SIGNED] = b_signed; - cell->parameters[ID::A_WIDTH] = sig_a.size(); - cell->parameters[ID::B_WIDTH] = sig_b.size(); - cell->parameters[ID::Y_WIDTH] = sig_y.size(); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::B, sig_b); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSr(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sr)); + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addFa(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($fa)); - cell->parameters[ID::WIDTH] = sig_a.size(); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::B, sig_b); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::X, sig_x); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addFf(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($ff)); + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($slice)); - cell->parameters[ID::A_WIDTH] = sig_a.size(); - cell->parameters[ID::Y_WIDTH] = sig_y.size(); - cell->parameters[ID::OFFSET] = offset; - cell->setPort(ID::A, sig_a); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($concat)); - cell->parameters[ID::A_WIDTH] = sig_a.size(); - cell->parameters[ID::B_WIDTH] = sig_b.size(); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::B, sig_b); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($lut)); - cell->parameters[ID::LUT] = lut; - cell->parameters[ID::WIDTH] = sig_a.size(); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffsr)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($tribuf)); - cell->parameters[ID::WIDTH] = sig_a.size(); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffsre(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffsre)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($assert)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($assume)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($live)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAldff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($aldff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::ALOAD, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($fair)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAldffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($aldffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ALOAD, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($cover)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::EN, sig_en); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($equiv)); - cell->setPort(ID::A, sig_a); - cell->setPort(ID::B, sig_b); - cell->setPort(ID::Y, sig_y); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($sr)); - cell->parameters[ID::SET_POLARITY] = set_polarity; - cell->parameters[ID::CLR_POLARITY] = clr_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::SET, sig_set); - cell->setPort(ID::CLR, sig_clr); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdffce(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdffce)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($ff)); - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dlatch)); + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dff)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool en_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adlatch)); + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dffe)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dlatchsr)); + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dffsr)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::SET_POLARITY] = set_polarity; - cell->parameters[ID::CLR_POLARITY] = clr_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::SET, sig_set); - cell->setPort(ID::CLR, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDffsre(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dffsre)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::SET_POLARITY] = set_polarity; - cell->parameters[ID::CLR_POLARITY] = clr_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::SET, sig_set); - cell->setPort(ID::CLR, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($_FF_)); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($adff)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::ARST_POLARITY] = arst_polarity; - cell->parameters[ID::ARST_VALUE] = arst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::ARST, sig_arst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($adffe)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::ARST_POLARITY] = arst_polarity; - cell->parameters[ID::ARST_VALUE] = arst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::ARST, sig_arst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAldff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($aldff)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::ALOAD, sig_aload); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::AD, sig_ad); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAldffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($aldffe)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::ALOAD, sig_aload); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::AD, sig_ad); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDffsreGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($sdff)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::SRST_POLARITY] = srst_polarity; - cell->parameters[ID::SRST_VALUE] = srst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::SRST, sig_srst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($sdffe)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::SRST_POLARITY] = srst_polarity; - cell->parameters[ID::SRST_VALUE] = srst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::SRST, sig_srst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSdffce(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($sdffce)); - cell->parameters[ID::CLK_POLARITY] = clk_polarity; - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::SRST_POLARITY] = srst_polarity; - cell->parameters[ID::SRST_VALUE] = srst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::CLK, sig_clk); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::SRST, sig_srst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAldffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::L, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dlatch)); - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAldffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::L, sig_aload); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addAdlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const arst_value, bool en_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($adlatch)); - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::ARST_POLARITY] = arst_polarity; - cell->parameters[ID::ARST_VALUE] = arst_value; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::ARST, sig_arst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($dlatchsr)); - cell->parameters[ID::EN_POLARITY] = en_polarity; - cell->parameters[ID::SET_POLARITY] = set_polarity; - cell->parameters[ID::CLR_POLARITY] = clr_polarity; - cell->parameters[ID::WIDTH] = sig_q.size(); - cell->setPort(ID::EN, sig_en); - cell->setPort(ID::SET, sig_set); - cell->setPort(ID::CLR, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->setPort(ID::S, sig_set); - cell->setPort(ID::R, sig_clr); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addSdffceGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, ID($_FF_)); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool en_polarity, bool arst_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } -RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::S, sig_set); - cell->setPort(ID::R, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addDffsreGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::S, sig_set); - cell->setPort(ID::R, sig_clr); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::R, sig_arst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::R, sig_arst); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addAldffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::L, sig_aload); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::AD, sig_ad); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addAldffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::L, sig_aload); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::AD, sig_ad); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::R, sig_srst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addSdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::R, sig_srst); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addSdffceGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); - cell->setPort(ID::C, sig_clk); - cell->setPort(ID::R, sig_srst); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - bool arst_value, bool en_polarity, bool arst_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::R, sig_arst); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} - -RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) -{ - RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->setPort(ID::E, sig_en); - cell->setPort(ID::S, sig_set); - cell->setPort(ID::R, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->set_src_attribute(src); - return cell; -} + template RTLIL::Cell* CellAdderMixin::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) + { + RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; + } RTLIL::Cell* RTLIL::Module::addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) { @@ -4166,7 +4166,7 @@ std::string RTLIL::Module::to_rtlil_str() const return f.str(); } -RTLIL::Wire::Wire() +RTLIL::Wire::Wire(ConstructToken) { static unsigned int hashidx_count = 123456789; hashidx_count = mkhash_xorshift(hashidx_count); @@ -4243,7 +4243,7 @@ std::string RTLIL::Process::to_rtlil_str() const return f.str(); } -RTLIL::Cell::Cell(RTLIL::Cell::ConstructToken) : module(nullptr) +RTLIL::Cell::Cell(ConstructToken) : module(nullptr) { static unsigned int hashidx_count = 123456789; hashidx_count = mkhash_xorshift(hashidx_count); @@ -4460,6 +4460,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) check(); } +bool RTLIL::Cell::has_keep_attr() const { + return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) && + module->design->module(type)->get_bool_attribute(ID::keep)); +} + bool RTLIL::Cell::has_memid() const { return type.in(ID($memwr), ID($memwr_v2), ID($memrd), ID($memrd_v2), ID($meminit), ID($meminit_v2)); @@ -5938,4 +5943,7 @@ std::map *RTLIL::Memory::get_all_memorys(void) return &all_memorys; } #endif + +template class CellAdderMixin; + YOSYS_NAMESPACE_END diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d21e0cd56..413a8477c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -2063,7 +2063,195 @@ struct RTLIL::Design std::string to_rtlil_str(bool only_selected = true) const; }; -struct RTLIL::Module : public RTLIL::NamedObject +namespace RTLIL_BACKEND { +void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); +} + +struct RTLIL::Wire : public RTLIL::NamedObject +{ +private: + struct ConstructToken { explicit ConstructToken() = default; }; + friend struct RTLIL::Design; + friend struct RTLIL::Cell; + friend struct RTLIL::Module; + friend struct RTLIL::Patch; +public: + Hasher::hash_t hashidx_; + [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } + // use module->addWire() and module->remove() to create or destroy wires + Wire(ConstructToken); + ~Wire(); + + friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); + RTLIL::Cell *driverCell_ = nullptr; + RTLIL::IdString driverPort_; + + // do not simply copy wires + Wire(ConstructToken, RTLIL::Wire &other); + void operator=(RTLIL::Wire &other) = delete; + + RTLIL::Module *module; + int width, start_offset, port_id; + bool port_input, port_output, upto, is_signed; + + bool known_driver() const { return driverCell_ != nullptr; } + + RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; }; + RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; }; + + int from_hdl_index(int hdl_index) { + int zero_index = hdl_index - start_offset; + int rtlil_index = upto ? width - 1 - zero_index : zero_index; + return rtlil_index >= 0 && rtlil_index < width ? rtlil_index : INT_MIN; + } + + int to_hdl_index(int rtlil_index) { + if (rtlil_index < 0 || rtlil_index >= width) + return INT_MIN; + int zero_index = upto ? width - 1 - rtlil_index : rtlil_index; + return zero_index + start_offset; + } + + std::string to_rtlil_str() const; + +#ifdef YOSYS_ENABLE_PYTHON + static std::map *get_all_wires(void); +#endif +}; + +inline int GetSize(RTLIL::Wire *wire) { + return wire->width; +} + +struct RTLIL::Memory : public RTLIL::NamedObject +{ + Hasher::hash_t hashidx_; + [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } + + Memory(); + + int width, start_offset, size; +#ifdef YOSYS_ENABLE_PYTHON + ~Memory(); + static std::map *get_all_memorys(void); +#endif + + std::string to_rtlil_str() const; +}; + +struct RTLIL::Cell : public RTLIL::NamedObject +{ +private: + struct ConstructToken { explicit ConstructToken() = default; }; + friend struct RTLIL::Module; + friend struct RTLIL::Patch; +public: + Hasher::hash_t hashidx_; + [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } + + // use module->addCell() and module->remove() to create or destroy cells + Cell(ConstructToken); + ~Cell(); + + // do not simply copy cells + Cell(ConstructToken, RTLIL::Cell &other); + void operator=(RTLIL::Cell &other) = delete; + + RTLIL::Module *module; + RTLIL::IdString type; + dict connections_; + dict parameters; + + // access cell ports + bool hasPort(RTLIL::IdString portname) const; + void unsetPort(RTLIL::IdString portname); + void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal); + const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const; + const dict &connections() const; + + // information about cell ports + bool known() const; + bool input(RTLIL::IdString portname) const; + bool output(RTLIL::IdString portname) const; + PortDir port_dir(RTLIL::IdString portname) const; + + // access cell parameters + bool hasParam(RTLIL::IdString paramname) const; + void unsetParam(RTLIL::IdString paramname); + void setParam(RTLIL::IdString paramname, RTLIL::Const value); + const RTLIL::Const &getParam(RTLIL::IdString paramname) const; + + void sort(); + void check(); + void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); + + bool has_keep_attr() const; + + template void rewrite_sigspecs(T &functor); + template void rewrite_sigspecs2(T &functor); + +#ifdef YOSYS_ENABLE_PYTHON + static std::map *get_all_cells(void); +#endif + + bool has_memid() const; + bool is_mem_cell() const; + bool is_builtin_ff() const; + + std::string to_rtlil_str() const; +}; + +struct RTLIL::CaseRule : public RTLIL::AttrObject +{ + std::vector compare; + std::vector actions; + std::vector switches; + + ~CaseRule(); + + bool empty() const; + + template void rewrite_sigspecs(T &functor); + template void rewrite_sigspecs2(T &functor); + RTLIL::CaseRule *clone() const; +}; + +struct RTLIL::SwitchRule : public RTLIL::AttrObject +{ + RTLIL::SigSpec signal; + std::vector cases; + + ~SwitchRule(); + + bool empty() const; + + template void rewrite_sigspecs(T &functor); + template void rewrite_sigspecs2(T &functor); + RTLIL::SwitchRule *clone() const; +}; + +struct RTLIL::MemWriteAction : RTLIL::AttrObject +{ + RTLIL::IdString memid; + RTLIL::SigSpec address; + RTLIL::SigSpec data; + RTLIL::SigSpec enable; + RTLIL::Const priority_mask; +}; + +struct RTLIL::SyncRule +{ + RTLIL::SyncType type; + RTLIL::SigSpec signal; + std::vector actions; + std::vector mem_write_actions; + + template void rewrite_sigspecs(T &functor); + template void rewrite_sigspecs2(T &functor); + RTLIL::SyncRule *clone() const; +}; + +struct RTLIL::Process : public RTLIL::NamedObject { friend struct RTLIL::SigNormIndex; friend struct RTLIL::Cell; @@ -2073,153 +2261,113 @@ struct RTLIL::Module : public RTLIL::NamedObject [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } protected: - void add(RTLIL::Wire *wire); - void add(RTLIL::Cell *cell); - void add(RTLIL::Process *process); + // use module->addProcess() and module->remove() to create or destroy processes + friend struct RTLIL::Module; + Process(); + ~Process(); public: - RTLIL::Design *design; - pool monitors; - - int refcount_wires_; - int refcount_cells_; - - dict wires_; - dict cells_; - - std::vector connections_; - std::vector bindings_; - - idict avail_parameters; - dict parameter_default_values; - dict memories; - dict processes; - - Module(); - virtual ~Module(); - virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail = false); - virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); - virtual size_t count_id(RTLIL::IdString id); - virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); - virtual bool reprocess_if_necessary(RTLIL::Design *design); - - virtual void sort(); - virtual void check(); - virtual void optimize(); - virtual void makeblackbox(); - - bool get_blackbox_attribute(bool ignore_wb=false) const { - return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); - } - - void connect(const RTLIL::SigSig &conn); - void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); - void new_connections(const std::vector &new_conn); - const std::vector &connections() const; - - std::vector ports; - void fixup_ports(); - - pool buf_norm_cell_queue; - pool> buf_norm_cell_port_queue; - pool buf_norm_wire_queue; - pool pending_deleted_cells; - dict> buf_norm_connect_index; - void bufNormalize(); - void dump_sigmap(); - -protected: - SigNormIndex *sig_norm_index = nullptr; - void clear_sig_norm_index(); - int timestamp_ = 0; -public: - void sigNormalize(); - - int timestamp() const { return timestamp_; } - int next_timestamp(); - std::vector dirty_cells(int starting_from); - const pool &fanout(SigBit bit); - const dict> &signorm_fanout() const; + RTLIL::Module *module; + RTLIL::CaseRule root_case; + std::vector syncs; template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); - void cloneInto(RTLIL::Module *new_mod) const; - virtual RTLIL::Module *clone() const; + RTLIL::Process *clone() const; - bool has_memories() const; - bool has_processes() const; + std::string to_rtlil_str() const; +}; - bool has_memories_warn() const; - bool has_processes_warn() const; +struct RTLIL::PortBit +{ + RTLIL::Cell *cell; + RTLIL::IdString port; + int offset; + PortBit(Cell* c, IdString p, int o) : cell(c), port(p), offset(o) {} - bool is_selected() const; - bool is_selected_whole() const; - - std::vector selected_wires() const; - std::vector selected_cells() const; - std::vector selected_memories() const; - std::vector selected_processes() const; - std::vector selected_members() const; - - template bool selected(T *member) const { - return design->selected_member(name, member->name); + bool operator<(const PortBit &other) const { + if (cell != other.cell) + return cell < other.cell; + if (port != other.port) + return port < other.port; + return offset < other.offset; } - RTLIL::Wire* wire(RTLIL::IdString id) { - auto it = wires_.find(id); - return it == wires_.end() ? nullptr : it->second; - } - RTLIL::Cell* cell(RTLIL::IdString id) { - auto it = cells_.find(id); - return it == cells_.end() ? nullptr : it->second; + bool operator==(const PortBit &other) const { + return cell == other.cell && port == other.port && offset == other.offset; } - const RTLIL::Wire* wire(RTLIL::IdString id) const{ - auto it = wires_.find(id); - return it == wires_.end() ? nullptr : it->second; + [[nodiscard]] Hasher hash_into(Hasher h) const { + h.eat(cell->name); + h.eat(port); + h.eat(offset); + return h; } - const RTLIL::Cell* cell(RTLIL::IdString id) const { - auto it = cells_.find(id); - return it == cells_.end() ? nullptr : it->second; +}; + +inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } +inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } +inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { } +inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } +inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } +inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } +inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } + +inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { + if (wire == other.wire) + return wire ? (offset < other.offset) : (data < other.data); + if (wire != nullptr && other.wire != nullptr) + return wire->name < other.wire->name; + return (wire != nullptr) < (other.wire != nullptr); +} + +inline bool RTLIL::SigBit::operator==(const RTLIL::SigBit &other) const { + return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data)); +} + +inline bool RTLIL::SigBit::operator!=(const RTLIL::SigBit &other) const { + return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); +} + +inline Hasher RTLIL::SigBit::hash_into(Hasher h) const { + if (wire) { + h.eat(offset); + h.eat(wire->name); + return h; } + h.eat(data); + return h; +} - RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } - int wires_size() const { return wires_.size(); } - RTLIL::Wire* wire_at(int index) const { return wires_.element(index)->second; } - RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } - int cells_size() const { return cells_.size(); } - RTLIL::Cell* cell_at(int index) const { return cells_.element(index)->second; } - void add(RTLIL::Binding *binding); +inline Hasher RTLIL::SigBit::hash_top() const { + Hasher h; + if (wire) { + h.force(hashlib::legacy::djb2_add(wire->name.index_, offset)); + return h; + } + h.force(data); + return h; +} - // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const pool &wires); - void remove(RTLIL::Cell *cell); - void remove(RTLIL::Memory *memory); - void remove(RTLIL::Process *process); +inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { + return (*sig_p)[index]; +} - void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); - void rename(RTLIL::Cell *cell, RTLIL::IdString new_name); - void rename(RTLIL::IdString old_name, RTLIL::IdString new_name); +inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() { + bit = (*sig_p)[index]; + return bit; +} - void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2); - void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); - - RTLIL::IdString uniquify(RTLIL::IdString name); - RTLIL::IdString uniquify(RTLIL::IdString name, int &index); - - RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); - RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); - - RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); - RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); - - RTLIL::Memory *addMemory(RTLIL::IdString name); - RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other); - - RTLIL::Process *addProcess(RTLIL::IdString name); - RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other); +inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { + log_assert(sig.size() == 1); + auto it = sig.chunks().begin(); + *this = SigBit(*it); +} +template +class CellAdderMixin { +public: // The add* methods create a cell and return the created cell. All signals must exist in advance. RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); @@ -2428,6 +2576,170 @@ public: RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = ""); RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = ""); RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = ""); +}; + +struct RTLIL::Module : public RTLIL::NamedObject, public CellAdderMixin +{ + friend struct RTLIL::SigNormIndex; + friend struct RTLIL::Cell; + friend struct RTLIL::Design; + + Hasher::hash_t hashidx_; + [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } + +protected: + void add(RTLIL::Wire *wire); + void add(RTLIL::Cell *cell); + void add(RTLIL::Process *process); + +public: + RTLIL::Design *design; + pool monitors; + + int refcount_wires_; + int refcount_cells_; + + dict wires_; + dict cells_; + + std::vector connections_; + std::vector bindings_; + + idict avail_parameters; + dict parameter_default_values; + dict memories; + dict processes; + + Module(); + virtual ~Module(); + virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail = false); + virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); + virtual size_t count_id(RTLIL::IdString id); + virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); + virtual bool reprocess_if_necessary(RTLIL::Design *design); + + virtual void sort(); + virtual void check(); + virtual void optimize(); + virtual void makeblackbox(); + + bool get_blackbox_attribute(bool ignore_wb=false) const { + return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); + } + + void connect(const RTLIL::SigSig &conn); + void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); + void new_connections(const std::vector &new_conn); + const std::vector &connections() const; + + std::vector ports; + void fixup_ports(); + + pool buf_norm_cell_queue; + pool> buf_norm_cell_port_queue; + pool buf_norm_wire_queue; + pool pending_deleted_cells; + dict> buf_norm_connect_index; + void bufNormalize(); + void dump_sigmap(); + +protected: + SigNormIndex *sig_norm_index = nullptr; + void clear_sig_norm_index(); + int timestamp_ = 0; +public: + void sigNormalize(); + + int timestamp() const { return timestamp_; } + int next_timestamp(); + std::vector dirty_cells(int starting_from); + const pool &fanout(SigBit bit); + const dict> &signorm_fanout() const; + + template void rewrite_sigspecs(T &functor); + template void rewrite_sigspecs2(T &functor); + void cloneInto(RTLIL::Module *new_mod) const; + virtual RTLIL::Module *clone() const; + + bool has_memories() const; + bool has_processes() const; + + bool has_memories_warn() const; + bool has_processes_warn() const; + + bool is_selected() const; + bool is_selected_whole() const; + + std::vector selected_wires() const; + std::vector selected_cells() const; + std::vector selected_memories() const; + std::vector selected_processes() const; + std::vector selected_members() const; + + template bool selected(T *member) const { + return design->selected_member(name, member->name); + } + + RTLIL::Wire* wire(const RTLIL::IdString &id) { + auto it = wires_.find(id); + return it == wires_.end() ? nullptr : it->second; + } + RTLIL::Cell* cell(const RTLIL::IdString &id) { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } + + const RTLIL::Wire* wire(const RTLIL::IdString &id) const{ + auto it = wires_.find(id); + return it == wires_.end() ? nullptr : it->second; + } + const RTLIL::Cell* cell(const RTLIL::IdString &id) const { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } + + RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } + int wires_size() const { return wires_.size(); } + RTLIL::Wire* wire_at(int index) const { return wires_.element(index)->second; } + RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + int cells_size() const { return cells_.size(); } + RTLIL::Cell* cell_at(int index) const { return cells_.element(index)->second; } + + void add(RTLIL::Binding *binding); + + // Removing wires is expensive. If you have to remove wires, remove them all at once. + void remove(const pool &wires); + void remove(RTLIL::Cell *cell); + void remove(RTLIL::Memory *memory); + void remove(RTLIL::Process *process); + + void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); + void rename(RTLIL::Cell *cell, RTLIL::IdString new_name); + void rename(RTLIL::IdString old_name, RTLIL::IdString new_name); + + void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2); + void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); + + RTLIL::IdString uniquify(RTLIL::IdString name); + RTLIL::IdString uniquify(RTLIL::IdString name, int &index); + + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); + RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); + + RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); + RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); + + RTLIL::Memory *addMemory(RTLIL::IdString name); + RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other); + + RTLIL::Process *addProcess(RTLIL::IdString name); + RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other); + + // The add* methods create a cell and return the created cell. All signals must exist in advance. + + RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); + + // The methods without the add* prefix create a cell and an output signal. They return the newly created output signal. RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); @@ -2448,308 +2760,6 @@ public: #endif }; -namespace RTLIL_BACKEND { -void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); -} - -struct RTLIL::Wire : public RTLIL::NamedObject -{ -private: - struct ConstructToken { explicit ConstructToken() = default; }; - friend struct RTLIL::Design; - friend struct RTLIL::Cell; - friend struct RTLIL::Module; - friend struct RTLIL::Patch; -public: - Hasher::hash_t hashidx_; - [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } - // use module->addWire() and module->remove() to create or destroy wires - friend struct RTLIL::SigNormIndex; - Wire(); - ~Wire(); - - friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); - RTLIL::Cell *driverCell_ = nullptr; - RTLIL::IdString driverPort_; - -public: - // do not simply copy wires - Wire(RTLIL::Wire &other) = delete; - void operator=(RTLIL::Wire &other) = delete; - - RTLIL::Module *module; - int width, start_offset, port_id; - bool port_input, port_output, upto, is_signed; - - bool known_driver() const { return driverCell_ != nullptr; } - - RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; }; - RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; }; - - int from_hdl_index(int hdl_index) { - int zero_index = hdl_index - start_offset; - int rtlil_index = upto ? width - 1 - zero_index : zero_index; - return rtlil_index >= 0 && rtlil_index < width ? rtlil_index : INT_MIN; - } - - int to_hdl_index(int rtlil_index) { - if (rtlil_index < 0 || rtlil_index >= width) - return INT_MIN; - int zero_index = upto ? width - 1 - rtlil_index : rtlil_index; - return zero_index + start_offset; - } - - std::string to_rtlil_str() const; -#ifdef YOSYS_ENABLE_PYTHON - static std::map *get_all_wires(void); -#endif -}; - -inline int GetSize(RTLIL::Wire *wire) { - return wire->width; -} - -struct RTLIL::Memory : public RTLIL::NamedObject -{ - Hasher::hash_t hashidx_; - [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } - - Memory(); - - int width, start_offset, size; - - std::string to_rtlil_str() const; -#ifdef YOSYS_ENABLE_PYTHON - ~Memory(); - static std::map *get_all_memorys(void); -#endif -}; - -struct RTLIL::Cell : public RTLIL::NamedObject -{ -private: - struct ConstructToken { explicit ConstructToken() = default; }; - friend struct RTLIL::Module; - friend struct RTLIL::Patch; -public: - Hasher::hash_t hashidx_; - [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } - - // use module->addCell() and module->remove() to create or destroy cells - Cell(ConstructToken); - ~Cell(); - - // do not simply copy cells - Cell(ConstructToken, RTLIL::Cell &other); - void operator=(RTLIL::Cell &other) = delete; - - RTLIL::Module *module; - RTLIL::IdString type; - dict connections_; - dict parameters; - - // access cell ports - bool hasPort(RTLIL::IdString portname) const; - void unsetPort(RTLIL::IdString portname); - void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal); - const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const; - const dict &connections() const; - - // information about cell ports - bool known() const; - bool input(RTLIL::IdString portname) const; - bool output(RTLIL::IdString portname) const; - PortDir port_dir(RTLIL::IdString portname) const; - - // access cell parameters - bool hasParam(RTLIL::IdString paramname) const; - void unsetParam(RTLIL::IdString paramname); - void setParam(RTLIL::IdString paramname, RTLIL::Const value); - const RTLIL::Const &getParam(RTLIL::IdString paramname) const; - - void sort(); - void check(); - void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); - - bool has_keep_attr() const { - return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) && - module->design->module(type)->get_bool_attribute(ID::keep)); - } - - template void rewrite_sigspecs(T &functor); - template void rewrite_sigspecs2(T &functor); - - std::string to_rtlil_str() const; - -#ifdef YOSYS_ENABLE_PYTHON - static std::map *get_all_cells(void); -#endif - - bool has_memid() const; - bool is_mem_cell() const; - bool is_builtin_ff() const; -}; - -struct RTLIL::CaseRule : public RTLIL::AttrObject -{ - std::vector compare; - std::vector actions; - std::vector switches; - - ~CaseRule(); - - bool empty() const; - - template void rewrite_sigspecs(T &functor); - template void rewrite_sigspecs2(T &functor); - RTLIL::CaseRule *clone() const; -}; - -struct RTLIL::SwitchRule : public RTLIL::AttrObject -{ - RTLIL::SigSpec signal; - std::vector cases; - - ~SwitchRule(); - - bool empty() const; - - template void rewrite_sigspecs(T &functor); - template void rewrite_sigspecs2(T &functor); - RTLIL::SwitchRule *clone() const; -}; - -struct RTLIL::MemWriteAction : RTLIL::AttrObject -{ - RTLIL::IdString memid; - RTLIL::SigSpec address; - RTLIL::SigSpec data; - RTLIL::SigSpec enable; - RTLIL::Const priority_mask; -}; - -struct RTLIL::SyncRule -{ - RTLIL::SyncType type; - RTLIL::SigSpec signal; - std::vector actions; - std::vector mem_write_actions; - - template void rewrite_sigspecs(T &functor); - template void rewrite_sigspecs2(T &functor); - RTLIL::SyncRule *clone() const; -}; - -struct RTLIL::Process : public RTLIL::NamedObject -{ - Hasher::hash_t hashidx_; - [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } - -protected: - // use module->addProcess() and module->remove() to create or destroy processes - friend struct RTLIL::Module; - Process(); - ~Process(); - -public: - RTLIL::Module *module; - RTLIL::CaseRule root_case; - std::vector syncs; - - template void rewrite_sigspecs(T &functor); - template void rewrite_sigspecs2(T &functor); - RTLIL::Process *clone() const; - std::string to_rtlil_str() const; -}; - -struct RTLIL::PortBit -{ - RTLIL::Cell *cell; - RTLIL::IdString port; - int offset; - PortBit(Cell* c, IdString p, int o) : cell(c), port(p), offset(o) {} - - bool operator<(const PortBit &other) const { - if (cell != other.cell) - return cell < other.cell; - if (port != other.port) - return port < other.port; - return offset < other.offset; - } - - bool operator==(const PortBit &other) const { - return cell == other.cell && port == other.port && offset == other.offset; - } - - [[nodiscard]] Hasher hash_into(Hasher h) const { - h.eat(cell->name); - h.eat(port); - h.eat(offset); - return h; - } -}; - - -inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } -inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } -inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { } -inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } -inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } -inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } -inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } - -inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { - if (wire == other.wire) - return wire ? (offset < other.offset) : (data < other.data); - if (wire != nullptr && other.wire != nullptr) - return wire->name < other.wire->name; - return (wire != nullptr) < (other.wire != nullptr); -} - -inline bool RTLIL::SigBit::operator==(const RTLIL::SigBit &other) const { - return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data)); -} - -inline bool RTLIL::SigBit::operator!=(const RTLIL::SigBit &other) const { - return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); -} - -inline Hasher RTLIL::SigBit::hash_into(Hasher h) const { - if (wire) { - h.eat(offset); - h.eat(wire->name); - return h; - } - h.eat(data); - return h; -} - - -inline Hasher RTLIL::SigBit::hash_top() const { - Hasher h; - if (wire) { - h.force(hashlib::legacy::djb2_add(wire->name.index_, offset)); - return h; - } - h.force(data); - return h; -} - -inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { - return (*sig_p)[index]; -} - -inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() { - bit = (*sig_p)[index]; - return bit; -} - -inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { - log_assert(sig.size() == 1); - auto it = sig.chunks().begin(); - *this = SigBit(*it); -} - template void RTLIL::Module::rewrite_sigspecs(T &functor) { diff --git a/kernel/unstable/patch.cc b/kernel/unstable/patch.cc index 33bbb9777..e1ca2aa96 100644 --- a/kernel/unstable/patch.cc +++ b/kernel/unstable/patch.cc @@ -5,40 +5,50 @@ YOSYS_NAMESPACE_BEGIN /** - * Notes - * - * If we want GC, we need more indices - * namely user count (and users?). This should be optional - * - * +* Notes +* +* If we want GC, we need more indices +* namely user count (and users?). This should be optional +* +* */ using namespace RTLIL; + +template class CellAdderMixin; + Cell* Patch::addCell(IdString name, IdString type) { - auto& cell = cells_.emplace_back(Cell::ConstructToken{}); + auto& cell = cells_.emplace_back(Cell::ConstructToken{}); cell.name = std::move(name); cell.type = type; - return &cell; + return &cell; +} + +Wire* Patch::addWire(IdString name, int width) { + (void)name; + (void)width; + log_assert(false); + return nullptr; } void Patch::patch() { - for (auto& cell: cells_) { - Cell* new_cell = mod->addCell(cell.name, &cell); - for (auto [port_name, sig] : new_cell->connections()) { - log_assert(yosys_celltypes.cell_known(cell.type)); - auto dir = cell.port_dir(port_name); - if (dir == PD_OUTPUT || dir == PD_INOUT) { - for (auto chunk : sig.chunks()) { - log_assert(chunk.is_wire()); - auto* wire = chunk.wire; - // Unwire old driver - wire->driverCell_->setPort(wire->driverPort_, SigSpec()); - // Maintain bufnorm - wire->driverCell_ = new_cell; - wire->driverPort_ = port_name; - } - } - } - } + for (auto& cell: cells_) { + Cell* new_cell = mod->addCell(cell.name, &cell); + for (auto [port_name, sig] : new_cell->connections()) { + log_assert(yosys_celltypes.cell_known(cell.type)); + auto dir = cell.port_dir(port_name); + if (dir == PD_OUTPUT || dir == PD_INOUT) { + for (auto chunk : sig.chunks()) { + log_assert(chunk.is_wire()); + auto* wire = chunk.wire; + // Unwire old driver + wire->driverCell_->setPort(wire->driverPort_, SigSpec()); + // Maintain bufnorm + wire->driverCell_ = new_cell; + wire->driverPort_ = port_name; + } + } + } + } } diff --git a/kernel/unstable/patch.h b/kernel/unstable/patch.h index 150ca379a..287a739d6 100644 --- a/kernel/unstable/patch.h +++ b/kernel/unstable/patch.h @@ -6,7 +6,7 @@ YOSYS_NAMESPACE_BEGIN -struct RTLIL::Patch +struct RTLIL::Patch final : public CellAdderMixin { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -34,6 +34,9 @@ public: RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); + + RTLIL::Cell* addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src); }; YOSYS_NAMESPACE_END