From 009940f56ca71cc8655a13a514371eb5757b96ca Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 11 Jul 2021 23:57:53 +0200 Subject: [PATCH] rtlil: Make Process handling more uniform with Cell and Wire. - add a backlink to module from Process - make constructor and destructor protected, expose Module functions to add and remove processes --- frontends/ast/genrtlil.cc | 4 +--- frontends/rtlil/rtlil_parser.y | 4 +--- kernel/rtlil.cc | 32 +++++++++++++++++++++++++++++++- kernel/rtlil.h | 16 ++++++++++++++-- kernel/yosys.h | 3 +++ passes/cmds/bugpoint.cc | 9 ++++----- passes/cmds/delete.cc | 10 ++++------ passes/proc/proc_clean.cc | 9 ++++----- 8 files changed, 62 insertions(+), 25 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6b119b7ff..e6f7b30c1 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -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 diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 0e6eacf88..67aeb10e0 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -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(¤t_process->root_case.switches); case_stack.clear(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b7bef723f..21ee15ac5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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 &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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d876d7831..dc0d5234b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -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 &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 syncs; - ~Process(); - template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); RTLIL::Process *clone() const; diff --git a/kernel/yosys.h b/kernel/yosys.h index 120311a6f..013c3308f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -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 : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; @@ -253,6 +255,7 @@ namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index c782d9a38..16ac5b6a7 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -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; } } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 48a2179b1..e341f29d6 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -90,7 +90,7 @@ struct DeletePass : public Pass { pool delete_wires; pool delete_cells; - pool delete_procs; + pool delete_procs; pool 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); diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 76d4cf51b..45872907b 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -209,7 +209,7 @@ struct ProcCleanPass : public Pass { extra_args(args, argidx, design); for (auto mod : design->modules()) { - std::vector delme; + std::vector 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); } } -- 2.30.2