Added Yosys::{dict,nodict,vector} container types
authorClifford Wolf <clifford@clifford.at>
Fri, 26 Dec 2014 09:53:21 +0000 (10:53 +0100)
committerClifford Wolf <clifford@clifford.at>
Fri, 26 Dec 2014 09:53:21 +0000 (10:53 +0100)
21 files changed:
backends/verilog/verilog_backend.cc
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ilang/ilang_parser.y
kernel/cost.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/yosys.h
passes/cmds/delete.cc
passes/cmds/rename.cc
passes/cmds/select.cc
passes/cmds/setattr.cc
passes/cmds/splitnets.cc
passes/fsm/fsm_export.cc
passes/hierarchy/hierarchy.cc
passes/opt/opt_clean.cc
passes/opt/opt_const.cc
passes/opt/opt_share.cc
passes/opt/wreduce.cc
passes/techmap/extract.cc
passes/techmap/techmap.cc

index 9e8342ab9d7fd59efdd3d807403c2bdd62c366f6..ffaf9ec07171246182c61f453ea010587d5ac088 100644 (file)
@@ -246,7 +246,7 @@ void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
        }
 }
 
-void dump_attributes(std::ostream &f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')
+void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')
 {
        if (noattr)
                return;
index 56ea64effd43ddc530a709adec8c54a88066e394..0f79352f7befe433eea180702c3ff0627d0db0b1 100644 (file)
@@ -1018,7 +1018,7 @@ AstModule::~AstModule()
 }
 
 // create a new parametric module (when needed) and return the name of the generated module
-RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters)
+RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters)
 {
        std::string stripped_name = name.str();
 
index 02375538723089c5eed072d69e83d877bbffa368..27cf0ef3d87452b39fbc429c28b30a62bffb54ca 100644 (file)
@@ -268,7 +268,7 @@ namespace AST
                AstNode *ast;
                bool nolatches, nomem2reg, mem2reg, lib, noopt, icells, autowire;
                virtual ~AstModule();
-               virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
+               virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters);
                virtual RTLIL::Module *clone() const;
        };
 
index a5cc06898337ff52f351d4c37b381ec70cd9079e..4e0981b51ba2f57a0d77af5380668f9a92a4cccc 100644 (file)
@@ -36,7 +36,7 @@ namespace ILANG_FRONTEND {
        RTLIL::Process *current_process;
        std::vector<std::vector<RTLIL::SwitchRule*>*> switch_stack;
        std::vector<RTLIL::CaseRule*> case_stack;
-       std::map<RTLIL::IdString, RTLIL::Const> attrbuf;
+       dict<RTLIL::IdString, RTLIL::Const> attrbuf;
 }
 using namespace ILANG_FRONTEND;
 YOSYS_NAMESPACE_END
index 61a693b9c74718fe0daf048326843e13dc297187..1b4166e00fba33078de0661116a48f070e45dc53 100644 (file)
 
 YOSYS_NAMESPACE_BEGIN
 
-int get_cell_cost(RTLIL::Cell *cell, std::map<RTLIL::Module*, int> *mod_cost_cache = nullptr);
+int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::Module*, int> *mod_cost_cache = nullptr);
 
-int get_cell_cost(RTLIL::IdString type, const std::map<RTLIL::IdString, RTLIL::Const> &parameters = std::map<RTLIL::IdString, RTLIL::Const>(),
-               RTLIL::Design *design = nullptr, std::map<RTLIL::Module*, int> *mod_cost_cache = nullptr)
+int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
+               RTLIL::Design *design = nullptr, dict<RTLIL::Module*, int> *mod_cost_cache = nullptr)
 {
-       static std::map<RTLIL::IdString, int> gate_cost = {
+       static dict<RTLIL::IdString, int> gate_cost = {
                { "$_BUF_",   1 },
                { "$_NOT_",   2 },
                { "$_AND_",   4 },
@@ -55,7 +55,7 @@ int get_cell_cost(RTLIL::IdString type, const std::map<RTLIL::IdString, RTLIL::C
                if (mod->attributes.count("\\cost"))
                        return mod->attributes.at("\\cost").as_int();
 
-               std::map<RTLIL::Module*, int> local_mod_cost_cache;
+               dict<RTLIL::Module*, int> local_mod_cost_cache;
                if (mod_cost_cache == nullptr)
                        mod_cost_cache = &local_mod_cost_cache;
 
@@ -74,7 +74,7 @@ int get_cell_cost(RTLIL::IdString type, const std::map<RTLIL::IdString, RTLIL::C
        return 1;
 }
 
-int get_cell_cost(RTLIL::Cell *cell, std::map<RTLIL::Module*, int> *mod_cost_cache)
+int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::Module*, int> *mod_cost_cache)
 {
        return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
 }
index 0e8078df6db12298bc9fc31b98415429f03e41d0..2d3d83f42ec1278a9b766835d43e9a4a1d2b9431 100644 (file)
@@ -30,7 +30,7 @@ YOSYS_NAMESPACE_BEGIN
 RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
 std::vector<int> RTLIL::IdString::global_refcount_storage_;
 std::vector<char*> RTLIL::IdString::global_id_storage_;
-std::map<char*, int, RTLIL::IdString::char_ptr_cmp> RTLIL::IdString::global_id_index_;
+dict<char*, int, RTLIL::IdString::char_ptr_hash, RTLIL::IdString::char_ptr_eq> RTLIL::IdString::global_id_index_;
 std::vector<int> RTLIL::IdString::global_free_idx_list_;
 
 RTLIL::Const::Const()
@@ -464,7 +464,7 @@ RTLIL::Module::~Module()
                delete it->second;
 }
 
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>)
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>)
 {
        log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
 }
@@ -480,7 +480,7 @@ namespace {
        {
                RTLIL::Module *module;
                RTLIL::Cell *cell;
-               std::set<RTLIL::IdString> expected_params, expected_ports;
+               nodict<RTLIL::IdString> expected_params, expected_ports;
 
                InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
 
@@ -1132,7 +1132,7 @@ namespace {
        struct DeleteWireWorker
        {
                RTLIL::Module *module;
-               const std::set<RTLIL::Wire*> *wires_p;
+               const nodict<RTLIL::Wire*> *wires_p;
 
                void operator()(RTLIL::SigSpec &sig) {
                        std::vector<RTLIL::SigChunk> chunks = sig;
@@ -1146,16 +1146,7 @@ namespace {
        };
 }
 
-#if 0
-void RTLIL::Module::remove(RTLIL::Wire *wire)
-{
-       std::setPort<RTLIL::Wire*> wires_;
-       wires_.insert(wire);
-       remove(wires_);
-}
-#endif
-
-void RTLIL::Module::remove(const std::set<RTLIL::Wire*> &wires)
+void RTLIL::Module::remove(const nodict<RTLIL::Wire*> &wires)
 {
        log_assert(refcount_wires_ == 0);
 
@@ -1811,7 +1802,7 @@ const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const
        return connections_.at(portname);
 }
 
-const std::map<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
+const dict<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
 {
        return connections_;
 }
@@ -2178,6 +2169,17 @@ RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
        check();
 }
 
+RTLIL::SigSpec::SigSpec(nodict<RTLIL::SigBit> bits)
+{
+       cover("kernel.rtlil.sigspec.init.stdset_bits");
+
+       width_ = 0;
+       hash_ = 0;
+       for (auto &bit : bits)
+               append_bit(bit);
+       check();
+}
+
 RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
 {
        cover("kernel.rtlil.sigspec.init.stdset_bits");
@@ -2306,7 +2308,7 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
        pattern.unpack();
        with.unpack();
 
-       std::map<RTLIL::SigBit, RTLIL::SigBit> rules;
+       dict<RTLIL::SigBit, RTLIL::SigBit> rules;
 
        for (int i = 0; i < GetSize(pattern.bits_); i++)
                if (pattern.bits_[i].wire != NULL)
@@ -2315,6 +2317,30 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
        replace(rules, other);
 }
 
+void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules)
+{
+       replace(rules, this);
+}
+
+void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
+{
+       cover("kernel.rtlil.sigspec.replace_dict");
+
+       log_assert(other != NULL);
+       log_assert(width_ == other->width_);
+
+       unpack();
+       other->unpack();
+
+       for (int i = 0; i < GetSize(bits_); i++) {
+               auto it = rules.find(bits_[i]);
+               if (it != rules.end())
+                       other->bits_[i] = it->second;
+       }
+
+       other->check();
+}
+
 void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules)
 {
        replace(rules, this);
@@ -2322,7 +2348,7 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
 
 void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
 {
-       cover("kernel.rtlil.sigspec.replace");
+       cover("kernel.rtlil.sigspec.replace_map");
 
        log_assert(other != NULL);
        log_assert(width_ == other->width_);
@@ -2352,22 +2378,22 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other
 
 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
 {
-       std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
+       nodict<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict();
        remove2(pattern_bits, other);
 }
 
-void RTLIL::SigSpec::remove(const std::set<RTLIL::SigBit> &pattern)
+void RTLIL::SigSpec::remove(const nodict<RTLIL::SigBit> &pattern)
 {
        remove2(pattern, NULL);
 }
 
-void RTLIL::SigSpec::remove(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const
+void RTLIL::SigSpec::remove(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const
 {
        RTLIL::SigSpec tmp = *this;
        tmp.remove2(pattern, other);
 }
 
-void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
+void RTLIL::SigSpec::remove2(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
 {
        if (other)
                cover("kernel.rtlil.sigspec.remove_other");
@@ -2413,11 +2439,11 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
 
 RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const
 {
-       std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
+       nodict<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict();
        return extract(pattern_bits, other);
 }
 
-RTLIL::SigSpec RTLIL::SigSpec::extract(const std::set<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const
+RTLIL::SigSpec RTLIL::SigSpec::extract(const nodict<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const
 {
        if (other)
                cover("kernel.rtlil.sigspec.extract_other");
@@ -2917,6 +2943,18 @@ std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
        return sigbits;
 }
 
+nodict<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_nodict() const
+{
+       cover("kernel.rtlil.sigspec.to_sigbit_nodict");
+
+       pack();
+       nodict<RTLIL::SigBit> sigbits;
+       for (auto &c : chunks_)
+               for (int i = 0; i < c.width; i++)
+                       sigbits.insert(RTLIL::SigBit(c, i));
+       return sigbits;
+}
+
 std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
 {
        cover("kernel.rtlil.sigspec.to_sigbit_vector");
@@ -2941,6 +2979,22 @@ std::map<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_map(const RTLIL
        return new_map;
 }
 
+dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::SigSpec &other) const
+{
+       cover("kernel.rtlil.sigspec.to_sigbit_dict");
+
+       unpack();
+       other.unpack();
+
+       log_assert(width_ == other.width_);
+
+       dict<RTLIL::SigBit, RTLIL::SigBit> new_map;
+       for (int i = 0; i < width_; i++)
+               new_map[bits_[i]] = other.bits_[i];
+
+       return new_map;
+}
+
 RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const
 {
        cover("kernel.rtlil.sigspec.to_single_sigbit");
index 99831244e49e9762bdf99badfd68b8d47dce3511..e684ba4ae1bad3c3846f730985f582c37ee5be80 100644 (file)
 #ifndef RTLIL_H
 #define RTLIL_H
 
+namespace std {
+       template<> struct hash<Yosys::RTLIL::IdString> {
+               size_t operator()(const Yosys::RTLIL::IdString &arg) const;
+       };
+       template<> struct equal_to<Yosys::RTLIL::IdString> {
+               bool operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const;
+       };
+       template<> struct hash<Yosys::RTLIL::SigBit> {
+               size_t operator()(const Yosys::RTLIL::SigBit &arg) const;
+       };
+       template<> struct equal_to<Yosys::RTLIL::SigBit> {
+               bool operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const;
+       };
+       template<> struct hash<Yosys::RTLIL::SigSpec> {
+               size_t operator()(const Yosys::RTLIL::SigSpec &arg) const;
+       };
+       template<> struct equal_to<Yosys::RTLIL::SigSpec> {
+               bool operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const;
+       };
+}
+
 YOSYS_NAMESPACE_BEGIN
 
 namespace RTLIL
@@ -85,6 +106,24 @@ namespace RTLIL
                        }
                };
 
+               struct char_ptr_hash {
+                       size_t operator()(const char *a) const {
+                               size_t hash = 5381;
+                               for (int c; (c = *a); a++)
+                                       hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+                               return hash;
+                       }
+               };
+
+               struct char_ptr_eq {
+                       bool operator()(const char *a, const char *b) const {
+                               for (int i = 0; a[i] || b[i]; i++)
+                                       if (a[i] != b[i])
+                                               return false;
+                               return true;
+                       }
+               };
+
                static struct destruct_guard_t {
                        bool ok; // POD, will be initialized to zero
                        destruct_guard_t() { ok = true; }
@@ -93,7 +132,7 @@ namespace RTLIL
 
                static std::vector<int> global_refcount_storage_;
                static std::vector<char*> global_id_storage_;
-               static std::map<char*, int, char_ptr_cmp> global_id_index_;
+               static dict<char*, int, char_ptr_hash, char_ptr_eq> global_id_index_;
                static std::vector<int> global_free_idx_list_;
 
                static inline int get_reference(int idx)
@@ -224,8 +263,8 @@ namespace RTLIL
                        *this = IdString();
                }
 
-               // The following is a helper key_compare class. Instead of for example std::set<Cell*>
-               // use std::set<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
+               // The following is a helper key_compare class. Instead of for example nodict<Cell*>
+               // use nodict<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
                // set has an influence on the algorithm.
 
                template<typename T> struct compare_ptr_by_name {
@@ -245,7 +284,7 @@ namespace RTLIL
                bool in(IdString rhs) { return *this == rhs; }
                bool in(const char *rhs) { return *this == rhs; }
                bool in(const std::string &rhs) { return *this == rhs; }
-               bool in(const std::set<IdString> &rhs) { return rhs.count(*this) != 0; }
+               bool in(const nodict<IdString> &rhs) { return rhs.count(*this) != 0; }
        };
 
        static inline std::string escape_id(std::string str) {
@@ -336,8 +375,8 @@ namespace RTLIL
        template<typename T>
        struct ObjIterator
        {
-               typename std::map<RTLIL::IdString, T>::iterator it;
-               std::map<RTLIL::IdString, T> *list_p;
+               typename dict<RTLIL::IdString, T>::iterator it;
+               dict<RTLIL::IdString, T> *list_p;
                int *refcount_p;
 
                ObjIterator() : list_p(nullptr), refcount_p(nullptr) {
@@ -401,7 +440,7 @@ namespace RTLIL
        template<typename T>
        struct ObjRange
        {
-               std::map<RTLIL::IdString, T> *list_p;
+               dict<RTLIL::IdString, T> *list_p;
                int *refcount_p;
 
                ObjRange(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { }
@@ -412,8 +451,8 @@ namespace RTLIL
                        return list_p->size();
                }
 
-               operator std::set<T>() const {
-                       std::set<T> result;
+               operator nodict<T>() const {
+                       nodict<T> result;
                        for (auto &it : *list_p)
                                result.insert(it.second);
                        return result;
@@ -427,7 +466,7 @@ namespace RTLIL
                        return result;
                }
 
-               std::set<T> to_set() const { return *this; }
+               nodict<T> to_set() const { return *this; }
                std::vector<T> to_vector() const { return *this; }
        };
 };
@@ -457,11 +496,232 @@ struct RTLIL::Const
        inline int size() const { return bits.size(); }
 };
 
+struct RTLIL::SigChunk
+{
+       RTLIL::Wire *wire;
+       std::vector<RTLIL::State> data; // only used if wire == NULL, LSB at index 0
+       int width, offset;
+
+       SigChunk();
+       SigChunk(const RTLIL::Const &value);
+       SigChunk(RTLIL::Wire *wire);
+       SigChunk(RTLIL::Wire *wire, int offset, int width = 1);
+       SigChunk(const std::string &str);
+       SigChunk(int val, int width = 32);
+       SigChunk(RTLIL::State bit, int width = 1);
+       SigChunk(RTLIL::SigBit bit);
+
+       RTLIL::SigChunk extract(int offset, int length) const;
+
+       bool operator <(const RTLIL::SigChunk &other) const;
+       bool operator ==(const RTLIL::SigChunk &other) const;
+       bool operator !=(const RTLIL::SigChunk &other) const;
+};
+
+struct RTLIL::SigBit
+{
+       RTLIL::Wire *wire;
+       union {
+               RTLIL::State data; // used if wire == NULL
+               int offset;        // used if wire != NULL
+       };
+
+       SigBit();
+       SigBit(RTLIL::State bit);
+       SigBit(bool bit);
+       SigBit(RTLIL::Wire *wire);
+       SigBit(RTLIL::Wire *wire, int offset);
+       SigBit(const RTLIL::SigChunk &chunk);
+       SigBit(const RTLIL::SigChunk &chunk, int index);
+       SigBit(const RTLIL::SigSpec &sig);
+
+       bool operator <(const RTLIL::SigBit &other) const;
+       bool operator ==(const RTLIL::SigBit &other) const;
+       bool operator !=(const RTLIL::SigBit &other) const;
+};
+
+struct RTLIL::SigSpecIterator : public std::iterator<std::input_iterator_tag, RTLIL::SigSpec>
+{
+       RTLIL::SigSpec *sig_p;
+       int index;
+
+       inline RTLIL::SigBit &operator*() const;
+       inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; }
+       inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; }
+       inline void operator++() { index++; }
+};
+
+struct RTLIL::SigSpecConstIterator : public std::iterator<std::input_iterator_tag, RTLIL::SigSpec>
+{
+       const RTLIL::SigSpec *sig_p;
+       int index;
+
+       inline const RTLIL::SigBit &operator*() const;
+       inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; }
+       inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; }
+       inline void operator++() { index++; }
+};
+
+struct RTLIL::SigSpec
+{
+private:
+       int width_;
+       unsigned long hash_;
+       std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
+       std::vector<RTLIL::SigBit> bits_; // LSB at index 0
+
+       void pack() const;
+       void unpack() const;
+       void hash() const;
+
+       inline bool packed() const {
+               return bits_.empty();
+       }
+
+       inline void inline_unpack() const {
+               if (!chunks_.empty())
+                       unpack();
+       }
+
+public:
+       SigSpec();
+       SigSpec(const RTLIL::SigSpec &other);
+       SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
+       const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
+
+       SigSpec(const RTLIL::Const &value);
+       SigSpec(const RTLIL::SigChunk &chunk);
+       SigSpec(RTLIL::Wire *wire);
+       SigSpec(RTLIL::Wire *wire, int offset, int width = 1);
+       SigSpec(const std::string &str);
+       SigSpec(int val, int width = 32);
+       SigSpec(RTLIL::State bit, int width = 1);
+       SigSpec(RTLIL::SigBit bit, int width = 1);
+       SigSpec(std::vector<RTLIL::SigChunk> chunks);
+       SigSpec(std::vector<RTLIL::SigBit> bits);
+       SigSpec(nodict<RTLIL::SigBit> bits);
+       SigSpec(std::set<RTLIL::SigBit> bits);
+       SigSpec(bool bit);
+
+       SigSpec(RTLIL::SigSpec &&other) {
+               width_ = other.width_;
+               hash_ = other.hash_;
+               chunks_ = std::move(other.chunks_);
+               bits_ = std::move(other.bits_);
+       }
+
+       const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) {
+               width_ = other.width_;
+               hash_ = other.hash_;
+               chunks_ = std::move(other.chunks_);
+               bits_ = std::move(other.bits_);
+               return *this;
+       }
+
+       size_t get_hash() const {
+               if (!hash_) hash();
+               return hash_;
+       }
+
+       inline const std::vector<RTLIL::SigChunk> &chunks() const { pack(); return chunks_; }
+       inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
+
+       inline int size() const { return width_; }
+       inline bool empty() const { return width_ == 0; }
+
+       inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); }
+       inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); }
+
+       inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; }
+       inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; }
+
+       inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; }
+       inline RTLIL::SigSpecConstIterator end() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = width_; return it; }
+
+       void sort();
+       void sort_and_unify();
+
+       void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with);
+       void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const;
+
+       void replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules);
+       void replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const;
+
+       void replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules);
+       void replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const;
+
+       void replace(int offset, const RTLIL::SigSpec &with);
+
+       void remove(const RTLIL::SigSpec &pattern);
+       void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const;
+       void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other);
+
+       void remove(const nodict<RTLIL::SigBit> &pattern);
+       void remove(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const;
+       void remove2(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other);
+
+       void remove(int offset, int length = 1);
+       void remove_const();
+
+       RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const;
+       RTLIL::SigSpec extract(const nodict<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const;
+       RTLIL::SigSpec extract(int offset, int length = 1) const;
+
+       void append(const RTLIL::SigSpec &signal);
+       void append_bit(const RTLIL::SigBit &bit);
+
+       void extend_xx(int width, bool is_signed = false);
+       void extend_u0(int width, bool is_signed = false);
+
+       RTLIL::SigSpec repeat(int num) const;
+
+       bool operator <(const RTLIL::SigSpec &other) const;
+       bool operator ==(const RTLIL::SigSpec &other) const;
+       inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); }
+
+       bool is_wire() const;
+       bool is_chunk() const;
+
+       bool is_fully_const() const;
+       bool is_fully_def() const;
+       bool is_fully_undef() const;
+       bool has_marked_bits() const;
+
+       bool as_bool() const;
+       int as_int(bool is_signed = false) const;
+       std::string as_string() const;
+       RTLIL::Const as_const() const;
+       RTLIL::Wire *as_wire() const;
+       RTLIL::SigChunk as_chunk() const;
+
+       bool match(std::string pattern) const;
+
+       std::set<RTLIL::SigBit> to_sigbit_set() const;
+       nodict<RTLIL::SigBit> to_sigbit_nodict() const;
+       std::vector<RTLIL::SigBit> to_sigbit_vector() const;
+       std::map<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_map(const RTLIL::SigSpec &other) const;
+       dict<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_dict(const RTLIL::SigSpec &other) const;
+       RTLIL::SigBit to_single_sigbit() const;
+
+       static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
+       static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str);
+       static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
+
+       operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
+       operator std::vector<RTLIL::SigBit>() const { return bits(); }
+
+#ifndef NDEBUG
+       void check() const;
+#else
+       void check() const { }
+#endif
+};
+
 struct RTLIL::Selection
 {
        bool full_selection;
-       std::set<RTLIL::IdString> selected_modules;
-       std::map<RTLIL::IdString, std::set<RTLIL::IdString>> selected_members;
+       nodict<RTLIL::IdString> selected_modules;
+       dict<RTLIL::IdString, nodict<RTLIL::IdString>> selected_members;
 
        Selection(bool full = true) : full_selection(full) { }
 
@@ -500,14 +760,14 @@ struct RTLIL::Monitor
 
 struct RTLIL::Design
 {
-       std::set<RTLIL::Monitor*> monitors;
-       std::map<std::string, std::string> scratchpad;
+       nodict<RTLIL::Monitor*> monitors;
+       dict<std::string, std::string> scratchpad;
 
        int refcount_modules_;
-       std::map<RTLIL::IdString, RTLIL::Module*> modules_;
+       dict<RTLIL::IdString, RTLIL::Module*> modules_;
 
        std::vector<RTLIL::Selection> selection_stack;
-       std::map<RTLIL::IdString, RTLIL::Selection> selection_vars;
+       dict<RTLIL::IdString, RTLIL::Selection> selection_vars;
        std::string selected_active_module;
 
        Design();
@@ -569,7 +829,7 @@ struct RTLIL::Design
 };
 
 #define RTLIL_ATTRIBUTE_MEMBERS                                \
-       std::map<RTLIL::IdString, RTLIL::Const> attributes;    \
+       dict<RTLIL::IdString, RTLIL::Const> attributes;    \
        void set_bool_attribute(RTLIL::IdString id) {          \
                attributes[id] = RTLIL::Const(1);              \
        }                                                      \
@@ -587,24 +847,24 @@ protected:
 
 public:
        RTLIL::Design *design;
-       std::set<RTLIL::Monitor*> monitors;
+       nodict<RTLIL::Monitor*> monitors;
 
        int refcount_wires_;
        int refcount_cells_;
 
-       std::map<RTLIL::IdString, RTLIL::Wire*> wires_;
-       std::map<RTLIL::IdString, RTLIL::Cell*> cells_;
+       dict<RTLIL::IdString, RTLIL::Wire*> wires_;
+       dict<RTLIL::IdString, RTLIL::Cell*> cells_;
        std::vector<RTLIL::SigSig> connections_;
 
        RTLIL::IdString name;
-       std::set<RTLIL::IdString> avail_parameters;
-       std::map<RTLIL::IdString, RTLIL::Memory*> memories;
-       std::map<RTLIL::IdString, RTLIL::Process*> processes;
+       nodict<RTLIL::IdString> avail_parameters;
+       dict<RTLIL::IdString, RTLIL::Memory*> memories;
+       dict<RTLIL::IdString, RTLIL::Process*> processes;
        RTLIL_ATTRIBUTE_MEMBERS
 
        Module();
        virtual ~Module();
-       virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
+       virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters);
        virtual size_t count_id(RTLIL::IdString id);
        virtual void check();
        virtual void optimize();
@@ -641,7 +901,7 @@ public:
        RTLIL::ObjRange<RTLIL::Cell*> cells() { return RTLIL::ObjRange<RTLIL::Cell*>(&cells_, &refcount_cells_); }
 
        // Removing wires is expensive. If you have to remove wires, remove them all at once.
-       void remove(const std::set<RTLIL::Wire*> &wires);
+       void remove(const nodict<RTLIL::Wire*> &wires);
        void remove(RTLIL::Cell *cell);
 
        void rename(RTLIL::Wire *wire, RTLIL::IdString new_name);
@@ -852,8 +1112,8 @@ public:
        RTLIL::Module *module;
        RTLIL::IdString name;
        RTLIL::IdString type;
-       std::map<RTLIL::IdString, RTLIL::SigSpec> connections_;
-       std::map<RTLIL::IdString, RTLIL::Const> parameters;
+       dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
+       dict<RTLIL::IdString, RTLIL::Const> parameters;
        RTLIL_ATTRIBUTE_MEMBERS
 
        // access cell ports
@@ -861,7 +1121,7 @@ public:
        void unsetPort(RTLIL::IdString portname);
        void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal);
        const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const;
-       const std::map<RTLIL::IdString, RTLIL::SigSpec> &connections() const;
+       const dict<RTLIL::IdString, RTLIL::SigSpec> &connections() const;
 
        // access cell parameters
        bool hasParam(RTLIL::IdString paramname) const;
@@ -880,241 +1140,6 @@ public:
        template<typename T> void rewrite_sigspecs(T functor);
 };
 
-struct RTLIL::SigChunk
-{
-       RTLIL::Wire *wire;
-       std::vector<RTLIL::State> data; // only used if wire == NULL, LSB at index 0
-       int width, offset;
-
-       SigChunk();
-       SigChunk(const RTLIL::Const &value);
-       SigChunk(RTLIL::Wire *wire);
-       SigChunk(RTLIL::Wire *wire, int offset, int width = 1);
-       SigChunk(const std::string &str);
-       SigChunk(int val, int width = 32);
-       SigChunk(RTLIL::State bit, int width = 1);
-       SigChunk(RTLIL::SigBit bit);
-
-       RTLIL::SigChunk extract(int offset, int length) const;
-
-       bool operator <(const RTLIL::SigChunk &other) const;
-       bool operator ==(const RTLIL::SigChunk &other) const;
-       bool operator !=(const RTLIL::SigChunk &other) const;
-};
-
-struct RTLIL::SigBit
-{
-       RTLIL::Wire *wire;
-       union {
-               RTLIL::State data; // used if wire == NULL
-               int offset;        // used if wire != NULL
-       };
-
-       SigBit() : wire(NULL), data(RTLIL::State::S0) { }
-       SigBit(RTLIL::State bit) : wire(NULL), data(bit) { }
-       SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { }
-       SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); }
-       SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }
-       SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; }
-       SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; }
-       SigBit(const RTLIL::SigSpec &sig);
-
-       bool 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 < other.wire;
-       }
-
-       bool operator ==(const RTLIL::SigBit &other) const {
-               return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data));
-       }
-
-       bool operator !=(const RTLIL::SigBit &other) const {
-               return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data));
-       }
-};
-
-struct RTLIL::SigSpecIterator : public std::iterator<std::input_iterator_tag, RTLIL::SigSpec>
-{
-       RTLIL::SigSpec *sig_p;
-       int index;
-
-       inline RTLIL::SigBit &operator*() const;
-       inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; }
-       inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; }
-       inline void operator++() { index++; }
-};
-
-struct RTLIL::SigSpecConstIterator : public std::iterator<std::input_iterator_tag, RTLIL::SigSpec>
-{
-       const RTLIL::SigSpec *sig_p;
-       int index;
-
-       inline const RTLIL::SigBit &operator*() const;
-       inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; }
-       inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; }
-       inline void operator++() { index++; }
-};
-
-struct RTLIL::SigSpec
-{
-private:
-       int width_;
-       unsigned long hash_;
-       std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
-       std::vector<RTLIL::SigBit> bits_; // LSB at index 0
-
-       void pack() const;
-       void unpack() const;
-       void hash() const;
-
-       inline bool packed() const {
-               return bits_.empty();
-       }
-
-       inline void inline_unpack() const {
-               if (!chunks_.empty())
-                       unpack();
-       }
-
-public:
-       SigSpec();
-       SigSpec(const RTLIL::SigSpec &other);
-       SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
-       const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
-
-       SigSpec(const RTLIL::Const &value);
-       SigSpec(const RTLIL::SigChunk &chunk);
-       SigSpec(RTLIL::Wire *wire);
-       SigSpec(RTLIL::Wire *wire, int offset, int width = 1);
-       SigSpec(const std::string &str);
-       SigSpec(int val, int width = 32);
-       SigSpec(RTLIL::State bit, int width = 1);
-       SigSpec(RTLIL::SigBit bit, int width = 1);
-       SigSpec(std::vector<RTLIL::SigChunk> chunks);
-       SigSpec(std::vector<RTLIL::SigBit> bits);
-       SigSpec(std::set<RTLIL::SigBit> bits);
-       SigSpec(bool bit);
-
-       SigSpec(RTLIL::SigSpec &&other) {
-               width_ = other.width_;
-               hash_ = other.hash_;
-               chunks_ = std::move(other.chunks_);
-               bits_ = std::move(other.bits_);
-       }
-
-       const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) {
-               width_ = other.width_;
-               hash_ = other.hash_;
-               chunks_ = std::move(other.chunks_);
-               bits_ = std::move(other.bits_);
-               return *this;
-       }
-
-       inline const std::vector<RTLIL::SigChunk> &chunks() const { pack(); return chunks_; }
-       inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
-
-       inline int size() const { return width_; }
-       inline bool empty() const { return width_ == 0; }
-
-       inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); }
-       inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); }
-
-       inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; }
-       inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; }
-
-       inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; }
-       inline RTLIL::SigSpecConstIterator end() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = width_; return it; }
-
-       void sort();
-       void sort_and_unify();
-
-       void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with);
-       void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const;
-
-       void replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules);
-       void replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const;
-
-       void replace(int offset, const RTLIL::SigSpec &with);
-
-       void remove(const RTLIL::SigSpec &pattern);
-       void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const;
-       void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other);
-
-       void remove(const std::set<RTLIL::SigBit> &pattern);
-       void remove(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const;
-       void remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other);
-
-       void remove(int offset, int length = 1);
-       void remove_const();
-
-       RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const;
-       RTLIL::SigSpec extract(const std::set<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const;
-       RTLIL::SigSpec extract(int offset, int length = 1) const;
-
-       void append(const RTLIL::SigSpec &signal);
-       void append_bit(const RTLIL::SigBit &bit);
-
-       void extend_xx(int width, bool is_signed = false);
-       void extend_u0(int width, bool is_signed = false);
-
-       RTLIL::SigSpec repeat(int num) const;
-
-       bool operator <(const RTLIL::SigSpec &other) const;
-       bool operator ==(const RTLIL::SigSpec &other) const;
-       inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); }
-
-       bool is_wire() const;
-       bool is_chunk() const;
-
-       bool is_fully_const() const;
-       bool is_fully_def() const;
-       bool is_fully_undef() const;
-       bool has_marked_bits() const;
-
-       bool as_bool() const;
-       int as_int(bool is_signed = false) const;
-       std::string as_string() const;
-       RTLIL::Const as_const() const;
-       RTLIL::Wire *as_wire() const;
-       RTLIL::SigChunk as_chunk() const;
-
-       bool match(std::string pattern) const;
-
-       std::set<RTLIL::SigBit> to_sigbit_set() const;
-       std::vector<RTLIL::SigBit> to_sigbit_vector() const;
-       std::map<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_map(const RTLIL::SigSpec &other) const;
-       RTLIL::SigBit to_single_sigbit() const;
-
-       static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
-       static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str);
-       static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
-
-       operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
-       operator std::vector<RTLIL::SigBit>() const { return bits(); }
-
-#ifndef NDEBUG
-       void check() const;
-#else
-       inline void check() const { }
-#endif
-};
-
-inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const {
-       return (*sig_p)[index];
-}
-
-inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const {
-       return (*sig_p)[index];
-}
-
-inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
-       log_assert(sig.size() == 1 && sig.chunks().size() == 1);
-       *this = SigBit(sig.chunks().front());
-}
-
 struct RTLIL::CaseRule
 {
        std::vector<RTLIL::SigSpec> compare;
@@ -1163,6 +1188,44 @@ struct RTLIL::Process
        RTLIL::Process *clone() const;
 };
 
+
+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 ? RTLIL::S1 : RTLIL::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 < other.wire;
+}
+
+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 RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const {
+       return (*sig_p)[index];
+}
+
+inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const {
+       return (*sig_p)[index];
+}
+
+inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
+       log_assert(sig.size() == 1 && sig.chunks().size() == 1);
+       *this = SigBit(sig.chunks().front());
+}
+
 template<typename T>
 void RTLIL::Module::rewrite_sigspecs(T functor)
 {
@@ -1222,4 +1285,35 @@ void RTLIL::Process::rewrite_sigspecs(T functor)
 
 YOSYS_NAMESPACE_END
 
+inline size_t std::hash<Yosys::RTLIL::IdString>::operator()(const Yosys::RTLIL::IdString &arg) const {
+       return arg.index_;
+}
+
+inline bool std::equal_to<Yosys::RTLIL::IdString>::operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const {
+       return lhs.index_ == rhs.index_;
+}
+
+inline size_t std::hash<Yosys::RTLIL::SigBit>::operator()(const Yosys::RTLIL::SigBit &arg) const {
+       if (arg.wire) {
+               size_t hash = arg.wire->name.index_;
+               hash = ((hash << 5) + hash) + arg.offset;
+               return hash;
+       }
+       return arg.data;
+}
+
+inline bool std::equal_to<Yosys::RTLIL::SigBit>::operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const {
+       if (lhs.wire || rhs.wire)
+               return lhs.wire == rhs.wire && lhs.offset == rhs.offset;
+       return lhs.data == rhs.data;
+}
+
+inline size_t std::hash<Yosys::RTLIL::SigSpec>::operator()(const Yosys::RTLIL::SigSpec &arg) const {
+       return arg.get_hash();
+}
+
+inline bool std::equal_to<Yosys::RTLIL::SigSpec>::operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const {
+       return lhs == rhs;
+}
+
 #endif
index b64739ad4e36b60406a916cb8753a2d2c43a40f8..5a6945c8ff4bde6d53e03bb954f2709cadf6833f 100644 (file)
@@ -45,6 +45,8 @@
 #include <string>
 #include <algorithm>
 #include <functional>
+#include <unordered_map>
+#include <unordered_set>
 #include <initializer_list>
 
 #include <sstream>
 
 YOSYS_NAMESPACE_BEGIN
 
+template <class Key, class T, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
+using dict = std::unordered_map<Key, T, Hash, KeyEqual>;
+
+template <class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
+using nodict = std::unordered_set<Key, Hash, KeyEqual>;
+
+template <class T>
+using vector = std::vector<T>;
+
 namespace RTLIL {
        struct IdString;
+       struct SigBit;
        struct SigSpec;
        struct Wire;
        struct Cell;
index 8c3391e521874aeb19aa51455e35c4594995d19a..d7edcfbfca33e4f928e792e6fb912fd828dcb5b2 100644 (file)
@@ -91,10 +91,10 @@ struct DeletePass : public Pass {
                                continue;
                        }
 
-                       std::set<RTLIL::Wire*> delete_wires;
-                       std::set<RTLIL::Cell*> delete_cells;
-                       std::set<RTLIL::IdString> delete_procs;
-                       std::set<RTLIL::IdString> delete_mems;
+                       nodict<RTLIL::Wire*> delete_wires;
+                       nodict<RTLIL::Cell*> delete_cells;
+                       nodict<RTLIL::IdString> delete_procs;
+                       nodict<RTLIL::IdString> delete_mems;
 
                        for (auto &it : module->wires_)
                                if (design->selected(module, it.second))
index b2e10e557b65878cab4f9606bad45c89dc5833c0..8f24af27820f0adf5f482134b4ab5f9d9dcab6c1 100644 (file)
@@ -118,7 +118,7 @@ struct RenamePass : public Pass {
                                if (!design->selected(module))
                                        continue;
 
-                               std::map<RTLIL::IdString, RTLIL::Wire*> new_wires;
+                               dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
                                for (auto &it : module->wires_) {
                                        if (it.first[0] == '$' && design->selected(module, it.second))
                                                do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
@@ -128,7 +128,7 @@ struct RenamePass : public Pass {
                                module->wires_.swap(new_wires);
                                module->fixup_ports();
 
-                               std::map<RTLIL::IdString, RTLIL::Cell*> new_cells;
+                               dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
                                for (auto &it : module->cells_) {
                                        if (it.first[0] == '$' && design->selected(module, it.second))
                                                do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
@@ -149,7 +149,7 @@ struct RenamePass : public Pass {
                                if (!design->selected(module))
                                        continue;
 
-                               std::map<RTLIL::IdString, RTLIL::Wire*> new_wires;
+                               dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
                                for (auto &it : module->wires_) {
                                        if (design->selected(module, it.second))
                                                if (it.first[0] == '\\' && it.second->port_id == 0)
@@ -159,7 +159,7 @@ struct RenamePass : public Pass {
                                module->wires_.swap(new_wires);
                                module->fixup_ports();
 
-                               std::map<RTLIL::IdString, RTLIL::Cell*> new_cells;
+                               dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
                                for (auto &it : module->cells_) {
                                        if (design->selected(module, it.second))
                                                if (it.first[0] == '\\')
index 7f841673f0e586b6e36c7d47bc175d50cd448e84..91368f572b21e7d3c2ba1287be1ac6746767b953 100644 (file)
@@ -101,7 +101,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
        log_abort();
 }
 
-static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
 {
        if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
                for (auto &it : attributes) {
@@ -119,7 +119,7 @@ static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes
        return false;
 }
 
-static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
 {
        size_t pos = match_expr.find_first_of("<!=>");
 
index 39c75c54e872ae418fa87a6b130f3ad08c6124d6..9a6d8a0389fe5b15d8ca52b8470590d10a8d26a6 100644 (file)
@@ -50,7 +50,7 @@ struct setunset_t
        }
 };
 
-static void do_setunset(std::map<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
+static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
 {
        for (auto &item : list)
                if (item.unset)
index a6c9fe8839fdd82d45d28a3bfbe68f2536959301..6c24a8e5f8ab41abf8271c3dbf42bfd344fbeb41 100644 (file)
@@ -176,7 +176,7 @@ struct SplitnetsPass : public Pass {
 
                        module->rewrite_sigspecs(worker);
 
-                       std::set<RTLIL::Wire*> delete_wires;
+                       nodict<RTLIL::Wire*> delete_wires;
                        for (auto &it : worker.splitmap)
                                delete_wires.insert(it.first);
                        module->remove(delete_wires);
index 668fe8d1dd5805a001f561967bce17bbca7c9494..ad927033429ff109d6ce6c31015c7ee500663a7f 100644 (file)
@@ -50,7 +50,7 @@ std::string kiss_convert_signal(const RTLIL::SigSpec &sig) {
  * @param cell pointer to the FSM cell which should be exported.
  */
 void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::string filename, bool origenc) {
-       std::map<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
+       dict<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
        FsmData fsm_data;
        FsmData::transition_t tr;
        std::ofstream kiss_file;
@@ -145,7 +145,7 @@ struct FsmExportPass : public Pass {
        }
        virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
        {
-               std::map<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
+               dict<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
                std::string arg;
                bool flag_noauto = false;
                std::string filename;
index e95947a926ee3191cef706b79bc0518eb75e2303..66d660324b4e572bed1d1b47cefd766a1fd17053 100644 (file)
@@ -462,7 +462,7 @@ struct HierarchyPass : public Pass {
                                        log_cmd_error("Option -top requires an additional argument!\n");
                                top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL;
                                if (top_mod == NULL && design->modules_.count("$abstract" + RTLIL::escape_id(args[argidx]))) {
-                                       std::map<RTLIL::IdString, RTLIL::Const> empty_parameters;
+                                       dict<RTLIL::IdString, RTLIL::Const> empty_parameters;
                                        design->modules_.at("$abstract" + RTLIL::escape_id(args[argidx]))->derive(design, empty_parameters);
                                        top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL;
                                }
@@ -560,7 +560,7 @@ struct HierarchyPass : public Pass {
                                RTLIL::Cell *cell = work.second;
                                log("Mapping positional arguments of cell %s.%s (%s).\n",
                                                RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
-                               std::map<RTLIL::IdString, RTLIL::SigSpec> new_connections;
+                               dict<RTLIL::IdString, RTLIL::SigSpec> new_connections;
                                for (auto &conn : cell->connections())
                                        if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
                                                int id = atoi(conn.first.c_str()+1);
index 8a20898cfb54ef2c0308cbe1b8a99977c4c1073d..01acb5c044e3090293d24381d233f078d7fced6d 100644 (file)
@@ -262,7 +262,7 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
        }
 
 
-       std::set<RTLIL::Wire*> del_wires;
+       nodict<RTLIL::Wire*> del_wires;
 
        int del_wires_count = 0;
        for (auto wire : maybe_del_wires)
index 5bac76cf62ea8ec4df0f7a572297038a67937ba3..7f800bde9e6e65ba8e64c067c763bc61906af620 100644 (file)
@@ -196,11 +196,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
        ct_combinational.setup_stdcells();
 
        SigMap assign_map(module);
-       std::map<RTLIL::SigSpec, RTLIL::SigSpec> invert_map;
+       dict<RTLIL::SigSpec, RTLIL::SigSpec> invert_map;
 
        TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
-       std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
-       std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
+       dict<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
+       dict<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
 
        for (auto cell : module->cells())
                if (design->selected(module, cell) && cell->type[0] == '$') {
index f8bc02205c6ce9fa5d83153f6de4183650481425..c581b749e6e390d5e4664cfaafc2ff9cb4fbcbda 100644 (file)
@@ -41,7 +41,7 @@ struct OptShareWorker
        CellTypes ct;
        int total_count;
 #ifdef USE_CELL_HASH_CACHE
-       std::map<const RTLIL::Cell*, std::string> cell_hash_cache;
+       dict<const RTLIL::Cell*, std::string> cell_hash_cache;
 #endif
 
 #ifdef USE_CELL_HASH_CACHE
@@ -67,8 +67,8 @@ struct OptShareWorker
                for (auto &it : cell->parameters)
                        hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n";
 
-               const std::map<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections();
-               std::map<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
+               const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections();
+               dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
 
                if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" ||
                                cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") {
@@ -127,12 +127,14 @@ struct OptShareWorker
 #endif
 
                if (cell1->parameters != cell2->parameters) {
-                       lt = cell1->parameters < cell2->parameters;
+                       std::map<RTLIL::IdString, RTLIL::Const> p1(cell1->parameters.begin(), cell1->parameters.end());
+                       std::map<RTLIL::IdString, RTLIL::Const> p2(cell2->parameters.begin(), cell2->parameters.end());
+                       lt = p1 < p2;
                        return true;
                }
 
-               std::map<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections();
-               std::map<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections();
+               dict<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections();
+               dict<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections();
 
                for (auto &it : conn1) {
                        if (ct.cell_output(cell1->type, it.first))
@@ -171,7 +173,9 @@ struct OptShareWorker
                }
 
                if (conn1 != conn2) {
-                       lt = conn1 < conn2;
+                       std::map<RTLIL::IdString, RTLIL::SigSpec> c1(conn1.begin(), conn1.end());
+                       std::map<RTLIL::IdString, RTLIL::SigSpec> c2(conn2.begin(), conn2.end());
+                       lt = c1 < c2;
                        return true;
                }
 
index 8f59a041ee44891029d1d7011c462ba0b727c609..e8a38d2120ec62e1bbff7e3b733c1bc5e8f70772 100644 (file)
@@ -28,11 +28,11 @@ PRIVATE_NAMESPACE_BEGIN
 
 struct WreduceConfig
 {
-       std::set<IdString> supported_cell_types;
+       nodict<IdString> supported_cell_types;
 
        WreduceConfig()
        {
-               supported_cell_types = std::set<IdString>({
+               supported_cell_types = nodict<IdString>({
                        "$not", "$pos", "$neg",
                        "$and", "$or", "$xor", "$xnor",
                        "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
index 994ef8f2a96d363a66f551020d8c9d259a5b153b..ff99040e173485dd66275f8e5011647064b950af 100644 (file)
@@ -42,7 +42,7 @@ public:
        {
        }
 
-       bool compareAttributes(const std::set<RTLIL::IdString> &attr, const std::map<RTLIL::IdString, RTLIL::Const> &needleAttr, const std::map<RTLIL::IdString, RTLIL::Const> &haystackAttr)
+       bool compareAttributes(const std::set<RTLIL::IdString> &attr, const dict<RTLIL::IdString, RTLIL::Const> &needleAttr, const dict<RTLIL::IdString, RTLIL::Const> &haystackAttr)
        {
                for (auto &it : attr) {
                        size_t nc = needleAttr.count(it), hc = haystackAttr.count(it);
@@ -123,7 +123,7 @@ public:
                {
                        RTLIL::Wire *lastNeedleWire = NULL;
                        RTLIL::Wire *lastHaystackWire = NULL;
-                       std::map<RTLIL::IdString, RTLIL::Const> emptyAttr;
+                       dict<RTLIL::IdString, RTLIL::Const> emptyAttr;
 
                        for (auto &conn : needleCell->connections())
                        {
index 04d345d31c016bb5b2ddac02e0ee874cecb1367c..94dd4d42c006888688e963ab638f96793f56cfbb 100644 (file)
@@ -341,7 +341,7 @@ struct TechmapWorker
                        {
                                RTLIL::IdString derived_name = tpl_name;
                                RTLIL::Module *tpl = map->modules_[tpl_name];
-                               std::map<RTLIL::IdString, RTLIL::Const> parameters = cell->parameters;
+                               std::map<RTLIL::IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
 
                                if (tpl->get_bool_attribute("\\blackbox"))
                                        continue;
@@ -529,7 +529,7 @@ struct TechmapWorker
                                                tpl = techmap_cache[key];
                                        } else {
                                                if (cell->parameters.size() != 0) {
-                                                       derived_name = tpl->derive(map, parameters);
+                                                       derived_name = tpl->derive(map, dict<RTLIL::IdString, RTLIL::Const>(parameters.begin(), parameters.end()));
                                                        tpl = map->module(derived_name);
                                                        log_continue = true;
                                                }
@@ -975,7 +975,7 @@ struct TechmapPass : public Pass {
                                        Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend);
                                }
 
-               std::map<RTLIL::IdString, RTLIL::Module*> modules_new;
+               dict<RTLIL::IdString, RTLIL::Module*> modules_new;
                for (auto &it : map->modules_) {
                        if (it.first.substr(0, 2) == "\\$")
                                it.second->name = it.first.substr(1);
@@ -1072,7 +1072,7 @@ struct FlattenPass : public Pass {
                log("No more expansions possible.\n");
 
                if (top_mod != NULL) {
-                       std::map<RTLIL::IdString, RTLIL::Module*> new_modules;
+                       dict<RTLIL::IdString, RTLIL::Module*> new_modules;
                        for (auto mod : design->modules())
                                if (mod == top_mod || mod->get_bool_attribute("\\blackbox")) {
                                        new_modules[mod->name] = mod;