diff options
Diffstat (limited to 'kernel/rtlil.cc')
-rw-r--r-- | kernel/rtlil.cc | 200 |
1 files changed, 196 insertions, 4 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a05023c52..72dcb89af 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -58,6 +58,8 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($dffsre), ID($adff), ID($adffe), + ID($aldff), + ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), @@ -118,6 +120,18 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_), + ID($_ALDFF_NN_), + ID($_ALDFF_NP_), + ID($_ALDFF_PN_), + ID($_ALDFF_PP_), + ID($_ALDFFE_NNN_), + ID($_ALDFFE_NNP_), + ID($_ALDFFE_NPN_), + ID($_ALDFFE_NPP_), + ID($_ALDFFE_PNN_), + ID($_ALDFFE_PNP_), + ID($_ALDFFE_PPN_), + ID($_ALDFFE_PPP_), ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), @@ -193,6 +207,7 @@ RTLIL::Const::Const() RTLIL::Const::Const(std::string str) { flags = RTLIL::CONST_FLAG_STRING; + bits.reserve(str.size() * 8); for (int i = str.size()-1; i >= 0; i--) { unsigned char ch = str[i]; for (int j = 0; j < 8; j++) { @@ -205,6 +220,7 @@ RTLIL::Const::Const(std::string str) RTLIL::Const::Const(int val, int width) { flags = RTLIL::CONST_FLAG_NONE; + bits.reserve(width); for (int i = 0; i < width; i++) { bits.push_back((val & 1) != 0 ? State::S1 : State::S0); val = val >> 1; @@ -214,6 +230,7 @@ RTLIL::Const::Const(int val, int width) RTLIL::Const::Const(RTLIL::State bit, int width) { flags = RTLIL::CONST_FLAG_NONE; + bits.reserve(width); for (int i = 0; i < width; i++) bits.push_back(bit); } @@ -221,6 +238,7 @@ RTLIL::Const::Const(RTLIL::State bit, int width) RTLIL::Const::Const(const std::vector<bool> &bits) { flags = RTLIL::CONST_FLAG_NONE; + this->bits.reserve(bits.size()); for (const auto &b : bits) this->bits.emplace_back(b ? State::S1 : State::S0); } @@ -228,6 +246,7 @@ RTLIL::Const::Const(const std::vector<bool> &bits) RTLIL::Const::Const(const RTLIL::Const &c) { flags = c.flags; + this->bits.reserve(c.size()); for (const auto &b : c.bits) this->bits.push_back(b); } @@ -466,6 +485,35 @@ vector<string> RTLIL::AttrObject::get_hdlname_attribute() const return split_tokens(get_string_attribute(ID::hdlname), " "); } +void RTLIL::AttrObject::set_intvec_attribute(RTLIL::IdString id, const vector<int> &data) +{ + std::stringstream attrval; + for (auto &i : data) { + if (attrval.tellp() > 0) + attrval << " "; + attrval << i; + } + attributes[id] = RTLIL::Const(attrval.str()); +} + +vector<int> RTLIL::AttrObject::get_intvec_attribute(RTLIL::IdString id) const +{ + vector<int> data; + auto it = attributes.find(id); + if (it != attributes.end()) + for (const auto &s : split_tokens(attributes.at(id).decode_string())) { + char *end = nullptr; + errno = 0; + long value = strtol(s.c_str(), &end, 10); + if (end != s.c_str() + s.size()) + log_cmd_error("Literal for intvec attribute has invalid format"); + if (errno == ERANGE || value < INT_MIN || value > INT_MAX) + log_cmd_error("Literal for intvec attribute is out of range"); + data.push_back(value); + } + return data; +} + bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const { if (full_selection) @@ -922,9 +970,14 @@ void RTLIL::Module::makeblackbox() set_bool_attribute(ID::blackbox); } -void RTLIL::Module::reprocess_module(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &) +void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &) +{ + log_error("Class doesn't support expand_interfaces (module: `%s')!\n", id2cstr(name)); +} + +bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *) { - log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name)); + return false; } RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail) @@ -1203,6 +1256,22 @@ namespace { return; } + if (cell->type == ID($bmux)) { + port(ID::A, param(ID::WIDTH) << param(ID::S_WIDTH)); + port(ID::S, param(ID::S_WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type == ID($demux)) { + port(ID::A, param(ID::WIDTH)); + port(ID::S, param(ID::S_WIDTH)); + port(ID::Y, param(ID::WIDTH) << param(ID::S_WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($lut)) { param(ID::LUT); port(ID::A, param(ID::WIDTH)); @@ -1337,6 +1406,32 @@ namespace { return; } + if (cell->type == ID($aldff)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::ALOAD_POLARITY); + port(ID::CLK, 1); + port(ID::ALOAD, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::AD, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type == ID($aldffe)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::ALOAD_POLARITY); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::ALOAD, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::AD, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatch)) { param_bool(ID::EN_POLARITY); port(ID::EN, 1); @@ -1649,6 +1744,15 @@ namespace { { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } if (cell->type.in( + ID($_ALDFF_NN_), ID($_ALDFF_NP_), ID($_ALDFF_PN_), ID($_ALDFF_PP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); check_expected(); return; } + + if (cell->type.in( + ID($_ALDFFE_NNN_), ID($_ALDFFE_NNP_), ID($_ALDFFE_NPN_), ID($_ALDFFE_NPP_), + ID($_ALDFFE_PNN_), ID($_ALDFFE_PNP_), ID($_ALDFFE_PPN_), ID($_ALDFFE_PPP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in( ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } @@ -2361,6 +2465,26 @@ DEF_METHOD(Mux, ID($mux), 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; \ + } +DEF_METHOD(Bmux, ID($bmux), 0) +DEF_METHOD(Demux, ID($demux), 1) +#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); \ @@ -2675,6 +2799,40 @@ RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec 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; +} + +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; +} + 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) { @@ -2865,6 +3023,33 @@ RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigS 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) { @@ -3214,14 +3399,21 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")) return; - if (type == ID($mux) || type == ID($pmux)) { + if (type == ID($mux) || type == ID($pmux) || type == ID($bmux)) { parameters[ID::WIDTH] = GetSize(connections_[ID::Y]); - if (type == ID($pmux)) + if (type != ID($mux)) parameters[ID::S_WIDTH] = GetSize(connections_[ID::S]); check(); return; } + if (type == ID($demux)) { + parameters[ID::WIDTH] = GetSize(connections_[ID::A]); + parameters[ID::S_WIDTH] = GetSize(connections_[ID::S]); + check(); + return; + } + if (type == ID($lut) || type == ID($sop)) { parameters[ID::WIDTH] = GetSize(connections_[ID::A]); return; |