J001 Creating records
If you develop a reader, a recJs script or are simple Signal Script production, impulse provides you always the same interfaces to simply create records, scopes and signals.
Independent from its source and type, impulse organizes all signal data by using these elements:
- Record: The top-level element, usually the content of a file, or the resulting input of a port.
- Scope: An organization element (like a folder) to group signals.
- Signal: An indexed sequence of signal samples (containing values of different type), organized along a domain base (e.g. time).
- Proxy: A signal that contains the identical content of a another signal, and therefore contains only a link to that signal (wave file often contains identical signals).
Record generator
The record generator help you to prepare a record with all its contents. If you create a reader,
your class will be derived from IRecordGenerator, if you are working with recJs
scripts or a scripted reader, a IRecordGenerator variable (generator) will be provided. The
"Signal Script" production does not require to use a record generator, as the signal and
reader setup is done internally.
To create a record , the following steps are
required:
- Initialize the record
- Add the record content (scopes, signals and proxies)
- Acquire writers for the signals you want to fill
- Open the writer
- Write samples
- Close the writer
Experimenting with records
If you want to experiment with records and signals, just create a file/resource with file ending "recJs" (e.g. my_wave.recJs) and put the following text into the header of the file ("//-recjs" is important to get the file identified) :
//-recjs (keep this line) // Vars: // * generator of ISingleDomainRecordGenerator // void initRecord(String name); ....
Add your code below and open with impulse.
Record initialization
The initialization provides the record with a name and in case of ISingleDomainRecordGenerator also with a domain base:
- name: to be used as record name.
- domainBase: Domain base in case of multi domain record (e.g. TimeBase.ms).
Interface
void initRecord(String name); // ISingleDomainRecordGenerator only void initRecord(String name, IDomainBase domainBase);
Examples
// Java (reader derived from IRecordGenerator, ISingleDomainRecordGenerator) initRecord("Example Record"); initRecord("Example Record",TimeBase.ns); // JavaScript (recJs, scripted reader,..) generator.initRecord("Example Record"); generator.initRecord("Example Record",TimeBase.ns);
Adding scopes
Scopes let you organize your signals within a hierarchy. To add a scope you need a container (or null for the root), a name and optionally a description.
- container: Parent of new scope, or null (for root).
- name: Name of the new scope.
- description: Scope description (just comments).
Interface
Scope addScope(ICell container, String name); Scope addScope(ICell container, String name, String description);
Examples
// Java (reader derived from IRecordGenerator, ISingleDomainRecordGenerator) addScope(null, "External Signals"); addScope(null, "External Signals","Just for this"); // JavaScript (recJs, scripted reader,..) generator.addScope(null, "External Signals"); generator.addScope(null, "External Signals","Just for this");
Defining signals
After defining a signal, you can create a writer to add samples. To define a signal you need a
signal and process type. The signal type defines the data type of a signal (text, integer, float,
...). The process type defines how the samples are organized on the domain (Discrete: at any
position; Continuous: at fixed positions with equal distance).
impulse supports the
following signal types:
- Logic (1..N bits — the bits are stored as 2-state, 4-state or 16-state data (usually nine states are used).
- Float (32-bit or 64-bit), Float arrays
- Integer (any length), Integer arrays
- Event (Enumeration), Event arrays
- Text (any length), Text arrays
- Structure (unlimited properties per structure: Text/Binary/Integer/Float/Enumeration)
- Transaction Event (a group of structures — a transaction can consist of multiple events)
- Binary (can contain images,… )
The signal descriptor contains additional information about the signal.
The domain
of a signal may be Time,Frequency,Index,... . The domain base represents the the minimum
distance between two samples (e.g. ns or ps).
If "createWriter" is set to true
(the default value), a writer is generated in background.
- container: Parent of new signal, or null (for root).
- name: Name of the new signal.
- description: Signal description (just comments).
- processType: Discrete or Continuous process type (ProcessType. ...).
- signalType: One of the defined signal types (SignalType. ...).
- signalDescriptor: Extended definition of the signal type, usually set to SignalDescriptor.DEFAULT.
- domainBase: Domain base in case of multi domain record, or null.
- createWriter: Set to true to automatically create a writer
Interface
Signal addSignal(ICell container, String name, String description, ProcessType processType, SignalType signalType, SignalDescriptor signalDescriptor, IDomainBase domainBase); Signal addSignal(ICell container, String name, String description, ProcessType processType, SignalType signalType, SignalDescriptor signalDescriptor, IDomainBase domainBase, boolean createWriter)); // ISingleDomainRecordGenerator only Signal addSignal(ICell container, String name, String description, ProcessType processType, SignalType signalType, SignalDescriptor signalDescriptor);
Examples
// Java (reader derived from IRecordGenerator, ISingleDomainRecordGenerator) Scope signals = addScope(null, "External Signals"); Signal clk = addSignal(signals, "Clk", "", ProcessType.Discrete, SignalType.Logic, SignalDescriptor.DEFAULT); // JavaScript (recJs, scripted reader,..) var signals = generator.addScope(null, "External Signals"); var clk = generator.addSignal(signals, "Clk", "", ProcessType.Discrete, SignalType.Logic, SignalDescriptor.DEFAULT);
The signal descriptor
In above examples i used the default signal descriptor (SignalDescriptor.DEFAULT). You may use a dedicated signal descriptor:- to define the bits width of a logic signal.
- to define the array size.
- to set content information (e.g a binary content contains an image).
- to define the accuracy of a signal (e.g. float 32/64)).
- to set a format specifier (e.g. decimal, hex, ..)
public SignalDescriptor(String content, int scale0, int accuracy, int format); Signal signal2 = addSignal(signals, "Integer3", "XY", ProcessType.Discrete, SignalType.IntegerArray, new SignalDescriptor(SignalDescriptor.CONTENT_DEFAULT,2, ISample.INTEGER_ACCURACY_DEFAULT,ISample.FORMAT_DEFAULT));
- content: String describing the content (meaning/definition) of a signals (e.g. image (binary), transaction (struct),..).
- scale0: Defines a type specific scale value (e.g. no of logic bits, dimension of float array).
- accuracy: May define a type specific accuracy definition.
- format: Defines the value rendering format (ISample.FORMAT_...).
Adding proxies
Proxies are signals that contains the identical content of a another signal. To create a proxy, you just need a container (or null for the root), a name, a descritpion (or null) and the referenced signal (must not be null).
Interface
SignalProxy addSignalProxy(ICell container, String name, String description, Signal signal);
Examples
// Java (reader derived from IRecordGenerator, ISingleDomainRecordGenerator) Signal clk = addSignal(signals, "Clk", "", ProcessType.Discrete, SignalType.Logic, SignalDescriptor.DEFAULT); addSignalProxy(other, "External Signals","Just for this",clk); // JavaScript (recJs, scripted reader,..) var clk = generator.addSignal(signals, "Clk", "", ProcessType.Discrete, SignalType.Logic, SignalDescriptor.DEFAULT); generator.addSignalProxy(other, "External Signals","Just for this",clk);The next chapter ( J02 Using sample writers ) handles the writer creation and the steps of writing samples.