--- /dev/null
+#!/bin/bash
+
+# run chromium / google-chrome on current display hack
+
+DISPDIR=$(echo $DISPLAY | awk -F. '{print $1}')
+exec google-chrome --user-data-dir=$HOME/.config/google-chrome/$DISPDIR $@
--- /dev/null
+#!/bin/bash
+
+# cleanup data from timeSampler,
+# removes null entries and sorts by time
+
+TMPFILE=$(tempfile)
+for f in $(ls -1 $HOME/.timeSampler.*); do
+ grep -v "null$" $f | sort > $TMPFILE
+ cp $TMPFILE $f
+done
+
+rm -f $TMPFILE
--- /dev/null
+#!/usr/bin/perl -w
+
+# usage: extblock infile rem_out spattern scount epattern ecount
+#
+# Dan White <dan@whiteaudio.com>
+
+# From infile, start copying the contents to stdout after finding spattern
+# scount times. Once epattern has been found ecount times (typically 1), copy
+# the remaininder of infile to rem_out.
+
+# Originally written to iteratively pick out HSPICE listing output related to
+# .print statements, e.g.:
+# extblock infile remfile "^x" 1 "^y" 1 > print_block.csv
+
+# There are better ways of doing this, probably with sed or awk, but I don't
+# know those languages.
+
+open(INFILE, $ARGV[0]) or die "Can't open file [ $ARGV[0] ] for reading.";
+open(OUTFILE, '>'.$ARGV[1]) or die "Can't open file [ $ARGV[1] ] for writing.";
+my $spattern=$ARGV[2];
+my $scount=$ARGV[3];
+my $epattern=$ARGV[4];
+my $ecount=$ARGV[5];
+
+my $sc=0;
+while(<INFILE>) {
+ #find start pattern
+ if(/$spattern/) {
+ if($sc<$scount) {
+ $sc++;
+ next;
+ } else {
+ last;
+ }
+ }
+ next;
+}
+
+print;
+my $ec=1;
+while(<INFILE>) {
+ #find end pattern
+ if(/$epattern/) {
+ if($ec<$ecount) {
+ $ec++;
+ print;
+ next;
+ }
+ #this is the ending line target
+ print;
+ last;
+ }
+ print;
+}
+
+#copy rest of file to rem_file
+#including the previous last line!
+print OUTFILE;
+while(<INFILE>) {
+ print OUTFILE;
+}
+
+
--- /dev/null
+#!/bin/bash
+
+# dirty hack to quickly look for a chip by PN
+
+browser=${BROWSER:-"xdg-open"}
+encoded=$(echo "$1" | perl -MURI::Escape -lne 'print uri_escape($_)')
+$browser "http://www.findchips.com/avail?part=$encoded"
+
--- /dev/null
+#!/usr/bin/perl -w
+
+# getuntil infile start_pattern scount end_pattern ecount
+# cat's file until it finds 'pattern' and exits
+
+if($ARGV[0] eq '-h') {
+ print "Usage:\n";
+ print "getuntil infile start_pattern scount end_pattern ecount\n";
+ exit(1);
+}
+
+$infile=$ARGV[0];
+$spattern=$ARGV[1];
+$scount=$ARGV[2];
+$epattern=$ARGV[3];
+$ecount=$ARGV[4];
+
+open(IFP, $infile);
+
+$sc=0;
+$ec=0;
+while(<IFP>){
+ if ($sc < $scount) {
+ if (/$spattern/) { $sc++; }
+ if ($sc == $scount) { print; }
+ } elsif ($ec < $ecount) {
+ #within start and end sections
+ if (/$epattern/) { $ec++; }
+ print;
+ } else {
+ last;
+ }
+}
+
+exit(0);
+
--- /dev/null
+#!/bin/bash
+
+# (C) Dan White <dan@whiteaudio.com>, GPL license
+
+VERBOSE=0
+
+function usage() {
+cat << EOF
+Usage: $0 [-o output.pdf] infile1.pdf [infile2.pdf [...]]
+
+Output a pdf whose pages are infile1:1, infile2:1 ... infile1:2, infile2:2
+The number of output pages is the length of the longest input file times the
+number of input files.
+EOF
+}
+
+letters=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
+declare -i nfiles=0
+declare -i maxpages=0
+outfile="output.pdf"
+while [ "$1" != "" ]; do
+ if [ "$1" == "-o" ]; then
+ #set name of output file to non-default value
+ outfile=$2
+ shift
+ elif [ "$1" == "-h" ]; then
+ usage
+ exit 1
+ else
+ infiles[$nfiles]=$1
+ npages[$nfiles]=$(pdftk $1 dump_data | tail -n1 | awk '{print $2}')
+ [[ npages[$nfiles] -gt $maxpages ]] && maxpages=${npages[$nfiles]}
+ let "nfiles=nfiles+1"
+ if [[ $nfiles -gt 26 ]]; then
+ echo "OOPS: can only handle 26 files to be interleaved presently"
+ exit 1
+ fi
+ fi
+ shift
+done
+
+#show some info
+if [ $VERBOSE == 1 ]; then
+ #echo "letters: ${letters[*]}"
+ echo "infiles: ${infiles[*]}"
+ echo "npages: ${npages[*]}"
+ echo "maxpages: $maxpages"
+fi
+
+#do the deed
+#
+# there are nfiles circular buffers of pages of varying lengths, the number of
+# output pages is maxpages*nfiles.
+for i in $(seq 1 $maxpages); do
+ [[ $VERBOSE == 1 ]] && echo "page $i"
+ #assign each file a letter for referencing with pdftk
+ pre=""
+ #cat the appropriate page number of each file, looping through the shorter
+ #ones, to an aggregate collection of pages
+ post=""
+ for fnum in $(seq 0 $(($nfiles -1)) ); do
+ pre="$pre ${letters[$fnum]}=${infiles[$fnum]}"
+ post="$post ${letters[$fnum]}$((i % npages[$fnum] +1))"
+ done
+ pdftk $pre cat $post output $outfile-p$i.pdf
+done
+
+#cat all the aggregations together into the final page stream
+echo "putting all together"
+pdftk $outfile-p*.pdf cat output $outfile
+rm -f $outfile-p*.pdf
+
--- /dev/null
+#!/bin/bash
+xset dpms force off
--- /dev/null
+#!/bin/bash
+
+if [ "$1" == "-h" ]; then
+ echo "Quick note taking function"
+ echo "Usage: note [-h] [-f otherFile] [- | note string]"
+ echo "-f file Append note to FILE instead"
+ echo "other arguments are appended to \$NOTES_FILE environment variable"
+ echo "if no arguments, edit note file directly"
+ exit 1
+fi
+
+#TIMESTAMP=`date`
+TIMESTAMP=`date +"%F %k:%M:%S"`
+
+# export to a different note file
+if [ "$1" == "-f" ]; then
+ NOTES_FILE=$2
+ shift 2
+ echo "using file: $NOTES_FILE" >&2
+fi
+
+# create the time-stamped note
+cat << END_NOTE_TEXT >> $NOTES_FILE
+
+$TIMESTAMP
+----------------------------------------
+END_NOTE_TEXT
+
+#text is from stdin
+if [ "$1" == "-" ]; then
+ cat >> $NOTES_FILE
+else
+ echo $* >> $NOTES_FILE
+fi
+
+# edit the note if no (remaining) arguments
+if [ $# -eq 0 ]; then
+ $EDITOR + $NOTES_FILE
+fi
+
--- /dev/null
+#!/bin/bash
+
+browser=${BROWSER:-"xdg-open"}
+
+encoded=$(echo "$1" | perl -MURI::Escape -lne 'print uri_escape($_)')
+echo $encoded
+
+$browser "http://octopart.com/parts/search?q=$encoded&js=on"
+
--- /dev/null
+#!/bin/bash
+
+# Dan White <dan@whiteaudio.com>
+
+function parent_has {
+# $1 - file/folder to look for in pwd and parents
+ if [ -e $1 ]; then
+ return 0
+ elif [ $PWD == "/" ]; then
+ return 1
+ fi
+
+ cd $(dirname $PWD)
+ parent_has "$1"
+}
+
+parent_has "$1"
+
--- /dev/null
+#!/bin/bash
+
+# Dan White <dan@whiteaudio.com>
+
+SMSTO=${SMSTO:-"dansms"}
+
+function usage {
+cat << EOF
+Usage: sms "subject" [filename | -]
+
+send the contents of stdin or 'filename' to \$SMSTO ($SMSTO)
+EOF
+}
+
+if [[ $# -eq 0 ]] || [[ $1 == "-h" ]] ; then
+ usage
+ exit 1
+fi
+
+SUBJECT=$1
+
+if [ -r "$2" ]; then
+ cat "$2" | email -s "$SUBJECT" $SMSTO
+else
+ email -b -s "$SUBJECT" $SMSTO
+fi
--- /dev/null
+#!/bin/bash
+
+# preprocessor for spice files
+# lines start with "**" to trigger the parser
+# Example
+# *spice netlist title
+# **ifdef GNUCAP
+#
+# *gnucap specific stuff
+#
+# **else
+#
+# *hspice specific stuff
+#
+# **endif
+# .end
+#
+gpp -U "" "" "(" "," ")" "(" ")" "#" "\\" \
+ -M "**" "\n" " " " " "\n" "(" ")" $@
+
--- /dev/null
+#!/usr/bin/env python
+
+# Dan White <dan@whiteaudio.com>
+
+"""Recurse from current or given directory and display all folders with
+tags."""
+
+import optparse
+import os
+import sys
+import re
+
+try:
+ import cStringIO as StringIO
+except ImportError:
+ import StringIO
+
+try:
+ import optcomplete
+except ImportError:
+ optcomplete = None
+
+#ignore tmp and hidden folders
+RE_DO_NOT_FOLLOW_DIR = re.compile(r'^tmp$|^\.')
+
+#tag prefix, these must match
+TAG_PREFIX = '.tag.'
+#RE_TAG = re.compile(r'^\.tag')
+RE_TAG = re.compile(r'^' + TAG_PREFIX.replace('.', '\.'))
+
+#
+# Options
+#
+optParser = optparse.OptionParser()
+optParser.add_option('-a', '--add', dest='add', action='store', type='string',
+ help='add TAG to folder', metavar='TAG')
+
+optParser.add_option('-d', '--delete', dest='delete', action='store',
+ type='string',
+ help='remove TAG from folder', metavar='TAG')
+
+optParser.add_option('-l', '--list', dest='list', action='store_true',
+ default=False,
+ help="list tags in all folders which have them")
+
+optParser.add_option('-t', '--tag', dest='tag', action='store', type='string',
+ help='list folders which have given comma-sep tag(s)')
+
+optParser.add_option('-r', '--recurse', dest='recurse', action='store_true',
+ default=False,
+ help='recurse into child folders')
+
+optParser.add_option('-R', '--no-recurse', dest='recurse', action='store_false',
+ help='do not recurse into child folders (default)')
+
+_cwd = os.getcwd()
+_HOME = os.getenv('HOME')
+
+def herePath(p, base=None):
+ '''Return the given path relative to base'''
+ if base:
+ return p.replace(base,'.')
+ else:
+ return p
+
+
+def listTags(baseDir):
+ files = os.listdir(baseDir)
+ tags = [t.replace(TAG_PREFIX, '') for t in files if RE_TAG.match(t)]
+ tags.sort()
+ return tags
+
+
+def findTag(tag, baseDir):
+ s = StringIO.StringIO()
+ for (path, dirs, files) in os.walk(baseDir):
+ dirs[:] = [d for d in dirs if not RE_DO_NOT_FOLLOW_DIR.match(d)]
+ tags = [t.replace(TAG_PREFIX, '') for t in files if t.startswith(TAG_PREFIX)]
+ if tag in tags:
+ print>>s, path
+ return s.getvalue().rstrip()
+
+
+def addTag(tag, baseDir):
+ try:
+ open(baseDir + '/' + TAG_PREFIX + tag, 'r')
+ print "ee's already got one (%s)" % tag
+ except IOError:
+ t = open(baseDir + '/' + TAG_PREFIX + tag, 'w')
+ t.close()
+
+
+def deleteTag(tag, baseDir):
+ try:
+ os.remove(baseDir + '/' + TAG_PREFIX + tag)
+ except OSError:
+ print 'tag already not present (%s)' % tag
+
+
+
+def main():
+ if optcomplete:
+ optcomplete.autocomplete(optParser)
+
+ (opt, args) = optParser.parse_args()
+ arglen = len(args)
+ #print opt
+ #print args
+
+ taglist = []
+ if arglen == 0:
+ walkDir = _cwd
+ elif arglen == 1:
+ walkDir = os.path.expandvars(os.path.expanduser(args[0]))
+ walkDir = walkDir.rstrip(os.sep)
+ elif arglen >=2:
+ walkDir = os.path.expandvars(os.path.expanduser(args[0]))
+ walkDir = walkDir.rstrip(os.sep)
+ taglist = args[1:]
+
+ if opt.list:
+ if opt.recurse:
+ alltags = {}
+ for (path, dirs, files) in os.walk(walkDir):
+ dirs[:] = [d for d in dirs if not RE_DO_NOT_FOLLOW_DIR.match(d)]
+ tags = [t.replace(TAG_PREFIX,'') for t in files
+ if RE_TAG.match(t)]
+ tags.sort()
+ if tags:
+ for t in tags:
+ if t in alltags:
+ alltags[t].append(path)
+ else:
+ alltags[t] = [path]
+ print '%s:' % herePath(path, walkDir)
+ print '\n'.join(tags)
+ #usedtags = alltags.keys()
+ #usedtags.sort()
+ #print
+ #print 'tags defined at:'
+ #for t in usedtags:
+ #print '%s:' % t
+ #print '\n'.join(alltags[t])
+ else:
+ print '\n'.join(listTags(walkDir))
+ elif opt.tag:
+ for t in opt.tag.split(',') + taglist:
+ print 'adding', t
+ print findTag(t, walkDir)
+ elif opt.add:
+ for t in opt.add.split(',') + taglist:
+ print 'adding', t
+ addTag(t, walkDir)
+ elif opt.delete:
+ for t in opt.delete.split(','):
+ deleteTag(t, walkDir)
+
+if __name__ == '__main__':
+ main()
+
--- /dev/null
+#!/usr/bin/env python
+
+# recursive todo - runs todo in all sub-directories which have a todo list in
+# them and only displays if there is actual output
+#
+# Dan White <dan@whiteaudio.com>
+# idea from Bash version by Brian Herlihy
+#
+
+import re
+import os
+import subprocess
+import sys
+
+#
+# semi-volatile options
+#
+
+#replaced with path to current .todo
+#HEADER_STRING = 'TODO %s'
+HEADER_STRING = '\n=== %s ==='
+
+#--force-colour necessary to keep color information
+DEFAULT_DEVTODO_OPTIONS = '--force-colour --filter -children'
+
+#do not recurse into these directories
+DO_NOT_FOLLOW_DIR_RE = re.compile(r'^tmp$|^\.|^Mail$')
+
+#re for finding the final newline from todo output immediately before
+#the final terminal color-changing code string
+LAST_NL_RE = re.compile(r'(\n)(\033\[0m$)')
+
+usage = '''\
+Usage: %s [devtodo options]
+Recursively displays devtodo .todo databases from the current directory.
+Default options are: %s '''
+
+#
+# display usage, pass options to devtodo, or use default options
+#
+if sys.argv[1:]:
+ #help if requested
+ if sys.argv[1] == '-h' or sys.argv[1] == '--help':
+ print usage % (os.path.basename(sys.argv[0]), DEFAULT_DEVTODO_OPTIONS)
+ sys.exit()
+ DEVTODO_OPTIONS = '--force-colour ' + ' '.join(sys.argv[1:])
+else:
+ DEVTODO_OPTIONS = DEFAULT_DEVTODO_OPTIONS
+
+DEVTODO_COMMAND = 'todo --database %s/.todo ' + DEVTODO_OPTIONS
+
+#
+# real functionality
+#
+def herePath(p, base=None):
+ '''Return the given path relative to base'''
+ if base:
+ return p.replace(base,'').lstrip('/')
+ else:
+ return p
+
+cwd = os.getcwd()
+for (dpath, dnames, fnames) in os.walk(cwd):
+ dnames[:] = [d for d in dnames if not DO_NOT_FOLLOW_DIR_RE.match(d)]
+ if '.todo' in fnames:
+ #f = os.popen(DEVTODO_COMMAND % dpath, 'r')
+ f = subprocess.Popen(DEVTODO_COMMAND % dpath, shell=True,
+ stdout=subprocess.PIPE).stdout
+ todoOutput = f.read()
+ if todoOutput:
+ print HEADER_STRING % herePath(dpath, cwd)
+ print LAST_NL_RE.sub('\g<2>', todoOutput)
+
--- /dev/null
+#!/bin/bash
+
+# from http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
+
+#
+# This file echoes a bunch of color codes to the
+# terminal to demonstrate what's available. Each
+# line is the color code of one forground color,
+# out of 17 (default + 16 escapes), followed by a
+# test use of that color on all nine background
+# colors (default + 8 escapes).
+#
+
+T='gYw' # The test text
+
+echo -e "\n 40m 41m 42m 43m\
+ 44m 45m 46m 47m";
+
+for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
+ '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
+ ' 36m' '1;36m' ' 37m' '1;37m';
+ do FG=${FGs// /}
+ echo -en " $FGs \033[$FG $T "
+ for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
+ do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
+ done
+ echo;
+done
+echo
--- /dev/null
+#!/bin/bash
+
+# texify [options] file.tex
+# Runs latex on file, runs again if necessary.
+# outputs warnings and errors
+
+# 'rubber' works better...
+
+
+CLEAN=0
+if [ "$1" == "-c" ]; then
+ shift
+ CLEAN=1
+fi
+
+tmpfile=tmp`date +%F-%H%M%S`
+
+echo "Rerun" > $tmpfile
+while grep -q "Rerun\|exist, replaced" $tmpfile; do
+ #run LaTeX and catch output
+ echo -n "texify: running LaTeX..."
+ #latex -interaction=nonstopmode --output-format=pdf $* > $tmpfile
+ pdflatex -interaction nonstopmode \
+ -output-format pdf \
+ -halt-on-error \
+ $@ > $tmpfile
+ echo "done"
+
+ #quit on error
+ if grep -A4 "^!" $tmpfile; then
+ if grep "pdfTeX warning" $tmpfile; then
+ continue;
+ else
+ rm $tmpfile;
+ exit 1;
+ fi
+ fi
+done
+
+#only print warnings, if any
+grep -A1 Warning $tmpfile
+
+rm $tmpfile
+if [ $CLEAN -eq 1 ]; then
+ rm *.out *.toc *.aux *.log
+fi
+
--- /dev/null
+#!/bin/bash
+
+MYSELF='dan'
+
+function usage {
+cat << EOF
+Usage: textmail 'subject' [filename]
+
+send the contents of stdin or 'filename' to \$MAILTO ($MAILTO)
+EOF
+}
+
+if [ $# -eq 0 ] || [ $1 == "-h" ]; then
+ usage
+ exit 1
+fi
+
+SUBJECT=$1
+MAILCMD="email -s $SUBJECT $MYSELF"
+MAILCMD="email -s $SUBJECT $MAILTO"
+
+if [ "$2" == "" ]; then
+ cat - | $MAILCMD
+else
+ cat $2 | $MAILCMD
+fi
--- /dev/null
+#!/bin/sh
+# Shell script to start Vim with less.vim.
+# Read stdin if no arguments were given.
+
+files=$@
+if [ -z "$files" ]; then files="-"; fi
+
+less_vim() {
+ vim -R -c 'let no_plugin_maps = 1' \
+ -c 'runtime! macros/less.vim' \
+ -c 'set mouse=h' "$@"
+}
+
+do_ps() {
+ ps fauxw
+}
+
+pproc() {
+ if uname -s | grep -iq linux; then
+ ps -p $1 -o comm=
+ elif uname -s | grep -iq cygwin; then
+ ps -p $1 | sed -e 's/^I/ /' | grep -v PID
+ fi
+}
+
+ppid() {
+ if uname -s | grep -iq linux; then
+ ps -p $1 -o ppid=
+ elif uname -s | grep -iq cygwin; then
+ ps -p $1 | sed -e 's/^I/ /' | grep -v PID | awk '{print $2}'
+ fi
+}
+
+# Check if called from man or perldoc
+MAN_LIKE_PROGS="man\|pydoc\>\|ipython\|python"
+if do_ps | grep -q '\(man\|perl\|py\(doc\|thon\)\)\>'; then
+ proc=$$
+ while next_parent=`ppid $proc` && [ $next_parent != 1 ]; do
+ #echo `pproc $next_parent`
+ #if pproc $next_parent | grep -q 'man\|pydoc\>'; then
+ if pproc $next_parent | grep -q $MAN_LIKE_PROGS; then
+ #echo "found man-like-prog"
+ perl -pi -e 's/\e\[[^m]*m//g' | col -b \
+ | less_vim -c 'set ft=man' -; exit
+ #less_vim -c 'set ft=man' -; exit
+ elif pproc $next_parent | grep -q 'perl\(doc\|$\)\>'; then
+ perl -pi -e 's/\e\[[^m]*m//g' | col -b \
+ | less_vim -c 'set ft=man' -; exit
+ #col -b < $files | less_vim -c "set ft=man" -; exit
+ fi
+ proc=$next_parent
+ done
+fi
+
+#echo "not man-like"
+less_vim $files
--- /dev/null
+#!/usr/bin/python
+
+# Dan White <dan@whiteaudio.com>
+
+import os
+import sys
+import re
+
+from decimal import Decimal
+
+try:
+ import psyco
+ psyco.full()
+except ImportError:
+ pass
+
+def usage():
+ print >>sys.stderr, '''
+Usage: vwf2pwl.py digitalinputs.vwf
+
+vwf file format:
+ [one name=value parameter per line]
+ [space-separated column labels for voltage source names AND node names]
+ [one line per bit interval of 0 or 1 for each column, no spaces between]
+
+Example .vwf contents for testing an adder:
+ clockdelay=500p
+ clockrisefall = 100p
+ risefall=200p
+ bittime=1n
+ bitlow=0
+ bithigh=5
+ a3 a2 a1 a0 b3 b2 b1 b0
+ 00000000
+ 00010001
+ 00010010
+ 11111111
+ 01011010
+ 01011011
+
+Include the generated file, which also includes the Voltage-source definitons
+for the input nodes as:
+ .include "foo.pwl"
+
+The "clockdelay=" parameter, if present, also generates a voltage source for a
+clock as "Vclock clock 0 PWL ..." with a rising edge at every bittime with an
+offset of clockdelay. Hence, set "clockdelay=" to the maximum setup time of
+your registers and the data on each line will be clocked in at the right time.
+Parameter "clockrisefall=" is optional to separately specify the clock rise/
+fall time.
+'''
+
+
+def info(s):
+ print 'INFO:', s
+
+
+def error(s):
+ print 'ERROR:', s
+ sys.exit(1)
+
+
+def warn(s):
+ print 'WARNING:', s
+
+
+def mkvwf(d):
+ t = Decimal('0.0')
+
+ #first bit interval starts at t=0, start from this value
+ lastbit = d[0]
+ bitv = Decimal(lastbit) * (bithigh - bitlow) + bitlow
+ s = '+ 0 %s' % str(bitv)
+ output(s)
+
+ trf = risefall
+ tb = bittime - risefall
+ t += trf + tb
+ for bit in d[1:]:
+ if bit != lastbit:
+ ti = t + trf
+ tf = ti + tb
+ lastbitv = Decimal(lastbit) * (bithigh - bitlow) + bitlow
+ bitv = Decimal(bit) * (bithigh - bitlow) + bitlow
+ output('+ %s %s' % (str(t), str(lastbitv)))
+ output('+ %s %s' % (str(ti), str(bitv)))
+ #output('+ %s %s' % (str(tf), str(bitv)))
+
+ t += trf + tb
+ lastbit = bit
+
+
+RE_UNIT = re.compile(r'^([0-9e\+\-\.]+)(t|g|meg|x|k|mil|m|u|n|p|f)?')
+def unit(s):
+ """Takes a string and returns the equivalent float.
+ '3.0u' -> 3.0e-6"""
+ mult = {'t' :Decimal('1.0e12'),
+ 'g' :Decimal('1.0e9'),
+ 'meg':Decimal('1.0e6'),
+ 'x' :Decimal('1.0e6'),
+ 'k' :Decimal('1.0e3'),
+ 'mil':Decimal('25.4e-6'),
+ 'm' :Decimal('1.0e-3'),
+ 'u' :Decimal('1.0e-6'),
+ 'n' :Decimal('1.0e-9'),
+ 'p' :Decimal('1.0e-12'),
+ 'f' :Decimal('1.0e-15')}
+
+ m = RE_UNIT.search(s.lower())
+ try:
+ if m.group(2):
+ return Decimal(Decimal(m.group(1)))*mult[m.group(2)]
+ else:
+ return Decimal(m.group(1))
+ except:
+ error("Bad unit: %s" % s)
+
+
+
+if len(sys.argv) < 2:
+ usage()
+ sys.exit(1)
+
+vwf = sys.argv[1]
+if not vwf.endswith('.vwf'):
+ usage()
+ print "Error: File must have a .vwf extension"
+ sys.exit(1)
+
+pwl = vwf.replace('.vwf', '.pwl')
+
+fvwf = open(vwf)
+fpwl = open(pwl, 'w')
+
+
+#read in the vwf definition file
+
+#get parameters
+requiredParams = ('risefall', 'bittime', 'bitlow', 'bithigh')
+params = {'clockdelay':None, 'clockrisefall':None}
+
+line = fvwf.readline()
+while '=' in line:
+ name, value = line.split('=')
+ name = name.strip()
+ value = value.strip()
+ params[name] = value
+ line = fvwf.readline()
+
+#check
+for p in requiredParams:
+ if p not in params:
+ error("%s is not specified, aborting." % p)
+
+info('Parameters:')
+for p,v in params.iteritems():
+ info(' %s = %s' % (p, v))
+
+if params['clockdelay']:
+ info("Adding a clock at 'clock' node.")
+
+#get column labels
+inputs = [c.strip() for c in line.strip().split()]
+info("Columns: %s" % inputs)
+
+#read in data
+data = {}
+for i in inputs:
+ data[i] = []
+
+for line in fvwf:
+ vector = line.strip()
+ if len(vector) != len(inputs):
+ error("Must have same # characters as column labels: %s" % line.strip())
+
+ i = 0
+ for bit in vector:
+ data[inputs[i]].append(bit)
+ i += 1
+
+#outputs
+output = lambda s: fpwl.write(s + '\n')
+
+#get the numbers
+risefall = unit(params['risefall'])
+bittime = unit(params['bittime'])
+bitlow = unit(params['bitlow'])
+bithigh = unit(params['bithigh'])
+
+#output clock definition if specified
+if params['clockdelay']:
+ #calculate clock high time
+ if params['clockrisefall']:
+ clockrisefall = unit(params['clockrisefall'])
+ else:
+ clockrisefall = risefall
+
+ clockhigh = Decimal('0.5') * (bittime - clockrisefall)
+ clockperiod = bittime
+
+ params['clockrisefall'] = str(clockrisefall)
+ params['clockhigh'] = str(clockhigh)
+ params['clockperiod'] = str(clockperiod)
+
+ clk = 'Vclock clock 0 pulse(%(bitlow)s %(bithigh)s %(clockdelay)s %(clockrisefall)s %(clockrisefall)s %(clockhigh)s %(clockperiod)s)' % params
+ info(clk)
+ output(clk)
+ output('')
+
+#output each input source
+for name in inputs:
+ d = data[name]
+
+ s = 'V%s %s 0 PWL' % (name, name)
+ info(s)
+ output(s)
+
+ #first bit interval starts at t=0, start from this value
+ bit = d[0]
+ bitv = Decimal(bit) * (bithigh - bitlow) + bitlow
+
+ mkvwf(d)
+ output('')
+