In order to run test patterns (stim files), we need a way to specify how to run them. To do this, we create a test program or a prgm file. Prgm files are written in a very minimal Lisp dialect called Fe, that provides control flow, variables, functions and an api to load, run and get the status of executed test patterns.

Below we find the Prgm file examples, the Prgm API and the Fe language syntax.

Prgm file examples

The best way to learn how a Prgm file works is to just show you a few examples, which you can use as a stepping stone to develop test patterns suited to your own particular needs. A Prgm file is actually just Fe Lisp code that calls the Prgm API, which gives you tremendous flexibility and endless possibilities.

As covered in other sections, before you can execute any Dots test patterns, dots files must first be compiled to stim files using Leda the compiler. The files must be placed on an NFS mount that the Prgm has access to. This can be configured through the Gemini Web App.

To start, here's a simple example Prgm file that loads three test patterns sequentially into Artix memory and executes the patterns, stopping execution if a pattern fails.

                    
# simple test program

(set-profile "board_profile.json")
(run 
    (load "file1.stim")
    (load "file2.stim")
    (load "file3.stim"))
                    
                

Prgm API

(reads <stim_path:str>) -> <stim_object:ptr>

Reads a stim file from disk and returns a stim object.

(writes <stim_object:ptr> <stim_path:str:) -> <stim_object:ptr>

Write a stim object to disk at the given path string.

(load <stim_path:str>) -> (<a1_addr:num>, <a2_addr:num>)

Sequentially loads the test pattern stim into tester memory after the previously loaded test pattern. Returns the address in tester memory where the stim was loaded.

(loads <stim_object>) -> (<a1_addr>, <a2_addr>)

Sequentially loads the test pattern stim into tester memory after the previously loaded test pattern given a stim object. Returns the address in tester memory where the stim was loaded.

(loada <stim_object> (<a1_addr>, <a2_addr>)) -> (<a1_addr>, <a2_addr>)

Loads the stim object given to the tester memory at the address given. Returns the address in tester memory where the stim was loaded.

DANGER: this can and will overwrite tester memory

(unload (<a1_addr>, <a2_addr)) -> nil

Unloads a stim at the address pair given.

(unload-all) -> (<num_a1_unloaded_stims>, <num_a2_unloaded_stims>)

Unloads all stims and returns num stims that were unloaded. Returns the number of stims that were unloaded.

(run <a1_addr> <a2_addr> ...) -> (<num_tests_ran>, <did_test_fail>, <fail_test_cycle>)

Executes loaded stims at the tester memory addresses given. Stops at the first failing pattern.

(runc <a1_addr> <a2_addr> ...) -> (<num_tests_ran>, <did_test_fail>, <fail_test_cycle>)

Executes loaded stims at the tester memory addresses given. Will execute all stims without stopping if it fails.

(set-profile "board_profile.json") -> nil

Globally sets the board profile to be used for subsequent "load" calls. Returns nil because the profile is saved globally.

(get-pin-names) -> (<p0:str>, <p1:str>, ...)

Returns a list of pin string net names for the last stim that ran. If no stim ran, returns nil;

(get-fail-pins) -> (<p0:bool>, <p1:bool>, ...)

Returns the failing pins for the last stim that ran. The failing pins is a list that corresponds to the Pin line in the dots. If the bool is true, that pin failed. Call (pin-names) to return a list of the pin names. If no stim ran, returns nil;

Fe language syntax

For more information about the Fe language, please take a look at the source code and documentation on Github.

Special-forms
(let sym val)

Creates a new binding of `sym` to the value `val` in the current environment.

(= sym val)

Sets the existing binding of `sym` to the value `val`; in lieu of an existing binding the global value is set.

(if cond then else ...)

If `cond` is true evaluates `then`, else evaluates `else` — `else` and `then` statements can be chained to replicate the functionality of else-if blocks.

                
> (= x 2)
nil
> (if (is x 1) "one"
      (is x 2) "two"
      (is x 3) "three"
      "?")
two
                
                
(fn params ...)

Creates a new function.

                
> (= sqr (fn (n) (* n n)))
nil
> (sqr 4)
16
                
                
(mac params ...)

Creates a new *macro*.

                
> (= incr (mac (x) (list '= x (list '+ x 1))))
nil
> (= n 0)
nil
> (incr n)
nil
> n
1
                
                
(while cond ...)

If `cond` evaluates to true evaluates the rest of its arguments and keeps repeating until `cond` evaluates to `nil`.

                
> (= i 0)
nil
> (while (< i 3)
    (print i)
    (= i (+ i 1)))
0
1
2
nil
                
                
(quote val)

Returns `val` unevaluated.

                
> (quote (hello world))
(hello world)
                
                
(and ...)

Evaluates each argument until one results in `nil` — the last argument's value is returned if all the arguments are true.

(or ...)

Evaluates each argument until one results in true, in which case that arguments value is returned — `nil` is returned if no arguments are true.

(do ...)

Evaluates each of its arguments and returns the value of the last one.

Functions
(cons car cdr)

Creates a new pair with the given `car` and `cdr` values.

(car pair)

Returns the `car` of the `pair` or `nil` if `pair` is `nil`.

(cdr pair)

Returns the `cdr` of the `pair` or `nil` if `pair` is `nil`.

(setcar pair val)

Sets the `car` of `pair` to `val`.

(setcdr pair val)

Sets the `cdr` of `pair` to `val`.

(list ...)

Returns all its arguments as a list.

                
> (list 1 2 3)
(1 2 3)
                
                
(not val)

Returns true if `val` is `nil`, else returns `nil`

                
> (not 1)
nil
                
                
(is a b)

Returns true if the values `a` and `b` are equal in value. Numbers and strings are equal if equivalent, all other values are equal only if it is the same underlying object.

(atom x)

Returns true if `x` is not a pair, otherwise `nil`.

(print ...)

Prints all it's arguments to `stdout`, each separated by a space and followed by a new line.

(< a b)

Returns true if the numerical value `a` is less than `b`.

(<= a b)

Returns true if the numerical value `a` is less than or equal to `b`.

(+ ...)

Adds all its arguments together.

(- ...)

Subtracts all its arguments, left-to-right.

(* ...)

Multiplies all its arguments.

(/ ...)

Divides all its arguments, left-to-right.