Design *design;
dict<Module*, SigMap> sigmaps;
- HierDirtyFlags *dirty_flags = nullptr;
vector<string> signal_declarations;
pool<int> generated_sigtypes;
dict<Cell*, int> topoidx;
+ pool<string> activated_cells;
+ pool<string> reactivated_cells;
+
SimplecWorker(Design *design) : design(design)
{
}
if ('a' <= s[i] && s[i] <= 'z')
s[i] -= 'a' - 'A';
+ util_declarations.push_back("");
util_declarations.push_back(stringf("#ifndef %s", s.c_str()));
util_declarations.push_back(stringf("#define %s", s.c_str()));
}
if (generated_utils.count(util_name) == 0)
{
util_ifdef_guard(util_name);
- util_declarations.push_back(stringf("bool %s(const %s *sig)", util_name.c_str(), sigtype(n).c_str()));
+ util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name.c_str(), sigtype(n).c_str()));
util_declarations.push_back(stringf("{"));
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
if (generated_utils.count(util_name) == 0)
{
util_ifdef_guard(util_name);
- util_declarations.push_back(stringf("void %s(%s *sig, bool value)", util_name.c_str(), sigtype(n).c_str()));
+ util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name.c_str(), sigtype(n).c_str()));
util_declarations.push_back(stringf("{"));
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
for (int i = 0; i < GetSize(topo.sorted); i++)
topoidx[mod->cell(topo.sorted[i])] = i;
+ string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name).c_str());
+
+ for (int i = 0; i < GetSize(ifdef_name); i++)
+ if ('a' <= ifdef_name[i] && ifdef_name[i] <= 'z')
+ ifdef_name[i] -= 'a' - 'A';
+
struct_declarations.push_back("");
+ struct_declarations.push_back(stringf("#ifndef %s", ifdef_name.c_str()));
+ struct_declarations.push_back(stringf("#define %s", ifdef_name.c_str()));
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name).c_str()));
struct_declarations.push_back("{");
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type).c_str(), cid(c->name).c_str(), log_id(c)));
struct_declarations.push_back(stringf("};"));
+ struct_declarations.push_back("#endif");
}
void eval_cell(HierDirtyFlags *work, const string &prefix, const string &/* log_prefix */, Cell *cell)
while (work->dirty)
{
if (verbose && (!work->dirty_bits.empty() || !work->dirty_cells.empty()))
- log("In %s:\n", log_prefix.c_str());
+ log(" In %s:\n", log_prefix.c_str());
while (!work->dirty_bits.empty() || !work->dirty_cells.empty())
{
for (SigChunk chunk : dirtysig.chunks()) {
if (verbose)
- log(" Propagating %s.%s[%d:%d].\n", log_prefix.c_str(), log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
+ log(" Propagating %s.%s[%d:%d].\n", log_prefix.c_str(), log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", log_prefix.c_str(), log_signal(chunk)));
}
work->parent->set_dirty(parent_bit);
if (verbose)
- log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", log_prefix.c_str(), log_id(bit.wire), bit.offset,
+ log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", log_prefix.c_str(), log_id(bit.wire), bit.offset,
parent_log_prefix.c_str(), log_id(parent_bit.wire), parent_bit.offset);
}
child->set_dirty(child_bit);
if (verbose)
- log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", log_prefix.c_str(), log_id(bit.wire), bit.offset,
+ log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", log_prefix.c_str(), log_id(bit.wire), bit.offset,
log_prefix.c_str(), log_id(std::get<0>(port)), log_id(child_bit.wire), child_bit.offset);
} else {
if (verbose)
- log(" Marking cell %s.%s (via %s.%s[%d]).\n", log_prefix.c_str(), log_id(std::get<0>(port)),
+ log(" Marking cell %s.%s (via %s.%s[%d]).\n", log_prefix.c_str(), log_id(std::get<0>(port)),
log_prefix.c_str(), log_id(bit.wire), bit.offset);
work->set_dirty(std::get<0>(port));
}
if (cell == nullptr || topoidx.at(cell) < topoidx.at(c))
cell = c;
+ string hiername = log_prefix + "." + log_id(cell);
+
if (verbose)
- log(" Evaluating %s.%s (%s, best of %d).\n", log_prefix.c_str(), log_id(cell), log_id(cell->type), GetSize(work->dirty_cells));
+ log(" Evaluating %s (%s, best of %d).\n", hiername.c_str(), log_id(cell->type), GetSize(work->dirty_cells));
+
+ if (activated_cells.count(hiername))
+ reactivated_cells.insert(hiername);
+ activated_cells.insert(hiername);
+
eval_cell(work, prefix, log_prefix, cell);
work->unset_dirty(cell);
}
}
}
- void run(Module *mod)
+ void make_func(HierDirtyFlags *work, const string &func_name)
{
- create_module_struct(mod);
+ log("Generating function %s():\n", func_name.c_str());
- dirty_flags = new HierDirtyFlags(mod, IdString(), nullptr);
+ activated_cells.clear();
+ reactivated_cells.clear();
funct_declarations.push_back("");
- funct_declarations.push_back(stringf("void %s_init(struct %s_state_t *state)", cid(mod->name).c_str(), cid(mod->name).c_str()));
+ funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name.c_str(), cid(work->module->name).c_str()));
funct_declarations.push_back("{");
+ eval_dirty(work, "state->", log_id(work->module->name), "", "");
funct_declarations.push_back("}");
- funct_declarations.push_back("");
- funct_declarations.push_back(stringf("void %s_eval(struct %s_state_t *state)", cid(mod->name).c_str(), cid(mod->name).c_str()));
- funct_declarations.push_back("{");
+ log(" Activated %d cells (%d activated more than once).\n", GetSize(activated_cells), GetSize(reactivated_cells));
+ }
+
+ void make_init_func(HierDirtyFlags* /* work */)
+ {
+ // FIXME
+ }
+
+ void make_eval_func(HierDirtyFlags *work)
+ {
+ Module *mod = work->module;
for (Wire *w : mod->wires()) {
if (w->port_input)
for (SigBit bit : sigmaps.at(mod)(w))
- dirty_flags->set_dirty(bit);
+ work->set_dirty(bit);
}
- eval_dirty(dirty_flags, "state->", log_id(mod), "", "");
+ make_func(work, cid(work->module->name) + "_eval");
+ }
- funct_declarations.push_back("}");
+ void make_tick_func(HierDirtyFlags* /* work */)
+ {
+ // FIXME
+ }
- funct_declarations.push_back("");
- funct_declarations.push_back(stringf("void %s_tick(struct %s_state_t *state)", cid(mod->name).c_str(), cid(mod->name).c_str()));
- funct_declarations.push_back("{");
- funct_declarations.push_back("}");
+ void run(Module *mod)
+ {
+ create_module_struct(mod);
+
+ HierDirtyFlags work(mod, IdString(), nullptr);
- delete dirty_flags;
- dirty_flags = nullptr;
+ make_init_func(&work);
+ make_eval_func(&work);
+ make_tick_func(&work);
}
void write(std::ostream &f)