HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
wave_data_provider.cpp
Go to the documentation of this file.
5 #include <QDebug>
6 
7 namespace hal {
9  {
10  mWaveType = type;
11  mBits = bts;
12  mValueBase = base;
13  }
14 
16  {
17  mIter = mDataMap.lowerBound(t);
18 
19  SaleaeDataTuple retval; // assume empty
20 
21  if (mIter != mDataMap.constEnd() && mIter.key() == t)
22  {
23  //exact hit
24  retval.mTime = mIter.key();
25  retval.mValue = mIter.value();
26  ++mIter;
27  }
28  else if (mIter != mDataMap.constBegin())
29  {
30  //value of last data point before entering t-range
31  --mIter;
32  retval.mTime = mIter.key();
33  retval.mValue = mIter.value();
34  ++mIter;
35  }
36  else if (mIter != mDataMap.constEnd())
37  {
38  //no previous data but not empty
39  retval.mTime = t;
40  retval.mValue = -1;
41  }
42  return retval;
43  }
44 
46  {
47  if (mIter==mDataMap.constEnd())
48  return SaleaeDataTuple();
49 
50  SaleaeDataTuple retval(mIter.key(),mIter.value());
51  ++mIter;
52  return retval;
53  }
54 
55  //-----------------------------------------------------
57  {
58  if (mBuffer) delete mBuffer;
59  }
60 
62  {
63  mDataMap.clear();
65 
66  SaleaeDataTuple lastval;
67  SaleaeDataTuple retval;
68  if (!mInputFile.good())
69  return retval;
70 
71  bool skipData = true;
72 
73  int loadCycle = 0;
74 
75  while (skipData && mInputFile.good())
76  {
77  if (mBuffer) delete mBuffer;
79  mIndex = 0;
80  ++loadCycle;
81  if (!mBuffer) return SaleaeDataTuple();
82 
83  while (mIndex < mBuffer->mCount && mBuffer->mTimeArray[mIndex] < t)
84  {
86  lastval.mTime = mBuffer->mTimeArray[mIndex];
87  lastval.mValue = mBuffer->mValueArray[mIndex];
88  ++mIndex;
89  }
90 
91  skipData = (mBuffer->mTimeArray[mIndex] < t);
92  }
93 
94  if (mIndex < mBuffer->mCount && mBuffer->mTimeArray[mIndex] == t)
95  {
96  //exact hit
97  retval.mTime = mBuffer->mTimeArray[mIndex];
98  retval.mValue = mBuffer->mValueArray[mIndex];
100  ++mIndex;
101  }
102  else if (mIndex || loadCycle > 1)
103  {
104  //value of last data point before entering t-range
105  retval = lastval;
106  }
107  else if (mIndex < mBuffer->mCount)
108  {
109  //no previous data but not empty
110  retval.mTime = t;
111  retval.mValue = -1;
112  }
113  return retval;
114 
115  }
116 
118  {
123  else
124  {
127  {
128  mStoreData = Failed;
129  mDataMap.clear();
130  }
133  }
134  }
135 
137  {
139 
140  if (mIndex >= mBuffer->mCount)
141  {
142  if (!mInputFile.good()) return SaleaeDataTuple();
143  if (mBuffer) delete mBuffer;
145  mIndex = 0;
146  if (!mBuffer) return SaleaeDataTuple();
147  }
148 
150  ++mIndex;
151  return retval;
152  }
153 
154  //-----------------------------------------------------
155  int WaveDataProviderClock::valueForTransition() const
156  {
157  return mClock.start_at_zero ? (mTransition%2) : 1 - (mTransition%2);
158  }
159 
161  {
162  mTransition = t / mClock.switch_time;
163  SaleaeDataTuple retval(mTransition * mClock.switch_time, valueForTransition());
164  ++mTransition;
165  return retval;
166  }
167 
169  {
170  SaleaeDataTuple retval(mTransition * mClock.switch_time, valueForTransition());
171  ++mTransition;
172  return retval;
173  }
174 
175  //-----------------------------------------------------
176  WaveDataProviderGroup::WaveDataProviderGroup(const std::string& saleaeDirectoryPath, const QList<WaveData*>& wdList)
177  : mParser(saleaeDirectoryPath), mBitMask(nullptr), mCurrentTime(0), mSampleValue(-1), mValuePending(false), mEventReady(false)
178  {
179  if (wdList.isEmpty()) return;
180  int n = wdList.size();
181  mBitMask = new u32[n];
182  mLastValue = WaveGroupValue(n);
183  for (int i=0; i<n; i++)
184  {
185  WaveData* wd = wdList.at(i);
186  mBitMask[i] = 1 << (n-i-1);
187  mParser.register_callback(wd->name().toStdString(), wd->id(), [this](const void* obj, uint64_t t, int val) {
188  if (t != mCurrentTime)
189  {
190  mNextValue.mergePrevious(mLastValue);
191  mSampleValue = mNextValue.value();
192  mSampleTime = mCurrentTime;
193  mLastValue = mNextValue;
194  mCurrentTime = t;
195  mEventReady = true;
196  }
197  int mask = *((int*) obj);
198  mNextValue.setValue(mask,val);
199  }, mBitMask+i);
200  }
201  }
202 
204  {
205  if (mBitMask) delete [] mBitMask;
206  }
207 
208  bool WaveDataProviderGroup::nextEventReady()
209  {
210  while (mParser.next_event())
211  {
212  if (mEventReady)
213  {
214  mEventReady = false;
215  return true;
216  }
217  }
218  return false;
219  }
220 
222  {
223  u64 lastT = 0;
224  int lastVal = -1;
225  SaleaeDataTuple retval;
226  while (nextEventReady())
227  {
228  if (mSampleTime < t)
229  {
230  lastT = mSampleTime;
231  lastVal = mSampleValue;
232  }
233  else
234  {
235  if (mSampleTime == t)
236  {
237  retval.mTime = mSampleTime;
238  retval.mValue = mSampleValue;
239  }
240  else
241  {
242  retval.mTime = t;
243  retval.mValue = lastVal;
244  mValuePending = true;
245  }
246  return retval;
247  }
248  }
249  return retval;
250  }
251 
253  {
254  SaleaeDataTuple retval;
255  if (mValuePending)
256  {
257  mValuePending = false;
258  retval.mTime = mSampleTime;
259  retval.mValue = mSampleValue;
260  return retval;
261  }
262  if (nextEventReady())
263  {
264  retval.mTime = mSampleTime;
265  retval.mValue = mSampleValue;
266  }
267  return retval;
268  }
269 
270  //-----------------------------------------------------
271  WaveDataProviderBoolean::WaveDataProviderBoolean(const std::string& saleaeDirectoryPath, const QList<WaveData*>& wdList, const char *ttable)
272  : WaveDataProviderGroup(saleaeDirectoryPath,wdList), mTruthTable(nullptr)
273  {
274  mInputCount = wdList.size();
275  int n = (mInputCount + 7) / 8;
276  mTruthTable = new char[n];
277  memcpy(mTruthTable, ttable, n);
279  }
280 
282  {
283  if (mTruthTable) delete [] mTruthTable;
284  }
285 
286  SaleaeDataTuple WaveDataProviderBoolean::convertToBoolean(SaleaeDataTuple sdt)
287  {
288  if (sdt.mValue >= 0)
289  {
290  int j = sdt.mValue / 8;
291  int k = sdt.mValue % 8;
292  sdt.mValue = (mTruthTable[j] & (1<<k)) ? 1 : 0;
293  }
294  return sdt;
295  }
296 
298  {
299  return convertToBoolean(WaveDataProviderGroup::startValue(t));
300  }
301 
303  {
304  return convertToBoolean(WaveDataProviderGroup::nextPoint());
305  }
306 
307  //-----------------------------------------------------
308  WaveDataProviderTrigger::WaveDataProviderTrigger(const std::string& saleaeDirectoryPath, const QList<WaveData*>& wdList, const QList<int>& toValue, WaveData* filter)
309  : mParser(saleaeDirectoryPath), mFilter(filter), mTransitionToValue(nullptr), mCurrentTime(0), mCurrentTrigger(false), mReportedTime(-1)
310  {
311  int n = wdList.size();
312 
313  mTransitionToValue = new int[n];
314  for (int i=0; i<n; i++)
315  {
316  if (i < toValue.size())
317  mTransitionToValue[i] = toValue.at(i);
318  else
319  mTransitionToValue[i] = -1;
320  }
321 
322  for (int i=0; i<wdList.size(); i++)
323  {
324  WaveData* wd = wdList.at(i);
325  mParser.register_callback(wd->name().toStdString(), wd->id(), [this](const void* obj, uint64_t t, int val) {
326  if (t != mCurrentTime)
327  {
328  mCurrentTime = t;
329  mCurrentTrigger = false;
330  }
331  int transTo = *((int*) obj);
332  if (transTo<0 || val==transTo)
333  mCurrentTrigger = true;
334  }, mTransitionToValue+i);
335  }
336  setWaveType(WaveData::TriggerTime);
337  if (mFilter) mFilter->loadDataUnlessAlreadyLoaded();
338  }
339 
340  WaveDataProviderTrigger::~WaveDataProviderTrigger()
341  {
342  if (mTransitionToValue) delete [] mTransitionToValue;
343  }
344 
345  //TODO: recording?
346  SaleaeDataTuple WaveDataProviderTrigger::startValue(u64 t)
347  {
348  while (mParser.next_event())
349  if (mCurrentTime >= t && (qint64)mCurrentTime > mReportedTime && mCurrentTrigger)
350  {
351  if (mFilter)
352  {
353  if (!mFilter->intValue(mCurrentTime)) continue;
354  }
355  mReportedTime = mCurrentTime;
356  return SaleaeDataTuple(mCurrentTime,1);
357  }
358  return SaleaeDataTuple();
359  }
360 
361  SaleaeDataTuple WaveDataProviderTrigger::nextPoint()
362  {
363  while (mParser.next_event())
364  if ((qint64)mCurrentTime > mReportedTime && mCurrentTrigger)
365  {
366  if (mFilter)
367  {
368  if (!mFilter->intValue(mCurrentTime)) continue;
369  }
370  mReportedTime = mCurrentTime;
371  return SaleaeDataTuple(mCurrentTime,1);
372  }
373  return SaleaeDataTuple();
374  }
375 }
uint64_t mCount
Number of elements in buffer.
Definition: saleae_file.h:137
uint64_t * mTimeArray
Buffer for mCount transition time values.
Definition: saleae_file.h:140
int * mValueArray
Buffer for mCount data values.
Definition: saleae_file.h:143
int mValue
Data value.
Definition: saleae_file.h:171
uint64_t mTime
Transition time.
Definition: saleae_file.h:168
SaleaeDataBuffer * get_buffered_data(uint64_t nread)
Returns pointer to data buffer reading from current file position up to nread events....
bool next_event()
Call to parser to deliver next event via registered callbacks (see above).
bool register_callback(const std::string &name, uint32_t id, std::function< void(void *, uint64_t, int)> callback, void *obj)
Registers callback which gets executed upon next_event()
QString name() const
Definition: wave_data.h:104
u32 id() const
Definition: wave_data.h:103
WaveDataProviderBoolean(const std::string &saleaeDirectoryPath, const QList< WaveData * > &wdList, const char *ttable)
virtual SaleaeDataTuple startValue(u64 t) override
virtual SaleaeDataTuple nextPoint() override
virtual SaleaeDataTuple nextPoint() override
virtual SaleaeDataTuple startValue(u64 t) override
virtual SaleaeDataTuple nextPoint() override
SaleaeDataBuffer * mBuffer
virtual SaleaeDataTuple startValue(u64 t) override
const WaveDataTimeframe & mTimeframe
SaleaeInputFile & mInputFile
virtual SaleaeDataTuple nextPoint() override
WaveDataProviderGroup(const std::string &saleaeDirectoryPath, const QList< WaveData * > &wdList)
virtual SaleaeDataTuple startValue(u64 t) override
void setWaveType(WaveData::NetType type, int bts=1, int base=16)
virtual SaleaeDataTuple nextPoint() override
virtual SaleaeDataTuple startValue(u64 t) override
WaveDataProviderTrigger(const std::string &saleaeDirectoryPath, const QList< WaveData * > &wdList, const QList< int > &toValue, WaveData *filter=nullptr)
u64 sceneMaxTime() const
Definition: wave_data.cpp:1228
bool hasUserTimeframe() const
Definition: wave_data.cpp:1256
u64 sceneMinTime() const
Definition: wave_data.cpp:1242
void setValue(u32 mask, int val)
WaveGroupValue mergePrevious(const WaveGroupValue &previous) const
uint64_t u64
Definition: defines.h:42
uint32_t u32
Definition: defines.h:41
Definition: defines.h:45
PinType type
const T & at(int i) const const
bool isEmpty() const const
int size() const const
void clear()
QMap::const_iterator constBegin() const const
QMap::const_iterator constEnd() const const
const Key key(const T &value, const Key &defaultKey) const const
QMap::iterator lowerBound(const Key &key)
int size() const const
const T value(const Key &key, const T &defaultValue) const const
std::string toStdString() const const