38 void WaveDataClock::dataFactory()
49 : mId(other.mId), mFileIndex(other.mFileIndex), mFileSize(other.mFileSize), mTimeframeSize(other.mTimeframeSize),
50 mName(other.mName), mNetType(other.mNetType), mBits(other.mBits), mValueBase(other.mValueBase),
51 mData(other.mData), mDirty(true)
55 : mId(id_), mFileIndex(-1), mFileSize(0), mTimeframeSize(0), mName(nam), mNetType(tp), mBits(1), mValueBase(16), mData(dat), mDirty(true)
59 : mId(n->get_id()), mFileIndex(-1), mFileSize(0), mTimeframeSize(0),
60 mName(
QString::fromStdString(n->get_name())),
61 mNetType(tp), mBits(1), mValueBase(16), mDirty(true)
78 if (mFileSize < maxSizeLoadable)
return LoadAllData;
79 if (mTimeframeSize && mTimeframeSize < maxSizeLoadable)
return LoadTimeframe;
91 if (mName == nam)
return false;
105 int val = (int) bval;
112 if (it.value() == bval)
return;
146 if (mFileSize != other.mFileSize)
return false;
153 if (it.value() != jt.value())
return false;
154 if (abs((int64_t)it.key()-(int64_t)jt.key()) > tolerance)
return false;
162 std::vector<std::pair<u64,int>> evtsThis =
get_events(t0);
163 std::vector<std::pair<u64,int>> evtsOther = other.
get_events(t0);
164 if (evtsThis.empty()&&evtsOther.empty())
return true;
165 if (evtsThis.size()!=evtsOther.size())
return false;
166 auto jt = evtsOther.begin();
167 for (
auto it = evtsThis.begin(); it != evtsThis.end(); ++it)
169 if (it->second != jt->second)
return false;
170 if (abs((int64_t)it->first-(int64_t)jt->first)> tolerance)
return false;
185 std::vector<std::pair<u64,int>> retval = wdTrig->
get_events(t0);
186 for (
auto it=retval.begin(); it!=retval.end(); ++it)
196 std::vector<std::pair<u64,int>> retval;
200 retval.push_back(std::make_pair(it.key(),it.value()));
235 retval.push_back(std::make_pair(sdt.
mTime,sdt.
mValue));
275 if (path.empty())
return false;
277 if (!sif.good())
return false;
283 bool valuePending =
false;
299 valuePending =
false;
301 else if (!t1 || t <= t1)
305 valuePending =
false;
310 valuePending =
false;
362 u64 notFound = (
u64) floor(t);
370 if (it ==
mData.
end())
return notFound;
405 u64 retval = notFound;
406 for (
const WaveData* wd : childList)
408 double tChild = wd->neighborTransition(t,next);
409 if (tChild == notFound)
continue;
417 if (tChild < retval) retval = tChild;
421 if (tChild > retval) retval = tChild;
430 if (!sif.good())
return notFound;
467 if (!sif.good())
return -1;
492 case -2 :
return "z";
493 case -1 :
return "x";
495 if (
bits <= 1 || !val)
499 int mask = 1 << (
bits-1);
534 if (!wd->
id()) mCode = 0;
538 if (grp) construct (grp->
id(),
false);
539 else construct (wd->
id(),
true);
543 void WaveDataGroupIndex::construct(
u32 id,
bool isNet)
547 mCode = (
id << 1) | (isNet?0:1);
555 mInputWaves(nullptr), mTruthTable(nullptr)
558 if (!mInputCount)
return;
559 if (mInputCount > 16)
565 mInputWaves =
new WaveData*[mInputCount];
566 for (
int i = 0; i<mInputCount; i++)
567 mInputWaves[i] = boolInput.
at(i);
571 int truthTableLen = (1 << mInputCount);
572 int nByte = (truthTableLen+7) / 8;
573 mTruthTable =
new char[nByte];
574 memset (mTruthTable, 0, nByte);
576 for (
int accept : acceptMask)
580 mTruthTable[j] |= (1<<k);
587 mInputCount(0), mInputWaves(nullptr), mTruthTable(nullptr)
591 if (bf.is_error())
return;
592 std::vector<std::string> netNames;
593 for (std::string netName : bf.get().get_variable_names())
594 netNames.push_back(netName);
595 if ((mInputCount = netNames.size()) <= 0)
return;
596 if (mInputCount > 16)
601 mInputWaves =
new WaveData*[mInputCount];
604 for (
int i = 0; i<mInputCount; i++)
606 const std::string& netName = netNames.at(i);
618 auto tt = bf.get().compute_truth_table(netNames);
639 int truthTableLen = (1 << mInputCount);
640 int nByte = (truthTableLen+7) / 8;
641 mTruthTable =
new char[nByte];
642 memset (mTruthTable, 0, nByte);
643 for (
int i=0; i<truthTableLen; i++)
645 switch (tt.get().at(0).at(i))
656 mTruthTable[j] |= (1<<k);
666 delete [] mInputWaves;
677 if (mInputWaves)
delete [] mInputWaves;
678 if (mTruthTable)
delete [] mTruthTable;
689 for (
int i=0; i<mInputCount; i++)
690 if (mInputWaves[i]->
data().isEmpty())
699 for (
int i=0; i<mInputCount; i++)
702 for (
u64 t : mInputWaves[i]->
data().keys())
707 for (
u64 t : transitionTime.
keys())
710 for (
int i=0; i<mInputCount; i++)
713 if (val < 0 || val > 1)
728 nextval = (mTruthTable[j] & (1<<k)) ? 1 : 0;
730 if (nextval != lastval)
741 for (
int i=0; i<mInputCount; i++)
742 retval.
append(mInputWaves[i]);
749 for (
int i=0; i<mInputCount; i++)
751 const WaveData* wd = mInputWaves[i];
770 for (
int i=0; i<mInputCount; i++)
772 int childVal = mInputWaves[i]->
intValue(t);
773 if (childVal < 0)
return childVal;
774 if (childVal) val |= mask;
777 return (mTruthTable[val/8] & (1<<val%8)) ? 1 : 0;
782 :
WaveData(wdList->nextTriggerId(),
"",TriggerTime),
783 mTriggerCount(wdTrigger.
size()), mTriggerWaves(nullptr), mFilterWave(nullptr), mToValue(nullptr)
787 if (!mTriggerCount)
return;
788 mTriggerWaves =
new WaveData*[mTriggerCount];
789 mToValue =
new int[mTriggerCount];
790 int nVal = toVal.
size();
791 for (
int i=0; i<mTriggerCount; i++)
793 mTriggerWaves[i] = wdTrigger.
at(i);
794 mToValue[i] = i < nVal ? toVal[i] : -1;
796 wdList->registerTrigger(
this);
801 if (mTriggerWaves)
delete [] mTriggerWaves;
802 if (mToValue)
delete [] mToValue;
824 for (
int i=0; i<mTriggerCount; i++)
827 auto it = mTriggerWaves[i]->
data().
find(floor(t+0.5));
828 if (it != mTriggerWaves[i]->
data().constEnd())
830 if (mToValue[i] < 0 || mToValue[i] == it.value())
return 1;
847 for (
int i=0; i<mTriggerCount; i++)
848 if (mTriggerWaves[i]->
data().isEmpty())
852 for (
int i=0; i<mTriggerCount; i++)
857 for (
int i=0; i<mTriggerCount; i++)
858 for (
auto it = mTriggerWaves[i]->
data().constBegin(); it != mTriggerWaves[i]->
data().constEnd(); ++it)
859 if (mToValue[i] < 0 || mToValue[i] == it.value())
860 if (!mFilterWave || mFilterWave->
intValue(it.key())==1)
867 for (
int i=0; i<=mTriggerCount; i++)
871 wd = mTriggerWaves[i];
892 for (
int i=0; i<mTriggerCount; i++)
893 retval.
append(mTriggerWaves[i]);
910 return it.
key()>=t ? t : it.key();
919 for (
int i=0; i<mTriggerCount; i++)
920 retval.
append(mToValue[i]);
944 int n = wdGrp->
bits();
948 for (
int i=0; i<n; i++) bitValue[i] = new QMap<u64,int>();
956 for (
int i=0; i<n ; i++)
959 if ( (v&mask) != (lastV&mask) || first )
960 bitValue[i]->
insert(t, (v&mask) ? 1 : 0);
965 for (
int i=0; i<n; i++)
996 if (irow < 0)
return;
1006 std::vector<WaveData*> retval;
1035 if (
bits() >= 30)
return;
1120 if (inx < 0)
return;
1130 switch (wd->loadPolicy())
1158 for (
int ibit = 0; ibit < nChildren; ibit++)
1160 undef |= (1 << ibit);
1185 int ibit = it.value();
1186 int v = wdArray[ibit]->
data().
value(t0);
1187 int mask = (1 << (nChildren - ibit - 1));
1211 int childVal = wd->intValue(t);
1212 if (childVal < 0)
return childVal;
1213 if (childVal) retval |= mask;
1221 : mSceneMaxTime(sMinSceneWidth), mSimulateMaxTime(0), mUserdefMaxTime(0), mUserdefMinTime(0) {;}
1225 return mSimulateMaxTime;
1231 return mSceneMaxTime;
1236 if (t < sMinSceneWidth)
1237 mSceneMaxTime = sMinSceneWidth;
1252 if (x1 <= x0)
return 1;
1258 return mUserdefMaxTime > 0;
1263 mUserdefMinTime = t0;
1264 mUserdefMaxTime = t1;
1270 mSaleaeDirectory(sdFilename.toStdString()), mMaxGroupId(0), mMaxBooleanId(0), mMaxTriggerid(0)
1278 void WaveDataList::setMaxTime(
u64 tmax)
1280 if (mTimeframe.mSceneMaxTime == tmax)
return;
1283 bool mustUpdateClocks = (tmax > mTimeframe.mSceneMaxTime);
1297 mTimeframe.mSimulateMaxTime += deltaT;
1298 if (mTimeframe.mSimulateMaxTime > mTimeframe.mSceneMaxTime)
1299 setMaxTime(mTimeframe.mSimulateMaxTime);
1304 if (t0 == mTimeframe.mUserdefMinTime && t1 == mTimeframe.mUserdefMaxTime)
return;
1306 for (
auto it=
begin(); it!=
end(); ++it)
1327 for (
auto it=
begin(); it!=
end(); ++it)
1335 fprintf(stderr,
"WaveDataList:_________%8u______________\n", (
unsigned int) mTimeframe.mSimulateMaxTime);
1338 fprintf(stderr,
" %4d <%s>:", (*it)->id(), (*it)->name().toStdString().c_str());
1339 for (
auto jt = (*it)->data().begin(); jt != (*it)->data().end(); ++jt)
1340 fprintf(stderr,
" <%u,%d>", (
unsigned int) jt.key(), jt.value());
1341 fprintf(stderr,
"\n");
1349 if (
at(iwave)->rename(nam))
1360 if (grp && grp->
rename(nam))
1379 u32 netId =
at(inx)->id();
1381 if (it.value()->hasNetId(netId))
1395 auto it = mTrashCan.
begin();
1396 while (it != mTrashCan.
end())
1398 if ((*it)->hasSubscriber())
1403 it = mTrashCan.
erase(it);
1412 u32 netId = wd->
id();
1414 if (it.value()->hasNetId(netId))
1416 it.value()->recalcData();
1424 for (
auto it=
begin(); it!=
end(); ++it)
1432 void WaveDataList::updateMaxTime()
1437 u64 tmaxWave = (*it)->maxTime();
1438 if (tmaxWave > tmax) tmax = tmaxWave;
1440 if (tmax>mTimeframe.mSceneMaxTime)
1460 if (iwave<0)
return;
1467 u32 trigId = wdTrig->
id();
1473 sdce.add_child(wd->id());
1475 std::vector<int> toValue;
1477 toValue.push_back(tval);
1478 sdce.set_data(toValue);
1483 SaleaeDirectoryNetEntry filterEntry(wdFilt->name().toStdString(),wdFilt->id(),wdFilt->composedType());
1484 sdce.set_filter_entry(filterEntry.uniqueKey());
1490 void WaveDataList::registerBoolean(WaveDataBoolean *wdBool)
1492 u32 boolId = wdBool->id();
1497 for (WaveData* wd : wdBool->children())
1500 sdce.add_child(wd->id());
1502 std::vector<int> acceptVal;
1503 const char* ttable = wdBool->truthTable();
1504 for (
int i=0; i<n; i++)
1508 if (ttable[j] & (1<<k)) acceptVal.push_back(i);
1510 sdce.set_data(acceptVal);
1515 void WaveDataList::registerGroup(WaveDataGroup *grp)
1517 u32 grpId = grp->id();
1536 int inx = grp->
size();
1562 void WaveDataList::replaceWaveData(
int inx,
WaveData* wdNew)
1568 Q_ASSERT(wdOld != wdNew);
1573 if (grp->hasNetId(wdNew->
id()))
1574 grp->replaceChild(wdNew);
1575 if (wdNew->
maxTime() > mTimeframe.mSceneMaxTime)
1590 if (sdMaxTime > mTimeframe.mSimulateMaxTime)
incrementSimulTime(sdMaxTime-mTimeframe.mSimulateMaxTime);
1604 for (
int i=0; i<
size(); i++)
1607 auto it = saleaeWaves.
find(wd->
name());
1608 if (it == saleaeWaves.
end())
continue;
1614 mTrashCan.
append(it.value());
1615 saleaeWaves.
erase(it);
1618 for (
auto it=saleaeWaves.
begin(); it!=saleaeWaves.
end(); ++it)
1620 add(it.value(),
false);
1626 (*it)->recalcData();
1633 int inx = mIds.
value(wd->
id(),-1);
1635 replaceWaveData(inx, wd);
1642 if (!n)
return nullptr;
1665 if (wd->
name()==needle)
1668 if (wdb->name()==needle)
1679 if (wdb->id() ==
id)
1684 void WaveDataList::testDoubleCount()
1696 ++doubleCount[wd->
id()];
1702 log_warning(
"simulation_plugin",
"Duplicate waveform ({}x) found : '{}'", it.value(),
at(mIds.
value(it.key()))->name().toStdString());
1709 log_warning(
"simulation_plugin",
"Waveform not in (partial) netlist : '{}'",
name.toStdString());
1711 mNotInNetlist += notInNetlist;
1715 void WaveDataList::restoreIndex()
1720 for (
const WaveData* wd : *
this)
1721 mIds[wd->id()] = inx++;
1728 return keyList.
toSet();
1734 auto it = mIds.
find(
id);
1735 if (it == mIds.
end())
return;
1736 int inx = it.
value();
1741 mTrashCan.
append(toDelete);
1750 if ((*it)->data().isEmpty())
1752 (*it)->insert(0,val);
static Result< BooleanFunction > from_string(const std::string &expression)
Value
represents the type of the node
static SimulationSettings * sSimulationSettings
uint64_t mCount
Number of elements in buffer.
uint64_t * mTimeArray
Buffer for mCount transition time values.
int * mValueArray
Buffer for mCount data values.
static const int sReadError
Fake data value to indicate all kind of errors.
uint64_t mTime
Transition time.
bool readError() const
Indicates that there was an error and no data was returned.
The SaleaeDirectoryComposedEntry class represents a composed waveform. There are currently three type...
void add_child(int key)
Add an additional child key to composed.
void set_filter_entry(int filt)
Setter for filter pointer described above.
bool isNull() const
Test for null.
The SaleaeDirectoryFileIndex class represents a single SALEAE data file. The class comprises the inde...
The SaleaeDirectory class provides the API for the SALEAE directory file. The SALEAE directory file w...
void rename_net(uint32_t id, const std::string &nam)
Change waveform name entry for net identified by id.
int get_datafile_index(const std::string &nam, uint32_t id) const
Get waveform datafile index for net identified by name and id.
void add_or_replace_net(SaleaeDirectoryNetEntry &sdne)
Add net entry if not yet existing, replace existing entry otherwise.
bool parse_json()
Parse .json file into class instance.
std::string get_directory() const
Get path to SALEAE directory without filename.
void add_or_replace_composed(SaleaeDirectoryComposedEntry sdce)
Add composed waveform entry (Group, Boolean, Trigger)
int get_next_available_index() const
Getter for next available file index ('digital_XXX.bin' with lowest number XXX not in use)
void remove_composed(uint32_t id, SaleaeDirectoryNetEntry::Type tp)
Remove composed waveform entry identified by id an type.
SaleaeDirectoryComposedEntry get_composed(uint32_t id, SaleaeDirectoryNetEntry::Type tp) const
Getter for pointer to composed waveform entry allowing modifications.
std::vector< ListEntry > get_net_list() const
Getter for all net entries.
std::string get_datafile_path(int index) const
Get full path to waveform data file.
std::string get_filename() const
Get full path to saleae directory file including filename (/.../saleae.json)
uint64_t get_max_time() const
Getter for maximum time.
The SaleaeDirectoryNetEntry class represents a regular waveform for a single simulated net....
int uniqueKey() const
Unique key as reference (used e.g. in mComposedEntryMap)
void addIndex(const SaleaeDirectoryFileIndex &sdfe)
Add index for binary file to net entry instance.
The SaleaeDirectoryStoreRequest class is useful to bundle requests for updating SALEAE directory....
void put_data(SaleaeDataBuffer *buf)
Write buffered data.
int maxSizeLoadable() const
WaveDataBoolean(WaveDataList *wdList, QString boolFunc)
QList< WaveData * > children() const
const char * truthTable() const
virtual int intValue(double t) const override
virtual LoadPolicy loadPolicy() const override
WaveDataClock(const Net *n, const SimulationInput::Clock &clk, u64 tmax)
void setMaxTime(u64 tmax)
virtual void replaceChild(WaveData *wd)
QList< int > childrenWaveIndex() const
virtual void updateWaveData(WaveData *wd)
virtual void recalcData()
virtual WaveData * childAt(int inx) const
std::vector< WaveData * > get_waveforms() const
virtual int bits() const override
void remove_waveform(WaveData *wd)
void addNet(const Net *n)
virtual LoadPolicy loadPolicy() const override
virtual void addWaves(const QVector< WaveData * > &wds)
virtual QList< WaveData * > children() const
virtual int intValue(double t) const override
virtual void insert(int inx, WaveData *wd)
virtual int childIndex(WaveData *wd) const
WaveDataGroup(WaveDataList *wdList, int grpId, const QString &nam)
void add_waveform(WaveData *wd)
virtual WaveData * removeAt(int inx)
QList< WaveData * > mGroupList
virtual int netIndex(u32 id) const
QHash< WaveDataGroupIndex, int > mIndex
virtual bool hasNetId(u32 id) const
WaveDataGroupIndex(const WaveData *wd)
void setData(const QMap< u64, int > &dat)
SaleaeDirectoryNetEntry::Type composedType() const
virtual u64 neighborTransition(double t, bool next) const
bool loadSaleae(const WaveDataTimeframe &tframe=WaveDataTimeframe())
bool isEqual(const WaveData &other, int tolerance=0) const
std::string get_name() const
std::vector< std::pair< u64, int > > get_events(u64 t0=0) const
void setFileSize(u64 siz)
static QString stringValue(int val, int bits, int base)
bool rename(const QString &nam)
virtual int intValue(double t) const
std::vector< std::pair< u64, int > > get_triggered_events(const WaveDataTrigger *wdTrig, u64 t0=0)
virtual LoadPolicy loadPolicy() const
WaveData(const WaveData &other)
void setWaveDataList(WaveDataList *wdList)
void loadDataUnlessAlreadyLoaded()
const QMap< u64, int > & data() const
QMap< u64, int >::const_iterator timeIterator(double t) const
void setTimeframeSize(u64 siz)
WaveDataList * mWaveDataList
std::string fileName() const
void insertBooleanValueWithoutSync(u64 t, BooleanFunction::Value bval)
void setFileIndex(int saleaIndex)
QString strValue(int val) const
void updateWaveName(int iwave, const QString &nam)
QMap< u32, WaveDataGroup * > mDataGroups
void waveUpdated(int inx, int grpId)
WaveData * waveDataByName(const std::string &nam) const
void emitWaveRemovedFromGroup(int iwave, int grpId)
void booleanAdded(int boolId)
void addWavesToGroup(u32 grpId, const QVector< WaveData * > &wds)
void waveRemovedFromGroup(int iwave, int grpId)
QMap< u32, WaveDataBoolean * > mDataBooleans
void emitWaveUpdated(int inx)
void add(WaveData *wd, bool updateSaleae)
void updateGroupName(u32 grpId, const QString &nam)
void triggerEndResetModel()
int waveIndexByNetId(u32 id) const
bool hasNet(u32 id) const
SaleaeDirectory & saleaeDirectory()
void addOrReplace(WaveData *wd)
void groupAdded(int grpId)
void waveRemoved(int inx)
void waveRenamed(int iwave)
void setValueForEmpty(int val)
WaveData * waveDataById(const int id)
void timeframeChanged(const hal::WaveDataTimeframe *tframe)
const WaveDataTimeframe & timeFrame() const
void emitTimeframeChanged()
WaveData * waveDataByNet(const Net *n)
void incrementSimulTime(u64 deltaT)
void setUserTimeframe(u64 t0=0, u64 t1=0)
void triggerAdded(int trigId)
void groupRenamed(int grpId)
WaveDataList(const QString &sdFilename, QObject *parent=nullptr)
QSet< u32 > toSet() const
void triggerAddToView(u32 id) const
void removeGroup(u32 grpId)
void emitWaveAdded(int inx)
void emitGroupUpdated(int grpId)
void groupAboutToBeRemoved(hal::WaveDataGroup *grp)
void insertBooleanValue(WaveData *wd, u64 t, BooleanFunction::Value bval)
void triggerBeginResetModel()
void groupUpdated(int grpId)
void waveAddedToGroup(const QVector< u32 > &netIds, int grpId)
void updateWaveData(int inx)
QMap< u32, WaveDataTrigger * > mDataTrigger
virtual SaleaeDataTuple nextPoint()=0
virtual SaleaeDataTuple startValue(u64 t)=0
bool hasUserTimeframe() const
void setSceneMaxTime(u64 t)
u64 simulateMaxTime() const
void setUserTimeframe(u64 t0=0, u64 t1=0)
virtual u64 neighborTransition(double t, bool next) const override
void set_filter_wave(WaveData *wd)
virtual int intValue(double t) const override
QList< int > toValueList() const
QList< WaveData * > children() const
WaveData * get_filter_wave() const
virtual LoadPolicy loadPolicy() const override
WaveDataTrigger(WaveDataList *wdList, const QList< WaveData * > &wdTrigger, const QList< int > &toVal=QList< int >())
#define log_warning(channel,...)
bool save(std::filesystem::path file_path, GateLibrary *gate_lib, bool overwrite=false)
uint qHash(const LaneIndex &ri)
QString absolutePath() const const
bool exists() const const
bool mkpath(const QString &dirPath) const const
void append(const T &value)
const T & at(int i) const const
QList::const_iterator constBegin() const const
QList::const_iterator constEnd() const const
QList::iterator erase(QList::iterator pos)
void insert(int i, const T &value)
bool isEmpty() const const
const T & operator[](int i) const const
QSet< T > toSet() const const
const Key & key() const const
const Key & key() const const
QMap::const_iterator constBegin() const const
QMap::const_iterator constEnd() const const
QMap::iterator erase(QMap::iterator pos)
QMap::iterator find(const Key &key)
const Key & firstKey() const const
QMap::iterator insert(const Key &key, const T &value)
bool isEmpty() const const
const Key key(const T &value, const Key &defaultKey) const const
QList< Key > keys() const const
const Key & lastKey() const const
QMap::iterator lowerBound(const Key &key)
QMap::iterator upperBound(const Key &key)
const T value(const Key &key, const T &defaultValue) const const
typename QMap< Key, T >::iterator insert(const Key &key, const T &value)
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
bool isEmpty() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
QString number(int n, int base)
std::string toStdString() const const
void append(const T &value)
QList< T > toList() const const