Script

  

Behavior/Script
Block Name: Script (Virtual_Machine)

Code File Location: VisualSim/actor/lib/Virtual_Machine

Table of Content


Block Overview

/* Script                         */
count        = 0     /* Initialize Count           */
LABEL: BEGIN         /* Block Inputs start here    */
while (count < 10)   /* Perform loop 10 times      */
{
   count     = count + 1
   SEND(output, "Count = " + count)
}
if (port_name == "input")
{
         QUEUE ("MyQueue", port_token, 0, put)
         Length = getBlockStatus(Block_Name, "MyQueue", "length", 0)
         SEND(output, "MyQueue Length = " + Length)       
}
else if (port_name == "virtual")
{
   throwMyException (Block_Name + " detected a virtual transaction.")
}

Parameter_Name                 Parameter_Value          Description  
Path                                              none                     path to block, can include "VS/" to be generic            
Read_File                                     none                     name of script.txt, using above path             
Save_Files                                    false                     save parsed script, using above path           
Profile_File                                   none                    profile file name, "MyProfile.txt", for example             
Listen_to_File                               none                    output listen to block to a file, "MyListenToFile.txt", for example             
Duplicate_Input                            true                      duplicate incoming data structure, if single input and output, can improve performance             
Profile                                           0                          profile script as an array of instructions executed by Virtual Machine, useful for estimating algorithm perf.               
Maximum_Loops                         10000000            maximum loops in a while loop, million default, some models may need a larger value.           
Block_Reference                          Block_Name       Block_Reference is used to define a unique Virtual_Machine block (Block_Path + Block_Name)        
Port_Order_Array                        {"input"}             VM block will add user added fields internally, else user can define order of reading here    
Add_Scheduler_Times_to_DS    false                      default is false, no scheduler times added, or stats.  Set to true for all QUEUE, TIMEQ statistics

Virtual_Machine


Description

The Virtual Machine contains an initialize section, an input queue, the sequence of code execution and outputs.  The initialize section is the portion of the code prior to LABEL: BEGIN.  This is executed at the beginning of the simulation.  The input queue is a non-priority queue and will list data structures arriving on all the input port and from virtual connections.  The data structures will trigger the code in the order of arrival.  The outputs can be a port of the block or a virtual device in the model.  They can be triggered using a RegEx or the SEND function.

Note: Any Virtual Machine script located in the VS_AR/VisualSim/actor directory cannot be edited and saved. If you need to edit these files, save it in a different directory within the CLASSPATH and define it as a new Class.

The sequence of operation is as follows:

At the start of the simulation, all the initialize code is executed. No input or trigger is required to execute the code.  There is no deterministic order of execution of all the virtual machines in the model.  They can execute in any order.  

When the data structure arrives at the input port or, via a virtual connection, it is placed in the input queue.  If there Virtual Machine is free, the head of this queue is removed and is called port_token.  

This is port_token executes through the code sequence, in order, beginning from the LABEL:BEGIN.  If the data structure encounters a WAIT, EXIT, Queue, GTO(END), TIMEQ, Event or completes execution of all the code; then data structure stops there and the head of the queue becomes the current port_token and starts executing.  The currently executing data structure is always called port_token.

When the data structure is released from the QUEUE (using a Pop) or a TIMEQ, it becomes the port_token and executes from the next line of the code.

If the data structure encounters a SEND, it is executed immediately.  The code continues to execute until it reaches the END or encounters a delay point.  At that point, the data structures in the output queue are sent to the appropriate destination, in the order received. 

If the SEND is to a LABEL in the same block, this is treated as a separate thread.  This can create a data structure that executes independent of the main sequence.

A WAIT completely stops execution of the Virtual Machine and nothing can execute.  This is a blocking request.  A TIMEQ delays the current transaction at the next execution line.  The next transaction or any other transaction, already executing can continue.  Only one transaction executes at any time.  Only when it reaches a "end" state, it will release control to another transaction. 

Each arriving data structure is assigned the name of the arriving port or "virtual", if from a virtual connection.  The name of the data structure is used to identify the port that it arrived at.  Unlike the Processing and Decision block, the name of the arriving port must not be used to address the transaction.  As there are delays and blocking operations in this block, a new transaction can arrive at input_queue from the same port while the current one is executing.  This can cause unwanted results.  The special keyword- port_token is used to address the currently executing transaction. There can be multiple port_tokens in a block that are in various states, like at a TIMEQ, WAIT, or a thread.

Virtual_Machine, Smart_Controller now support cancellation of TIMEQ and WAIT events.  There are both Block commands (CANCEL()) and RegEx commands (cancelEvent()), which are similar in operation.  Details below. 

To access the field of a variable or port_token, use the standard format of port_token.field_name, variable_name.field_name and parameter.field_name. Port name is used for making a control decision. For example, the port_name could be used as the SWITCH (port_name).  Port name can also be used in a if-else as a test to see the source or origination.

Most Virtual Machine code operate as a single sequence or thread. It is possible to create model with Threads that can execute in parallel. The process to create a Thread is to define a LABEL:”Name” followed by a sequence of code that stands by itself. This will be a continuous loop in most cases. The main thread flow will start this new thread by calling it using the SEND operation. The format is SEND (Label_Name, value). The port_token is normally the best value to be sent out. When the SEND function is called, it starts the new Thread but does not start executing it immediately. When the executing Thread goes to a TIMEQ or a GTO (END) or completes the code execution for a port_token, then the new Thread starts executing as a synchronous (0.0 time event).  Using the TIMEQ function allows one to enforce different rates for each thread.


Parts of the Code

Initialize

All code before the LABEL line, "LABEL: BEGIN" is considered initialize.  During the Initialize phase, all the variables are defined and initial values are assigned.  To improve simulation performance, parameter values are assigned to internal variables for use within this block. It is possible to define loops and execution sequence in the initialize that can execute any time in the future.  This is used for starting the statistics gathering and reporting the same at the termination of a simulation.  

Note: An alternate way to initialize is to add the hidden parameter Self_Start to the block and setting the value to true.  In this case, the LABEL: BEGIN must not be in the code.

Execution

The sequence of code can utilize the incoming data structures field, variable (local, global and variable-defined inside this block), RegEx language and parameter values.  Using the virtual connection methodology, the VM can use the built-in RegEx functions to send the Data Structures to Virtual Connection, Schedulers and other Virtual Machine blocks.  The block has a set of standard functions, a set of specific methods and resource definition, and the complete RegEx language.

To access the code, Right-click on the block and select "Open Block". Alternately, the code can be located in a text file.

The block can be self-triggered (set Self_Start = true) or triggered by an incoming data structure (either ports or virtual connections).  If the Self_start parameter is set to true for the block, do not use the LABEL: BEGIN.  The Self_Start executes the initial code.  Self_Start is used when the block will not receive any inputs and will execute in a continuous loop.  This is useful for defining arbitration algorithms that run on clock cycles. 

The code then execute in sequence.  A WAIT in the code creates a blocking operation and prevents any further execution of any data structure until the time has elapsed.  A WAIT can also contain an EVENT.  This requires the EVENT to be triggered in another block in the model.  Additional input/output ports can be added. Virtual_Machine supports both local and global virtual input/output. The input ports will be processed using an "OR" approach, meaning one at a time.  The SEND function will send the values to the output ports, vitual connections, other Virtual Machine blocks or a LABEL.

The SEND operation behaves as a port activity of the block.  When the SEND is executed, it can cause execution of code in another virtual machine (virtual connection) or a sequence of blocks if connected to the output port or a virtual connection block.  The current code will start executing on the next line only when the transaction has encountered a delay, relation or a end of sequence.  All of this will occur in zero time.


Differences from C/C++ program

The Virtual Machine works like a function block in C programming or script.  The simple logic expressions use a C/C++ syntax.  Note the following:

  1. Virtual Machine does not require ';' at end of each expression statement, however can have end-of-line C/C++ ';' syntax.
  2. There can be only one operation per line.  This can be an expression, LABEL:, or curly bracket {.
  3. Declaration not required, unless initial value by Name = value;  This will declare the data type.
  4. If no declaration, then the first use on the Left Hand Side (LHS) of an expression determines the data type.
  5. LABEL, SWITCH, CASE, BREAK need to be all capitals.
  6. CASE: Value can be integer, long, double, string, or a model parameter.
  7. End of each CASE requires a BREAK, RETURN, GTO(Value), or GTO (END).
  8. The last CASE statement must be CASE: DEFAULT to define the scope of the SWITCH, CASE.
  9. Pointers are not supported, only reference by variable name is supported.
  10. There must be at least one statement line between { and }.
  11. The Virtual Machine supports both /* string */ and //string comment styles.

To learn more about the Virtual Machine, click here for VM_Basic_Features model.


Keywords

if, if-else, else, else-if

single line if-else

while

LABEL

SWITCH/CASE/BREAK

CALL/ RETURN

GTO

EXIT or GTO(END)

CANCEL

for


S.NO.
KEYWORD
SYNTAX
DESCRIPTION
1.
LABEL
LABEL:Nam
  • An identifier to denote a specific address in the code. This can be used to send the DS to continue processing from a particular point in the code. It is used in conjunction with GTO ("Name"). 
  • Virtual_Machine, Virtual_Machine_Untimed, Smart_Controller now sends to LABEL: by adding to the input queue, instead of generating a 0.0 event.
  • The previous method would place multiple send to LABEL: data structures in correct order. 
  • This update improves performance, and in correct sequence for this use model.
2.
If,
else if,
else
if(<conditional statement>)
{
    
<true statements>
}
else if
(<conditional statement>)
{
    
<true statements>
}
else
{
    
<false statements>
}

     This is a traditional if condition.
3.
Single line If-else
<conditional statement> ? <true statement> : <false statement
  •  This is a single line if-else statement.
  • This is used where a field or variable is updated based on a condition or a data flow is routed based on a field at a threshold.
4.
SWITCH,
 CASE,
 BREAK
SWITCH (port_token.ID) { /* Decodes ID integer field of Transaction */
   CASE: 0
      <RegEx statements>      
   BREAK      /* Exit from script           */
   CASE: DEFAULT  /* Last CASE, unlike C code, must be DEFAULT  */
      <RegEx statements>
   GTO (END)      /* Exit from script           */
}
     This is similar to C format with some differences.
5.
While

while (true)        /* Loop */
  {
     Remain_Bytes  = readField(port_token, Bytes_Remaining_Field)

                                   /* Down Counter */
     WAIT (Time_Between_Fragments)
                                     /* Delay */

  }

  •      This operates in a loop and terminates when a condition is reached.
  •  This is commonly used to conduct a repetitive search, or loop through a sequence of operation for each index in an array or fragment.
6.
CALL,
 RETURN
CALL (Name)
 
                                                              Note: The NAME is a LABEL
  •    This function is used to call a common piece of code.
  • The port_token in the current flow, before the CALL, must be a data structure. It cannot be a Scalar, Boolean or String type.
1.  At the end of the routine, the token must encounter a RETURN and this returns the control to the next line after the CALL in the calling code.
2.  Any actions within this routine that jumps out (example: GTO (END)), will prevent the token from returning to the original caller. This means that the lines following the CALL function will not be executed.
3.   If there is a TIMEQ within the called routine, the token used in the TIMEQ must be port_token, else an error will be generated.
4.  The CALL function stalls the current thread and start executing the called function. 
When a TIMEQ is encountered in the Called thread, the next item in the input queue starts executing.
The code beyond the CALL function does not execute until the return from the called function.
7.
CANCEL CANCEL (“RemoteBlockName”, “wait”)                                                 // cancels first, only event for WAIT
CANCEL (“RemoteBlockName”,
                  “MyTimeq”)                  
                              // cancels first event for MyTimeq
CANCEL (“MyTimeq”, Event_Time)         
                             // cancels first event with simulation Time = t, user needs to know when event fires. 
CANCEL (“RemoteBlockName”, “MyTimeq”, Event_ID)  
                            // cancels event with EventID > 0, user can copy DSs in TIMEQ to obtain Event_ID field



CANCEL (“RemoteBlockName”, “wait”)                             
                                                          // cancels first, only event for WAIT
CANCEL (“RemoteBlockName”, “MyTimeq”)                     
                                                           // cancels first event for MyTimeq
CANCEL (“RemoteBlockName”, “MyTimeq”, Event_ID)   
                                                          // cancels event with EventID > 0, user can copy DSs in TIMEQ to obtain Event_ID field
CANCEL (“RemoteBlockName”, “MyTimeq”, Event_Time)
                                                          // cancels first event with simulation Time = t, user needs to know when event fires.



public static double cancelEvent(String block_name, String name)                      { ... }
public static double cancelEvent(String block_name, String name, int evt_id)                    { ... }
public static double cancelEvent(String block_name, String name, double time)                       { ... }


  • This function is used to cancel an event already scheduled.
  • They are supported for TIMEQ = “MyTimeq” in Virtual_Machine, Smart_Controller block. Event_Time field contains time.
  • If result from CANCEL is greater than 0.0, then event was successfully removed, else event not found. 
  • If an event is successfully removed, then it is removed from VM block event queue, TIMEQ by name, immediate Digital, and top Digital. Event_ID will delete a specific event by ID, Time will delete async events by time, equal to Event_Time field. 
  • All TIMEQ by name will use the same Event_ID mechanism, and all will be unique IDs.


  • They are supported for WAIT, TIMEQ in another Virtual_Machine, Smart_Controller block.










  • LHS of expression can be block variable, or port token with a field. 
  • ‘result’ is the default variable, and if no ‘=’ sign then result of CANCEL will be placed in ‘result’.
  • If result from CANCEL is greater than 0.0, then event was successfully removed, else event not found.  There are three RegEx commands that can be executed from Processing, Decision, VM blocks.
  • If the return is true, then the event was cancelled, else it could not be found.  If the id == 0, then the time will be used to delete the first event at ‘time’.
8.
for

for(idx=0;idx<10;idx++)   {

       flag_arr(i)   =   true

}

  • This operates in a loop and terminates when a condition is reached.
  •  This is commonly used to conduct a repetitive search, or loop through a sequence of operation for each index in an array or fragment.


9.
EXIT or GTO(END) EXIT
  • These function are equivalent statements to end or exit a running Virtual_Machine thread.


Functions

FUNCTIONS
DESCRIPTION
SYNTAX

fragment

this function is used to generate the fragments as per the word size specified

frag_arr=port_token.fragment(burst_word_size)
Note: The data structure should contain A_Bytes field which specifies the total payload of the packet which has to be fragmented
newToken
this function is used for generating a new data structure
newDS=newToken("Processor_DS")
newArray
this function is used for creating an array of saaid lenth with said values
arr=newArray(10,true)
getBlockStatus
this fuction is used to get the statistics of resource blocks
resource_data=getBlockStatus(Resource_Name,<option>,int index)
<option> can be "copy","length","stats","take"

Methods

1.

WAIT (<time> or <event> or <clock_hertz>)

5.

QUEUE (<queue name>, <token>, <priority>, <queue operation>)

2.

SEND (<port name> or <Virtual_Machine(Block_Name)> or <virtual_connection> or <label>, <token expression>, optional <delay>)

6.

TIMEQ (<queue name>, <token>, <priority>, <queue operation>, <delay expression> or <clock_hertz>)

3.

PLOT(<plot_name>,<destination>,<plot_color>,<plot_offset>,<plot_value 1.0 or 0.0>)

7.

CLOCK(“MyEvent”)

4.

EVENT, newEvent, .event()



WAIT
DESCRIPTION:
o  This is a delay and holds the Virtual_Machine from operating on any data structure until the time has expired.
o  The WAIT is used for blocking delay, meaning no other statements will execute, till the WAIT() completes.
o  If the WAIT refers to a string "MyEvent", then it will wait on an EVENT.
If the WAIT refers to a clock_hertz as an integer or long, then it will wait for the specific clock time.
SYNTAX:
CLOCK(“MyEvent”)
SEND
S.NO.
SYNTAX & SUPPORTED FORMATS
DESCRIPTION
1.
SEND (<port name>or <virtual_connection> or <label>, <token expression>)




Example:
SEND (output, port_token)
 o    This method can send to a port, virtual connection, another Virtual_Machine or to a LABEL.  The first two are to send the data structure out of this block, the latter to create a thread.
o    Port_name identifies the output destination.

o    Token_expression is the value to be output.  This can be a string, RegEx operation or a token.

o    The send to LABEL creates a new Thread within the Virtual_Machine that can be executed parallelly.

The <port name>  can have the following options: port name of this block, port_token.field_name where the destination is in the field of the data structure, name of another Virtual Machine block in the model, Destination of a IN or MUX block and a LABEL of the current block.

The output value can be the port_token, any variable name, field in a variable or a data structure field.

The output value can be of any data type.



2.
SEND (<port name>or <virtual_connection>, <token expression>, <delay>)


Example:
SEND (output, port_token, 1.0)
SEND (output, port_token, delay)
SEND (output, port_token, BlkVar.field)
o    This method can send to a port, virtual connection with a delay.  Delay can be a double, block variable, or block variable with a field. SEND supports (X.field, Y.field, Z.field) field arguments in a block variable.
o    Port_name identifies the output destination.
o    Token_expression is the value to be output.  This can be a string, RegEx operation or a token.
3.
MyLength  =QUEUE (“MyQueueName”, “length”) gets the statistics, places in block variable "MyStats".
4.
MyStats     = QUEUE (“MyQueueName”, “stats”) gets the statistics, places in block variable "MyStats".
5.
MyToken  = QUEUE (“MyQueueName”, “pop”) gets the first item out of the Queue, places in block variable "MyToken".
PLOT
DESCRIPTION:
o  One can plot values using the format, presumably with a delay in between one and zero values using a WAIT(), TIMEQ expression.
 
o  The plot_value is relative to the current value, to allow for multiple levels, meaning if the offset is 1, and the first value is 0.0, then the plot will go to 0.0, whereas a first value of 1.0 will plot a 2.0
 

The supported colors are:
{"red","blue","cyan","black","orange","cadet_blue","coral","green","brown","grey","bright_green","french_rose","indigo",
"cornflower_blue","chocolate","gold","purple","pumpkin","sapphire","rust","maroon","moss_green"

SYNTAX:
PLOT(<plot_name>,<destination>,<plot_color>,<plot_offset>,<plot_value 1.0 or 0.0>)



PLOT("MyPlot","output","red",0,1.0)  /* Plot 1.0 with 0 offset         */

WAIT(1.0)

PLOT("MyPlot","output","red",0,0.0)  /* Plot 0.0 with 0 offset         */

 

EVENT

DESCRIPTION:
A Model Event is similar to a time event, except generated by the user, and can occur at any time between blocks.
In other words, a model condition triggers a Model Event for synchronizing between blocks, or within clock-driven processes.
The most common use is to generate clocks from a single block to multiple blocks waiting for a clock event.

SYNTAX:
EVENT, newEvent, .event()
S.NO.
SYNTAX & SUPPORTED FORMATS
DESCRIPTION
1.
newEvent (“MyEvent”) o    Model Events can be generated from any RegEx block using the following RegEx function.

2.
("MyEvent").event()                                                   //A alternate and newer                                                                             format for any RegEx block
 o    One can also place it an expression, and it will return true if a WAIT() is pending, else false.
3.
newEvent(MyParameter + “_MyEvent”)                    //for events inside                                                                                              hierarchical block o    The argument of newEvent must evaluate to a string name.
o    This function can be applied in Processing, Decision, Virtual_Machine or Smart_Controller Blocks.
4.
EVENT (“MyEvent”)









WAIT (“My_Event_Name”)

o    The Virtual_Machine and Smart_Controller blocks also support the following syntax which executes locally on the Virtual_Machine or Smart_Controller block.
o     This notation is preferred over the newEvent() RegEx notation.







Blocking event WAIT() does not allow any other statements to execute, till the WAIT() continues.
The blocking WAIT (“My_Event_Name”) will not allow any other actions in the block, until an EVENT(“My_Event_Name”) is called
.

The WAIT (time) function and TIMEQ (…,time) functions can include a clock synchronization feature.  Currently, the argument ‘time’ can be a double value, meaning the WAIT() or TIMEQ() will wait that amount of time, once it begins execution.  If ‘time’ is represented as a long, then the statements will interpret ‘time’ as the clock speed in Hertz.  This means that the delay will be based on the current simulation time and when the next clock cycle occurs.  If the ‘time’ argument is 1, then this means every 1.0 second a clock will occur.  If the statement is executes at 0.0 sec, then the WAIT() or TIMEQ() will complete at 1.0 sec, or one clock cycle later.  If the statement executes at 0.5 sec, then the WAIT() or TIMEQ() will complete at 1.0 sec, or the next clock time.  In other words, the clock synchronization feature synchronizes execution with this clock rate.
5.
WAIT (“MyEvent”)









TIMEQ (“My_Event_Name”)
    In a corresponding Virtual_Machine or Smart_Controller block, the user needs a matching syntax as follows.
    This statement will continue processing on the next statement once it receives a newEvent() or EVENT(). If the newEvent() or EVENT() is generated before the WAIT() on event, characterized as a string argument, then the WAIT() will immediately go to the next statement. Finally, if two newEvent()’s or EVENT()’s are generated prior to a WAIT (“MyEvent”) only one will execute similar to an ‘OR’ of pending events. This is done to prevent the unintentional build up of events in a model, that may not execute as expected.




Non-blocking event TIMEQ does allow other statements to execute.
The non-blocking TIMEQ(“My_Event_Name”) will allow the block to process other inputs or events, prior to receiving an EVENT (“My_Event_Name”).
QUEUE

ATTRIBUTES:

o    queue_name is an unique identifier.  Every queue will have an unique name.  This is a string.

o    Token is the item that needs to be stored in the queue.

o    Priority is used to reorder the queue.  This can be a field, variable or a value.  This is an integer.

o    Queue_operation can be "put" or "pop".  put puts the token into the queue and the pop takes it out.  The string must be within " ".


DESCRIPTION:

  • This stores and removes the token in the Queue in a FIFO method.
  • The queue is reordered based on the priority of the incoming token.
  • The QUEUE need not be declared before use.
  •  "copy", "length", "get", "pop", "take" operations will also place the queue length in the block variable called "length".
  •  This will overwritten if another QUEUE is accessed.

S.NO.
SYNTAX & SUPPORTED FORMATS
DESCRIPTION & EXAMPLES (Access within the same Virtual Machine )
1.
QUEUE (<queue name>, <token>, <priority>, <queue operation>)
  QUEUE (queue_one, port_token, 1, "put")
2.
MyCopy    =QUEUE (“MyQueueName”, “copy”) gets the first item out of the Queue, places in block variable "MyCopy".
3.
MyLength  =QUEUE (“MyQueueName”, “length”) gets the statistics, places in block variable "MyStats".
4.
MyStats     = QUEUE (“MyQueueName”, “stats”) gets the statistics, places in block variable "MyStats".
5.
MyToken  = QUEUE (“MyQueueName”, “pop”) gets the first item out of the Queue, places in block variable "MyToken".

STATISTICS OF THE QUEUE

ATTRIBUTES:

o    The LHS is a variable that contains the result of the getBlockStatus operation.

o    o Virtual_Machine_Name is the Block_Reference (default Block_Name) of the Virtual_Machine containing the QUEUE. This is a string in "".

o    QUEUE_name is the queue for which the options are accessed.  This is a string in "".

o    The options are "copy" (based on the Index number), "stats" (to get the current stats if index=1 and reset stats if index=-1), "length" (to get the current queue length) and "take" (remove the position in the queue based on index value).

o    Index is an integer value.  For "copy", this is position in the queue. For "stats", this gets the stats (1) or resets the stats (-1).  For length, this is not used but a value must be present.  For "take", this is the position in the queue.


FORMAT:

getBlockStatus (Virtual_Machine Name,  QUEUE_name, <option>, int Index)    
                                                                    // one-based Index



EXAMPLE:

wr_data     = getBlockStatus (VM1, "Cache_Access", "stats", 0)
TIMEQ
ATTRIBUTES:

o    queue_name is an unique identifier.  Every queue will have an unique name with type string.

o    Token is the item that needs to be stored in the queue.

o    Priority is used to reorder the queue.  This can be a field, variable or a value with type integer.

o    Delay_expression is service time for the token when it reaches the head of the queue.


DESCRIPTION:
o    This stores the token in a queue in a FIFO fashion, delays it when it comes to the head of the queue and then sends it to the next line to execute.  The queue is reordered based on the priority of the incoming token.
o     Events can be scheduled internal to the Virtual Machine using the TIMEQ much like a Timed Queue block.
o      Several TIMEQs can be executed in parallel without effecting the delay of other TIMEQs.
o      TIMEQ need not be declared before use.
o    TIMEQ "copy", "length", "set", "take" operations will also place the queue length in the block variable "length".  This is useful if a "non_block" is performed, the "length" is automatically available.

   

S.NO.
SYNTAX & SUPPORTED FORMATS
DESCRIPTION & EXAMPLES (Access within the same Virtual Machine )
1.
TIMEQ (<queue name>, <token>, <priority>, <delay expression>)
  TIMEQ (timequeue_one, port_token, 1, "non_block", port_token.A_Delay)
2.
MyCopy    =TIMEQ(“MyTimeqName”, “copy”) copy the first item out of the TIMEQ, places in block variable "MyCopy".
3.
MyLength  =TIMEQ(“MyTimeqName”, “length”) gets the statistics, places in block variable "MyLength".
4.
MyStats     = TIMEQ(“MyTimeqName”, “stats”) gets the statistics, places in block variable "MyStats".
5.
MyToken  = TIMEQ(“MyTimeqName”,port_token, 0, 1.0) gets the first item out of the Queue, places in variable "MyToken".
6.
TIMEQ (“MyEvent") If the TIMEQ has a single parameter which is of type string, then it will wait on an EVENT that matches the string value.
7.
TIMEQ (“MyTimeqName”, port_token, 0, round (1.0E06 * Clock_Speed_Mhz)) If the TIMEQ refers to a clock_hertz as an integer or long, then it will wait for the specific clock time. The clock time means that the value align to a clock boundary. Refer to section Model Event
8.
TIMEQ
GTO(END)
LABEL: BEGIN
If a TIMEQ precedes LABEL: BEGIN, GTO (END) is required before LABEL: BEGIN to cause the TIMEQ thread to exit.I
STATISTICS OF THE TIMEQ
ATTRIBUTES:

o    The LHS is a variable that contains the result of the getBlockStatus operation.

o     Virtual_Machine_Name is the Block_Reference (default Block_Name) of the Virtual_Machine containing the TIMEQ. This is a string in "".

o    TIMEQ_name is the queue for which the options are accessed. This is a string in "".

o   The options are "copy" (Index is the position in the TIMEQ), "stats" (to get the current stats if index=1 and reset stats if index= -1), "length" (to get the current queue length) and "take" (remove the 'Index' position in the queue).

o    Index is an integer value.  For "copy", this is position in the queue. For "stats", this gets the stats (1) or resets the stats (-1).  For length, this is not used but a value must be present.  For "take", this is the position in the queue.


FORMAT:

getBlockStatus (Virtual_Machine Name, TIMEQ_name, <option>, int Index)    
                                                                    // one-based Index



EXAMPLE:

wr_data     = getBlockStatus(VM1, "Cache_Access", "stats") 
CLOCK

DESCRIPTION:
oThis is an added variation of EVENT that will selectively fire a WAIT (“MyEvent”) or TIMEQ (“MyEvent”), only if the WAIT or TIMEQ instruction has a data structure waiting, else nothing is executed.
o It acts like a virtual clock.
SYNTAX:
CLOCK(“MyEvent”)

Threads

THREADS
DESCRIPTION:
  • Threads are a integral part of the Virtual Machine code.
  • The threads can be used to manage the statistics or run a independent signaling process or for a polling procedure or a fixed internal interrupt.
  • When a given thread reaches a TIMEQ() function, that particular thread's execution stops there until the conditions for its continuation (defined in the arguments of the TIMEQ) are satisfied.  During this time, other threads can execute.  You can have 2 or more threads whose relationship to each other (from a modeling perspective) is asynchronous.  Parallel operation is from the modeling perspective only - not from the actual computer hardware.
  • There are two perspectives here:
    • Simulation Model Perspective - The fact that two threads running in parallel is denoted by the fact that their model time (thread begin through thread end) overlap
    • Computer/OS Perspective - Two threads running in "parallel" cannot happen - one runs before the other (which one that is - is indeterminate)
EXAMPLE:
  • Look at the example in doc\Training_Material\General\Virtual_Machine\MultiThread_VM.xml.
HOW TO CREATE A THREAD:
  • The process to create a Thread is: 
                    1. Define a LABEL:”Name” followed by a sequence of code that stands by itself.
                    2.
The code between LABEL and the end will be a continuous loop in most cases.
                    3.
The main thread flow will start this new thread by calling it using the SEND operation. The format is SEND (Label_Name, value). The port_token is normally the best value to be sent out.
                    4.
When the SEND function is called, it starts the new Thread but does not start executing it immediately. When the executing Thread goes to a TIMEQ, EXIT or a GTO (END) or completes the code execution for a port_token, then the new Thread starts executing as a synchronous (0.0 time event).
                    5.
Using the TIMEQ function allows one to enforce different rates for each thread.

    Variable Reference

    VARIABLE REFERENCE
    DESCRIPTION:
    • VM blocks updated to check if a Parameter is on LHS of an expression in VM JIT compiler.
    • Also, applies to Optional_Parameters text window, a parameter as name of Optional_Parameter.
    • Variable_Init also checks for paramters as names of Global or Local variable.
    • Also added a check of parameters being written to during a simulation by placing in WARNINGVisualSimConsoleLog.txt log file.
        • Virtual_Machine, Virtual_Machine_Untimed, Smart_Controller variable now supports a flag to indicate it is a parameter, and if the key is written to, meaning LHS of expression, then a warning is issued to the VisualSimConsoleLog.txt file. 

        • In addition, if a parameter is placed on the LHS of an expression, then it will throw an exception indicating one is trying to update a parameter, which should be constant throughout a simulation. 

        • Top Digital checks parameter conflicts with Global, Local variable and parameters after 1000 events, and if any conflicts are found,a warning is issued to the model VisualSimConsoleLog.txt file.

    S.NO.
    SYNTAX
    DESCRIPTION
    1.
    public boolean setTrace (String trace_name, boolean flag)   {  ...  }
    There is a new RegEx function to enable tracing of Virtual_Machine, Smart_Controller, Global_variable, Local_variable.  This update allows for turning on/off trace, where the flag set to true enables tracing, false turns it off.  In UtilityFunctions, this syntax is used.
    2.
    Listen_to_File               = none
                                                                  
    /* by default , change none to the file name in which the listen to file have to be saved, then the file will be saved as per the name specifed in    the path mentioned ( another optional parameter ) */
    The trace_name can be “variable” to trace global, local variable.  So the user can selectively listen to variable by turning flag on or off.  In the VM blocks, the flag sets, this expression is used.

    So, user can selectively listen to file by changing the default value "none".  trace_name is the name of the specific VM block, useful for DI cases.  If setTrace is not used, then the Optional_Parameters work as before defining Listen_to_File.
    3.
    RegEx myTrace (trace_name, trace)   User can send to the trace file without above setTrace, using this only, just like
     myWarning.( can be seen in
    VisualSimTraceLog.txt file ).
    4.
    readAndClearTrace()
     Another RegEx funtion that reads the current trace file, and clears the current one.
    This is useful for tracing specific areas, and obtaining the current trace.
    5.
    writeFile(file_name, string) For saving to a separate file, using this RegEx command.
    6.  

    Ref_Mem = ("GlobalVariableName").read()

    Ref_Mem = (local_variable + "LocalVariableName").read()

    Ref_Mem = ("BlockVariableName").read("Block_Name")

    ("GlobalVariableName").check()

    (local_variable + "LocalVariableName").check()

    ("BlockVariableName").check("Block_Name")

    In the Virtual_Machine, Virtual_Machine_Untimed, Smart_Controller, Processing and Decision blocks, Reference name to a variable (local or global) can be created. There are variable reference formats to access local, global, and block level memory.


    The last three can be used to first check if the variable exists before reading it.
    7.

    ("GlobalVariableName").write(MyToken)

    (local_variable + "LocalVariableName").write(MyToken)

    ("BlockVariableName").write("Block_Name", MyToken)

    There are newly supported variable references for write operation for local, global, and block level variable.  The variable local_variable is a keyword that references the local variable.

    Writing to these variable locations will alter variable references previously executed.

    Note: If you place the GlobalVariableName or the Ref_Mem on the LHS of an equation and have an assignment on the RHS, the reference is lost and the two will behave like independent variable variables.

    For example, this is correct:

    Ref_Var = (“GlobalVariableName”).read()

    Ref_Var.incr()

    Other_Variable = Ref_Var + 2

    This is incorrect and will delink the variable.

    Ref_Var = (“GlobalVariableName”).read()

    Ref_Var = Ref_Var.incr() /* This creates a new space and the reference is lost */

    GlobalVaribaleName = Ref_Var + 2 /* This delinks the original reference *.



    Other Operations

    S.NO.
    OPERATIONS
    SYNTAX
    DESCRIPTION
    1.
    Fragmentation fragment()           For the data structure "Processor_DS" , we can fragment the bytes using this function.
    2.
    Fragmentation limit frag_arr = port_token.fragment(val)           In this format, val defines the fragmentation limit. if the A_Bytes value is greater than fragmentation limit, then they gets fragmented.
    For example:
                         lets say A_Bytes=64 and val=16. Then the frag_arr will have 4 fragmented parts. frag_arr as a whole is a 2D array. In this case frag_arr will be of length 4 and can be accessed from index 0 to 3.

    3.
    Accessing statistics of Model Resources

    getBlockStatus(Resource_Name, <option>, int Index)

              The getBlockStatus is the easiest way to get access to the statistics, length, first token in the queue and remove the first item in a queue.
    Usage:
               wr_data     = getBlockStatus(Sched_1, "stats", 0)

    o    The LHS is a variable that contains the result of the getBlockStatus operation.

    o    Resource_Name is the Scheduler or Smart_Resource Block_Name.  This is a string in "".

    o    The options are "copy" (gets the head of the queue for the Smart_Resource and not available for the Scheduler), "stats" (current stats if index=1 and reset stats if index= -1for both the Smart_Resource and Scheduler), "length" (get the current queue length for the Smart_Resource and Scheduler) and "take" (remove the head of the queue for the Smart_Resource).

    o    Index is an integer value.  For "copy", this is the queue for the Smart_Resource. For "stats", this gets stats (1) or resets the stats (-1) for both the Smart_Resource and Scheduler.  For length, this is the queue number of the Smart_Resource and needs any value for the Scheduler.  For "take", this is the is the queue number of the Smart_Resource.

    4.
    Length of a specific queue Smart_Resource_Name+"_"+Length(Queue Number)          The length of the Smart_Resource is an array of multiple queue and is accessed a lot within the Virtual_Machine to make a decision. 
             To accelerate the access, the length of a specific queue inside the Smart_Resource can be accessed as given.
    5.
    Length of the Smart_Resource Smart_Resource_Name+"_"+Length

            You can get the entire array by this format.

            This will contain an extra value in index 0 which is not used.  The queue number to index start at 1.

    For example, this would be
                                            
    Queue_Length = Smart_Resource_1_Length(10)
                                                                 
    where Smart_Resource_1 is the name and we are looking for the 10th queue.
    6.
    Scheduler Acess
    scheduleTask(Token token, String return_name, String  sched_name, double  task_time, double tnow, int task_priority, int task_id, boolean mutex)         The user can schedule to a Scheduler_HW or Scheduler_SW using the RegEx scheduler function.
            This task will return to this Virtual Machine if the return_name, in the expression, is the same as the Block_Reference (Block_Name).

    Important Virtual_Machine RegEx Functions

    1. Create a new Token from the VisualSim/data folder

    MyToken = newToken ("Processor_DS")
    MyArray = newToken ("{100:0}")

    2. Create a new variable or Field

    port_token.A_New_Field   = Field_Value

    ("MyNewVariable").write(Variable_Value)                                                                                                                        where Field_Value or Variable_Value can be a parameter or block level variable.

    3. Check if Data Structure contains field

    if  (port_token.check("A_Command"))
    {
          port_token.RIO_Command = port_token.A_Command + "_" + Block_Name
    }

    4. Read a variable or Field and insert into a field of port_token

    port_token.MyField  = readField(port_token, Channel_Field_Name)

    port_token.MyField  = port_token.get(Channel_Field_Name)

    port_token.MyField  = (("MyVariable").read()).get(Variable_Field_Name)                                                             where Channel_Field_Name or Variable_Field_Name can be a parameter or block level variable.

    5. Throw a model exception, stop the simulation
    throwMyException (Block_Name + " has a Channel value that is inconsistent.")
    6. Send statement to the Command Line (debug is block variable flag), do not stop the simulation
    debug ? sendToCommandLine (Block_Name + " next Cache Prefetch (" + C_Prefetch.ID + ") \t@ " + formatTime(TNow)) : Tnow

    7. Array processing for 1D operations incrementing, decrementing values; removing head, tail; and searching
    S.NO
    SYNTAX
    DESCRIPTION
    1.
    (MyArray(index)).incr()
    can be used for block level arrays, or references to local, global arrays.  Returns updated value.
    2.
    (MyArray(index)).decr() can be used for block level arrays, or references to local, global arrays.  Returns updated value.
    3.
    MyArray.removeHead()  removes from position 0.
    4.
     MyArray.removeTail() removes from last position.Useful for queue-like operations.
    5.
    MyArray.search(matching_token, starting_index) will return the index of  the first matching token, whether integer, long, double, or string.
    6.
    MyArray.firstGreaterThanZero(starting_index) will return the first index greater than zero, whether integer, long, double.
    8. Array processing for 2D operations incrementing, decrementing values

    S.NO
    SYNTAX
    DESCRIPTION
    1.
    MyArrayArray.incrementArrayArrayElement(index, index2)  increments the specific element.
    2.
    MyArrayArray.decrementArrayArrayElement(index, index2)  decrements the specific element.
    9. Format Time

    formatTime(TNow)

    ------ 25.43410 us ------

    10. Identify a Architectural Library Hello Message and add a new device to the Routing Table

    if  (port_token.A_Destination == Architecture_Name)
    {
         addToRoutingTable(Architecture_Name, port_token.A_Source, Block_Name, port_token.A_Hop) /* Src, Des, Hop, Port */
    }

         Using the Processor_DS or one might simply pass the hello message.
         If A_Destination != Architecture_Name (parameter), then this can be the non-hello message flow

    Special Functions- Available only for the Virtual Machine

    S.NO
    FUNCTIONS
    SYNTAX & EXAMPLES
    DESCRIPTION
    1.
         ++
          --
    ++MyInt                               // integer
    ++MyLong                          // long
    ++MyDouble                       // double
    ++MyDS.MyIntField           // data structure integer
    ++MyDS.MyLongField      // data structure long
    ++MyDS.MyDoubleField   // data structure double
    ++MyArr(index)                  // array with int, long, double elements

    Here is an example:  This works:

    Idx         = 0
    while (Idx  < 10) {
       SEND (output, Idx)
       ++Idx
    }

           Applies to single variables only, not functions.
           These are some ++ examples, which also apply to --
    The most common use is for loop indexes. 






    This does not work:

    Idx         = 0
    while (++Idx  < 10)  {          // cannot have ++ increment inside a conditional
       SEND (output, Idx)           // or function, just single variables
    }
    2.
         +=
         -=
         *=
         /=
         %=
    MyInt        += MyInt2                                  // integer
    MyLong    += MyLong2                             // long
    MyDouble += MyDouble2                          // double
    MyString   += MyString2                            // string
    MyInt        += MyInt2         + MyInt3         // integer (2)
    MyLong    += MyLong2     + MyLong3    // long    (2)
    MyDouble += MyDouble2 + MySouble3  // double  (2)
    MyString   += MyString2   + MyString3    // string  (2)
          applies to single and double values only.  Note: That this functional cannot have a expression on the RHS.  If you do so, you will get erroneous results.  Here are some += examples, which also apply to -=, *=, /=, %=.
         
    These expressions are used in loops, conditional statements.  The RHS cannot contain functions, just single variables.
    3.
    Address Here is an example:

    LABEL: BEGIN
    if (port_name  == scheduler) {  // from Scheduler
       GTO (port_token.Address)
    }
    else                         {
       port_token.Address = address + 2

       // to Scheduler, scheduleTask in RegEx documentation
       result       = scheduleTask(port_token,"MyRTOS",Cmd_In,Idx_In*Cycle_t,TNow,Pri_In,ID,false)
       EXIT
       LABEL: Return_Here
       // continue
    }
    EXIT

             A keyword that will obtain the current script address and save as a variable.
            This is useful for executing Scheduler blocks from a Virtual_Machine by setting a field to address + 2, and computed GTO (port_token.Address).  A scheduler will return to the port_name ‘scheduler’. 
            With this mechanism one can process multiple Schedulers with returns in a single Virtual_Machine. 

                                 



    Debugging Scripts

    For small scripts, less than 30 lines, right click the Virtual_Machine block and select Listen to Block. Use this approach to verify the correctness of the RegEx statement during execution. To debug larger scripts, enable the parameter Single_Cycle and set the block parameter Breakpoint to an expression that evaluates to true. The most common “Breakpoint” expression is TNow >= 1.0 (Some time unit). In addition, the "Breakpoint” expression can combine time and a specific address, such as

    TNow >= 1.0 && address == 10

    To start the debugging, the user must first select Listen to Block for this Virtual_Machine. The first time the "Breakpoint" is valid, a pop-up window will ask:

    List_Memories? (Yes or No)

    If you accept, all the memories and the current values of the optional parameters will be displayed. When user hits "Run or Resume (Ctrl + R) the model will move to the next execution point where the Breakpoint evaluates to true.  After 10 instructions repetitions, a pop-up window will ask:

    Continue Single Cycle? (Yes or No)

    If the user selects no, then the model will continue to the end of the simulation. Another way to debug a portion of a script execution would be to define a time window:

    Breakpoint TNow > 1.0E-03 && TNow < 2.0E-03

    This will execute a breakpoint, asking List_Memories? after 1.0E-03 sim time, continue to execute 10 statements for every "Run or Resume..." selection, and once the simulation time, TNow is greater than 2.0E-03, the model will continue to run without single cycle. Users can enter a single line conditional statement to set a value, as long as the statement result is true or false:

    Breakpoint TNow>1.0E-03 && TNow<2.0E-03 ? (MyMem == 3 ? (MyMem.newValue(4) == 4 ? true : false) : false) : false

    This expression will stop on statement 10, if the Simulation time TNow >= 1.0. Everytime the Run/Resume Run is pushed, the next script line will execute. In addition, Block_Memories will be displayed prior to the execution of each Single_Cycle statement, so one can checkout the values.

    Before each execution statement in Single_Cycle mode, one can see the following (typical) output:

    Block Memories:            @ 0.10 ns
      statistics:    {a=1,b=2}
      self_start:    false
      port_token:    {BLOCK="Transaction_Source",DELTA=0.0,DS_NAME="Header_Only",ID=1,INDEX=0,TIME=1.0E-10}
      port_name:    __LABEL__
      main_Length:    1
      local_variable:    MultiThread_VM.
      length:    0
      input:    {BLOCK="Transaction_Source",DELTA=0.0,DS_NAME="Header_Only",ID=1,INDEX=0,TIME=1.0E-10}
      first_Length:    1
      counter2:    199
      counter1:    99
      counter:    0
      copy:    {1,2}
      address:    33
      __LABEL___Length:    0
      TStop:    10.0
      TResolution:    1.0E-10
      TNow:    1.0E-10
      Save_Files:    false
      Read_File:    none
      Profile_File:    none
      Profile:    0
      Port_Order_Array:    {"input"}
      Path:    none
      MyPlotThread2:    true
      MyPlotThread1:    true
      Maximum_Loops:    1000000
      Listen_to_File:    none
      Input_Queue_Length:    0
      Duplicate_Input:    true
      Block_Reference:    Threads
      Block_Path:    MultiThread_VM.
      Add_Scheduler_Times_to_DS:    false

    Expression  (33):    GTO (2)
      Result        :    35

    *** SEND ***    :     0.10 ns 

    Note: To stop the single cycle debugging, simply close the Listen to Block window and the model will simulate to the end.  If you want to stoop the simulation, while in debugging model, click on Stop and then on Go.  This will make the simulation stop.

      Script Profiler

    The Script Profiler is embedded in the block execution and keeps track of the number of times a statement executes and also the average time the statement took to execute down to the nano-second level.  This feature provides all users with the detailed execution information about his/her script.  In addition, it provides the script address, and the script statement associated with that address.  If the number of times executed equals 0, then this provides feedback on whether a certain function even executed.  This may be useful information, sometimes referred to as code coverage in lower level verification testing.
    Profile_File: The Script Profiler can be turned on by adding a parameter to the Virtual_Machine and Smart_Controller block called “Profile_File”.  This identifies the name of the file to be generated by the profiler.    If the parameter does not exist, or is set to “none”, then the Script Profiler will be turned off.  A typical Profile_File, Block_Name + “_Profiler.txt”.
    Path:   One can place the entire path in “Profile_File” variable, or add the “Path” variable.  A typical path, “C:/VisualSim/Profiles”.

      Listen to File

    The Listen to File is a text based version of listen to block, one just enters a parameter in the block.
    Listen_to_File: The Listen to File can be turned on by adding a parameter to the Virtual_Machine and Smart_Controller block called “Listen_to_File”.  This identifies the name of the file to be generated.    If the parameter does not exist, or is set to “none”, then Listen to File will be turned off.  A typical Listen_to_File value is Block_Name + “_Listen_to_File.txt”.
    Path:   One can place the entire path in “Listen_to_File” variable, or add the “Path” variable.  A typical path is “C:/VisualSim/Listen_to_Files”.

      Profile

    The Profile is enabled when the Profile parameter is added to the Virtual Machine block and the value is set to true.  The profile generates a Instruction Mnemonics for the sequence of execution of the script.  The Profile generates the instructions and palces them in arrays.  The length of each array is the Profile paramete value.  The last array will have "END" in the last index position.  The arrays can be output on a port of this block called "profile"  The user must add this manually after instantiating the block.  Alternately, the user can add a virtual connection called Block_Name + "_Profile".  There are some limitations to the code type that can be profiled.  All 'for' loops must be modified to a While.  The user must also modify [] arrays to ().  LHS of an array needs to be a single value, not a computation like i-1.  View the example to understand the usage.

    Profile parameter is an integer that defines the maximum length array to be output to a port named “profile”.  This array can be added to a data structure, such as Processor_DS and send to a Processor block for execution.  
    Here is a list of ADD instruction types generated from an internal script:

    ADD (int), ADD_l (long), ADD_d (double), ADD_a (array), ADD_m (matrix), ADD_s (string), IMM (immediate) is x = y, IMM_b (boolean), IMM_r (record)

    Other arithmetic instructions, excluding types:

    SUB (subtract), MUL (multiply), DIV divide), INC (increment), DEC (decrement), MOD (modulo), POW (power), SHIFT (<< or >>), IMM (immediate), LT (less than), LTE (less than or equal),  GT  (greater than), GTE (greater than or equal), EQ (equal),  FX (function), FXA (function with at least two args)

    Script related instructions:

    GTO (goto), BCH (branch), SBR (subroutine), RTN (return), EVENT(event), CLOCK (special event), WAIT (blocking), TIMEQ (non-blocking), QUEUE, SEND (thread or port)

    Here is an example of a small loop in a script with the instruction array generated by a Profile parameter of 1000 to the port added to the block named “profile”:

    Script (software)
    ------

    MyBoolean   = true
    Idx                = 0
    while (Idx     < 10)       {
       SEND (output, Idx)
       ++Idx
    }

    LABEL: BEGIN


    profile Output (array of internal execution)
    -------------- 

    DISPLAY AT TIME         ------ 0.0 ps ------
    {"IMM_b", "IMM", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "SEND", "INC", "GTO", "LT", "EXIT"}


    How to Create Model Clocks

    Here is an example script to generate clocks within a model, using Virtual_Machine blocks:

      /* Clock_Generator_Block VM */   /* Block_A Script, Clock Loop portion VM */  /*  Block_B Script, Clock Loop portion VM */
    Speed_Hertz  = round (1.0E06 * Speed_Mhz)

            LABEL: Loop

                WAIT (Speed_Hertz)

                if  (Block_A_Ready) {                          /* No clock if not ready      */

                    EVENT (“Block_A_Clock”)            /* Trigger Block_A_Clock */
                }

                if  (Block_B_Ready) {                          /* No clock if not ready      */

                    EVENT (“Block_B_Clock”)            /* Trigger Block_B_Clock */
               }
            GTO (Loop)

            LABEL: BEGIN

    LABEL: Clock_Loop

            ... 

           WAIT (“Block_A_Clock”)       

                  /* Event from Clock_Generator_Block */

            ...

           GTO (“Clock_Loop”)

     LABEL: Clock_Loop

           ... 

               WAIT (“Block_B_Clock”)      

                /* Event from Clock_Generator_Block */

           ...

           GTO (“Clock_Loop”)


    For example, Block_A_Ready and Block_B_Ready are user generated Boolean values in a model that can mimimize clock events for blocks that have nothing to process. 

    Another way to generate clocks for Block_A or Block_B may be to enable the clock when it needs to process some data.  In this case, the WAIT (Next_Cycle) would appear in the functional blocks, while the enable would be generated from a newEvent() or EVENT() in the same block or external block.

      /* Source_Block requesting processing */ /* Block_A Script, Clock Loop portion */

    /* Block_B Script, Clock Loop portion */

    ....

        EVENT (“Request_Processing_on_Next_Clock”)                        /* Trigger Block_A, Block_B */

        ....

      Speed_Hertz   = round (1.0E06 * Speed_Mhz)

        LABEL: Clock_Loop

               WAIT ("Request_Processing_on_Next_Clock")     

                                                     /* Event from Source_Block */

               WAIT (Speed_Hertz )                                     

                                                /* Proper Clock Boundary    */      

               ....

               if  (Processing_Not_Done) {

                   EVENT (“Request_Processing_on_Next_Clock”)
               }

       GTO (“Clock_Loop”)

      Speed_Hertz   = round (1.0E06 * Speed_Mhz)

      LABEL: Clock_Loop

               WAIT ("Request_Processing_on_Next_Clock")           

                                                                /* Event from Source_Block */

               WAIT (Speed_Hertz )                                            

                                                               /* Proper Clock Boundary    */      

               ....

               if  (Processing_Not_Done) {

                      EVENT (“Request_Processing_on_Next_Clock”)
                  }

     GTO (“Clock_Loop”)


    The EVENT() shown in Block_A, Block_B Clock_Loop can sustain the processing until the task is complete. When the processing is complete “Processing_Not_Done” would be set false based on user conditions.

    The Virtual Machine name can be local or global. If local, then the name is accessible from within the hierarchy window.  In case of global, the access is from the whole model. This is similar to the local and global IN and OUT blocks.


    Reserved Words

    S.NO
    RESERVED WORDS
    DESCRIPTION
    1.

    port_name

    Name of input port, scheduler return, or virtual

       virtual

       scheduler

       input, input2, input3, etc.

    2.
    port_token

    Active data structure from any input, scheduler return, or virtual

    3.
    TNow

    Current Simulation time

    4.
    TStop

    Simulation stop time

    5.
    TResolution

    Simulation resolution time

    6.
    address

    Address of executing statement used in Single_Cycle mode

    7.
    local_variable

    User can construct Local variable prefix, contains "ModelName.HierarchicalName."

    local variable name = local_variable + variable_name, contains "ModelName.HierarchicalName.VariableName"


    Parameter

    Explanation

    Type

     Example 

    Block_Name

    Block_Name is a Parameter that needs to be unique in modeling space.

    String

    "MyMachine"

    Optional_Parameters

    List of parameters that are used infrequently.  Previously called Hidden Parameters.  If the current block has these parameter listed in a separate field, those values get precedence over this list.  for more details on these parameter,s look at the list below.

    String

    Parameter_Name                 Parameter_Value    
    Path                           VS/User_Library    
    Read_File                      none               
    Save_Files                     false              
    Profile_File                   none               
    Listen_to_File                 none               
    Duplicate_Input                true               
    Profile                        0                  
    Maximum_Loops                  1000000            
    Block_Reference                Block_Name        
    Port_Order_Array               {"input"}        
    Add_Scheduler_Times_to_DS      false         -

    Single_Cycle

    This enables Single Cycle mode in conjunction with the setBreakpoints. Set to "Stop before Executing Timed Activity”. User can "Listen to Block" to see individual instructions executing. Single Cycle mode now supports the “address” of the executing statement and can be used in the “Breakpoint” parameter expression. This improves the debugging capabilities to allow the user to stop on a specific script address.

    Boolean

    -

    Breakpoint

    User can set a breakpoint RegEx expression that can cause the script to pause based on block inputs, variable values, or left-hand side of expression.

    String

    "Variable_Flag"


    Optional Parameters

    Each parameter in this list has a value associated with it.  The first line has Parameter_Name                 Parameter_Value.  No suffix or line ending is required.

    S.NO
    PARAMETER
    FUNCTIONS
    1.
    Path
    • This applies to the Read_File, Save_Files, Profile_File, and Listen_to_File options. 
    • This path is used to save the compiled files, profile file, listen to file; and for reading a code file.
    2.
    Read_File
    • This is a file name that contains the code when it needs to be read from a file.
    •  This approach is preferred when the code needs to be modified between simulation runs. 
    • The code is not in the block but is written in a separate text file. 
    • If the Path parameter is available, then block searches in the directory, else in $VS directory. 
    • This is file name with a .txt extension.
    3.
    Save_Files
    • This is a boolean used to save the compiled file in a location specified by the Path parameter of this block or the $VS directory. 
    • This parameter used to speed up the compile time.
    •  This is used when there are 100's of instances of the Virtual Machine or Smart_Controller.
    •  If this value is true, then the file is saved.
    • The first time the code is compiled, it is written to a file.
    •   The next time around the delta is compared and if there is no change, the code is not recompiled.
    4.
    Profile_File
    • This is a file name that contains a profile of the script execution.
    •  It lists the number of times the statement executed and the average time per execution, plus the script statement.
    •  If a statement does not execute, then the number will be zero, the time will be zero. 
    • This provides a "code coverage" view of the script execution.
    •  If the Path is set, then this file will be found in the same path.
    5.
    Listen_to_File
    • This is a file that is identical to the "Listen to Block" except it is written to a designated file name.
    •  If the Path is set, then this file will be found in the same path.          
    6.
    Duplicate_Input(Default set to true)
    • The transaction arriving on each input is duplicated and placed in the input_queue.
    •  If this is set to false, the transaction is not duplicated.
    •   This is used to speed up the simulation where the duplication is not required.
    •  The duplication is required if the same data structure has been sent to multiple blocks.
    7.
    Profile
    • This is a Integer parameter and is the length of the profile generated array.
    • The addition of this parameter to the Virtual Machine generates a array of Instruction Mnemonics associated with the execution of this Virtual Machine code. 
    • More information on the Profile can be seen in this explanation.
    8.
    Maximum_Loops
    • (Default value is 1000000)
    • This applies to a while loop without a WAIT or TIMEQ function being encountered.
    9.
    Block_Reference
    • This is now the Virtual_Machine virtual reference, the default is the existing Block_Name.
    • If a script uses Block_Name, and Block_Reference default is not changed, then script will execute as before.
    •  There is a new internal value, Block_Path, which is identical to local_variable, and user can now define a unique Block_Reference:
        • Block_Reference Block_Path + Block_Name
        • Block_Reference now contains: Model_Name.Hierarchical_Block.Block_Name
    10.
    Port_Order_Array
    • Port_Order_Array defaults to existing ports, user does not need to modify.
    •  Port_Order_Array applies to a Virtual_Machine with multiple input ports and Data Structures arriving at the same time, the user can specify which port will be processed first by the order of input ports in this array.
    11.
    Add_Scheduler_Times_to_DS
    • (Default to false)
    •  Used to add fields to incoming data structure:
      • TIME_ACTIVATION, TIME_RELEASE, TIME_FINISH, TIME_RESPONSE, TIME_IN_SYSTEM.
      • Refer to Scheduler documentation for more details on these field values.
    12.
    Self_Start
    • This parameter has been deprecated. 
    • All lines before LABEL: BEGIN will execute at initialize.
    •  If the user adds "Self_Start" to the block parameters and sets the value to true, then the Virtual_Machine will begin to execute at time 0.0.
    •  This mode does not require any input to arrive on the ports to begin execution.
    •   Use only LABEL:BEGIN or Self_Start but not both.
    •   If both are used that will result in two triggers to the block.
          

    Port

    Explanation

    Type

    Input

    This is a default input port.

    General

    Output

    This is the default output port.

    General




     

    Created with the Personal Edition of HelpNDoc: Easy EPub and documentation editor