mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-23 09:05:32 +00:00
Add support for various ff/latch cells simulation
This commit is contained in:
parent
1586000048
commit
fb22d7cdc4
3 changed files with 260 additions and 171 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pnt_time > past_time) {
|
||||
past_data = last_data;
|
||||
past_time = pnt_time;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
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;
|
||||
fstReaderSetUnlimitedTimeRange(ctx);
|
||||
fstReaderClrFacProcessMaskAll(ctx);
|
||||
for(const auto sig : signal)
|
||||
fstReaderSetFacProcessMask(ctx,sig);
|
||||
fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FstData::reconstructAllAtTimes(std::vector<uint64_t> time)
|
||||
{
|
||||
handle_to_data.clear();
|
||||
time_to_index.clear();
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue