SimStm is a VHDL testbench designed to facilitate testing driven by external stimulus files with a “.stm” extension. This testbench is provided by Eccelerators GmbH and aims to simplify test script creation by introducing the SimStm language. Eccelerators GmbH provides IDE support for this language through Visual Studio Code and Eclipse by SimStm plugins; visit Eccelerators. The full power of SimStm is achieved together with the HxS tool of Eccelerators GmbH since all necessary SimStm code for the HW/SW interfaces is generated by HxS.
The original VHDL testbench was coded by Ken Campbell; visit GitHub. Therefore, the SimStm repository is forked from this original. The complete VHDL source code of the SimStm VHDL testbench is distributed under the same license as the original. However, Eccelerators GmbH has substantially repartitioned and changed the code. The original copyright notice has been retained within all source files related to the original.
The IDE plugins are available for free on the Eccelerators GmbH web page. They may also be available for free on the respective IDE marketplaces once deployed. The source code of the SimStm language IDE plugins is the property of Eccelerators GmbH and is closed source.
It is common practice to use the file I/O features of VHDL for VHDL testbenches. Typically, each developer creates their own format for commands in an input stimuli text file, along with a unique file name and extension. The command set is focused on the tasks currently being solved.
The general advantage of this technique is that the VHDL code of the testbench doesn't need to be changed and recompiled for different stimuli command sets. Different command set files can be presented to the VHDL testbench, or command files can be interactively changed during debugging.
While the advantage of not having to recompile the VHDL testbench has decreased due to increased computer and tool performance, a major part of the advantage remains valid for reusability and having a first decoupled level of abstraction for stimuli above the VHDL code.
This is particularly applicable to CPUs attached or integrated into components under development. For example, an IP such as an I2C-controller with a HW/SW interface can be tested with the same stimuli, whether attached to an AXI-bus in a SOC of the latest generation or to a plain microcontroller bus connected via copper on a PCB to an FPGA housing the I2C controller IP.
SimStm focuses on this purpose. It delivers a command set that is fixed and suitable for all needs in this context. The command set is defined by a domain-specific language that provides and controls all necessary keywords and object references, called the SimStm language. The commands are referred to as instructions.
The SimStm language is edited within respective IDE plugins for Eclipse or Visual Studio Code editors, supplying state-of-the-art coding support such as syntax highlighting, auto-completion, error detection, and more.
The user starts editing a top.stm
file and as many child.stm
files as needed. The latter are included by include
instructions,
which may be nested. Child.stm
files can be used in a library manner
for reuse.
The SimStm instructions are purposely very close to HW to avoid debugging through too much overhead. All objects declared, such as variables, constants, arrays, implicit labels, etc., are global within one SimStm project. All objects representing values consider the values to be unsigned integer values. The values are 64-bit wide by default but can be customized to be any width by setting the machine_value_width generic when instanciating the tb_simstm top entity, individually for each instance.
The SimStm testbench presents a bus and a signal package source file to the user. These packages can be customized by the user to add busses, signals, or interrupts to the testbench. All other files shall be used unchanged. Eccelerator samples for Wishbone, Avalon, and AXI4lite busses for single read/write accesses are already included.
The primary focus of SimStm is to have a functional verification of all connected IPs via multiple busses with high coverage in a short time. It is not prepared to be used to verify the different conditions and sequences of accesses to the busses like other testbenches. However, it could control these testbenches via respective bus adapters. Eccelerators uses its own HxS tool to design and generate HW/SW interfaces. The patterns used by the generators are verified to work with all circumstances happening on the supported busses all the way to having counterparts in other asynchronous clock domains. The generated instances do not have to be verified again at this depth.
The SimStm language can be transpiled into Python, C, and other programming languages to use the code written in SimStm for a first test of a target HW. Thus, a functional coverage test is achieved very fast when the real target HW arrives. The transport and isolation of problems from the real application to the simulation environment and vice versa are simplified. Interaction between SW and HW developers is simplified too since SW developers can work with SimStm code rather than VHDL.
- Compact and lightweight
- Pure VHDL 2008, no use of a vendor-specific simulator interface
- Easy to debug within any simulator, instructions close to HW
- Abstraction of test code by SimStm language
- State-of-the-art SimStm language IDE support for rapid test case creation
- Test case code change and test without re-compilation
- SimStm language transpiles to Python or C, thus simulation code can be reused for the test of real target HW
- Easily customizable to support user-defined busses, signals, and interrupts
- Standard busses Axi4Lite, Avalon, Wishbone and direct synchronous RAM are included
- High coverage of functional verification of all connected IPs via multiple busses
- Supports JUnit test reports
- Open Visual Studio Code.
- Go to the Extensions Marketplace.
- Search for “SimStm” and install the plugin.
- Create or open a “.stm” test script file.
- Leverage the plugin's IDE features to enhance your testing workflow.
- Navigate to Eccelerators.
- Download the “SimStm” Eclipse plugin.
- Unpack it to a local folder.
- Open Eclipse and navigate via the menu to “Help”, “Install new Software…”
- Press the “Add” button.
- Choose “Local”, enter SimStm as the plugin name.
- Browse to the folder you have unpacked as the location.
- Press the “Install” button.
- Create or open a “.stm” test script file within a project.
- Leverage the plugin's IDE features to enhance your testing workflow.
The following picture illustrates how the tb_simstm
module is
integrated into the user testbench. The tb_simstm
module should not
be changed by the user. The signals and interrupts that the user wants
to control the DUT or the Mocks shall be defined in tb_signals_pkg
.
The buses the user wants to connect to the DUT or the Mocks shall be
defined in tb_bus_pkg
, and eventually, a new bus type package if the
predefined buses aren't sufficient. All other packages shall not be
changed.
Eccelerators accepts GitHub pull requests, GitHub issues, or an email to
trigger a bug fix. Reported issues with samples cut down to reproduce a
bug are highly appreciated. In the case of email, please send it to
[email protected]
.
Eccelerators may accept pull requests for small improvements.
The repository contend needed by the user:
src
: The main folder containing the VHDL code of the testbench not to be modified by the user.src/vhdl/tb_simstm
: The testbench top entity and architecture to be instanciated in the the user testbench.src_to_customize
: The folder containing the packages to be customized by the user.
All Eccelerators IP repositories are aimed to be presented as Python Packages in future. SimStm though not a syntheziable IP, is presented in the same manner. SimStm tests itself by its own means.
helper
: The helper folder containing helper scripts only needed the SimStm selftest.helper/proposal_for_setup_py.py
: Generatingsetup.py
based on Eccelerators conventions.helper/generate-ghdl-ant-build-xml.py
: Generatingsimulation/ghdl/build-ghdl.xml
based onsetup.py
.helper/generate-modelsim-ant-build-xml.py
: Generatingsimulation/modelsim/build-modelsim.xml
based onsetup.py
.helper/collect-simulation-results.py
: Generating JUnit test resultsimulation/SimulationResults/testSuitesSimulation.xml
called by ant controlled test flow.
All Eccelerators IP repositories are build by ant. The ant build scripts are organized hierarchically.
The top build script is build.xml in the repository root. It imports helper/build-helper.xml
.
This presents the initial workflow target _helper-gnerate-proposal-for-setup-py to generate setup.py
.
As a next step the target _helper-generate-ghdl-ant-build-xml is called to generate the ghdl build script.
Once you refresh the list of shown ant targets in your IDE, you will see the new ghdl targets.
The target ghdl-all is the one to be called to run the simulation. Similar it would be if you decide for modelsim.
simulation
: The simulation folder containing the generated preparations and the simulation results.tb/hdl
: The (self)test bench hdl sources and tbTop.vhd with the top entity and architecture.tb/simstm
: The (self)test bench simstm sources following Eccelerators conventions to produce a selftest result as JUnit test result.
Beneath the simstm sefttest sources in tb/simstm subfolders which of course test every simstm instruction, extensively the command_list.stm
in the repository root can be used as a comprehensive list for instruction examples.
The main purpose of this repository is to provide and test SimStm. Complex real-world examples how it is used are found in the eccelerators group of repositories on GitHub.
In SimStm instructions a line is a instruction, except empty lines or comment only lines. Subroutine labels are considered as instruction in this manner too.
The colon postfix of a subroutine label must end with a colon. No space is allowed between the label ID and the colon. A dollar sign as prefix is used to reference to object content e.g. variables. No space is allowed between the dollar sign and referenced object ID. Otherwise the SimStm language is not white space sensitive.
The SimStm language is case sensitive.
All constant, variable or label ID are global within a SimStm project. The IDs must be unique.
There are no subroutine parameters or local variables. Values must be passed by unique global objects. This is an accommodation to having a simple SimStm interpreter and develops its own charm when using and debugging it.
The subroutine with the label testMain:
is the entry point into the
SimStm code for the simulator.
-- This is a full line comment
const aconst 0x03 -- This is an appended line comment
include "aninclude.stm"
Include another child \*.stm file
.
The include
instructions should be the first instructions of a \*.stm file
.
An included file can include further \*.stm files
, thus nested includes
are possible. The file path to be given is relative to the file with the
respective include instruction. Nested includes of files from the same
folder or in child folders are predictable; nested includes to files in
parent folders would be bad practice.
const aconst 0x03
const bconst 0b011
const cconst 3
The const
instruction declares and defines a constant with ID and hex, binary,
decimal unsigned value.
It isn't possible to initialize a constant by referencing another constant.
var avar 0x03
var bvar 0b011
var cvar 3
The var
instruction declares and defines a variable with ID and initial hex, binary, or
decimal unsigned value.
It isn't possible to initialize a variable by referencing another
variable or constant yet. The equ
instruction must be used within a procedure for this purpose.
barray 16
The array
instruction declares an array with ID and an unsigned 32-bit integer length.
Only arrays with one dimension are possible; the length must be fixed.
file afile "filename.stm"
file afile "filename{:d}{:d}.stm" $index1 $index2
The file
instruction declares a file with ID and file name.
The latter must be a relative path to the location of the main.stm file.
Text substitution by variables is allowed in file names. Thus, files can
be accessed in an indexed manner. The variables are evaluated each time
when a reference to a file is used in another instruction accessing a
file, e.g., file read all afile alines
.
lines alines
The lines
instruction declares a lines object with ID.
The lines object contains an arbitrary number of line objects. It is
defined to have no content when it is declared by default. It can grow
or shrink dynamically by lines instructions accessing it, e.g.,
lines insert array alines 9 barray
.
signal asignal
The signal
instruction declares a signal object with ID.
The signal object associates a SimStm signal name with a signal number. This signal number must be given in the tb_signal package by customization and attached to a signal.
bus abus
The bus
instruction declares a bus object with ID.
The signal object associates a SimStm bus name with a bus number. This bus number must be given in the tb_bus package by customization and attached to a bus.
equ operand1 $operand2
equ operand1 0xF0
The equ
instruction copies the value of operand2 variable, constant, or numeric value into
variable operand1 value or copy the value 0xF0 into variable operand1
value.
add operand1 $operand2
add operand1 0xF0
The add
instruction adds variable or constant operand2 value to variable operand1 value or
add value 0xF0 to variable operand1 value. The resulting value of the
addition is in variable operand1 value after the operation.
sub operand1 $operand2
sub operand1 0xF0`
The sub
instruction subtracts variable or constant operand2 value from variable operand1
value or subtract value 0xF0 from variable operand1 value. The resulting
value of the subtraction is in variable operand1 value after the
operation.
mul operand1 $operand2
mul operand1 0xF0
The mul
instruction multiplies variable or constant operand2 value with variable operand1
value or multiply value 0xF0 with variable operand1 value. The resulting
value of the multiplication is in variable operand1 value after the
operation.
div operand1 $operand2
div operand1 0xF0
The div
instruction divides variable operand1 value by variable or constant operand2 value or
divide variable operand1 value by value 0xF0. The resulting value of the
division is in variable operand1 value after the operation.
and operand1 $operand2
and operand1 0xF0
The and
instruction does a bitwise and of variable or constant operand2 value with variable operand1
value or bitwise and value 0xF0 with variable operand1 value. The
resulting value of the bitwise and is in variable operand1 value after
the operation.
or operand1 $operand2
or operand1 0xF0
The or
instruction does a bitwise or of variable or constant operand2 value with variable operand1
value or bitwise or value 0xF0 with variable operand1 value. The
resulting value of the bitwise or is in variable operand1 value after
the operation.
xor operand1 $operand2
xor operand1 0xF0
The xor
instruction does a bitwise xor of variable or constant operand2 value with variable operand1
value or bitwise xor value 0xF0 with variable operand1 value. The
resulting value of the bitwise xor is in variable operand1 value after
the operation.
shl operand1 $operand2
shl operand1 0xF0
The shl
instruction does a bitwise shift left of variable or constant operand2 value with variable
operand1 value or bitwise shift left value 0xF0 with variable operand1
value. The resulting value of the bitwise shift left is in variable
operand1 value after the operation.
shr operand1 $operand2
shr operand1 0xF0
The shr
instruction does a bitwise shift right of variable or constant operand2 value with variable
operand1 value or bitwise shift right value 0xF0 with variable operand1
value. The resulting value of the bitwise shift right is in variable
operand1 value after the operation.
inv operand1
The or
instruction does a bitwise invert of variable operand1 value. The resulting value of the
bitwise invert is in variable operand1 value after the operation.
ld operand1
The ld
instruction does calculates logarithmus dualis of variable operand1 value. The resulting
value is in variable operand1 value after the operation. The function
returns the number of the utmost set bit, e.g., 4 for the input 16. It
returns 0 for the input 0 too since this is the best approximation in a
natural number range. The user should handle this discontinuity if
another result or an error is expected.
aproc:
proc
--...
-- subroutine code
--...
end proc
Code of a subroutine is placed between proc
and end proc
instructions.
The subroutine name is a label placed on the line before the proc
instruction, e.g., aproc
. The label ends with a colon as a label
indicator.
call $aproc
The call
instruction branches execution to the subroutine with the label aproc
and continues
execution with the next line when it returns from the subroutine after
it has reached an end proc
or return
instruction there.
return
The return
instruction returns to calling code from a subroutine.
aninterrupt:
interrupt
--...
-- interrupt subroutine code
--...
end interrupt
Code of an interrupt subroutine is placed between interrupt
and end interrupt
instructions. The interrupt subroutine name is a label placed
on the line before the interrupt
instruction, e.g., aninterrupt. The label
ends with a colon as a label indicator. The label must be given in the
tbsignal package by customization and attached to a signal triggering
the interrupt. If necessary, the handling of nested interrupts must be
resolved there too.
if $avar = $bvar
-- ... some code
elsif $avar 0xABC
-- ... some code
elsif 0x123} $bvar
-- ... some code
else
-- ... some code
end if
Possible comparison operators are:
>= <= > < != =
.
The if
or elsif
instructions compares 2 variables, constants, or numeric values and branches
execution to the next line if resolving to true. Otherwise, it branches
to the next elsif
or else
or end if
instruction.
The if
elsif
or else
instructions can be nested.
loop $lvar
-- ... some code
end loop
loop 32
-- ... some code
end loop
The loop
instruction executes a loop of the code between the loop
and end loop
instruction.
The number of times the loop should be executed is given after the loop
keyword. It can be a numeric value, a variable, or a constant.
In case of a variable, this number can be changed by code within the loop, e.g., to skip loops or end the loop earlier, due to the global nature of all variables. No break or continue instructions are supported therefore.
The loop can be terminated by a return
instruction too at any time,
which is a good practice.
abort
The abort
instruction aborts the simulation with severity failure.
finish
The finish
instruction exits the simulation with severity note or error. The latter occurs only
if resume has been set to other values than 0, and there were verify
errors in verify instructions.
var verify a_var $evar $mvar
var verify a_var 0x01 0x0F
The var verify
instruction reads the value of a signal and compares it to an expected
value with a given mask.
The expected value and mask can be variables, constants, or numeric values. On mismatch, the simulation stops with severity failure if the global resume is set to 0.
array set barray $pvar $avar
array set barray 3 $avar
array set barray $pvar 5
array set barray 3 4
The array set
instruction sets the value of barray
at position pvar``to the value of ``avar
or
5
.
The array set
instruction the value of barray
at position 3``to the value of ``avar
or
4
.
array get barray $pvar tvar
array get barray 5 tvar
The array get
instruction gets the value of barray
at position pvar
or 5
into tvar
.
array verify barray $pvar $evar $mvar
array verify barray $pvar 0x01 0x0F
The array verify
instruction reads the value of an array at a position and compares it to an expected
value with a given mask.
The expected value and mask can be variables, constants, or numeric values. On mismatch, the simulation stops with severity failure if the global resume is set to 0.
array size barray tvar
The array size
instruction gets the size of an array.
array pointer copy tarray sarray
The array pointer copy
instruction copies an array pointer; for example, tarray
pointer is a copy of
sarray
pointer after the execution of the instruction. Used, for
instance, to hand over an array to a subroutine. Changes to the source
array happen in the target array too.
file writeable afile rvar
The file writeable
instruction tests if a file is writable. If the file is not present, it is created
without having content. The result is for STATUSOK 0, STATUSERROR 1,
STATUSNAMEERROR 2, STATUSMODEERROR 3 and may, in case of error, depend
on the operating system.
file readable afile rvar
The file readable
instruction tests if a file is readable. The result is for STATUSOK 0, STATUSERROR 1,
STATUSNAMEERROR 2, STATUSMODEERROR 3 and may, in case of error, depend
on the operating system.
file appendable afile rvar
The file appendable
instruction tests if a file is appendable. The result is for STATUSOK 0, STATUSERROR
1, STATUSNAMEERROR 2, STATUSMODEERROR 3 and may, in case of error,
depend on the operating system.
file write afile alines
The file write
instruction writes all lines of an alines
object to a file. The file is
overwritten if it exists.
file append afile alines
The file append
instruction appends all lines of an alines
object to a file. The method will fail
if the file doesn't exist.
file read all afile alines
The file read all
instruction reads all lines of a file into an alines
object.
file read afile alines $nvar
file read afile alines 10
The file read
instruction reads a number of lines from a file into an alines
object.
The first read opens the file for read, following reads start at the line after the last line which has been read by the previous read. Thus a file can be read piecewise similar as it can be written piecewise by file append. The piecewise read process of the file must be terminated by a file read end instruction always. The number of concurrent file read processes is limited to 4.
file read end afile
The ``file read end `` instruction ends the piecewise read process of a file.
file pointer copy tfile sfile
The file pointer copy
instruction copies a file pointer; for example, tfile
pointer is a copy of
sfile
pointer after the execution of the instruction. Used, for
instance, to hand over a file to a subroutine. Changes to the source
file happen in the target file too.
lines get array alines $pvar tarray rvar
lines get array alines 9 tarray rvar
The lines get array
instruction gets a line from a lines object at a given position and write its content
into an array.
The line is expected to hold hex numbers (without 0x prefix) separated by spaces (e.g., A123 BCF11 123 E333 would be 4 hex numbers). The given array must be able to hold the number of found hex numbers. It will not be filled completely if fewer than its size are found. Numbers will be skipped if there are more hex numbers found than the array can hold. The number of detected hex numbers is reported in a result variable. Then the user can decide what action should follow a mismatch.
lines set array alines $pvar sarray
lines set array alines 9 sarray
lines set message alines $pvar "Some message to be written to a file later"
lines set message alines $pvar "Value1: {} Value2: {} to be written to a file later" $mvar1 $mvar2
The lines get array
instruction sets a line at a given position of a lines object.
The line currently at this position is overwritten. The line can be derived from an array or a message. The message string can contain {} placeholders which are filled by values of variables given after the message string.
lines insert array alines $pvar sarray
lines insert array alines 9 sarray
lines insert message alines $pvar "Some message to be written to a file later"
lines insert message alines $pvar "Value1: {} Value2: {} to be written to a file later" $mvar1 $mvar2
The lines insert array
instruction inserts a line at a given position of a lines object. The line currently
at this position is moved to the next position. The line can be derived
from an array or a message. The message string can contain {}
placeholders which are filled by values of variables given after the
message string.
lines append array alines sarray
lines append message alines "Some message to be written to a file later"
lines append message alines "Value1: {} Value2: {} to be written to a file later" $mvar1 $mvar2
The lines append array
instruction appends a line at the end of a lines object. The line can be derived from
an array or a message. The message string can contain {} placeholders
which are filled by values of variables given after the message string.
lines delete alines $pvar
lines delete alines 3
The lines delete
instruction deletes a line at a given position of a lines object. The next line is
moved to the given position if it exists.
lines size alines rvar
The lines size
instruction gets the size of a lines object, which is the number of lines it contains
currently.
lines pointer copy tlines slines
The lines pointer copy
instruction copies a lines pointer; for example, tlines
pointer is a copy of
slines
log message $vvar "A message to the console"
log message $vvar "A message to the console{}{}" $mvar1 $mvar2
The log message
instruction prints a message at a given verbosity level to the console.
The message string can contain {} placeholders which are filled by values of variables given after the message string.
log lines} $vvar slines
The log lines
instruction dumps a lines object at a given verbosity level to the console.
verbosity $vvar
verbosity 20
Usual practice is to use the following constants to set verbosity:
const FAILURE 0
const WARNING 10
const INFO 20
The verbosity
instruction sets the global verbosity for log messages. Log messages with a
verbosity level greater than the globally set verbosity are not printed
to the console. Of course, the global verbosity can be changed at any
point in the execution flow.
wait $wvar
wait 10000
The wait
instruction waits for the given number of nanoseconds.
random tvar $minvar $maxvar
random tvar 0 10
The random
instruction generates a random number greater or equal to the min value given and
less than the maximum number given.
seed $svar
seed 10
The seed
instruction sets the internal start value for the random number generator.
trace $tvar
trace 0b111
The trace
instruction enables or disables the output of trace
information when it is set at some point during the SimStm code
execution. Thus, e.g., the flow through complex if, elsif … trees can be
shown.
- Setting the bit 0 in the given value prints the lines of code with some additional information.
- Setting the bit 1 dumps all(!) objects before a line is executed.
- Setting the bit 2 dumps all file names currently in use.
marker $nvar $mvar
marker 0xF 0b1
The marker
instruction sets a marker at a given number used to mark
interesting points of time in the simulation wavefrom.
The tb_simstm
entity has an output signal marker which is a
std_logic_vector(15 downto 0)
. Thus there are 16 markers which can
be set 0b1
or 0b0
. This should be used to mark occurrences
during the execution of the SimStm code so they can be found easily in
the waveform display. Beneath this, the Executing_Line
and
Executing_File
tb_simstm
intern variables are always present and
show the currently executed line of code.
signal write asignal $svar
signal write asignal 0b11
The signal write
instruction writes variable, constant, or numeric value to a signal.
signal read asignal tvar
The signal read
instruction reads the value of a signal into a variable.
signal verify asignal tvar $evar $mvar
signal verify asignal tvar 0x01 0x0F
The signal verify
instruction reads the value of a signal into a variable and compares it to an expected
value with a given mask.
The expected value and mask can be variables, constants, or numeric values. On mismatch, the simulation stops with severity failure if the global resume is set to 0.
signal pointer copy tsignal ssignal
The signal pointer copy
instruction copies a signal pointer; for example, tsignal
pointer is a copy of
ssignal
signal pointer set tsignal 5
signal pointer set tsignal $ptvar
The signal pointer set
instruction sets a signal pointer; for example, tsignal
pointer absolutely.
signal pointer get ssignal ptvar
The signal pointer get
instruction gets a signal pointer; for example, tsignal
pointer absolutely into e.g. ptvar.
bus write abus $width $address $wvar
bus write abus 32 0x0004 0x12345678
The bus write
instruction writes a variable, constant, or numeric value to a bus with a given width and address.
bus read abus $width $address tvar
The bus read
instruction reads the value of a bus with a given width and address into a variable.
bus verify abus $width $address tvar $evar $mvar
bus verify abus $width $address tvar 0x01 0x0F
The bus verify
instruction reads the value of a bus with a given width and address into a variable and compare it to an expected
value with a given mask. The expected value and mask can be variables,
constants, or numeric values. On mismatch, the simulation stops with
severity failure if the global resume is set to 0; otherwise, it
continues and reports an error.
bus pointer copy tsignal ssignal
The bus pointer copy
instruction copies a bus pointer; for example, tbus
pointer is a copy of
sbus
bus pointer set tbus 5
bus pointer set tbus $ptvar
The bus pointer set
instruction sets a bus pointer; for example, tbus
pointer absolutely.
bus pointer get sbus ptvar
The bus pointer get
instruction gets a bus pointer; for example, tbus
pointer absolutely into e.g. ptvar.
bus timeout set abus $svar
bus timeout set abus 1000
The bus timeout
instruction sets the timeout in nanoseconds to wait for a bus access to end. On
violation, the simulation stops with severity failure always.
bus timeout get sbus tovar
The bus timeout get
instruction gets a bus timeout; for example, tbus
pointer absolutely into e.g. tovar.
resume $EXIT_ON_VERIFY_ERROR
resume 0
const
RESUME_ON_VERIFY_ERROR 1
const
EXIT_ON_VERIFY_ERROR 0
The resume
instruction sets the global resume behavior for verify instructions. On a verify
mismatch, the simulation stops with severity failure if the global
resume is set to 0; otherwise, it continues and reports an error.
const YEAR 2023
var month 11
var day 22
testMain:
proc`
loop 3
log message 0 "Hello World {:d}-{:d}-{:d}" $YEAR $month $day
end loop`
finish
end proc
This example is a unit test too and can be found in the repository folder tb/simstm/others. The file others.stm contains the testOtherHelloWorld test subroutine.
An demonstration of all commands is in the file command_list.stm in the repository root folder..
The test folder contains unittest for all commands. Thus all commands are verified for each release by regression tests.
Complex real-world example are found in the eccelerators group of repositories on GitHub.