Skip to content

eccelerators/SimStm

 
 

Repository files navigation

SimStm

Description of new Release 2.0.0 features:
  • removal of "$"-prefixes
  • variables can now be initialized with constants regardless of their definition sequence
  • local variables in procedures now possible
  • new procedures can now have parameters

** The compagnion simstm eclipse plugin Release 2.0.0 validation is still minimal **

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.

History and License

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 property of Eccelerators GmbH and is closed source.

Focus

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 buses, signals, or interrupts to the testbench. All other files shall be used unchanged. Eccelerator samples for Wishbone, Avalon, and AXI4lite buses 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 buses 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 buses 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 buses 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.

Features and Advantages

  • 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 buses, signals, and interrupts
  • Standard buses Axi4Lite, Avalon, Wishbone and direct synchronous RAM are included
  • High coverage of functional verification of all connected IPs via multiple buses
  • Supports JUnit test reports

Installation and Usage of the Plugins

Visual Studio Code

  • 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.

Eclipse

  • 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.

Overview and Integration into User Testbench

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.

simstm-overview

simstm-overview

Contributions and Bugs

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 support@eccelerators.com.

Eccelerators may accept pull requests for small improvements.

Repository Guide

The repository content 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 synthesizable IP, is presented in the same manner. SimStm tests itself by its own means.

  • helper: The helper folder containing helper scripts only needed for the SimStm selftest.
  • helper/proposal_for_setup_py.py: Generating setup.py based on Eccelerators conventions.
  • helper/generate-ghdl-ant-build-xml.py: Generating simulation/ghdl/build-ghdl.xml based on setup.py.
  • helper/generate-modelsim-ant-build-xml.py: Generating simulation/modelsim/build-modelsim.xml based on setup.py.
  • helper/collect-simulation-results.py: Generating JUnit test result simulation/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. It would be similar 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 selfttest sources in tb/simstm subfolders which of course test every simstm instruction, 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 of how it is used are found in the Eccelerators group of repositories on GitHub.

SimStm language instructions

General

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. Otherwise the SimStm language is not white space sensitive.

The SimStm language is case sensitive.

All constants, variables and label IDs 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.

Comments

-- This is a full line comment
const aconst 0x03 -- This is an appended line comment
Comments in a line start with two hyphens.
There are only line comments, no block comments.

Includes, Language Objects, and Declarations

Include

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.

Namespace

namespace a
var l_var 0
end namespace

The namespace instruction declares a container-like space, that can hold variables, subroutines etc. These are defined only inside the namespace and therefore help organizing code and avoiding naming conflicts. In the given example, the variable l_var is only defined inside the namespace a.

Const

const a_const 0x03
const b_const 0b011
const c_const 3

The const instruction declares and defines a constant with an ID and a hex, binary, decimal unsigned value.

It isn't possible to initialize a constant by referencing another constant.

Var

var a_var 0x03
var b_var 0b011
var c_var 3

The var instruction declares and defines a variable with an ID and an 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.

Array

a_array 16

The array instruction declares an array with an ID and an unsigned 32-bit integer length.

Only arrays with one dimension are possible; the length is fixed.

File

file a_file "filename.stm"
file a_file "filename{:d}{:d}.stm" index1 index2

The file instruction declares a file with an ID and a 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 every time a reference to a file is used in another instruction accessing a file, e.g., file read all a_file a_lines.

Lines

lines a_lines

The lines instruction declares a lines object with an 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 a_lines 9 b_array.

Signal

signal a_signal

The signal instruction declares a signal object with an 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

bus a_bus

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.

Equations and Arithmetic Operations

equ

equ operand1 operand2
equ operand1 0xF0

The equ instruction copies the value of operand2 (variable or constant) into operand1 (variable) or copies the value 0xF0 into operand1.

add

add operand1 operand2
add operand1 0xF0

The add instruction adds the value of operand2 (variable or constant) to the value of operand1 (variable) or adds the value 0xF0 to the value of operand1. The resulting value of the addition is stored in operand1 after the operation.

sub

sub operand1 operand2
sub operand1 0xF0`

The sub instruction subtracts the value of operand2 (variable or constant) from the value of operand1 (variable) or subtracts the value 0xF0 from the value operand1. The resulting value of the subtraction is stored in operand1 after the operation.

mul

mul operand1 operand2
mul operand1 0xF0

The mul instruction multiplies the value of operand2 (variable or constant) with the value of operand1 (variable) or multiplies the value 0xF0 with the value operand1. The resulting value of the multiplication is stored in operand1 after the operation.

div

div operand1 operand2
div operand1 0xF0

The div instruction divides the value of operand1 (variable) by the value of operand2 (variable or constant) or divides the value of operand1 by the value 0xF0. The resulting value of the division is stored in operand1 after the operation.

and

and operand1 operand2
and operand1 0xF0

The and instruction does a bitwise and of the value of operand2 (variable or constant) with the value of operand1 (variable) or a bitwise and of value 0xF0 with the value of operand1. The resulting value of the bitwise and is stored in operand1 after the operation.

or

or operand1 operand2
or operand1 0xF0

The or instruction does a bitwise or of the value of operand2 (variable or constant) with the value of operand1 (variable) or a bitwise or of value 0xF0 with the value of operand1. The resulting value of the bitwise or is stored in operand1 after the operation.

xor

xor operand1 operand2
xor operand1 0xF0

The xor instruction does a bitwise xor of the value of operand2 (variable or constant) with the value of operand1 (variable) or a bitwise xor of value 0xF0 with the value of operand1. The resulting value of the bitwise xor is stored in operand1 after the operation.

shl

shl operand1 operand2
shl operand1 0xF0

The shl instruction does a bitwise left shift of the value of operand2 (variable or constant) with the value of operand1 (variable) or a bitwise left shift of value 0xF0 with the value of operand1. The resulting value of the bitwise left shift is stored in operand1 after the operation.

shr

shr operand1 operand2
shr operand1 0xF0

The shr instruction does a bitwise right shift of the value of operand2 (variable or constant) with the value ofoperand1 (variable) or a bitwise variable shift of value 0xF0 with the value of operand1. The resulting value of the bitwise right shift is stored in operand1 after the operation.

inv

inv operand1

The or instruction does a bitwise inversion of the value of operand1 (variable). The resulting value of the bitwise inversion is stored in operand1 after the operation.

ld

ld operand1

The ld instruction calculates the logarithmus dualis of the value operand1 (variable). The resulting value is stored in operand1 after the operation. The function returns the index of the highest 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.

Subroutines, Branches, and Loops

proc, end proc

a_proc:
proc
    --...
    -- subroutine code
    --...
end proc

Code of a subroutine is placed between proc and end proc instructions. The name of the subroutine is a label placed a line ahead of the proc instruction, e.g., a_proc. The label ends with a colon as a label indicator.

call

call a_proc

The call instruction branches execution to the subroutine with the given label. Code execution proceeds in the next line after an end proc or a return in the subroutine.

return

return

The return instruction returns to calling code from a subroutine.

interrupt, end interrupt

an_interrupt:
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 a line ahead of the interrupt instruction, e.g., an_interrupt. 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, elsif, else, end if

if a_var = b_var
    -- ... some code
elsif a_var 0xABC
    -- ... some code
elsif 0x123} b_var
    -- ... some code
else
    -- ... some code
end if

Possible comparison operators are: >= <= > < != =.

The if or elsif instructions compares two variables, constants, or numeric values and branches execution to the next line after the end if if it resolves 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

loop l_var
    -- ... 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

abort

The abort instruction aborts the simulation with severity Failure.

finish

finish

The finish instruction exits the simulation.

stop

stop

The stop instruction stops the simulation with the severity Failure. The simulation can be resumed.

Var Access

Var Verify

var verify a_var e_var m_var
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.

Var Pointer Copy

var pointer copy a_varA a_varB

The var pointer copy instruction copies an variable pointer; for example, the pointer a_varA is a copy of the pointer a_varB after the execution of the instruction.

Array Access

Array Set

array set b_array p_var a_var
array set b_array 3 a_var
array set b_array p_var 5
array set b_array 3 4

The array set instruction sets the value of b_array at position p_var``to the value of ``a_var or 5.

The array set instruction sets the value of b_array at position 3``to the value of ``avar or 4.

Array Get

array get b_array p_var t_var
array get b_array 5  t_var

The array get instruction gets the value of b_array at position p_var or 5 into t_var.

Array Verify

array verify b_array p_var e_var m_var
array verify b_array p_var 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

array size b_array t_var

The array size instruction gets the size of an array.

Array Pointer Copy

array pointer copy t_array s_array

The array pointer copy instruction copies an array pointer; for example, the pointer t_array is a copy of the pointer s_array after the execution of the instruction. Used, for instance, to hand over an array to a subroutine. Changes to the source array also apply to the target array.

File Access

File Writable

file writable a_file r_var

The file writable 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

file readable a_file r_var

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

file appendable a_file r_var

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

file write a_file a_lines

The file write instruction writes all lines of a lines object to a file. The file is overwritten if it exists.

File Append

file append a_file a_lines

The file append instruction appends all lines of a lines object to a file. The method will fail if the file doesn't exist.

File Read All

file read all a_file a_lines

The file read all instruction reads all lines of a file into a lines object.

File Read

file read a_file a_lines n_var
file read a_file a_lines 10

The file read instruction reads a number of lines from a file into an lines 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

file read end a_file

The ``file read end `` instruction ends the piecewise read process of a file.

File Pointer Copy

file pointer copy t_file s_file

The file pointer copy instruction copies a file pointer; for example, the pointer``t_file`` is a copy of the pointer sfile after the execution of the instruction. Used, for instance, to hand over a file to a subroutine. Changes to the source file are applied in the target file as well.

Lines Access

Lines Get

lines get array a_lines p_var t_array r_var
lines get array a_lines 9 t_array r_var

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

lines set array a_lines p_var s_array
lines set array a_lines 9 s_array
lines set message a_lines p_var "Some message to be written to a file later"
lines set message a_lines p_var "Value1: {} Value2: {} to be written to a file later" m_var1 m_var2

The lines set 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

lines insert array a_lines p_var s_array
lines insert array a_lines 9 s_array
lines insert message a_lines p_var "Some message to be written to a file later"
lines insert message a_lines p_var "Value1: {} Value2: {} to be written to a file later" mvar1 mvar2

The lines insert 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

lines append array a_lines s_array
lines append message a_lines "Some message to be written to a file later"
lines append message a_lines "Value1: {} Value2: {} to be written to a file later" m_var1 m_var2

The lines append 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

lines delete a_lines p_var
lines delete a_lines 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

lines size a_lines r_var

The lines size instruction gets the size of a lines object, which is the number of lines it contains at that point.

Lines Pointer Copy

lines pointer copy t_lines s_lines

The lines pointer copy instruction copies a lines pointer; for example, the pointer t_lines is a copy of s_lines.

Log

Log Message

log message v_var "A message to the console"
log message v_var "A message to the console{}{}" m_var1 m_var2

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

log lines v_var s_lines

The log lines instruction dumps a lines object at a given verbosity level to the console.

Verbosity

verbosity v_var
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

wait w_var
wait 10000

The wait instruction waits for the given number of nanoseconds.

Random Numbers

Random

random t_var min_var max_var
random t_var 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

seed s_var
seed 10

The seed instruction sets the internal start value for the random number generator.

Debug

Trace

trace t_var
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

marker n_var m_var
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 and Bus Access

Signal Write

signal write a_signal s_var
signal write a_signal 0b11

The signal write instruction writes a variable, constant, or numeric value to a signal.

Signal Read

signal read a_signal t_var

The signal read instruction reads the value of a signal into a variable.

Signal Verify

signal verify a_signal t_var e_var m_var
signal verify a_signal t_var 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

signal pointer copy t_signal s_signal

The signal pointer copy instruction copies a signal pointer; for example, the pointer t_signal is a copy of the pointer s_signal.

Signal Pointer Set

signal pointer set t_signal 5
signal pointer set t_signal ptr_var

The signal pointer set instruction sets a signal pointer (for example, the pointer t_signal) to an absolute address.

Signal Pointer Get

signal pointer get s_signal ptr_var

The signal pointer get instruction gets the value of a signal pointer and stores it in a variable. For example, the pointer s_signal is stored in ptr_var.

Bus Write

bus write a_bus a_width an_address a_var
bus write a_bus 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

bus read a_bus a_width an_address a_var

The bus read instruction reads the value of a bus with a given width and address into a variable.

Bus Verify

bus verify a_bus a_width an_address a_var e_var m_var
bus verify a_bus a_width an_address a_var 0x01 0x0F

The bus verify instruction reads the value of a bus with a given width and address into a variable and compares it to an expected value with a given mask. The expected values and masks 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

bus pointer copy t_signal s_signal

The bus pointer copy instruction copies a bus pointer; for example, the pointer t_bus is a copy of the pointer s_bus.

Bus Pointer Set

bus pointer set t_bus 5
bus pointer set t_bus ptr_var

The bus pointer set instruction sets a bus pointer (for example, the pointer t_bus) to an absolute address.

Bus Pointer Get

bus pointer get s_bus ptr_var

The bus pointer get instruction gets the value of a bus pointer and stores it in a variable. For example, the pointer s_bus is stored in ptr_var.

Bus Timeout Set

bus timeout set a_bus s_var
bus timeout set a_bus 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

bus timeout get s_bus to_var

The bus timeout get instruction gets a bus timeout and stores it in a variable; for example, the timeout s_bus ist stored in to_var.

Resume

resume EXIT_ON_VERIFY_ERROR
resume 0
Usual practice is to use the following constants to set verbosity:
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.

Examples

Hello World

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..

Unit Tests

The test folder contains unittests for all commands. Thus all commands are verified for each release by regression tests.

Real-World Examples

Complex real-world example are found in the eccelerators group of repositories on GitHub.

About

SimStm is a VHDL testbench

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • VHDL 76.9%
  • Python 13.5%
  • XSLT 8.4%
  • Other 1.2%