gpsim

$Date:: 2017-06-12#$

Table of Contents

Introduction

gpsim is a full-featured software simulator for Microchip PIC microcontrollers distributed under the GNU General Public License and GNU Lesser Public License(see the LICENSE section).
gpsim has been designed to be as accurate as possible. Accuracy includes the entire PIC - from the core to the I/O pins and including ALL of the internal peripherals. Thus it’s possible to create stimuli and tie them to the I/O pins and test the PIC the same way you would in the real world.
gpsim has been designed to be as fast as possible. Real time simulation speeds of 20Mhz pics are possible.
gpsim can be controlled from either a graphical user interface (GUI), a command line interface (CLI) or by a remote process. Typical debugging features like breakpoints, single stepping, disassembling, memory inspect & change, and so on are all supported. In addition, complex debugging features like real time tracing, assertions, conditional breaks, and plugin modules to name a few are also supported.

1 gpsim - An Overview

If you don’t care to wade through details, this chapter should help you get things up and running. The INSTALL and README files will provide more up-to-date information than this document, so please refer to those first.

1.1 Making the executable

gpsim’s executable is created in a manner that’s consistent with much of the other open source software:
command description
tar -xvzf gpsim-x.y.z.tar.gz expand the compressed tar file
./configure Create a ’makefile’ unique to your system
make compile gpsim
make install install gpsim
The last step will require root privileges.

1.1.1 Make Details - ./configure options

gui-less

The default configuration will provide a gui (graphical user interface). The cli (command line interface) is still available, however many people prefer just to use the cli. These hardy souls may build a command-line only interface by configuring gpsim:
./configure --disable-gui

debugging

If you want to debug gpsim then you will probably use gdb. Consequently, you will want to disable shared libraries:
./configure --disable-shared
This will create one, huge monolithic executable with symbolic information.

1.1.2 RPMs

gpsim is also available in RPM form from linux distributions such as Fedora.

1.1.3 Windows

Gpsim runs on Windows too. Both release and snapshot gpsim apps can be installed and run on windows machines.
The release version of the gpsim apps are generated on each new release of gpsim. These can be downloaded from the following web site:
https://sourceforge.net/projects/gpsim/files/gpsim-win32/
The snapshot versions are generated from time to time from the then current source code and will contain bug fixes and new features added since the last release. These versions should work, but are not given the extra testing of a new release. Snapshots can be downloaded from:
https://sourceforge.net/projects/gpsim/files/snapshot_builds/gpsim-win32/
If you wish to build your own windows version of gpsim, the late Borut Razem has documented the process which can be found at this location:
http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html

1.2 Running

The executable created above is called: gpsim. The following command line options may be specified when gpsim is invoked.
gpsim [-?] [-p <device> [<hex_file>]] [[-c] <stc_file>] [[-s] <symbol file>]
  -p, --processor=<processor name>     processor (e.g. -pp16c84 for the ’c84)
  -c, --command=STRING                 startup command file (optional .stc files)
  -s                                   .cod symbol file (optional .cod files)
  -L, —                               colon separated list of directories to
                                       search.
  -v, --version                        gpsim version
  -i, --cli                            command line mode only
  -d, --icd=STRING                     use ICD (e.g. -d /dev/ttyS0).
  Help options:
  -?, --help                           Show this help message
  --usage                              Display brief usage message
Typically gpsim will be invoked like:
[My-Computer]$ gpsim  mypic-program.cod
(The [My-Computer]$ text is an example of a typical bash command prompt - you will only type the text after this prompt). This loads the .cod file generated by gputils.
Under Windows, gpsim can also be invoked by navigating through the Start/Program menu. This will open a DOS window to provide access to the command line interface. It’s also possible to open a DOS window (or CygWin bash session) and invoke gpsim from there.

1.3 Requirements

gpsim has been developed under Linux. It should build and run just fine under the popular Linux distributions like Fedora, Ubuntu, etc. gpsim has also been ported to the MAC, MicroSoft Windows, Solaris, and BSD. Two packages gpsim requires that may not be available with all Linux distributions are readline and gtk (the gimp tool kit). The ./configure script should tell you if these packages are not installed on your system or if the revisions that are installed are too old.
There are no minimum hardware requirements to run gpsim. Faster is better though!
gputils, the gnupic utilities package, is also very useful. gpsim will accept straight hex files, but if you want to do any symbolic debugging then you will want to use the .cod [A]  [A] .cod files are symbol files that were created by ByteCraft and are used by Microchip. files that gputils produces. The .cod files are in the same format as the .cod files MPASM [B]  [B] MPASM is Microchip’s Assembler. produces.

2 Command Line Interface

The command line interface is fairly straight-forward. The table below summarizes the available commands. Brief descriptions of these commands can also be displayed by typing help at the command line.
command summary
attach Attach stimuli to nodes
break Set a break point
bus Add or display node busses
clear Remove a break point
disassemble Disassemble the current cpu
dump Display either the RAM or EEPROM
frequency Set processor frequency
help Type help "command" for more help on a command
icd In Circuit Debugger support.
list Display source and list files
load Load either a hex or command file
log Log/record events to a file
node Add or display stimulus nodes
module Select & Display modules
processor Add/list processors
quit Quit gpsim
reset Reset all or parts of the simulation
run Execute the pic program
set display and control gpsim behavior flags
step Execute one or more instructions
stimulus Create a stimulus
stopwatch Measure time between events
symbol Add/list symbols
trace Dump the trace history
version Display gpsim’s version
x (deprecated) examine and/or modify memory
The built in ’help’ command provides additional online information.

2.1 attach

attach node1 stimulus1 [stimulus2 stimulus_N]
Attach is used to define connections between one or more stimulus and a node. One node and at least one stimulus must be specified, but in general two or more stimuli are used. Attach can be viewed as wiring stimuli together, with the node acting as the wire. A stimulus is either a CPU or module I/O pin or a stimulus name.
Attach_pointN can have one of the following formats
pin(<number>) or pin(<symbol>) \begin_inset Separator latexpar\end_inset
<connection> or pin(<connection>) \begin_inset Separator latexpar\end_inset
Example
**gpsim> load instructions_14bit.cod     # load code
**gpsim> module library libgpsim_modules #load module lib
**gpsim> module load usart U1            # create USART
**gpsim> node n1                         # define a node
**gpsim> node n2                         #define another node
**gpsim> symbol TWO=2                    #define symbol with value 2
**gpsim> attach n1 pin(1) pin(TWO)       #attach CPU pins 1 and 2
**gpsim> attach n1 U1.RXPIN              #add usart pin to n1
**gpsim> attach n2 portb0 pin(U1.TXPIN)  #connect portb0 to UASRT TX pin
**gpsim> node                            # show results

2.2 break

The break command is used to set and examine break points. New break points are assigned a unique number. This number can be used to query or clear the break point. Break points halt the simulation when the condition associated with them is true. Break points are ignored during single stepping. See chapter 5↓ for more examples of breakpoints.

Examining break points

break [bp_number]
Break points can be examined by typing the break command without any options. Specific breaks can be queried by specifying the break point number.

Program Memory/Execution breaks

The most common break point is an execution break point. This one halts execution whenever the program counter reaches the address at which the break point is set. The syntax is:
break e|r|w ADDRESS [,expr [,message]]
The simulation halts when the address is executed, read, or written. The ADDRESS can be a symbol or a number. If the optional expression is specified, then it must evaluate to true before the simulation will halt. The optional message allows a description to be associated with the break. The read and write options only apply to those processors that can manipulate their own program memory.

Register Memory breaks

gpsim can also associate break points with register accesses. This is useful for capturing bugs that stomp on RAM. E.g. you can say something like “halt execution whenever bit 4 of register 42 is cleared”. The command line syntax is:
break r|w|ch REGISTER [,expr [,message]]
The simulation halts when REGISTER is read, written, or changed on write, and the optional expression evaluates to true.
Other syntaxes with a boolean expression are:
break r|w|ch REGISTER == value
The simulation halts when REGISTER is assigned the specified value, and:
break r|w|ch REGISTER & mask == value
The simulation halts when specified bits in REGISTER are assigned the specified value.
Here’s an example of a register write break. This one will halt the simulation if any value is written to the variable named temp1.
break w temp1
Sometimes it’s necessary to specify an auxiliary condition with a break point. For example, there may be a temporary variable that is shared throughout the code. You may wish to trap writes to that variable only while executing a specific subroutine. For example, the following break point triggers when temp1 is written and while the program counter is in between the labels func_start and func_end:
break w temp1, (pc >= func_start && pc < func_end)
TIP: Use this type of break point if you suspect an interrupt routine is over writing a variable.
Another situation is one where you wish to trap writes to a variable only if some other variable is a certain value:
break w temp1, (CurTask & 0x0f != 0b101)
If the firmware writes to the variable temp1 then the simulation will halt if the lower nibble of CurTask is not equal to 5.
This example breaks only if the hex digit ’C’ is written to the upper nibble of temp1:
break w (temp1 & 0b11110000) == 0b11000000

Processor exception breakpoints

Stack overflow, underflow and watchdog timeout can also halt the simulation.
break so
break su
break wdt

Attribute Breakpoints

break attribute
gpsim also supports a concept of attribute breakpoints. Attributes are parameters that gpsim and its modules expose to the user interface. For example, the simulator stopwatch exposes attributes which support breakpoints. This feature is intend mainly for module writers to provide a mechanism for allowing the user to control the module.

Cycle counter Breakpoints

break c cycle_number
The cycle counter is gpsim’s time keeper. It increments once every instruction cycle. The ’c’ option to the break command allows a break point to be set at a particular value of the cycle counter.

2.3 clear

clear bp_number

The clear command is used to clear break points. The break point number must be specified. The break command without any arguments displays all of the currently defined break points. This can be used to ascertain the break point number. Once cleared, a break point is deleted.  [C]  [C] A break point disable/enable feature has been discussed and may be added a future date.

2.4 disassemble

disassemble [[begin:end] | [count]]

The disassemble command decodes the program memory opcodes into their standard mnemonics. With no options, the disassemble command disassembles instructions surrounding the current program counter:
gpsim> disassemble
current pc = 0x1c
    0012 2a03 incf reg3,f,0
    0014 0004 clrwdt
    0016 5000 movf reg,w,0
    0018 1001 iorwf reg1,w,0
    001a 1002 iorwf reg2,w,0
==> 001c 1003 iorwf reg3,w,0
    001e e1f4 bnz $-0x16 ;(0x8)
    0020 d7ff bra $-0x0 ;(0x00020) 
With a single numeric option, the disassemble command will disassemble given number of instructions starting with the instruction at the PC.
With a two numbers, the disassemble command will disassemble instructions starting and ending given number of instructions from the PC.

2.5 dump

dump [r | s | e [module_name [filename]]]

dump r or dump with no options will display all of the file registers and special function registers.
dump s will display only special function registers.
dump e will display the contents of the processor EEPROM (if the pic being simulated contains any).
The ’dump e module_name’ command will display the contents of an EEPROM where module_name can either be the name of a module or processor which contains an EEPROM.
The ’dump e module_name filename’ command dumps the contents of a module’s EEPROM, in Intel hex format, into the file with the given name. The ’load e’ command can later be used to read the dumped file thus allowing the contents of the EEPROM to be preserved between runs of gpsim.
See the ’x’ command for examining and modifying individual registers.

2.6 echo

The echo command is used like a print statement within configuration files. It just lets you display information about your configuration file.

2.7 frequency

This command sets the oscillator frequency. By default gpsim uses 20 MHz oscillator. The oscillator frequency is used to compute time in seconds. Use this command to adjust this value. If no value is provided this command prints the current frequency. Note that PICs have an instruction frequency that’s a quarter of the oscillator frequency clock.

2.8 help

help [command]
By itself, help will display all of the commands along with a brief description on how they work. With a command as a parameter help provides more extensive online help. The help command can also display information about attributes.

2.9 icd

icd [open <port>]
The open command is used to enable ICD mode and specify the serial port where the ICD is. (e.g. "icd open /dev/ttyS0"). Without options (and after the icd is enabled), it will print some information about the ICD.

2.10 list

The list command allows you to view the source code while you are debugging.
list [[s | l] [*pc] [line_number1 [,line_number2]]]
Without any options, list will use the last specified options.
list s will display lines in the source (or .asm) file.
list l will display lines in the .lst file.
list *pc will display either .asm or .lst lines around the PC. Without *pc use current PC as a reference.
Line numbers are relative to the line of the PC.

2.11 load

The load command is used to load a program file, a command file, or eeprom data.
Program file is usually used to program the physical part. A .hex file provides no symbolic information. .cod files on the other hand, do provide symbolic information. The only reason to use a hex file is when there’s no .cod file available.
The syntax for loading program files is:
load [processortype] programfile [label]
Gpsim will automatically determine if the file is a .hex or .cod file. The optional processortype is needed if a .hex file is being loaded and the processor type is not yet defined.
The optional label is used to identify the processor module on the breadboard and as the prefix in the symbol table. If a label is not given then the processor type is used for this functionality.
load [i] commandfile.stc
Command files contain gpsim commands. These are extremely useful for creating a debugging environment that will be used repeatedly. Normally loading a command file residing in other directories changes working directory. This can be overridden with the ’i’ (include) option.
load e module_name file
This command loads the contents of either a processor’s EEPROM or an EEPROM module from a file containing the data in Intel hex format. In either case the address of the first cell of the EEPROM is 0x0000. Used in conjunction with the ’dump e module_name filename’ command, the contents of an EEPROM can be carried over from one run of gpsim to another.

2.12 macros

Macros are defined like:
name macro [arg1, arg2, ..., argN]
   macro body
endm
And they’re invoked by:
name param1, param2, ..., paramN
Macros are a way of collecting several parameterized commands into one short command. The first line of a macro definition specifies the macro’s name and optional arguments. The name is used to invoke the macro. The arguments are text string place holders. When a macro is invoked, the parameters are aligned with the arguments. I.e. param1 in the invocation can be thought of being assigned to arg1 in the definition. The parameters replace the arguments in the macro body.
In the following example, a variable or attribute called mac_flags is being manipulated in an expression. The arguments add and mask appear in the macro body and provide a parameterized way of manipulating this expression.
mac_exp macro add, mask
  mac_flags = (mac_flags+add) & mask
endm 
Note that the indentation is arbitrary. The macro is invoked by:
mac_exp 1, 0b00001111 # increment the lower nibble
The parameter add is replaced by the number 1 while mask is replaced with the binary number 0b00001111. The invocation turns into the gpsim command:
mac_flags = (mac_flags+1) & 0b00001111

Nested Macros

The macro body can contain any gpsim command. Of particular interest are macro invocations within other macros. Here’s another macro that invokes the one defined above.
# Nested macro example
mac1 macro p1, p2
  run
  mac_exp p1, p2
endm 
And it could be used like:
mac1  1,      0b00001111   #  test lower nibble
mac1  (1<<4), 0b11110000   #  test upper nibble
The first invocation starts the simulator by executing a run command. When a break point is encountered, control returns to the command line and the mac_exp macro is invoked.

Displaying Defined Macros

All currently defined macros can be displayed by typing the macro command without a name or arguments:
gpsim> macro
mac1 macro p1 p2
   run
   mac_exp p1, p2
endm
mac_exp macro add mask
    mac_flags = (mac_flags+add) & mask
endm 

2.13 module

The module command is used to load and query external modules (see section 8↓ for more information about gpsim modules). A module is a special piece of software that can extend gpsim in some manner. LED’s and switches are examples of modules. A module library is collection of modules.

Loading module libraries

module lib lib_name
The lib option is used to load a module library. Module libraries are system dependent shared libraries, i.e. on Windows they’re DLL’s and UNIX they’re shared libraries. This means that either the libraries should reside in a path where the OS knows libraries exist or that the full path name must be specified along with the lib_name. gpsim provides a module library with a few modules:
gpsim> module lib libgpsim_modules

Displaying available modules

module list
The list option will display all of the modules that can be loaded. Here is an example of gpsim’s built-in modules.
gpsim> module list
Module Library Files
libgpsim_modules.so
   switch
   and2
   or2
   xor2
   not
   led_7segments
   led
   push_button
   PortStimulus
   pullup
   pulldown
   pulsegen
   Encoder
   usart
   TTL377
   I2C-EEPROM2k
   I2C-EEPROM16k
   I2C-EEPROM256k

Loading a specific module

module load module_type [module_name]
Once a library has been loaded, specific modules can be instantiated. The module_type is what’s displayed by the module list command. The optional module name specifies what the instance is called. Here’s an example
gpsim> module load led D1 

Display loaded modules

module

Querying modules

Dumping modules and listing the pins is not yet implemented.

2.14 node

node [new_node1 new_node2 ...]
The node command defines or queries “nodes”, used to connect external signals to the simulated PIC. If no new_node is specified then all of the nodes that have been defined are displayed. If a new_node is specified then it will be added to the node list. See the "attach" and "stimulus" commands to see how stimuli are added to the nodes.
examples:

node           // display the node list
node n1 n2 n3  // create and add 3 new nodes to the list 

2.15 processor

processor [new_processor_type [new_processor_name]] | [list] | [pins] 
The processor command is used to either define a new processor or to query one that has already been defined. Normally there’s no need to explicitly define the processor since the symbol file already contains that information. The two exceptions are when a) the symbolic information is not available or b) you wish to override the processor specified in the symbol file. (See the load command on how the processor in a symbol file can be overridden.)
To see a list of the processors supported by gpsim, type ’processor list’. To display the state of the I/O processor, type ’processor pins’. For now, this will display the pin numbers and their current state.
examples:
processor        // Display the processors you’ve already defined. 
processor list   // Display the list of processors supported. 
processor pins   // Display the processor package and pin state 
processor p16cr84 fred   // Create a new processor. 
processor p16c74 wilma   // and another. 
processor p16c65         // Create one with no name.

2.16 quit

Quit gpsim.

2.17 run

Start (or continue) simulation. The simulation will continue until the next break point is encountered.

2.18 step

Execute a single instruction, or a specified number of instructions.
step [over | n]
With no arguments, the step command executes one instruction of the PIC code. If a numeric argument is given, this specifies a fixed number of instructions to simulate. The specific word “over” as an argument to step tells gpsim to run everything involved in the current instruction. This would normally be used on a CALL instruction, in which case the whole subroutine runs and the simulation stops after it returns.

2.19 symbol

symbol [symbol_name [symbol_type value]] 
The symbol command is used to query and define symbols. If no options are specified, the whole symbol table is displayed. The creation of user defined symbols is limited at this time (see the online help for the current state of this command).

2.20 stimulus

stimulus [[type] options]
The stimulus command creates a signal that can be tied to a node or an attribute. If no options are specified then all currently defined stimuli are displayed.
Note that in most cases it is easier to create a stimulus file then to type the command by hand.
initial_state state at the start and at the rollover
start_cycle simulation cycle when the stimulus will begin
period stimulus period
name specifies the stimulus name
Here’s an example of a stimulus that will generate two pulses and repeat this in 1000 cycles.
stimulus asynchronous_stimulus

# The initial state AND the state the stimulus is when 
# it rolls over

initial_state 0
start_cycle 0

# the asynchronous stimulus will roll over in ’period’
# cycles. Delete this line if you don’t want a roll over.

period 1000

{ 100, 1,
  200, 0,
  300, 1,
  400, 0 
}
# Give the stimulus a name:

name two_pulse_repeat

end
A stimulus can be queried by typing its name at the command line:
gpsim> two_pulse_repeat 
two_pulse_repeat attached to pulse_node
  Vth=0V  Zth=250 ohms  Cth=0 F  nodeVoltage= 7.49998e-07V 
  Driving=0 drivingState=0 drivenState=0 bitState=0

  states = 5
    100 1
    200 0
    300 1
    400 0
    1000 0   
initial=0   
period=1000   
start_cycle=0   
Next break cycle=100 
Even though this example uses 1’s and 0’s for the data, one can use integers, floating point numbers, or expressions instead. Integers are useful for supplying a stimulus to an attribute. Expressions are useful for abstracting the data. See Chapter 7↓ for more discussion and examples of stimuli.

2.21 stopwatch [D]  [D] The stopwatch is really a collection of attributes and not a command. But the behavior is so similar to a command that it has been included here.

A timer for monitoring and controlling the simulation.  
The units are in simulation cycles.
  stopwatch.rollover - specifies rollover value.
  stopwatch.direction - specifies count direction.
  stopwatch.enable - enables counting if true. 
Without any options, stopwatch will display the contents of the stopwatch timer. stopwatch is writable, so you may initialize it to whatever value you like. The behavior of the timer may be manipulated via the three attributes. The .rollover attribute is the number of cycles at which the stopwatch timer rolls over. The .direction and .enable attributes are boolean types. When true, the .direction attribute will instruction the stopwatch to count up.

2.22 trace

trace [dump_amount]
trace will print out the most recent "dump_amount" traces. If no dump_amount is specified, then the entire trace buffer will be displayed.

2.23 version

version
Display gpsim’s version. Note, this command will probably get replaced by an attribute with the same (or similar) name.

2.24 x

The x command is deprecated. It’s former use was to examine and modify memory. The preferred way to do this now is with expressions. The help for x now indicates this:
x examine command — deprecated
  Instead of the using a special command to examine and modify
  variables, it’s possible to directly access them using gpsim’s
  expression parsing. For example, to examine a variable:
gpsim> my_variable
my_variable [0x27] = 0x00 = 0b00000000
  To modify a variable
gpsim> my_variable = 10
  It’s also possible to assign the value of register to another
gpsim> my_variable = porta
  Or to assign the results of an expression:
gpsim> my_variable = (porta ^ portc) & 0x0f 
 

3 Graphical User Interface

FIXME: We could use a few illustrations here!
gpsim also provides a graphical user interface that simplifies some of the drudgery associated with the cli. It’s possible to open windows to view all the details about your debug environment. To get the most out of your debugging session, you will want to assemble your code with gpasm (the gnupic assembler) and use the symbolic .cod files it produces.

3.1 Main window

3.1.1 Menus

File->Open .stc or .cod files.
File->Quit Quit gpsim
Windows->* Open/Close the windows.

3.1.2 Buttons

(These are also found as keyboard bindings in the source windows.)
Step Step one instruction
Over Step until pc is after next instruction
Finish Run to return address
Run Run continuously
Stop Stop execution
Reset Reset CPU

3.1.3 Simulation mode

This controls how gpsim simulates, and how the GUI updates.
Never Don’t ever update the GUI when simulating. This is the fastest mode. You will have to stop simulation by pressing Ctrl-C in the command line interface.
x cycles Update the GUI every x cycles simulated.
every cycle Update the GUI every cycle. (you see everything, if you have filled up on coffee :-)
x ms animate Here you can slow down simulation with a delay between every cycle.
realtime This will make gpsim try to synchronize simulation speed with wall clock time.

3.2 Source Browsers

gpsim provides two views of your source: ’.asm’ and ’.obj’ browsers. The ’.asm’ browser is a color coded display of your pic source.

3.2.1 .asm Browser

When a .cod file with source is loaded, there should be something in this display. (TODO: add section about high level debugging).
There is an area to the left of the source, where symbols representing the program counter, breakpoints, etc are displayed. Double clicking in this area toggles breakpoints. You can drag these symbols up or down in order to move them and change the PC or move a breakpoint.
A right button click on the source pops up a menu with six items (the word ’here’ in some menu items denote the line in source the mouse pointer was on when right mouse button was clicked.):
Menu item Description
Find PC This menu item will find the PC and changed page tab and scroll the source view to the current PC.
Run here This sets a breakpoint ’here’ and starts running until a breakpoint is hit.
Move PC here This simply changes PC to the address that line ’here’ in source has.
Breakpoint here Set a breakpoint ’here’.
Profile start here Set a start marker for routine profiling here.
Profile stop here Set a stop marker. (See the section for the profiling window.)
Select symbol. This menu item is only available when some text is selected in the text widget. What it does is search the list of symbols for the selected word, and if it is found it is selected in the symbol window. Depending of type of symbol other things are also done, the same thing as when selecting a symbol in the symbol window: \begin_inset Separator latexpar\end_inset
Find text This opens up a search dialog. Every time you hit the ’Find’ button, the current notebook page is found and the source in that page is used.
Settings A dialog with which you can change the fonts used.
Controls A submenu containing the simulation commands. (these are also found as keyboard bindings (recommended), or in the main window.)
These are the keyboard bindings:
Key command
s,S,F7 Step one instruction.
o,O,F8 Step over instruction
r,R,F9 Run continuously.
Escape Stop simulation.
f,F Run to return address
1..9 Step n instructions
ctrl-f Find text

3.2.2 Opcode view - the .obj Browser

This window has two tabs. One with each memory cell on one line and information about address, hexadecimal value and decoded instruction (i.e. disassembly), and one with the program memory
displayed with sixteen memory cells per row and a configurable ASCII column.

The Assembly tab you can:

The Opcode tab.

Here the program memory is ordered as columns of sixteen memory cells per column and as many row as needed to contain all memory.
The seventeenth column contains an ASCII representation of the program memory.
You can change font with the menu item ’Settings’.
The breakpoints can be set or cleared on one or more (drag the mouse to select more cells) addresses with the right click menu.

3.3 Register views

There are two similar register windows. One for the RAM and one for the EEPROM data, when available.
Here you see all registers in the current processor. Clicking on a cell displays it’s name and value above the sheet of registers. You can change values by entering it in the entry (or in the spreadsheet cell).
The following things can be done on one register, or a range of registers. (Selecting a range of registers is done by holding down left mouse button, moving cursor, and releasing button.)
The cells have different background colors depending on if they represent:
gpsim dynamically updates the registers as the simulation proceeds. Registers that change value between updates of the window during simulation are highlighted with a blue foreground color.
The menu also has a ’settings’ item where you can change the font used.

3.4 Symbol view

This window, as its name suggests, displays symbols. All of the special function registers will have entries in the symbol viewer. If you are using .cod files then you will additionally have file registers (that are defined in cblocks), equates, and address labels.
You can filter out some symbol types using the buttons in the top of the window, and you can sort the rows by clicking on the column buttons (the ones reading ’symbol’, ’type’ and ’address’).
You can add the symbol to the watch window by right-clicking and selecting the "Add to watch window" menu item. This will add the ram register with address equal to the symbols value to the watch window.
The symbol viewer is linked to the other windows. For example, if you click on a symbol and:

3.5 Watch view

This is not a output-only window as the name suggests (change name?). You can both view and change data. Double-clicking on a bit toggles the bit. You add variables here by marking them in a register viewer and select “Add watch” from menu. The right-click menu has the following items:
"Columns...” opens up a window where you can select which of the following data to display:
You can sort the list of watches by clicking on the column buttons. Clicking twice sorts the list backwards.

3.6 Stack viewer

This window displays current stack. Selecting an entry makes the code windows display the return address. Double clicking sets a breakpoint on the return address.

3.7 Breadboard

Here you can create/modify and examine the environment around the pic. Pins are displayed as an arrow. The direction of the arrow indicates if its an input or output pin. The color of the arrow indicates its state (green=low, red=high).
You can’t instantiate pic processors from here, you will have to do that from the command line, or from a .stc file.
Your can create nodes by clicking on the "new node" button. (A node is ’a piece of wire’ to which you can connect stimulus.) You can see the list of created nodes under the "nodes" item in the upper-left tree widget.
You can create connections to nodes by clicking on a pin, and then clicking on the button "Connect stimulus to node". This will bring up a list of nodes. Choose one by double-clicking on the one you like.
If you click on a pin that is already connected to a node, then you will see the node and its connections in the lower left part of the window. You can disconnect a stimulus by clicking on it and pressing the "remove stimulus" button.
When you want to add a module to the simulation, you first have to specify the library which contains the module you want. Click on the "add library" button and enter the library name (e.g. "libgpsim_modules.so"). Now you can click the "add module" button. Select the module you want from the list by double-clicking on it. Enter a name for the module (this has to be unique, and not used before). You now have to position the module. Move the mouse pointer to where you would like the module, and left-click.
If you middle-click on a pin, you will see how the pin is connected. Press the "trace all" to see all at
once, and "clear traces" to remove all (you will only remove the graphical trace, not the connection!). If the tracing doesn’t work, try moving the packages so that there are more space around the pins.
When you are done, you can save by clicking the "save configuration" button. You can then load this file from the command line like this (assuming the .cod file with your source is called "mycode.cod", and the file you just saved was called "mynets.stc":
gpsim -s mycode.cod -c mynets.stc
You can’t load only the .stc file since this doesn’t contain the processor type and code. You can create (with an editor) your own .stc file (e.g. my_project.stc) and in that file put a command "load c mynets.stc" after you have loaded the .cod file. You then only have to load this file (gpsim -c my_project.stc).

3.8 Trace viewer

This window shows the trace of instructions executed. See 6↓.

3.9 Profile viewer

This window show execution count for program memory addresses. The profile window must be opened before starting simulation, because the tracing is not enabled by default.

Instruction profile

This shows the number of times each instruction are executed.

Instruction range profile

Here you can group ranges of instruction into one entry.
The right click menu contains:
Remove range Remove an entry.
Add range... Open a dialog from where you can add a range of instructions as an entry.
Add all labels Add all code labels as ranges.
Snapshot to plot Open a window containing a graph of the data. From this new window you can also save (postscript) or print it.

Register profile

This shows the number of reads or writes the simulator does on register.

Routine profile

Here you can see statistics about execution time for a selected routine. You mark the entry and exit points from the source browser (profile start/stop). If the routine you want to measure have multiple entry and/or exit points, then you have to put a marker on every entry point as well as (and especially) every exit point. Otherwise you will get bad data.
When you have done that, gpsim will (as simulation goes by) store the execution times of that routine and calculate min/max/average/etc. You can also use the menu item ’Plot distribution’ to open a window displaying a histogram of the data. From this new window you can also save (in postscript) or print it.
You can also measure call period by switching the ’entry’ and ’exit’ points. If also want the time from reset (or some equal point) to the first ’entry’, then you must also put an ’entry’ point there.

3.10 Stopwatch

The stopwatch window shows a cycle counter and a re-settable counter. The cycle counter is the same as the one in the register window. It basically counts instructions.
The other counter counts at the same rate as the cycle counter, but can be cleared by clicking the "clear" button (or preset by entering a number in the entry box).
The up/down indicator denotes the direction the counter counts.
The rollover value specifies the range the cycle counter can be in (a modulo counter). For example, if the rollover value is specified to be 0x42, then whenever the resettable counter reaches 0x42 it will rollover to zero. If the counter is counting down, then when it reaches 0 the next state will be 0x41. If you don’t want is like this, then set the rollover value to something large.

3.11 Scope Window

FIXME: The scope window still needs some work...
The Scope Window graphs I/O pin states. It is similar to an oscilloscope or logic analyzer. It can be controlled either from the command line or from the GUI. Currently only the digital state of I/O pins are supported.
To use the scope window, each scope channel being used must first be connected to the stimulus being tracked. This can only be done on the command line (or via the .sim directive in the .asm file). The following example shows how this is done, but note that in the .sim command the ’”’s need to be escaped with a ’\’.
**gpsim> scope.ch0 = “portc3”
**gpsim> scope.ch1 = “portc4”
Once the data are captured, the scope window display may need to be altered to better see the data. In the GUI, the following keys can be used:
z Zoom In
Z Zoom out
l Pan left
r Pan right
In the command line, zooming and panning can be achieved by modifying the scope.start and scope.end variables.

4 Scripting and Configuring

gpsim does not have a native scripting language per se. However it is possible to place gpsim commands into a file and load them later. This is useful for loading modules and stimuli and connecting various devices together. By convention, gpsim’s configuration files have the extension .stc, for startup configuration.

4.1 Embedded Commands

If you’re using gputils, it is possible to embed configuration commands directly into your PIC assembly source. The gputils supplied include file coff.inc contains several macros that embed simulation command into a COFF and COD files.

4.1.1 .sim macro

; Simulator Command
.sim macro x
  .direct "e", x
  endm
The .sim macro allows gpsim configuration commands to be embedded in the PIC source. While gpsim loads a .cod file, the commands in the .sim macros are collected. After the .cod file is loaded, the commands are redirected to gpsim’s command line interpreter in the order they were received.
Here’s an example of switch module being loaded and configured:
 ;# Module libraries:
 .sim "module library libgpsim_modules"
 .sim "module load switch SW1"
 .sim "SW1.state=false"
 .sim "SW1.xpos = 216.0"
 .sim "SW1.ypos = 156.0"
 .sim "SW1.Ropen = 1.0e8"
This loads gpsim’s module library, instantiates a switch module, and configures the switch’s attributes.

4.1.2 .command macro

.command macro x
  .direct "c", x
  endm
The .command macro is similar to a .sim macro except that it associates a gpsim command with a particular instruction. This is useful for changing attribute values at different points of the program.

4.1.3 .assert macro

; Assertion
.assert macro x
 .direct "a", x
 endm
The .assert macro provides a source code mechanism for setting breakpoints (see chapter 5↓). An assertion is an expression associated with a specific instruction. It essentially means, “If the expression at this instruction evaluates to false, then halt the simulation.”
   ; Close the switch. Because of capacitance, portc1 will go high after a delay:
   ; R=145, C=4.2e-6 TC=6.11e-4 or 1527 cycles, 0-2 volts requires 0.51 Tc
   .command "SW1.state=closed"
        nop
        ; portc0 should be same as portc1
   .assert "(portc & 3) == 0, \"SW1 closed, cap holds low\""
        nop

In this example, the .command macro writes to the switch module’s .state attribute (see section 8.1.4↓). Just prior to executing the first nop instruction, the switch will be closed. The .assert macro at the very next instruction makes sure that the expected state is seen on PORTC.

4.2 Sockets

gpsim supports a socket interface. This is inhibited by default. Advanced users may wish to study code in the examples/scripts subdirectory. This code is not distributed and is only available in the subversion repository.

5 Assertions and Extended Breakpoints

gpsim supports a wide variety of breakpoints and assertions. Many of these were described with the break command. This section will illustrate how to extend the break command even further and introduce simulation assertions.

Breakpoint Messages

A breakpoint message is an ASCII string that is displayed whenever a breakpoint is encountered. Any break point can have an associated message. The syntax at the command line is
break conditions, “This is a breakpoint message
The conditions are described above in the break command and are the conditions under which the break occurs.
Breakpoint messages are useful for distinguishing among many different breakpoints.
break w counter & 0xf0 == 0x80, “Counter overflowed!”
In this example, the user is monitoring the upper nibble of the variable counter and breaking whenever it is equal to 8. When the command is entered, gpsim will display:
break when bit pattern 1000XXXX is written to register counter(0x26). break #: 0x20 
The breakpoint can be queried with the break command:
gpsim> break 32
32: p18f452 register write value: [0x26] & 0xf0 == 0x8
    Message:Counter overflowed!
When the simulation encounters the break, execution halts and the message is printed.

5.1 Assertions and Embedded Simulation commands

gpsim’s breakpoint design is a powerful tool that can catch many problems. The assertion design extends this power even further. An assertion is like a breakpoint that is defined in the program source code for a particular instruction. gpsim reads the breakpoint from a special message area in the .cod file. For example, you may have a routine that requires BANK 0 be selected. A gpsim assertion can be placed at the entry of the routine to verify that this is the case.
    .assert  "(status & 0x60) == 0, \"Bank 0 must be selected!\""
The syntax is identical to the extended breakpoint command. The expression is the condition that is checked. If the expression evaluates to false, then the code halts and prints the message. The .assert is a macro that is part of gputils. It requires a string as its input argument. Notice that the assertion message is embedded in the argument. gpasm and MPASM copy C’s method of placing a backslash in front of quotations that are part of a string.

Command Assertions

A command assertion is a gpsim associated with a particular instruction in your PIC source code. These are useful for changing the behavior of the simulation based on where the code executes. Almost any gpsim command can be placed in a command assertion. However, the most useful ones are assignment commands. For example:
.command “SW1.state = open”
This assignment writes to the state attribute of a switch module named SW1.

6 Trace and Log: What has happen?

Inspecting the current state of your program is sometimes insufficient to determine the cause of a bug. Often times it’s useful to know the conditions that led up to the current state. gpsim provides a history or trace of everything that occurs - whether you want it or not - to help you diagnose these otherwise difficult to analyze bugs.
What’s traced notes
program counter addresses executed
instructions opcode
register read value and location
register write value and location
cycle counter current value
skipped instructions addresses skipped
status register during implicit modification
interrupts
break points type
resets type
The ’trace’ command will dump the contents of the trace buffer.
A large circular buffer (whose size is hard coded) stores the information for the trace buffer. When it fills, it will wrap around and write over the old history. The contents of the trace buffer are parsed into frames, where one frame corresponds to a simulation cycle.
Here’s an example of a trace output:
gpsim> trace
0x00000000000026F6 p18f452 0x001C 0x1003 iorwf  reg3,w,0
   Read: 0x00 from reg3(0x0003)
  Wrote: 0xE7 to W(0x0FE8) was 0xE7
  Wrote: 0x18 to status(0x0FD8) was 0x18
0x00000000000026F7 p18f452 0x001E 0xE1F4 bnz    $-0x16  ;(0x8)
0x00000000000026F8 p18f452 0x0008 0x3E00 incfsz reg,f,0
   Read: 0xE4 from reg(0x0000)
  Wrote: 0xE5 to reg(0x0000) was 0xE4
0x00000000000026F9 p18f452 0x000A 0xD004 bra    $+0xa   ;(0x00014) 0x00000000000026FA p18f452 0x0014 0x0004 clrwdt
0x00000000000026FB p18f452 0x0016 0x5000 movf   reg,w,0
   Read: 0xE5 from reg(0x0000)
  Wrote: 0xE5 to W(0x0FE8) was 0xE7
  Wrote: 0x18 to status(0x0FD8) was 0x18
0x00000000000026FC p18f452 0x0018 0x1001 iorwf  reg1,w,0
   Read: 0x03 from reg1(0x0001)
  Wrote: 0xE7 to W(0x0FE8) was 0xE5
  Wrote: 0x18 to status(0x0FD8) was 0x18 
Each trace frame begins with a new simulation cycle. Typically this will include a simulated instruction. Here’s each of the fields:
64-bit simulation cycle processor PC opcode instruction
0x00000000000026F6 p18f452 0x001C 0x1003 iorwf reg3,w,0
Other events that occur during the trace frame are indented. Typically these will be register read or write traces. The read traces show the value read. Write traces show the value written and the value that was previously in the register.

Saving Trace to a file

The trace buffer may contain thousands of entries making it difficult to search. The trace save feature will allow the trace buffer to be written to a file.
gpsim> trace save mytrace.log
The entire contents of the trace buffer are decoded and written to the file. The format of the trace is the same as it is when displayed at the command line.

Raw Traces

The raw trace buffer is the trace buffer displayed in a minimally decoded form. This is primarily used for gpsim development. When saved to a file, the raw trace is not decoded at all. In addition, the processor’s state is written to the file. Thus third party tools can be written to create custom trace reports [E]  [E] FIXME - The dynamically created trace type information needs to be written to this file too. Without it, it is difficult to tell what each traced item is..

7 Simulating the Real World: Stimuli

Stimuli are extremely useful, if not necessary, for simulations. They provide a means for simulating interactions with the real world.
The gpsim stimuli capability is designed to be accurate, efficient and flexible. The models for the PIC’s I/O pins mimic the real devices. For example, the open collector output on port A of a PIC16C84 can only drive low. Multiple I/O pins may be tied to one another so that the open collector on port A can get a pull up resistor from port B. The overhead for stimuli only occurs when a stimulus changes states. In other words, stimuli are not polled to determine their state.
Analog stimuli are also available. It’s possible to create voltage references and sources to simulate almost any kind of real world thing. For example, it’s possible to combine two analog stimuli together to create signals like DTMF tones.
Note, however, that gpsim does not attempt to be a full electronic circuit simulator, and certain approximations made for efficiency will cause inaccuracy in complex simulation environments.

7.1 How They Work

In the simplest case, a stimulus acts a source for an I/O pin on a PIC. For example, you may want to simulate a clock and measure its period using TMR0. In this case, the stimulus is the source and the TMR0 input pin on the pic is the load. In gpsim you would create a stimulus for the clock using the stimulus command and connect it to the I/O pin using the node command.
In general, you can have several ’sources’ and several ’loads’ that are interconnected with nodes [F]  [F] Although, gpsim is currently limited to ’one-port’ devices. In other words, it is assumed that ground serves as a common reference for the sources and the loads.. A good analogy is a spice circuit. The spice netlist corresponds to a node-list in gpsim and the spice elements correspond to the stimuli sources and loads. This general approach makes it possible to create a variety of simulation environments. Here’s a list of different ways in which stimuli may be connected:
  1. Stimulus connected to one I/O pin
  2. Stimulus connected to several I/O pins
  3. Several stimuli connected to one I/O pin
  4. Several stimuli connected to several I/O pins
  5. I/O pins connected to I/O pins
The general technique for implementing stimuli is as follows:
  1. Define the stimulus or stimuli.
  2. Define a node.
  3. Attach the stimuli to the node.
More often than not, the stimulus definition will reside in a file.

7.1.1 Contention among stimuli

One of the problems with this nodal approach to modeling stimuli is that it’s possible for contention to exist. For example, if two I/O pins are connected to one another and driving in the opposite directions, there will be contention. gpsim resolves contention with attribute summing. Each stimulus - even if it’s an input - has an effect on the node. This effect is characterised by a voltage and an impedance. When a node is updated, gpsim performs a Thevenin voltage summing of all the stimuli together. The resultant voltage is then propagated to all connected stimuli as the current state of the node.
For example, in the port A open collector / port B weak pull-up connection example, gpsim assigns a voltage of 5V with an impedance of 20kohms to the pull up resistor, and a voltage of 0V with an impedance of 150ohms to the open collector if it is active, or 100Mohms if it’s not driving. The Thevenin sum will be roughly 0.05V if the output is driving, or 5V otherwise. Capacitive effects are not currently supported.

7.2 I/O Pins

gpsim models I/O pins as stimuli. Thus anywhere a stimulus is used, an I/O pin may be substituted. For example, you may want to tie two I/O pins to one another; like a port B pull up resistor to a port A open collector. gpsim automatically creates the I/O pin stimuli whenever a processor is created. All you need to do is to specify a node and then attach the stimuli to it. The names of these stimuli are formed by concatenating the port name with the bit position of the I/O pin. For example, bit 3 in port B is called portb3.
Here’s a list of the types of I/O pin stimuli that are supported:
I/O Pin Type Function
INPUT_ONLY Only accepts input (like MCLR)
BI_DIRECTIONAL Can be a source or a load (most I/O pins)
BI_DIRECTIONAL_PU PU=Pullup resistor (PORTB)
OPEN_COLLECTOR Can only drive low (RA4 on c84)
There is no special pin type for analog I/O pins. All pic analog inputs are multiplexed with digital inputs. The I/O pin definition will always be for the digital input. gpsim automatically knows when I/O pin is analog input.

7.3 Asynchronous Stimuli

Asynchronous stimuli are analog or digital stimuli that can change states at any given instant (limited to the resolution of the cycle counter). They can be defined to be repetitive too.
parameter function
start_cycle The # of cycles before the stimulus starts
cycles[] An array of cycle #’s
data[] Stimulus state for a cycle
period The # of cycles for one period
initial_state The initial state before data[0]
When the stimulus is first initialized, it will be driven to the ’initial state’ and will remain there until the cpu’s instruction cycle counter matches the specified ’start’ cycle. After that, the two arrays ’cycles[]’ and ’data[]’ define the stimulus’ outputs. The size of the arrays are the same and correspond to the number of events that are to be created. So the event number, if you will, serves as the index into these arrays. The ’cycles[]’ array define when the events occur while the ’data[]’ array defines the states the stimulus will enter. The ’cycles[]’ are measured with respect to the ’start’ cycle. The asynchronous stimulus can be made periodic by specifying the number of cycles in the ’period’ parameter.
Here’s an example that generates three pulses and then repeats:
stimulus asynchronous_stimulus # or we could have used asy

# The initial state AND the state the stimulus is when
# it rolls over

initial_state 1

# all times are with respect to the cpu’s cycle counter
start_cycle 100

# the asynchronous stimulus will roll over in ’period’
# cycles. Delete this line if you don’t want a roll over.
period 5000

# Now the cycles at which stimulus changes states are 
# specified. The initial cycle was specified above. So 
# the first cycle specified below will toggle this state. 
# In this example, the stimulus will start high. 
# At cycle 100 the stimulus ’begins’. However nothing happens
# until cycle 200+100.
{ 200, 0,
  300, 1,
  400, 0,
  600, 1,
  1000, 0, 
  3000, 1 }

# Give the stimulus a name:
name asy_test

# Finally, tell the command line interface that we’re done
# with the stimulus
end

7.3.1 Analog Asynchronous Stimuli

Analog Asynchronous Stimuli are identical to Synchronous Stimuli except the data points are floating point numbers.

7.4 Extended Stimuli

Discuss the extended stimuli in the modules/ directory. In particular, describe the PulseGen module and how it can complete replace the asynchronous stimuli. Also describe the PullUp and PullDown modules and how they can be manipulated into being general purpose DC voltage sources (FIXME, would it make sense to rename these modules?).

7.5 Limitations of the Stimulus Mechanism

The simulation of external devices using gpsim stimuli and nodes is intended to assist in PIC software debugging, not electronic circuit design. As such it takes a simplified approach to certain things.

7.5.1 Propagation Delays

gpsim makes no attempt to simulate propagation delays in the circuit. Usually this is not a problem. However, when using modules8↓ to expand gpsim’s environment, it is possible to create situations where it matters. For example, daisy-chaining two or more shift registers with a shared clock relies on the propagation delay of the first register to ensure the second shifts the correct data in. Since gpsim does not simulate this delay, the results may be wrong [G]  [G] They may be right, it depends on execution order, which is subtle..

8 Modules

gpsim has been designed to debug microprocessors. However, microprocessors are always a part of a system. And invariably, the bugs one often encounters are those that are a result of interfacing with a system. Modules provide users with a way to extend gpsim and simulate a system. For example, the system may be a processor with a few pull up resistors and switches or it may be a processor and an LCD display. gpsim provides a few modules that one may use either for debugging or as templates for creating new modules.
Note that gpsim’s modules are provided to facilitate debugging of the PIC code, not the hardware. gpsim does not attempt to be a circuit simulator by itself. If you need that functionality, the gpsim core can be embedded into third party simulators.
Modules reside in a library and are dynamically loaded with the module command. All modules have I/O pins which can connect to other modules or processors. Most modules provide attributes that allow the user to control a module’s behavior or query its internal state. For example, the USART module has transmit and receive baud rate attributes that may be configured:
gpsim> U1.txbaud = 9600   # set the transmit rate
gpsim> U1.rxbaud          # query the receiver rate
9600
The symbol command can be used to query all attributes of a module.
gpsim> symbol U1.     # note the period
U1 = USARTModule
U1.console = false
U1.crlf = true
U1.loop = true
U1.rx = 0
U1.rxbaud = 9600
U1.tx = 0
U1.txbaud = 9600
U1.xpos = 72.00000000000000
U1.ypos = 276.0000000000000

Modules may provide help which can be accessed using the help command:
gpsim> help U1
USARTModule
no description
Well, the USART module isn’t the best example here! However, a better example is one of the USART attributes.
gpsim> help U1.txbaud
9600
USART Module Transmitter baud rate

8.1 gpsim Modules

gpsim provides a library of useful modules for simulation. The current version includes the following modules:
pushbutton
pullup A resistor connected (nominally) to Vdd
pulldown A resistor connected (nominally) to Vss
usart A serial interface with a GUI terminal window
pulsegen
I2C-EEPROM2K A 256 byte I2C serial EEPROM like the 24LC024.
I2C-EEPROM16K A 2k byte I2C serial EEPROM like the 24LC16B.
I2C-EEPROM256K A 32k byte I2C serial EEPROM like the 24LC256.
i2c2par A slave I2C device with an 8 bit I/O port
switch Switch, which connects two nodes together
and2 2-input logical AND gate
or2 2-input logical OR gate
xor2 2-input logical XOR gate
not Inverter (logical NOT gate)
led_7segments A 7-segment LED digit
led A single pin LED which can be active either high or low
TTL377 A 74xx377 style 8-bit tristate latch
TTL165 A 74xx165 parallel-in-serial-out shift register
TTL595 A 74xx595 serial-in-parallel-out shift register

8.1.1 USART

The USART module is a full duplex configurable USART. In graphics mode, the USART will display its output in a console. In addition, the console will accept keyboard input.

Attributes

.tx - The .tx attribute is the USART transmit register. Data written to this attribute will initiate a transmission. The USART supports a transmit FIFO, making it possible to stuff several bytes into the transmit queue while the program under test is paused.
.rx - The .rx attribute is the USART receiver register. Data received by the USART is available for querying through here.
.txbaud - The .txbaud attribute specifies the transmitter baud rate.
.rxbaud - The .rxbaud attribute specifies the receiver baud rate.
.console - When set to true, the console window will display received data and will accept keyboard entries for the transmitter.
.crlf - When set to true, carriage returns and line feeds generate new lines in the console window.
.hex - When set to true, the data is assumed to be binary and all bytes are shown in hex.
.loop - When set to true, received characters are looped back to the transmitter.
.xpos - horizontal position in breadboard window.
.ypos - vertical position in breadboard window.

I/O Pins

.TXPIN - transmit pin
.RXPIN - receiver pin
.CTS - Clear to send pin. This can be left unconnected
.RTS - Request to send pin.

8.1.2 Logic

The only attributes supported be the logic devices are the standard .xpos and .ypos breadboard positions. FIXME There should be attributes to specify the switching characteristics.

and2 - Two input AND gate

I/O pins

.in0 - First input
.in1 - First input
.out - Output

or2 - Two input OR gate

.in0 - First input
.in1 - First input
.out - Output

xor2 - Two input XOR gate

.in0 - First input
.in1 - First input
.out - Output

not - Inverter

.in0 - Input
.out - Output

TTL377 - Octal Latch

The TTL377 module simulates an 8-bit parallel latch with output enable. It latches all bits simultaneously so that connecting an output to an input gives correct results. However, this is not guaranteed where multiple modules are so connected.
.D0..7 - Input
.Q0..7 - Output
.E - output enable
.CP - clock (rising edge)

TTL165 - Parallel to Serial Shift Register

The TTL165 module simulates an 8-bit parallel input serial output shift register. It is particularly useful for connecting to a SPI peripheral. Note, however, that the common practice of daisy-chaining such shift registers is not guaranteed to simulate correctly.
.D0..7 - parallel input
.Ds - daisy-chain serial input
.Q7 - output
.nQ7 - inverted output
.CE - clock enable
.CP - clock (rising edge)
.PL - parallel load

TTL595 - Serial to Parallel Shift Register

The TTL595 module simulates an 8-bit serial input parallel output shift register. It is particularly useful for connecting to a SPI peripheral. Note, however, that the common practice of daisy-chaining such shift registers is not guaranteed to simulate correctly.
.Q0..7 - parallel output
.Ds - serial input
.Qs - daisy-chain serial output
.OE - output enable
.SCK - shift clock (rising edge)
.RCK - output latch clock (rising edge)
.MR - master reset

8.1.3 I2C EEPROM

There are currently three I2C EEPROMs supported: I2C-EEPROM2k, I2C-EEPROM16k, and I2C-EEPROM256K.
The commands ’dump e module_name filename’ and ’load e module_name filename’ can be used to save and restore the contents of the EEPROM module. This allows the contents of the EEPROM to be preserved between runs of gpsim.
The cells of the EEPROM can be examined and modified using the command interface with the commands ’module_name.eeData[index]’ and ’module_name.eeData[index] = new_value’. The following example shows loading an EEPROM module, setting cell 16 to ’0’ (0x30) and checking that the new value was written.
**gpsim> module load I2C-EEPROM16k e2 
**gpsim>  
**gpsim> e2.eeData[16] = $30 
**gpsim> e2.eeData[16] 
e2.eeData[$10] = $30
**gpsim>  

I/O Pins

.A0 - Chip select to set bit 0 of slave address
.A1 - Chip select to set bit 1 of slave address
.A2 - Chip select to set bit 2 of slave address
.SCL - I2C serial clock
.SDA - I2C serial data
.WP - Hardware write protect

8.1.4 Switches & Resistors

The switch module is a model of a simple two terminal switch. It may be controlled either from the command line or the breadboard GUI. The switch module’s open and closed resistance are controlled by attributes. Thus a two terminal resistor can be modeled as a switch that is always closed (or open).

Attributes

.Ropen - Switch resistance in ohms when the switch is opened.
.Rclosed - Switch resistance in ohms when the switch is closed.
.state - Switch state. The switch state takes the values of open or closed, although false for open and true for closed is supported for backward compatibility. The .state attribute is writable.

I/O Pins

.A - One side
.B - The other side

8.1.5 Voltage Sources, Resistors, and Capacitors

The pullup and pulldown modules are two terminal devices with one terminal tied to a voltage source. Their voltage, resistance, and pin capacitance are controllable via attributes.

Attributes

.voltage - DC voltage
.resistance - resistance in ohms between the I/O pin and the voltage source.
.capacitance - capacitance in farads between the I/O pin and ground.

I/O Pins

.pin - the only pin exposed.

8.1.6 LED_7SEGMENTS and LED

led_7segments - 7 segment common cathode LED display

The segments are numbered as per the following figure.
   ___
5 | 0 | 1
   ___
4 | 6 | 2
   ___
    3

I/O Pins

.cc - common cathode
.seg0 - segment 0
.seg1 - segment 1
.seg2 - segment 2
.seg3 - segment 3
.seg4 - segment 4
.seg5 - segment 5
.seg6 - segment 6

Led - Simple LED

The simple LED is a single pin module internally tied to either Vss or Vdd.By default the LED is internally tied to Vdd(0V) and turns on when the pin is driven high.However, by setting the ActiveState parameter to low, the LED is internally tied to Vss(5V) and turns on when the pin is driven low.Like a real LED, the module will either sink or source current from the driving line which may affect its logic level.
The LED color is by default red, but can be set to other colors.

Attributes

color - LED color, possible values red, green, yellow, orange or blue
ActiveState - LED active state mode, possible values: high or low

I/O Pin

.in - drives LED

8.1.7 I2C slave to Parallel port

The i2c2par is a 7 bit address I2C module with an 8 bit I/O port. The direction of the I/O port is determined from I2C R/W bit. When R/W is zero the I/O port outputs the data sent by the master device. Otherwise the port is set as an input port and when the master device requests data, the port is read and transmitted to the master.

Attributes

.Slave_Address - I2C 7 bit device address

I/O Pins

.p0..7 - I/O pins
.SDA - I2C serial data
.SCL - I2c serial clock

8.2 Extras Modules

In addition to the standard modules, modules largely supplied by third parties are supplied in the libgpsim_extras library.
Name Alias Description
dht11 dht11 Temperature and humidity sensor
DS1307 ds1307 64 x 8, Serial, I2C Real-Time Clock
DS1820 ds1820 High-Precision 1-Wire Digital Thermometer
DS18S20 ds18s20 High-Precision 1-Wire Digital Thermometer
DS18B20 ds18b20 High-Precision 1-Wire Digital Thermometer
lcd_display lcd_2X20 LCD - HD44780 2X20
lcd_20x4 lcd_20x4 LCD - HD44780 4x20
lcd_dt161A lcd_2X8 LCD - HD44780 2x8
LCD100X32 LCD100X32 LCD - SED1530 100x32
OSRAM128X64 OSRAM128X64 LCD - SSD0323 128x64
lcd_7Seg lcd_7seg LCD - 7 segment no controler
Solar Solar Solar Panel, Controler, Battery

8.2.1 Temperature and humidity sensor - DHT11

This module emulates the DHT11 temperature/humidity sensor using a single-wire interface.

Attributes

temperature - Temperature degree C * 100
humidity - Relative humidity % * 100

I/O Pins

.pin - Serial I/O pin

8.2.2 64 x 8, Serial, I2C Real-Time Clock - DS1307

This module emulates the Dallas Semiconductor DS1307 Real-Time clock which also has 56 x 8 eeprom memory and connects via an I2C serial bus.

I/O Pins

.SDA - Serial Data Line I/O pin
.SCL - Serial Clock Line I/O pin
.SQW - Square Wave Output

8.2.3 High-Precision 1-Wire Digital Thermometer - DS1820 Family

These modules emulate the DS1820, DS18S20 and DS18B20 High-Precision 1-Wire Digital Thermometers.These devices uses a single-wire bus interface.

Attributes

ROMCode - Device ROM code
temperature - Temperature of device
powered - Device is self powered
alarm_th - Temperature high alarm register
alarm_tl - Temperature low alarm register
config_register - Value of configuration register (ds18B20 only)

I/O Pins

.pin - Serial I/O pin

8.2.4 Character LCD - HD44780

The library libgpsim_lcd contains several LCD display formats using the HD44780 controller.
Name Description
lcd_display 20 col 2 row LCD
lcd_20x4 20 col 4 row LCD
lcd_dt161A 16 col 1 row LCD

I/O Pins

.DC - Data / command select
.RW - Read/Write select
.E - start data read/write
.d0-7 - data bus

8.2.5 Graphic LCD - SED1530

This module emulates a 100X32 pixel graphics LCD based on dual SED1350 controllers.

8.2.6 LCD_7Seg

A 7 segment LCD display without a controller. If common > 2.5V, (cc- segn) > 1.4V segment is on otherwise segment is off.
The segments are numbered as per the following figure.
   ___
5 | 0 | 1
   ___
4 | 6 | 2
   ___
    3

I/O Pins

.cc - common
.seg0-6 - 7 segment drives

8.2.7 Solar

This module emulates a 20 Watt solar panel, a 20mah battery, and a PWM controler for testing control strategies for the controler.

Attributes

Aoffset - Voltage on Asol pin for zero panel current
Ascale - Voltage/Amp panel current scale factor for Asol
VSscale - scale factor for Vsol pin
VBscale - scale factor for Vbat pin
inductor - controler inductor size in Henries
BDOC - Battery degree of charge %

I/O Pins

.Vsol - Solar Panel output Voltage
.Asol - Solar Panel output current
.Vbat - Battery Voltage
.PWM - Pulse Width Modulation signal
.OK - PWM is enabled

8.3 Writing new modules

A module is a library of code. On Windows the library is a .DLL and on Unix a shared library. There are a few details that a module must adhere to, but in general the module has full access to gpsim’s API.
The easiest way to write a new module is to start from the source code from one of the existing modules. For example, suppose your project produces a serial bit-stream in PPM coding and you want to display the output during the simulation. The external module you need is similar to the usart module but not the same, so start by making a copy of the usart module and then modify it to work how you need.
To be able to load your module into gpsim it needs to be in a library. Usually you will be creating a new library just for one device, but sometimes you will have a few devices. Either way, the library must declare to gpsim what devices it contains. This is achieved with an array of Module_Types class instances, returned to gpsim by a function named “get_mod_list”. All gpsim module libraries must declare this function. You can copy the required template from the gpsim source – probably one of the “extras” modules is slightly cleaner than the main library. For our PPM decoder example, we might have a module_manager.cc containing the following code:
/* IN_MODULE should be defined for modules */
#define IN_MODULE

#include <stdio.h>
#include <gpsim/modules.h>
#include "ppm.h"

Module_Types available_modules[] =
{
  { "ppm_display", "ppm_rx_iface", PpmDisplay::construct},
  // No more modules
  { NULL,NULL,NULL}
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*****************************************************************
 * get_mod_list - Report all of the modules in this library.
 *
 * This is a required function for gpsim compliant libraries.
 */
  Module_Types * get_mod_list(void)
  {
    return available_modules;
  }
#ifdef __cplusplus
}
#endif /* __cplusplus */

This declares that this library provides one module, called ppm_display, implemented by the C++ class PpmDisplay. The class which implements the module must provide a static method “construct” to create a new instance of the class. For example:
Module * PpmDisplay::construct(const char *_new_name=0)
{
    PpmDisplay *ppmd = new PpmDisplay(_new_name);
    ppmd->create_iopin_map();
    ppmd->create_window(_new_name);
    return ppmd;
}
Your module will need to include stimuli for its I/O connections. You can use the standard gpsim stimulus classes: IOPIN, io_bidirectional, io_bidirectional_pu, io_open_collector. In many cases, however, you will want to derive your own class from one of them. This will allow you to customise the actions when the node state changes. For example:
class DecoderPin : public IOPIN
{
private:
    PpmDisplay * Parent;
public:
    DecoderPin ( PpmDisplay * parent, unsigned int b, const char * name=0 );
    virtual void setDrivenState(bool new_state);
};
The only methods we provide here are the constructor and an overridden “setDrivenState”. This is because our PPM decoder needs to be told when the input pin changes state.

9 Symbolic Debugging

gpsim maintains a symbol table.
<write me>

10 Macros

<write me>

11 Hex Files

The target code simulated by gpsim can be supplied by a hex file, or more specifically an Intel Hex file. gpsim accepts the format of hex provided by gpasm and mpasm. The hex file does not provide any symbolic information. It’s recommended that hex files only be used if 1) you suspect there’s a problem with the way .cod files are generated by your assembler or compiler OR 2) your assembler or compiler doesn’t generate .cod files. Also, you must supply a processor when loading hex files. See the load command.

12 The ICD- Not Supported in versions 0.21.0 and later

gpsim supports (partly) the first version of the ICD (as opposed to ICD2 (the round hockey-puck shaped one)).

Special configuration of the code

Read the MPLAB ICD USER’s GUIDE.
Here’s the short version:

icdprog

Download and install icdprog.
Use icdprog to program the target with the hex file (icdprog mycode.hex).

ICD usage

Start gpsim like this:
gpsim -d /dev/ttyS0 -s mycode.cod
, assuming the ICD is connected to the first serial port.
Now you can type ’icd’ to see some information:
**gpsim> icd
ICD version "2.31.00" was found.
Target controller is 16F877 rev 13.
Vdd: 5.2 Vpp: 13.3
Debug module is present
2.31 is the firmware version. I have only tried this particular version...
You can step, reset, run, halt, set the breakpoint and read file registers. It works both from the GUI and the cli.

ICD TODO

13 Examples

The examples/ subdirectory contains several examples. The examples/projects/ subdirectory demonstrate sample projects that can serve as templates for new projects. In addition, the examples/modules subdirectory contains several examples illustrating how to use gpsim’s various modules. Finally, as described in chapter , gpsim’s regression tests illustrate many powerful debugging techniques that have not been fully documented.

usart_gui example

Each example contains a brief README explaining its purpose. For example, the README for the usart_gui example in the examples/modules directory contains
The tests the USART module with the GUI fix.

The code for a 16f628 PIC is used. The code first transmits a string of
characters, which are instructions to the user, to the USART module which
will then be displayed on its GUI. This verifies that the USART can receive
serial data.

When the focus is on the USART GUI window, characters typed on the keyboard
are sent from the USART to the PIC and then retransmitted from the PIC back
to the USART.

If all works, the typed characters will be displayed in the GUI text window
of the USART. Both transmit and receive must be functioning for this to
happen.
Fixme - we really need to document all of the examples!

14 Regression Tests

Starting with version 0.22.0, gpsim distributes regression tests. The purpose of a regression test is to validate correctness. The tests are designed to exercise many of the aspects of gpsim and gpsim’s modules. While designed primarily for developers, the regression tests also serve as a rich source of examples. There are many features gpsim’s developers will tuck away into a regression test and fail to document!

15 Theory of Operation

This section is only provided for those who may be interested in how gpsim operates. The information in here is ’mostly’ accurate. However, as gpsim evolves so do the details of the theory of operation. Use the information provided here as a high level introduction and use the (well commented :]) source to learn the details.

15.1 Background

gpsim is written mostly in C++. Why? Well the main reason is to easily implement a hierarchical model of a pic. If you think about a microcontroller, it’s really easy to modularize the various components. C++ lends itself well to this conceptualization. Furthermore Microchip, like other microcontroller manufacturers, has created families of devices that are quite similar to one another. Again, the C++ provides ’inheritance’ that allows the relationships to be shared among the various models of pics.

15.2 Instructions

There’s a base class for the 14-bit instructions (I plan to go one step further and create a base class from which all pic instructions can be derived). It primarily serves two purposes: storage that is common for each instruction and a means for generically accessing virtual functions. The common information consists of a name - or more specifically the instruction mnemonic, the opcode, and a pointer to the processor owning the instruction. Some of the virtual functions are ’execute’ and ’name’. As the hex file is decoded, instances of the instructions are created and stored in an array called program_memory. The index into this array is the address at which the instruction resides. To execute an instruction the following code sequence is invoked:
program_memory[pc->value]->execute();
which says, get the instruction at the current program index (pc->value) and invoke via the virtual function execute(). This approach allows execution break points to be easily set. A special break point instruction can replace the one residing in the program memory array. When ’execute’ is called the break point can be invoked.

Program memory

Note that in the above discussion, the pc->value is referred to as the “program index”. On the 12-bit and 14-bit PIC cores this is unambiguous as the program memory is instruction-word-wide and the program counter increments by one for each instruction. On the PIC17 and PIC18 cores, however, the program memory is accessible through the TBLPTR in byte-wide form. The program counter increments by two for each instruction.
The program_memory array in gpsim is always an array of instructions. Thus the pc->value on a PIC18 is an index whose value is half of the PC register-triple value.

15.3 General File Registers

A file register is simulated by the ’file_register’ class. There is one instance of a ’file_register’ object for each file register in the PIC. All of the registers are collected together into an array called ’registers’ which is indexed by the registers’ corresponding PIC addresses. The array is linear and not banked like it is in the PIC. (Banking is handled during the simulation.)

15.4 Special File Registers

Special file registers are all of the other registers that are not general file registers. This includes the core registers like status and option and also the peripheral registers like eeadr for the EEPROM. The special file registers are derived from the general file registers and are also stored in the ’registers’ array. There is one instance for each register - even if the register is accessible in more than one bank. So for example, there’s only one instance for the ’status’ register, however it may be accessed through the ’registers’ array in more than one place.
All file registers are accessed by the virtual functions ’put’ and ’get’. This is done for two main reasons. First, it conveniently encapsulates the breakpoint overhead (for register breakpoints) in the file register and not in the instruction. Second, and more important, it allows derived classes to implement the put and get more specifically. For example, a ’put’ to the indf register is a whole lot different than a put to the intcon register. In each case, the ’put’ initiates an action beyond simply storing a byte of data in an array. It also allows the following code sequence to be easily implemented:
movlw   trisa   ;Get the address of tris 
movwf   fsr 
movf    indf,w  ;Read trisa indirectly

15.5 Example of an instruction

Here’s an example of the code for the movf instruction that illustrates what has been discussed above. Somewhere in gpsim the code sequence:
program_memory[pc->value]->execute();
is executed. Let’s say that the pc is pointing to a movf instruction. The ->execute() virtual function will invoke MOVF::execute. I’ve added extra comments (that aren’t in the main code) to illustrate in detail what’s happening.
void MOVF::execute(void)
{
  unsigned int source_value;
 
  // All instructions are ’traced’ (discussed below). It’s sufficient 
  //to only store the opcode. However, even this may be unnecessary since 
  //the program counter is also traced. Expect this to disappear in the 
  //future... 
  trace.instruction(opcode);
 
  // ’source’ is a pointer to a ’file_register’ object. It is initialized 
  //by reading the ’registers’ array. Note that the index depends on the 
  //’rp’ bits (actually just one bit) in the status register. Time is
  // saved by caching rp as opposed to decoding the status register.
  source = cpu->registers[cpu->rp | opcode&REG_IN_INSTRUCTION_MASK];
 
  // We have no idea which register we are trying to access and how it 
  //should be accessed or if there’s a breakpoint set on it. No problem,
  //the virtual function ’get’ will resolve all of those details
  // and ’do the right thing’.
  source_value = source->get();
 
  // If the destination is W, then the constructor has already initialized 
  //’destination’. Otherwise the destination and source are the same.
  if(opcode&DESTINATION_MASK)
    destination = source;      // Result goes to source
 
  // Write the source value to the destination. Again, we have no idea 
  // where the destination may be or
  // or how the data should be written there.
  destination->put(source_value);
 
  // The movf instruction will set Z (zero) bit in the status register
  //if the source value was zero.
  cpu->status.put_Z(0==source_value);
 
  // Finally, advance the pc by one.
  cpu->pc->increment();
 
}
 

15.6 Trace

Everything that is simulated is traced - all of the time. The trace buffer is one huge circular buffer of integers. Information is or’ed with a trace token and then is stored in the trace buffer. No attempt is made to associate the items in the trace buffer while the simulator is simulating a PIC. Thus, if you look at the raw buffer you will see stuff like: cycle counter = ..., opcode fetch = ..., register read = ..., register write = ..., etc. However, this information is post processed to ascertain what happened and when it happened. It’s also possible to use this information to undo the simulation, or in other words you can step backwards. I don’t have this implemented yet though.

15.7 Breakpoints

Breakpoints fall into three categories: execution, register, and cycle.

Execution:

For execution breakpoints a special instruction appropriately called ’Breakpoint_Instruction’ is created and placed into the program memory array at the location the break point is desired. The original instruction is saved in the newly created breakpoint instruction. When the break point is cleared, the original instruction is fetched from the break point instruction and placed back into the program memory array.
Note that this scheme has zero overhead. The simulation is only affected when the breakpoint is encountered.

Register:

There are at least four different breakpoint types that can be set on a register: read any value, write any value, read a specific value, or write a specific value. Like the execution breakpoints, there are special breakpoint registers that replace a register object. So when the user sets a write breakpoint at register 0x20 for example, a new breakpoint object is created and insert into the file register array at location 0x20. When the simulator attempts to access register location 0x20, the breakpoint object will be accessed instead.
Note that this scheme too has zero overhead, accept when a breakpoint is encountered.

Cycle:

Cycle breakpoints allow gpsim to alter execution at a specific instruction cycle. This is useful for running your simulation for a very specific amount of time. Internally, gpsim makes extensive use of the cycle breakpoints. For example, the TMR0 object can be programmed to generate a periodic cycle break point.
Cycle break points are implemented with a sorted doubly-linked list. The linked list contains two pieces of information (besides the links): the cycle at which the break is to occur and the call back function [H]  [H] A call back function is a pointer to a function. In this context, gpsim is given a pointer to the function that’s to be invoked (called) whenever a cycle break occurs. that’s to be invoked when the cycle does occur. The break logic is extremely simple. Whenever the cycle counter is advanced (that is, incremented), it’s compared to the next desired cycle break point. If there’s NO match, then we’re done. So the overhead for cycle breaks is the time required to implement a comparison. If there IS a match, then the call back function associated with this break point is invoked and the next break point in the doubly-linked list serves as the reference for the next cycle break.

15.8 TIMER1 External input

The timer1 module can support external input, on some processors, as either a crystal using two pins or a single pin drive.

External Crystal

If an external crystal, typically 32,768 KHz, is being used, then both T1OSCEN and TMR1CS in register T1CON should be true. Gpsim will then automatically simulate timer1 being driven at the crystal frequency which can be changed from the default frequency by changing the value of the processor symbol called tmr1_freq.

Single pin drive

If the single pin drive is being used, then the T1CON register bits for T1OSCEN should be false and TMR1CS true, and the T1CKI pin must be driven manually such as by a stimuli command.

16 LICENSES

16.1 Gpsim.lyx

Copyright © 2000-2010
T. Scott Dattalo, Ralf Forsberg, Robert Pearce, Borut Ražem and Roy Rankin
The source of this document is gpsim.lyx.
This document is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License published by the Free Software Foundation; either version 2, or (at your option) any later version.
This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

16.2 Gpsim

The Gpsim program is licensed under version 2 or higher of the GNU General Public License. Details of this license can be found in the COPYING file which should have come with this program. If not the license can be found at http://www.gnu.org/licenses/gpl-2.0.html.

16.3 Libraries libgpsim, libgpsim_modules, libgpsim_eXdbm

The libraries libgpsim, libgpsim_modules, and libgpsim_eXdbm are licensed under version 2.1 of the GNU Lesser General Public License. Details of this license can be found in the COPYING.LESSER file which should have come with the program. If not, the license can be found at http://www.gnu.org/licenses/lgpl-2.1.html.

Index

7SEGMENTS:

Capacitors:

DHT11:

DS1307:

DS1820 Family:

GNU GPL:

HD44780:

I2C EEPROM:

LCD_7Seg:

LED:

Logic:

Modules:

Resistors: ,

SED1530:

Solar:

Stimulus:

Switches:

USART module:

Voltage Sources:

and2:

attach: ,

break: ,

bus:

clear: ,

disassemble: ,

dump: ,

echo:

frequency: ,

help: ,

i2c2par:

icd: ,

instructions:

list: ,

load: ,

log:

macros:

module: ,

node: ,

not:

or2:

processor: ,

quit: ,

registers:

run: ,

set:

step: ,

stimulus: ,

stopwatch: ,

symbol: ,

trace: ,

ttl165:

ttl377:

ttl595:

version:

x: ,

xor2: