From 7c818d30f73c9d6820587781189a4f3990c0c55d Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 25 Jan 2024 16:08:52 +0100 Subject: [PATCH] sim: Bring $print trigger/sampling semantics in line with FFs --- passes/sat/sim.cc | 66 +++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 542eb5c18..aeed16b97 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -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)