aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2022-02-15 09:30:42 +0100
committerMiodrag Milanovic <mmicko@gmail.com>2022-02-16 13:27:59 +0100
commitfb22d7cdc411ec52672cb7f13364651c564872db (patch)
tree0b69b27f9806a39772b0980f7c8ab701234e754f /kernel
parent15860000487e2d6748843888b78289f95f3ea46b (diff)
downloadyosys-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.cc141
-rw-r--r--kernel/fstdata.h22
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