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