diff options
author | Miodrag Milanovic <mmicko@gmail.com> | 2022-02-15 09:30:42 +0100 |
---|---|---|
committer | Miodrag Milanovic <mmicko@gmail.com> | 2022-02-16 13:27:59 +0100 |
commit | fb22d7cdc411ec52672cb7f13364651c564872db (patch) | |
tree | 0b69b27f9806a39772b0980f7c8ab701234e754f /kernel | |
parent | 15860000487e2d6748843888b78289f95f3ea46b (diff) | |
download | yosys-fb22d7cdc411ec52672cb7f13364651c564872db.tar.gz yosys-fb22d7cdc411ec52672cb7f13364651c564872db.tar.bz2 yosys-fb22d7cdc411ec52672cb7f13364651c564872db.zip |
Add support for various ff/latch cells simulation
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fstdata.cc | 141 | ||||
-rw-r--r-- | kernel/fstdata.h | 22 |
2 files changed, 54 insertions, 109 deletions
diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index 330c4d189..1386a3300 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -109,8 +109,7 @@ void FstData::extractVarNames() } if (clean_name[0]=='\\') clean_name = clean_name.substr(1); - //log("adding %s.%s\n",var.scope.c_str(), clean_name.c_str()); - + name_to_handle[var.scope+"."+clean_name] = h->u.var.handle; break; } @@ -118,48 +117,6 @@ void FstData::extractVarNames() } } -static void reconstruct_edges_varlen(void *user_data, uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen) -{ - FstData *ptr = (FstData*)user_data; - ptr->reconstruct_edges_callback(pnt_time, pnt_facidx, pnt_value, plen); -} - -static void reconstruct_edges(void *user_data, uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value) -{ - FstData *ptr = (FstData*)user_data; - uint32_t plen = (pnt_value) ? strlen((const char *)pnt_value) : 0; - ptr->reconstruct_edges_callback(pnt_time, pnt_facidx, pnt_value, plen); -} - -void FstData::reconstruct_edges_callback(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t /* plen */) -{ - std::string val = std::string((const char *)pnt_value); - std::string prev = last_data[pnt_facidx]; - if (pnt_time>=start_time) { - if (prev!="1" && val=="1") - edges.push_back(pnt_time); - if (prev!="0" && val=="0") - edges.push_back(pnt_time); - } - last_data[pnt_facidx] = val; -} - -std::vector<uint64_t> FstData::getAllEdges(std::vector<fstHandle> &signal, uint64_t start, uint64_t end) -{ - start_time = start; - end_time = end; - last_data.clear(); - for(auto &s : signal) { - last_data[s] = "x"; - } - edges.clear(); - fstReaderSetLimitTimeRange(ctx, start_time, end_time); - fstReaderClrFacProcessMaskAll(ctx); - for(const auto sig : signal) - fstReaderSetFacProcessMask(ctx,sig); - fstReaderIterBlocks2(ctx, reconstruct_edges, reconstruct_edges_varlen, this, nullptr); - return edges; -} static void reconstruct_clb_varlen_attimes(void *user_data, uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen) { @@ -176,77 +133,65 @@ 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 (sample_times_ndx >= sample_times.size()) return; - - uint64_t time = sample_times[sample_times_ndx]; + if (pnt_time > end_time) return; // if we are past the timestamp - if (pnt_time > time) { - for (auto const& c : last_data) - { - handle_to_data[c.first].push_back(std::make_pair(time,c.second)); - size_t index = handle_to_data[c.first].size() - 1; - time_to_index[c.first][time] = index; + bool is_clock = false; + if (!all_samples) { + for(auto &s : clk_signals) { + if (s==pnt_facidx) { + is_clock=true; + break; + } } - sample_times_ndx++; } - // always update last_data - last_data[pnt_facidx] = std::string((const char *)pnt_value); -} -void FstData::reconstructAtTimes(std::vector<fstHandle> &signal, std::vector<uint64_t> time) -{ - handle_to_data.clear(); - time_to_index.clear(); - last_data.clear(); - sample_times_ndx = 0; - sample_times = time; - fstReaderSetUnlimitedTimeRange(ctx); - fstReaderClrFacProcessMaskAll(ctx); - for(const auto sig : signal) - fstReaderSetFacProcessMask(ctx,sig); - fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr); + if (pnt_time > past_time) { + past_data = last_data; + past_time = pnt_time; + } - if (time_to_index[signal.back()].count(time.back())==0) { - for (auto const& c : last_data) - { - handle_to_data[c.first].push_back(std::make_pair(time.back(),c.second)); - size_t index = handle_to_data[c.first].size() - 1; - time_to_index[c.first][time.back()] = index; + if (pnt_time > last_time) { + if (all_samples) { + callback(last_time); + last_time = pnt_time; + } else { + if (is_clock) { + std::string val = std::string((const char *)pnt_value); + std::string prev = past_data[pnt_facidx]; + if ((prev!="1" && val=="1") || (prev!="0" && val=="0")) { + callback(last_time); + last_time = pnt_time; + } + } } } + // always update last_data + last_data[pnt_facidx] = std::string((const char *)pnt_value); } -void FstData::reconstructAllAtTimes(std::vector<uint64_t> time) +void FstData::reconstructAllAtTimes(std::vector<fstHandle> &signal, uint64_t start, uint64_t end, CallbackFunction cb) { - handle_to_data.clear(); - time_to_index.clear(); + clk_signals = signal; + callback = cb; + start_time = start; + end_time = end; last_data.clear(); - sample_times_ndx = 0; - sample_times = time; + last_time = start_time; + past_data.clear(); + past_time = start_time; + all_samples = clk_signals.empty(); fstReaderSetUnlimitedTimeRange(ctx); fstReaderSetFacProcessMaskAll(ctx); fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr); - - if (time_to_index[1].count(time.back())==0) { - for (auto const& c : last_data) - { - handle_to_data[c.first].push_back(std::make_pair(time.back(),c.second)); - size_t index = handle_to_data[c.first].size() - 1; - time_to_index[c.first][time.back()] = index; - } - } + callback(last_time); + if (last_time!=end_time) + callback(end_time); } -std::string FstData::valueAt(fstHandle signal, uint64_t time) +std::string FstData::valueOf(fstHandle signal) { - if (handle_to_data.find(signal) == handle_to_data.end()) + if (past_data.find(signal) == past_data.end()) log_error("Signal id %d not found\n", (int)signal); - auto &data = handle_to_data[signal]; - if (time_to_index[signal].count(time)!=0) { - size_t index = time_to_index[signal][time]; - return data.at(index).second; - } else { - log_error("No data for signal %d at time %d\n", (int)signal, (int)time); - } + return past_data[signal]; } diff --git a/kernel/fstdata.h b/kernel/fstdata.h index c069ff5e5..707d1b64e 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -25,6 +25,9 @@ YOSYS_NAMESPACE_BEGIN +typedef std::function<void(uint64_t)> CallbackFunction; +struct fst_end_of_data_exception { }; + struct FstVar { fstHandle id; @@ -45,14 +48,10 @@ class FstData std::vector<FstVar>& getVars() { return vars; }; - void reconstruct_edges_callback(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen); - std::vector<uint64_t> getAllEdges(std::vector<fstHandle> &signal, uint64_t start_time, uint64_t end_time); - void reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen); - void reconstructAtTimes(std::vector<fstHandle> &signal,std::vector<uint64_t> time); - void reconstructAllAtTimes(std::vector<uint64_t> time); + void reconstructAllAtTimes(std::vector<fstHandle> &signal, uint64_t start_time, uint64_t end_time, CallbackFunction cb); - std::string valueAt(fstHandle signal, uint64_t time); + std::string valueOf(fstHandle signal); fstHandle getHandle(std::string name); double getTimescale() { return timescale; } const char *getTimescaleString() { return timescale_str.c_str(); } @@ -64,16 +63,17 @@ private: std::vector<FstVar> vars; std::map<fstHandle, FstVar> handle_to_var; std::map<std::string, fstHandle> name_to_handle; - std::map<fstHandle, std::vector<std::pair<uint64_t, std::string>>> handle_to_data; std::map<fstHandle, std::string> last_data; - std::map<fstHandle, std::map<uint64_t, size_t>> time_to_index; - std::vector<uint64_t> sample_times; - size_t sample_times_ndx; + uint64_t last_time; + std::map<fstHandle, std::string> past_data; + uint64_t past_time; double timescale; std::string timescale_str; uint64_t start_time; uint64_t end_time; - std::vector<uint64_t> edges; + CallbackFunction callback; + std::vector<fstHandle> clk_signals; + bool all_samples; }; YOSYS_NAMESPACE_END |