sim: Bring $print trigger/sampling semantics in line with FFs

This commit is contained in:
Jannis Harder 2024-01-25 16:08:52 +01:00
parent 80511ced71
commit 7c818d30f7
1 changed files with 35 additions and 31 deletions

View File

@ -813,7 +813,7 @@ struct SimInstance
} }
} }
void update_ph3(bool check_assertions) void update_ph3(bool gclk_trigger)
{ {
for (auto &it : ff_database) for (auto &it : ff_database)
{ {
@ -858,10 +858,11 @@ struct SimInstance
Const en = get_state(cell->getPort(ID::EN)); Const en = get_state(cell->getPort(ID::EN));
Const args = get_state(cell->getPort(ID::ARGS)); Const args = get_state(cell->getPort(ID::ARGS));
if (!en.as_bool()) bool sampled = trg_en && trg.size() > 0;
goto update_print;
if (trg.size() > 0 && trg_en) { if (sampled ? print.past_en.as_bool() : en.as_bool()) {
if (sampled) {
sampled = true;
Const trg_pol = cell->getParam(ID::TRG_POLARITY); Const trg_pol = cell->getParam(ID::TRG_POLARITY);
for (int i = 0; i < trg.size(); i++) { for (int i = 0; i < trg.size(); i++) {
bool pol = trg_pol[i] == State::S1; bool pol = trg_pol[i] == State::S1;
@ -875,6 +876,9 @@ struct SimInstance
// initial $print (TRG width = 0, TRG_ENABLE = true) // initial $print (TRG width = 0, TRG_ENABLE = true)
if (!print.initial_done && en != print.past_en) if (!print.initial_done && en != print.past_en)
triggered = true; triggered = true;
} else if (cell->get_bool_attribute(ID(trg_on_gclk))) {
// unified $print for cycle based FV semantics
triggered = gclk_trigger;
} else { } else {
// always @(*) $print // always @(*) $print
if (args != print.past_args || en != print.past_en) if (args != print.past_args || en != print.past_en)
@ -884,7 +888,7 @@ struct SimInstance
if (triggered) { if (triggered) {
int pos = 0; int pos = 0;
for (auto &part : print.fmt.parts) { for (auto &part : print.fmt.parts) {
part.sig = args.extract(pos, part.sig.size()); part.sig = (sampled ? print.past_args : args).extract(pos, part.sig.size());
pos += part.sig.size(); pos += part.sig.size();
} }
@ -892,15 +896,15 @@ struct SimInstance
log("%s", rendered.c_str()); log("%s", rendered.c_str());
shared->display_output.emplace_back(shared->step, this, cell, rendered); shared->display_output.emplace_back(shared->step, this, cell, rendered);
} }
}
update_print:
print.past_trg = trg; print.past_trg = trg;
print.past_en = en; print.past_en = en;
print.past_args = args; print.past_args = args;
print.initial_done = true; print.initial_done = true;
} }
if (check_assertions) if (gclk_trigger)
{ {
for (auto cell : formal_database) for (auto cell : formal_database)
{ {
@ -932,7 +936,7 @@ struct SimInstance
} }
for (auto it : children) for (auto it : children)
it.second->update_ph3(check_assertions); it.second->update_ph3(gclk_trigger);
} }
void set_initstate_outputs(State state) void set_initstate_outputs(State state)