Simthetic Development Documentation
Simthetic is a simulation tool, written in the object-oriented programming language C++. This tool is the framework for many different system blocks, most of them implemented in separate libraries. The basic available library
simtheticlib contains a complete OFDM coded transmission system.
To run a simulation, you need to compile (1.) the included executable
simthetic with its included library
simtheticbase and (2.) at least one external library, e.g.
More documentation pages:
- A simulation in Simthetic consists of many devices, also called blocks. All devices are C++ classes derived from simth::Device.
- A concrete simulation will connect these devices by connecting their interfaces. The list of all connections as well as the configuration of the devices is defined in a so-called parameterfile. A parameterfile is the full description for a concrete simulation.
- From a programmer's point of view, the configuration of each device (block) for a concrete simulation is done through a list of simth::Propertys.
- Simthetic supports multiple computational domains (the model of computation) in theory. However, the only available computational domain is a synchronous dataflow, implemented in simth::StreamDrivenSystem.
If you need example code for creating a new simthetic library, look into the directory api-doc/templatelib of the simthetic package.
The software architecture of Simthetic supports the development of different simulation system models of computation (computational domains). All models of computations are derived from the class simth::SimulationSystem that is declared in basicsimulationsystem.h Currently the only implemented simulation system model is a stream driven system model, simth::StreamDrivenSystem.
- The rest of the documentation below might be quite outdated. This needs to be rewritten. If in doubt, then the documentation as generated from the header files is probably always more accurate.
This simulation model is represented by the class simth::StreamDrivenSystem (SDS) that is declared in streamdrivensystem.h. Basic idea of that model are the so-called block devices. A block devices possesses a certain number of input interfaces and output interfaces that are connected with output interfaces and input interfaces of other block devices, respectively.
(Note: Probably outdated) The most important function of these block devices is the function process(). This function is called by the SDS, after a block sent a READY_TO_PROCESS signal to the simulation system. Actually, the SDS does not call the function process() of that device immediately, but it stores the request to process in a FIFO. If the FIFO is empty, i.e. it contains no requests (which for examples is the case at the beginning of each simulation run), the process function of the so-called start device is called. Any device that expects no input data for processing can be specified as start device in a certain simulation scenario.
- See also:
- Sequence diagram of Main Simulation Loop
(Note: Probably outdated) Normally, the signal READY_TO_PROCESS is sent by a device to the system, if it received new data to its input interfaces and if the stored data of all input interfaces exceed a certain length (see Device::inputLength()). For example, a device 'B' receives new data from a device 'A' via one or more of its input interfaces that are connected with one or more output interfaces of the device 'A'. Device 'A' calls the function Device::acceptNewData() from Device 'B' after finishing writing new data to one of the input interfaces of Device 'B'. Since the function acceptNewData() is declared virtual, each special block device can define by its own what should happened if that function is called. The standard implementation of that function checks the current lengths of stored input data of all input interfaces and sends the READY_TO_PROCESS signal if each of them exceeds a certain length. These so-called input lengths could be set independently from each other by the help of the function Device::setInputLength(int ).
The information structures that are used to exchange information between interfaces are called signal sequences (class SignalSequence). A signal sequence could be any class that will be accepted as template argument of an interface. To be accepted as template argument, the classes must provide certain requirements, e.g any class that should be used as signal sequence must provide the index operator . To see all requirements that have to be complied see the template class SignalSequenceBase in signals.h (Note: Yes, these Signal classes are quite complicated. Yes, this is necessary. Please read the introduction in signals.h about why this is necessary). It will be helpful to use this class as base class when implementing new classes representing signal sequences.
However, the file signals.h provides already several types of signal sequences that could be useful in a digital communications simulation. Additionally some functions to convert signal sequences to other signal sequences are provided by the signal module.
All classes, functions and types of Simthetic are declared within the namespace
Every class that is used in Simthetic and its libraries usually has several parameters that are different in different simulation setups (e.g.: the number of output bits in the simthlib::BitGenerator class; the number of reflection paths in the simthlib::WssusChannel radio channel). These parameters should therefore be read from a configuration file at simulation startup time (the file is called "the parameter file"), and the values should somehow passed on to the respective objects.
The file format of these parameter files are described in detail here: The XML file format of the Parameter files
Some very old devices and C++ classes still use an old, deprecated text-based parameter file format. In that format, a simulation is described not by one file but instead by several files. See Legacy text-based parameter files and Migration of Parameter files to the XML format .
The best way to understand how to program new blocks is to take existing blocks as templates. This will help you to perform the following steps.
Documentation will follow soon. So long look to signals.h to get more information and to see some example source code.
- Step 1: Creating new header and source files.
- Step 2: Overloading the pure virtual functions of the base class Device. If necessary overload the virtual functions of device that are not pure virtual with your own implementation.
- Step 3: Add your module (header, cpp-file) to the Makefile.am within that directory.
- Step 4: Compile the new module.
- Step 5: Write an XML description file to specify what parameters are taken by your device from the parameter file.
- Step 6: Add your function to the simth::DeviceFactory() of your library using the function
- Step 7: Add your XML-file to the Makefile.am within that directory.
- Step 8: Recompile your library.
- Step 9: Test the new device and enjoy.
Generated on Mon Apr 24 21:19:19 2006 for simthetic by