diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index a62691fa1..c127cdf83 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -206,6 +206,7 @@ static void reconstruct_clb_attimes(void *user_data, uint64_t pnt_time, fstHandl void FstData::reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t /* plen */) { if (pnt_time > end_time || !pnt_value) return; + if (curr_cycle > last_cycle) return; // if we are past the timestamp bool is_clock = false; if (!all_samples) { @@ -225,6 +226,7 @@ void FstData::reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_faci if (pnt_time > last_time) { if (all_samples) { callback(last_time); + curr_cycle++; last_time = pnt_time; } else { if (is_clock) { @@ -232,6 +234,7 @@ void FstData::reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_faci std::string prev = past_data[pnt_facidx]; if ((prev!="1" && val=="1") || (prev!="0" && val=="0")) { callback(last_time); + curr_cycle++; last_time = pnt_time; } } @@ -241,12 +244,14 @@ void FstData::reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_faci last_data[pnt_facidx] = std::string((const char *)pnt_value); } -void FstData::reconstructAllAtTimes(std::vector &signal, uint64_t start, uint64_t end, CallbackFunction cb) +void FstData::reconstructAllAtTimes(std::vector &signal, uint64_t start, uint64_t end, unsigned int end_cycle, CallbackFunction cb) { clk_signals = signal; callback = cb; start_time = start; end_time = end; + curr_cycle = 0; + last_cycle = end_cycle; last_data.clear(); last_time = start_time; past_data.clear(); @@ -256,12 +261,16 @@ void FstData::reconstructAllAtTimes(std::vector &signal, uint64_t sta fstReaderSetUnlimitedTimeRange(ctx); fstReaderSetFacProcessMaskAll(ctx); fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr); - if (last_time!=end_time) { + if (last_time!=end_time && curr_cycle < last_cycle) { past_data = last_data; callback(last_time); + curr_cycle++; + } + if (curr_cycle < last_cycle) { + past_data = last_data; + callback(end_time); + curr_cycle++; } - past_data = last_data; - callback(end_time); } std::string FstData::valueOf(fstHandle signal) diff --git a/kernel/fstdata.h b/kernel/fstdata.h index f5cf1d48d..a8ae40301 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -50,7 +50,7 @@ class FstData std::vector& getVars() { return vars; }; void reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen); - void reconstructAllAtTimes(std::vector &signal, uint64_t start_time, uint64_t end_time, CallbackFunction cb); + void reconstructAllAtTimes(std::vector &signal, uint64_t start_time, uint64_t end_time, unsigned int end_cycle, CallbackFunction cb); std::string valueOf(fstHandle signal); fstHandle getHandle(std::string name); @@ -73,6 +73,8 @@ private: std::string timescale_str; uint64_t start_time; uint64_t end_time; + unsigned int last_cycle; + unsigned int curr_cycle; CallbackFunction callback; std::vector clk_signals; bool all_samples; diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index b250d23d8..e2b0022ff 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1546,36 +1546,27 @@ struct SimWorker : SimShared log(" for %d clock cycle(s)",numcycles); log("\n"); bool all_samples = fst_clock.empty(); + unsigned int end_cycle = cycles_set ? numcycles*2 : INT_MAX; - try { - fst->reconstructAllAtTimes(fst_clock, startCount, stopCount, [&](uint64_t time) { - if (verbose) - log("Co-simulating %s %d [%lu%s].\n", (all_samples ? "sample" : "cycle"), cycle, (unsigned long)time, fst->getTimescaleString()); - bool did_something = top->setInputs(); + fst->reconstructAllAtTimes(fst_clock, startCount, stopCount, end_cycle, [&](uint64_t time) { + if (verbose) + log("Co-simulating %s %d [%lu%s].\n", (all_samples ? "sample" : "cycle"), cycle, (unsigned long)time, fst->getTimescaleString()); + bool did_something = top->setInputs(); - if (initial) { - if (!fst_noinit) did_something |= top->setInitState(); - initialize_stable_past(); - initial = false; - } - if (did_something) - update(true); - register_output_step(time); + if (initial) { + if (!fst_noinit) did_something |= top->setInitState(); + initialize_stable_past(); + initial = false; + } + if (did_something) + update(true); + register_output_step(time); - bool status = top->checkSignals(); - if (status) - log_error("Signal difference\n"); - cycle++; - - // Limit to number of cycles if provided - if (cycles_set && cycle > numcycles *2) - throw fst_end_of_data_exception(); - if (time==stopCount) - throw fst_end_of_data_exception(); - }); - } catch(fst_end_of_data_exception) { - // end of data detected - } + bool status = top->checkSignals(); + if (status) + log_error("Signal difference\n"); + cycle++; + }); write_output_files(); delete fst; @@ -2248,40 +2239,31 @@ struct SimWorker : SimShared log("Writing data to `%s`\n", (tb_filename+".txt").c_str()); std::ofstream data_file(tb_filename+".txt"); std::stringstream initstate; - try { - fst->reconstructAllAtTimes(fst_clock, startCount, stopCount, [&](uint64_t time) { - for(auto &item : clocks) - data_file << stringf("%s",fst->valueOf(item.second).c_str()); - for(auto &item : inputs) - data_file << stringf("%s",fst->valueOf(item.second).c_str()); - for(auto &item : outputs) - data_file << stringf("%s",fst->valueOf(item.second).c_str()); - data_file << stringf("%s\n",Const(time-prev_time).as_string().c_str()); + unsigned int end_cycle = cycles_set ? numcycles*2 : INT_MAX; + fst->reconstructAllAtTimes(fst_clock, startCount, stopCount, end_cycle, [&](uint64_t time) { + for(auto &item : clocks) + data_file << stringf("%s",fst->valueOf(item.second).c_str()); + for(auto &item : inputs) + data_file << stringf("%s",fst->valueOf(item.second).c_str()); + for(auto &item : outputs) + data_file << stringf("%s",fst->valueOf(item.second).c_str()); + data_file << stringf("%s\n",Const(time-prev_time).as_string().c_str()); - if (time==startCount) { - // initial state - for(auto var : fst->getVars()) { - if (var.is_reg && !Const::from_string(fst->valueOf(var.id).c_str()).is_fully_undef()) { - if (var.scope == scope) { - initstate << stringf("\t\tuut.%s = %d'b%s;\n", var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); - } else if (var.scope.find(scope+".")==0) { - initstate << stringf("\t\tuut.%s.%s = %d'b%s;\n",var.scope.substr(scope.size()+1).c_str(), var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); - } + if (time==startCount) { + // initial state + for(auto var : fst->getVars()) { + if (var.is_reg && !Const::from_string(fst->valueOf(var.id).c_str()).is_fully_undef()) { + if (var.scope == scope) { + initstate << stringf("\t\tuut.%s = %d'b%s;\n", var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); + } else if (var.scope.find(scope+".")==0) { + initstate << stringf("\t\tuut.%s.%s = %d'b%s;\n",var.scope.substr(scope.size()+1).c_str(), var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); } } } - cycle++; - prev_time = time; - - // Limit to number of cycles if provided - if (cycles_set && cycle > numcycles *2) - throw fst_end_of_data_exception(); - if (time==stopCount) - throw fst_end_of_data_exception(); - }); - } catch(fst_end_of_data_exception) { - // end of data detected - } + } + cycle++; + prev_time = time; + }); f << stringf("\treg [0:%d] data [0:%d];\n", data_len-1, cycle-1); f << "\tinitial begin;\n";