adds working FST reader implementation
This commit is contained in:
parent
299f76323f
commit
e44e4d0a05
|
@ -4,4 +4,5 @@ bin.includes = META-INF/,\
|
||||||
.,\
|
.,\
|
||||||
lib/jna-5.13.0.jar,\
|
lib/jna-5.13.0.jar,\
|
||||||
lib/jna-jpms-5.13.0.jar,\
|
lib/jna-jpms-5.13.0.jar,\
|
||||||
linux-x86-64/
|
linux-x86-64/,\
|
||||||
|
OSGI-INF/
|
||||||
|
|
|
@ -5,7 +5,7 @@ project (fstlib VERSION 1.0.0)
|
||||||
set(BUILD_SHARED_LIBS ON)
|
set(BUILD_SHARED_LIBS ON)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
|
|
||||||
add_library(fstapi fstapi.c lz4.c fastlz.c)
|
add_library(fstapi fstapi.c lz4.c fastlz.c fst_helper.c)
|
||||||
target_include_directories(fstapi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIRS})
|
target_include_directories(fstapi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||||
target_link_libraries(fstapi PRIVATE ${ZLIB_LIBRARIES})
|
target_link_libraries(fstapi PRIVATE ${ZLIB_LIBRARIES})
|
||||||
# hack to avoid creating dummy config.h
|
# hack to avoid creating dummy config.h
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
cmake -B build -S . -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=../../linux-x86-64
|
||||||
|
cmake --build build --target install
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "fstapi.h"
|
||||||
|
|
||||||
|
int getHierType(struct fstHier * hier){
|
||||||
|
return hier->htyp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getHierScope(struct fstHier* h, struct fstHierScope* scope){
|
||||||
|
if(h->htyp==FST_HT_SCOPE)
|
||||||
|
*scope=h->u.scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getHierVar(struct fstHier* h, struct fstHierVar* var){
|
||||||
|
if(h->htyp==FST_HT_VAR)
|
||||||
|
*var=h->u.var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getHierAttr(struct fstHier* h, struct fstHierAttr* attr){
|
||||||
|
if(h->htyp==FST_HT_ATTRBEGIN)
|
||||||
|
*attr=h->u.attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*value_change_callback)(uint64_t time, fstHandle facidx, const char *value);
|
||||||
|
|
||||||
|
static void forward_cb(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value) {
|
||||||
|
//fprintf(stderr, "val: %s @ %ld\n", value, time);
|
||||||
|
((value_change_callback)user_callback_data_pointer)(time, facidx, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterateValueChanges(void* ctx, value_change_callback vcc) {
|
||||||
|
fstReaderIterBlocks(ctx, forward_cb, vcc, NULL);
|
||||||
|
}
|
Binary file not shown.
|
@ -13,22 +13,18 @@ package com.minres.scviewer.database.fst;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.minres.scviewer.database.BitVector;
|
import com.minres.scviewer.database.BitVector;
|
||||||
import com.minres.scviewer.database.DoubleVal;
|
import com.minres.scviewer.database.DoubleVal;
|
||||||
|
import com.minres.scviewer.database.EventList;
|
||||||
import com.minres.scviewer.database.IEventList;
|
import com.minres.scviewer.database.IEventList;
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
|
||||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||||
import com.minres.scviewer.database.InputFormatException;
|
import com.minres.scviewer.database.InputFormatException;
|
||||||
import com.minres.scviewer.database.RelationType;
|
import com.minres.scviewer.database.RelationType;
|
||||||
|
@ -39,59 +35,56 @@ import com.minres.scviewer.database.RelationType;
|
||||||
public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
||||||
|
|
||||||
|
|
||||||
/** The Constant TIME_RES. */
|
|
||||||
private static final Long TIME_RES = 1000L; // ps
|
|
||||||
|
|
||||||
/** The module stack. */
|
/** The module stack. */
|
||||||
private ArrayDeque<String> moduleStack;
|
private ArrayDeque<String> moduleStack;
|
||||||
|
|
||||||
/** The signals. */
|
/** The signals. */
|
||||||
private List<IWaveform> signals;
|
private List<IWaveform> signals;
|
||||||
|
|
||||||
|
FstFileParser parser;
|
||||||
/** The max time. */
|
/** The max time. */
|
||||||
private long maxTime;
|
private long maxTime;
|
||||||
|
|
||||||
|
private int timeScale;
|
||||||
|
|
||||||
/** The pcs. */
|
/** The pcs. */
|
||||||
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
|
|
||||||
|
static int calculateTimescaleMultipierPower(int power){
|
||||||
|
int answer = 1;
|
||||||
|
if(power<=0){
|
||||||
|
return answer;
|
||||||
|
} else{
|
||||||
|
for(int i = 1; i<= power; i++)
|
||||||
|
answer *= 10;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
public void load(File file) throws InputFormatException {
|
||||||
dispose();
|
dispose();
|
||||||
this.maxTime=0;
|
this.maxTime=0;
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
signals = new Vector<>();
|
signals = new Vector<>();
|
||||||
moduleStack= new ArrayDeque<>();
|
moduleStack= new ArrayDeque<>();
|
||||||
res = new FstFileParser(file).load(this);
|
parser = new FstFileParser(file);
|
||||||
|
res = parser.open(this);
|
||||||
moduleStack=null;
|
moduleStack=null;
|
||||||
if(!res)
|
if(!res)
|
||||||
throw new InputFormatException("Could not parse VCD file");
|
throw new InputFormatException("Could not parse VCD file");
|
||||||
// calculate max time of this database
|
// calculate max time of this database
|
||||||
for(IWaveform waveform:signals) {
|
|
||||||
IEventList events =waveform.getEvents();
|
|
||||||
if(!events.isEmpty())
|
|
||||||
maxTime= Math.max(maxTime, events.lastKey());
|
|
||||||
}
|
|
||||||
// extend signals to have a last value set at max time
|
|
||||||
for(IWaveform s:signals){
|
|
||||||
if(s instanceof FstSignal<?>) {
|
|
||||||
IEventList events = ((FstSignal<?>)s).getEvents();
|
|
||||||
if(events.size()>0 && events.lastKey()<maxTime){
|
|
||||||
Object val = events.lastEntry().events[0];
|
|
||||||
if(val instanceof BitVector) {
|
|
||||||
((FstSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
|
|
||||||
} else if(val instanceof DoubleVal)
|
|
||||||
((FstSignal<DoubleVal>)s).addSignalChange(maxTime, (DoubleVal) val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null);
|
pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
if(parser!=null) {
|
||||||
|
parser.close();
|
||||||
|
parser=null;
|
||||||
|
}
|
||||||
moduleStack=null;
|
moduleStack=null;
|
||||||
signals=null;
|
signals=null;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +94,7 @@ public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long getMaxTime() {
|
public long getMaxTime() {
|
||||||
return maxTime;
|
return maxTime*calculateTimescaleMultipierPower(15+timeScale); // timescape is 1e(timeScale), we calculate in fs
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -136,20 +129,14 @@ public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public Integer newNet(String name, int i, int width) {
|
public void newNet(String name, int handle, int width, boolean alias) {
|
||||||
String netName = moduleStack.isEmpty()? name: moduleStack.peek()+"."+name;
|
String netName = moduleStack.isEmpty()? name: moduleStack.peek()+"."+name;
|
||||||
int id = signals.size();
|
IWaveform signal = width==0?
|
||||||
if(width==0) {
|
new FstSignal<DoubleVal>(this, handle, netName, width):
|
||||||
signals.add( i<0 ? new FstSignal<DoubleVal>(id, netName, width) :
|
new FstSignal<BitVector>(this, handle, netName, width);
|
||||||
new FstSignal<DoubleVal>((FstSignal<DoubleVal>)signals.get(i), id, netName));
|
signals.add(signal);
|
||||||
} else if(width>0){
|
|
||||||
signals.add( i<0 ? new FstSignal<BitVector>(id, netName, width) :
|
|
||||||
new FstSignal<BitVector>((FstSignal<BitVector>)signals.get(i), id, netName));
|
|
||||||
}
|
|
||||||
pcs.firePropertyChange(IWaveformDbLoader.SIGNAL_ADDED, null, Iterables.getLast(signals));
|
pcs.firePropertyChange(IWaveformDbLoader.SIGNAL_ADDED, null, Iterables.getLast(signals));
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -161,28 +148,10 @@ public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
||||||
return signal.getRowCount();
|
return signal.getRowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public void setMaxTime(long maxTime, int timeScale) {
|
||||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
|
this.maxTime = maxTime;
|
||||||
*/
|
this.timeScale=timeScale;
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void appendTransition(int signalId, long currentTime, BitVector value) {
|
|
||||||
FstSignal<BitVector> signal = (FstSignal<BitVector>) signals.get(signalId);
|
|
||||||
Long time = currentTime* TIME_RES;
|
|
||||||
signal.addSignalChange(time, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void appendTransition(int signalId, long currentTime, double value) {
|
|
||||||
FstSignal<DoubleVal> signal = (FstSignal<DoubleVal>) signals.get(signalId);
|
|
||||||
Long time = currentTime* TIME_RES;
|
|
||||||
signal.addSignalChange(time, new DoubleVal(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
|
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
|
||||||
*/
|
*/
|
||||||
|
@ -211,5 +180,8 @@ public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
|
||||||
pcs.removePropertyChangeListener(l);
|
pcs.removePropertyChangeListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getEvents(int id, int width, IEventList values) {
|
||||||
|
if(values instanceof EventList)
|
||||||
|
parser.getValueChanges(id, width, calculateTimescaleMultipierPower(15+timeScale), (EventList) values);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,30 +10,84 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database.fst;
|
package com.minres.scviewer.database.fst;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.BitValue;
|
|
||||||
import com.minres.scviewer.database.BitVector;
|
import com.minres.scviewer.database.BitVector;
|
||||||
|
import com.minres.scviewer.database.EventList;
|
||||||
|
import com.minres.scviewer.database.fst.FstLibrary.HierAttr;
|
||||||
|
import com.minres.scviewer.database.fst.FstLibrary.HierScope;
|
||||||
|
import com.minres.scviewer.database.fst.FstLibrary.HierType;
|
||||||
|
import com.minres.scviewer.database.fst.FstLibrary.HierVar;
|
||||||
|
import com.minres.scviewer.database.fst.FstLibrary.ValueChangeCallback;
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
|
||||||
class FstFileParser {
|
class FstFileParser {
|
||||||
long currentTime;
|
long currentTime;
|
||||||
final File file;
|
final File file;
|
||||||
|
Pointer fst;
|
||||||
|
|
||||||
public FstFileParser(File file) {
|
public FstFileParser(File file) {
|
||||||
this.file=file;
|
this.file=file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean load(IFstDatabaseBuilder builder) {
|
public boolean open(IFstDatabaseBuilder builder) {
|
||||||
Pointer ctx = FstLibrary.fstReaderOpen(file.getAbsolutePath());
|
fst = FstLibrary.fstReaderOpen(file.getAbsolutePath());
|
||||||
if(!ctx.equals(Pointer.NULL)) {
|
if(!fst.equals(Pointer.NULL)) {
|
||||||
String version = FstLibrary.fstReaderGetVersionString(ctx);
|
String version = FstLibrary.fstReaderGetVersionString(fst);
|
||||||
System.out.println(version);
|
System.out.println(version);
|
||||||
FstLibrary.fstReaderClose(ctx);
|
long endTime = FstLibrary.fstReaderGetEndTime(fst);
|
||||||
}
|
byte timeScale = FstLibrary.fstReaderGetTimescale(fst);
|
||||||
return false;
|
builder.setMaxTime(endTime, timeScale);
|
||||||
|
FstLibrary.fstReaderIterateHierRewind(fst);
|
||||||
|
Pointer p = FstLibrary.fstReaderIterateHier(fst);
|
||||||
|
while(p!=null && !p.equals(Pointer.NULL)) {
|
||||||
|
int hierType = FstLibrary.getHierType(p);
|
||||||
|
HierType type = HierType.values()[hierType];
|
||||||
|
switch(type) {
|
||||||
|
case HT_SCOPE:
|
||||||
|
HierScope scope = new HierScope();
|
||||||
|
FstLibrary.getHierScope(p, scope);
|
||||||
|
builder.enterModule(scope.name);
|
||||||
|
break;
|
||||||
|
case HT_UPSCOPE:
|
||||||
|
builder.exitModule();
|
||||||
|
break;
|
||||||
|
case HT_VAR:
|
||||||
|
HierVar v = new HierVar();
|
||||||
|
FstLibrary.getHierVar(p, v);
|
||||||
|
builder.newNet(v.name, v.handle, v.length, v.is_alias!=0);
|
||||||
|
break;
|
||||||
|
case HT_ATTRBEGIN:
|
||||||
|
HierAttr attr = new HierAttr();
|
||||||
|
FstLibrary.getHierAttr(p, attr);
|
||||||
|
break;
|
||||||
|
case HT_ATTREND:
|
||||||
|
break;
|
||||||
|
case HT_TREEBEGIN:
|
||||||
|
break;
|
||||||
|
case HT_TREEEND:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = FstLibrary.fstReaderIterateHier(fst);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getValueChanges(final int id, final int width, int timeScale, final EventList values) {
|
||||||
|
FstLibrary.fstReaderSetFacProcessMask(fst, id);
|
||||||
|
FstLibrary.iterateValueChanges(fst, new ValueChangeCallback() {
|
||||||
|
@Override
|
||||||
|
public void callback(long time, int facidx, String value) {
|
||||||
|
values.put(time*timeScale, BitVector.fromString(width, value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void close() {
|
||||||
|
FstLibrary.fstReaderClose(fst);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,12 @@ package com.minres.scviewer.database.fst;
|
||||||
import com.sun.jna.Native;
|
import com.sun.jna.Native;
|
||||||
import com.sun.jna.Platform;
|
import com.sun.jna.Platform;
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
import com.sun.jna.Structure;
|
||||||
|
import com.sun.jna.Structure.FieldOrder;
|
||||||
|
import com.sun.jna.Callback;
|
||||||
|
|
||||||
public class FstLibrary {
|
public class FstLibrary {
|
||||||
public enum FstScopeType {
|
public static enum ScopeType {
|
||||||
MIN(0),
|
MIN(0),
|
||||||
VCD_MODULE(0),
|
VCD_MODULE(0),
|
||||||
VCD_TASK(1),
|
VCD_TASK(1),
|
||||||
|
@ -31,74 +34,178 @@ public class FstLibrary {
|
||||||
VHDL_GENERATE(20),
|
VHDL_GENERATE(20),
|
||||||
VHDL_PACKAGE(21),
|
VHDL_PACKAGE(21),
|
||||||
MAX(21),
|
MAX(21),
|
||||||
FST_ST_GEN_ATTRBEGIN(252),
|
ST_GEN_ATTRBEGIN(252),
|
||||||
FST_ST_GEN_ATTREND(253),
|
ST_GEN_ATTREND(253),
|
||||||
|
|
||||||
FST_ST_VCD_SCOPE(254),
|
ST_VCD_SCOPE(254),
|
||||||
FST_ST_VCD_UPSCOPE(255);
|
ST_VCD_UPSCOPE(255);
|
||||||
|
|
||||||
public final int label;
|
public final int label;
|
||||||
private FstScopeType(int label) {
|
private ScopeType(int label) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
public static enum HierType {
|
||||||
|
HT_SCOPE(0),
|
||||||
|
HT_UPSCOPE(1),
|
||||||
|
HT_VAR(2),
|
||||||
|
HT_ATTRBEGIN(3),
|
||||||
|
HT_ATTREND(4),
|
||||||
|
HT_TREEBEGIN(5),
|
||||||
|
HT_TREEEND(6);
|
||||||
|
public final int type;
|
||||||
|
private HierType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static enum VarType {
|
||||||
|
FST_VT_VCD_EVENT (0),
|
||||||
|
FST_VT_VCD_INTEGER (1),
|
||||||
|
FST_VT_VCD_PARAMETER (2),
|
||||||
|
FST_VT_VCD_REAL (3),
|
||||||
|
FST_VT_VCD_REAL_PARAMETER (4),
|
||||||
|
FST_VT_VCD_REG (5),
|
||||||
|
FST_VT_VCD_SUPPLY0 (6),
|
||||||
|
FST_VT_VCD_SUPPLY1 (7),
|
||||||
|
FST_VT_VCD_TIME (8),
|
||||||
|
FST_VT_VCD_TRI (9),
|
||||||
|
FST_VT_VCD_TRIAND (10),
|
||||||
|
FST_VT_VCD_TRIOR (11),
|
||||||
|
FST_VT_VCD_TRIREG (12),
|
||||||
|
FST_VT_VCD_TRI0 (13),
|
||||||
|
FST_VT_VCD_TRI1 (14),
|
||||||
|
FST_VT_VCD_WAND (15),
|
||||||
|
FST_VT_VCD_WIRE (16),
|
||||||
|
FST_VT_VCD_WOR (17),
|
||||||
|
FST_VT_VCD_PORT (18),
|
||||||
|
FST_VT_VCD_SPARRAY (19), /* used to define the rownum (index) port for a sparse array */
|
||||||
|
FST_VT_VCD_REALTIME (20),
|
||||||
|
|
||||||
|
FST_VT_GEN_STRING (21), /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
|
||||||
|
|
||||||
|
FST_VT_SV_BIT (22),
|
||||||
|
FST_VT_SV_LOGIC (23),
|
||||||
|
FST_VT_SV_INT (24), /* declare as size = 32 */
|
||||||
|
FST_VT_SV_SHORTINT (25), /* declare as size = 16 */
|
||||||
|
FST_VT_SV_LONGINT (26), /* declare as size = 64 */
|
||||||
|
FST_VT_SV_BYTE (27), /* declare as size = 8 */
|
||||||
|
FST_VT_SV_ENUM (28), /* declare as appropriate type range */
|
||||||
|
FST_VT_SV_SHORTREAL (29); /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
|
||||||
|
public final int varType;
|
||||||
|
private VarType(int varType) {
|
||||||
|
this.varType = varType;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static enum AttrType {
|
||||||
|
FST_AT_MISC ( 0), /* self-contained: does not need matching FST_HT_ATTREND */
|
||||||
|
FST_AT_ARRAY ( 1),
|
||||||
|
FST_AT_ENUM ( 2),
|
||||||
|
FST_AT_PACK ( 3);
|
||||||
|
public final int attrType;
|
||||||
|
private AttrType(int attrType) {
|
||||||
|
this.attrType = attrType;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@FieldOrder({"type","name","component", "name_length", "component_length"})
|
||||||
|
public static class HierScope extends Structure {
|
||||||
|
public byte type; /* FST_ST_MIN ... FST_ST_MAX */
|
||||||
|
public String name;
|
||||||
|
public String component;
|
||||||
|
public int name_length; /* strlen(u.scope.name) */
|
||||||
|
public int component_length; /* strlen(u.scope.component) */
|
||||||
|
};
|
||||||
|
|
||||||
|
@FieldOrder({"type","direction","svt_workspace", "sdt_workspace", "sxt_workspace", "name","length","handle","name_length", "is_alias"})
|
||||||
|
public static class HierVar extends Structure {
|
||||||
|
public byte type; /* FST_VT_MIN ... FST_VT_MAX */
|
||||||
|
public byte direction; /* FST_VD_MIN ... FST_VD_MAX */
|
||||||
|
public byte svt_workspace; /* zeroed out by FST reader, for client code use */
|
||||||
|
public byte sdt_workspace; /* zeroed out by FST reader, for client code use */
|
||||||
|
public int sxt_workspace; /* zeroed out by FST reader, for client code use */
|
||||||
|
public String name;
|
||||||
|
public int length;
|
||||||
|
public int handle; /*fstHandle*/
|
||||||
|
public int name_length; /* strlen(u.var.name) */
|
||||||
|
public int is_alias;
|
||||||
|
};
|
||||||
|
|
||||||
|
@FieldOrder({"type","subtype","name", "arg", "arg_from_name", "name_length"})
|
||||||
|
public static class HierAttr extends Structure {
|
||||||
|
public byte type; /* FST_AT_MIN ... FST_AT_MAX */
|
||||||
|
public byte subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
|
||||||
|
public String name;
|
||||||
|
public long arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
|
||||||
|
public long arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
|
||||||
|
public long name_length; /* strlen(u.attr.name) */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public static native Pointer fstReaderOpen(String name);
|
public static native Pointer fstReaderOpen(String name);
|
||||||
|
public static native Pointer fstReaderOpenForUtilitiesOnly();
|
||||||
public static native void fstReaderClose(Pointer ctx);
|
public static native void fstReaderClose(Pointer ctx);
|
||||||
public static native String fstReaderGetVersionString(Pointer ctx);
|
public static native String fstReaderGetVersionString(Pointer ctx);
|
||||||
public static native String fstReaderGetDateString(Pointer ctx);
|
public static native String fstReaderGetDateString(Pointer ctx);
|
||||||
public static native int fstReaderGetFileType(Pointer ctx);
|
public static native int fstReaderGetFileType(Pointer ctx);
|
||||||
public static native long fstReaderGetVarCount(Pointer ctx);
|
public static native long fstReaderGetVarCount(Pointer ctx);
|
||||||
public static native long fstReaderGetScopeCount(Pointer ctx);
|
public static native long fstReaderGetScopeCount(Pointer ctx);
|
||||||
public static native long fstReaderGetAliasCount(Pointer ctx);
|
public static native long fstReaderGetAliasCount(Pointer ctx);
|
||||||
public static native long fstReaderGetValueChangeSectionCount(Pointer ctx);
|
public static native long fstReaderGetValueChangeSectionCount(Pointer ctx);
|
||||||
public static native long fstReaderGetStartTime(Pointer ctx);
|
public static native long fstReaderGetStartTime(Pointer ctx);
|
||||||
public static native long fstReaderGetEndTime(Pointer ctx);
|
public static native long fstReaderGetEndTime(Pointer ctx);
|
||||||
public static native byte fstReaderGetTimescale(Pointer ctx);
|
public static native byte fstReaderGetTimescale(Pointer ctx);
|
||||||
public static native long fstReaderGetTimezero(Pointer ctx);
|
public static native long fstReaderGetTimezero(Pointer ctx);
|
||||||
|
public static native int fstReaderGetMaxHandle(Pointer ctx);
|
||||||
|
|
||||||
public static native void fstReaderResetScope(Pointer ctx);
|
public static native void fstReaderResetScope(Pointer ctx);
|
||||||
public static native String fstReaderPushScope(Pointer ctx, String nam, Pointer user_info);
|
public static native String fstReaderPushScope(Pointer ctx, String nam, Pointer user_info);
|
||||||
public static native String fstReaderPopScope(Pointer ctx);
|
public static native String fstReaderPopScope(Pointer ctx);
|
||||||
public static native int fstReaderGetCurrentScopeLen(Pointer ctx);
|
public static native int fstReaderGetCurrentScopeLen(Pointer ctx);
|
||||||
|
public static native String fstReaderGetCurrentFlatScope(Pointer ctx);
|
||||||
|
|
||||||
/*
|
public static native int fstReaderGetNumberDumpActivityChanges(Pointer ctx);
|
||||||
void fstReaderClrFacProcessMask(Pointer ctx, fstHandle facidx);
|
public static native long fstReaderGetDumpActivityChangeTime(Pointer ctx, int idx);
|
||||||
void fstReaderClrFacProcessMaskAll(Pointer ctx);
|
public static native byte fstReaderGetDumpActivityChangeValue(Pointer ctx, int idx);
|
||||||
String fstReaderGetCurrentFlatScope(Pointer ctx);
|
|
||||||
Pointer fstReaderGetCurrentScopeUserInfo(Pointer ctx);
|
public static native int fstReaderIterateHierRewind(Pointer ctx);
|
||||||
int fstReaderGetDoubleEndianMatchState(Pointer ctx);
|
public static native Pointer fstReaderIterateHier(Pointer ctx);
|
||||||
long fstReaderGetDumpActivityChangeTime(Pointer ctx, int idx);
|
public static native int getHierType(Pointer hier);
|
||||||
byte fstReaderGetDumpActivityChangeValue(Pointer ctx, int idx);
|
public static native void getHierScope(Pointer hier, HierScope scope);
|
||||||
int fstReaderGetFacProcessMask(Pointer ctx, fstHandle facidx);
|
public static native void getHierVar(Pointer hier, HierVar scope);
|
||||||
int fstReaderGetFseekFailed(Pointer ctx);
|
public static native void getHierAttr(Pointer hier, HierAttr scope);
|
||||||
fstHandle fstReaderGetMaxHandle(Pointer ctx);
|
public static native int fstReaderGetFacProcessMask(Pointer ctx, int facidx);
|
||||||
long fstReaderGetMemoryUsedByWriter(Pointer ctx);
|
public static native void fstReaderSetFacProcessMask(Pointer ctx, int facidx);
|
||||||
int fstReaderGetNumberDumpActivityChanges(Pointer ctx);
|
public static native void fstReaderClrFacProcessMask(Pointer ctx, int facidx);
|
||||||
String fstReaderGetValueFromHandleAtTime(Pointer ctx, long tim, fstHandle facidx, Stringbuf);
|
public static native void fstReaderSetFacProcessMaskAll(Pointer ctx);
|
||||||
struct fstHier *fstReaderIterateHier(Pointer ctx);
|
public static native void fstReaderClrFacProcessMaskAll(Pointer ctx);
|
||||||
int fstReaderIterateHierRewind(Pointer ctx);
|
|
||||||
int fstReaderIterBlocks(Pointer ctx,
|
public interface ValueChangeCallback extends Callback {
|
||||||
void (*value_change_callback)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue),
|
void callback(long time, int facidx, String value);
|
||||||
Pointer user_callback_data_pointer, FILE *vcdhandle);
|
}
|
||||||
int fstReaderIterBlocks2(Pointer ctx,
|
|
||||||
|
public static native void iterateValueChanges(Pointer ctx, ValueChangeCallback vcc);
|
||||||
|
|
||||||
|
/* untranslated functions:
|
||||||
|
int fstReaderIterBlocks(Pointer ctx, ValueChangeCallback vcc, Pointer user_callback_data_pointer, Pointer vcdhandle);
|
||||||
|
Pointer fstReaderGetCurrentScopeUserInfo(Pointer ctx);
|
||||||
|
int fstReaderGetDoubleEndianMatchState(Pointer ctx);
|
||||||
|
int fstReaderGetFseekFailed(Pointer ctx);
|
||||||
|
long fstReaderGetMemoryUsedByWriter(Pointer ctx);
|
||||||
|
String fstReaderGetValueFromHandleAtTime(Pointer ctx, long tim, fstHandle facidx, Stringbuf);
|
||||||
|
int fstReaderIterBlocks2(Pointer ctx,
|
||||||
void (*value_change_callback)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue),
|
void (*value_change_callback)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue),
|
||||||
void (*value_change_callback_varlen)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue, int len),
|
void (*value_change_callback_varlen)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue, int len),
|
||||||
Pointer user_callback_data_pointer, FILE *vcdhandle);
|
Pointer user_callback_data_pointer, FILE *vcdhandle);
|
||||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(Pointer ctx, int enable);
|
void fstReaderIterBlocksSetNativeDoublesOnCallback(Pointer ctx, int enable);
|
||||||
Pointer fstReaderOpenForUtilitiesOnly(void);
|
int fstReaderProcessHier(Pointer ctx, FILE *vcdhandle);
|
||||||
int fstReaderProcessHier(Pointer ctx, FILE *vcdhandle);
|
void fstReaderSetLimitTimeRange(Pointer ctx, long start_time, long end_time);
|
||||||
void fstReaderSetFacProcessMask(Pointer ctx, fstHandle facidx);
|
void fstReaderSetUnlimitedTimeRange(Pointer ctx);
|
||||||
void fstReaderSetFacProcessMaskAll(Pointer ctx);
|
void fstReaderSetVcdExtensions(Pointer ctx, int enable);
|
||||||
void fstReaderSetLimitTimeRange(Pointer ctx, long start_time, long end_time);
|
|
||||||
void fstReaderSetUnlimitedTimeRange(Pointer ctx);
|
|
||||||
void fstReaderSetVcdExtensions(Pointer ctx, int enable);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.setProperty("jna.debug_load", "true");
|
// System.setProperty("jna.debug_load", "true");
|
||||||
// System.out.println(System.getProperty("jna.library.path", "UNKNOWN"));
|
|
||||||
Native.register("fstapi");
|
Native.register("fstapi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,25 +20,28 @@ import com.minres.scviewer.database.WaveformType;
|
||||||
|
|
||||||
public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
|
public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
|
||||||
|
|
||||||
private long id;
|
private final FstDbLoader loader;
|
||||||
|
|
||||||
private String fullName;
|
private final int id;
|
||||||
|
|
||||||
|
private final String fullName;
|
||||||
|
|
||||||
private final int width;
|
private final int width;
|
||||||
|
|
||||||
private IEventList values;
|
private final IEventList values;
|
||||||
|
|
||||||
public FstSignal(String name) {
|
public FstSignal(FstDbLoader loader, String name) {
|
||||||
this(0, name, 1);
|
this(loader, 0, name, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FstSignal(int id, String name) {
|
public FstSignal(FstDbLoader loader, int id, String name) {
|
||||||
this(id,name,1);
|
this(loader, id,name,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FstSignal(int id, String name, int width) {
|
public FstSignal(FstDbLoader loader, int id, String name, int width) {
|
||||||
super(name);
|
super(name);
|
||||||
fullName=name;
|
fullName=name;
|
||||||
|
this.loader=loader;
|
||||||
this.id=id;
|
this.id=id;
|
||||||
this.width=width;
|
this.width=width;
|
||||||
this.values=new EventList();
|
this.values=new EventList();
|
||||||
|
@ -47,6 +50,7 @@ public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
|
||||||
public FstSignal(FstSignal<T> o, int id, String name) {
|
public FstSignal(FstSignal<T> o, int id, String name) {
|
||||||
super(name);
|
super(name);
|
||||||
fullName=name;
|
fullName=name;
|
||||||
|
this.loader=o.loader;
|
||||||
this.id=id;
|
this.id=id;
|
||||||
this.width=o.width;
|
this.width=o.width;
|
||||||
this.values=o.values;
|
this.values=o.values;
|
||||||
|
@ -57,36 +61,30 @@ public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
|
||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id=id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignalChange(Long time, T value){
|
|
||||||
values.put(time, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IEventList getEvents() {
|
public IEventList getEvents() {
|
||||||
|
if(values.size()==0)
|
||||||
|
loader.getEvents(id, width, values);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IEvent[] getEventsAtTime(long time) {
|
public IEvent[] getEventsAtTime(long time) {
|
||||||
return values.get(time);
|
return getEvents().get(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IEvent[] getEventsBeforeTime(long time) {
|
public IEvent[] getEventsBeforeTime(long time) {
|
||||||
EventEntry e = values.floorEntry(time);
|
EventEntry e = getEvents().floorEntry(time);
|
||||||
if(e==null)
|
if(e==null)
|
||||||
return new IEvent[] {};
|
return new IEvent[] {};
|
||||||
else
|
else
|
||||||
return values.floorEntry(time).events;
|
return getEvents().floorEntry(time).events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,6 +99,11 @@ public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package com.minres.scviewer.database.fst;
|
|
||||||
|
|
||||||
import com.sun.jna.Library;
|
|
||||||
import com.sun.jna.Native;
|
|
||||||
import com.sun.jna.Platform;
|
|
||||||
|
|
||||||
/** Simple example of JNA interface mapping and usage. */
|
|
||||||
public class HelloWorld {
|
|
||||||
|
|
||||||
// This is the standard, stable way of mapping, which supports extensive
|
|
||||||
// customization and mapping of Java to native types.
|
|
||||||
|
|
||||||
public interface CLibrary extends Library {
|
|
||||||
CLibrary INSTANCE = (CLibrary)
|
|
||||||
Native.load((Platform.isWindows() ? "msvcrt" : "c"),
|
|
||||||
CLibrary.class);
|
|
||||||
|
|
||||||
void printf(String format, Object... args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
CLibrary.INSTANCE.printf("Hello, World\n");
|
|
||||||
for (int i=0;i < args.length;i++) {
|
|
||||||
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,8 +10,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database.fst;
|
package com.minres.scviewer.database.fst;
|
||||||
|
|
||||||
import com.minres.scviewer.database.BitVector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Interface IVCDDatabaseBuilder. It allows to add VCD events into the database
|
* The Interface IVCDDatabaseBuilder. It allows to add VCD events into the database
|
||||||
*/
|
*/
|
||||||
|
@ -37,7 +35,7 @@ public interface IFstDatabaseBuilder {
|
||||||
* @param width the width, -1 equals real, 0... is a bit vector
|
* @param width the width, -1 equals real, 0... is a bit vector
|
||||||
* @return the net id
|
* @return the net id
|
||||||
*/
|
*/
|
||||||
public Integer newNet(String netName, int i, int width) ;
|
public void newNet(String netName, int handle, int width, boolean alias) ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the net width.
|
* Gets the net width.
|
||||||
|
@ -47,22 +45,5 @@ public interface IFstDatabaseBuilder {
|
||||||
*/
|
*/
|
||||||
public int getNetWidth(int netId);
|
public int getNetWidth(int netId);
|
||||||
|
|
||||||
/**
|
public void setMaxTime(long time, int timeScale);
|
||||||
* Append transition.
|
|
||||||
*
|
|
||||||
* @param netId the int value
|
|
||||||
* @param currentTime the current time in ps
|
|
||||||
* @param decodedValues the decoded values
|
|
||||||
*/
|
|
||||||
public void appendTransition(int netId, long currentTime, BitVector decodedValue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append transition.
|
|
||||||
*
|
|
||||||
* @param netId the int value
|
|
||||||
* @param currentTime the current time in ps
|
|
||||||
* @param decodedValue the decoded values
|
|
||||||
*/
|
|
||||||
public void appendTransition(int netId, long currentTime, double decodedValue);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class DatabaseServicesTest {
|
||||||
List<IWaveform> waves= waveformDb.getAllWaves();
|
List<IWaveform> waves= waveformDb.getAllWaves();
|
||||||
assertEquals(14, waves.size());
|
assertEquals(14, waves.size());
|
||||||
assertEquals(2, waveformDb.getChildNodes().size());
|
assertEquals(2, waveformDb.getChildNodes().size());
|
||||||
IWaveform bus_data_wave = waves.get(0);
|
IWaveform bus_data_wave = waves.get(12);
|
||||||
EventEntry bus_data_entry = bus_data_wave.getEvents().floorEntry(1400000000L);
|
EventEntry bus_data_entry = bus_data_wave.getEvents().floorEntry(1400000000L);
|
||||||
assertEquals("00001011", bus_data_entry.events[0].toString());
|
assertEquals("00001011", bus_data_entry.events[0].toString());
|
||||||
IWaveform rw_wave = waves.get(2);
|
IWaveform rw_wave = waves.get(2);
|
||||||
|
|
Loading…
Reference in New Issue