Commands to build simulations, add primitives, modules, parameters, and the connections between them.
The commands described here enable you to:
The command
systemlist
will return the list of names of systems that currently exist. The command
newsystem [<name>] [<dom>]
creates a new, empty system named name (default is main) and makes it the current system with domain dom (default is current domain). Both arguments may be omitted. If there was previously a system with the same name, it will be overwritten. The previous actual system will not be affected, unless it had the same name as the new one and will therefore be overwritten. To remove a system, simply issue the command:
delsystem [<name>]
If no argument is given, this will delete the current system. After this, the current system will be main. To find out what the current system is, issue the command:
cursystem [<name>]
With no arguments the name of the current system is returned. With one argument the current system will become name. A system can be renamed using the syntax
renamesystem [<oldname>] <newname>
With one argument newname, renamesystem renames the current system to newname. With two arguments, the system named oldname is renamed to newname. Note that any existing system named newname is deleted.
MLDesigner supports multiple simulation domains. Before creating a simulation environment and running it, it is necessary to establish the domain. The interpreter has a current domain which is initially the default domain SDF. The command
domain [<name>]
changes the current domain. This is only legal when the current module is empty. The argument name must be the name of a known domain. If the argument name is omitted, the command domain returns the current domain. It is possible to create wormhole interfaces between domains by including a domain command inside a module definition. The command
domains
lists the domains that are currently linked to the interpreter.
The first step toward creating a system is to define the blocks - primitives and modules - to be used in the system. The command
primitive <name> <class>
creates a new instance of a primitive or module of class class, names it name, and inserts it into the current module. Any parameters in the primitive or module are created with their default values. While it is not enforced, the normal naming convention is that names begin with a lower case letter and classes begin with an upper case letter. This makes it easy to distinguish instances of a class from the class itself.
The next step is to connect the blocks so that they can pass data among themselves using the connect command. This forms a connection between two primitives or modules by connecting their portholes. A porthole is specified by giving the primitive or module name followed by the port name within the primitive. The first porthole must be an output porthole and the second must be an input porthole. For example:
connect <block1> <port1> <block2> <port2> [<delay>]
The connect command accepts an optional integer delay parameter. For example:
connect myprimitive output yourprimitive input 1
This specifies one delay on the connection. The delay parameter makes sense only for domains that support it. The delay argument may be an integer expression with variables referring to module parameters as well.
One or both of the portholes may really be a MultiPortHole. If so, the effect of doing the connect is to create a new porthole within the MultiPortHole and connect to that (see also the numports command).
As an alternative to issue connect commands, which specify point-to-point connections, you may specify connections in a netlist style. This syntax is used to connect an output to more than one input. This is called auto-forking. Two commands are provided for this purpose. The node command creates a node with name:
node <name>
The nodeconnect command connects a porthole port of block block to a node nodename:
nodeconnect <block> <port> <nodename> [<delay>]
Any number of portholes may be connected to a node, but only one of them can be an output node.
A pair of multi portholes can be connected using a bus connection, meaning that each multi porthole has N portholes and they all connect in parallel to the corresponding port in the other multi porthole. The syntax for creating such connections is
busconnect <block1> <port1> <block2> <port2> <width> [<delay>]
Here, width is an expression specifying the width of the bus (how many portholes in the multi porthole); and delay is an optional expression giving the delay on each connection. The other arguments are identical to those of the connect command.
When you define a new module there are typically external connections to that module that need to be connected through to internal blocks. The alias command is used to add a porthole newport to the current module, and associate it with an input or output porthole blockport of one of the contained block within the module. The syntax is:
alias <newport> <block> <blockport>
This also works if blockport is a MultiPortHole - the module will then appear to have a multi porthole as well.
A parameter is a piece of data that is assigned to a module and can be used to affect its behavior. Typically the value of a parameter is coupled to the parameter of blocks within the module, allowing you to customize the behavior of blocks within the module. The newparam command adds a parameter to the current module. The form of the command is
newparam <name> <type> <value>
The name argument is the name to be given to the parameter. The type argument is the type of parameter. All standard types are supported. The value argument is the default value to be given to the parameter, if the programmer of the module does not change it using the setparam command described below. The default value specifies the initial value of the parameter, and can be an arbitrary expression involving constant values and other parameter names. This expression is evaluated when the simulation starts. The following parameter names are predefined: YES, NO, TRUE, FALSE, and PI. YES and TRUE have a value of 1; NO and FALSE have a value of 0; PI has the value 3.14159... Some examples are:
newparam count int 3
newparam level float 1.0
newparam title string "This is a title"
newparam myfreq float modulefreq
newparam angularFreq float "2*PI*$freq"
The full syntax of parameter initial value strings depends on the type of parameter, and is explained in Add parameters and specify their default values.
The setparam command is used to change the value of a parameter. It can be used in three contexts:
The latter would normally be used when you want to perform multiple simulations using different parameter values. The syntax for setparam is:
setparam <block> <parameter> <value>
An example of the use of setparam is given in the section describing the defmodule command below.
Some primitives in MLDesigner are defined with an unspecified number of multiple ports. The number of connections is defined by the user of the primitive rather than the primitive itself. The numports command applies to primitives that contain such MultiPortHoles. It causes a specified number of PortHoles to be created within the MultiPortHole. The syntax is
numports <block> <port> <n>
where block is the name of a primitive within the current module, port is the name of a MultiPortHole in the primitive, and n is an integer, representing the number of PortHoles to be created. After the portholes are created, they may be referred to by appending #i, where i is an integer, to the multi porthole name, and enclosing the resulting name in quotes. The main reason for using this command is to allow the portholes to be connected in random order. Here is an example:
domain SDF
primitive spring Ramp
primitive summer AddFloat
numports summer Input 2
alias galInput summer "Input#1"
connect spring output summer "Input#2"
The defmodule command allows you to define a new class of modules. The syntax is
defmodule <name>
{
command
command
...
}
Here name is the name of the module type you are creating. While it is not required, we suggest that you have the name begin with a capital letter in accordance with our standard naming convention that class names begin with capital letters. The command lines may be any of the commands described before, such as primitive, connect, busconnect, node, nodeconnect, numports, newparam, setparam, or alias. The defined class is added to the known list, and you can then create instances of it and add them to other modules. An example is:
reset domain SDF defmodule SinGen { domain SDF # The frequency of the sine wave is a module parameter newparam freq float "0.05" # Create a primitive instance of class "Ramp" named "ramp" primitive ramp Ramp # The ramp advances by 2*pi each sample setparam ramp step "6.283185307179586" # Multiply the ramp by a value, setting the frequency primitive gain MpyConstFloat # The multiplier is set to "freq" setparam gain Multiplier "freq" # Finally the sine generator primitive sin Sin connect ramp output gain Input connect gain Output sin input # The output of "sin" becomes the modules output alias output sin output }
In this example, note the use of parameters to allow the frequency of the sine wave generator to be changed. For example, we could now run the sine generator, changing its frequency to 0.02, with the interpreter input:
primitive generator SinGen setparam generator freq "0.02" primitive printer Printer connect generator output printer input run 100
You may include a domain command within a defmodule command. If the inside domain is different to the outside domain, an object known as a Wormhole is created. This is an interface between two domains and is described in a later section.