This is an old revision of the document!
Actsim: an ACT simulator
To run actsim
, you need to select the ACT file to simulate and the top-level process for your design:
% actsim file.act process actsim>
A simple example
The following ACT file is a CHP example that sends three integers on an output channel, and connects that process to one that simply receives an integer and displays it to the screen.
- simple.act
defproc my_source (chan!(int) X) { chp { X!0; X!4; X!3 } } defproc my_sink (chan?(int) X) { int x; chp { *[ X?x; log ("received ", x) ] } } defproc test() { my_source s; my_sink t(s.X); }
A simple simulation can be run as follows:
% actsim simple.act test WARNING: my_sink<>: substituting chp model (requested prs, not found) WARNING: my_source<>: substituting chp model (requested prs, not found) actsim> cycle [ 10] <t> received 0 [ 20] <t> received 4 [ 30] <t> received 3 actsim> quit
actsim
was started by specifying the simple.act
file as the design input, and test
as the top-level process for the simulation. When actsim
started, two warnings were displayed that say that actsim
was looking for prs
models for the circuit, but found a chp
model instead which it substituted. ACT can specify circuits at different levels of abstraction using sub-languages, and the simulator has to select one of them. This warning can be turned off using one of the standard ACT command-line options as follows:
% actsim -Wlang_subst:off simple.act test actsim> cycle [ 10] <t> received 0 [ 20] <t> received 4 [ 30] <t> received 3 actsim> quit
The cycle
command will run the simulation until there is nothing left to simulate. The log
command is used to display output messages; when the circuit is implemented, all log
commands in CHP are replaced by skip
. The message displayed has three parts:
- The first part is the current simulation time displayed in square brackets. By default, every event takes ten time units. (This can be modified by specifying delay parameters in a configuration file.)
- The next part is the name of the instance, in angle brackets. Here the log message was generated by
my_sink
instancet
. - The final part is the actual text from the log command
Commands
General
help
display a list of commands with short descriptions
exit
terminate
source <file>
read in a script file and execute the commands within
Timing
random [<min> <max>]
Set the random timing mode and optionally specify the default random timing bounds for all nodes.
random_seed <seed>
set the seed for the random timing mode.
norandom
Set the deterministic timing mode.
random_choice on|off
turn on/off random exclhi/lo firings
Running Simulation
mode reset|run
set current running mode.
Mode | Effect |
---|---|
reset | reset turns off weak interference warnings (node still becomes X). During chip initialization, there can be weak interference since the simulator assumes all nodes are initially X. Setting the mode to reset during the reset phase prevents these warnings from being printed to the screen. |
run | Warnings of weak interference are enabled. This should be the standard mode after the reset phase has completed. |
initialize <proc>
initialize the simulation with the specified process as the top-level.
step [<steps>]
simulate <steps> events (default is 1)
advance [<duration>]
simulate for <duration> units of simulation time (default is 1)
cycle
simulate until there is nothing more to simulate.
break <variable> breakpt <variable>
set a breakpoint on <variable>.
break-on-warn
toggles the break-on-warn flag which stops/doesn't stop simulation on instability or interference
exit-on-warn
like break-on-warn, but exits prsim
Setting/Getting Values
set <variable> <value>
set <variable> to specified <value>
get <variable> [#f]
get value of <variable>. This returns the value in addition to displaying it. If the optional argument is provided and set to #f
, then the value is returned without displaying it to the screen.
watch <n1> <n2> ...
add watchpoints for <n1>, <n2>, etc.
unwatch <n1> <n2> ...
delete watchpoints for <n1>, <n2>, etc.
timescale <ps>
Set the conversion from integer time units to picoseconds for simulation tracing. By default the conversion is 10ps, but this default can be changed by updating the simulation configuration file.
vcd_start <flle>
Create a VCD file that contains all the variables that are currently watched. The timescale is used for the time reported in the VCD output.
vcd_stop
Stop VCD file generation.
Debug
status 0|1|X
list all nodes with specified value
break-on-warn
Stop the simulation when a warning is generated
exit-on-warn
Quit simulation on a warning
resume-on-warn
Don't stop/exit simulation when a warning is generated
(Work in progress; try running help
on the command-line)
User-defined commands
There is a complete programming language on the command-line. The language is a subset of the Scheme programming language. The implemented subset is documented on github.
Everything typed on the command-line is executed by adding a set of parentheses around it. Hence, a command like
set x 1
typed on the command-line or in a standard script is actually executed as (set x 1)
. A script can be written directly in the Scheme subset and loaded using load-scm “file.scm”
on the command-line.
This means your Scheme programs can execute any of the standard actsim
commands, as they are built-in to the Scheme execution engine. For example, if you want to see the output of a gate for all possible input settings, here's a Scheme function you could define:
(define try-all (lambda (inlist out) (begin (if (null? inlist) (begin (cycle) (get out)) (begin (echo "-- " (car inlist) " <- 0") (set (car inlist) 0) (cycle) (try-all (cdr inlist) out) (echo "-- " (car inlist) " <- 1") (set (car inlist) 1) (cycle) (try-all (cdr inlist) out) ) ) ) ) )
If you load this definition, then
(actsim) try-all (list "a" "b" "c") "out"
will try all possible 0/1 assignments to a
, b
, and c
, and display the value of out
.
Example with a test environment
To illustrate how one can write a range of test benches for actsim
, we use a simple example of an adder (in adder.act
) written as follows:
- adder.act
defproc adder(chan?(int) A, B; chan!(int) C) { int a, b; chp { *[ A?a, B?b; C!(a+b) ] } }
A simple test environment would look like this:
- testadd.act
import "adder.act"; defproc src1 (chan!(int) X) { chp { X!3; X!5; X!2 // test inputs } } defproc src2(chan!(int) X) { chp { X!7; X!9; X!3 } } defproc sink(chan?(int) X) { int x; chp { *[ X?x; log ("received ", x) ] // read a value and display it } } defproc test() { adder a; src1 s1(a.A); src2 s2(a.B); sink sx(a.C); }
Running actsim testadd.act test
will start the simulation with the defined environment.
Since this is a commonly-used approach, the ACT standard library contains a sim
(for simulation) namespace that has commonly used sources and sinks.
Mixed-signal simulations
Mixed analog-digital simulations can be done in actsim
, if it was built with Xyce (see building actsim with Xyce).
There are two ways to specify an analog simulation:
- Specify prs for a process and simulate it at the device level using spice models. This can be done by specifying the device level using an ACT configuration file that is loaded at runtime into
actsim
. The simulator will use the same approach as prs2net to generate the SPICE netlist for the specified processes/instances. - Specify a blackbox process with ports and provide a netlist file to simulate. This provides more flexibility in the netlist simulated by Xyce; for example it can include extracted parasitics.
The method to specify a blackbox process is described here. An example with three inverters, one each with digital actsim simulation, analog simulation of prs and analog simulation of blackbox spice netlist can be found at this repository.