2015-01-21 21:58:35 +01:00
|
|
|
/*******************************************************************************
|
2015-10-22 00:25:12 +02:00
|
|
|
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
2015-01-21 21:58:35 +01:00
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* MINRES Technologies GmbH - initial API and implementation
|
|
|
|
*******************************************************************************/
|
2015-01-06 17:14:16 +01:00
|
|
|
package com.minres.scviewer.database.vcd;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
2015-11-15 22:15:37 +01:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
2015-01-06 17:14:16 +01:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Stack;
|
2015-01-20 18:50:15 +01:00
|
|
|
import java.util.TreeMap;
|
2015-01-06 17:14:16 +01:00
|
|
|
import java.util.Vector;
|
|
|
|
|
2015-01-09 09:16:40 +01:00
|
|
|
import com.minres.scviewer.database.BitVector;
|
2015-01-06 17:14:16 +01:00
|
|
|
import com.minres.scviewer.database.ISignal;
|
|
|
|
import com.minres.scviewer.database.ISignalChange;
|
|
|
|
import com.minres.scviewer.database.ISignalChangeMulti;
|
|
|
|
import com.minres.scviewer.database.ISignalChangeSingle;
|
|
|
|
import com.minres.scviewer.database.IWaveform;
|
2015-01-20 18:50:15 +01:00
|
|
|
import com.minres.scviewer.database.IWaveformDb;
|
2015-01-10 00:23:46 +01:00
|
|
|
import com.minres.scviewer.database.IWaveformDbLoader;
|
2015-01-20 18:50:15 +01:00
|
|
|
import com.minres.scviewer.database.IWaveformEvent;
|
2015-01-06 17:14:16 +01:00
|
|
|
import com.minres.scviewer.database.InputFormatException;
|
2015-11-15 22:15:37 +01:00
|
|
|
import com.minres.scviewer.database.RelationType;
|
2015-01-06 17:14:16 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The Class VCDDb.
|
|
|
|
*/
|
2015-01-10 00:23:46 +01:00
|
|
|
public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
2015-01-06 17:14:16 +01:00
|
|
|
|
|
|
|
|
2015-11-22 12:47:07 +01:00
|
|
|
/** The Constant TIME_RES. */
|
2015-01-20 18:50:15 +01:00
|
|
|
private static final Long TIME_RES = 1000L; // ps;
|
2015-01-06 17:14:16 +01:00
|
|
|
|
2015-11-22 12:47:07 +01:00
|
|
|
/** The db. */
|
2015-01-10 00:23:46 +01:00
|
|
|
private IWaveformDb db;
|
|
|
|
|
2015-01-06 17:14:16 +01:00
|
|
|
/** The module stack. */
|
|
|
|
private Stack<String> moduleStack;
|
|
|
|
|
|
|
|
/** The signals. */
|
2015-01-20 18:50:15 +01:00
|
|
|
private List<IWaveform<? extends IWaveformEvent>> signals;
|
2015-01-06 17:14:16 +01:00
|
|
|
|
2015-11-22 12:47:07 +01:00
|
|
|
/** The max time. */
|
2015-01-06 17:14:16 +01:00
|
|
|
private long maxTime;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instantiates a new VCD db.
|
|
|
|
*/
|
2015-01-10 00:23:46 +01:00
|
|
|
public VCDDbLoader() {
|
2015-01-06 17:14:16 +01:00
|
|
|
}
|
|
|
|
|
2015-11-22 12:47:07 +01:00
|
|
|
/** The date bytes. */
|
|
|
|
private byte[] dateBytes = "$date".getBytes();
|
2015-01-06 17:14:16 +01:00
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
|
|
|
*/
|
2015-01-20 18:50:15 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
2015-01-06 17:14:16 +01:00
|
|
|
@Override
|
2015-01-10 00:23:46 +01:00
|
|
|
public boolean load(IWaveformDb db, File file) throws Exception {
|
|
|
|
this.db=db;
|
|
|
|
FileInputStream fis = new FileInputStream(file);
|
2015-11-22 12:47:07 +01:00
|
|
|
byte[] buffer = new byte[dateBytes.length];
|
|
|
|
int read = fis.read(buffer, 0, dateBytes.length);
|
2015-01-10 00:23:46 +01:00
|
|
|
fis.close();
|
2015-11-22 12:47:07 +01:00
|
|
|
if (read == dateBytes.length)
|
|
|
|
for (int i = 0; i < dateBytes.length; i++)
|
|
|
|
if (buffer[i] != dateBytes[i])
|
2015-01-10 00:23:46 +01:00
|
|
|
return false;
|
|
|
|
|
2015-01-20 18:50:15 +01:00
|
|
|
signals = new Vector<IWaveform<? extends IWaveformEvent>>();
|
2015-01-06 17:14:16 +01:00
|
|
|
moduleStack= new Stack<String>();
|
2015-01-10 00:23:46 +01:00
|
|
|
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
|
2015-01-06 17:14:16 +01:00
|
|
|
moduleStack=null;
|
|
|
|
if(!res) throw new InputFormatException();
|
2015-01-20 18:50:15 +01:00
|
|
|
// calculate max time of database
|
|
|
|
for(IWaveform<? extends IWaveformEvent> waveform:signals)
|
|
|
|
maxTime= Math.max(maxTime, ((ISignal<? extends ISignalChange>)waveform).getEvents().lastKey());
|
|
|
|
// extend signals to hav a last value set at max time
|
|
|
|
for(IWaveform<? extends IWaveformEvent> waveform:signals){
|
|
|
|
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values;
|
|
|
|
if(events.lastKey()<maxTime){
|
|
|
|
ISignalChange x = events.lastEntry().getValue();
|
|
|
|
if(x instanceof ISignalChangeSingle)
|
|
|
|
((VCDSignal<ISignalChangeSingle>)waveform).values.put(maxTime,
|
|
|
|
new VCDSignalChangeSingle(maxTime, ((ISignalChangeSingle)x).getValue()));
|
|
|
|
else
|
|
|
|
if(x instanceof ISignalChangeMulti)
|
|
|
|
((VCDSignal<ISignalChangeMulti>)waveform).values.put(maxTime,
|
|
|
|
new VCDSignalChangeMulti(maxTime, ((ISignalChangeMulti)x).getValue()));
|
2015-01-06 17:14:16 +01:00
|
|
|
}
|
|
|
|
}
|
2015-01-10 00:23:46 +01:00
|
|
|
return true;
|
2015-01-06 17:14:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
|
|
|
|
*/
|
|
|
|
@Override
|
2015-01-20 18:50:15 +01:00
|
|
|
public Long getMaxTime() {
|
2015-01-21 21:58:35 +01:00
|
|
|
return maxTime;
|
2015-01-06 17:14:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
|
|
|
|
*/
|
|
|
|
@Override
|
2015-01-20 18:50:15 +01:00
|
|
|
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
2015-01-06 17:14:16 +01:00
|
|
|
return signals;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#enterModule(java.lang.String)
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void enterModule(String tokenString) {
|
2018-07-16 13:17:58 +02:00
|
|
|
if(moduleStack.isEmpty()) {
|
|
|
|
if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString);
|
|
|
|
} else
|
2015-01-06 17:14:16 +01:00
|
|
|
moduleStack.push(moduleStack.peek()+"."+tokenString);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#exitModule()
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void exitModule() {
|
|
|
|
if(!moduleStack.isEmpty()) moduleStack.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
|
|
|
|
*/
|
2015-01-20 18:50:15 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
2015-01-06 17:14:16 +01:00
|
|
|
@Override
|
2018-07-16 13:17:58 +02:00
|
|
|
public Integer newNet(String name, int i, int width) {
|
|
|
|
String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name;
|
2015-01-06 17:14:16 +01:00
|
|
|
int id = signals.size();
|
2015-01-20 18:50:15 +01:00
|
|
|
VCDSignal<? extends IWaveformEvent> signal;
|
2015-01-06 17:14:16 +01:00
|
|
|
if(width==1){
|
2015-01-10 00:23:46 +01:00
|
|
|
signal = i<0 ? new VCDSignal<ISignalChangeSingle>(db, id, netName) :
|
2015-01-20 18:50:15 +01:00
|
|
|
new VCDSignal<ISignalChangeSingle>((VCDSignal<ISignalChangeSingle>)signals.get(i), id, netName);
|
2015-01-06 17:14:16 +01:00
|
|
|
} else {
|
2015-01-10 00:23:46 +01:00
|
|
|
signal = i<0 ? new VCDSignal<ISignalChangeMulti>(db, id, netName, width) :
|
2015-01-20 18:50:15 +01:00
|
|
|
new VCDSignal<ISignalChangeMulti>((VCDSignal<VCDSignalChangeMulti>)signals.get(i), id, netName);
|
2015-01-06 17:14:16 +01:00
|
|
|
};
|
|
|
|
signals.add(signal);
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#getNetWidth(int)
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public int getNetWidth(int intValue) {
|
2015-01-20 18:50:15 +01:00
|
|
|
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue);
|
2015-01-06 17:14:16 +01:00
|
|
|
return signal.getWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
|
|
|
|
*/
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
@Override
|
2015-01-21 21:58:35 +01:00
|
|
|
public void appendTransition(int signalId, long currentTime, BitVector decodedValues) {
|
2015-01-20 18:50:15 +01:00
|
|
|
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
2015-01-21 21:58:35 +01:00
|
|
|
Long time = currentTime* TIME_RES;
|
2015-01-06 17:14:16 +01:00
|
|
|
if(signal.getWidth()==1){
|
2015-01-20 18:50:15 +01:00
|
|
|
((VCDSignal<ISignalChangeSingle>)signal).values.put(time, new VCDSignalChangeSingle(time, decodedValues.getValue()[0]));
|
2015-01-06 17:14:16 +01:00
|
|
|
} else {
|
2015-01-20 18:50:15 +01:00
|
|
|
((VCDSignal<VCDSignalChangeMulti>)signal).values.put(time, new VCDSignalChangeMulti(time, decodedValues));
|
2015-01-06 17:14:16 +01:00
|
|
|
}
|
|
|
|
}
|
2015-11-15 22:15:37 +01:00
|
|
|
|
2015-11-22 12:47:07 +01:00
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
|
|
|
|
*/
|
2015-11-15 22:15:37 +01:00
|
|
|
@Override
|
|
|
|
public Collection<RelationType> getAllRelationTypes(){
|
|
|
|
return Collections.emptyList();
|
|
|
|
}
|
2015-01-06 17:14:16 +01:00
|
|
|
|
|
|
|
}
|