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
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();
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);
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);
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;
}
#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;
protected:
void add(RTLIL::Wire *wire);
void add(RTLIL::Cell *cell);
+ void add(RTLIL::Process *process);
public:
RTLIL::Design *design;
// 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);
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.
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;
struct Wire;
struct Cell;
struct Memory;
+ struct Process;
struct Module;
struct Design;
struct Monitor;
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 {};
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 {};
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))
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;
}
}
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())
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);
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);
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) {
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);
}
}