Section: User Commands (1)
Updated: July 2012
Return to Main Contents
pb_parse - parser for pulseblaster code: covert pbsrc to vliw.
pb_parse - convert Pulseblaster program to opcodes.
pb_parse -i SOURCE_FILE.pbsrc [ -o OUTPUT_FILE.vliw ]
pb_parse reads in a human-readable (.pbsrc) input file containing a program for
the Spincore PulseBlaster and outputs a pseudo-machine-code (.vliw) file suitable
for loading into the PulseBlaster card.
The parser checks for most errors, and will exit with failure if they are serious.
Non-fatal errors will emit a warning. Please read the warnings!
* Outputs and arguments may be specified in binary, hex, or base-10
* Lengths may be specified in ticks, or in units of ns,us,ms,s,ks,min...weeks
* Where an argument is irrelevant, a '-' is used to make this explicit.
* Permits labels, instead of numeric addresses. Comments are: '//', '/* ... */'.
* Support for #include, #define [#what, #default:, #if, #ifnot].
* Scientific/experimental parameters can be easily varied with -D (and #if/#ifnot).
* Executable includes (#execinc) allow dynamic code generation and complex calculations.
* Outputs can be specified as bitwise changes to the previous values (or SAME).
* Inlined #macros (with parameter substitution), almost acting like functions.
* Use of #set simplifies use of active-low logic on the peripheral.
* Debugging features: #assert, #hwassert, #echo, #endhere.
* "Do what I mean" fixes for infelicities in the instruction set:
* calculates ARG for longdelay if specified as 'auto'
* promotes cont or demotes longdelay if length is out of range.
* zeroloop: loop (0) converted to goto (addr_of(endloop)+1).
* opcode macros: __call/goto/return/loop/endloop can appear instantaneous.
* Case-sensitive (except opcode-names). Alternate opcode mnemonics (eg GOTO vs BRANCH).
* Allows STOP to be overloaded (set outputs). Adds NOP.
* VLIW-reordering: opcode,arg may be written before/inside/after out...len, for clarity.
* Mathematical operators: *,-,+,/,%,(,) Bitwise operators: |,&,~,^,<<,>>
* Comparison operators: ==,!=,<,>,<=,>= Logical: &&,||,!,?,: Error-control: @
* Detailed error checking, with helpful messages. Ensures that all instructions are valid.
* Simulation of the hardware, to verify the program. Options:
* Optimised simulation (full proof of program correctness),
* Output on virtual LEDs, parallel ports, VCD file, and target-simulation logfile.
* Real-time, measurement, single-step, or manual triggering.
* Output Formats: pulseblaster (.vliw, .bin), simulation (.pbsim, .vcd), byte-stream.
input from source_file. The extension .pbsrc is required, unless the filename
is '-' (meaning STDIN).
output to output_file. The extension .vliw is required, unless file is /dev/null
or '-' (meaning STDOUT). If '-o output_file' is not specified, then source_filename
will be used, but renamed with the extension .vliw, (and in the same directory as
as source_file; not in $PWD).
-a Assemble the result (using `pb_asm`) to generate a .bin file as well.
The name pattern for the .bin file will be the same as output_file.
-x OK to overwrite an existing output file. This is prevented by default.
(If output_file is /dev/null, or a named pipe, -x is irrelevant.)
-X enables #execinc. Compilation of the .pbsrc file can invoke any external program:
a security hole unless you read it first: be careful! If pb_parse finds
#execinc without -X, it will print what would have happened.
-D const1=value1 -Dconst2=value2 -Dconst3=value3 -Dconst -Dnoconst ...
equivalent to '#define const value', but at compile-time, rather than in source.
conflicts with #define, required by #define/#what, optional with #define/#default:.
-Dconst and -DNoconst are equivalent to -Dconst=1 and -Dconst="", and are used to
conditionally enable/disable source lines prefixed by #if(const)/#ifnot(const).
-d print *lots* of verbose debug information. (also overrides '@').
-v make debugging even more verbose, useful for debugging pb_parse itself.
-q quieter: supress Notices and repeated Warnings. Not everything is supressed.
(Note: -d overrides -q. To hide warnings, use '2>/dev/null')
-Q quieter than -q: also suppress #echo, and #execinc's stderr. (overridden by -d).
-S scream: break the silence operator '@', forcing warnings on. (-d also does this).
-h display this help message (to STDOUT).
-e write an example .pbsrc file to STDOUT. Then exit. This can be used as a template
for writing your own programs.
-m monochrome: disable colour (ANSI escapes) in output messages. Useful when
processing the output further, piping to less, or with fast -t. (Also, see -y.)
-c print the configuration used by this program, and the data about the PulseBlaster
model for which we are compiling. Then exit.
-n print out the .pbsrc source, as parsed, and expanded with numbered (instruction)
lines, and the corresponding source filenames and line numbers. Useful to view the generated
code and to debug 'error at line $i' messages. This goes to STDOUT, not STDERR.
-V print version information (to STDOUT)
-s simulate an entire run. This is normally an *optimised*, *quiet* simulation. It
checks for termination, repetition, max stack/loop depth etc. This *is* possible
(despite The Halting Problem!), and it proves whether the code contains any
program-flow or stack-depth bugs. Because of optimisation, the simulation runs very
quickly, and always finishes: it need only encounter each instruction line *once*.
Output is terse. For more information, see the file pb_parse/doc/simulation.txt .
(If the simulation detects an error, but you want to generate a .vliw file anyway,
re-invoke the parser without the -s option.)
-f full simulation, not just the optimised simulation. Each instruction is faithfully
executed. For example, a loop always receives n passes, not just 1. This is useful
if you want to trace the program in full (-s suffices to prove correctness). Unless
the program contains a STOP opcode (or a bug), this simulation will not terminate,
and may need to be stopped with Q,[Enter] or Ctrl-C.
(Quitting simulation with Q,[Enter] generates a .vliw file; Ctrl-C doesn't.)
-r verbosely show registers and the corresponding source-lines during simulation. For
each line of the program, the source, instruction, and PC/LD/SD registers are
printed. Explanation of the instruction, and program-flow is shown too.
(This is compatible with either -s or -f, defaulting to -s)
FULL SIMULATION OPTIONS:
These options imply -f, and modify/enhance the simulation. Note that a full simulation will
not terminate unless the program contains a STOP, therefore an output file will only be
generated when the user presses "Q" (but not Ctrl-C).
-l show a single status line with all registers, the full instruction, and simulated
LEDs, (but omit the source-line, for reasons of space). This uses \r to produce a
single, updating status-line, on STDOUT.
(The full simulation defaults to -l, unless -r or -p are specified).
-p piano-roll mode: like -l, but with \n rather than \r, also STDOUT.
-y 'yep'. very terse simulation display. Useful with -g and a slow terminal.
-t real-time mode. Simulate the lengths too, as well as is possible. In practice, this
is only correct for lengths >~ 0.1ms, depending on the computer's speed. The
simulation tries to constantly re-synchronise with "wall-clock time", by comparing
ELAPSED_TICKS with the current microtime; it emits a warning if it can't catch up.
speed up the simulation by a factor of clock_factor. This is a float; if < 1, it
acts to slow down the simulation. (implies -t).
-k enable single/multi-step on keypress. Enter 'n' followed by [ENTER] to jump forward
by n steps. n=1, or just [ENTER] moves to the next instruction. Press Q, then
[ENTER] to quit. (-k implies -p)
automatically stop the simulation after max_steps. Useful in scripts to ensure that
simulation stops, even if the program itself doesn't.
-b beep on each new instruction. (only in real-time, or single-step modes).
-w when simulating a WAIT instruction, actually wait for manual re-trigger, rather
than simply continuing automatically.
during simulation, write the bytes to actual devices. This allows for a "poor-man's
PulseBlaster", using 1-3 parallel ports. Accurately-timed ascii-hex data (eg
"0xffeedd\n") is written to a named-pipe (fifo); this is then transferred to the
physical port(s) by running the separate utility 'pb_parport-output' in another
shell. The fifo, parport_fifo will be created if necessary. (most useful with -t).
-g generate a Simulation Replay Log, (extension .pbsim). The Simulation Replay Log is
useful for simulating the target hardware. After simulation, this logfile contains
the outputs (and lengths) that the PulseBlaster would have output. If the
PulseBlaster is connected to, for example, a camera controller which itself has a
simulation program, the camera-simulator (hawaiisim) can replay the logfile.
MARK instructions highlight specific 'breakpoints', (prefaced with '//MARK:').
If the program loops, this logfile could be infinite: recommend using "-u", or a
named-pipe. (Not affected by -z; enables -y unless -p/-l; not recommended with -w,
nor -k. Filename controlled by -o.) For more details, see: pb_parse/doc/pbsim.txt
-G generate a Value Change Dump file (extension .vcd). The VCD file contains the
same information as the simulation replay log, but in the standard format used by
wavefile viewers, such as gtkwave. For the line labels, use #vcdlabels, or -L.
(Behaves like -g regarding flags z,y,p,l,w,k. Filename from -o.) For more details,
see: pb_parse/doc/vcd.txt, or Wikipedia:Value_change_dump
comma-delimited list of bit-labels for the .vcd file (override source #vcdlabels).
Use '-' to skip; <= 24 elements. E.g: 'Reset,Clock,-,Enable' means: show only bits
3,2,0 in the .vcd file, labelled as 'Reset','Clock','Enable'. (modifies -G).
pb_parse -i example.pbsrc -o example.vliw #Parse example.pbsrc
pb_parse -qasxi example.pbsrc #Parse, assemble, check. (quietly)
pb_parse -xi example.pbsrc -lb -tz 0.1 #Simulate, LEDs, realtime/10, beep.
pb_parse -i example.pbsrc -gG -u 100 #Generate short replay-log and VCD file.
mkfifo pbfifo; pb_parport-output pbfifo & pb_parse -j pbfifo -tymqxi example.pbsrc #Parport.
* The .pbsrc format is thoroughly documented in: /usr/local/share/doc/pb_parse/pbsrc.txt
* There are some sample programs in: pb_parse/pbsrc_examples/
* Simulation is described in: pb_parse/doc/simulation.txt
* The device is documented at http://www.pulseblaster.com
* See also man pb_parse(1), man pbsrc(5), pb_parse/doc/*
The parser will exit with status 0 if all is well. In case of any problem, the exit code
is 1. There will always be a helpful message just before exiting. If the source contains
a syntax error, any .vliw file will be removed: this protects against inadvertently
re-using an old .vliw file for pb_prog.
All error messages (and interactive prompts) are sent to stderr, so may be redirected with
2>/dev/null. Some outputs (notably -n,-l,-p) are sent to STDOUT. Full simulation uses both
STDIN and STDOUT, so clashes with '-i -' and '-o -'; optimised simulation doesn't."
pb_parse is a PHP script, using the PHP 5 SAPI. It can parse a 32k-line .pbsrc file in
5-15 seconds (depending on debugging and number of warnings) on a 3.5GHz Intel i7 machine.
The simulation is very much faster than the parser (< 1 second). However, memory usage is
high for large input files: if PHP complains "Allowed memory size of .... bytes exhausted",
then increase 'memory_limit' in /etc/php-cli.ini to at least 32 MB (or -1 for unlimited).
If the computer is marginally too slow when simulating with -t, a significant speedup can
be obtained by redirecting STDOUT to a log file, rather than directly displaying it on the
terminal, also use -m or -y. Typically, the simulator can run at 4.9 kips without -j and
redirecting STDOUT. With -j, performance drops to about 3.4 kips; if output is also viewed
on the terminal, perfornmance is nearer 1.1 kips. Realtime parallel-port output (-tj, with
pb_parport-output) is possible at up to 1 kips, without significant jitter.
* pb_parse can require rather a lot of memory: approx 1kB per line of the .pbsrc file.
* PHP doesn't have an unsigned-int or long type. Therefore the LENGTHs are parsed as floats
instead. This works, because a double has ~52 bits of integer-precision.
* If either ARG or OUTPUT should ever become > 31 bits long, in future versions of the
PulseBlaster, this script will need to be re-written (though it will warn).
* Some of the source-code and output lines can be rather long. We could make full use of a
screen width of 200 characters!
* By nature, it encourages "pre-processor abuse": for example this line compiles fine:
#define JULY #ifnot(HERRING) bit_flip(PENGUIN) goto ANTARCTICA ALL_SUMMER
* It hasn't (yet) expanded to the point where it can read email, so as to fulfil Zawinski's
Law! But we're now at 5398 lines, 130 REs, 328 kB and counting... Inner Platform Effect?
Richard Neill <pulseblaster at richardneill.org> 2004-2013
Download from: http://www.richardneill.org/source
This is Free Software, licensed under the GNU GPL version 3 or later.
Version 2.85, released on 2013-09-17.
- SEE ALSO
This document was created by
using the manual pages.
Time: 15:45:34 GMT, November 19, 2013