rtlil: Make Process handling more uniform with Cell and Wire.
authorMarcelina Kościelnicka <mwk@0x04.net>
Sun, 11 Jul 2021 21:57:53 +0000 (23:57 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Sun, 11 Jul 2021 22:47:34 +0000 (00:47 +0200)
- add a backlink to module from Process
- make constructor and destructor protected, expose Module functions
  to add and remove processes

frontends/ast/genrtlil.cc
frontends/rtlil/rtlil_parser.y
kernel/rtlil.cc
kernel/rtlil.h
kernel/yosys.h
passes/cmds/bugpoint.cc
passes/cmds/delete.cc
passes/proc/proc_clean.cc

index 6b119b7fff93f6c1f2bdfd188c7c1dd2d6a6bb8f..e6f7b30c1f2c81eb8262f536191eaac1bbe0e81b 100644 (file)
@@ -319,16 +319,14 @@ struct AST_INTERNAL::ProcessGenerator
                LookaheadRewriter la_rewriter(always);
 
                // generate process and simple root case
-               proc = new RTLIL::Process;
+               proc = current_module->addProcess(stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++));
                set_src_attr(proc, always);
-               proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++);
                for (auto &attr : always->attributes) {
                        if (attr.second->type != AST_CONSTANT)
                                log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n",
                                                attr.first.c_str());
                        proc->attributes[attr.first] = attr.second->asAttrConst();
                }
-               current_module->processes[proc->name] = proc;
                current_case = &proc->root_case;
 
                // create initial temporary signal for all output registers
index 0e6eacf88464eab7418709b8355ac288128c49e9..67aeb10e02c1ff5d90adcaa27c18bb88325ef7df 100644 (file)
@@ -283,10 +283,8 @@ proc_stmt:
        TOK_PROCESS TOK_ID EOL {
                if (current_module->processes.count($2) != 0)
                        rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of process %s.", $2).c_str());
-               current_process = new RTLIL::Process;
-               current_process->name = $2;
+               current_process = current_module->addProcess($2);
                current_process->attributes = attrbuf;
-               current_module->processes[$2] = current_process;
                switch_stack.clear();
                switch_stack.push_back(&current_process->root_case.switches);
                case_stack.clear();
index b7bef723ff375f61202efd4466d9dbce8854d22a..21ee15ac548a6cd23ba16ee31d8f204ec0ad2573 100644 (file)
@@ -1839,6 +1839,14 @@ void RTLIL::Module::add(RTLIL::Cell *cell)
        cell->module = this;
 }
 
+void RTLIL::Module::add(RTLIL::Process *process)
+{
+       log_assert(!process->name.empty());
+       log_assert(count_id(process->name) == 0);
+       processes[process->name] = process;
+       process->module = this;
+}
+
 void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
 {
        log_assert(refcount_wires_ == 0);
@@ -1895,6 +1903,13 @@ void RTLIL::Module::remove(RTLIL::Cell *cell)
        delete cell;
 }
 
+void RTLIL::Module::remove(RTLIL::Process *process)
+{
+       log_assert(processes.count(process->name) != 0);
+       processes.erase(process->name);
+       delete process;
+}
+
 void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
 {
        log_assert(wires_[wire->name] == wire);
@@ -2120,11 +2135,19 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memor
        return mem;
 }
 
+RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name)
+{
+       RTLIL::Process *proc = new RTLIL::Process;
+       proc->name = name;
+       add(proc);
+       return proc;
+}
+
 RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other)
 {
        RTLIL::Process *proc = other->clone();
        proc->name = name;
-       processes[name] = proc;
+       add(proc);
        return proc;
 }
 
@@ -2920,6 +2943,13 @@ RTLIL::Memory::Memory()
 #endif
 }
 
+RTLIL::Process::Process() : module(nullptr)
+{
+       static unsigned int hashidx_count = 123456789;
+       hashidx_count = mkhash_xorshift(hashidx_count);
+       hashidx_ = hashidx_count;
+}
+
 RTLIL::Cell::Cell() : module(nullptr)
 {
        static unsigned int hashidx_count = 123456789;
index d876d7831e3b966bb860d675ec9cea062b6eefd7..dc0d5234b98662f07f006431d35f3e4df351144b 100644 (file)
@@ -1129,6 +1129,7 @@ struct RTLIL::Module : public RTLIL::AttrObject
 protected:
        void add(RTLIL::Wire *wire);
        void add(RTLIL::Cell *cell);
+       void add(RTLIL::Process *process);
 
 public:
        RTLIL::Design *design;
@@ -1209,6 +1210,7 @@ public:
        // Removing wires is expensive. If you have to remove wires, remove them all at once.
        void remove(const pool<RTLIL::Wire*> &wires);
        void remove(RTLIL::Cell *cell);
+       void remove(RTLIL::Process *process);
 
        void rename(RTLIL::Wire *wire, RTLIL::IdString new_name);
        void rename(RTLIL::Cell *cell, RTLIL::IdString new_name);
@@ -1228,6 +1230,7 @@ public:
 
        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.
@@ -1581,12 +1584,21 @@ struct RTLIL::SyncRule
 
 struct RTLIL::Process : public RTLIL::AttrObject
 {
+       unsigned int hashidx_;
+       unsigned int hash() const { return hashidx_; }
+
+protected:
+       // use module->addProcess() and module->remove() to create or destroy processes
+       friend struct RTLIL::Module;
+       Process();
+       ~Process();
+
+public:
        RTLIL::IdString name;
+       RTLIL::Module *module;
        RTLIL::CaseRule root_case;
        std::vector<RTLIL::SyncRule*> syncs;
 
-       ~Process();
-
        template<typename T> void rewrite_sigspecs(T &functor);
        template<typename T> void rewrite_sigspecs2(T &functor);
        RTLIL::Process *clone() const;
index 120311a6f6e06e6662af24bf566509900663626a..013c3308fd84c04c37933746beb1f553e2d8c9e8 100644 (file)
@@ -222,6 +222,7 @@ namespace RTLIL {
        struct Wire;
        struct Cell;
        struct Memory;
+       struct Process;
        struct Module;
        struct Design;
        struct Monitor;
@@ -245,6 +246,7 @@ namespace hashlib {
        template<> struct hash_ops<RTLIL::Wire*> : hash_obj_ops {};
        template<> struct hash_ops<RTLIL::Cell*> : hash_obj_ops {};
        template<> struct hash_ops<RTLIL::Memory*> : hash_obj_ops {};
+       template<> struct hash_ops<RTLIL::Process*> : hash_obj_ops {};
        template<> struct hash_ops<RTLIL::Module*> : hash_obj_ops {};
        template<> struct hash_ops<RTLIL::Design*> : hash_obj_ops {};
        template<> struct hash_ops<RTLIL::Monitor*> : hash_obj_ops {};
@@ -253,6 +255,7 @@ namespace hashlib {
        template<> struct hash_ops<const RTLIL::Wire*> : hash_obj_ops {};
        template<> struct hash_ops<const RTLIL::Cell*> : hash_obj_ops {};
        template<> struct hash_ops<const RTLIL::Memory*> : hash_obj_ops {};
+       template<> struct hash_ops<const RTLIL::Process*> : hash_obj_ops {};
        template<> struct hash_ops<const RTLIL::Module*> : hash_obj_ops {};
        template<> struct hash_ops<const RTLIL::Design*> : hash_obj_ops {};
        template<> struct hash_ops<const RTLIL::Monitor*> : hash_obj_ops {};
index c782d9a385801c56eb0bf398c9b92b2ec1edf0d4..16ac5b6a7efd2bffd26d58fdcdd44982e5e179ff 100644 (file)
@@ -275,7 +275,7 @@ struct BugpointPass : public Pass {
                                if (mod->get_blackbox_attribute())
                                        continue;
 
-                               RTLIL::IdString removed_process;
+                               RTLIL::Process *removed_process = nullptr;
                                for (auto process : mod->processes)
                                {
                                        if (process.second->get_bool_attribute(ID::bugpoint_keep))
@@ -284,13 +284,12 @@ struct BugpointPass : public Pass {
                                        if (index++ == seed)
                                        {
                                                log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first));
-                                               removed_process = process.first;
+                                               removed_process = process.second;
                                                break;
                                        }
                                }
-                               if (!removed_process.empty()) {
-                                       delete mod->processes[removed_process];
-                                       mod->processes.erase(removed_process);
+                               if (removed_process) {
+                                       mod->remove(removed_process);
                                        return design_copy;
                                }
                        }
index 48a2179b13ea897cd5165e1f25c69db378e5b350..e341f29d601cd394bd4d23caf0d75a7cbbfd97e4 100644 (file)
@@ -90,7 +90,7 @@ struct DeletePass : public Pass {
 
                        pool<RTLIL::Wire*> delete_wires;
                        pool<RTLIL::Cell*> delete_cells;
-                       pool<RTLIL::IdString> delete_procs;
+                       pool<RTLIL::Process*> delete_procs;
                        pool<RTLIL::IdString> delete_mems;
 
                        for (auto wire : module->selected_wires())
@@ -110,7 +110,7 @@ struct DeletePass : public Pass {
 
                        for (auto &it : module->processes)
                                if (design->selected(module, it.second))
-                                       delete_procs.insert(it.first);
+                                       delete_procs.insert(it.second);
 
                        for (auto &it : delete_mems) {
                                delete module->memories.at(it);
@@ -120,10 +120,8 @@ struct DeletePass : public Pass {
                        for (auto &it : delete_cells)
                                module->remove(it);
 
-                       for (auto &it : delete_procs) {
-                               delete module->processes.at(it);
-                               module->processes.erase(it);
-                       }
+                       for (auto &it : delete_procs)
+                               module->remove(it);
 
                        module->remove(delete_wires);
 
index 76d4cf51b4838abc816eaf07ca388bec0388ac80..45872907bd86f94d88ca3324b64ca81cd66cb0e4 100644 (file)
@@ -209,7 +209,7 @@ struct ProcCleanPass : public Pass {
                extra_args(args, argidx, design);
 
                for (auto mod : design->modules()) {
-                       std::vector<RTLIL::IdString> delme;
+                       std::vector<RTLIL::Process *> delme;
                        if (!design->selected(mod))
                                continue;
                        for (auto &proc_it : mod->processes) {
@@ -220,12 +220,11 @@ struct ProcCleanPass : public Pass {
                                                proc_it.second->root_case.actions.size() == 0) {
                                        if (!quiet)
                                                log("Removing empty process `%s.%s'.\n", log_id(mod), proc_it.second->name.c_str());
-                                       delme.push_back(proc_it.first);
+                                       delme.push_back(proc_it.second);
                                }
                        }
-                       for (auto &id : delme) {
-                               delete mod->processes[id];
-                               mod->processes.erase(id);
+                       for (auto proc : delme) {
+                               mod->remove(proc);
                        }
                }